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 #undef LOG_TAG
27 #define LOG_TAG "CoreUtil"
28
29 #include <math.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <signal.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <limits.h>
39 #include <ctype.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <dirent.h>
43
44 #ifdef HAVE_LANGINFO_H
45 #include <langinfo.h>
46 #endif
47
48 #ifdef HAVE_UNAME
49 #include <sys/utsname.h>
50 #endif
51
52 #if defined(HAVE_REGEX_H)
53 #include <regex.h>
54 #elif defined(HAVE_PCREPOSIX_H)
55 #include <pcreposix.h>
56 #endif
57
58 #ifdef HAVE_STRTOD_L
59 #ifdef HAVE_LOCALE_H
60 #include <locale.h>
61 #endif
62 #ifdef HAVE_XLOCALE_H
63 #include <xlocale.h>
64 #endif
65 #endif
66
67 #ifdef HAVE_SYS_RESOURCE_H
68 #include <sys/resource.h>
69 #endif
70
71 #ifdef HAVE_SYS_CAPABILITY_H
72 #include <sys/capability.h>
73 #endif
74
75 #ifdef HAVE_SYS_MMAN_H
76 #include <sys/mman.h>
77 #endif
78
79 #ifdef HAVE_PTHREAD
80 #include <pthread.h>
81 #endif
82
83 #ifdef HAVE_NETDB_H
84 #include <netdb.h>
85 #endif
86
87 #ifdef HAVE_WINDOWS_H
88 #include <windows.h>
89 #include <shlobj.h>
90 #endif
91
92 #ifndef ENOTSUP
93 #define ENOTSUP 135
94 #endif
95
96 #ifdef HAVE_PWD_H
97 #include <pwd.h>
98 #endif
99
100 #ifdef HAVE_GRP_H
101 #include <grp.h>
102 #endif
103
104 #ifdef HAVE_LIBSAMPLERATE
105 #include <samplerate.h>
106 #endif
107
108 #ifdef HAVE_DBUS
109 #include <pulsecore/rtkit.h>
110 #endif
111
112 #if defined(__linux__) && !defined(__ANDROID__)
113 #include <sys/personality.h>
114 #endif
115
116 #ifdef HAVE_CPUID_H
117 #include <cpuid.h>
118 #endif
119
120 #include <pulse/xmalloc.h>
121 #include <pulse/util.h>
122 #include <pulse/utf8.h>
123
124 #include <pulsecore/core-error.h>
125 #include <pulsecore/socket.h>
126 #include <pulsecore/log.h>
127 #include <pulsecore/macro.h>
128 #include <pulsecore/thread.h>
129 #include <pulsecore/strbuf.h>
130 #include <pulsecore/usergroup.h>
131 #include <pulsecore/strlist.h>
132 #include <pulsecore/pipe.h>
133 #include <pulsecore/once.h>
134 #include "log/audio_log.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
146 static pa_strlist *recorded_env = NULL;
147
148 #ifdef OS_IS_WIN32
149 static 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 */
pa_win32_get_toplevel(HANDLE handle)155 char *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
pa_win32_get_system_appdata()179 char *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
set_nonblock(int fd,bool nonblock)190 static 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 */
pa_make_fd_nonblock(int fd)232 void 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 */
pa_make_fd_block(int fd)237 void pa_make_fd_block(int fd) {
238 set_nonblock(fd, false);
239 }
240
241 /** Query if a file descriptor is non-blocking */
pa_is_fd_nonblock(int fd)242 bool 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 */
pa_make_fd_cloexec(int fd)261 void 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. */
pa_make_secure_dir(const char * dir,mode_t m,uid_t uid,gid_t gid,bool update_perms)278 int 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
285 again:
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
366 fail:
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 */
pa_parent_dir(const char * fn)375 char *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 */
pa_make_secure_parent_dir(const char * fn,mode_t m,uid_t uid,gid_t gid,bool update_perms)389 int 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
401 finish:
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. */
pa_read(int fd,void * buf,size_t count,int * type)412 ssize_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 */
pa_write(int fd,const void * buf,size_t count,int * type)447 ssize_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 */
pa_loop_read(int fd,void * data,size_t size,int * type)493 ssize_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() */
pa_loop_write(int fd,const void * data,size_t size,int * type)524 ssize_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. */
pa_close(int fd)556 int 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 AUDIO_ERR_LOG("Close fd failed, err code: %{public}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 */
pa_check_signal_is_blocked(int sig)586 void 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(). */
pa_sprintf_malloc(const char * format,...)627 char *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 */
pa_vsprintf_malloc(const char * format,va_list ap)657 char *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 */
pa_strlcpy(char * b,const char * s,size_t l)686 char *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
set_nice(int nice_level)705 static 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..*/
pa_raise_priority(int nice_level)754 int 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()*/
pa_reset_priority(void)791 void 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. */
pa_match(const char * expr,const char * v)807 int 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. */
pa_is_regex_valid(const char * expr)841 bool 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.*/
pa_parse_boolean(const char * v)857 int 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 */
pa_parse_volume(const char * v,pa_volume_t * volume)890 int 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. */
pa_split(const char * c,const char * delimiter,const char ** state)944 char *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. */
pa_split_in_place(const char * c,const char * delimiter,size_t * n,const char ** state)966 const 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(). */
pa_split_spaces(const char * c,const char ** state)984 char *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(). */
pa_split_spaces_in_place(const char * c,size_t * n,const char ** state)1002 const 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
1018 PA_STATIC_TLS_DECLARE(signame, pa_xfree);
1019
1020 /* Return the name of an UNIX signal. Similar to Solaris sig2str() */
pa_sig2str(int sig)1021 const 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
1140 fail:
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 */
is_group(gid_t gid,const char * name)1151 static 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
1167 finish:
1168 pa_getgrgid_free(group);
1169
1170 return r;
1171 }
1172
1173 /* Check the current user is member of the specified group */
pa_own_uid_in_group(const char * name,gid_t * gid)1174 int 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
1209 finish:
1210
1211 pa_xfree(gids);
1212 return r;
1213 }
1214
1215 /* Check whether the specific user id is a member of the specified group */
pa_uid_in_group(uid_t uid,const char * name)1216 int 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
1245 finish:
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. */
pa_get_gid_of_group(const char * name)1252 gid_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
1265 finish:
1266 pa_getgrnam_free(gr);
1267 return ret;
1268 }
1269
pa_check_in_group(gid_t g)1270 int 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
pa_own_uid_in_group(const char * name,gid_t * gid)1286 int pa_own_uid_in_group(const char *name, gid_t *gid) {
1287 errno = ENOTSUP;
1288 return -1;
1289
1290 }
1291
pa_uid_in_group(uid_t uid,const char * name)1292 int pa_uid_in_group(uid_t uid, const char *name) {
1293 errno = ENOTSUP;
1294 return -1;
1295 }
1296
pa_get_gid_of_group(const char * name)1297 gid_t pa_get_gid_of_group(const char *name) {
1298 errno = ENOTSUP;
1299 return (gid_t) -1;
1300 }
1301
pa_check_in_group(gid_t g)1302 int 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) */
pa_lock_fd(int fd,int b)1311 int 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 */
pa_strip_nl(char * s)1352 char* pa_strip_nl(char *s) {
1353 pa_assert(s);
1354
1355 s[strcspn(s, NEWLINE)] = 0;
1356 return s;
1357 }
1358
pa_strip(char * s)1359 char *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. */
pa_lock_lockfile(const char * fn)1380 int 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
1425 fail:
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 */
pa_unlock_lockfile(const char * fn,int fd)1437 int 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
check_ours(const char * p)1461 static 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
get_pulse_home(void)1477 static 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
pa_get_state_dir(void)1508 char *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
pa_get_home_dir_malloc(void)1530 char *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
pa_append_to_home_dir(const char * path,char ** _r)1552 int 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
pa_get_config_home_dir(char ** _r)1569 int 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
pa_get_data_home_dir(char ** _r)1590 int 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
pa_get_data_dirs(pa_dynarray ** _r)1615 int 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
pa_append_to_config_home_dir(const char * path,char ** _r)1654 int 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
pa_get_binary_name_malloc(void)1670 char *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
make_random_dir(mode_t m)1692 static 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
make_random_dir_and_link(mode_t m,const char * k)1735 static 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
pa_get_runtime_dir(void)1763 char *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
1937 fail:
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.*/
pa_open_config_file(const char * global,const char * local,const char * env,char ** result)1951 FILE *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
pa_find_config_file(const char * global,const char * local,const char * env)2031 char *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 */
pa_hexstr(const uint8_t * d,size_t dlength,char * s,size_t slength)2093 char *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 */
hexc(char c)2114 static 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 */
pa_parsehex(const char * p,uint8_t * d,size_t dlength)2129 size_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 */
pa_startswith(const char * s,const char * pfx)2157 bool 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 */
pa_endswith(const char * s,const char * sfx)2169 bool 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
pa_is_path_absolute(const char * fn)2181 bool 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
pa_make_path_absolute(const char * p)2191 char *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. */
get_path(const char * fn,bool prependmid,bool rt)2211 static 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
pa_runtime_path(const char * fn)2257 char *pa_runtime_path(const char *fn) {
2258 return get_path(fn, false, true);
2259 }
2260
pa_state_path(const char * fn,bool appendmid)2261 char *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 */
pa_atoi(const char * s,int32_t * ret_i)2266 int 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
2285 enum 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. */
prepare_number_string(const char * s,enum numtype type,char ** tmp,const char ** ret)2303 static 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
2364 finish:
2365 *ret = s;
2366 return 0;
2367 }
2368
2369 /* Convert the string s to an unsigned integer in *ret_u */
pa_atou(const char * s,uint32_t * ret_u)2370 int 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 */
pa_atou64(const char * s,uint64_t * ret_u)2404 int 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. */
pa_atol(const char * s,long * ret_l)2438 int 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. */
pa_atoi64(const char * s,int64_t * ret_l)2472 int 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
2511 static locale_t c_locale = NULL;
2512
c_locale_destroy(void)2513 static void c_locale_destroy(void) {
2514 freelocale(c_locale);
2515 }
2516 #endif
2517
pa_atod(const char * s,double * ret_d)2518 int 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 */
pa_snprintf(char * str,size_t size,const char * format,...)2571 size_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 */
pa_vsnprintf(char * str,size_t size,const char * format,va_list ap)2587 size_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 */
pa_truncate_utf8(char * c,size_t l)2609 char *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
pa_getcwd(void)2624 char *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
pa_will_need(const void * p,size_t l)2642 void *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
pa_close_pipe(int fds[2])2714 void 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
pa_readlink(const char * p)2726 char *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
pa_close_all(int except_fd,...)2754 int 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
pa_close_allv(const int except_fds[])2789 int 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
pa_unblock_sigs(int except,...)2885 int 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
pa_unblock_sigsv(const int except[])2920 int 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
pa_reset_sigs(int except,...)2938 int 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
pa_reset_sigsv(const int except[])2973 int 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
pa_set_env(const char * key,const char * value)3016 void 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
pa_unset_env(const char * key)3038 void 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
pa_set_env_and_record(const char * key,const char * value)3057 void 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
pa_unset_env_recorded(void)3067 void 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
pa_in_system_mode(void)3084 bool 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 */
pa_str_in_list(const char * haystack,const char * delimiters,const char * needle)3094 bool 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 */
pa_str_in_list_spaces(const char * haystack,const char * needle)3114 bool 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
pa_str_strip_suffix(const char * str,const char * suffix)3130 char* 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
pa_get_user_name_malloc(void)3156 char *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
pa_get_host_name_malloc(void)3177 char *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
pa_machine_id(void)3215 char *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
pa_session_id(void)3265 char *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
pa_uname_string(void)3275 char *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
pa_in_valgrind(void)3295 bool 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
pa_gcd(unsigned a,unsigned b)3309 unsigned 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
pa_reduce(unsigned * num,unsigned * den)3320 void 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
pa_ncpus(void)3333 unsigned 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
pa_replace(const char * s,const char * a,const char * b)3345 char *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
pa_escape(const char * p,const char * chars)3373 char *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
pa_unescape(char * p)3411 char *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
pa_realpath(const char * path)3430 char *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
pa_disable_sigpipe(void)3476 void 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
pa_xfreev(void ** a)3497 void 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
pa_split_spaces_strv(const char * s)3509 char **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
pa_maybe_prefix_path(const char * path,const char * prefix)3533 char* 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
pa_pipe_buf(int fd)3542 size_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
pa_reset_personality(void)3558 void 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
pa_run_from_build_tree(void)3567 bool 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
pa_get_temp_dir(void)3583 const 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
pa_open_cloexec(const char * fn,int flags,mode_t mode)3605 int 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
3626 finish:
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
pa_socket_cloexec(int domain,int type,int protocol)3634 int 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
3651 finish:
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
pa_pipe_cloexec(int pipefd[2])3659 int 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
3697 finish:
3698 pa_make_fd_cloexec(pipefd[0]);
3699 pa_make_fd_cloexec(pipefd[1]);
3700
3701 return 0;
3702 }
3703
pa_accept_cloexec(int sockfd,struct sockaddr * addr,socklen_t * addrlen)3704 int 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
3729 finish:
3730 pa_make_fd_cloexec(fd);
3731 return fd;
3732 }
3733
pa_fopen_cloexec(const char * path,const char * mode)3734 FILE* 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
3754 finish:
3755 pa_make_fd_cloexec(fileno(f));
3756 return f;
3757 }
3758
pa_nullify_stdfds(void)3759 void 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
pa_read_line_from_file(const char * fn)3775 char *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
pa_running_in_vm(void)3794 bool 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
pa_page_size(void)3853 size_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