]> code.delx.au - pulseaudio/blob - src/pulse/util.c
Merge remote branch 'tanuk/master'
[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 #endif
193
194 #ifdef __FreeBSD__
195 {
196 char *rp;
197
198 if ((rp = pa_readlink("/proc/curproc/file"))) {
199 pa_strlcpy(s, pa_path_get_filename(rp), l);
200 pa_xfree(rp);
201 return s;
202 }
203 }
204 #endif
205
206 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
207 {
208
209 #ifndef TASK_COMM_LEN
210 /* Actually defined in linux/sched.h */
211 #define TASK_COMM_LEN 16
212 #endif
213
214 char tcomm[TASK_COMM_LEN+1];
215 memset(tcomm, 0, sizeof(tcomm));
216
217 /* This works on Linux only */
218 if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
219 return pa_strlcpy(s, tcomm, l);
220
221 }
222 #endif
223
224 errno = ENOENT;
225 return NULL;
226 }
227
228 char *pa_path_get_filename(const char *p) {
229 char *fn;
230
231 if (!p)
232 return NULL;
233
234 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
235 return fn+1;
236
237 return (char*) p;
238 }
239
240 char *pa_get_fqdn(char *s, size_t l) {
241 char hn[256];
242 #ifdef HAVE_GETADDRINFO
243 struct addrinfo *a, hints;
244 #endif
245
246 pa_assert(s);
247 pa_assert(l > 0);
248
249 if (!pa_get_host_name(hn, sizeof(hn)))
250 return NULL;
251
252 #ifdef HAVE_GETADDRINFO
253 memset(&hints, 0, sizeof(hints));
254 hints.ai_family = AF_UNSPEC;
255 hints.ai_flags = AI_CANONNAME;
256
257 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
258 return pa_strlcpy(s, hn, l);
259
260 pa_strlcpy(s, a->ai_canonname, l);
261 freeaddrinfo(a);
262 return s;
263 #else
264 return pa_strlcpy(s, hn, l);
265 #endif
266 }
267
268 int pa_msleep(unsigned long t) {
269 #ifdef OS_IS_WIN32
270 Sleep(t);
271 return 0;
272 #elif defined(HAVE_NANOSLEEP)
273 struct timespec ts;
274
275 ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC);
276 ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC);
277
278 return nanosleep(&ts, NULL);
279 #else
280 #error "Platform lacks a sleep function."
281 #endif
282 }