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