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, see <http://www.gnu.org/licenses/>.
20***/
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26#ifndef LOG_TAG
27#define LOG_TAG "CoreUtil"
28#endif
29
30#include <math.h>
31#include <stdarg.h>
32#include <stdlib.h>
33#include <signal.h>
34#include <errno.h>
35#include <string.h>
36#include <stdio.h>
37#include <fcntl.h>
38#include <unistd.h>
39#include <limits.h>
40#include <ctype.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <dirent.h>
44
45#ifdef HAVE_LANGINFO_H
46#include <langinfo.h>
47#endif
48
49#ifdef HAVE_UNAME
50#include <sys/utsname.h>
51#endif
52
53#if defined(HAVE_REGEX_H)
54#include <regex.h>
55#elif defined(HAVE_PCREPOSIX_H)
56#include <pcreposix.h>
57#endif
58
59#ifdef HAVE_STRTOD_L
60#ifdef HAVE_LOCALE_H
61#include <locale.h>
62#endif
63#ifdef HAVE_XLOCALE_H
64#include <xlocale.h>
65#endif
66#endif
67
68#ifdef HAVE_SYS_RESOURCE_H
69#include <sys/resource.h>
70#endif
71
72#ifdef HAVE_SYS_CAPABILITY_H
73#include <sys/capability.h>
74#endif
75
76#ifdef HAVE_SYS_MMAN_H
77#include <sys/mman.h>
78#endif
79
80#ifdef HAVE_PTHREAD
81#include <pthread.h>
82#endif
83
84#ifdef HAVE_NETDB_H
85#include <netdb.h>
86#endif
87
88#ifdef HAVE_WINDOWS_H
89#include <windows.h>
90#include <shlobj.h>
91#endif
92
93#ifndef ENOTSUP
94#define ENOTSUP   135
95#endif
96
97#ifdef HAVE_PWD_H
98#include <pwd.h>
99#endif
100
101#ifdef HAVE_GRP_H
102#include <grp.h>
103#endif
104
105#ifdef HAVE_LIBSAMPLERATE
106#include <samplerate.h>
107#endif
108
109#ifdef HAVE_DBUS
110#include <pulsecore/rtkit.h>
111#endif
112
113#if defined(__linux__) && !defined(__ANDROID__)
114#include <sys/personality.h>
115#endif
116
117#ifdef HAVE_CPUID_H
118#include <cpuid.h>
119#endif
120
121#include <pulse/xmalloc.h>
122#include <pulse/util.h>
123#include <pulse/utf8.h>
124
125#include <pulsecore/core-error.h>
126#include <pulsecore/socket.h>
127#include <pulsecore/log.h>
128#include <pulsecore/macro.h>
129#include <pulsecore/thread.h>
130#include <pulsecore/strbuf.h>
131#include <pulsecore/usergroup.h>
132#include <pulsecore/strlist.h>
133#include <pulsecore/pipe.h>
134#include <pulsecore/once.h>
135
136#include "core-util.h"
137
138/* Not all platforms have this */
139#ifndef MSG_NOSIGNAL
140#define MSG_NOSIGNAL 0
141#endif
142
143#define NEWLINE "\r\n"
144#define WHITESPACE "\n\r \t"
145
146static pa_strlist *recorded_env = NULL;
147
148#ifdef OS_IS_WIN32
149static fd_set nonblocking_fds;
150#endif
151
152#ifdef OS_IS_WIN32
153
154/* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
155char *pa_win32_get_toplevel(HANDLE handle) {
156    static char *toplevel = NULL;
157
158    if (!toplevel) {
159        char library_path[MAX_PATH];
160        char *p;
161
162        if (!GetModuleFileName(handle, library_path, MAX_PATH))
163            return NULL;
164
165        toplevel = pa_xstrdup(library_path);
166
167        p = strrchr(toplevel, PA_PATH_SEP_CHAR);
168        if (p)
169            *p = '\0';
170
171        p = strrchr(toplevel, PA_PATH_SEP_CHAR);
172        if (p && pa_streq(p + 1, "bin"))
173            *p = '\0';
174    }
175
176    return toplevel;
177}
178
179char *pa_win32_get_system_appdata() {
180    static char appdata[MAX_PATH] = {0};
181
182    if (!*appdata && SHGetFolderPathAndSubDirA(NULL, CSIDL_COMMON_APPDATA|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, "PulseAudio", appdata) != S_OK)
183        return NULL;
184
185    return appdata;
186}
187
188#endif
189
190static void set_nonblock(int fd, bool nonblock) {
191
192#ifdef O_NONBLOCK
193    int v, nv;
194    pa_assert(fd >= 0);
195
196    pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
197
198    if (nonblock)
199        nv = v | O_NONBLOCK;
200    else
201        nv = v & ~O_NONBLOCK;
202
203    if (v != nv)
204        pa_assert_se(fcntl(fd, F_SETFL, nv) >= 0);
205
206#elif defined(OS_IS_WIN32)
207    u_long arg;
208
209    if (nonblock)
210        arg = 1;
211    else
212        arg = 0;
213
214    if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
215        pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
216        pa_log_warn("Only sockets can be made non-blocking!");
217        return;
218    }
219
220    /* There is no method to query status, so we remember all fds */
221    if (nonblock)
222        FD_SET(fd, &nonblocking_fds);
223    else
224        FD_CLR(fd, &nonblocking_fds);
225#else
226    pa_log_warn("Non-blocking I/O not supported.!");
227#endif
228
229}
230
231/** Make a file descriptor nonblock. Doesn't do any error checking */
232void pa_make_fd_nonblock(int fd) {
233    set_nonblock(fd, true);
234}
235
236/** Make a file descriptor blocking. Doesn't do any error checking */
237void pa_make_fd_block(int fd) {
238    set_nonblock(fd, false);
239}
240
241/** Query if a file descriptor is non-blocking */
242bool pa_is_fd_nonblock(int fd) {
243
244#ifdef O_NONBLOCK
245    int v;
246    pa_assert(fd >= 0);
247
248    pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
249
250    return !!(v & O_NONBLOCK);
251
252#elif defined(OS_IS_WIN32)
253    return !!FD_ISSET(fd, &nonblocking_fds);
254#else
255    return false;
256#endif
257
258}
259
260/* Set the FD_CLOEXEC flag for a fd */
261void pa_make_fd_cloexec(int fd) {
262
263#ifdef FD_CLOEXEC
264    int v;
265    pa_assert(fd >= 0);
266
267    pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0);
268
269    if (!(v & FD_CLOEXEC))
270        pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0);
271#endif
272
273}
274
275/** Creates a directory securely. Will create parent directories recursively if
276 * required. This will not update permissions on parent directories if they
277 * already exist, however. */
278int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid, bool update_perms) {
279    struct stat st;
280    int r, saved_errno;
281    bool retry = true;
282
283    pa_assert(dir);
284
285again:
286#ifdef OS_IS_WIN32
287    r = mkdir(dir);
288#else
289{
290    mode_t u;
291    u = umask((~m) & 0777);
292    r = mkdir(dir, m);
293    umask(u);
294}
295#endif
296
297    if (r < 0 && errno == ENOENT && retry) {
298        /* If a parent directory in the path doesn't exist, try to create that
299         * first, then try again. */
300        pa_make_secure_parent_dir(dir, m, uid, gid, false);
301        retry = false;
302        goto again;
303    }
304
305    if (r < 0 && errno != EEXIST)
306        return -1;
307
308#if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
309{
310    int fd;
311    if ((fd = open(dir,
312#ifdef O_CLOEXEC
313                   O_CLOEXEC|
314#endif
315#ifdef O_NOCTTY
316                   O_NOCTTY|
317#endif
318#ifdef O_NOFOLLOW
319                   O_NOFOLLOW|
320#endif
321                   O_RDONLY)) < 0)
322        goto fail;
323
324    if (fstat(fd, &st) < 0) {
325        pa_assert_se(pa_close(fd) >= 0);
326        goto fail;
327    }
328
329    if (!S_ISDIR(st.st_mode)) {
330        pa_assert_se(pa_close(fd) >= 0);
331        errno = EEXIST;
332        goto fail;
333    }
334
335    if (!update_perms) {
336        pa_assert_se(pa_close(fd) >= 0);
337        return 0;
338    }
339
340#ifdef HAVE_FCHOWN
341    if (uid == (uid_t) -1)
342        uid = getuid();
343    if (gid == (gid_t) -1)
344        gid = getgid();
345    if (((st.st_uid != uid) || (st.st_gid != gid)) && fchown(fd, uid, gid) < 0) {
346        pa_assert_se(pa_close(fd) >= 0);
347        goto fail;
348    }
349#endif
350
351#ifdef HAVE_FCHMOD
352    if ((st.st_mode & 07777) != m && fchmod(fd, m) < 0) {
353        pa_assert_se(pa_close(fd) >= 0);
354        goto fail;
355    };
356#endif
357
358    pa_assert_se(pa_close(fd) >= 0);
359}
360#else
361    pa_log_warn("Secure directory creation not supported on this platform.");
362#endif
363
364    return 0;
365
366fail:
367    saved_errno = errno;
368    rmdir(dir);
369    errno = saved_errno;
370
371    return -1;
372}
373
374/* Return a newly allocated sting containing the parent directory of the specified file */
375char *pa_parent_dir(const char *fn) {
376    char *slash, *dir = pa_xstrdup(fn);
377
378    if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
379        pa_xfree(dir);
380        errno = ENOENT;
381        return NULL;
382    }
383
384    *(slash-1) = 0;
385    return dir;
386}
387
388/* Creates a the parent directory of the specified path securely */
389int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid, bool update_perms) {
390    int ret = -1;
391    char *dir;
392
393    if (!(dir = pa_parent_dir(fn)))
394        goto finish;
395
396    if (pa_make_secure_dir(dir, m, uid, gid, update_perms) < 0)
397        goto finish;
398
399    ret = 0;
400
401finish:
402    pa_xfree(dir);
403    return ret;
404}
405
406/** Platform independent read function. Necessary since not all
407 * systems treat all file descriptors equal. If type is
408 * non-NULL it is used to cache the type of the fd. This is
409 * useful for making sure that only a single syscall is executed per
410 * function call. The variable pointed to should be initialized to 0
411 * by the caller. */
412ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
413
414#ifdef OS_IS_WIN32
415
416    if (!type || *type == 0) {
417        ssize_t r;
418
419        if ((r = recv(fd, buf, count, 0)) >= 0)
420            return r;
421
422        if (WSAGetLastError() != WSAENOTSOCK) {
423            errno = WSAGetLastError();
424            if (errno == WSAEWOULDBLOCK)
425                errno = EAGAIN;
426            return r;
427        }
428
429        if (type)
430            *type = 1;
431    }
432
433#endif
434
435    for (;;) {
436        ssize_t r;
437
438        if ((r = read(fd, buf, count)) < 0)
439            if (errno == EINTR)
440                continue;
441
442        return r;
443    }
444}
445
446/** Similar to pa_read(), but handles writes */
447ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
448
449    if (!type || *type == 0) {
450        ssize_t r;
451
452        for (;;) {
453            if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
454
455                if (errno == EINTR)
456                    continue;
457
458                break;
459            }
460
461            return r;
462        }
463
464#ifdef OS_IS_WIN32
465        if (WSAGetLastError() != WSAENOTSOCK) {
466            errno = WSAGetLastError();
467            if (errno == WSAEWOULDBLOCK)
468                errno = EAGAIN;
469            return r;
470        }
471#else
472        if (errno != ENOTSOCK)
473            return r;
474#endif
475
476        if (type)
477            *type = 1;
478    }
479
480    for (;;) {
481        ssize_t r;
482
483        if ((r = write(fd, buf, count)) < 0)
484            if (errno == EINTR)
485                continue;
486
487        return r;
488    }
489}
490
491/** Calls read() in a loop. Makes sure that as much as 'size' bytes,
492 * unless EOF is reached or an error occurred */
493ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
494    ssize_t ret = 0;
495    int _type;
496
497    pa_assert(fd >= 0);
498    pa_assert(data);
499    pa_assert(size);
500
501    if (!type) {
502        _type = 0;
503        type = &_type;
504    }
505
506    while (size > 0) {
507        ssize_t r;
508
509        if ((r = pa_read(fd, data, size, type)) < 0)
510            return r;
511
512        if (r == 0)
513            break;
514
515        ret += r;
516        data = (uint8_t*) data + r;
517        size -= (size_t) r;
518    }
519
520    return ret;
521}
522
523/** Similar to pa_loop_read(), but wraps write() */
524ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
525    ssize_t ret = 0;
526    int _type;
527
528    pa_assert(fd >= 0);
529    pa_assert(data);
530    pa_assert(size);
531
532    if (!type) {
533        _type = 0;
534        type = &_type;
535    }
536
537    while (size > 0) {
538        ssize_t r;
539
540        if ((r = pa_write(fd, data, size, type)) < 0)
541            return r;
542
543        if (r == 0)
544            break;
545
546        ret += r;
547        data = (const uint8_t*) data + r;
548        size -= (size_t) r;
549    }
550
551    return ret;
552}
553
554/** Platform independent close function. Necessary since not all
555 * systems treat all file descriptors equal. */
556int pa_close(int fd) {
557
558#ifdef OS_IS_WIN32
559    int ret;
560
561    FD_CLR(fd, &nonblocking_fds);
562
563    if ((ret = closesocket(fd)) == 0)
564        return 0;
565
566    if (WSAGetLastError() != WSAENOTSOCK) {
567        errno = WSAGetLastError();
568        return ret;
569    }
570#endif
571
572    for (;;) {
573        int r;
574
575        if ((r = close(fd)) < 0) {
576            if (errno == EINTR)
577                continue;
578            pa_log_error("Close fd failed, err code: %d", r);
579        }
580        return r;
581    }
582}
583
584/* Print a warning messages in case that the given signal is not
585 * blocked or trapped */
586void pa_check_signal_is_blocked(int sig) {
587#ifdef HAVE_SIGACTION
588    struct sigaction sa;
589    sigset_t set;
590
591    /* If POSIX threads are supported use thread-aware
592     * pthread_sigmask() function, to check if the signal is
593     * blocked. Otherwise fall back to sigprocmask() */
594
595#ifdef HAVE_PTHREAD
596    if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) {
597#endif
598        if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) {
599            pa_log("sigprocmask(): %s", pa_cstrerror(errno));
600            return;
601        }
602#ifdef HAVE_PTHREAD
603    }
604#endif
605
606    if (sigismember(&set, sig))
607        return;
608
609    /* Check whether the signal is trapped */
610
611    if (sigaction(sig, NULL, &sa) < 0) {
612        pa_log("sigaction(): %s", pa_cstrerror(errno));
613        return;
614    }
615
616    if (sa.sa_handler != SIG_DFL)
617        return;
618
619    pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig));
620#else /* HAVE_SIGACTION */
621    pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig));
622#endif
623}
624
625/* The following function is based on an example from the GNU libc
626 * documentation. This function is similar to GNU's asprintf(). */
627char *pa_sprintf_malloc(const char *format, ...) {
628    size_t size = 100;
629    char *c = NULL;
630
631    pa_assert(format);
632
633    for(;;) {
634        int r;
635        va_list ap;
636
637        c = pa_xrealloc(c, size);
638
639        va_start(ap, format);
640        r = vsnprintf(c, size, format, ap);
641        va_end(ap);
642
643        c[size-1] = 0;
644
645        if (r > -1 && (size_t) r < size)
646            return c;
647
648        if (r > -1)    /* glibc 2.1 */
649            size = (size_t) r+1;
650        else           /* glibc 2.0 */
651            size *= 2;
652    }
653}
654
655/* Same as the previous function, but use a va_list instead of an
656 * ellipsis */
657char *pa_vsprintf_malloc(const char *format, va_list ap) {
658    size_t size = 100;
659    char *c = NULL;
660
661    pa_assert(format);
662
663    for(;;) {
664        int r;
665        va_list aq;
666
667        c = pa_xrealloc(c, size);
668
669        va_copy(aq, ap);
670        r = vsnprintf(c, size, format, aq);
671        va_end(aq);
672
673        c[size-1] = 0;
674
675        if (r > -1 && (size_t) r < size)
676            return c;
677
678        if (r > -1)    /* glibc 2.1 */
679            size = (size_t) r+1;
680        else           /* glibc 2.0 */
681            size *= 2;
682    }
683}
684
685/* Similar to OpenBSD's strlcpy() function */
686char *pa_strlcpy(char *b, const char *s, size_t l) {
687    size_t k;
688
689    pa_assert(b);
690    pa_assert(s);
691    pa_assert(l > 0);
692
693    k = strlen(s);
694
695    if (k > l-1)
696        k = l-1;
697
698    memcpy(b, s, k);
699    b[k] = 0;
700
701    return b;
702}
703
704#ifdef HAVE_SYS_RESOURCE_H
705static int set_nice(int nice_level) {
706#ifdef HAVE_DBUS
707    DBusError error;
708    DBusConnection *bus;
709    int r;
710
711    dbus_error_init(&error);
712#endif
713
714#ifdef HAVE_SYS_RESOURCE_H
715    if (setpriority(PRIO_PROCESS, 0, nice_level) >= 0) {
716        pa_log_debug("setpriority() worked.");
717        return 0;
718    }
719#endif
720
721#ifdef HAVE_DBUS
722    /* Try to talk to RealtimeKit */
723
724    if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
725        pa_log("Failed to connect to system bus: %s", error.message);
726        dbus_error_free(&error);
727        errno = -EIO;
728        return -1;
729    }
730
731    /* We need to disable exit on disconnect because otherwise
732     * dbus_shutdown will kill us. See
733     * https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
734    dbus_connection_set_exit_on_disconnect(bus, FALSE);
735
736    r = rtkit_make_high_priority(bus, 0, nice_level);
737    dbus_connection_close(bus);
738    dbus_connection_unref(bus);
739
740    if (r >= 0) {
741        pa_log_debug("RealtimeKit worked.");
742        return 0;
743    }
744
745    errno = -r;
746#endif
747
748    return -1;
749}
750#endif
751
752/* Raise the priority of the current process as much as possible that
753 * is <= the specified nice level..*/
754int pa_raise_priority(int nice_level) {
755
756#ifdef HAVE_SYS_RESOURCE_H
757    int n;
758
759    if (set_nice(nice_level) >= 0) {
760        pa_log_info("Successfully gained nice level %i.", nice_level);
761        return 0;
762    }
763
764    for (n = nice_level+1; n < 0; n++)
765        if (set_nice(n) >= 0) {
766            pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
767            return 0;
768        }
769
770    pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno));
771    return -1;
772#endif
773
774#ifdef OS_IS_WIN32
775    if (nice_level < 0) {
776        if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
777            pa_log_warn("SetPriorityClass() failed: 0x%08lX", GetLastError());
778            errno = EPERM;
779            return -1;
780        }
781
782        pa_log_info("Successfully gained high priority class.");
783    }
784#endif
785
786    return 0;
787}
788
789/* Reset the priority to normal, inverting the changes made by
790 * pa_raise_priority() and pa_thread_make_realtime()*/
791void pa_reset_priority(void) {
792#ifdef HAVE_SYS_RESOURCE_H
793    struct sched_param sp;
794
795    setpriority(PRIO_PROCESS, 0, 0);
796
797    pa_zero(sp);
798    pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp);
799#endif
800
801#ifdef OS_IS_WIN32
802    SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
803#endif
804}
805
806/* Check whenever any substring in v matches the provided regex. */
807int pa_match(const char *expr, const char *v) {
808#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
809    int k;
810    regex_t re;
811    int r;
812
813    pa_assert(expr);
814    pa_assert(v);
815
816    if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
817        errno = EINVAL;
818        return -1;
819    }
820
821    if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
822        r = 1;
823    else if (k == REG_NOMATCH)
824        r = 0;
825    else
826        r = -1;
827
828    regfree(&re);
829
830    if (r < 0)
831        errno = EINVAL;
832
833    return r;
834#else
835    errno = ENOSYS;
836    return -1;
837#endif
838}
839
840/* Check whenever the provided regex pattern is valid. */
841bool pa_is_regex_valid(const char *expr) {
842#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
843    regex_t re;
844
845    if (expr == NULL || regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
846        return false;
847    }
848
849    regfree(&re);
850    return true;
851#else
852    return false;
853#endif
854}
855
856/* Try to parse a boolean string value.*/
857int pa_parse_boolean(const char *v) {
858    pa_assert(v);
859
860    /* First we check language independent */
861    if (pa_streq(v, "1") || !strcasecmp(v, "y") || !strcasecmp(v, "t")
862            || !strcasecmp(v, "yes") || !strcasecmp(v, "true") || !strcasecmp(v, "on"))
863        return 1;
864    else if (pa_streq(v, "0") || !strcasecmp(v, "n") || !strcasecmp(v, "f")
865                 || !strcasecmp(v, "no") || !strcasecmp(v, "false") || !strcasecmp(v, "off"))
866        return 0;
867
868#ifdef HAVE_LANGINFO_H
869{
870    const char *expr;
871    /* And then we check language dependent */
872    if ((expr = nl_langinfo(YESEXPR)))
873        if (expr[0])
874            if (pa_match(expr, v) > 0)
875                return 1;
876
877    if ((expr = nl_langinfo(NOEXPR)))
878        if (expr[0])
879            if (pa_match(expr, v) > 0)
880                return 0;
881}
882#endif
883
884    errno = EINVAL;
885    return -1;
886}
887
888/* Try to parse a volume string to pa_volume_t. The allowed formats are:
889 * db, % and unsigned integer */
890int pa_parse_volume(const char *v, pa_volume_t *volume) {
891    int len;
892    uint32_t i;
893    double d;
894    char str[64];
895
896    pa_assert(v);
897    pa_assert(volume);
898
899    len = strlen(v);
900
901    if (len <= 0 || len >= 64)
902        return -1;
903
904    memcpy(str, v, len + 1);
905
906    if (str[len - 1] == '%') {
907        str[len - 1] = '\0';
908        if (pa_atod(str, &d) < 0)
909            return -1;
910
911        d = d / 100 * PA_VOLUME_NORM;
912
913        if (d < 0 || d > PA_VOLUME_MAX)
914            return -1;
915
916        *volume = d;
917        return 0;
918    }
919
920    if (len > 2 && (str[len - 1] == 'b' || str[len - 1] == 'B') &&
921               (str[len - 2] == 'd' || str[len - 2] == 'D')) {
922        str[len - 2] = '\0';
923        if (pa_atod(str, &d) < 0)
924            return -1;
925
926        if (d > pa_sw_volume_to_dB(PA_VOLUME_MAX))
927            return -1;
928
929        *volume = pa_sw_volume_from_dB(d);
930        return 0;
931    }
932
933    if (pa_atou(v, &i) < 0 || !PA_VOLUME_IS_VALID(i))
934        return -1;
935
936    *volume = i;
937    return 0;
938}
939
940/* Split the specified string wherever one of the characters in delimiter
941 * occurs. Each time it is called returns a newly allocated string
942 * with pa_xmalloc(). The variable state points to, should be
943 * initialized to NULL before the first call. */
944char *pa_split(const char *c, const char *delimiter, const char**state) {
945    const char *current = *state ? *state : c;
946    size_t l;
947
948    if (!*current)
949        return NULL;
950
951    l = strcspn(current, delimiter);
952    *state = current+l;
953
954    if (**state)
955        (*state)++;
956
957    return pa_xstrndup(current, l);
958}
959
960/* Split the specified string wherever one of the characters in delimiter
961 * occurs. Each time it is called returns a pointer to the substring within the
962 * string and the length in 'n'. Note that the resultant string cannot be used
963 * as-is without the length parameter, since it is merely pointing to a point
964 * within the original string. The variable state points to, should be
965 * initialized to NULL before the first call. */
966const char *pa_split_in_place(const char *c, const char *delimiter, size_t *n, const char**state) {
967    const char *current = *state ? *state : c;
968    size_t l;
969
970    if (!*current)
971        return NULL;
972
973    l = strcspn(current, delimiter);
974    *state = current+l;
975
976    if (**state)
977        (*state)++;
978
979    *n = l;
980    return current;
981}
982
983/* Split a string into words. Otherwise similar to pa_split(). */
984char *pa_split_spaces(const char *c, const char **state) {
985    const char *current = *state ? *state : c;
986    size_t l;
987
988    if (!*current || *c == 0)
989        return NULL;
990
991    current += strspn(current, WHITESPACE);
992    l = strcspn(current, WHITESPACE);
993
994    *state = current+l;
995
996    return pa_xstrndup(current, l);
997}
998
999/* Similar to pa_split_spaces, except this returns a string in-place.
1000   Returned string is generally not NULL-terminated.
1001   See pa_split_in_place(). */
1002const char *pa_split_spaces_in_place(const char *c, size_t *n, const char **state) {
1003    const char *current = *state ? *state : c;
1004    size_t l;
1005
1006    if (!*current || *c == 0)
1007        return NULL;
1008
1009    current += strspn(current, WHITESPACE);
1010    l = strcspn(current, WHITESPACE);
1011
1012    *state = current+l;
1013
1014    *n = l;
1015    return current;
1016}
1017
1018PA_STATIC_TLS_DECLARE(signame, pa_xfree);
1019
1020/* Return the name of an UNIX signal. Similar to Solaris sig2str() */
1021const char *pa_sig2str(int sig) {
1022    char *t;
1023
1024    if (sig <= 0)
1025        goto fail;
1026
1027#ifdef NSIG
1028    if (sig >= NSIG)
1029        goto fail;
1030#endif
1031
1032#ifdef HAVE_SIG2STR
1033    {
1034        char buf[SIG2STR_MAX];
1035
1036        if (sig2str(sig, buf) == 0) {
1037            pa_xfree(PA_STATIC_TLS_GET(signame));
1038            t = pa_sprintf_malloc("SIG%s", buf);
1039            PA_STATIC_TLS_SET(signame, t);
1040            return t;
1041        }
1042    }
1043#else
1044
1045    switch (sig) {
1046#ifdef SIGHUP
1047        case SIGHUP:    return "SIGHUP";
1048#endif
1049        case SIGINT:    return "SIGINT";
1050#ifdef SIGQUIT
1051        case SIGQUIT:   return "SIGQUIT";
1052#endif
1053        case SIGILL:    return "SIGULL";
1054#ifdef SIGTRAP
1055        case SIGTRAP:   return "SIGTRAP";
1056#endif
1057        case SIGABRT:   return "SIGABRT";
1058#ifdef SIGBUS
1059        case SIGBUS:    return "SIGBUS";
1060#endif
1061        case SIGFPE:    return "SIGFPE";
1062#ifdef SIGKILL
1063        case SIGKILL:   return "SIGKILL";
1064#endif
1065#ifdef SIGUSR1
1066        case SIGUSR1:   return "SIGUSR1";
1067#endif
1068        case SIGSEGV:   return "SIGSEGV";
1069#ifdef SIGUSR2
1070        case SIGUSR2:   return "SIGUSR2";
1071#endif
1072#ifdef SIGPIPE
1073        case SIGPIPE:   return "SIGPIPE";
1074#endif
1075#ifdef SIGALRM
1076        case SIGALRM:   return "SIGALRM";
1077#endif
1078        case SIGTERM:   return "SIGTERM";
1079#ifdef SIGSTKFLT
1080        case SIGSTKFLT: return "SIGSTKFLT";
1081#endif
1082#ifdef SIGCHLD
1083        case SIGCHLD:   return "SIGCHLD";
1084#endif
1085#ifdef SIGCONT
1086        case SIGCONT:   return "SIGCONT";
1087#endif
1088#ifdef SIGSTOP
1089        case SIGSTOP:   return "SIGSTOP";
1090#endif
1091#ifdef SIGTSTP
1092        case SIGTSTP:   return "SIGTSTP";
1093#endif
1094#ifdef SIGTTIN
1095        case SIGTTIN:   return "SIGTTIN";
1096#endif
1097#ifdef SIGTTOU
1098        case SIGTTOU:   return "SIGTTOU";
1099#endif
1100#ifdef SIGURG
1101        case SIGURG:    return "SIGURG";
1102#endif
1103#ifdef SIGXCPU
1104        case SIGXCPU:   return "SIGXCPU";
1105#endif
1106#ifdef SIGXFSZ
1107        case SIGXFSZ:   return "SIGXFSZ";
1108#endif
1109#ifdef SIGVTALRM
1110        case SIGVTALRM: return "SIGVTALRM";
1111#endif
1112#ifdef SIGPROF
1113        case SIGPROF:   return "SIGPROF";
1114#endif
1115#ifdef SIGWINCH
1116        case SIGWINCH:  return "SIGWINCH";
1117#endif
1118#ifdef SIGIO
1119        case SIGIO:     return "SIGIO";
1120#endif
1121#ifdef SIGPWR
1122        case SIGPWR:    return "SIGPWR";
1123#endif
1124#ifdef SIGSYS
1125        case SIGSYS:    return "SIGSYS";
1126#endif
1127    }
1128
1129#ifdef SIGRTMIN
1130    if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
1131        pa_xfree(PA_STATIC_TLS_GET(signame));
1132        t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN);
1133        PA_STATIC_TLS_SET(signame, t);
1134        return t;
1135    }
1136#endif
1137
1138#endif
1139
1140fail:
1141
1142    pa_xfree(PA_STATIC_TLS_GET(signame));
1143    t = pa_sprintf_malloc("SIG%i", sig);
1144    PA_STATIC_TLS_SET(signame, t);
1145    return t;
1146}
1147
1148#ifdef HAVE_GRP_H
1149
1150/* Check whether the specified GID and the group name match */
1151static int is_group(gid_t gid, const char *name) {
1152    struct group *group = NULL;
1153    int r = -1;
1154
1155    errno = 0;
1156    if (!(group = pa_getgrgid_malloc(gid))) {
1157        if (!errno)
1158            errno = ENOENT;
1159
1160        pa_log("pa_getgrgid_malloc(%u): %s", gid, pa_cstrerror(errno));
1161
1162        goto finish;
1163    }
1164
1165    r = pa_streq(name, group->gr_name);
1166
1167finish:
1168    pa_getgrgid_free(group);
1169
1170    return r;
1171}
1172
1173/* Check the current user is member of the specified group */
1174int pa_own_uid_in_group(const char *name, gid_t *gid) {
1175    GETGROUPS_T *gids, tgid;
1176    long n = sysconf(_SC_NGROUPS_MAX);
1177    int r = -1, i, k;
1178
1179    pa_assert(n > 0);
1180
1181    gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
1182
1183    if ((n = getgroups((int) n, gids)) < 0) {
1184        pa_log("getgroups(): %s", pa_cstrerror(errno));
1185        goto finish;
1186    }
1187
1188    for (i = 0; i < n; i++) {
1189
1190        if ((k = is_group(gids[i], name)) < 0)
1191            goto finish;
1192        else if (k > 0) {
1193            *gid = gids[i];
1194            r = 1;
1195            goto finish;
1196        }
1197    }
1198
1199    if ((k = is_group(tgid = getgid(), name)) < 0)
1200        goto finish;
1201    else if (k > 0) {
1202        *gid = tgid;
1203        r = 1;
1204        goto finish;
1205    }
1206
1207    r = 0;
1208
1209finish:
1210
1211    pa_xfree(gids);
1212    return r;
1213}
1214
1215/* Check whether the specific user id is a member of the specified group */
1216int pa_uid_in_group(uid_t uid, const char *name) {
1217    struct group *group = NULL;
1218    char **i;
1219    int r = -1;
1220
1221    errno = 0;
1222    if (!(group = pa_getgrnam_malloc(name))) {
1223        if (!errno)
1224            errno = ENOENT;
1225        goto finish;
1226    }
1227
1228    r = 0;
1229    for (i = group->gr_mem; *i; i++) {
1230        struct passwd *pw = NULL;
1231
1232        errno = 0;
1233        if (!(pw = pa_getpwnam_malloc(*i)))
1234            continue;
1235
1236        if (pw->pw_uid == uid)
1237            r = 1;
1238
1239        pa_getpwnam_free(pw);
1240
1241        if (r == 1)
1242            break;
1243    }
1244
1245finish:
1246    pa_getgrnam_free(group);
1247
1248    return r;
1249}
1250
1251/* Get the GID of a given group, return (gid_t) -1 on failure. */
1252gid_t pa_get_gid_of_group(const char *name) {
1253    gid_t ret = (gid_t) -1;
1254    struct group *gr = NULL;
1255
1256    errno = 0;
1257    if (!(gr = pa_getgrnam_malloc(name))) {
1258        if (!errno)
1259            errno = ENOENT;
1260        goto finish;
1261    }
1262
1263    ret = gr->gr_gid;
1264
1265finish:
1266    pa_getgrnam_free(gr);
1267    return ret;
1268}
1269
1270int pa_check_in_group(gid_t g) {
1271    gid_t gids[NGROUPS_MAX];
1272    int r;
1273
1274    if ((r = getgroups(NGROUPS_MAX, gids)) < 0)
1275        return -1;
1276
1277    for (; r > 0; r--)
1278        if (gids[r-1] == g)
1279            return 1;
1280
1281    return 0;
1282}
1283
1284#else /* HAVE_GRP_H */
1285
1286int pa_own_uid_in_group(const char *name, gid_t *gid) {
1287    errno = ENOTSUP;
1288    return -1;
1289
1290}
1291
1292int pa_uid_in_group(uid_t uid, const char *name) {
1293    errno = ENOTSUP;
1294    return -1;
1295}
1296
1297gid_t pa_get_gid_of_group(const char *name) {
1298    errno = ENOTSUP;
1299    return (gid_t) -1;
1300}
1301
1302int pa_check_in_group(gid_t g) {
1303    errno = ENOTSUP;
1304    return -1;
1305}
1306
1307#endif
1308
1309/* Lock or unlock a file entirely.
1310  (advisory on UNIX, mandatory on Windows) */
1311int pa_lock_fd(int fd, int b) {
1312#ifdef F_SETLKW
1313    struct flock f_lock;
1314
1315    /* Try a R/W lock first */
1316
1317    f_lock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
1318    f_lock.l_whence = SEEK_SET;
1319    f_lock.l_start = 0;
1320    f_lock.l_len = 0;
1321
1322    if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1323        return 0;
1324
1325    /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
1326    if (b && errno == EBADF) {
1327        f_lock.l_type = F_RDLCK;
1328        if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
1329            return 0;
1330    }
1331
1332    pa_log("%slock: %s", !b ? "un" : "", pa_cstrerror(errno));
1333#endif
1334
1335#ifdef OS_IS_WIN32
1336    HANDLE h = (HANDLE) _get_osfhandle(fd);
1337
1338    if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1339        return 0;
1340    if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
1341        return 0;
1342
1343    pa_log("%slock failed: 0x%08lX", !b ? "un" : "", GetLastError());
1344
1345    /* FIXME: Needs to set errno! */
1346#endif
1347
1348    return -1;
1349}
1350
1351/* Remove trailing newlines from a string */
1352char* pa_strip_nl(char *s) {
1353    pa_assert(s);
1354
1355    s[strcspn(s, NEWLINE)] = 0;
1356    return s;
1357}
1358
1359char *pa_strip(char *s) {
1360    char *e, *l = NULL;
1361
1362    /* Drops trailing whitespace. Modifies the string in
1363     * place. Returns pointer to first non-space character */
1364
1365    s += strspn(s, WHITESPACE);
1366
1367    for (e = s; *e; e++)
1368        if (!strchr(WHITESPACE, *e))
1369            l = e;
1370
1371    if (l)
1372        *(l+1) = 0;
1373    else
1374        *s = 0;
1375
1376    return s;
1377}
1378
1379/* Create a temporary lock file and lock it. */
1380int pa_lock_lockfile(const char *fn) {
1381    int fd;
1382    pa_assert(fn);
1383
1384    for (;;) {
1385        struct stat st;
1386
1387        if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR
1388#ifdef O_NOFOLLOW
1389                       |O_NOFOLLOW
1390#endif
1391                       , S_IRUSR|S_IWUSR)) < 0) {
1392            pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno));
1393            goto fail;
1394        }
1395
1396        if (pa_lock_fd(fd, 1) < 0) {
1397            pa_log_warn("Failed to lock file '%s'.", fn);
1398            goto fail;
1399        }
1400
1401        if (fstat(fd, &st) < 0) {
1402            pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno));
1403            goto fail;
1404        }
1405
1406        /* Check whether the file has been removed meanwhile. When yes,
1407         * restart this loop, otherwise, we're done */
1408        if (st.st_nlink >= 1)
1409            break;
1410
1411        if (pa_lock_fd(fd, 0) < 0) {
1412            pa_log_warn("Failed to unlock file '%s'.", fn);
1413            goto fail;
1414        }
1415
1416        if (pa_close(fd) < 0) {
1417            pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
1418            fd = -1;
1419            goto fail;
1420        }
1421    }
1422
1423    return fd;
1424
1425fail:
1426
1427    if (fd >= 0) {
1428        int saved_errno = errno;
1429        pa_close(fd);
1430        errno = saved_errno;
1431    }
1432
1433    return -1;
1434}
1435
1436/* Unlock a temporary lock file */
1437int pa_unlock_lockfile(const char *fn, int fd) {
1438    int r = 0;
1439    pa_assert(fd >= 0);
1440
1441    if (fn) {
1442        if (unlink(fn) < 0) {
1443            pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno));
1444            r = -1;
1445        }
1446    }
1447
1448    if (pa_lock_fd(fd, 0) < 0) {
1449        pa_log_warn("Failed to unlock file '%s'.", fn);
1450        r = -1;
1451    }
1452
1453    if (pa_close(fd) < 0) {
1454        pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno));
1455        r = -1;
1456    }
1457
1458    return r;
1459}
1460
1461static int check_ours(const char *p) {
1462    struct stat st;
1463
1464    pa_assert(p);
1465
1466    if (stat(p, &st) < 0)
1467        return -errno;
1468
1469#ifdef HAVE_GETUID
1470    if (st.st_uid != getuid() && st.st_uid != 0)
1471        return -EACCES;
1472#endif
1473
1474    return 0;
1475}
1476
1477static char *get_pulse_home(void) {
1478    char *h, *ret;
1479    int t;
1480
1481    h = pa_get_home_dir_malloc();
1482    if (!h) {
1483        pa_log_error("Failed to get home directory.");
1484        return NULL;
1485    }
1486
1487    t = check_ours(h);
1488    if (t < 0 && t != -ENOENT) {
1489        pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t));
1490        pa_xfree(h);
1491        return NULL;
1492    }
1493
1494    /* If the old directory exists, use it. */
1495    ret = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
1496    pa_xfree(h);
1497    if (access(ret, F_OK) >= 0)
1498        return ret;
1499    free(ret);
1500
1501    /* Otherwise go for the XDG compliant directory. */
1502    if (pa_get_config_home_dir(&ret) < 0)
1503        return NULL;
1504
1505    return ret;
1506}
1507
1508char *pa_get_state_dir(void) {
1509    char *d;
1510
1511    /* The state directory shall contain dynamic data that should be
1512     * kept across reboots, and is private to this user */
1513
1514    if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
1515        if (!(d = get_pulse_home()))
1516            return NULL;
1517
1518    /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
1519     * dir then this will break. */
1520
1521    if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1, true) < 0) {
1522        pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
1523        pa_xfree(d);
1524        return NULL;
1525    }
1526
1527    return d;
1528}
1529
1530char *pa_get_home_dir_malloc(void) {
1531    char *homedir;
1532    size_t allocated = 128;
1533
1534    for (;;) {
1535        homedir = pa_xmalloc(allocated);
1536
1537        if (!pa_get_home_dir(homedir, allocated)) {
1538            pa_xfree(homedir);
1539            return NULL;
1540        }
1541
1542        if (strlen(homedir) < allocated - 1)
1543            break;
1544
1545        pa_xfree(homedir);
1546        allocated *= 2;
1547    }
1548
1549    return homedir;
1550}
1551
1552int pa_append_to_home_dir(const char *path, char **_r) {
1553    char *home_dir;
1554
1555    pa_assert(path);
1556    pa_assert(_r);
1557
1558    home_dir = pa_get_home_dir_malloc();
1559    if (!home_dir) {
1560        pa_log("Failed to get home directory.");
1561        return -PA_ERR_NOENTITY;
1562    }
1563
1564    *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", home_dir, path);
1565    pa_xfree(home_dir);
1566    return 0;
1567}
1568
1569int pa_get_config_home_dir(char **_r) {
1570    const char *e;
1571    char *home_dir;
1572
1573    pa_assert(_r);
1574
1575    e = getenv("XDG_CONFIG_HOME");
1576    if (e && *e) {
1577        *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", e);
1578        return 0;
1579    }
1580
1581    home_dir = pa_get_home_dir_malloc();
1582    if (!home_dir)
1583        return -PA_ERR_NOENTITY;
1584
1585    *_r = pa_sprintf_malloc("%s" PA_PATH_SEP ".config" PA_PATH_SEP "pulse", home_dir);
1586    pa_xfree(home_dir);
1587    return 0;
1588}
1589
1590int pa_get_data_home_dir(char **_r) {
1591    const char *e;
1592    char *home_dir;
1593
1594    pa_assert(_r);
1595
1596    e = getenv("XDG_DATA_HOME");
1597    if (e && *e) {
1598        if (pa_is_path_absolute(e)) {
1599            *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "pulseaudio", e);
1600            return 0;
1601        }
1602        else
1603            pa_log_warn("Ignored non-absolute XDG_DATA_HOME value '%s'", e);
1604    }
1605
1606    home_dir = pa_get_home_dir_malloc();
1607    if (!home_dir)
1608        return -PA_ERR_NOENTITY;
1609
1610    *_r = pa_sprintf_malloc("%s" PA_PATH_SEP ".local" PA_PATH_SEP "share" PA_PATH_SEP "pulseaudio", home_dir);
1611    pa_xfree(home_dir);
1612    return 0;
1613}
1614
1615int pa_get_data_dirs(pa_dynarray **_r) {
1616    const char *e;
1617    const char *def = "/usr/local/share/:/usr/share/";
1618    const char *p;
1619    const char *split_state = NULL;
1620    char *n;
1621    pa_dynarray *paths;
1622
1623    pa_assert(_r);
1624
1625    e = getenv("XDG_DATA_DIRS");
1626    p = e && *e ? e : def;
1627
1628    paths = pa_dynarray_new((pa_free_cb_t) pa_xfree);
1629
1630    while ((n = pa_split(p, ":", &split_state))) {
1631        char *path;
1632
1633        if (!pa_is_path_absolute(n)) {
1634            pa_log_warn("Ignored non-absolute path '%s' in XDG_DATA_DIRS", n);
1635            pa_xfree(n);
1636            continue;
1637        }
1638
1639        path = pa_sprintf_malloc("%s" PA_PATH_SEP "pulseaudio", n);
1640        pa_xfree(n);
1641        pa_dynarray_append(paths, path);
1642    }
1643
1644    if (pa_dynarray_size(paths) == 0) {
1645        pa_log_warn("XDG_DATA_DIRS contains no valid paths");
1646        pa_dynarray_free(paths);
1647        return -PA_ERR_INVALID;
1648    }
1649
1650    *_r = paths;
1651    return 0;
1652}
1653
1654int pa_append_to_config_home_dir(const char *path, char **_r) {
1655    int r;
1656    char *config_home_dir;
1657
1658    pa_assert(path);
1659    pa_assert(_r);
1660
1661    r = pa_get_config_home_dir(&config_home_dir);
1662    if (r < 0)
1663        return r;
1664
1665    *_r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", config_home_dir, path);
1666    pa_xfree(config_home_dir);
1667    return 0;
1668}
1669
1670char *pa_get_binary_name_malloc(void) {
1671    char *t;
1672    size_t allocated = 128;
1673
1674    for (;;) {
1675        t = pa_xmalloc(allocated);
1676
1677        if (!pa_get_binary_name(t, allocated)) {
1678            pa_xfree(t);
1679            return NULL;
1680        }
1681
1682        if (strlen(t) < allocated - 1)
1683            break;
1684
1685        pa_xfree(t);
1686        allocated *= 2;
1687    }
1688
1689    return t;
1690}
1691
1692static char* make_random_dir(mode_t m) {
1693    static const char table[] =
1694        "abcdefghijklmnopqrstuvwxyz"
1695        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1696        "0123456789";
1697
1698    char *fn;
1699    size_t pathlen;
1700
1701    fn = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse-XXXXXXXXXXXX", pa_get_temp_dir());
1702    pathlen = strlen(fn);
1703
1704    for (;;) {
1705        size_t i;
1706        int r;
1707        mode_t u;
1708        int saved_errno;
1709
1710        for (i = pathlen - 12; i < pathlen; i++)
1711            fn[i] = table[rand() % (sizeof(table)-1)];
1712
1713        u = umask((~m) & 0777);
1714#ifndef OS_IS_WIN32
1715        r = mkdir(fn, m);
1716#else
1717        r = mkdir(fn);
1718#endif
1719
1720        saved_errno = errno;
1721        umask(u);
1722        errno = saved_errno;
1723
1724        if (r >= 0)
1725            return fn;
1726
1727        if (errno != EEXIST) {
1728            pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
1729            pa_xfree(fn);
1730            return NULL;
1731        }
1732    }
1733}
1734
1735static int make_random_dir_and_link(mode_t m, const char *k) {
1736    char *p;
1737
1738    if (!(p = make_random_dir(m)))
1739        return -1;
1740
1741#ifdef HAVE_SYMLINK
1742    if (symlink(p, k) < 0) {
1743        int saved_errno = errno;
1744
1745        if (errno != EEXIST)
1746            pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
1747
1748        rmdir(p);
1749        pa_xfree(p);
1750
1751        errno = saved_errno;
1752        return -1;
1753    }
1754#else
1755    pa_xfree(p);
1756    return -1;
1757#endif
1758
1759    pa_xfree(p);
1760    return 0;
1761}
1762
1763char *pa_get_runtime_dir(void) {
1764    char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
1765    mode_t m;
1766
1767    /* The runtime directory shall contain dynamic data that needs NOT
1768     * to be kept across reboots and is usually private to the user,
1769     * except in system mode, where it might be accessible by other
1770     * users, too. Since we need POSIX locking and UNIX sockets in
1771     * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
1772     * set create a directory in $HOME and link it to a random subdir
1773     * in /tmp, if it was not explicitly configured. */
1774
1775    m = pa_in_system_mode() ? 0755U : 0755U;
1776
1777    /* Use the explicitly configured value if it is set */
1778    d = getenv("PULSE_RUNTIME_PATH");
1779    if (d) {
1780
1781        if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, true) < 0) {
1782            pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
1783            goto fail;
1784        }
1785
1786        return pa_xstrdup(d);
1787    }
1788
1789    /* Use the XDG standard for the runtime directory. */
1790    d = getenv("XDG_RUNTIME_DIR");
1791    if (d) {
1792#ifdef HAVE_GETUID
1793        struct stat st;
1794        if (stat(d, &st) == 0 && st.st_uid != getuid()) {
1795            pa_log(_("XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d! "
1796                   "(This could e.g. happen if you try to connect to a non-root PulseAudio as a root user, over the native protocol. Don't do that.)"),
1797                   d, getuid(), st.st_uid);
1798            goto fail;
1799        }
1800#endif
1801
1802        k = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", d);
1803
1804        if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1, true) < 0) {
1805            pa_log_error("Failed to create secure directory (%s): %s", k, pa_cstrerror(errno));
1806            goto fail;
1807        }
1808
1809        return k;
1810    }
1811
1812    /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
1813    d = get_pulse_home();
1814    if (!d)
1815        goto fail;
1816
1817    if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, true) < 0) {
1818        pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
1819        pa_xfree(d);
1820        goto fail;
1821    }
1822
1823    mid = pa_machine_id();
1824    if (!mid) {
1825        pa_xfree(d);
1826        goto fail;
1827    }
1828
1829    k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-runtime", d, mid);
1830    pa_xfree(d);
1831    pa_xfree(mid);
1832
1833    for (;;) {
1834        /* OK, first let's check if the "runtime" symlink already exists */
1835
1836        p = pa_readlink(k);
1837        if (!p) {
1838
1839            if (errno != ENOENT) {
1840                pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
1841                goto fail;
1842            }
1843
1844#ifdef HAVE_SYMLINK
1845            /* Hmm, so the runtime directory didn't exist yet, so let's
1846             * create one in /tmp and symlink that to it */
1847
1848            if (make_random_dir_and_link(0700, k) < 0) {
1849
1850                /* Mhmm, maybe another process was quicker than us,
1851                 * let's check if that was valid */
1852                if (errno == EEXIST)
1853                    continue;
1854
1855                goto fail;
1856            }
1857#else
1858            /* No symlink possible, so let's just create the runtime directly
1859             * Do not check again if it exists since it cannot be a symlink */
1860            if (mkdir(k) < 0 && errno != EEXIST)
1861                goto fail;
1862#endif
1863
1864            return k;
1865        }
1866
1867        /* Make sure that this actually makes sense */
1868        if (!pa_is_path_absolute(p)) {
1869            pa_log_error("Path %s in link %s is not absolute.", p, k);
1870            errno = ENOENT;
1871            goto fail;
1872        }
1873
1874        /* Hmm, so this symlink is still around, make sure nobody fools us */
1875#ifdef HAVE_LSTAT
1876{
1877        struct stat st;
1878        if (lstat(p, &st) < 0) {
1879
1880            if (errno != ENOENT) {
1881                pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
1882                goto fail;
1883            }
1884
1885        } else {
1886
1887            if (S_ISDIR(st.st_mode) &&
1888                (st.st_uid == getuid()) &&
1889                ((st.st_mode & 0777) == 0700)) {
1890
1891                pa_xfree(p);
1892                return k;
1893            }
1894
1895            pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
1896        }
1897}
1898#endif
1899
1900        pa_xfree(p);
1901        p = NULL;
1902
1903        /* Hmm, so the link points to some nonexisting or invalid
1904         * dir. Let's replace it by a new link. We first create a
1905         * temporary link and then rename that to allow concurrent
1906         * execution of this function. */
1907
1908        t = pa_sprintf_malloc("%s.tmp", k);
1909
1910        if (make_random_dir_and_link(0700, t) < 0) {
1911
1912            if (errno != EEXIST) {
1913                pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
1914                goto fail;
1915            }
1916
1917            pa_xfree(t);
1918            t = NULL;
1919
1920            /* Hmm, someone else was quicker then us. Let's give
1921             * him some time to finish, and retry. */
1922            pa_msleep(10);
1923            continue;
1924        }
1925
1926        /* OK, we succeeded in creating the temporary symlink, so
1927         * let's rename it */
1928        if (rename(t, k) < 0) {
1929            pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
1930            goto fail;
1931        }
1932
1933        pa_xfree(t);
1934        return k;
1935    }
1936
1937fail:
1938    pa_xfree(p);
1939    pa_xfree(k);
1940    pa_xfree(t);
1941
1942    return NULL;
1943}
1944
1945/* Try to open a configuration file. If "env" is specified, open the
1946 * value of the specified environment variable. Otherwise look for a
1947 * file "local" in the home directory or a file "global" in global
1948 * file system. If "result" is non-NULL, a pointer to a newly
1949 * allocated buffer containing the used configuration file is
1950 * stored there.*/
1951FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
1952    const char *fn;
1953    FILE *f;
1954
1955    if (env && (fn = getenv(env))) {
1956        if ((f = pa_fopen_cloexec(fn, "r"))) {
1957            if (result)
1958                *result = pa_xstrdup(fn);
1959
1960            return f;
1961        }
1962
1963        pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1964        return NULL;
1965    }
1966
1967    if (local) {
1968        const char *e;
1969        char *lfn;
1970        char *h;
1971
1972        if ((e = getenv("PULSE_CONFIG_PATH"))) {
1973            fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
1974            f = pa_fopen_cloexec(fn, "r");
1975        } else if ((h = pa_get_home_dir_malloc())) {
1976            fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
1977            f = pa_fopen_cloexec(fn, "r");
1978            if (!f) {
1979                free(lfn);
1980                fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".config/pulse" PA_PATH_SEP "%s", h, local);
1981                f = pa_fopen_cloexec(fn, "r");
1982            }
1983            pa_xfree(h);
1984        } else
1985            return NULL;
1986
1987        if (f) {
1988            if (result)
1989                *result = pa_xstrdup(fn);
1990
1991            pa_xfree(lfn);
1992            return f;
1993        }
1994
1995        if (errno != ENOENT) {
1996            pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
1997            pa_xfree(lfn);
1998            return NULL;
1999        }
2000
2001        pa_xfree(lfn);
2002    }
2003
2004    if (global) {
2005        char *gfn;
2006
2007#ifdef OS_IS_WIN32
2008        if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
2009            gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
2010                                    pa_win32_get_toplevel(NULL),
2011                                    global + strlen(PA_DEFAULT_CONFIG_DIR));
2012        else
2013#endif
2014        gfn = pa_xstrdup(global);
2015
2016        if ((f = pa_fopen_cloexec(gfn, "r"))) {
2017            if (result)
2018                *result = gfn;
2019            else
2020                pa_xfree(gfn);
2021
2022            return f;
2023        }
2024        pa_xfree(gfn);
2025    }
2026
2027    errno = ENOENT;
2028    return NULL;
2029}
2030
2031char *pa_find_config_file(const char *global, const char *local, const char *env) {
2032    const char *fn;
2033
2034    if (env && (fn = getenv(env))) {
2035        if (access(fn, R_OK) == 0)
2036            return pa_xstrdup(fn);
2037
2038        pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
2039        return NULL;
2040    }
2041
2042    if (local) {
2043        const char *e;
2044        char *lfn;
2045        char *h;
2046
2047        if ((e = getenv("PULSE_CONFIG_PATH")))
2048            fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
2049        else if ((h = pa_get_home_dir_malloc())) {
2050            fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
2051            pa_xfree(h);
2052        } else
2053            return NULL;
2054
2055        if (access(fn, R_OK) == 0) {
2056            char *r = pa_xstrdup(fn);
2057            pa_xfree(lfn);
2058            return r;
2059        }
2060
2061        if (errno != ENOENT) {
2062            pa_log_warn("Failed to access configuration file '%s': %s", fn, pa_cstrerror(errno));
2063            pa_xfree(lfn);
2064            return NULL;
2065        }
2066
2067        pa_xfree(lfn);
2068    }
2069
2070    if (global) {
2071        char *gfn;
2072
2073#ifdef OS_IS_WIN32
2074        if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
2075            gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
2076                                    pa_win32_get_toplevel(NULL),
2077                                    global + strlen(PA_DEFAULT_CONFIG_DIR));
2078        else
2079#endif
2080        gfn = pa_xstrdup(global);
2081
2082        if (access(gfn, R_OK) == 0)
2083            return gfn;
2084        pa_xfree(gfn);
2085    }
2086
2087    errno = ENOENT;
2088
2089    return NULL;
2090}
2091
2092/* Format the specified data as a hexademical string */
2093char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
2094    size_t i = 0, j = 0;
2095    const char hex[] = "0123456789abcdef";
2096
2097    pa_assert(d);
2098    pa_assert(s);
2099    pa_assert(slength > 0);
2100
2101    while (j+2 < slength && i < dlength) {
2102        s[j++] = hex[*d >> 4];
2103        s[j++] = hex[*d & 0xF];
2104
2105        d++;
2106        i++;
2107    }
2108
2109    s[j < slength ? j : slength] = 0;
2110    return s;
2111}
2112
2113/* Convert a hexadecimal digit to a number or -1 if invalid */
2114static int hexc(char c) {
2115    if (c >= '0' && c <= '9')
2116        return c - '0';
2117
2118    if (c >= 'A' && c <= 'F')
2119        return c - 'A' + 10;
2120
2121    if (c >= 'a' && c <= 'f')
2122        return c - 'a' + 10;
2123
2124    errno = EINVAL;
2125    return -1;
2126}
2127
2128/* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */
2129size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {
2130    size_t j = 0;
2131
2132    pa_assert(p);
2133    pa_assert(d);
2134
2135    while (j < dlength && *p) {
2136        int b;
2137
2138        if ((b = hexc(*(p++))) < 0)
2139            return (size_t) -1;
2140
2141        d[j] = (uint8_t) (b << 4);
2142
2143        if (!*p)
2144            return (size_t) -1;
2145
2146        if ((b = hexc(*(p++))) < 0)
2147            return (size_t) -1;
2148
2149        d[j] |= (uint8_t) b;
2150        j++;
2151    }
2152
2153    return j;
2154}
2155
2156/* Returns nonzero when *s starts with *pfx */
2157bool pa_startswith(const char *s, const char *pfx) {
2158    size_t l;
2159
2160    pa_assert(s);
2161    pa_assert(pfx);
2162
2163    l = strlen(pfx);
2164
2165    return strlen(s) >= l && strncmp(s, pfx, l) == 0;
2166}
2167
2168/* Returns nonzero when *s ends with *sfx */
2169bool pa_endswith(const char *s, const char *sfx) {
2170    size_t l1, l2;
2171
2172    pa_assert(s);
2173    pa_assert(sfx);
2174
2175    l1 = strlen(s);
2176    l2 = strlen(sfx);
2177
2178    return l1 >= l2 && pa_streq(s + l1 - l2, sfx);
2179}
2180
2181bool pa_is_path_absolute(const char *fn) {
2182    pa_assert(fn);
2183
2184#ifndef OS_IS_WIN32
2185    return *fn == '/';
2186#else
2187    return strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\';
2188#endif
2189}
2190
2191char *pa_make_path_absolute(const char *p) {
2192    char *r;
2193    char *cwd;
2194
2195    pa_assert(p);
2196
2197    if (pa_is_path_absolute(p))
2198        return pa_xstrdup(p);
2199
2200    if (!(cwd = pa_getcwd()))
2201        return pa_xstrdup(p);
2202
2203    r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", cwd, p);
2204    pa_xfree(cwd);
2205    return r;
2206}
2207
2208/* If fn is NULL, return the PulseAudio runtime or state dir (depending on the
2209 * rt parameter). If fn is non-NULL and starts with /, return fn. Otherwise,
2210 * append fn to the runtime/state dir and return it. */
2211static char *get_path(const char *fn, bool prependmid, bool rt) {
2212    char *rtp;
2213
2214    rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
2215
2216    if (fn) {
2217        char *r, *canonical_rtp;
2218
2219        if (pa_is_path_absolute(fn)) {
2220            pa_xfree(rtp);
2221            return pa_xstrdup(fn);
2222        }
2223
2224        if (!rtp)
2225            return NULL;
2226
2227        /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
2228        if ((canonical_rtp = pa_realpath(rtp))) {
2229            if (strlen(rtp) >= strlen(canonical_rtp))
2230                pa_xfree(rtp);
2231            else {
2232                pa_xfree(canonical_rtp);
2233                canonical_rtp = rtp;
2234            }
2235        } else
2236            canonical_rtp = rtp;
2237
2238        if (prependmid) {
2239            char *mid;
2240
2241            if (!(mid = pa_machine_id())) {
2242                pa_xfree(canonical_rtp);
2243                return NULL;
2244            }
2245
2246            r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-%s", canonical_rtp, mid, fn);
2247            pa_xfree(mid);
2248        } else
2249            r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", canonical_rtp, fn);
2250
2251        pa_xfree(canonical_rtp);
2252        return r;
2253    } else
2254        return rtp;
2255}
2256
2257char *pa_runtime_path(const char *fn) {
2258    return get_path(fn, false, true);
2259}
2260
2261char *pa_state_path(const char *fn, bool appendmid) {
2262    return get_path(fn, appendmid, false);
2263}
2264
2265/* Convert the string s to a signed integer in *ret_i */
2266int pa_atoi(const char *s, int32_t *ret_i) {
2267    long l;
2268
2269    pa_assert(s);
2270    pa_assert(ret_i);
2271
2272    if (pa_atol(s, &l) < 0)
2273        return -1;
2274
2275    if (l < INT32_MIN || l > INT32_MAX) {
2276        errno = ERANGE;
2277        return -1;
2278    }
2279
2280    *ret_i = (int32_t) l;
2281
2282    return 0;
2283}
2284
2285enum numtype {
2286    NUMTYPE_UINT,
2287    NUMTYPE_INT,
2288    NUMTYPE_DOUBLE,
2289};
2290
2291/* A helper function for pa_atou() and friends. This does some common checks,
2292 * because our number parsing is more strict than the strtoX functions.
2293 *
2294 * Leading zeros are stripped from integers so that they don't get parsed as
2295 * octal (but "0x" is preserved for hexadecimal numbers). For NUMTYPE_INT the
2296 * zero stripping may involve allocating a new string, in which case it's
2297 * stored in tmp. Otherwise tmp is set to NULL. The caller needs to free tmp
2298 * after they're done with ret. When parsing other types than NUMTYPE_INT the
2299 * caller can pass NULL as tmp.
2300 *
2301 * The final string to parse is returned in ret. ret will point either inside
2302 * s or to tmp. */
2303static int prepare_number_string(const char *s, enum numtype type, char **tmp, const char **ret) {
2304    const char *original = s;
2305    bool negative = false;
2306
2307    pa_assert(s);
2308    pa_assert(type != NUMTYPE_INT || tmp);
2309    pa_assert(ret);
2310
2311    if (tmp)
2312        *tmp = NULL;
2313
2314    /* The strtoX functions accept leading spaces, we don't. */
2315    if (isspace((unsigned char) s[0]))
2316        return -1;
2317
2318    /* The strtoX functions accept a plus sign, we don't. */
2319    if (s[0] == '+')
2320        return -1;
2321
2322    /* The strtoul and strtoull functions allow a minus sign even though they
2323     * parse an unsigned number. In case of a minus sign the original negative
2324     * number gets negated. We don't want that kind of behviour. */
2325    if (type == NUMTYPE_UINT && s[0] == '-')
2326        return -1;
2327
2328    /* The strtoX functions interpret the number as octal if it starts with
2329     * a zero. We prefer to use base 10, so we strip all leading zeros (if the
2330     * string starts with "0x", strtoul() interprets it as hexadecimal, which
2331     * is fine, because it's unambiguous unlike octal).
2332     *
2333     * While stripping the leading zeros, we have to remember to also handle
2334     * the case where the number is negative, which makes the zero skipping
2335     * code somewhat complex. */
2336
2337    /* Doubles don't need zero stripping, we can finish now. */
2338    if (type == NUMTYPE_DOUBLE)
2339        goto finish;
2340
2341    if (s[0] == '-') {
2342        negative = true;
2343        s++; /* Skip the minus sign. */
2344    }
2345
2346    /* Don't skip zeros if the string starts with "0x". */
2347    if (s[0] == '0' && s[1] != 'x') {
2348        while (s[0] == '0' && s[1])
2349            s++; /* Skip zeros. */
2350    }
2351
2352    if (negative) {
2353        s--; /* Go back one step, we need the minus sign back. */
2354
2355        /* If s != original, then we have skipped some zeros and we need to replace
2356         * the last skipped zero with a minus sign. */
2357        if (s != original) {
2358            *tmp = pa_xstrdup(s);
2359            *tmp[0] = '-';
2360            s = *tmp;
2361        }
2362    }
2363
2364finish:
2365    *ret = s;
2366    return 0;
2367}
2368
2369/* Convert the string s to an unsigned integer in *ret_u */
2370int pa_atou(const char *s, uint32_t *ret_u) {
2371    char *x = NULL;
2372    unsigned long l;
2373
2374    pa_assert(s);
2375    pa_assert(ret_u);
2376
2377    if (prepare_number_string(s, NUMTYPE_UINT, NULL, &s) < 0) {
2378        errno = EINVAL;
2379        return -1;
2380    }
2381
2382    errno = 0;
2383    l = strtoul(s, &x, 0);
2384
2385    /* If x doesn't point to the end of s, there was some trailing garbage in
2386     * the string. If x points to s, no conversion was done (empty string). */
2387    if (!x || *x || x == s || errno) {
2388        if (!errno)
2389            errno = EINVAL;
2390        return -1;
2391    }
2392
2393    if (l > UINT32_MAX) {
2394        errno = ERANGE;
2395        return -1;
2396    }
2397
2398    *ret_u = (uint32_t) l;
2399
2400    return 0;
2401}
2402
2403/* Convert the string s to an unsigned 64 bit integer in *ret_u */
2404int pa_atou64(const char *s, uint64_t *ret_u) {
2405    char *x = NULL;
2406    unsigned long long l;
2407
2408    pa_assert(s);
2409    pa_assert(ret_u);
2410
2411    if (prepare_number_string(s, NUMTYPE_UINT, NULL, &s) < 0) {
2412        errno = EINVAL;
2413        return -1;
2414    }
2415
2416    errno = 0;
2417    l = strtoull(s, &x, 0);
2418
2419    /* If x doesn't point to the end of s, there was some trailing garbage in
2420     * the string. If x points to s, no conversion was done (empty string). */
2421    if (!x || *x || x == s || errno) {
2422        if (!errno)
2423            errno = EINVAL;
2424        return -1;
2425    }
2426
2427    if (l > UINT64_MAX) {
2428        errno = ERANGE;
2429        return -1;
2430    }
2431
2432    *ret_u = (uint64_t) l;
2433
2434    return 0;
2435}
2436
2437/* Convert the string s to a signed long integer in *ret_l. */
2438int pa_atol(const char *s, long *ret_l) {
2439    char *tmp;
2440    char *x = NULL;
2441    long l;
2442
2443    pa_assert(s);
2444    pa_assert(ret_l);
2445
2446    if (prepare_number_string(s, NUMTYPE_INT, &tmp, &s) < 0) {
2447        errno = EINVAL;
2448        return -1;
2449    }
2450
2451    errno = 0;
2452    l = strtol(s, &x, 0);
2453
2454    /* If x doesn't point to the end of s, there was some trailing garbage in
2455     * the string. If x points to s, no conversion was done (at least an empty
2456     * string can trigger this). */
2457    if (!x || *x || x == s || errno) {
2458        if (!errno)
2459            errno = EINVAL;
2460        pa_xfree(tmp);
2461        return -1;
2462    }
2463
2464    pa_xfree(tmp);
2465
2466    *ret_l = l;
2467
2468    return 0;
2469}
2470
2471/* Convert the string s to a signed 64 bit integer in *ret_l. */
2472int pa_atoi64(const char *s, int64_t *ret_l) {
2473    char *tmp;
2474    char *x = NULL;
2475    long long l;
2476
2477    pa_assert(s);
2478    pa_assert(ret_l);
2479
2480    if (prepare_number_string(s, NUMTYPE_INT, &tmp, &s) < 0) {
2481        errno = EINVAL;
2482        return -1;
2483    }
2484
2485    errno = 0;
2486    l = strtoll(s, &x, 0);
2487
2488    /* If x doesn't point to the end of s, there was some trailing garbage in
2489     * the string. If x points to s, no conversion was done (at least an empty
2490     * string can trigger this). */
2491    if (!x || *x || x == s || errno) {
2492        if (!errno)
2493            errno = EINVAL;
2494        pa_xfree(tmp);
2495        return -1;
2496    }
2497
2498    pa_xfree(tmp);
2499
2500    *ret_l = l;
2501
2502    if (l < INT64_MIN || l > INT64_MAX) {
2503        errno = ERANGE;
2504        return -1;
2505    }
2506
2507    return 0;
2508}
2509
2510#ifdef HAVE_STRTOD_L
2511static locale_t c_locale = NULL;
2512
2513static void c_locale_destroy(void) {
2514    freelocale(c_locale);
2515}
2516#endif
2517
2518int pa_atod(const char *s, double *ret_d) {
2519    char *x = NULL;
2520    double f;
2521
2522    pa_assert(s);
2523    pa_assert(ret_d);
2524
2525    if (prepare_number_string(s, NUMTYPE_DOUBLE, NULL, &s) < 0) {
2526        errno = EINVAL;
2527        return -1;
2528    }
2529
2530    /* This should be locale independent */
2531
2532#ifdef HAVE_STRTOD_L
2533
2534    PA_ONCE_BEGIN {
2535
2536        if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
2537            atexit(c_locale_destroy);
2538
2539    } PA_ONCE_END;
2540
2541    if (c_locale) {
2542        errno = 0;
2543        f = strtod_l(s, &x, c_locale);
2544    } else
2545#endif
2546    {
2547        errno = 0;
2548        f = strtod(s, &x);
2549    }
2550
2551    /* If x doesn't point to the end of s, there was some trailing garbage in
2552     * the string. If x points to s, no conversion was done (at least an empty
2553     * string can trigger this). */
2554    if (!x || *x || x == s || errno) {
2555        if (!errno)
2556            errno = EINVAL;
2557        return -1;
2558    }
2559
2560    if (isnan(f)) {
2561        errno = EINVAL;
2562        return -1;
2563    }
2564
2565    *ret_d = f;
2566
2567    return 0;
2568}
2569
2570/* Same as snprintf, but guarantees NUL-termination on every platform */
2571size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
2572    size_t ret;
2573    va_list ap;
2574
2575    pa_assert(str);
2576    pa_assert(size > 0);
2577    pa_assert(format);
2578
2579    va_start(ap, format);
2580    ret = pa_vsnprintf(str, size, format, ap);
2581    va_end(ap);
2582
2583    return ret;
2584}
2585
2586/* Same as vsnprintf, but guarantees NUL-termination on every platform */
2587size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
2588    int ret;
2589
2590    pa_assert(str);
2591    pa_assert(size > 0);
2592    pa_assert(format);
2593
2594    ret = vsnprintf(str, size, format, ap);
2595
2596    str[size-1] = 0;
2597
2598    if (ret < 0)
2599        return strlen(str);
2600
2601    if ((size_t) ret > size-1)
2602        return size-1;
2603
2604    return (size_t) ret;
2605}
2606
2607/* Truncate the specified string, but guarantee that the string
2608 * returned still validates as UTF8 */
2609char *pa_truncate_utf8(char *c, size_t l) {
2610    pa_assert(c);
2611    pa_assert(pa_utf8_valid(c));
2612
2613    if (strlen(c) <= l)
2614        return c;
2615
2616    c[l] = 0;
2617
2618    while (l > 0 && !pa_utf8_valid(c))
2619        c[--l] = 0;
2620
2621    return c;
2622}
2623
2624char *pa_getcwd(void) {
2625    size_t l = 128;
2626
2627    for (;;) {
2628        char *p = pa_xmalloc(l);
2629        if (getcwd(p, l))
2630            return p;
2631
2632        if (errno != ERANGE) {
2633            pa_xfree(p);
2634            return NULL;
2635        }
2636
2637        pa_xfree(p);
2638        l *= 2;
2639    }
2640}
2641
2642void *pa_will_need(const void *p, size_t l) {
2643#ifdef RLIMIT_MEMLOCK
2644    struct rlimit rlim;
2645#endif
2646    const void *a;
2647    size_t size;
2648    int r = ENOTSUP;
2649    size_t bs;
2650    const size_t page_size = pa_page_size();
2651
2652    pa_assert(p);
2653    pa_assert(l > 0);
2654
2655    a = PA_PAGE_ALIGN_PTR(p);
2656    size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
2657
2658#ifdef HAVE_POSIX_MADVISE
2659    if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
2660        pa_log_debug("posix_madvise() worked fine!");
2661        return (void*) p;
2662    }
2663#endif
2664
2665    /* Most likely the memory was not mmap()ed from a file and thus
2666     * madvise() didn't work, so let's misuse mlock() do page this
2667     * stuff back into RAM. Yeah, let's fuck with the MM!  It's so
2668     * inviting, the man page of mlock() tells us: "All pages that
2669     * contain a part of the specified address range are guaranteed to
2670     * be resident in RAM when the call returns successfully." */
2671
2672#ifdef RLIMIT_MEMLOCK
2673    pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
2674
2675    if (rlim.rlim_cur < page_size) {
2676        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));
2677        errno = EPERM;
2678        return (void*) p;
2679    }
2680
2681    bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
2682#else
2683    bs = page_size*4;
2684#endif
2685
2686    pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r));
2687
2688#ifdef HAVE_MLOCK
2689    while (size > 0 && bs > 0) {
2690
2691        if (bs > size)
2692            bs = size;
2693
2694        if (mlock(a, bs) < 0) {
2695            bs = PA_PAGE_ALIGN(bs / 2);
2696            continue;
2697        }
2698
2699        pa_assert_se(munlock(a, bs) == 0);
2700
2701        a = (const uint8_t*) a + bs;
2702        size -= bs;
2703    }
2704#endif
2705
2706    if (bs <= 0)
2707        pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno));
2708    else
2709        pa_log_debug("mlock() worked fine!");
2710
2711    return (void*) p;
2712}
2713
2714void pa_close_pipe(int fds[2]) {
2715    pa_assert(fds);
2716
2717    if (fds[0] >= 0)
2718        pa_assert_se(pa_close(fds[0]) == 0);
2719
2720    if (fds[1] >= 0)
2721        pa_assert_se(pa_close(fds[1]) == 0);
2722
2723    fds[0] = fds[1] = -1;
2724}
2725
2726char *pa_readlink(const char *p) {
2727#ifdef HAVE_READLINK
2728    size_t l = 100;
2729
2730    for (;;) {
2731        char *c;
2732        ssize_t n;
2733
2734        c = pa_xmalloc(l);
2735
2736        if ((n = readlink(p, c, l-1)) < 0) {
2737            pa_xfree(c);
2738            return NULL;
2739        }
2740
2741        if ((size_t) n < l-1) {
2742            c[n] = 0;
2743            return c;
2744        }
2745
2746        pa_xfree(c);
2747        l *= 2;
2748    }
2749#else
2750    return NULL;
2751#endif
2752}
2753
2754int pa_close_all(int except_fd, ...) {
2755    va_list ap;
2756    unsigned n = 0, i;
2757    int r, *p;
2758
2759    va_start(ap, except_fd);
2760
2761    if (except_fd >= 0)
2762        for (n = 1; va_arg(ap, int) >= 0; n++)
2763            ;
2764
2765    va_end(ap);
2766
2767    p = pa_xnew(int, n+1);
2768
2769    va_start(ap, except_fd);
2770
2771    i = 0;
2772    if (except_fd >= 0) {
2773        int fd;
2774        p[i++] = except_fd;
2775
2776        while ((fd = va_arg(ap, int)) >= 0)
2777            p[i++] = fd;
2778    }
2779    p[i] = -1;
2780
2781    va_end(ap);
2782
2783    r = pa_close_allv(p);
2784    pa_xfree(p);
2785
2786    return r;
2787}
2788
2789int pa_close_allv(const int except_fds[]) {
2790#ifndef OS_IS_WIN32
2791    struct rlimit rl;
2792    int maxfd, fd;
2793
2794#if defined(__linux__) || defined(__sun)
2795    int saved_errno;
2796    DIR *d;
2797
2798    if ((d = opendir("/proc/self/fd"))) {
2799
2800        struct dirent *de;
2801
2802        while ((de = readdir(d))) {
2803            bool found;
2804            long l;
2805            char *e = NULL;
2806            int i;
2807
2808            if (de->d_name[0] == '.')
2809                continue;
2810
2811            errno = 0;
2812            l = strtol(de->d_name, &e, 10);
2813            if (errno != 0 || !e || *e) {
2814                closedir(d);
2815                errno = EINVAL;
2816                return -1;
2817            }
2818
2819            fd = (int) l;
2820
2821            if ((long) fd != l) {
2822                closedir(d);
2823                errno = EINVAL;
2824                return -1;
2825            }
2826
2827            if (fd < 3)
2828                continue;
2829
2830            if (fd == dirfd(d))
2831                continue;
2832
2833            found = false;
2834            for (i = 0; except_fds[i] >= 0; i++)
2835                if (except_fds[i] == fd) {
2836                    found = true;
2837                    break;
2838                }
2839
2840            if (found)
2841                continue;
2842
2843            if (pa_close(fd) < 0) {
2844                saved_errno = errno;
2845                closedir(d);
2846                errno = saved_errno;
2847
2848                return -1;
2849            }
2850        }
2851
2852        closedir(d);
2853        return 0;
2854    }
2855
2856#endif
2857
2858    if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
2859        maxfd = (int) rl.rlim_max;
2860    else
2861        maxfd = sysconf(_SC_OPEN_MAX);
2862
2863    for (fd = 3; fd < maxfd; fd++) {
2864        int i;
2865        bool found;
2866
2867        found = false;
2868        for (i = 0; except_fds[i] >= 0; i++)
2869            if (except_fds[i] == fd) {
2870                found = true;
2871                break;
2872            }
2873
2874        if (found)
2875            continue;
2876
2877        if (pa_close(fd) < 0 && errno != EBADF)
2878            return -1;
2879    }
2880#endif  /* !OS_IS_WIN32 */
2881
2882    return 0;
2883}
2884
2885int pa_unblock_sigs(int except, ...) {
2886    va_list ap;
2887    unsigned n = 0, i;
2888    int r, *p;
2889
2890    va_start(ap, except);
2891
2892    if (except >= 1)
2893        for (n = 1; va_arg(ap, int) >= 0; n++)
2894            ;
2895
2896    va_end(ap);
2897
2898    p = pa_xnew(int, n+1);
2899
2900    va_start(ap, except);
2901
2902    i = 0;
2903    if (except >= 1) {
2904        int sig;
2905        p[i++] = except;
2906
2907        while ((sig = va_arg(ap, int)) >= 0)
2908            p[i++] = sig;
2909    }
2910    p[i] = -1;
2911
2912    va_end(ap);
2913
2914    r = pa_unblock_sigsv(p);
2915    pa_xfree(p);
2916
2917    return r;
2918}
2919
2920int pa_unblock_sigsv(const int except[]) {
2921#ifndef OS_IS_WIN32
2922    int i;
2923    sigset_t ss;
2924
2925    if (sigemptyset(&ss) < 0)
2926        return -1;
2927
2928    for (i = 0; except[i] > 0; i++)
2929        if (sigaddset(&ss, except[i]) < 0)
2930            return -1;
2931
2932    return sigprocmask(SIG_SETMASK, &ss, NULL);
2933#else
2934    return 0;
2935#endif
2936}
2937
2938int pa_reset_sigs(int except, ...) {
2939    va_list ap;
2940    unsigned n = 0, i;
2941    int *p, r;
2942
2943    va_start(ap, except);
2944
2945    if (except >= 1)
2946        for (n = 1; va_arg(ap, int) >= 0; n++)
2947            ;
2948
2949    va_end(ap);
2950
2951    p = pa_xnew(int, n+1);
2952
2953    va_start(ap, except);
2954
2955    i = 0;
2956    if (except >= 1) {
2957        int sig;
2958        p[i++] = except;
2959
2960        while ((sig = va_arg(ap, int)) >= 0)
2961            p[i++] = sig;
2962    }
2963    p[i] = -1;
2964
2965    va_end(ap);
2966
2967    r = pa_reset_sigsv(p);
2968    pa_xfree(p);
2969
2970    return r;
2971}
2972
2973int pa_reset_sigsv(const int except[]) {
2974#ifndef OS_IS_WIN32
2975    int sig;
2976
2977    for (sig = 1; sig < NSIG; sig++) {
2978        bool reset = true;
2979
2980        switch (sig) {
2981            case SIGKILL:
2982            case SIGSTOP:
2983                reset = false;
2984                break;
2985
2986            default: {
2987                int i;
2988
2989                for (i = 0; except[i] > 0; i++) {
2990                    if (sig == except[i]) {
2991                        reset = false;
2992                        break;
2993                    }
2994                }
2995            }
2996        }
2997
2998        if (reset) {
2999            struct sigaction sa;
3000
3001            memset(&sa, 0, sizeof(sa));
3002            sa.sa_handler = SIG_DFL;
3003
3004            /* On Linux the first two RT signals are reserved by
3005             * glibc, and sigaction() will return EINVAL for them. */
3006            if ((sigaction(sig, &sa, NULL) < 0))
3007                if (errno != EINVAL)
3008                    return -1;
3009        }
3010    }
3011#endif
3012
3013    return 0;
3014}
3015
3016void pa_set_env(const char *key, const char *value) {
3017    pa_assert(key);
3018    pa_assert(value);
3019
3020    /* This is not thread-safe */
3021
3022#ifdef OS_IS_WIN32
3023    int kl = strlen(key);
3024    int vl = strlen(value);
3025    char *tmp = pa_xmalloc(kl+vl+2);
3026    memcpy(tmp, key, kl);
3027    memcpy(tmp+kl+1, value, vl);
3028    tmp[kl] = '=';
3029    tmp[kl+1+vl] = '\0';
3030    putenv(tmp);
3031    /* Even though it should be safe to free it on Windows, we don't want to
3032     * rely on undocumented behaviour. */
3033#else
3034    setenv(key, value, 1);
3035#endif
3036}
3037
3038void pa_unset_env(const char *key) {
3039    pa_assert(key);
3040
3041    /* This is not thread-safe */
3042
3043#ifdef OS_IS_WIN32
3044    int kl = strlen(key);
3045    char *tmp = pa_xmalloc(kl+2);
3046    memcpy(tmp, key, kl);
3047    tmp[kl] = '=';
3048    tmp[kl+1] = '\0';
3049    putenv(tmp);
3050    /* Even though it should be safe to free it on Windows, we don't want to
3051     * rely on undocumented behaviour. */
3052#else
3053    unsetenv(key);
3054#endif
3055}
3056
3057void pa_set_env_and_record(const char *key, const char *value) {
3058    pa_assert(key);
3059    pa_assert(value);
3060
3061    /* This is not thread-safe */
3062
3063    pa_set_env(key, value);
3064    recorded_env = pa_strlist_prepend(recorded_env, key);
3065}
3066
3067void pa_unset_env_recorded(void) {
3068
3069    /* This is not thread-safe */
3070
3071    for (;;) {
3072        char *s;
3073
3074        recorded_env = pa_strlist_pop(recorded_env, &s);
3075
3076        if (!s)
3077            break;
3078
3079        pa_unset_env(s);
3080        pa_xfree(s);
3081    }
3082}
3083
3084bool pa_in_system_mode(void) {
3085    const char *e;
3086
3087    if (!(e = getenv("PULSE_SYSTEM")))
3088        return false;
3089
3090    return !!atoi(e);
3091}
3092
3093/* Checks a delimiters-separated list of words in haystack for needle */
3094bool pa_str_in_list(const char *haystack, const char *delimiters, const char *needle) {
3095    char *s;
3096    const char *state = NULL;
3097
3098    if (!haystack || !needle)
3099        return false;
3100
3101    while ((s = pa_split(haystack, delimiters, &state))) {
3102        if (pa_streq(needle, s)) {
3103            pa_xfree(s);
3104            return true;
3105        }
3106
3107        pa_xfree(s);
3108    }
3109
3110    return false;
3111}
3112
3113/* Checks a whitespace-separated list of words in haystack for needle */
3114bool pa_str_in_list_spaces(const char *haystack, const char *needle) {
3115    const char *s;
3116    size_t n;
3117    const char *state = NULL;
3118
3119    if (!haystack || !needle)
3120        return false;
3121
3122    while ((s = pa_split_spaces_in_place(haystack, &n, &state))) {
3123        if (pa_strneq(needle, s, n))
3124            return true;
3125    }
3126
3127    return false;
3128}
3129
3130char* pa_str_strip_suffix(const char *str, const char *suffix) {
3131    size_t str_l, suf_l, prefix;
3132    char *ret;
3133
3134    pa_assert(str);
3135    pa_assert(suffix);
3136
3137    str_l = strlen(str);
3138    suf_l = strlen(suffix);
3139
3140    if (str_l < suf_l)
3141        return NULL;
3142
3143    prefix = str_l - suf_l;
3144
3145    if (!pa_streq(&str[prefix], suffix))
3146        return NULL;
3147
3148    ret = pa_xmalloc(prefix + 1);
3149
3150    strncpy(ret, str, prefix);
3151    ret[prefix] = '\0';
3152
3153    return ret;
3154}
3155
3156char *pa_get_user_name_malloc(void) {
3157    ssize_t k;
3158    char *u;
3159
3160#ifdef _SC_LOGIN_NAME_MAX
3161    k = (ssize_t) sysconf(_SC_LOGIN_NAME_MAX);
3162
3163    if (k <= 0)
3164#endif
3165        k = 32;
3166
3167    u = pa_xnew(char, k+1);
3168
3169    if (!(pa_get_user_name(u, k))) {
3170        pa_xfree(u);
3171        return NULL;
3172    }
3173
3174    return u;
3175}
3176
3177char *pa_get_host_name_malloc(void) {
3178    size_t l;
3179
3180    l = 100;
3181    for (;;) {
3182        char *c;
3183
3184        c = pa_xmalloc(l);
3185
3186        if (!pa_get_host_name(c, l)) {
3187
3188            if (errno != EINVAL && errno != ENAMETOOLONG)
3189                break;
3190
3191        } else if (strlen(c) < l-1) {
3192            char *u;
3193
3194            if (*c == 0) {
3195                pa_xfree(c);
3196                break;
3197            }
3198
3199            u = pa_utf8_filter(c);
3200            pa_xfree(c);
3201            return u;
3202        }
3203
3204        /* Hmm, the hostname is as long the space we offered the
3205         * function, we cannot know if it fully fit in, so let's play
3206         * safe and retry. */
3207
3208        pa_xfree(c);
3209        l *= 2;
3210    }
3211
3212    return NULL;
3213}
3214
3215char *pa_machine_id(void) {
3216    FILE *f;
3217    char *h;
3218
3219    /* The returned value is supposed be some kind of ascii identifier
3220     * that is unique and stable across reboots. First we try if the machine-id
3221     * file is available. If it's available, that's great, since it provides an
3222     * identifier that suits our needs perfectly. If it's not, we fall back to
3223     * the hostname, which is not as good, since it can change over time. */
3224
3225    /* We search for the machine-id file from four locations. The first two are
3226     * relative to the configured installation prefix, but if we're installed
3227     * under /usr/local, for example, it's likely that the machine-id won't be
3228     * found there, so we also try the hardcoded paths.
3229     *
3230     * PA_MACHINE_ID or PA_MACHINE_ID_FALLBACK might exist on a Windows system,
3231     * but the last two hardcoded paths certainly don't, hence we don't try
3232     * them on Windows. */
3233    if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r")) ||
3234        (f = pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK, "r")) ||
3235#if !defined(OS_IS_WIN32)
3236        (f = pa_fopen_cloexec("/etc/machine-id", "r")) ||
3237        (f = pa_fopen_cloexec("/var/lib/dbus/machine-id", "r"))
3238#else
3239        false
3240#endif
3241        ) {
3242        char ln[34] = "", *r;
3243
3244        r = fgets(ln, sizeof(ln)-1, f);
3245        fclose(f);
3246
3247        pa_strip_nl(ln);
3248
3249        if (r && ln[0])
3250            return pa_utf8_filter(ln);
3251    }
3252
3253    if ((h = pa_get_host_name_malloc()))
3254        return h;
3255
3256#if !defined(OS_IS_WIN32) && !defined(__ANDROID__)
3257    /* If no hostname was set we use the POSIX hostid. It's usually
3258     * the IPv4 address.  Might not be that stable. */
3259    return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
3260#else
3261    return NULL;
3262#endif
3263}
3264
3265char *pa_session_id(void) {
3266    const char *e;
3267
3268    e = getenv("XDG_SESSION_ID");
3269    if (!e)
3270        return NULL;
3271
3272    return pa_utf8_filter(e);
3273}
3274
3275char *pa_uname_string(void) {
3276#ifdef HAVE_UNAME
3277    struct utsname u;
3278
3279    pa_assert_se(uname(&u) >= 0);
3280
3281    return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
3282#endif
3283#ifdef OS_IS_WIN32
3284    OSVERSIONINFO i;
3285
3286    pa_zero(i);
3287    i.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
3288    pa_assert_se(GetVersionEx(&i));
3289
3290    return pa_sprintf_malloc("Windows %lu.%lu (%lu) %s", i.dwMajorVersion, i.dwMinorVersion, i.dwBuildNumber, i.szCSDVersion);
3291#endif
3292}
3293
3294#ifdef HAVE_VALGRIND_MEMCHECK_H
3295bool pa_in_valgrind(void) {
3296    static int b = 0;
3297
3298    /* To make heisenbugs a bit simpler to find we check for $VALGRIND
3299     * here instead of really checking whether we run in valgrind or
3300     * not. */
3301
3302    if (b < 1)
3303        b = getenv("VALGRIND") ? 2 : 1;
3304
3305    return b > 1;
3306}
3307#endif
3308
3309unsigned pa_gcd(unsigned a, unsigned b) {
3310
3311    while (b > 0) {
3312        unsigned t = b;
3313        b = a % b;
3314        a = t;
3315    }
3316
3317    return a;
3318}
3319
3320void pa_reduce(unsigned *num, unsigned *den) {
3321
3322    unsigned gcd = pa_gcd(*num, *den);
3323
3324    if (gcd <= 0)
3325        return;
3326
3327    *num /= gcd;
3328    *den /= gcd;
3329
3330    pa_assert(pa_gcd(*num, *den) == 1);
3331}
3332
3333unsigned pa_ncpus(void) {
3334    long ncpus;
3335
3336#ifdef _SC_NPROCESSORS_ONLN
3337    ncpus = sysconf(_SC_NPROCESSORS_ONLN);
3338#else
3339    ncpus = 1;
3340#endif
3341
3342    return ncpus <= 0 ? 1 : (unsigned) ncpus;
3343}
3344
3345char *pa_replace(const char*s, const char*a, const char *b) {
3346    pa_strbuf *sb;
3347    size_t an;
3348
3349    pa_assert(s);
3350    pa_assert(a);
3351    pa_assert(*a);
3352    pa_assert(b);
3353
3354    an = strlen(a);
3355    sb = pa_strbuf_new();
3356
3357    for (;;) {
3358        const char *p;
3359
3360        if (!(p = strstr(s, a)))
3361            break;
3362
3363        pa_strbuf_putsn(sb, s, p-s);
3364        pa_strbuf_puts(sb, b);
3365        s = p + an;
3366    }
3367
3368    pa_strbuf_puts(sb, s);
3369
3370    return pa_strbuf_to_string_free(sb);
3371}
3372
3373char *pa_escape(const char *p, const char *chars) {
3374    const char *s;
3375    const char *c;
3376    char *out_string, *output;
3377    int char_count = strlen(p);
3378
3379    /* Maximum number of characters in output string
3380     * including trailing 0. */
3381    char_count = 2 * char_count + 1;
3382
3383    /* allocate output string */
3384    out_string = pa_xmalloc(char_count);
3385    output = out_string;
3386
3387    /* write output string */
3388    for (s = p; *s; ++s) {
3389        if (*s == '\\')
3390            *output++ = '\\';
3391        else if (chars) {
3392            for (c = chars; *c; ++c) {
3393                if (*s == *c) {
3394                    *output++ = '\\';
3395                    break;
3396                }
3397            }
3398        }
3399        *output++ = *s;
3400    }
3401
3402    *output = 0;
3403
3404    /* Remove trailing garbage */
3405    output = pa_xstrdup(out_string);
3406
3407    pa_xfree(out_string);
3408    return output;
3409}
3410
3411char *pa_unescape(char *p) {
3412    char *s, *d;
3413    bool escaped = false;
3414
3415    for (s = p, d = p; *s; s++) {
3416        if (!escaped && *s == '\\') {
3417            escaped = true;
3418            continue;
3419        }
3420
3421        *(d++) = *s;
3422        escaped = false;
3423    }
3424
3425    *d = 0;
3426
3427    return p;
3428}
3429
3430char *pa_realpath(const char *path) {
3431    char *t;
3432    pa_assert(path);
3433
3434    /* We want only absolute paths */
3435    if (path[0] != '/') {
3436        errno = EINVAL;
3437        return NULL;
3438    }
3439
3440#if defined(__GLIBC__)
3441    {
3442        char *r;
3443
3444        if (!(r = realpath(path, NULL)))
3445            return NULL;
3446
3447        /* We copy this here in case our pa_xmalloc() is not
3448         * implemented on top of libc malloc() */
3449        t = pa_xstrdup(r);
3450        pa_xfree(r);
3451    }
3452#elif defined(PATH_MAX)
3453    {
3454        char *path_buf;
3455        path_buf = pa_xmalloc(PATH_MAX);
3456
3457#if defined(OS_IS_WIN32)
3458        if (!(t = _fullpath(path_buf, path, _MAX_PATH))) {
3459            pa_xfree(path_buf);
3460            return NULL;
3461        }
3462#else
3463        if (!(t = realpath(path, path_buf))) {
3464            pa_xfree(path_buf);
3465            return NULL;
3466        }
3467#endif
3468    }
3469#else
3470#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."
3471#endif
3472
3473    return t;
3474}
3475
3476void pa_disable_sigpipe(void) {
3477
3478#ifdef SIGPIPE
3479    struct sigaction sa;
3480
3481    pa_zero(sa);
3482
3483    if (sigaction(SIGPIPE, NULL, &sa) < 0) {
3484        pa_log("sigaction(): %s", pa_cstrerror(errno));
3485        return;
3486    }
3487
3488    sa.sa_handler = SIG_IGN;
3489
3490    if (sigaction(SIGPIPE, &sa, NULL) < 0) {
3491        pa_log("sigaction(): %s", pa_cstrerror(errno));
3492        return;
3493    }
3494#endif
3495}
3496
3497void pa_xfreev(void**a) {
3498    void **p;
3499
3500    if (!a)
3501        return;
3502
3503    for (p = a; *p; p++)
3504        pa_xfree(*p);
3505
3506    pa_xfree(a);
3507}
3508
3509char **pa_split_spaces_strv(const char *s) {
3510    char **t, *e;
3511    unsigned i = 0, n = 8;
3512    const char *state = NULL;
3513
3514    t = pa_xnew(char*, n);
3515    while ((e = pa_split_spaces(s, &state))) {
3516        t[i++] = e;
3517
3518        if (i >= n) {
3519            n *= 2;
3520            t = pa_xrenew(char*, t, n);
3521        }
3522    }
3523
3524    if (i <= 0) {
3525        pa_xfree(t);
3526        return NULL;
3527    }
3528
3529    t[i] = NULL;
3530    return t;
3531}
3532
3533char* pa_maybe_prefix_path(const char *path, const char *prefix) {
3534    pa_assert(path);
3535
3536    if (pa_is_path_absolute(path))
3537        return pa_xstrdup(path);
3538
3539    return pa_sprintf_malloc("%s" PA_PATH_SEP "%s", prefix, path);
3540}
3541
3542size_t pa_pipe_buf(int fd) {
3543
3544#ifdef _PC_PIPE_BUF
3545    long n;
3546
3547    if ((n = fpathconf(fd, _PC_PIPE_BUF)) >= 0)
3548        return (size_t) n;
3549#endif
3550
3551#ifdef PIPE_BUF
3552    return PIPE_BUF;
3553#else
3554    return 4096;
3555#endif
3556}
3557
3558void pa_reset_personality(void) {
3559
3560#if defined(__linux__) && !defined(__ANDROID__)
3561    if (personality(PER_LINUX) < 0)
3562        pa_log_warn("Uh, personality() failed: %s", pa_cstrerror(errno));
3563#endif
3564
3565}
3566
3567bool pa_run_from_build_tree(void) {
3568    static bool b = false;
3569
3570#ifdef HAVE_RUNNING_FROM_BUILD_TREE
3571    char *rp;
3572    PA_ONCE_BEGIN {
3573        if ((rp = pa_readlink("/proc/self/exe"))) {
3574            b = pa_startswith(rp, PA_BUILDDIR);
3575            pa_xfree(rp);
3576        }
3577    } PA_ONCE_END;
3578#endif
3579
3580    return b;
3581}
3582
3583const char *pa_get_temp_dir(void) {
3584    const char *t;
3585
3586    if ((t = getenv("TMPDIR")) &&
3587        pa_is_path_absolute(t))
3588        return t;
3589
3590    if ((t = getenv("TMP")) &&
3591        pa_is_path_absolute(t))
3592        return t;
3593
3594    if ((t = getenv("TEMP")) &&
3595        pa_is_path_absolute(t))
3596        return t;
3597
3598    if ((t = getenv("TEMPDIR")) &&
3599        pa_is_path_absolute(t))
3600        return t;
3601
3602    return "/tmp";
3603}
3604
3605int pa_open_cloexec(const char *fn, int flags, mode_t mode) {
3606    int fd;
3607
3608#ifdef O_NOCTTY
3609    flags |= O_NOCTTY;
3610#endif
3611
3612#ifdef O_CLOEXEC
3613    if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0)
3614        goto finish;
3615
3616    if (errno != EINVAL)
3617        return fd;
3618#endif
3619
3620    if ((fd = open(fn, flags, mode)) >= 0)
3621        goto finish;
3622
3623    /* return error */
3624    return fd;
3625
3626finish:
3627    /* Some implementations might simply ignore O_CLOEXEC if it is not
3628     * understood, make sure FD_CLOEXEC is enabled anyway */
3629
3630    pa_make_fd_cloexec(fd);
3631    return fd;
3632}
3633
3634int pa_socket_cloexec(int domain, int type, int protocol) {
3635    int fd;
3636
3637#ifdef SOCK_CLOEXEC
3638    if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0)
3639        goto finish;
3640
3641    if (errno != EINVAL)
3642        return fd;
3643#endif
3644
3645    if ((fd = socket(domain, type, protocol)) >= 0)
3646        goto finish;
3647
3648    /* return error */
3649    return fd;
3650
3651finish:
3652    /* Some implementations might simply ignore SOCK_CLOEXEC if it is
3653     * not understood, make sure FD_CLOEXEC is enabled anyway */
3654
3655    pa_make_fd_cloexec(fd);
3656    return fd;
3657}
3658
3659int pa_pipe_cloexec(int pipefd[2]) {
3660    int r;
3661
3662#ifdef HAVE_PIPE2
3663    if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0)
3664        goto finish;
3665
3666    if (errno == EMFILE) {
3667        pa_log_error("The per-process limit on the number of open file descriptors has been reached.");
3668        return r;
3669    }
3670
3671    if (errno == ENFILE) {
3672        pa_log_error("The system-wide limit on the total number of open files has been reached.");
3673        return r;
3674    }
3675
3676    if (errno != EINVAL && errno != ENOSYS)
3677        return r;
3678
3679#endif
3680
3681    if ((r = pipe(pipefd)) >= 0)
3682        goto finish;
3683
3684    if (errno == EMFILE) {
3685        pa_log_error("The per-process limit on the number of open file descriptors has been reached.");
3686        return r;
3687    }
3688
3689    if (errno == ENFILE) {
3690        pa_log_error("The system-wide limit on the total number of open files has been reached.");
3691        return r;
3692    }
3693
3694    /* return error */
3695    return r;
3696
3697finish:
3698    pa_make_fd_cloexec(pipefd[0]);
3699    pa_make_fd_cloexec(pipefd[1]);
3700
3701    return 0;
3702}
3703
3704int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
3705    int fd;
3706
3707    errno = 0;
3708
3709#ifdef HAVE_ACCEPT4
3710    if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0)
3711        goto finish;
3712
3713    if (errno != EINVAL && errno != ENOSYS)
3714        return fd;
3715
3716#endif
3717
3718#ifdef HAVE_PACCEPT
3719    if ((fd = paccept(sockfd, addr, addrlen, NULL, SOCK_CLOEXEC)) >= 0)
3720        goto finish;
3721#endif
3722
3723    if ((fd = accept(sockfd, addr, addrlen)) >= 0)
3724        goto finish;
3725
3726    /* return error */
3727    return fd;
3728
3729finish:
3730    pa_make_fd_cloexec(fd);
3731    return fd;
3732}
3733
3734FILE* pa_fopen_cloexec(const char *path, const char *mode) {
3735    FILE *f;
3736    char *m;
3737
3738    m = pa_sprintf_malloc("%se", mode);
3739
3740    errno = 0;
3741    if ((f = fopen(path, m))) {
3742        pa_xfree(m);
3743        goto finish;
3744    }
3745
3746    pa_xfree(m);
3747
3748    if (errno != EINVAL)
3749        return NULL;
3750
3751    if (!(f = fopen(path, mode)))
3752        return NULL;
3753
3754finish:
3755    pa_make_fd_cloexec(fileno(f));
3756    return f;
3757}
3758
3759void pa_nullify_stdfds(void) {
3760
3761#ifndef OS_IS_WIN32
3762        pa_close(STDIN_FILENO);
3763        pa_close(STDOUT_FILENO);
3764        pa_close(STDERR_FILENO);
3765
3766        pa_assert_se(open("/dev/null", O_RDONLY) == STDIN_FILENO);
3767        pa_assert_se(open("/dev/null", O_WRONLY) == STDOUT_FILENO);
3768        pa_assert_se(open("/dev/null", O_WRONLY) == STDERR_FILENO);
3769#else
3770        FreeConsole();
3771#endif
3772
3773}
3774
3775char *pa_read_line_from_file(const char *fn) {
3776    FILE *f;
3777    char ln[256] = "", *r;
3778
3779    if (!(f = pa_fopen_cloexec(fn, "r")))
3780        return NULL;
3781
3782    r = fgets(ln, sizeof(ln)-1, f);
3783    fclose(f);
3784
3785    if (!r) {
3786        errno = EIO;
3787        return NULL;
3788    }
3789
3790    pa_strip_nl(ln);
3791    return pa_xstrdup(ln);
3792}
3793
3794bool pa_running_in_vm(void) {
3795
3796#if defined(__i386__) || defined(__x86_64__)
3797
3798    /* Both CPUID and DMI are x86 specific interfaces... */
3799
3800#ifdef HAVE_CPUID_H
3801    unsigned int eax, ebx, ecx, edx;
3802#endif
3803
3804#ifdef __linux__
3805    const char *const dmi_vendors[] = {
3806        "/sys/class/dmi/id/sys_vendor",
3807        "/sys/class/dmi/id/board_vendor",
3808        "/sys/class/dmi/id/bios_vendor"
3809    };
3810
3811    unsigned i;
3812
3813    for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) {
3814        char *s;
3815
3816        if ((s = pa_read_line_from_file(dmi_vendors[i]))) {
3817
3818            if (pa_startswith(s, "QEMU") ||
3819                /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3820                pa_startswith(s, "VMware") ||
3821                pa_startswith(s, "VMW") ||
3822                pa_startswith(s, "Microsoft Corporation") ||
3823                pa_startswith(s, "innotek GmbH") ||
3824                pa_startswith(s, "Xen")) {
3825
3826                pa_xfree(s);
3827                return true;
3828            }
3829
3830            pa_xfree(s);
3831        }
3832    }
3833
3834#endif
3835
3836#ifdef HAVE_CPUID_H
3837
3838    /* Hypervisors provide presence on 0x1 cpuid leaf.
3839     * http://lwn.net/Articles/301888/ */
3840    if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0)
3841        return false;
3842
3843    if (ecx & 0x80000000)
3844        return true;
3845
3846#endif /* HAVE_CPUID_H */
3847
3848#endif /* defined(__i386__) || defined(__x86_64__) */
3849
3850    return false;
3851}
3852
3853size_t pa_page_size(void) {
3854#if defined(PAGE_SIZE)
3855    return PAGE_SIZE;
3856#elif defined(PAGESIZE)
3857    return PAGESIZE;
3858#elif defined(HAVE_SYSCONF)
3859    static size_t page_size = 4096; /* Let's hope it's like x86. */
3860
3861    PA_ONCE_BEGIN {
3862        long ret = sysconf(_SC_PAGE_SIZE);
3863        if (ret > 0)
3864            page_size = ret;
3865    } PA_ONCE_END;
3866
3867    return page_size;
3868#else
3869    return 4096;
3870#endif
3871}
3872