Merge commit 'origin/master-tx'
[profile/ivi/pulseaudio.git] / src / pulsecore / core-util.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2006 Lennart Poettering
5   Copyright 2004 Joe Marcus Clarke
6   Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
7
8   PulseAudio is free software; you can redistribute it and/or modify
9   it under the terms of the GNU Lesser General Public License as
10   published by the Free Software Foundation; either version 2.1 of the
11   License, or (at your option) any later version.
12
13   PulseAudio is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public
19   License along with PulseAudio; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21   USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <signal.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <limits.h>
37 #include <time.h>
38 #include <ctype.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/time.h>
42 #include <dirent.h>
43 #include <regex.h>
44 #include <langinfo.h>
45 #include <sys/utsname.h>
46
47 #ifdef HAVE_STRTOF_L
48 #include <locale.h>
49 #endif
50
51 #ifdef HAVE_SCHED_H
52 #include <sched.h>
53 #endif
54
55 #ifdef HAVE_SYS_RESOURCE_H
56 #include <sys/resource.h>
57 #endif
58
59 #ifdef HAVE_SYS_CAPABILITY_H
60 #include <sys/capability.h>
61 #endif
62
63 #ifdef HAVE_SYS_MMAN_H
64 #include <sys/mman.h>
65 #endif
66
67 #ifdef HAVE_PTHREAD
68 #include <pthread.h>
69 #endif
70
71 #ifdef HAVE_NETDB_H
72 #include <netdb.h>
73 #endif
74
75 #ifdef HAVE_WINDOWS_H
76 #include <windows.h>
77 #endif
78
79 #ifdef HAVE_PWD_H
80 #include <pwd.h>
81 #endif
82
83 #ifdef HAVE_GRP_H
84 #include <grp.h>
85 #endif
86
87 #ifdef HAVE_LIBSAMPLERATE
88 #include <samplerate.h>
89 #endif
90
91 #ifdef __APPLE__
92 #include <xlocale.h>
93 #endif
94
95 #include <pulse/xmalloc.h>
96 #include <pulse/util.h>
97 #include <pulse/utf8.h>
98
99 #include <pulsecore/core-error.h>
100 #include <pulsecore/winsock.h>
101 #include <pulsecore/log.h>
102 #include <pulsecore/macro.h>
103 #include <pulsecore/thread.h>
104 #include <pulsecore/strbuf.h>
105
106 #include "core-util.h"
107
108 /* Not all platforms have this */
109 #ifndef MSG_NOSIGNAL
110 #define MSG_NOSIGNAL 0
111 #endif
112
113 #ifdef OS_IS_WIN32
114
115 #define PULSE_ROOTENV "PULSE_ROOT"
116
117 int pa_set_root(HANDLE handle) {
118     char library_path[MAX_PATH + sizeof(PULSE_ROOTENV) + 1], *sep;
119
120     strcpy(library_path, PULSE_ROOTENV "=");
121
122     /* FIXME: Needs to set errno */
123
124     if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH))
125         return 0;
126
127     sep = strrchr(library_path, PA_PATH_SEP_CHAR);
128     if (sep)
129         *sep = '\0';
130
131     if (_putenv(library_path) < 0)
132         return 0;
133
134     return 1;
135 }
136
137 #endif
138
139 /** Make a file descriptor nonblock. Doesn't do any error checking */
140 void pa_make_fd_nonblock(int fd) {
141
142 #ifdef O_NONBLOCK
143     int v;
144     pa_assert(fd >= 0);
145
146     pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
147
148     if (!(v & O_NONBLOCK))
149         pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
150
151 #elif defined(OS_IS_WIN32)
152     u_long arg = 1;
153     if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
154         pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
155         pa_log_warn("Only sockets can be made non-blocking!");
156     }
157 #else
158     pa_log_warn("Non-blocking I/O not supported.!");
159 #endif
160
161 }
162
163 /* Set the FD_CLOEXEC flag for a fd */
164 void pa_make_fd_cloexec(int fd) {
165
166 #ifdef FD_CLOEXEC
167     int v;
168     pa_assert(fd >= 0);
169
170     pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0);
171
172     if (!(v & FD_CLOEXEC))
173         pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0);
174 #endif
175
176 }
177
178 /** Creates a directory securely */
179 int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
180     struct stat st;
181     int r, saved_errno;
182
183     pa_assert(dir);
184
185 #ifdef OS_IS_WIN32
186     r = mkdir(dir);
187 #else
188     {
189     mode_t u;
190     u = umask((~m) & 0777);
191     r = mkdir(dir, m);
192     umask(u);
193     }
194 #endif
195
196     if (r < 0 && errno != EEXIST)
197         return -1;
198
199 #ifdef HAVE_CHOWN
200     if (uid == (uid_t)-1)
201         uid = getuid();
202     if (gid == (gid_t)-1)
203         gid = getgid();
204     (void) chown(dir, uid, gid);
205 #endif
206
207 #ifdef HAVE_CHMOD
208     chmod(dir, m);
209 #endif
210
211 #ifdef HAVE_LSTAT
212     if (lstat(dir, &st) < 0)
213 #else
214     if (stat(dir, &st) < 0)
215 #endif
216         goto fail;
217
218 #ifndef OS_IS_WIN32
219     if (!S_ISDIR(st.st_mode) ||
220         (st.st_uid != uid) ||
221         (st.st_gid != gid) ||
222         ((st.st_mode & 0777) != m)) {
223         errno = EACCES;
224         goto fail;
225     }
226 #else
227     pa_log_warn("Secure directory creation not supported on Win32.");
228 #endif
229
230     return 0;
231
232 fail:
233     saved_errno = errno;
234     rmdir(dir);
235     errno = saved_errno;
236
237     return -1;
238 }
239
240 /* Return a newly allocated sting containing the parent directory of the specified file */
241 char *pa_parent_dir(const char *fn) {
242     char *slash, *dir = pa_xstrdup(fn);
243
244     if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
245         pa_xfree(dir);
246         errno = ENOENT;
247         return NULL;
248     }
249
250     *(slash-1) = 0;
251     return dir;
252 }
253
254 /* Creates a the parent directory of the specified path securely */
255 int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
256     int ret = -1;
257     char *dir;
258
259     if (!(dir = pa_parent_dir(fn)))
260         goto finish;
261
262     if (pa_make_secure_dir(dir, m, uid, gid) < 0)
263         goto finish;
264
265     ret = 0;
266
267 finish:
268     pa_xfree(dir);
269     return ret;
270 }
271
272 /** Platform independent read function. Necessary since not all
273  * systems treat all file descriptors equal. If type is
274  * non-NULL it is used to cache the type of the fd. This is
275  * useful for making sure that only a single syscall is executed per
276  * function call. The variable pointed to should be initialized to 0
277  * by the caller. */
278 ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
279
280 #ifdef OS_IS_WIN32
281
282     if (!type || *type == 0) {
283         ssize_t r;
284
285         if ((r = recv(fd, buf, count, 0)) >= 0)
286             return r;
287
288         if (WSAGetLastError() != WSAENOTSOCK) {
289             errno = WSAGetLastError();
290             return r;
291         }
292
293         if (type)
294             *type = 1;
295     }
296
297 #endif
298
299     return read(fd, buf, count);
300 }
301
302 /** Similar to pa_read(), but handles writes */
303 ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
304
305     if (!type || *type == 0) {
306         ssize_t r;
307
308         if ((r = send(fd, buf, count, MSG_NOSIGNAL)) >= 0)
309             return r;
310
311 #ifdef OS_IS_WIN32
312         if (WSAGetLastError() != WSAENOTSOCK) {
313             errno = WSAGetLastError();
314             return r;
315         }
316 #else
317         if (errno != ENOTSOCK)
318             return r;
319 #endif
320
321         if (type)
322             *type = 1;
323     }
324
325     return write(fd, buf, count);
326 }
327
328 /** Calls read() in a loop. Makes sure that as much as 'size' bytes,
329  * unless EOF is reached or an error occurred */
330 ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
331     ssize_t ret = 0;
332     int _type;
333
334     pa_assert(fd >= 0);
335     pa_assert(data);
336     pa_assert(size);
337
338     if (!type) {
339         _type = 0;
340         type = &_type;
341     }
342
343     while (size > 0) {
344         ssize_t r;
345
346         if ((r = pa_read(fd, data, size, type)) < 0)
347             return r;
348
349         if (r == 0)
350             break;
351
352         ret += r;
353         data = (uint8_t*) data + r;
354         size -= (size_t) r;
355     }
356
357     return ret;
358 }
359
360 /** Similar to pa_loop_read(), but wraps write() */
361 ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
362     ssize_t ret = 0;
363     int _type;
364
365     pa_assert(fd >= 0);
366     pa_assert(data);
367     pa_assert(size);
368
369     if (!type) {
370         _type = 0;
371         type = &_type;
372     }
373
374     while (size > 0) {
375         ssize_t r;
376
377         if ((r = pa_write(fd, data, size, type)) < 0)
378             return r;
379
380         if (r == 0)
381             break;
382
383         ret += r;
384         data = (const uint8_t*) data + r;
385         size -= (size_t) r;
386     }
387
388     return ret;
389 }
390
391 /** Platform independent read function. Necessary since not all
392  * systems treat all file descriptors equal. */
393 int pa_close(int fd) {
394
395 #ifdef OS_IS_WIN32
396     int ret;
397
398     if ((ret = closesocket(fd)) == 0)
399         return 0;
400
401     if (WSAGetLastError() != WSAENOTSOCK) {
402         errno = WSAGetLastError();
403         return ret;
404     }
405 #endif
406
407     for (;;) {
408         int r;
409
410         if ((r = close(fd)) >= 0)
411             return r;
412
413         if (errno != EINTR)
414             return r;
415     }
416 }
417
418 /* Print a warning messages in case that the given signal is not
419  * blocked or trapped */
420 void pa_check_signal_is_blocked(int sig) {
421 #ifdef HAVE_SIGACTION
422     struct sigaction sa;
423     sigset_t set;
424
425     /* If POSIX threads are supported use thread-aware
426      * pthread_sigmask() function, to check if the signal is
427      * blocked. Otherwise fall back to sigprocmask() */
428
429 #ifdef HAVE_PTHREAD
430     if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) {
431 #endif
432         if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) {
433             pa_log("sigprocmask(): %s", pa_cstrerror(errno));
434             return;
435         }
436 #ifdef HAVE_PTHREAD
437     }
438 #endif
439
440     if (sigismember(&set, sig))
441         return;
442
443     /* Check whether the signal is trapped */
444
445     if (sigaction(sig, NULL, &sa) < 0) {
446         pa_log("sigaction(): %s", pa_cstrerror(errno));
447         return;
448     }
449
450     if (sa.sa_handler != SIG_DFL)
451         return;
452
453     pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig));
454 #else /* HAVE_SIGACTION */
455     pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig));
456 #endif
457 }
458
459 /* The following function is based on an example from the GNU libc
460  * documentation. This function is similar to GNU's asprintf(). */
461 char *pa_sprintf_malloc(const char *format, ...) {
462     size_t  size = 100;
463     char *c = NULL;
464
465     pa_assert(format);
466
467     for(;;) {
468         int r;
469         va_list ap;
470
471         c = pa_xrealloc(c, size);
472
473         va_start(ap, format);
474         r = vsnprintf(c, size, format, ap);
475         va_end(ap);
476
477         c[size-1] = 0;
478
479         if (r > -1 && (size_t) r < size)
480             return c;
481
482         if (r > -1)    /* glibc 2.1 */
483             size = (size_t) r+1;
484         else           /* glibc 2.0 */
485             size *= 2;
486     }
487 }
488
489 /* Same as the previous function, but use a va_list instead of an
490  * ellipsis */
491 char *pa_vsprintf_malloc(const char *format, va_list ap) {
492     size_t  size = 100;
493     char *c = NULL;
494
495     pa_assert(format);
496
497     for(;;) {
498         int r;
499         va_list aq;
500
501         c = pa_xrealloc(c, size);
502
503         va_copy(aq, ap);
504         r = vsnprintf(c, size, format, aq);
505         va_end(aq);
506
507         c[size-1] = 0;
508
509         if (r > -1 && (size_t) r < size)
510             return c;
511
512         if (r > -1)    /* glibc 2.1 */
513             size = (size_t) r+1;
514         else           /* glibc 2.0 */
515             size *= 2;
516     }
517 }
518
519 /* Similar to OpenBSD's strlcpy() function */
520 char *pa_strlcpy(char *b, const char *s, size_t l) {
521     pa_assert(b);
522     pa_assert(s);
523     pa_assert(l > 0);
524
525     strncpy(b, s, l);
526     b[l-1] = 0;
527     return b;
528 }
529
530 /* Make the current thread a realtime thread, and acquire the highest
531  * rtprio we can get that is less or equal the specified parameter. If
532  * the thread is already realtime, don't do anything. */
533 int pa_make_realtime(int rtprio) {
534
535 #ifdef _POSIX_PRIORITY_SCHEDULING
536     struct sched_param sp;
537     int r, policy;
538
539     memset(&sp, 0, sizeof(sp));
540     policy = 0;
541
542     if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) {
543         pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r));
544         return -1;
545     }
546
547     if (policy == SCHED_FIFO && sp.sched_priority >= rtprio) {
548         pa_log_info("Thread already being scheduled with SCHED_FIFO with priority %i.", sp.sched_priority);
549         return 0;
550     }
551
552     sp.sched_priority = rtprio;
553     if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0) {
554
555         while (sp.sched_priority > 1) {
556             sp.sched_priority --;
557
558             if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) == 0) {
559                 pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i, which is lower than the requested %i.", sp.sched_priority, rtprio);
560                 return 0;
561             }
562         }
563
564         pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r));
565         return -1;
566     }
567
568     pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority);
569     return 0;
570 #else
571
572     errno = ENOTSUP;
573     return -1;
574 #endif
575 }
576
577 /* This is merely used for giving the user a hint. This is not correct
578  * for anything security related */
579 pa_bool_t pa_can_realtime(void) {
580
581     if (geteuid() == 0)
582         return TRUE;
583
584 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
585     {
586         struct rlimit rl;
587
588         if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0)
589             if (rl.rlim_cur > 0 || rl.rlim_cur == RLIM_INFINITY)
590                 return TRUE;
591     }
592 #endif
593
594 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
595     {
596         cap_t cap;
597
598         if ((cap = cap_get_proc())) {
599             cap_flag_value_t flag = CAP_CLEAR;
600
601             if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
602                 if (flag == CAP_SET) {
603                     cap_free(cap);
604                     return TRUE;
605                 }
606
607             cap_free(cap);
608         }
609     }
610 #endif
611
612     return FALSE;
613 }
614
615 /* This is merely used for giving the user a hint. This is not correct
616  * for anything security related */
617 pa_bool_t pa_can_high_priority(void) {
618
619     if (geteuid() == 0)
620         return TRUE;
621
622 #if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
623     {
624         struct rlimit rl;
625
626         if (getrlimit(RLIMIT_NICE, &rl) >= 0)
627             if (rl.rlim_cur >= 21 || rl.rlim_cur == RLIM_INFINITY)
628                 return TRUE;
629     }
630 #endif
631
632 #if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
633     {
634         cap_t cap;
635
636         if ((cap = cap_get_proc())) {
637             cap_flag_value_t flag = CAP_CLEAR;
638
639             if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
640                 if (flag == CAP_SET) {
641                     cap_free(cap);
642                     return TRUE;
643                 }
644
645             cap_free(cap);
646         }
647     }
648 #endif
649
650     return FALSE;
651 }
652
653 /* Raise the priority of the current process as much as possible that
654  * is <= the specified nice level..*/
655 int pa_raise_priority(int nice_level) {
656
657 #ifdef HAVE_SYS_RESOURCE_H
658     if (setpriority(PRIO_PROCESS, 0, nice_level) < 0) {
659         int n;
660
661         for (n = nice_level+1; n < 0; n++) {
662
663             if (setpriority(PRIO_PROCESS, 0, n) == 0) {
664                 pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
665                 return 0;
666             }
667         }
668
669         pa_log_warn("setpriority(): %s", pa_cstrerror(errno));
670         return -1;
671     }
672
673     pa_log_info("Successfully gained nice level %i.", nice_level);
674 #endif
675
676 #ifdef OS_IS_WIN32
677     if (nice_level < 0) {
678         if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
679             pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
680             errno = EPERM;
681             return .-1;
682         } else
683             pa_log_info("Successfully gained high priority class.");
684     }
685 #endif
686
687     return 0;
688 }
689
690 /* Reset the priority to normal, inverting the changes made by
691  * pa_raise_priority() and pa_make_realtime()*/
692 void pa_reset_priority(void) {
693 #ifdef HAVE_SYS_RESOURCE_H
694     struct sched_param sp;
695
696     setpriority(PRIO_PROCESS, 0, 0);
697
698     memset(&sp, 0, sizeof(sp));
699     pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp) == 0);
700 #endif
701
702 #ifdef OS_IS_WIN32
703     SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
704 #endif
705 }
706
707 int pa_match(const char *expr, const char *v) {
708     int k;
709     regex_t re;
710     int r;
711
712     if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
713         errno = EINVAL;
714         return -1;
715     }
716
717     if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
718         r = 1;
719     else if (k == REG_NOMATCH)
720         r = 0;
721     else
722         r = -1;
723
724     regfree(&re);
725
726     if (r < 0)
727         errno = EINVAL;
728
729     return r;
730 }
731
732 /* Try to parse a boolean string value.*/
733 int pa_parse_boolean(const char *v) {
734     const char *expr;
735     int r;
736     pa_assert(v);
737
738     /* First we check language independant */
739     if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
740         return 1;
741     else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
742         return 0;
743
744     /* And then we check language dependant */
745     if ((expr = nl_langinfo(YESEXPR)))
746         if (expr[0])
747             if ((r = pa_match(expr, v)) > 0)
748                 return 1;
749
750     if ((expr = nl_langinfo(NOEXPR)))
751         if (expr[0])
752             if ((r = pa_match(expr, v)) > 0)
753                 return 0;
754
755     errno = EINVAL;
756     return -1;
757 }
758
759 /* Split the specified string wherever one of the strings in delimiter
760  * occurs. Each time it is called returns a newly allocated string
761  * with pa_xmalloc(). The variable state points to, should be
762  * initiallized to NULL before the first call. */
763 char *pa_split(const char *c, const char *delimiter, const char**state) {
764     const char *current = *state ? *state : c;
765     size_t l;
766
767     if (!*current)
768         return NULL;
769
770     l = strcspn(current, delimiter);
771     *state = current+l;
772
773     if (**state)
774         (*state)++;
775
776     return pa_xstrndup(current, l);
777 }
778
779 /* What is interpreted as whitespace? */
780 #define WHITESPACE " \t\n"
781
782 /* Split a string into words. Otherwise similar to pa_split(). */
783 char *pa_split_spaces(const char *c, const char **state) {
784     const char *current = *state ? *state : c;
785     size_t l;
786
787     if (!*current || *c == 0)
788         return NULL;
789
790     current += strspn(current, WHITESPACE);
791     l = strcspn(current, WHITESPACE);
792
793     *state = current+l;
794
795     return pa_xstrndup(current, l);
796 }
797
798 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
799
800 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
801 const char *pa_sig2str(int sig) {
802     char *t;
803
804     if (sig <= 0)
805         goto fail;
806
807 #ifdef NSIG
808     if (sig >= NSIG)
809         goto fail;
810 #endif
811
812 #ifdef HAVE_SIG2STR
813     {
814         char buf[SIG2STR_MAX];
815
816         if (sig2str(sig, buf) == 0) {
817             pa_xfree(PA_STATIC_TLS_GET(signame));
818             t = pa_sprintf_malloc("SIG%s", buf);
819             PA_STATIC_TLS_SET(signame, t);
820             return t;
821         }
822     }
823 #else
824
825     switch(sig) {
826 #ifdef SIGHUP
827         case SIGHUP:    return "SIGHUP";
828 #endif
829         case SIGINT:    return "SIGINT";
830 #ifdef SIGQUIT
831         case SIGQUIT:   return "SIGQUIT";
832 #endif
833         case SIGILL:    return "SIGULL";
834 #ifdef SIGTRAP
835         case SIGTRAP:   return "SIGTRAP";
836 #endif
837         case SIGABRT:   return "SIGABRT";
838 #ifdef SIGBUS
839         case SIGBUS:    return "SIGBUS";
840 #endif
841         case SIGFPE:    return "SIGFPE";
842 #ifdef SIGKILL
843         case SIGKILL:   return "SIGKILL";
844 #endif
845 #ifdef SIGUSR1
846         case SIGUSR1:   return "SIGUSR1";
847 #endif
848         case SIGSEGV:   return "SIGSEGV";
849 #ifdef SIGUSR2
850         case SIGUSR2:   return "SIGUSR2";
851 #endif
852 #ifdef SIGPIPE
853         case SIGPIPE:   return "SIGPIPE";
854 #endif
855 #ifdef SIGALRM
856         case SIGALRM:   return "SIGALRM";
857 #endif
858         case SIGTERM:   return "SIGTERM";
859 #ifdef SIGSTKFLT
860         case SIGSTKFLT: return "SIGSTKFLT";
861 #endif
862 #ifdef SIGCHLD
863         case SIGCHLD:   return "SIGCHLD";
864 #endif
865 #ifdef SIGCONT
866         case SIGCONT:   return "SIGCONT";
867 #endif
868 #ifdef SIGSTOP
869         case SIGSTOP:   return "SIGSTOP";
870 #endif
871 #ifdef SIGTSTP
872         case SIGTSTP:   return "SIGTSTP";
873 #endif
874 #ifdef SIGTTIN
875         case SIGTTIN:   return "SIGTTIN";
876 #endif
877 #ifdef SIGTTOU
878         case SIGTTOU:   return "SIGTTOU";
879 #endif
880 #ifdef SIGURG
881         case SIGURG:    return "SIGURG";
882 #endif
883 #ifdef SIGXCPU
884         case SIGXCPU:   return "SIGXCPU";
885 #endif
886 #ifdef SIGXFSZ
887         case SIGXFSZ:   return "SIGXFSZ";
888 #endif
889 #ifdef SIGVTALRM
890         case SIGVTALRM: return "SIGVTALRM";
891 #endif
892 #ifdef SIGPROF
893         case SIGPROF:   return "SIGPROF";
894 #endif
895 #ifdef SIGWINCH
896         case SIGWINCH:  return "SIGWINCH";
897 #endif
898 #ifdef SIGIO
899         case SIGIO:     return "SIGIO";
900 #endif
901 #ifdef SIGPWR
902         case SIGPWR:    return "SIGPWR";
903 #endif
904 #ifdef SIGSYS
905         case SIGSYS:    return "SIGSYS";
906 #endif
907     }
908
909 #ifdef SIGRTMIN
910     if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
911         pa_xfree(PA_STATIC_TLS_GET(signame));
912         t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN);
913         PA_STATIC_TLS_SET(signame, t);
914         return t;
915     }
916 #endif
917
918 #endif
919
920 fail:
921
922     pa_xfree(PA_STATIC_TLS_GET(signame));
923     t = pa_sprintf_malloc("SIG%i", sig);
924     PA_STATIC_TLS_SET(signame, t);
925     return t;
926 }
927
928 #ifdef HAVE_GRP_H
929
930 /* Check whether the specified GID and the group name match */
931 static int is_group(gid_t gid, const char *name) {
932     struct group group, *result = NULL;
933     long n;
934     void *data;
935     int r = -1;
936
937 #ifdef HAVE_GETGRGID_R
938 #ifdef _SC_GETGR_R_SIZE_MAX
939     n = sysconf(_SC_GETGR_R_SIZE_MAX);
940 #else
941     n = -1;
942 #endif
943     if (n <= 0)
944         n = 512;
945
946     data = pa_xmalloc((size_t) n);
947
948     errno = 0;
949     if (getgrgid_r(gid, &group, data, (size_t) n, &result) < 0 || !result) {
950         pa_log("getgrgid_r(%u): %s", (unsigned) gid, pa_cstrerror(errno));
951
952         if (!errno)
953             errno = ENOENT;
954
955         goto finish;
956     }
957
958     r = strcmp(name, result->gr_name) == 0;
959
960 finish:
961     pa_xfree(data);
962 #else
963     /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not
964      * support getgrgid_r. */
965
966     errno = 0;
967     if (!(result = getgrgid(gid))) {
968         pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
969
970         if (!errno)
971             errno = ENOENT;
972
973         goto finish;
974     }
975
976     r = strcmp(name, result->gr_name) == 0;
977
978 finish:
979 #endif
980
981     return r;
982 }
983
984 /* Check the current user is member of the specified group */
985 int pa_own_uid_in_group(const char *name, gid_t *gid) {
986     GETGROUPS_T *gids, tgid;
987     long n = sysconf(_SC_NGROUPS_MAX);
988     int r = -1, i, k;
989
990     pa_assert(n > 0);
991
992     gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
993
994     if ((n = getgroups((int) n, gids)) < 0) {
995         pa_log("getgroups(): %s", pa_cstrerror(errno));
996         goto finish;
997     }
998
999     for (i = 0; i < n; i++) {
1000
1001         if ((k = is_group(gids[i], name)) < 0)
1002             goto finish;
1003         else if (k > 0) {
1004             *gid = gids[i];
1005             r = 1;
1006             goto finish;
1007         }
1008     }
1009
1010     if ((k = is_group(tgid = getgid(), name)) < 0)
1011         goto finish;
1012     else if (k > 0) {
1013         *gid = tgid;
1014         r = 1;
1015         goto finish;
1016     }
1017
1018     r = 0;
1019
1020 finish:
1021
1022     pa_xfree(gids);
1023     return r;
1024 }
1025
1026 /* Check whether the specifc user id is a member of the specified group */
1027 int pa_uid_in_group(uid_t uid, const char *name) {
1028     char *g_buf, *p_buf;
1029     long g_n, p_n;
1030     struct group grbuf, *gr;
1031     char **i;
1032     int r = -1;
1033
1034 #ifdef _SC_GETGR_R_SIZE_MAX
1035     g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
1036 #else
1037     g_n = -1;
1038 #endif
1039     if (g_n <= 0)
1040         g_n = 512;
1041
1042     g_buf = pa_xmalloc((size_t) g_n);
1043
1044 #ifdef _SC_GETPW_R_SIZE_MAX
1045     p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
1046 #else
1047     p_n = -1;
1048 #endif
1049     if (p_n <= 0)
1050         p_n = 512;
1051
1052     p_buf = pa_xmalloc((size_t) p_n);
1053
1054     errno = 0;
1055 #ifdef HAVE_GETGRNAM_R
1056     if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
1057 #else
1058     if (!(gr = getgrnam(name)))
1059 #endif
1060     {
1061         if (!errno)
1062             errno = ENOENT;
1063         goto finish;
1064     }
1065
1066     r = 0;
1067     for (i = gr->gr_mem; *i; i++) {
1068         struct passwd pwbuf, *pw;
1069
1070 #ifdef HAVE_GETPWNAM_R
1071         if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw)
1072 #else
1073         if (!(pw = getpwnam(*i)))
1074 #endif
1075             continue;
1076
1077         if (pw->pw_uid == uid) {
1078             r = 1;
1079             break;
1080         }
1081     }
1082
1083 finish:
1084     pa_xfree(g_buf);
1085     pa_xfree(p_buf);
1086
1087     return r;
1088 }
1089
1090 /* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
1091 gid_t pa_get_gid_of_group(const char *name) {
1092     gid_t ret = (gid_t) -1;
1093     char *g_buf;
1094     long g_n;
1095     struct group grbuf, *gr;
1096
1097 #ifdef _SC_GETGR_R_SIZE_MAX
1098     g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
1099 #else
1100     g_n = -1;
1101 #endif
1102     if (g_n <= 0)
1103         g_n = 512;
1104
1105     g_buf = pa_xmalloc((size_t) g_n);
1106
1107     errno = 0;
1108 #ifdef HAVE_GETGRNAM_R
1109     if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
1110 #else
1111     if (!(gr = getgrnam(name)))
1112 #endif
1113     {
1114         if (!errno)
1115             errno = ENOENT;
1116         goto finish;
1117     }
1118
1119     ret = gr->gr_gid;
1120
1121 finish:
1122     pa_xfree(g_buf);
1123     return ret;
1124 }
1125
1126 int pa_check_in_group(gid_t g) {
1127     gid_t gids[NGROUPS_MAX];
1128     int r;
1129
1130     if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
1131         return -1;
1132
1133     for (; r > 0; r--)
1134         if (gids[r-1] == g)
1135             return 1;
1136
1137     return 0;
1138 }
1139
1140 #else /* HAVE_GRP_H */
1141
1142 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1143     errno = ENOSUP;
1144     return -1;
1145
1146 }
1147
1148 int pa_uid_in_group(uid_t uid, const char *name) {
1149     errno = ENOSUP;
1150     return -1;
1151 }
1152
1153 gid_t pa_get_gid_of_group(const char *name) {
1154     errno = ENOSUP;
1155     return (gid_t) -1;
1156 }
1157
1158 int pa_check_in_group(gid_t g) {
1159     errno = ENOSUP;
1160     return -1;
1161 }
1162
1163 #endif
1164
1165 /* Lock or unlock a file entirely.
1166   (advisory on UNIX, mandatory on Windows) */
1167 int pa_lock_fd(int fd, int b) {
1168 #ifdef F_SETLKW
1169     struct flock flock;
1170
1171     /* Try a R/W lock first */
1172
1173     flock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
1174     flock.l_whence = SEEK_SET;
1175     flock.l_start = 0;
1176     flock.l_len = 0;
1177
1178     if (fcntl(fd, F_SETLKW, &flock) >= 0)
1179         return 0;
1180
1181     /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
1182     if (b && errno == EBADF) {
1183         flock.l_type = F_RDLCK;
1184         if (fcntl(fd, F_SETLKW, &flock) >= 0)
1185             return 0;
1186     }
1187
1188     pa_log("%slock: %s", !b? "un" : "", pa_cstrerror(errno));
1189 #endif
1190
1191 #ifdef OS_IS_WIN32
1192     HANDLE h = (HANDLE)_get_osfhandle(fd);
1193
1194     if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1195         return 0;
1196     if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1197         return 0;
1198
1199     pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
1200
1201     /* FIXME: Needs to set errno! */
1202 #endif
1203
1204     return -1;
1205 }
1206
1207 /* Remove trailing newlines from a string */
1208 char* pa_strip_nl(char *s) {
1209     pa_assert(s);
1210
1211     s[strcspn(s, "\r\n")] = 0;
1212     return s;
1213 }
1214
1215 /* Create a temporary lock file and lock it. */
1216 int pa_lock_lockfile(const char *fn) {
1217     int fd = -1;
1218     pa_assert(fn);
1219
1220     for (;;) {
1221         struct stat st;
1222
1223         if ((fd = open(fn, O_CREAT|O_RDWR
1224 #ifdef O_NOCTTY
1225                        |O_NOCTTY
1226 #endif
1227 #ifdef O_NOFOLLOW
1228                        |O_NOFOLLOW
1229 #endif
1230                        , S_IRUSR|S_IWUSR)) < 0) {
1231             pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno));
1232             goto fail;
1233         }
1234
1235         if (pa_lock_fd(fd, 1) < 0) {
1236             pa_log_warn("Failed to lock file '%s'.", fn);
1237             goto fail;
1238         }
1239
1240         if (fstat(fd, &st) < 0) {
1241             pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno));
1242             goto fail;
1243         }
1244
1245         /* Check whether the file has been removed meanwhile. When yes,
1246          * restart this loop, otherwise, we're done */
1247         if (st.st_nlink >= 1)
1248             break;
1249
1250         if (pa_lock_fd(fd, 0) < 0) {
1251             pa_log_warn("Failed to unlock file '%s'.", fn);
1252             goto fail;
1253         }
1254
1255         if (pa_close(fd) < 0) {
1256             pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
1257             fd = -1;
1258             goto fail;
1259         }
1260
1261         fd = -1;
1262     }
1263
1264     return fd;
1265
1266 fail:
1267
1268     if (fd >= 0) {
1269         int saved_errno = errno;
1270         pa_close(fd);
1271         errno = saved_errno;
1272     }
1273
1274     return -1;
1275 }
1276
1277 /* Unlock a temporary lcok file */
1278 int pa_unlock_lockfile(const char *fn, int fd) {
1279     int r = 0;
1280     pa_assert(fd >= 0);
1281
1282     if (fn) {
1283         if (unlink(fn) < 0) {
1284             pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno));
1285             r = -1;
1286         }
1287     }
1288
1289     if (pa_lock_fd(fd, 0) < 0) {
1290         pa_log_warn("Failed to unlock file '%s'.", fn);
1291         r = -1;
1292     }
1293
1294     if (pa_close(fd) < 0) {
1295         pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno));
1296         r = -1;
1297     }
1298
1299     return r;
1300 }
1301
1302 static char *get_pulse_home(void) {
1303     char h[PATH_MAX];
1304     struct stat st;
1305
1306     if (!pa_get_home_dir(h, sizeof(h))) {
1307         pa_log_error("Failed to get home directory.");
1308         return NULL;
1309     }
1310
1311     if (stat(h, &st) < 0) {
1312         pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno));
1313         return NULL;
1314     }
1315
1316     if (st.st_uid != getuid()) {
1317         pa_log_error("Home directory %s not ours.", h);
1318         errno = EACCES;
1319         return NULL;
1320     }
1321
1322     return pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
1323 }
1324
1325 char *pa_get_state_dir(void) {
1326     char *d;
1327
1328     /* The state directory shall contain dynamic data that should be
1329      * kept across reboots, and is private to this user */
1330
1331     if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1332         if (!(d = get_pulse_home()))
1333             return NULL;
1334
1335     /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1336      * dir then this will break. */
1337
1338     if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0)  {
1339         pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1340         pa_xfree(d);
1341         return NULL;
1342     }
1343
1344     return d;
1345 }
1346
1347 static char* make_random_dir(mode_t m) {
1348     static const char table[] =
1349         "abcdefghijklmnopqrstuvwxyz"
1350         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1351         "0123456789";
1352
1353     const char *tmpdir;
1354     char *fn;
1355     size_t pathlen;
1356
1357     if (!(tmpdir = getenv("TMPDIR")))
1358         if (!(tmpdir = getenv("TMP")))
1359             if (!(tmpdir = getenv("TEMP")))
1360                 tmpdir = getenv("TEMPDIR");
1361
1362     if (!tmpdir || !pa_is_path_absolute(tmpdir))
1363         tmpdir = "/tmp";
1364
1365     fn = pa_sprintf_malloc("%s/pulse-XXXXXXXXXXXX", tmpdir);
1366     pathlen = strlen(fn);
1367
1368     for (;;) {
1369         size_t i;
1370         int r;
1371         mode_t u;
1372         int saved_errno;
1373
1374         for (i = pathlen - 12; i < pathlen; i++)
1375             fn[i] = table[rand() % (sizeof(table)-1)];
1376
1377         u = umask((~m) & 0777);
1378         r = mkdir(fn, m);
1379
1380         saved_errno = errno;
1381         umask(u);
1382         errno = saved_errno;
1383
1384         if (r >= 0)
1385             return fn;
1386
1387         if (errno != EEXIST) {
1388             pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
1389             pa_xfree(fn);
1390             return NULL;
1391         }
1392     }
1393 }
1394
1395 static int make_random_dir_and_link(mode_t m, const char *k) {
1396     char *p;
1397
1398     if (!(p = make_random_dir(m)))
1399         return -1;
1400
1401     if (symlink(p, k) < 0) {
1402         int saved_errno = errno;
1403
1404         if (errno != EEXIST)
1405             pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
1406
1407         rmdir(p);
1408         pa_xfree(p);
1409
1410         errno = saved_errno;
1411         return -1;
1412     }
1413
1414     pa_xfree(p);
1415     return 0;
1416 }
1417
1418 char *pa_get_runtime_dir(void) {
1419     char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
1420     struct stat st;
1421     mode_t m;
1422
1423     /* The runtime directory shall contain dynamic data that needs NOT
1424      * to be kept accross reboots and is usuallly private to the user,
1425      * except in system mode, where it might be accessible by other
1426      * users, too. Since we need POSIX locking and UNIX sockets in
1427      * this directory, we link it to a random subdir in /tmp, if it
1428      * was not explicitly configured. */
1429
1430     m = pa_in_system_mode() ? 0755U : 0700U;
1431
1432     if ((d = getenv("PULSE_RUNTIME_PATH"))) {
1433
1434         if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
1435             pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1436             goto fail;
1437         }
1438
1439         return pa_xstrdup(d);
1440     }
1441
1442     if (!(d = get_pulse_home()))
1443         goto fail;
1444
1445     if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
1446         pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
1447         pa_xfree(d);
1448         goto fail;
1449     }
1450
1451     if (!(mid = pa_machine_id())) {
1452         pa_xfree(d);
1453         goto fail;
1454     }
1455
1456     k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:runtime", d, mid);
1457     pa_xfree(d);
1458     pa_xfree(mid);
1459
1460     for (;;) {
1461         /* OK, first let's check if the "runtime" symlink is already
1462          * existant */
1463
1464         if (!(p = pa_readlink(k))) {
1465
1466             if (errno != ENOENT) {
1467                 pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
1468                 goto fail;
1469             }
1470
1471             /* Hmm, so the runtime directory didn't exist yet, so let's
1472              * create one in /tmp and symlink that to it */
1473
1474             if (make_random_dir_and_link(0700, k) < 0) {
1475
1476                 /* Mhmm, maybe another process was quicker than us,
1477                  * let's check if that was valid */
1478                 if (errno == EEXIST)
1479                     continue;
1480
1481                 goto fail;
1482             }
1483
1484             return k;
1485         }
1486
1487         /* Make sure that this actually makes sense */
1488         if (!pa_is_path_absolute(p)) {
1489             pa_log_error("Path %s in link %s is not absolute.", p, k);
1490             errno = ENOENT;
1491             goto fail;
1492         }
1493
1494         /* Hmm, so this symlink is still around, make sure nobody fools
1495          * us */
1496
1497         if (lstat(p, &st) < 0) {
1498
1499             if (errno != ENOENT) {
1500                 pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
1501                 goto fail;
1502             }
1503
1504         } else {
1505
1506             if (S_ISDIR(st.st_mode) &&
1507                 (st.st_uid == getuid()) &&
1508                 ((st.st_mode & 0777) == 0700)) {
1509
1510                 pa_xfree(p);
1511                 return k;
1512             }
1513
1514             pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1515         }
1516
1517         pa_xfree(p);
1518         p = NULL;
1519
1520         /* Hmm, so the link points to some nonexisting or invalid
1521          * dir. Let's replace it by a new link. We first create a
1522          * temporary link and then rename that to allow concurrent
1523          * execution of this function. */
1524
1525         t = pa_sprintf_malloc("%s.tmp", k);
1526
1527         if (make_random_dir_and_link(0700, t) < 0) {
1528
1529             if (errno != EEXIST) {
1530                 pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
1531                 goto fail;
1532             }
1533
1534             pa_xfree(t);
1535             t = NULL;
1536
1537             /* Hmm, someone lese was quicker then us. Let's give
1538              * him some time to finish, and retry. */
1539             pa_msleep(10);
1540             continue;
1541         }
1542
1543         /* OK, we succeeded in creating the temporary symlink, so
1544          * let's rename it */
1545         if (rename(t, k) < 0) {
1546             pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
1547             goto fail;
1548         }
1549
1550         pa_xfree(t);
1551         return k;
1552     }
1553
1554 fail:
1555     pa_xfree(p);
1556     pa_xfree(k);
1557     pa_xfree(t);
1558
1559     return NULL;
1560 }
1561
1562 /* Try to open a configuration file. If "env" is specified, open the
1563  * value of the specified environment variable. Otherwise look for a
1564  * file "local" in the home directory or a file "global" in global
1565  * file system. If "result" is non-NULL, a pointer to a newly
1566  * allocated buffer containing the used configuration file is
1567  * stored there.*/
1568 FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
1569     const char *fn;
1570 #ifdef OS_IS_WIN32
1571     char buf[PATH_MAX];
1572
1573     if (!getenv(PULSE_ROOTENV))
1574         pa_set_root(NULL);
1575 #endif
1576
1577     if (env && (fn = getenv(env))) {
1578         FILE *f;
1579
1580 #ifdef OS_IS_WIN32
1581         if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
1582             /* FIXME: Needs to set errno! */
1583             return NULL;
1584         fn = buf;
1585 #endif
1586
1587         if ((f = fopen(fn, "r"))) {
1588             if (result)
1589                 *result = pa_xstrdup(fn);
1590
1591             return f;
1592         }
1593
1594         pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1595         return NULL;
1596     }
1597
1598     if (local) {
1599         const char *e;
1600         char *lfn;
1601         char h[PATH_MAX];
1602         FILE *f;
1603
1604         if ((e = getenv("PULSE_CONFIG_PATH")))
1605             fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1606         else if (pa_get_home_dir(h, sizeof(h)))
1607             fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1608         else
1609             return NULL;
1610
1611 #ifdef OS_IS_WIN32
1612         if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
1613             /* FIXME: Needs to set errno! */
1614             pa_xfree(lfn);
1615             return NULL;
1616         }
1617         fn = buf;
1618 #endif
1619
1620         if ((f = fopen(fn, "r"))) {
1621             if (result)
1622                 *result = pa_xstrdup(fn);
1623
1624             pa_xfree(lfn);
1625             return f;
1626         }
1627
1628         if (errno != ENOENT) {
1629             pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1630             pa_xfree(lfn);
1631             return NULL;
1632         }
1633
1634         pa_xfree(lfn);
1635     }
1636
1637     if (global) {
1638         FILE *f;
1639
1640 #ifdef OS_IS_WIN32
1641         if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
1642             /* FIXME: Needs to set errno! */
1643             return NULL;
1644         global = buf;
1645 #endif
1646
1647         if ((f = fopen(global, "r"))) {
1648
1649             if (result)
1650                 *result = pa_xstrdup(global);
1651
1652             return f;
1653         }
1654     }
1655
1656     errno = ENOENT;
1657     return NULL;
1658 }
1659
1660 char *pa_find_config_file(const char *global, const char *local, const char *env) {
1661     const char *fn;
1662 #ifdef OS_IS_WIN32
1663     char buf[PATH_MAX];
1664
1665     if (!getenv(PULSE_ROOTENV))
1666         pa_set_root(NULL);
1667 #endif
1668
1669     if (env && (fn = getenv(env))) {
1670
1671 #ifdef OS_IS_WIN32
1672         if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
1673             /* FIXME: Needs to set errno! */
1674             return NULL;
1675         fn = buf;
1676 #endif
1677
1678         if (access(fn, R_OK) == 0)
1679             return pa_xstrdup(fn);
1680
1681         pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1682         return NULL;
1683     }
1684
1685     if (local) {
1686         const char *e;
1687         char *lfn;
1688         char h[PATH_MAX];
1689
1690         if ((e = getenv("PULSE_CONFIG_PATH")))
1691             fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1692         else if (pa_get_home_dir(h, sizeof(h)))
1693             fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1694         else
1695             return NULL;
1696
1697 #ifdef OS_IS_WIN32
1698         if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
1699             /* FIXME: Needs to set errno! */
1700             pa_xfree(lfn);
1701             return NULL;
1702         }
1703         fn = buf;
1704 #endif
1705
1706         if (access(fn, R_OK) == 0) {
1707             char *r = pa_xstrdup(fn);
1708             pa_xfree(lfn);
1709             return r;
1710         }
1711
1712         if (errno != ENOENT) {
1713             pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
1714             pa_xfree(lfn);
1715             return NULL;
1716         }
1717
1718         pa_xfree(lfn);
1719     }
1720
1721     if (global) {
1722 #ifdef OS_IS_WIN32
1723         if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
1724             /* FIXME: Needs to set errno! */
1725             return NULL;
1726         global = buf;
1727 #endif
1728
1729         if (access(global, R_OK) == 0)
1730             return pa_xstrdup(global);
1731     }
1732
1733     errno = ENOENT;
1734
1735     return NULL;
1736 }
1737
1738 /* Format the specified data as a hexademical string */
1739 char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
1740     size_t i = 0, j = 0;
1741     const char hex[] = "0123456789abcdef";
1742
1743     pa_assert(d);
1744     pa_assert(s);
1745     pa_assert(slength > 0);
1746
1747     while (i < dlength && j+3 <= slength) {
1748         s[j++] = hex[*d >> 4];
1749         s[j++] = hex[*d & 0xF];
1750
1751         d++;
1752         i++;
1753     }
1754
1755     s[j < slength ? j : slength] = 0;
1756     return s;
1757 }
1758
1759 /* Convert a hexadecimal digit to a number or -1 if invalid */
1760 static int hexc(char c) {
1761     if (c >= '0' && c <= '9')
1762         return c - '0';
1763
1764     if (c >= 'A' && c <= 'F')
1765         return c - 'A' + 10;
1766
1767     if (c >= 'a' && c <= 'f')
1768         return c - 'a' + 10;
1769
1770     errno = EINVAL;
1771     return -1;
1772 }
1773
1774 /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
1775 size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {
1776     size_t j = 0;
1777
1778     pa_assert(p);
1779     pa_assert(d);
1780
1781     while (j < dlength && *p) {
1782         int b;
1783
1784         if ((b = hexc(*(p++))) < 0)
1785             return (size_t) -1;
1786
1787         d[j] = (uint8_t) (b << 4);
1788
1789         if (!*p)
1790             return (size_t) -1;
1791
1792         if ((b = hexc(*(p++))) < 0)
1793             return (size_t) -1;
1794
1795         d[j] |= (uint8_t) b;
1796         j++;
1797     }
1798
1799     return j;
1800 }
1801
1802 /* Returns nonzero when *s starts with *pfx */
1803 pa_bool_t pa_startswith(const char *s, const char *pfx) {
1804     size_t l;
1805
1806     pa_assert(s);
1807     pa_assert(pfx);
1808
1809     l = strlen(pfx);
1810
1811     return strlen(s) >= l && strncmp(s, pfx, l) == 0;
1812 }
1813
1814 /* Returns nonzero when *s ends with *sfx */
1815 pa_bool_t pa_endswith(const char *s, const char *sfx) {
1816     size_t l1, l2;
1817
1818     pa_assert(s);
1819     pa_assert(sfx);
1820
1821     l1 = strlen(s);
1822     l2 = strlen(sfx);
1823
1824     return l1 >= l2 && strcmp(s+l1-l2, sfx) == 0;
1825 }
1826
1827 pa_bool_t pa_is_path_absolute(const char *fn) {
1828     pa_assert(fn);
1829
1830 #ifndef OS_IS_WIN32
1831     return *fn == '/';
1832 #else
1833     return strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\';
1834 #endif
1835 }
1836
1837 char *pa_make_path_absolute(const char *p) {
1838     char *r;
1839     char *cwd;
1840
1841     pa_assert(p);
1842
1843     if (pa_is_path_absolute(p))
1844         return pa_xstrdup(p);
1845
1846     if (!(cwd = pa_getcwd()))
1847         return pa_xstrdup(p);
1848
1849     r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", cwd, p);
1850     pa_xfree(cwd);
1851     return r;
1852 }
1853
1854 /* if fn is null return the PulseAudio run time path in s (~/.pulse)
1855  * if fn is non-null and starts with / return fn
1856  * otherwise append fn to the run time path and return it */
1857 static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
1858     char *rtp;
1859
1860     if (pa_is_path_absolute(fn))
1861         return pa_xstrdup(fn);
1862
1863     rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
1864
1865     if (!rtp)
1866         return NULL;
1867
1868     if (fn) {
1869         char *r;
1870
1871         if (prependmid) {
1872             char *mid;
1873
1874             if (!(mid = pa_machine_id())) {
1875                 pa_xfree(rtp);
1876                 return NULL;
1877             }
1878
1879             r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:%s", rtp, mid, fn);
1880             pa_xfree(mid);
1881         } else
1882             r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn);
1883
1884         pa_xfree(rtp);
1885         return r;
1886     } else
1887         return rtp;
1888 }
1889
1890 char *pa_runtime_path(const char *fn) {
1891     return get_path(fn, FALSE, TRUE);
1892 }
1893
1894 char *pa_state_path(const char *fn, pa_bool_t appendmid) {
1895     return get_path(fn, appendmid, FALSE);
1896 }
1897
1898 /* Convert the string s to a signed integer in *ret_i */
1899 int pa_atoi(const char *s, int32_t *ret_i) {
1900     char *x = NULL;
1901     long l;
1902
1903     pa_assert(s);
1904     pa_assert(ret_i);
1905
1906     errno = 0;
1907     l = strtol(s, &x, 0);
1908
1909     if (!x || *x || errno) {
1910         if (!errno)
1911             errno = EINVAL;
1912         return -1;
1913     }
1914
1915     if ((int32_t) l != l) {
1916         errno = ERANGE;
1917         return -1;
1918     }
1919
1920     *ret_i = (int32_t) l;
1921
1922     return 0;
1923 }
1924
1925 /* Convert the string s to an unsigned integer in *ret_u */
1926 int pa_atou(const char *s, uint32_t *ret_u) {
1927     char *x = NULL;
1928     unsigned long l;
1929
1930     pa_assert(s);
1931     pa_assert(ret_u);
1932
1933     errno = 0;
1934     l = strtoul(s, &x, 0);
1935
1936     if (!x || *x || errno) {
1937         if (!errno)
1938             errno = EINVAL;
1939         return -1;
1940     }
1941
1942     if ((uint32_t) l != l) {
1943         errno = ERANGE;
1944         return -1;
1945     }
1946
1947     *ret_u = (uint32_t) l;
1948
1949     return 0;
1950 }
1951
1952 #ifdef HAVE_STRTOF_L
1953 static locale_t c_locale = NULL;
1954
1955 static void c_locale_destroy(void) {
1956     freelocale(c_locale);
1957 }
1958 #endif
1959
1960 int pa_atod(const char *s, double *ret_d) {
1961     char *x = NULL;
1962     double f;
1963
1964     pa_assert(s);
1965     pa_assert(ret_d);
1966
1967     /* This should be locale independent */
1968
1969 #ifdef HAVE_STRTOF_L
1970
1971     PA_ONCE_BEGIN {
1972
1973         if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
1974             atexit(c_locale_destroy);
1975
1976     } PA_ONCE_END;
1977
1978     if (c_locale) {
1979         errno = 0;
1980         f = strtod_l(s, &x, c_locale);
1981     } else
1982 #endif
1983     {
1984         errno = 0;
1985         f = strtod(s, &x);
1986     }
1987
1988     if (!x || *x || errno) {
1989         if (!errno)
1990             errno = EINVAL;
1991         return -1;
1992     }
1993
1994     *ret_d = f;
1995
1996     return 0;
1997 }
1998
1999 /* Same as snprintf, but guarantees NUL-termination on every platform */
2000 size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
2001     size_t ret;
2002     va_list ap;
2003
2004     pa_assert(str);
2005     pa_assert(size > 0);
2006     pa_assert(format);
2007
2008     va_start(ap, format);
2009     ret = pa_vsnprintf(str, size, format, ap);
2010     va_end(ap);
2011
2012     return ret;
2013 }
2014
2015 /* Same as vsnprintf, but guarantees NUL-termination on every platform */
2016 size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
2017     int ret;
2018
2019     pa_assert(str);
2020     pa_assert(size > 0);
2021     pa_assert(format);
2022
2023     ret = vsnprintf(str, size, format, ap);
2024
2025     str[size-1] = 0;
2026
2027     if (ret < 0)
2028         return strlen(str);
2029
2030     if ((size_t) ret > size-1)
2031         return size-1;
2032
2033     return (size_t) ret;
2034 }
2035
2036 /* Truncate the specified string, but guarantee that the string
2037  * returned still validates as UTF8 */
2038 char *pa_truncate_utf8(char *c, size_t l) {
2039     pa_assert(c);
2040     pa_assert(pa_utf8_valid(c));
2041
2042     if (strlen(c) <= l)
2043         return c;
2044
2045     c[l] = 0;
2046
2047     while (l > 0 && !pa_utf8_valid(c))
2048         c[--l] = 0;
2049
2050     return c;
2051 }
2052
2053 char *pa_getcwd(void) {
2054     size_t l = 128;
2055
2056     for (;;) {
2057         char *p = pa_xmalloc(l);
2058         if (getcwd(p, l))
2059             return p;
2060
2061         if (errno != ERANGE)
2062             return NULL;
2063
2064         pa_xfree(p);
2065         l *= 2;
2066     }
2067 }
2068
2069 void *pa_will_need(const void *p, size_t l) {
2070 #ifdef RLIMIT_MEMLOCK
2071     struct rlimit rlim;
2072 #endif
2073     const void *a;
2074     size_t size;
2075     int r;
2076     size_t bs;
2077
2078     pa_assert(p);
2079     pa_assert(l > 0);
2080
2081     a = PA_PAGE_ALIGN_PTR(p);
2082     size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
2083
2084 #ifdef HAVE_POSIX_MADVISE
2085     if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
2086         pa_log_debug("posix_madvise() worked fine!");
2087         return (void*) p;
2088     }
2089 #endif
2090
2091     /* Most likely the memory was not mmap()ed from a file and thus
2092      * madvise() didn't work, so let's misuse mlock() do page this
2093      * stuff back into RAM. Yeah, let's fuck with the MM!  It's so
2094      * inviting, the man page of mlock() tells us: "All pages that
2095      * contain a part of the specified address range are guaranteed to
2096      * be resident in RAM when the call returns successfully." */
2097
2098 #ifdef RLIMIT_MEMLOCK
2099     pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
2100
2101     if (rlim.rlim_cur < PA_PAGE_SIZE) {
2102         pa_log_debug("posix_madvise() failed (or doesn't exist), resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r));
2103         errno = EPERM;
2104         return (void*) p;
2105     }
2106
2107     bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
2108 #else
2109     bs = PA_PAGE_SIZE*4;
2110 #endif
2111
2112     pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r));
2113
2114 #ifdef HAVE_MLOCK
2115     while (size > 0 && bs > 0) {
2116
2117         if (bs > size)
2118             bs = size;
2119
2120         if (mlock(a, bs) < 0) {
2121             bs = PA_PAGE_ALIGN(bs / 2);
2122             continue;
2123         }
2124
2125         pa_assert_se(munlock(a, bs) == 0);
2126
2127         a = (const uint8_t*) a + bs;
2128         size -= bs;
2129     }
2130 #endif
2131
2132     if (bs <= 0)
2133         pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno));
2134     else
2135         pa_log_debug("mlock() worked fine!");
2136
2137     return (void*) p;
2138 }
2139
2140 void pa_close_pipe(int fds[2]) {
2141     pa_assert(fds);
2142
2143     if (fds[0] >= 0)
2144         pa_assert_se(pa_close(fds[0]) == 0);
2145
2146     if (fds[1] >= 0)
2147         pa_assert_se(pa_close(fds[1]) == 0);
2148
2149     fds[0] = fds[1] = -1;
2150 }
2151
2152 char *pa_readlink(const char *p) {
2153     size_t l = 100;
2154
2155     for (;;) {
2156         char *c;
2157         ssize_t n;
2158
2159         c = pa_xmalloc(l);
2160
2161         if ((n = readlink(p, c, l-1)) < 0) {
2162             pa_xfree(c);
2163             return NULL;
2164         }
2165
2166         if ((size_t) n < l-1) {
2167             c[n] = 0;
2168             return c;
2169         }
2170
2171         pa_xfree(c);
2172         l *= 2;
2173     }
2174 }
2175
2176 int pa_close_all(int except_fd, ...) {
2177     va_list ap;
2178     unsigned n = 0, i;
2179     int r, *p;
2180
2181     va_start(ap, except_fd);
2182
2183     if (except_fd >= 0)
2184         for (n = 1; va_arg(ap, int) >= 0; n++)
2185             ;
2186
2187     va_end(ap);
2188
2189     p = pa_xnew(int, n+1);
2190
2191     va_start(ap, except_fd);
2192
2193     i = 0;
2194     if (except_fd >= 0) {
2195         int fd;
2196         p[i++] = except_fd;
2197
2198         while ((fd = va_arg(ap, int)) >= 0)
2199             p[i++] = fd;
2200     }
2201     p[i] = -1;
2202
2203     va_end(ap);
2204
2205     r = pa_close_allv(p);
2206     free(p);
2207
2208     return r;
2209 }
2210
2211 int pa_close_allv(const int except_fds[]) {
2212     struct rlimit rl;
2213     int fd;
2214     int saved_errno;
2215
2216 #ifdef __linux__
2217
2218     DIR *d;
2219
2220     if ((d = opendir("/proc/self/fd"))) {
2221
2222         struct dirent *de;
2223
2224         while ((de = readdir(d))) {
2225             pa_bool_t found;
2226             long l;
2227             char *e = NULL;
2228             int i;
2229
2230             if (de->d_name[0] == '.')
2231                 continue;
2232
2233             errno = 0;
2234             l = strtol(de->d_name, &e, 10);
2235             if (errno != 0 || !e || *e) {
2236                 closedir(d);
2237                 errno = EINVAL;
2238                 return -1;
2239             }
2240
2241             fd = (int) l;
2242
2243             if ((long) fd != l) {
2244                 closedir(d);
2245                 errno = EINVAL;
2246                 return -1;
2247             }
2248
2249             if (fd < 3)
2250                 continue;
2251
2252             if (fd == dirfd(d))
2253                 continue;
2254
2255             found = FALSE;
2256             for (i = 0; except_fds[i] >= 0; i++)
2257                 if (except_fds[i] == fd) {
2258                     found = TRUE;
2259                     break;
2260                 }
2261
2262             if (found)
2263                 continue;
2264
2265             if (pa_close(fd) < 0) {
2266                 saved_errno = errno;
2267                 closedir(d);
2268                 errno = saved_errno;
2269
2270                 return -1;
2271             }
2272         }
2273
2274         closedir(d);
2275         return 0;
2276     }
2277
2278 #endif
2279
2280     if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
2281         return -1;
2282
2283     for (fd = 3; fd < (int) rl.rlim_max; fd++) {
2284         int i;
2285         pa_bool_t found;
2286
2287         found = FALSE;
2288         for (i = 0; except_fds[i] >= 0; i++)
2289             if (except_fds[i] == fd) {
2290                 found = TRUE;
2291                 break;
2292             }
2293
2294         if (found)
2295             continue;
2296
2297         if (pa_close(fd) < 0 && errno != EBADF)
2298             return -1;
2299     }
2300
2301     return 0;
2302 }
2303
2304 int pa_unblock_sigs(int except, ...) {
2305     va_list ap;
2306     unsigned n = 0, i;
2307     int r, *p;
2308
2309     va_start(ap, except);
2310
2311     if (except >= 1)
2312         for (n = 1; va_arg(ap, int) >= 0; n++)
2313             ;
2314
2315     va_end(ap);
2316
2317     p = pa_xnew(int, n+1);
2318
2319     va_start(ap, except);
2320
2321     i = 0;
2322     if (except >= 1) {
2323         int sig;
2324         p[i++] = except;
2325
2326         while ((sig = va_arg(ap, int)) >= 0)
2327             p[i++] = sig;
2328     }
2329     p[i] = -1;
2330
2331     va_end(ap);
2332
2333     r = pa_unblock_sigsv(p);
2334     pa_xfree(p);
2335
2336     return r;
2337 }
2338
2339 int pa_unblock_sigsv(const int except[]) {
2340     int i;
2341     sigset_t ss;
2342
2343     if (sigemptyset(&ss) < 0)
2344         return -1;
2345
2346     for (i = 0; except[i] > 0; i++)
2347         if (sigaddset(&ss, except[i]) < 0)
2348             return -1;
2349
2350     return sigprocmask(SIG_SETMASK, &ss, NULL);
2351 }
2352
2353 int pa_reset_sigs(int except, ...) {
2354     va_list ap;
2355     unsigned n = 0, i;
2356     int *p, r;
2357
2358     va_start(ap, except);
2359
2360     if (except >= 1)
2361         for (n = 1; va_arg(ap, int) >= 0; n++)
2362             ;
2363
2364     va_end(ap);
2365
2366     p = pa_xnew(int, n+1);
2367
2368     va_start(ap, except);
2369
2370     i = 0;
2371     if (except >= 1) {
2372         int sig;
2373         p[i++] = except;
2374
2375         while ((sig = va_arg(ap, int)) >= 0)
2376             sig = p[i++];
2377     }
2378     p[i] = -1;
2379
2380     va_end(ap);
2381
2382     r = pa_reset_sigsv(p);
2383     pa_xfree(p);
2384
2385     return r;
2386 }
2387
2388 int pa_reset_sigsv(const int except[]) {
2389     int sig;
2390
2391     for (sig = 1; sig < NSIG; sig++) {
2392         pa_bool_t reset = TRUE;
2393
2394         switch (sig) {
2395             case SIGKILL:
2396             case SIGSTOP:
2397                 reset = FALSE;
2398                 break;
2399
2400             default: {
2401                 int i;
2402
2403                 for (i = 0; except[i] > 0; i++) {
2404                     if (sig == except[i]) {
2405                         reset = FALSE;
2406                         break;
2407                     }
2408                 }
2409             }
2410         }
2411
2412         if (reset) {
2413             struct sigaction sa;
2414
2415             memset(&sa, 0, sizeof(sa));
2416             sa.sa_handler = SIG_DFL;
2417
2418             /* On Linux the first two RT signals are reserved by
2419              * glibc, and sigaction() will return EINVAL for them. */
2420             if ((sigaction(sig, &sa, NULL) < 0))
2421                 if (errno != EINVAL)
2422                     return -1;
2423         }
2424     }
2425
2426     return 0;
2427 }
2428
2429 void pa_set_env(const char *key, const char *value) {
2430     pa_assert(key);
2431     pa_assert(value);
2432
2433     putenv(pa_sprintf_malloc("%s=%s", key, value));
2434 }
2435
2436 pa_bool_t pa_in_system_mode(void) {
2437     const char *e;
2438
2439     if (!(e = getenv("PULSE_SYSTEM")))
2440         return FALSE;
2441
2442     return !!atoi(e);
2443 }
2444
2445 char *pa_machine_id(void) {
2446     FILE *f;
2447     size_t l;
2448
2449     /* The returned value is supposed be some kind of ascii identifier
2450      * that is unique and stable across reboots. */
2451
2452     /* First we try the D-Bus UUID, which is the best option we have,
2453      * since it fits perfectly our needs and is not as volatile as the
2454      * hostname which might be set from dhcp. */
2455
2456     if ((f = fopen(PA_MACHINE_ID, "r"))) {
2457         char ln[34] = "", *r;
2458
2459         r = fgets(ln, sizeof(ln)-1, f);
2460         fclose(f);
2461
2462         pa_strip_nl(ln);
2463
2464         if (r && ln[0])
2465             return pa_xstrdup(ln);
2466     }
2467
2468     /* The we fall back to the host name. It supposed to be somewhat
2469      * unique, at least in a network, but may change. */
2470
2471     l = 100;
2472     for (;;) {
2473         char *c;
2474
2475         c = pa_xmalloc(l);
2476
2477         if (!pa_get_host_name(c, l)) {
2478
2479             if (errno != EINVAL && errno != ENAMETOOLONG)
2480                 break;
2481
2482         } else if (strlen(c) < l-1) {
2483
2484             if (*c == 0) {
2485                 pa_xfree(c);
2486                 break;
2487             }
2488
2489             return c;
2490         }
2491
2492         /* Hmm, the hostname is as long the space we offered the
2493          * function, we cannot know if it fully fit in, so let's play
2494          * safe and retry. */
2495
2496         pa_xfree(c);
2497         l *= 2;
2498     }
2499
2500     /* If no hostname was set we use the POSIX hostid. It's usually
2501      * the IPv4 address.  Mit not be that stable. */
2502     return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
2503 }
2504
2505 char *pa_uname_string(void) {
2506     struct utsname u;
2507
2508     pa_assert_se(uname(&u) >= 0);
2509
2510     return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
2511 }
2512
2513 #ifdef HAVE_VALGRIND_MEMCHECK_H
2514 pa_bool_t pa_in_valgrind(void) {
2515     static int b = 0;
2516
2517     /* To make heisenbugs a bit simpler to find we check for $VALGRIND
2518      * here instead of really checking whether we run in valgrind or
2519      * not. */
2520
2521     if (b < 1)
2522         b = getenv("VALGRIND") ? 2 : 1;
2523
2524     return b > 1;
2525 }
2526 #endif
2527
2528 unsigned pa_gcd(unsigned a, unsigned b) {
2529
2530     while (b > 0) {
2531         unsigned t = b;
2532         b = a % b;
2533         a = t;
2534     }
2535
2536     return a;
2537 }
2538
2539 void pa_reduce(unsigned *num, unsigned *den) {
2540
2541     unsigned gcd = pa_gcd(*num, *den);
2542
2543     if (gcd <= 0)
2544         return;
2545
2546     *num /= gcd;
2547     *den /= gcd;
2548
2549     pa_assert(pa_gcd(*num, *den) == 1);
2550 }
2551
2552 unsigned pa_ncpus(void) {
2553     long ncpus;
2554
2555 #ifdef _SC_NPROCESSORS_CONF
2556     ncpus = sysconf(_SC_NPROCESSORS_CONF);
2557 #else
2558     ncpus = 1;
2559 #endif
2560
2561     return ncpus <= 0 ? 1 : (unsigned) ncpus;
2562 }
2563
2564 char *pa_replace(const char*s, const char*a, const char *b) {
2565     pa_strbuf *sb;
2566     size_t an;
2567
2568     pa_assert(s);
2569     pa_assert(a);
2570     pa_assert(b);
2571
2572     an = strlen(a);
2573     sb = pa_strbuf_new();
2574
2575     for (;;) {
2576         const char *p;
2577
2578         if (!(p = strstr(s, a)))
2579             break;
2580
2581         pa_strbuf_putsn(sb, s, p-s);
2582         pa_strbuf_puts(sb, b);
2583         s = p + an;
2584     }
2585
2586     pa_strbuf_puts(sb, s);
2587
2588     return pa_strbuf_tostring_free(sb);
2589 }
2590
2591 char *pa_unescape(char *p) {
2592     char *s, *d;
2593     pa_bool_t escaped = FALSE;
2594
2595     for (s = p, d = p; *s; s++) {
2596         if (!escaped && *s == '\\') {
2597             escaped = TRUE;
2598             continue;
2599         }
2600
2601         *(d++) = *s;
2602         escaped = FALSE;
2603     }
2604
2605     *d = 0;
2606
2607     return p;
2608 }
2609
2610 char *pa_realpath(const char *path) {
2611     char *t;
2612     pa_assert(path);
2613
2614     /* We want only abolsute paths */
2615     if (path[0] != '/') {
2616         errno = EINVAL;
2617         return NULL;
2618     }
2619
2620 #if defined(__GLIBC__) || defined(__APPLE__)
2621     {
2622         char *r;
2623
2624         if (!(r = realpath(path, NULL)))
2625             return NULL;
2626
2627         /* We copy this here in case our pa_xmalloc() is not
2628          * implemented on top of libc malloc() */
2629         t = pa_xstrdup(r);
2630         pa_xfree(r);
2631     }
2632 #elif defined(PATH_MAX)
2633     {
2634         char *path_buf;
2635         path_buf = pa_xmalloc(PATH_MAX);
2636
2637         if (!(t = realpath(path, path_buf))) {
2638             pa_xfree(path_buf);
2639             return NULL;
2640         }
2641     }
2642 #else
2643 #error "It's not clear whether this system supports realpath(..., NULL) like GNU libc does. If it doesn't we need a private version of realpath() here."
2644 #endif
2645
2646     return t;
2647 }