1/*** 2 This file is part of eudev, forked from systemd. 3 4 Copyright 2010 Lennart Poettering 5 6 systemd is free software; you can redistribute it and/or modify it 7 under the terms of the GNU Lesser General Public License as published by 8 the Free Software Foundation; either version 2.1 of the License, or 9 (at your option) any later version. 10 11 systemd is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with systemd; If not, see <http://www.gnu.org/licenses/>. 18***/ 19 20#include <assert.h> 21#include <string.h> 22#include <unistd.h> 23#include <errno.h> 24#include <stdlib.h> 25#include <signal.h> 26#include <stdio.h> 27#include <syslog.h> 28#include <sched.h> 29#include <sys/resource.h> 30#include <linux/sched.h> 31#include <sys/types.h> 32#include <sys/stat.h> 33#include <fcntl.h> 34#include <dirent.h> 35#include <sys/ioctl.h> 36#include <stdarg.h> 37#include <poll.h> 38#include <ctype.h> 39#include <sys/prctl.h> 40#include <sys/utsname.h> 41#include <pwd.h> 42#include <netinet/ip.h> 43#include <linux/kd.h> 44#include <dlfcn.h> 45#include <sys/wait.h> 46#include <sys/time.h> 47#include <glob.h> 48#include <grp.h> 49#include <sys/mman.h> 50#include <sys/vfs.h> 51#include <linux/magic.h> 52#include <limits.h> 53#include <locale.h> 54#include <libgen.h> 55 56#include "macro.h" 57#include "util.h" 58#include "ioprio.h" 59#include "missing.h" 60#include "log.h" 61#include "strv.h" 62#include "mkdir.h" 63#include "path-util.h" 64#include "hashmap.h" 65#include "fileio.h" 66#include "utf8.h" 67#include "virt.h" 68#include "process-util.h" 69#include "random-util.h" 70#include "terminal-util.h" 71 72/* Put this test here for a lack of better place */ 73assert_cc(EAGAIN == EWOULDBLOCK); 74 75int saved_argc = 0; 76char **saved_argv = NULL; 77 78size_t page_size(void) { 79 static thread_local size_t pgsz = 0; 80 long r; 81 82 if (_likely_(pgsz > 0)) 83 return pgsz; 84 85 r = sysconf(_SC_PAGESIZE); 86 assert(r > 0); 87 88 pgsz = (size_t) r; 89 return pgsz; 90} 91 92bool streq_ptr(const char *a, const char *b) { 93 94 /* Like streq(), but tries to make sense of NULL pointers */ 95 96 if (a && b) 97 return streq(a, b); 98 99 if (!a && !b) 100 return true; 101 102 return false; 103} 104 105char* endswith(const char *s, const char *postfix) { 106 size_t sl, pl; 107 108 assert(s); 109 assert(postfix); 110 111 sl = strlen(s); 112 pl = strlen(postfix); 113 114 if (pl == 0) 115 return (char*) s + sl; 116 117 if (sl < pl) 118 return NULL; 119 120 if (memcmp(s + sl - pl, postfix, pl) != 0) 121 return NULL; 122 123 return (char*) s + sl - pl; 124} 125 126size_t cescape_char(char c, char *buf) { 127 char * buf_old = buf; 128 129 switch (c) { 130 131 case '\a': 132 *(buf++) = '\\'; 133 *(buf++) = 'a'; 134 break; 135 case '\b': 136 *(buf++) = '\\'; 137 *(buf++) = 'b'; 138 break; 139 case '\f': 140 *(buf++) = '\\'; 141 *(buf++) = 'f'; 142 break; 143 case '\n': 144 *(buf++) = '\\'; 145 *(buf++) = 'n'; 146 break; 147 case '\r': 148 *(buf++) = '\\'; 149 *(buf++) = 'r'; 150 break; 151 case '\t': 152 *(buf++) = '\\'; 153 *(buf++) = 't'; 154 break; 155 case '\v': 156 *(buf++) = '\\'; 157 *(buf++) = 'v'; 158 break; 159 case '\\': 160 *(buf++) = '\\'; 161 *(buf++) = '\\'; 162 break; 163 case '"': 164 *(buf++) = '\\'; 165 *(buf++) = '"'; 166 break; 167 case '\'': 168 *(buf++) = '\\'; 169 *(buf++) = '\''; 170 break; 171 172 default: 173 /* For special chars we prefer octal over 174 * hexadecimal encoding, simply because glib's 175 * g_strescape() does the same */ 176 if ((c < ' ') || (c >= 127)) { 177 *(buf++) = '\\'; 178 *(buf++) = octchar((unsigned char) c >> 6); 179 *(buf++) = octchar((unsigned char) c >> 3); 180 *(buf++) = octchar((unsigned char) c); 181 } else 182 *(buf++) = c; 183 break; 184 } 185 186 return buf - buf_old; 187} 188 189int close_nointr(int fd) { 190 assert(fd >= 0); 191 192 if (close(fd) >= 0) 193 return 0; 194 195 /* 196 * Just ignore EINTR; a retry loop is the wrong thing to do on 197 * Linux. 198 * 199 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html 200 * https://bugzilla.gnome.org/show_bug.cgi?id=682819 201 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR 202 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain 203 */ 204 if (errno == EINTR) 205 return 0; 206 207 return -errno; 208} 209 210int safe_close(int fd) { 211 212 /* 213 * Like close_nointr() but cannot fail. Guarantees errno is 214 * unchanged. Is a NOP with negative fds passed, and returns 215 * -1, so that it can be used in this syntax: 216 * 217 * fd = safe_close(fd); 218 */ 219 220 if (fd >= 0) { 221 PROTECT_ERRNO; 222 223 /* The kernel might return pretty much any error code 224 * via close(), but the fd will be closed anyway. The 225 * only condition we want to check for here is whether 226 * the fd was invalid at all... */ 227 228 assert_se(close_nointr(fd) != -EBADF); 229 } 230 231 return -1; 232} 233 234void close_many(const int fds[], unsigned n_fd) { 235 unsigned i; 236 237 assert(fds || n_fd <= 0); 238 239 for (i = 0; i < n_fd; i++) 240 safe_close(fds[i]); 241} 242 243int unlink_noerrno(const char *path) { 244 PROTECT_ERRNO; 245 int r; 246 247 r = unlink(path); 248 if (r < 0) 249 return -errno; 250 251 return 0; 252} 253 254int parse_uid(const char *s, uid_t* ret_uid) { 255 unsigned long ul = 0; 256 uid_t uid; 257 int r; 258 259 assert(s); 260 261 r = safe_atolu(s, &ul); 262 if (r < 0) 263 return r; 264 265 uid = (uid_t) ul; 266 267 if ((unsigned long) uid != ul) 268 return -ERANGE; 269 270 /* Some libc APIs use UID_INVALID as special placeholder */ 271 if (uid == (uid_t) 0xFFFFFFFF) 272 return -ENXIO; 273 274 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */ 275 if (uid == (uid_t) 0xFFFF) 276 return -ENXIO; 277 278 if (ret_uid) 279 *ret_uid = uid; 280 281 return 0; 282} 283 284int safe_atou(const char *s, unsigned *ret_u) { 285 char *x = NULL; 286 unsigned long l; 287 288 assert(s); 289 assert(ret_u); 290 291 errno = 0; 292 l = strtoul(s, &x, 0); 293 294 if (!x || x == s || *x || errno) 295 return errno > 0 ? -errno : -EINVAL; 296 297 if ((unsigned long) (unsigned) l != l) 298 return -ERANGE; 299 300 *ret_u = (unsigned) l; 301 return 0; 302} 303 304int safe_atoi(const char *s, int *ret_i) { 305 char *x = NULL; 306 long l; 307 308 assert(s); 309 assert(ret_i); 310 311 errno = 0; 312 l = strtol(s, &x, 0); 313 314 if (!x || x == s || *x || errno) 315 return errno > 0 ? -errno : -EINVAL; 316 317 if ((long) (int) l != l) 318 return -ERANGE; 319 320 *ret_i = (int) l; 321 return 0; 322} 323 324int safe_atollu(const char *s, long long unsigned *ret_llu) { 325 char *x = NULL; 326 unsigned long long l; 327 328 assert(s); 329 assert(ret_llu); 330 331 errno = 0; 332 l = strtoull(s, &x, 0); 333 334 if (!x || x == s || *x || errno) 335 return errno ? -errno : -EINVAL; 336 337 *ret_llu = l; 338 return 0; 339} 340 341int safe_atolli(const char *s, long long int *ret_lli) { 342 char *x = NULL; 343 long long l; 344 345 assert(s); 346 assert(ret_lli); 347 348 errno = 0; 349 l = strtoll(s, &x, 0); 350 351 if (!x || x == s || *x || errno) 352 return errno ? -errno : -EINVAL; 353 354 *ret_lli = l; 355 return 0; 356} 357 358static size_t strcspn_escaped(const char *s, const char *reject) { 359 bool escaped = false; 360 int n; 361 362 for (n=0; s[n]; n++) { 363 if (escaped) 364 escaped = false; 365 else if (s[n] == '\\') 366 escaped = true; 367 else if (strchr(reject, s[n])) 368 break; 369 } 370 371 /* if s ends in \, return index of previous char */ 372 return n - escaped; 373} 374 375/* Split a string into words. */ 376const char* split(const char **state, size_t *l, const char *separator, bool quoted) { 377 const char *current; 378 379 current = *state; 380 381 if (!*current) { 382 assert(**state == '\0'); 383 return NULL; 384 } 385 386 current += strspn(current, separator); 387 if (!*current) { 388 *state = current; 389 return NULL; 390 } 391 392 if (quoted && strchr("\'\"", *current)) { 393 char quotechars[2] = {*current, '\0'}; 394 395 *l = strcspn_escaped(current + 1, quotechars); 396 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] || 397 (current[*l + 2] && !strchr(separator, current[*l + 2]))) { 398 /* right quote missing or garbage at the end */ 399 *state = current; 400 return NULL; 401 } 402 *state = current++ + *l + 2; 403 } else if (quoted) { 404 *l = strcspn_escaped(current, separator); 405 if (current[*l] && !strchr(separator, current[*l])) { 406 /* unfinished escape */ 407 *state = current; 408 return NULL; 409 } 410 *state = current + *l; 411 } else { 412 *l = strcspn(current, separator); 413 *state = current + *l; 414 } 415 416 return current; 417} 418 419char *truncate_nl(char *s) { 420 assert(s); 421 422 s[strcspn(s, NEWLINE)] = 0; 423 return s; 424} 425 426char *strnappend(const char *s, const char *suffix, size_t b) { 427 size_t a; 428 char *r; 429 430 if (!s && !suffix) 431 return strdup(""); 432 433 if (!s) 434 return strndup(suffix, b); 435 436 if (!suffix) 437 return strdup(s); 438 439 assert(s); 440 assert(suffix); 441 442 a = strlen(s); 443 if (b > ((size_t) -1) - a) 444 return NULL; 445 446 r = new(char, a+b+1); 447 if (!r) 448 return NULL; 449 450 memcpy(r, s, a); 451 memcpy(r+a, suffix, b); 452 r[a+b] = 0; 453 454 return r; 455} 456 457char *strappend(const char *s, const char *suffix) { 458 return strnappend(s, suffix, suffix ? strlen(suffix) : 0); 459} 460 461int rmdir_parents(const char *path, const char *stop) { 462 size_t l; 463 int r = 0; 464 465 assert(path); 466 assert(stop); 467 468 l = strlen(path); 469 470 /* Skip trailing slashes */ 471 while (l > 0 && path[l-1] == '/') 472 l--; 473 474 while (l > 0) { 475 char *t; 476 477 /* Skip last component */ 478 while (l > 0 && path[l-1] != '/') 479 l--; 480 481 /* Skip trailing slashes */ 482 while (l > 0 && path[l-1] == '/') 483 l--; 484 485 if (l <= 0) 486 break; 487 488 if (!(t = strndup(path, l))) 489 return -ENOMEM; 490 491 if (path_startswith(stop, t)) { 492 free(t); 493 return 0; 494 } 495 496 r = rmdir(t); 497 free(t); 498 499 if (r < 0) 500 if (errno != ENOENT) 501 return -errno; 502 } 503 504 return 0; 505} 506 507char hexchar(int x) { 508 static const char table[16] = "0123456789abcdef"; 509 510 return table[x & 15]; 511} 512 513int unhexchar(char c) { 514 515 if (c >= '0' && c <= '9') 516 return c - '0'; 517 518 if (c >= 'a' && c <= 'f') 519 return c - 'a' + 10; 520 521 if (c >= 'A' && c <= 'F') 522 return c - 'A' + 10; 523 524 return -EINVAL; 525} 526 527char octchar(int x) { 528 return '0' + (x & 7); 529} 530 531int unoctchar(char c) { 532 533 if (c >= '0' && c <= '7') 534 return c - '0'; 535 536 return -EINVAL; 537} 538 539char *cescape(const char *s) { 540 char *r, *t; 541 const char *f; 542 543 assert(s); 544 545 /* Does C style string escaping. May be reversed with 546 * cunescape(). */ 547 548 r = new(char, strlen(s)*4 + 1); 549 if (!r) 550 return NULL; 551 552 for (f = s, t = r; *f; f++) 553 t += cescape_char(*f, t); 554 555 *t = 0; 556 557 return r; 558} 559 560 561static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) { 562 int r = 1; 563 564 assert(p); 565 assert(*p); 566 assert(ret); 567 568 /* Unescapes C style. Returns the unescaped character in ret, 569 * unless we encountered a \u sequence in which case the full 570 * unicode character is returned in ret_unicode, instead. */ 571 572 if (length != (size_t) -1 && length < 1) 573 return -EINVAL; 574 575 switch (p[0]) { 576 577 case 'a': 578 *ret = '\a'; 579 break; 580 case 'b': 581 *ret = '\b'; 582 break; 583 case 'f': 584 *ret = '\f'; 585 break; 586 case 'n': 587 *ret = '\n'; 588 break; 589 case 'r': 590 *ret = '\r'; 591 break; 592 case 't': 593 *ret = '\t'; 594 break; 595 case 'v': 596 *ret = '\v'; 597 break; 598 case '\\': 599 *ret = '\\'; 600 break; 601 case '"': 602 *ret = '"'; 603 break; 604 case '\'': 605 *ret = '\''; 606 break; 607 608 case 's': 609 /* This is an extension of the XDG syntax files */ 610 *ret = ' '; 611 break; 612 613 case 'x': { 614 /* hexadecimal encoding */ 615 int a, b; 616 617 if (length != (size_t) -1 && length < 3) 618 return -EINVAL; 619 620 a = unhexchar(p[1]); 621 if (a < 0) 622 return -EINVAL; 623 624 b = unhexchar(p[2]); 625 if (b < 0) 626 return -EINVAL; 627 628 /* Don't allow NUL bytes */ 629 if (a == 0 && b == 0) 630 return -EINVAL; 631 632 *ret = (char) ((a << 4U) | b); 633 r = 3; 634 break; 635 } 636 637 case 'u': { 638 /* C++11 style 16bit unicode */ 639 640 int a[4]; 641 unsigned i; 642 uint32_t c; 643 644 if (length != (size_t) -1 && length < 5) 645 return -EINVAL; 646 647 for (i = 0; i < 4; i++) { 648 a[i] = unhexchar(p[1 + i]); 649 if (a[i] < 0) 650 return a[i]; 651 } 652 653 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3]; 654 655 /* Don't allow 0 chars */ 656 if (c == 0) 657 return -EINVAL; 658 659 if (c < 128) 660 *ret = c; 661 else { 662 if (!ret_unicode) 663 return -EINVAL; 664 665 *ret = 0; 666 *ret_unicode = c; 667 } 668 669 r = 5; 670 break; 671 } 672 673 case 'U': { 674 /* C++11 style 32bit unicode */ 675 676 int a[8]; 677 unsigned i; 678 uint32_t c; 679 680 if (length != (size_t) -1 && length < 9) 681 return -EINVAL; 682 683 for (i = 0; i < 8; i++) { 684 a[i] = unhexchar(p[1 + i]); 685 if (a[i] < 0) 686 return a[i]; 687 } 688 689 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) | 690 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7]; 691 692 /* Don't allow 0 chars */ 693 if (c == 0) 694 return -EINVAL; 695 696 /* Don't allow invalid code points */ 697 if (!unichar_is_valid(c)) 698 return -EINVAL; 699 700 if (c < 128) 701 *ret = c; 702 else { 703 if (!ret_unicode) 704 return -EINVAL; 705 706 *ret = 0; 707 *ret_unicode = c; 708 } 709 710 r = 9; 711 break; 712 } 713 714 case '0': 715 case '1': 716 case '2': 717 case '3': 718 case '4': 719 case '5': 720 case '6': 721 case '7': { 722 /* octal encoding */ 723 int a, b, c; 724 uint32_t m; 725 726 if (length != (size_t) -1 && length < 4) 727 return -EINVAL; 728 729 a = unoctchar(p[0]); 730 if (a < 0) 731 return -EINVAL; 732 733 b = unoctchar(p[1]); 734 if (b < 0) 735 return -EINVAL; 736 737 c = unoctchar(p[2]); 738 if (c < 0) 739 return -EINVAL; 740 741 /* don't allow NUL bytes */ 742 if (a == 0 && b == 0 && c == 0) 743 return -EINVAL; 744 745 /* Don't allow bytes above 255 */ 746 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c; 747 if (m > 255) 748 return -EINVAL; 749 750 *ret = m; 751 r = 3; 752 break; 753 } 754 755 default: 756 return -EINVAL; 757 } 758 759 return r; 760} 761 762char *xescape(const char *s, const char *bad) { 763 char *r, *t; 764 const char *f; 765 766 /* Escapes all chars in bad, in addition to \ and all special 767 * chars, in \xFF style escaping. May be reversed with 768 * cunescape(). */ 769 770 r = new(char, strlen(s) * 4 + 1); 771 if (!r) 772 return NULL; 773 774 for (f = s, t = r; *f; f++) { 775 776 if ((*f < ' ') || (*f >= 127) || 777 (*f == '\\') || strchr(bad, *f)) { 778 *(t++) = '\\'; 779 *(t++) = 'x'; 780 *(t++) = hexchar(*f >> 4); 781 *(t++) = hexchar(*f); 782 } else 783 *(t++) = *f; 784 } 785 786 *t = 0; 787 788 return r; 789} 790 791_pure_ static bool hidden_file_allow_backup(const char *filename) { 792 assert(filename); 793 794 return 795 filename[0] == '.' || 796 streq(filename, "lost+found") || 797 streq(filename, "aquota.user") || 798 streq(filename, "aquota.group") || 799 endswith(filename, ".rpmnew") || 800 endswith(filename, ".rpmsave") || 801 endswith(filename, ".rpmorig") || 802 endswith(filename, ".dpkg-old") || 803 endswith(filename, ".dpkg-new") || 804 endswith(filename, ".dpkg-tmp") || 805 endswith(filename, ".dpkg-dist") || 806 endswith(filename, ".dpkg-bak") || 807 endswith(filename, ".dpkg-backup") || 808 endswith(filename, ".dpkg-remove") || 809 endswith(filename, ".swp"); 810} 811 812bool hidden_file(const char *filename) { 813 assert(filename); 814 815 if (endswith(filename, "~")) 816 return true; 817 818 return hidden_file_allow_backup(filename); 819} 820 821int flush_fd(int fd) { 822 struct pollfd pollfd = { 823 .fd = fd, 824 .events = POLLIN, 825 }; 826 827 for (;;) { 828 char buf[LINE_MAX]; 829 ssize_t l; 830 int r; 831 832 r = poll(&pollfd, 1, 0); 833 if (r < 0) { 834 if (errno == EINTR) 835 continue; 836 837 return -errno; 838 839 } else if (r == 0) 840 return 0; 841 842 l = read(fd, buf, sizeof(buf)); 843 if (l < 0) { 844 845 if (errno == EINTR) 846 continue; 847 848 if (errno == EAGAIN) 849 return 0; 850 851 return -errno; 852 } else if (l == 0) 853 return 0; 854 } 855} 856 857ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { 858 uint8_t *p = buf; 859 ssize_t n = 0; 860 861 assert(fd >= 0); 862 assert(buf); 863 864 while (nbytes > 0) { 865 ssize_t k; 866 867 k = read(fd, p, nbytes); 868 if (k < 0) { 869 if (errno == EINTR) 870 continue; 871 872 if (errno == EAGAIN && do_poll) { 873 874 /* We knowingly ignore any return value here, 875 * and expect that any error/EOF is reported 876 * via read() */ 877 878 fd_wait_for_event(fd, POLLIN, USEC_INFINITY); 879 continue; 880 } 881 882 return n > 0 ? n : -errno; 883 } 884 885 if (k == 0) 886 return n; 887 888 p += k; 889 nbytes -= k; 890 n += k; 891 } 892 893 return n; 894} 895 896int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) { 897 ssize_t n; 898 899 n = loop_read(fd, buf, nbytes, do_poll); 900 if (n < 0) 901 return n; 902 if ((size_t) n != nbytes) 903 return -EIO; 904 return 0; 905} 906 907int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { 908 const uint8_t *p = buf; 909 910 assert(fd >= 0); 911 assert(buf); 912 913 errno = 0; 914 915 do { 916 ssize_t k; 917 918 k = write(fd, p, nbytes); 919 if (k < 0) { 920 if (errno == EINTR) 921 continue; 922 923 if (errno == EAGAIN && do_poll) { 924 /* We knowingly ignore any return value here, 925 * and expect that any error/EOF is reported 926 * via write() */ 927 928 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY); 929 continue; 930 } 931 932 return -errno; 933 } 934 935 if (nbytes > 0 && k == 0) /* Can't really happen */ 936 return -EIO; 937 938 p += k; 939 nbytes -= k; 940 } while (nbytes > 0); 941 942 return 0; 943} 944 945char* dirname_malloc(const char *path) { 946 char *d, *dir, *dir2; 947 948 d = strdup(path); 949 if (!d) 950 return NULL; 951 dir = dirname(d); 952 assert(dir); 953 954 if (dir != d) { 955 dir2 = strdup(dir); 956 free(d); 957 return dir2; 958 } 959 960 return dir; 961} 962 963_pure_ static int is_temporary_fs(struct statfs *s) { 964 assert(s); 965 966 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) || 967 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC); 968} 969 970int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { 971 assert(path); 972 973 /* Under the assumption that we are running privileged we 974 * first change the access mode and only then hand out 975 * ownership to avoid a window where access is too open. */ 976 977 if (mode != MODE_INVALID) 978 if (chmod(path, mode) < 0) 979 return -errno; 980 981 if (uid != UID_INVALID || gid != GID_INVALID) 982 if (chown(path, uid, gid) < 0) 983 return -errno; 984 985 return 0; 986} 987 988int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) { 989 _cleanup_close_ int fd; 990 int r; 991 992 assert(path); 993 994 if (parents) 995 mkdir_parents(path, 0755); 996 997 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644); 998 if (fd < 0) 999 return -errno; 1000 1001 if (mode > 0) { 1002 r = fchmod(fd, mode); 1003 if (r < 0) 1004 return -errno; 1005 } 1006 1007 if (uid != UID_INVALID || gid != GID_INVALID) { 1008 r = fchown(fd, uid, gid); 1009 if (r < 0) 1010 return -errno; 1011 } 1012 1013 if (stamp != USEC_INFINITY) { 1014 struct timespec ts[2]; 1015 1016 timespec_store(&ts[0], stamp); 1017 ts[1] = ts[0]; 1018 r = futimens(fd, ts); 1019 } else 1020 r = futimens(fd, NULL); 1021 if (r < 0) 1022 return -errno; 1023 1024 return 0; 1025} 1026 1027int touch(const char *path) { 1028 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0); 1029} 1030 1031bool null_or_empty(struct stat *st) { 1032 assert(st); 1033 1034 if (S_ISREG(st->st_mode) && st->st_size <= 0) 1035 return true; 1036 1037 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) 1038 return true; 1039 1040 return false; 1041} 1042 1043int null_or_empty_path(const char *fn) { 1044 struct stat st; 1045 1046 assert(fn); 1047 1048 if (stat(fn, &st) < 0) 1049 return -errno; 1050 1051 return null_or_empty(&st); 1052} 1053 1054int null_or_empty_fd(int fd) { 1055 struct stat st; 1056 1057 assert(fd >= 0); 1058 1059 if (fstat(fd, &st) < 0) 1060 return -errno; 1061 1062 return null_or_empty(&st); 1063} 1064 1065bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { 1066 assert(de); 1067 1068 if (de->d_type != DT_REG && 1069 de->d_type != DT_LNK && 1070 de->d_type != DT_UNKNOWN) 1071 return false; 1072 1073 if (hidden_file_allow_backup(de->d_name)) 1074 return false; 1075 1076 return endswith(de->d_name, suffix); 1077} 1078 1079bool nulstr_contains(const char*nulstr, const char *needle) { 1080 const char *i; 1081 1082 if (!nulstr) 1083 return false; 1084 1085 NULSTR_FOREACH(i, nulstr) 1086 if (streq(i, needle)) 1087 return true; 1088 1089 return false; 1090} 1091 1092 1093static inline int ppoll_fallback(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts, const sigset_t *sigmask) { 1094 int ready, timeout; 1095 sigset_t origmask; 1096 1097 timeout = (timeout_ts == NULL) ? -1 : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000); 1098 1099 /* This is racey, but what can we do without ppoll? */ 1100 sigprocmask(SIG_SETMASK, sigmask, &origmask); 1101 ready = poll(fds, nfds, timeout); 1102 sigprocmask(SIG_SETMASK, &origmask, NULL); 1103 1104 return ready; 1105} 1106 1107int fd_wait_for_event(int fd, int event, usec_t t) { 1108 1109 struct pollfd pollfd = { 1110 .fd = fd, 1111 .events = event, 1112 }; 1113 1114 struct timespec ts; 1115 int r; 1116 1117#if HAVE_DECL_PPOLL 1118 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL); 1119#else 1120 /* Fallback path when ppoll() is unavailable */ 1121 r = ppoll_fallback(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL); 1122#endif 1123 if (r < 0) 1124 return -errno; 1125 1126 if (r == 0) 1127 return 0; 1128 1129 return pollfd.revents; 1130} 1131 1132int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { 1133 FILE *f; 1134 char *t; 1135 int r, fd; 1136 1137 assert(path); 1138 assert(_f); 1139 assert(_temp_path); 1140 1141 r = tempfn_xxxxxx(path, &t); 1142 if (r < 0) 1143 return r; 1144 1145#if HAVE_DECL_MKOSTEMP 1146 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC); 1147#else 1148 fd = mkstemp_safe(t); 1149 fcntl(fd, F_SETFD, FD_CLOEXEC); 1150#endif 1151 if (fd < 0) { 1152 free(t); 1153 return -errno; 1154 } 1155 1156 f = fdopen(fd, "we"); 1157 if (!f) { 1158 unlink(t); 1159 free(t); 1160 return -errno; 1161 } 1162 1163 *_f = f; 1164 *_temp_path = t; 1165 1166 return 0; 1167} 1168 1169int get_user_creds( 1170 const char **username, 1171 uid_t *uid, gid_t *gid, 1172 const char **home, 1173 const char **shell) { 1174 1175 struct passwd *p; 1176 uid_t u; 1177 1178 assert(username); 1179 assert(*username); 1180 1181 /* We enforce some special rules for uid=0: in order to avoid 1182 * NSS lookups for root we hardcode its data. */ 1183 1184 if (streq(*username, "root") || streq(*username, "0")) { 1185 *username = "root"; 1186 1187 if (uid) 1188 *uid = 0; 1189 1190 if (gid) 1191 *gid = 0; 1192 1193 if (home) 1194 *home = "/root"; 1195 1196 if (shell) 1197 *shell = "/bin/sh"; 1198 1199 return 0; 1200 } 1201 1202 if (parse_uid(*username, &u) >= 0) { 1203 errno = 0; 1204 p = getpwuid(u); 1205 1206 /* If there are multiple users with the same id, make 1207 * sure to leave $USER to the configured value instead 1208 * of the first occurrence in the database. However if 1209 * the uid was configured by a numeric uid, then let's 1210 * pick the real username from /etc/passwd. */ 1211 if (p) 1212 *username = p->pw_name; 1213 } else { 1214 errno = 0; 1215 p = getpwnam(*username); 1216 } 1217 1218 if (!p) 1219 return errno > 0 ? -errno : -ESRCH; 1220 1221 if (uid) 1222 *uid = p->pw_uid; 1223 1224 if (gid) 1225 *gid = p->pw_gid; 1226 1227 if (home) 1228 *home = p->pw_dir; 1229 1230 if (shell) 1231 *shell = p->pw_shell; 1232 1233 return 0; 1234} 1235 1236int get_group_creds(const char **groupname, gid_t *gid) { 1237 struct group *g; 1238 gid_t id; 1239 1240 assert(groupname); 1241 1242 /* We enforce some special rules for gid=0: in order to avoid 1243 * NSS lookups for root we hardcode its data. */ 1244 1245 if (streq(*groupname, "root") || streq(*groupname, "0")) { 1246 *groupname = "root"; 1247 1248 if (gid) 1249 *gid = 0; 1250 1251 return 0; 1252 } 1253 1254 if (parse_gid(*groupname, &id) >= 0) { 1255 errno = 0; 1256 g = getgrgid(id); 1257 1258 if (g) 1259 *groupname = g->gr_name; 1260 } else { 1261 errno = 0; 1262 g = getgrnam(*groupname); 1263 } 1264 1265 if (!g) 1266 return errno > 0 ? -errno : -ESRCH; 1267 1268 if (gid) 1269 *gid = g->gr_gid; 1270 1271 return 0; 1272} 1273 1274char *strjoin(const char *x, ...) { 1275 va_list ap; 1276 size_t l; 1277 char *r, *p; 1278 1279 va_start(ap, x); 1280 1281 if (x) { 1282 l = strlen(x); 1283 1284 for (;;) { 1285 const char *t; 1286 size_t n; 1287 1288 t = va_arg(ap, const char *); 1289 if (!t) 1290 break; 1291 1292 n = strlen(t); 1293 if (n > ((size_t) -1) - l) { 1294 va_end(ap); 1295 return NULL; 1296 } 1297 1298 l += n; 1299 } 1300 } else 1301 l = 0; 1302 1303 va_end(ap); 1304 1305 r = new(char, l+1); 1306 if (!r) 1307 return NULL; 1308 1309 if (x) { 1310 p = stpcpy(r, x); 1311 1312 va_start(ap, x); 1313 1314 for (;;) { 1315 const char *t; 1316 1317 t = va_arg(ap, const char *); 1318 if (!t) 1319 break; 1320 1321 p = stpcpy(p, t); 1322 } 1323 1324 va_end(ap); 1325 } else 1326 r[0] = 0; 1327 1328 return r; 1329} 1330 1331bool is_main_thread(void) { 1332 static thread_local int cached = 0; 1333 1334 if (_unlikely_(cached == 0)) 1335 cached = getpid() == gettid() ? 1 : -1; 1336 1337 return cached > 0; 1338} 1339 1340static const char *const ioprio_class_table[] = { 1341 [IOPRIO_CLASS_NONE] = "none", 1342 [IOPRIO_CLASS_RT] = "realtime", 1343 [IOPRIO_CLASS_BE] = "best-effort", 1344 [IOPRIO_CLASS_IDLE] = "idle" 1345}; 1346 1347DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX); 1348 1349static const char *const sigchld_code_table[] = { 1350 [CLD_EXITED] = "exited", 1351 [CLD_KILLED] = "killed", 1352 [CLD_DUMPED] = "dumped", 1353 [CLD_TRAPPED] = "trapped", 1354 [CLD_STOPPED] = "stopped", 1355 [CLD_CONTINUED] = "continued", 1356}; 1357 1358DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int); 1359 1360static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = { 1361 [LOG_FAC(LOG_KERN)] = "kern", 1362 [LOG_FAC(LOG_USER)] = "user", 1363 [LOG_FAC(LOG_MAIL)] = "mail", 1364 [LOG_FAC(LOG_DAEMON)] = "daemon", 1365 [LOG_FAC(LOG_AUTH)] = "auth", 1366 [LOG_FAC(LOG_SYSLOG)] = "syslog", 1367 [LOG_FAC(LOG_LPR)] = "lpr", 1368 [LOG_FAC(LOG_NEWS)] = "news", 1369 [LOG_FAC(LOG_UUCP)] = "uucp", 1370 [LOG_FAC(LOG_CRON)] = "cron", 1371 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv", 1372 [LOG_FAC(LOG_FTP)] = "ftp", 1373 [LOG_FAC(LOG_LOCAL0)] = "local0", 1374 [LOG_FAC(LOG_LOCAL1)] = "local1", 1375 [LOG_FAC(LOG_LOCAL2)] = "local2", 1376 [LOG_FAC(LOG_LOCAL3)] = "local3", 1377 [LOG_FAC(LOG_LOCAL4)] = "local4", 1378 [LOG_FAC(LOG_LOCAL5)] = "local5", 1379 [LOG_FAC(LOG_LOCAL6)] = "local6", 1380 [LOG_FAC(LOG_LOCAL7)] = "local7" 1381}; 1382 1383DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0)); 1384 1385static const char *const log_level_table[] = { 1386 [LOG_EMERG] = "emerg", 1387 [LOG_ALERT] = "alert", 1388 [LOG_CRIT] = "crit", 1389 [LOG_ERR] = "err", 1390 [LOG_WARNING] = "warning", 1391 [LOG_NOTICE] = "notice", 1392 [LOG_INFO] = "info", 1393 [LOG_DEBUG] = "debug" 1394}; 1395 1396DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG); 1397 1398static const char* const sched_policy_table[] = { 1399 [SCHED_OTHER] = "other", 1400 [SCHED_BATCH] = "batch", 1401 [SCHED_IDLE] = "idle", 1402 [SCHED_FIFO] = "fifo", 1403 [SCHED_RR] = "rr" 1404}; 1405 1406DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); 1407 1408static const char* const rlimit_table[_RLIMIT_MAX] = { 1409 [RLIMIT_CPU] = "LimitCPU", 1410 [RLIMIT_FSIZE] = "LimitFSIZE", 1411 [RLIMIT_DATA] = "LimitDATA", 1412 [RLIMIT_STACK] = "LimitSTACK", 1413 [RLIMIT_CORE] = "LimitCORE", 1414 [RLIMIT_RSS] = "LimitRSS", 1415 [RLIMIT_NOFILE] = "LimitNOFILE", 1416 [RLIMIT_AS] = "LimitAS", 1417 [RLIMIT_NPROC] = "LimitNPROC", 1418 [RLIMIT_MEMLOCK] = "LimitMEMLOCK", 1419 [RLIMIT_LOCKS] = "LimitLOCKS", 1420 [RLIMIT_SIGPENDING] = "LimitSIGPENDING", 1421 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE", 1422 [RLIMIT_NICE] = "LimitNICE", 1423 [RLIMIT_RTPRIO] = "LimitRTPRIO", 1424 [RLIMIT_RTTIME] = "LimitRTTIME" 1425}; 1426 1427DEFINE_STRING_TABLE_LOOKUP(rlimit, int); 1428 1429static const char* const ip_tos_table[] = { 1430 [IPTOS_LOWDELAY] = "low-delay", 1431 [IPTOS_THROUGHPUT] = "throughput", 1432 [IPTOS_RELIABILITY] = "reliability", 1433 [IPTOS_LOWCOST] = "low-cost", 1434}; 1435 1436DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); 1437 1438static const char *const __signal_table[] = { 1439 [SIGHUP] = "HUP", 1440 [SIGINT] = "INT", 1441 [SIGQUIT] = "QUIT", 1442 [SIGILL] = "ILL", 1443 [SIGTRAP] = "TRAP", 1444 [SIGABRT] = "ABRT", 1445 [SIGBUS] = "BUS", 1446 [SIGFPE] = "FPE", 1447 [SIGKILL] = "KILL", 1448 [SIGUSR1] = "USR1", 1449 [SIGSEGV] = "SEGV", 1450 [SIGUSR2] = "USR2", 1451 [SIGPIPE] = "PIPE", 1452 [SIGALRM] = "ALRM", 1453 [SIGTERM] = "TERM", 1454#ifdef SIGSTKFLT 1455 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */ 1456#endif 1457 [SIGCHLD] = "CHLD", 1458 [SIGCONT] = "CONT", 1459 [SIGSTOP] = "STOP", 1460 [SIGTSTP] = "TSTP", 1461 [SIGTTIN] = "TTIN", 1462 [SIGTTOU] = "TTOU", 1463 [SIGURG] = "URG", 1464 [SIGXCPU] = "XCPU", 1465 [SIGXFSZ] = "XFSZ", 1466 [SIGVTALRM] = "VTALRM", 1467 [SIGPROF] = "PROF", 1468 [SIGWINCH] = "WINCH", 1469 [SIGIO] = "IO", 1470 [SIGPWR] = "PWR", 1471 [SIGSYS] = "SYS" 1472}; 1473 1474DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); 1475 1476const char *signal_to_string(int signo) { 1477 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1]; 1478 const char *name; 1479 1480 name = __signal_to_string(signo); 1481 if (name) 1482 return name; 1483 1484 if (signo >= SIGRTMIN && signo <= SIGRTMAX) 1485 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN); 1486 else 1487 snprintf(buf, sizeof(buf), "%d", signo); 1488 1489 return buf; 1490} 1491 1492int fd_inc_sndbuf(int fd, size_t n) { 1493 int r, value; 1494 socklen_t l = sizeof(value); 1495 1496 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); 1497 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2) 1498 return 0; 1499 1500 /* If we have the privileges we will ignore the kernel limit. */ 1501 1502 value = (int) n; 1503 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) 1504 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) 1505 return -errno; 1506 1507 return 1; 1508} 1509 1510bool in_initrd(void) { 1511 static int saved = -1; 1512 struct statfs s; 1513 1514 if (saved >= 0) 1515 return saved; 1516 1517 /* We make two checks here: 1518 * 1519 * 1. the flag file /etc/initrd-release must exist 1520 * 2. the root file system must be a memory file system 1521 * 1522 * The second check is extra paranoia, since misdetecting an 1523 * initrd can have bad bad consequences due the initrd 1524 * emptying when transititioning to the main systemd. 1525 */ 1526 1527 saved = access("/etc/initrd-release", F_OK) >= 0 && 1528 statfs("/", &s) >= 0 && 1529 is_temporary_fs(&s); 1530 1531 return saved; 1532} 1533 1534bool filename_is_valid(const char *p) { 1535 1536 if (isempty(p)) 1537 return false; 1538 1539 if (strchr(p, '/')) 1540 return false; 1541 1542 if (streq(p, ".")) 1543 return false; 1544 1545 if (streq(p, "..")) 1546 return false; 1547 1548 if (strlen(p) > FILENAME_MAX) 1549 return false; 1550 1551 return true; 1552} 1553 1554/* hey glibc, APIs with callbacks without a user pointer are so useless */ 1555void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, 1556 int (*compar) (const void *, const void *, void *), void *arg) { 1557 size_t l, u, idx; 1558 const void *p; 1559 int comparison; 1560 1561 l = 0; 1562 u = nmemb; 1563 while (l < u) { 1564 idx = (l + u) / 2; 1565 p = (void *)(((const char *) base) + (idx * size)); 1566 comparison = compar(key, p, arg); 1567 if (comparison < 0) 1568 u = idx; 1569 else if (comparison > 0) 1570 l = idx + 1; 1571 else 1572 return (void *)p; 1573 } 1574 return NULL; 1575} 1576 1577void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) { 1578 size_t a, newalloc; 1579 void *q; 1580 1581 assert(p); 1582 assert(allocated); 1583 1584 if (*allocated >= need) 1585 return *p; 1586 1587 newalloc = MAX(need * 2, 64u / size); 1588 a = newalloc * size; 1589 1590 /* check for overflows */ 1591 if (a < size * need) 1592 return NULL; 1593 1594 q = realloc(*p, a); 1595 if (!q) 1596 return NULL; 1597 1598 *p = q; 1599 *allocated = newalloc; 1600 return q; 1601} 1602 1603int proc_cmdline(char **ret) { 1604 assert(ret); 1605 1606 if (detect_container(NULL) > 0) 1607 return get_process_cmdline(1, 0, false, ret); 1608 else 1609 return read_one_line_file("/proc/cmdline", ret); 1610} 1611 1612int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) { 1613 _cleanup_free_ char *line = NULL; 1614 const char *p; 1615 int r; 1616 1617 assert(parse_item); 1618 1619 r = proc_cmdline(&line); 1620 if (r < 0) 1621 return r; 1622 1623 p = line; 1624 for (;;) { 1625 _cleanup_free_ char *word = NULL; 1626 char *value = NULL; 1627 1628 r = unquote_first_word(&p, &word, UNQUOTE_RELAX); 1629 if (r < 0) 1630 return r; 1631 if (r == 0) 1632 break; 1633 1634 /* Filter out arguments that are intended only for the 1635 * initrd */ 1636 if (!in_initrd() && startswith(word, "rd.")) 1637 continue; 1638 1639 value = strchr(word, '='); 1640 if (value) 1641 *(value++) = 0; 1642 1643 r = parse_item(word, value); 1644 if (r < 0) 1645 return r; 1646 } 1647 1648 return 0; 1649} 1650 1651int getpeercred(int fd, struct ucred *ucred) { 1652 socklen_t n = sizeof(struct ucred); 1653 struct ucred u; 1654 int r; 1655 1656 assert(fd >= 0); 1657 assert(ucred); 1658 1659 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n); 1660 if (r < 0) 1661 return -errno; 1662 1663 if (n != sizeof(struct ucred)) 1664 return -EIO; 1665 1666 /* Check if the data is actually useful and not suppressed due 1667 * to namespacing issues */ 1668 if (u.pid <= 0) 1669 return -ENODATA; 1670 if (u.uid == UID_INVALID) 1671 return -ENODATA; 1672 if (u.gid == GID_INVALID) 1673 return -ENODATA; 1674 1675 *ucred = u; 1676 return 0; 1677} 1678 1679#if HAVE_DECL_MKOSTEMP 1680/* This is much like like mkostemp() but is subject to umask(). */ 1681int mkostemp_safe(char *pattern, int flags) { 1682 _cleanup_umask_ mode_t u; 1683 int fd; 1684 1685 assert(pattern); 1686 1687 u = umask(077); 1688 1689 fd = mkostemp(pattern, flags); 1690 if (fd < 0) 1691 return -errno; 1692 1693 return fd; 1694} 1695#else 1696/* This is much like like mkstemp() but is subject to umask(). */ 1697int mkstemp_safe(char *pattern) { 1698 _cleanup_umask_ mode_t u; 1699 int fd; 1700 1701 assert(pattern); 1702 1703 u = umask(077); 1704 1705 fd = mkstemp(pattern); 1706 if (fd < 0) 1707 return -errno; 1708 1709 return fd; 1710} 1711#endif 1712 1713int tempfn_xxxxxx(const char *p, char **ret) { 1714 const char *fn; 1715 char *t; 1716 1717 assert(p); 1718 assert(ret); 1719 1720 /* 1721 * Turns this: 1722 * /foo/bar/waldo 1723 * 1724 * Into this: 1725 * /foo/bar/.#waldoXXXXXX 1726 */ 1727 1728 fn = basename((char*)p); 1729 if (!filename_is_valid(fn)) 1730 return -EINVAL; 1731 1732 t = new(char, strlen(p) + 2 + 6 + 1); 1733 if (!t) 1734 return -ENOMEM; 1735 1736 strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), "XXXXXX"); 1737 1738 *ret = path_kill_slashes(t); 1739 return 0; 1740} 1741 1742int is_dir(const char* path, bool follow) { 1743 struct stat st; 1744 int r; 1745 1746 if (follow) 1747 r = stat(path, &st); 1748 else 1749 r = lstat(path, &st); 1750 if (r < 0) 1751 return -errno; 1752 1753 return !!S_ISDIR(st.st_mode); 1754} 1755 1756int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) { 1757 _cleanup_free_ char *s = NULL; 1758 size_t allocated = 0, sz = 0; 1759 int r; 1760 1761 enum { 1762 START, 1763 VALUE, 1764 VALUE_ESCAPE, 1765 SINGLE_QUOTE, 1766 SINGLE_QUOTE_ESCAPE, 1767 DOUBLE_QUOTE, 1768 DOUBLE_QUOTE_ESCAPE, 1769 SPACE, 1770 } state = START; 1771 1772 assert(p); 1773 assert(*p); 1774 assert(ret); 1775 1776 /* Parses the first word of a string, and returns it in 1777 * *ret. Removes all quotes in the process. When parsing fails 1778 * (because of an uneven number of quotes or similar), leaves 1779 * the pointer *p at the first invalid character. */ 1780 1781 for (;;) { 1782 char c = **p; 1783 1784 switch (state) { 1785 1786 case START: 1787 if (c == 0) 1788 goto finish; 1789 else if (strchr(WHITESPACE, c)) 1790 break; 1791 1792 state = VALUE; 1793 /* fallthrough */ 1794 1795 case VALUE: 1796 if (c == 0) 1797 goto finish; 1798 else if (c == '\'') 1799 state = SINGLE_QUOTE; 1800 else if (c == '\\') 1801 state = VALUE_ESCAPE; 1802 else if (c == '\"') 1803 state = DOUBLE_QUOTE; 1804 else if (strchr(WHITESPACE, c)) 1805 state = SPACE; 1806 else { 1807 if (!GREEDY_REALLOC(s, allocated, sz+2)) 1808 return -ENOMEM; 1809 1810 s[sz++] = c; 1811 } 1812 1813 break; 1814 1815 case VALUE_ESCAPE: 1816 if (c == 0) { 1817 if (flags & UNQUOTE_RELAX) 1818 goto finish; 1819 return -EINVAL; 1820 } 1821 1822 if (!GREEDY_REALLOC(s, allocated, sz+7)) 1823 return -ENOMEM; 1824 1825 if (flags & UNQUOTE_CUNESCAPE) { 1826 uint32_t u; 1827 1828 r = cunescape_one(*p, (size_t) -1, &c, &u); 1829 if (r < 0) 1830 return -EINVAL; 1831 1832 (*p) += r - 1; 1833 1834 if (c != 0) 1835 s[sz++] = c; /* normal explicit char */ 1836 else 1837 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */ 1838 } else 1839 s[sz++] = c; 1840 1841 state = VALUE; 1842 break; 1843 1844 case SINGLE_QUOTE: 1845 if (c == 0) { 1846 if (flags & UNQUOTE_RELAX) 1847 goto finish; 1848 return -EINVAL; 1849 } else if (c == '\'') 1850 state = VALUE; 1851 else if (c == '\\') 1852 state = SINGLE_QUOTE_ESCAPE; 1853 else { 1854 if (!GREEDY_REALLOC(s, allocated, sz+2)) 1855 return -ENOMEM; 1856 1857 s[sz++] = c; 1858 } 1859 1860 break; 1861 1862 case SINGLE_QUOTE_ESCAPE: 1863 if (c == 0) { 1864 if (flags & UNQUOTE_RELAX) 1865 goto finish; 1866 return -EINVAL; 1867 } 1868 1869 if (!GREEDY_REALLOC(s, allocated, sz+7)) 1870 return -ENOMEM; 1871 1872 if (flags & UNQUOTE_CUNESCAPE) { 1873 uint32_t u; 1874 1875 r = cunescape_one(*p, (size_t) -1, &c, &u); 1876 if (r < 0) 1877 return -EINVAL; 1878 1879 (*p) += r - 1; 1880 1881 if (c != 0) 1882 s[sz++] = c; 1883 else 1884 sz += utf8_encode_unichar(s + sz, u); 1885 } else 1886 s[sz++] = c; 1887 1888 state = SINGLE_QUOTE; 1889 break; 1890 1891 case DOUBLE_QUOTE: 1892 if (c == 0) 1893 return -EINVAL; 1894 else if (c == '\"') 1895 state = VALUE; 1896 else if (c == '\\') 1897 state = DOUBLE_QUOTE_ESCAPE; 1898 else { 1899 if (!GREEDY_REALLOC(s, allocated, sz+2)) 1900 return -ENOMEM; 1901 1902 s[sz++] = c; 1903 } 1904 1905 break; 1906 1907 case DOUBLE_QUOTE_ESCAPE: 1908 if (c == 0) { 1909 if (flags & UNQUOTE_RELAX) 1910 goto finish; 1911 return -EINVAL; 1912 } 1913 1914 if (!GREEDY_REALLOC(s, allocated, sz+7)) 1915 return -ENOMEM; 1916 1917 if (flags & UNQUOTE_CUNESCAPE) { 1918 uint32_t u; 1919 1920 r = cunescape_one(*p, (size_t) -1, &c, &u); 1921 if (r < 0) 1922 return -EINVAL; 1923 1924 (*p) += r - 1; 1925 1926 if (c != 0) 1927 s[sz++] = c; 1928 else 1929 sz += utf8_encode_unichar(s + sz, u); 1930 } else 1931 s[sz++] = c; 1932 1933 state = DOUBLE_QUOTE; 1934 break; 1935 1936 case SPACE: 1937 if (c == 0) 1938 goto finish; 1939 if (!strchr(WHITESPACE, c)) 1940 goto finish; 1941 1942 break; 1943 } 1944 1945 (*p) ++; 1946 } 1947 1948finish: 1949 if (!s) { 1950 *ret = NULL; 1951 return 0; 1952 } 1953 1954 s[sz] = 0; 1955 *ret = s; 1956 s = NULL; 1957 1958 return 1; 1959} 1960 1961void cmsg_close_all(struct msghdr *mh) { 1962 struct cmsghdr *cmsg; 1963 1964 assert(mh); 1965 1966 for (cmsg = CMSG_FIRSTHDR(mh); cmsg; cmsg = CMSG_NXTHDR(mh, cmsg)) 1967 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) 1968 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int)); 1969} 1970