]> code.delx.au - pulseaudio/blob - src/pulse/util.c
i18n: Update Russian translation
[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 char *dir;
136 #ifdef HAVE_PWD_H
137 struct passwd *r;
138 #endif
139
140 pa_assert(s);
141 pa_assert(l > 0);
142
143 if ((e = getenv("HOME"))) {
144 dir = pa_strlcpy(s, e, l);
145 goto finish;
146 }
147
148 if ((e = getenv("USERPROFILE"))) {
149 dir = pa_strlcpy(s, e, l);
150 goto finish;
151 }
152
153 #ifdef HAVE_PWD_H
154 errno = 0;
155 if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
156 if (!errno)
157 errno = ENOENT;
158
159 return NULL;
160 }
161
162 dir = pa_strlcpy(s, r->pw_dir, l);
163
164 pa_getpwuid_free(r);
165 #endif /* HAVE_PWD_H */
166
167 finish:
168 if (!dir) {
169 errno = ENOENT;
170 return NULL;
171 }
172
173 if (!pa_is_path_absolute(dir)) {
174 pa_log("Failed to get the home directory, not an absolute path: %s", dir);
175 errno = ENOENT;
176 return NULL;
177 }
178
179 return dir;
180 }
181
182 char *pa_get_binary_name(char *s, size_t l) {
183
184 pa_assert(s);
185 pa_assert(l > 0);
186
187 #if defined(OS_IS_WIN32)
188 {
189 char path[PATH_MAX];
190
191 if (GetModuleFileName(NULL, path, PATH_MAX))
192 return pa_strlcpy(s, pa_path_get_filename(path), l);
193 }
194 #endif
195
196 #ifdef __linux__
197 {
198 char *rp;
199 /* This works on Linux only */
200
201 if ((rp = pa_readlink("/proc/self/exe"))) {
202 pa_strlcpy(s, pa_path_get_filename(rp), l);
203 pa_xfree(rp);
204 return s;
205 }
206 }
207 #endif
208
209 #ifdef __FreeBSD__
210 {
211 char *rp;
212
213 if ((rp = pa_readlink("/proc/curproc/file"))) {
214 pa_strlcpy(s, pa_path_get_filename(rp), l);
215 pa_xfree(rp);
216 return s;
217 }
218 }
219 #endif
220
221 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
222 {
223
224 #ifndef TASK_COMM_LEN
225 /* Actually defined in linux/sched.h */
226 #define TASK_COMM_LEN 16
227 #endif
228
229 char tcomm[TASK_COMM_LEN+1];
230 memset(tcomm, 0, sizeof(tcomm));
231
232 /* This works on Linux only */
233 if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
234 return pa_strlcpy(s, tcomm, l);
235
236 }
237 #endif
238
239 #ifdef OS_IS_DARWIN
240 {
241 int mib[] = { CTL_KERN, KERN_PROCARGS, getpid(), 0 };
242 size_t len, nmib = (sizeof(mib) / sizeof(mib[0])) - 1;
243 char *buf;
244
245 sysctl(mib, nmib, NULL, &len, NULL, 0);
246 buf = (char *) pa_xmalloc(len);
247
248 if (sysctl(mib, nmib, buf, &len, NULL, 0) == 0) {
249 pa_strlcpy(s, basename(buf), l);
250 pa_xfree(buf);
251 return s;
252 }
253
254 pa_xfree(buf);
255
256 /* fall thru */
257 }
258 #endif /* OS_IS_DARWIN */
259
260 errno = ENOENT;
261 return NULL;
262 }
263
264 char *pa_path_get_filename(const char *p) {
265 char *fn;
266
267 if (!p)
268 return NULL;
269
270 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
271 return fn+1;
272
273 return (char*) p;
274 }
275
276 char *pa_get_fqdn(char *s, size_t l) {
277 char hn[256];
278 #ifdef HAVE_GETADDRINFO
279 struct addrinfo *a, hints;
280 #endif
281
282 pa_assert(s);
283 pa_assert(l > 0);
284
285 if (!pa_get_host_name(hn, sizeof(hn)))
286 return NULL;
287
288 #ifdef HAVE_GETADDRINFO
289 memset(&hints, 0, sizeof(hints));
290 hints.ai_family = AF_UNSPEC;
291 hints.ai_flags = AI_CANONNAME;
292
293 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
294 return pa_strlcpy(s, hn, l);
295
296 pa_strlcpy(s, a->ai_canonname, l);
297 freeaddrinfo(a);
298 return s;
299 #else
300 return pa_strlcpy(s, hn, l);
301 #endif
302 }
303
304 int pa_msleep(unsigned long t) {
305 #ifdef OS_IS_WIN32
306 Sleep(t);
307 return 0;
308 #elif defined(HAVE_NANOSLEEP)
309 struct timespec ts;
310
311 ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC);
312 ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC);
313
314 return nanosleep(&ts, NULL);
315 #else
316 #error "Platform lacks a sleep function."
317 #endif
318 }