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