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