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