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