]> code.delx.au - pulseaudio/blob - src/pulse/util.c
48ccf2951beef152bacb3b507f03613e20e1bfe0
[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_NETDB_H
41 #include <netdb.h>
42 #endif
43
44 #ifdef HAVE_WINDOWS_H
45 #include <windows.h>
46 #endif
47
48 #ifdef HAVE_SYS_PRCTL_H
49 #include <sys/prctl.h>
50 #endif
51
52 #ifdef OS_IS_DARWIN
53 #include <libgen.h>
54 #include <sys/sysctl.h>
55 #endif
56
57 #include <pulse/xmalloc.h>
58 #include <pulse/timeval.h>
59
60 #include <pulsecore/socket.h>
61 #include <pulsecore/core-error.h>
62 #include <pulsecore/log.h>
63 #include <pulsecore/core-util.h>
64 #include <pulsecore/macro.h>
65 #include <pulsecore/usergroup.h>
66
67 #include "util.h"
68
69 char *pa_get_user_name(char *s, size_t l) {
70 const char *p;
71 char *name = NULL;
72 #ifdef OS_IS_WIN32
73 char buf[1024];
74 #endif
75
76 #ifdef HAVE_PWD_H
77 struct passwd *r;
78 #endif
79
80 pa_assert(s);
81 pa_assert(l > 0);
82
83 p = NULL;
84 #ifdef HAVE_GETUID
85 p = getuid() == 0 ? "root" : NULL;
86 #endif
87 if (!p) p = getenv("USER");
88 if (!p) p = getenv("LOGNAME");
89 if (!p) p = getenv("USERNAME");
90
91 if (p) {
92 name = pa_strlcpy(s, p, l);
93 } else {
94 #ifdef HAVE_PWD_H
95
96 if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
97 pa_snprintf(s, l, "%lu", (unsigned long) getuid());
98 return s;
99 }
100
101 name = pa_strlcpy(s, r->pw_name, l);
102 pa_getpwuid_free(r);
103
104 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
105 DWORD size = sizeof(buf);
106
107 if (!GetUserName(buf, &size)) {
108 errno = ENOENT;
109 return NULL;
110 }
111
112 name = pa_strlcpy(s, buf, l);
113
114 #else /* HAVE_PWD_H */
115
116 return NULL;
117 #endif /* HAVE_PWD_H */
118 }
119
120 return name;
121 }
122
123 char *pa_get_host_name(char *s, size_t l) {
124
125 pa_assert(s);
126 pa_assert(l > 0);
127
128 if (gethostname(s, l) < 0)
129 return NULL;
130
131 s[l-1] = 0;
132 return s;
133 }
134
135 char *pa_get_home_dir(char *s, size_t l) {
136 char *e, *dir;
137
138 #ifdef HAVE_PWD_H
139 struct passwd *r;
140 #endif
141
142 pa_assert(s);
143 pa_assert(l > 0);
144
145 if ((e = getenv("HOME")))
146 return pa_strlcpy(s, e, l);
147
148 if ((e = getenv("USERPROFILE")))
149 return pa_strlcpy(s, e, l);
150
151 #ifdef HAVE_PWD_H
152 errno = 0;
153 if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
154 if (!errno)
155 errno = ENOENT;
156
157 return NULL;
158 }
159
160 dir = pa_strlcpy(s, r->pw_dir, l);
161
162 pa_getpwuid_free(r);
163
164 return dir;
165 #else /* HAVE_PWD_H */
166
167 errno = ENOENT;
168 return NULL;
169 #endif
170 }
171
172 char *pa_get_binary_name(char *s, size_t l) {
173
174 pa_assert(s);
175 pa_assert(l > 0);
176
177 #if defined(OS_IS_WIN32)
178 {
179 char path[PATH_MAX];
180
181 if (GetModuleFileName(NULL, path, PATH_MAX))
182 return pa_strlcpy(s, pa_path_get_filename(path), l);
183 }
184 #endif
185
186 #ifdef __linux__
187 {
188 char *rp;
189 /* This works on Linux only */
190
191 if ((rp = pa_readlink("/proc/self/exe"))) {
192 pa_strlcpy(s, pa_path_get_filename(rp), l);
193 pa_xfree(rp);
194 return s;
195 }
196 }
197 #endif
198
199 #ifdef __FreeBSD__
200 {
201 char *rp;
202
203 if ((rp = pa_readlink("/proc/curproc/file"))) {
204 pa_strlcpy(s, pa_path_get_filename(rp), l);
205 pa_xfree(rp);
206 return s;
207 }
208 }
209 #endif
210
211 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
212 {
213
214 #ifndef TASK_COMM_LEN
215 /* Actually defined in linux/sched.h */
216 #define TASK_COMM_LEN 16
217 #endif
218
219 char tcomm[TASK_COMM_LEN+1];
220 memset(tcomm, 0, sizeof(tcomm));
221
222 /* This works on Linux only */
223 if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
224 return pa_strlcpy(s, tcomm, l);
225
226 }
227 #endif
228
229 #ifdef OS_IS_DARWIN
230 {
231 int mib[] = { CTL_KERN, KERN_PROCARGS, getpid(), 0 };
232 size_t len, nmib = (sizeof(mib) / sizeof(mib[0])) - 1;
233 char *buf;
234
235 sysctl(mib, nmib, NULL, &len, NULL, 0);
236 buf = (char *) pa_xmalloc(len);
237
238 if (sysctl(mib, nmib, buf, &len, NULL, 0) == 0) {
239 pa_strlcpy(s, basename(buf), l);
240 pa_xfree(buf);
241 return s;
242 }
243
244 pa_xfree(buf);
245
246 /* fall thru */
247 }
248 #endif /* OS_IS_DARWIN */
249
250 errno = ENOENT;
251 return NULL;
252 }
253
254 char *pa_path_get_filename(const char *p) {
255 char *fn;
256
257 if (!p)
258 return NULL;
259
260 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
261 return fn+1;
262
263 return (char*) p;
264 }
265
266 char *pa_get_fqdn(char *s, size_t l) {
267 char hn[256];
268 #ifdef HAVE_GETADDRINFO
269 struct addrinfo *a, hints;
270 #endif
271
272 pa_assert(s);
273 pa_assert(l > 0);
274
275 if (!pa_get_host_name(hn, sizeof(hn)))
276 return NULL;
277
278 #ifdef HAVE_GETADDRINFO
279 memset(&hints, 0, sizeof(hints));
280 hints.ai_family = AF_UNSPEC;
281 hints.ai_flags = AI_CANONNAME;
282
283 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
284 return pa_strlcpy(s, hn, l);
285
286 pa_strlcpy(s, a->ai_canonname, l);
287 freeaddrinfo(a);
288 return s;
289 #else
290 return pa_strlcpy(s, hn, l);
291 #endif
292 }
293
294 int pa_msleep(unsigned long t) {
295 #ifdef OS_IS_WIN32
296 Sleep(t);
297 return 0;
298 #elif defined(HAVE_NANOSLEEP)
299 struct timespec ts;
300
301 ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC);
302 ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC);
303
304 return nanosleep(&ts, NULL);
305 #else
306 #error "Platform lacks a sleep function."
307 #endif
308 }