]> code.delx.au - pulseaudio/blob - src/pulse/util.c
Merge commit 'origin/master-tx'
[pulseaudio] / src / pulse / util.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <errno.h>
28 #include <limits.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33 #include <unistd.h>
34 #include <sys/types.h>
35
36 #ifdef HAVE_PWD_H
37 #include <pwd.h>
38 #endif
39
40 #ifdef HAVE_SYS_SOCKET_H
41 #include <sys/socket.h>
42 #endif
43
44 #ifdef HAVE_NETDB_H
45 #include <netdb.h>
46 #endif
47
48 #ifdef HAVE_WINDOWS_H
49 #include <windows.h>
50 #endif
51
52 #ifdef HAVE_SYS_PRCTL_H
53 #include <sys/prctl.h>
54 #endif
55
56 #include <pulse/xmalloc.h>
57 #include <pulse/timeval.h>
58
59 #include <pulsecore/winsock.h>
60 #include <pulsecore/core-error.h>
61 #include <pulsecore/log.h>
62 #include <pulsecore/core-util.h>
63 #include <pulsecore/macro.h>
64 #include <pulsecore/usergroup.h>
65
66 #include "util.h"
67
68 char *pa_get_user_name(char *s, size_t l) {
69 const char *p;
70 char *name = NULL;
71 #ifdef OS_IS_WIN32
72 char buf[1024];
73 #endif
74
75 #ifdef HAVE_PWD_H
76 struct passwd *r;
77 #endif
78
79 pa_assert(s);
80 pa_assert(l > 0);
81
82 if ((p = (getuid() == 0 ? "root" : NULL)) ||
83 (p = getenv("USER")) ||
84 (p = getenv("LOGNAME")) ||
85 (p = getenv("USERNAME")))
86 {
87 name = pa_strlcpy(s, p, l);
88 } else {
89 #ifdef HAVE_PWD_H
90
91 if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
92 pa_snprintf(s, l, "%lu", (unsigned long) getuid());
93 return s;
94 }
95
96 name = pa_strlcpy(s, r->pw_name, l);
97 pa_getpwuid_free(r);
98
99 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
100 DWORD size = sizeof(buf);
101
102 if (!GetUserName(buf, &size)) {
103 errno = ENOENT;
104 return NULL;
105 }
106
107 name = pa_strlcpy(s, buf, l);
108
109 #else /* HAVE_PWD_H */
110
111 return NULL;
112 #endif /* HAVE_PWD_H */
113 }
114
115 return name;
116 }
117
118 char *pa_get_host_name(char *s, size_t l) {
119
120 pa_assert(s);
121 pa_assert(l > 0);
122
123 if (gethostname(s, l) < 0)
124 return NULL;
125
126 s[l-1] = 0;
127 return s;
128 }
129
130 char *pa_get_home_dir(char *s, size_t l) {
131 char *e, *dir;
132
133 #ifdef HAVE_PWD_H
134 struct passwd *r;
135 #endif
136
137 pa_assert(s);
138 pa_assert(l > 0);
139
140 if ((e = getenv("HOME")))
141 return pa_strlcpy(s, e, l);
142
143 if ((e = getenv("USERPROFILE")))
144 return pa_strlcpy(s, e, l);
145
146 #ifdef HAVE_PWD_H
147 errno = 0;
148 if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
149 if (!errno)
150 errno = ENOENT;
151
152 return NULL;
153 }
154
155 dir = pa_strlcpy(s, r->pw_dir, l);
156
157 pa_getpwuid_free(r);
158
159 return dir;
160 #else /* HAVE_PWD_H */
161
162 errno = ENOENT;
163 return NULL;
164 #endif
165 }
166
167 char *pa_get_binary_name(char *s, size_t l) {
168
169 pa_assert(s);
170 pa_assert(l > 0);
171
172 #if defined(OS_IS_WIN32)
173 {
174 char path[PATH_MAX];
175
176 if (GetModuleFileName(NULL, path, PATH_MAX))
177 return pa_strlcpy(s, pa_path_get_filename(path), l);
178 }
179 #endif
180
181 #ifdef __linux__
182 {
183 char *rp;
184 /* This works on Linux only */
185
186 if ((rp = pa_readlink("/proc/self/exe"))) {
187 pa_strlcpy(s, pa_path_get_filename(rp), l);
188 pa_xfree(rp);
189 return s;
190 }
191 }
192
193 #endif
194
195 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
196 {
197
198 #ifndef TASK_COMM_LEN
199 /* Actually defined in linux/sched.h */
200 #define TASK_COMM_LEN 16
201 #endif
202
203 char tcomm[TASK_COMM_LEN+1];
204 memset(tcomm, 0, sizeof(tcomm));
205
206 /* This works on Linux only */
207 if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
208 return pa_strlcpy(s, tcomm, l);
209
210 }
211 #endif
212
213 errno = ENOENT;
214 return NULL;
215 }
216
217 char *pa_path_get_filename(const char *p) {
218 char *fn;
219
220 if (!p)
221 return NULL;
222
223 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
224 return fn+1;
225
226 return (char*) p;
227 }
228
229 char *pa_get_fqdn(char *s, size_t l) {
230 char hn[256];
231 #ifdef HAVE_GETADDRINFO
232 struct addrinfo *a, hints;
233 #endif
234
235 pa_assert(s);
236 pa_assert(l > 0);
237
238 if (!pa_get_host_name(hn, sizeof(hn)))
239 return NULL;
240
241 #ifdef HAVE_GETADDRINFO
242 memset(&hints, 0, sizeof(hints));
243 hints.ai_family = AF_UNSPEC;
244 hints.ai_flags = AI_CANONNAME;
245
246 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
247 return pa_strlcpy(s, hn, l);
248
249 pa_strlcpy(s, a->ai_canonname, l);
250 freeaddrinfo(a);
251 return s;
252 #else
253 return pa_strlcpy(s, hn, l);
254 #endif
255 }
256
257 int pa_msleep(unsigned long t) {
258 #ifdef OS_IS_WIN32
259 Sleep(t);
260 return 0;
261 #elif defined(HAVE_NANOSLEEP)
262 struct timespec ts;
263
264 ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC);
265 ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC);
266
267 return nanosleep(&ts, NULL);
268 #else
269 #error "Platform lacks a sleep function."
270 #endif
271 }