LCOV - code coverage report
Current view: top level - basic - util.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 2125 3405 62.4 %
Date: 2015-07-29 18:47:03 Functions: 163 234 69.7 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2010 Lennart Poettering
       7             : 
       8             :   systemd is free software; you can redistribute it and/or modify it
       9             :   under the terms of the GNU Lesser General Public License as published by
      10             :   the Free Software Foundation; either version 2.1 of the License, or
      11             :   (at your option) any later version.
      12             : 
      13             :   systemd 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 License
      19             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include <string.h>
      23             : #include <unistd.h>
      24             : #include <errno.h>
      25             : #include <stdlib.h>
      26             : #include <signal.h>
      27             : #include <libintl.h>
      28             : #include <stdio.h>
      29             : #include <syslog.h>
      30             : #include <sched.h>
      31             : #include <sys/resource.h>
      32             : #include <linux/sched.h>
      33             : #include <sys/types.h>
      34             : #include <sys/stat.h>
      35             : #include <fcntl.h>
      36             : #include <dirent.h>
      37             : #include <sys/ioctl.h>
      38             : #include <stdarg.h>
      39             : #include <poll.h>
      40             : #include <ctype.h>
      41             : #include <sys/prctl.h>
      42             : #include <sys/utsname.h>
      43             : #include <pwd.h>
      44             : #include <netinet/ip.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 <sys/mount.h>
      52             : #include <linux/magic.h>
      53             : #include <limits.h>
      54             : #include <langinfo.h>
      55             : #include <locale.h>
      56             : #include <sys/personality.h>
      57             : #include <sys/xattr.h>
      58             : #include <sys/statvfs.h>
      59             : #include <sys/file.h>
      60             : #include <linux/fs.h>
      61             : 
      62             : /* When we include libgen.h because we need dirname() we immediately
      63             :  * undefine basename() since libgen.h defines it as a macro to the POSIX
      64             :  * version which is really broken. We prefer GNU basename(). */
      65             : #include <libgen.h>
      66             : #undef basename
      67             : 
      68             : #ifdef HAVE_SYS_AUXV_H
      69             : #include <sys/auxv.h>
      70             : #endif
      71             : 
      72             : #include "config.h"
      73             : #include "macro.h"
      74             : #include "util.h"
      75             : #include "ioprio.h"
      76             : #include "missing.h"
      77             : #include "log.h"
      78             : #include "strv.h"
      79             : #include "mkdir.h"
      80             : #include "path-util.h"
      81             : #include "exit-status.h"
      82             : #include "hashmap.h"
      83             : #include "env-util.h"
      84             : #include "fileio.h"
      85             : #include "device-nodes.h"
      86             : #include "utf8.h"
      87             : #include "gunicode.h"
      88             : #include "virt.h"
      89             : #include "def.h"
      90             : #include "sparse-endian.h"
      91             : #include "formats-util.h"
      92             : #include "process-util.h"
      93             : #include "random-util.h"
      94             : #include "terminal-util.h"
      95             : #include "hostname-util.h"
      96             : #include "signal-util.h"
      97             : 
      98             : /* Put this test here for a lack of better place */
      99             : assert_cc(EAGAIN == EWOULDBLOCK);
     100             : 
     101             : int saved_argc = 0;
     102             : char **saved_argv = NULL;
     103             : 
     104       76022 : size_t page_size(void) {
     105             :         static thread_local size_t pgsz = 0;
     106             :         long r;
     107             : 
     108       76022 :         if (_likely_(pgsz > 0))
     109       75962 :                 return pgsz;
     110             : 
     111          60 :         r = sysconf(_SC_PAGESIZE);
     112          60 :         assert(r > 0);
     113             : 
     114          60 :         pgsz = (size_t) r;
     115          60 :         return pgsz;
     116             : }
     117             : 
     118      148709 : bool streq_ptr(const char *a, const char *b) {
     119             : 
     120             :         /* Like streq(), but tries to make sense of NULL pointers */
     121             : 
     122      148709 :         if (a && b)
     123      132115 :                 return streq(a, b);
     124             : 
     125       16594 :         if (!a && !b)
     126         134 :                 return true;
     127             : 
     128       16460 :         return false;
     129             : }
     130             : 
     131      147209 : char* endswith(const char *s, const char *postfix) {
     132             :         size_t sl, pl;
     133             : 
     134      147209 :         assert(s);
     135      147209 :         assert(postfix);
     136             : 
     137      147209 :         sl = strlen(s);
     138      147209 :         pl = strlen(postfix);
     139             : 
     140      147209 :         if (pl == 0)
     141           2 :                 return (char*) s + sl;
     142             : 
     143      147207 :         if (sl < pl)
     144        7205 :                 return NULL;
     145             : 
     146      140002 :         if (memcmp(s + sl - pl, postfix, pl) != 0)
     147      135644 :                 return NULL;
     148             : 
     149        4358 :         return (char*) s + sl - pl;
     150             : }
     151             : 
     152           0 : char* endswith_no_case(const char *s, const char *postfix) {
     153             :         size_t sl, pl;
     154             : 
     155           0 :         assert(s);
     156           0 :         assert(postfix);
     157             : 
     158           0 :         sl = strlen(s);
     159           0 :         pl = strlen(postfix);
     160             : 
     161           0 :         if (pl == 0)
     162           0 :                 return (char*) s + sl;
     163             : 
     164           0 :         if (sl < pl)
     165           0 :                 return NULL;
     166             : 
     167           0 :         if (strcasecmp(s + sl - pl, postfix) != 0)
     168           0 :                 return NULL;
     169             : 
     170           0 :         return (char*) s + sl - pl;
     171             : }
     172             : 
     173          10 : char* first_word(const char *s, const char *word) {
     174             :         size_t sl, wl;
     175             :         const char *p;
     176             : 
     177          10 :         assert(s);
     178          10 :         assert(word);
     179             : 
     180             :         /* Checks if the string starts with the specified word, either
     181             :          * followed by NUL or by whitespace. Returns a pointer to the
     182             :          * NUL or the first character after the whitespace. */
     183             : 
     184          10 :         sl = strlen(s);
     185          10 :         wl = strlen(word);
     186             : 
     187          10 :         if (sl < wl)
     188           1 :                 return NULL;
     189             : 
     190           9 :         if (wl == 0)
     191           1 :                 return (char*) s;
     192             : 
     193           8 :         if (memcmp(s, word, wl) != 0)
     194           1 :                 return NULL;
     195             : 
     196           7 :         p = s + wl;
     197           7 :         if (*p == 0)
     198           1 :                 return (char*) p;
     199             : 
     200           6 :         if (!strchr(WHITESPACE, *p))
     201           1 :                 return NULL;
     202             : 
     203           5 :         p += strspn(p, WHITESPACE);
     204           5 :         return (char*) p;
     205             : }
     206             : 
     207        5601 : size_t cescape_char(char c, char *buf) {
     208        5601 :         char * buf_old = buf;
     209             : 
     210        5601 :         switch (c) {
     211             : 
     212             :                 case '\a':
     213           1 :                         *(buf++) = '\\';
     214           1 :                         *(buf++) = 'a';
     215           1 :                         break;
     216             :                 case '\b':
     217           1 :                         *(buf++) = '\\';
     218           1 :                         *(buf++) = 'b';
     219           1 :                         break;
     220             :                 case '\f':
     221           1 :                         *(buf++) = '\\';
     222           1 :                         *(buf++) = 'f';
     223           1 :                         break;
     224             :                 case '\n':
     225           1 :                         *(buf++) = '\\';
     226           1 :                         *(buf++) = 'n';
     227           1 :                         break;
     228             :                 case '\r':
     229           1 :                         *(buf++) = '\\';
     230           1 :                         *(buf++) = 'r';
     231           1 :                         break;
     232             :                 case '\t':
     233           1 :                         *(buf++) = '\\';
     234           1 :                         *(buf++) = 't';
     235           1 :                         break;
     236             :                 case '\v':
     237           1 :                         *(buf++) = '\\';
     238           1 :                         *(buf++) = 'v';
     239           1 :                         break;
     240             :                 case '\\':
     241         118 :                         *(buf++) = '\\';
     242         118 :                         *(buf++) = '\\';
     243         118 :                         break;
     244             :                 case '"':
     245           6 :                         *(buf++) = '\\';
     246           6 :                         *(buf++) = '"';
     247           6 :                         break;
     248             :                 case '\'':
     249           5 :                         *(buf++) = '\\';
     250           5 :                         *(buf++) = '\'';
     251           5 :                         break;
     252             : 
     253             :                 default:
     254             :                         /* For special chars we prefer octal over
     255             :                          * hexadecimal encoding, simply because glib's
     256             :                          * g_strescape() does the same */
     257        5465 :                         if ((c < ' ') || (c >= 127)) {
     258           4 :                                 *(buf++) = '\\';
     259           4 :                                 *(buf++) = octchar((unsigned char) c >> 6);
     260           4 :                                 *(buf++) = octchar((unsigned char) c >> 3);
     261           4 :                                 *(buf++) = octchar((unsigned char) c);
     262             :                         } else
     263        5461 :                                 *(buf++) = c;
     264        5465 :                         break;
     265             :         }
     266             : 
     267        5601 :         return buf - buf_old;
     268             : }
     269             : 
     270       19269 : int close_nointr(int fd) {
     271       19269 :         assert(fd >= 0);
     272             : 
     273       19269 :         if (close(fd) >= 0)
     274       19264 :                 return 0;
     275             : 
     276             :         /*
     277             :          * Just ignore EINTR; a retry loop is the wrong thing to do on
     278             :          * Linux.
     279             :          *
     280             :          * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
     281             :          * https://bugzilla.gnome.org/show_bug.cgi?id=682819
     282             :          * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
     283             :          * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
     284             :          */
     285           5 :         if (errno == EINTR)
     286           0 :                 return 0;
     287             : 
     288           5 :         return -errno;
     289             : }
     290             : 
     291       28036 : int safe_close(int fd) {
     292             : 
     293             :         /*
     294             :          * Like close_nointr() but cannot fail. Guarantees errno is
     295             :          * unchanged. Is a NOP with negative fds passed, and returns
     296             :          * -1, so that it can be used in this syntax:
     297             :          *
     298             :          * fd = safe_close(fd);
     299             :          */
     300             : 
     301       28036 :         if (fd >= 0) {
     302       38492 :                 PROTECT_ERRNO;
     303             : 
     304             :                 /* The kernel might return pretty much any error code
     305             :                  * via close(), but the fd will be closed anyway. The
     306             :                  * only condition we want to check for here is whether
     307             :                  * the fd was invalid at all... */
     308             : 
     309       19246 :                 assert_se(close_nointr(fd) != -EBADF);
     310             :         }
     311             : 
     312       28036 :         return -1;
     313             : }
     314             : 
     315       15687 : void close_many(const int fds[], unsigned n_fd) {
     316             :         unsigned i;
     317             : 
     318       15687 :         assert(fds || n_fd <= 0);
     319             : 
     320       15693 :         for (i = 0; i < n_fd; i++)
     321           6 :                 safe_close(fds[i]);
     322       15687 : }
     323             : 
     324           2 : int unlink_noerrno(const char *path) {
     325           4 :         PROTECT_ERRNO;
     326             :         int r;
     327             : 
     328           2 :         r = unlink(path);
     329           2 :         if (r < 0)
     330           1 :                 return -errno;
     331             : 
     332           1 :         return 0;
     333             : }
     334             : 
     335          68 : int parse_boolean(const char *v) {
     336          68 :         assert(v);
     337             : 
     338          68 :         if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
     339          28 :                 return 1;
     340          40 :         else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
     341          32 :                 return 0;
     342             : 
     343           8 :         return -EINVAL;
     344             : }
     345             : 
     346         220 : int parse_pid(const char *s, pid_t* ret_pid) {
     347         220 :         unsigned long ul = 0;
     348             :         pid_t pid;
     349             :         int r;
     350             : 
     351         220 :         assert(s);
     352         220 :         assert(ret_pid);
     353             : 
     354         220 :         r = safe_atolu(s, &ul);
     355         220 :         if (r < 0)
     356          11 :                 return r;
     357             : 
     358         209 :         pid = (pid_t) ul;
     359             : 
     360         209 :         if ((unsigned long) pid != ul)
     361           0 :                 return -ERANGE;
     362             : 
     363         209 :         if (pid <= 0)
     364           2 :                 return -ERANGE;
     365             : 
     366         207 :         *ret_pid = pid;
     367         207 :         return 0;
     368             : }
     369             : 
     370         131 : int parse_uid(const char *s, uid_t* ret_uid) {
     371         131 :         unsigned long ul = 0;
     372             :         uid_t uid;
     373             :         int r;
     374             : 
     375         131 :         assert(s);
     376             : 
     377         131 :         r = safe_atolu(s, &ul);
     378         131 :         if (r < 0)
     379           4 :                 return r;
     380             : 
     381         127 :         uid = (uid_t) ul;
     382             : 
     383         127 :         if ((unsigned long) uid != ul)
     384           0 :                 return -ERANGE;
     385             : 
     386             :         /* Some libc APIs use UID_INVALID as special placeholder */
     387         127 :         if (uid == (uid_t) 0xFFFFFFFF)
     388           0 :                 return -ENXIO;
     389             : 
     390             :         /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
     391         127 :         if (uid == (uid_t) 0xFFFF)
     392           0 :                 return -ENXIO;
     393             : 
     394         127 :         if (ret_uid)
     395         114 :                 *ret_uid = uid;
     396             : 
     397         127 :         return 0;
     398             : }
     399             : 
     400         533 : int safe_atou(const char *s, unsigned *ret_u) {
     401         533 :         char *x = NULL;
     402             :         unsigned long l;
     403             : 
     404         533 :         assert(s);
     405         533 :         assert(ret_u);
     406             : 
     407         533 :         errno = 0;
     408         533 :         l = strtoul(s, &x, 0);
     409             : 
     410         533 :         if (!x || x == s || *x || errno)
     411          52 :                 return errno > 0 ? -errno : -EINVAL;
     412             : 
     413         481 :         if ((unsigned long) (unsigned) l != l)
     414           0 :                 return -ERANGE;
     415             : 
     416         481 :         *ret_u = (unsigned) l;
     417         481 :         return 0;
     418             : }
     419             : 
     420         256 : int safe_atoi(const char *s, int *ret_i) {
     421         256 :         char *x = NULL;
     422             :         long l;
     423             : 
     424         256 :         assert(s);
     425         256 :         assert(ret_i);
     426             : 
     427         256 :         errno = 0;
     428         256 :         l = strtol(s, &x, 0);
     429             : 
     430         256 :         if (!x || x == s || *x || errno)
     431          46 :                 return errno > 0 ? -errno : -EINVAL;
     432             : 
     433         210 :         if ((long) (int) l != l)
     434           0 :                 return -ERANGE;
     435             : 
     436         210 :         *ret_i = (int) l;
     437         210 :         return 0;
     438             : }
     439             : 
     440           8 : int safe_atou8(const char *s, uint8_t *ret) {
     441           8 :         char *x = NULL;
     442             :         unsigned long l;
     443             : 
     444           8 :         assert(s);
     445           8 :         assert(ret);
     446             : 
     447           8 :         errno = 0;
     448           8 :         l = strtoul(s, &x, 0);
     449             : 
     450           8 :         if (!x || x == s || *x || errno)
     451           0 :                 return errno > 0 ? -errno : -EINVAL;
     452             : 
     453           8 :         if ((unsigned long) (uint8_t) l != l)
     454           0 :                 return -ERANGE;
     455             : 
     456           8 :         *ret = (uint8_t) l;
     457           8 :         return 0;
     458             : }
     459             : 
     460           0 : int safe_atou16(const char *s, uint16_t *ret) {
     461           0 :         char *x = NULL;
     462             :         unsigned long l;
     463             : 
     464           0 :         assert(s);
     465           0 :         assert(ret);
     466             : 
     467           0 :         errno = 0;
     468           0 :         l = strtoul(s, &x, 0);
     469             : 
     470           0 :         if (!x || x == s || *x || errno)
     471           0 :                 return errno > 0 ? -errno : -EINVAL;
     472             : 
     473           0 :         if ((unsigned long) (uint16_t) l != l)
     474           0 :                 return -ERANGE;
     475             : 
     476           0 :         *ret = (uint16_t) l;
     477           0 :         return 0;
     478             : }
     479             : 
     480           0 : int safe_atoi16(const char *s, int16_t *ret) {
     481           0 :         char *x = NULL;
     482             :         long l;
     483             : 
     484           0 :         assert(s);
     485           0 :         assert(ret);
     486             : 
     487           0 :         errno = 0;
     488           0 :         l = strtol(s, &x, 0);
     489             : 
     490           0 :         if (!x || x == s || *x || errno)
     491           0 :                 return errno > 0 ? -errno : -EINVAL;
     492             : 
     493           0 :         if ((long) (int16_t) l != l)
     494           0 :                 return -ERANGE;
     495             : 
     496           0 :         *ret = (int16_t) l;
     497           0 :         return 0;
     498             : }
     499             : 
     500       16072 : int safe_atollu(const char *s, long long unsigned *ret_llu) {
     501       16072 :         char *x = NULL;
     502             :         unsigned long long l;
     503             : 
     504       16072 :         assert(s);
     505       16072 :         assert(ret_llu);
     506             : 
     507       16072 :         errno = 0;
     508       16072 :         l = strtoull(s, &x, 0);
     509             : 
     510       16072 :         if (!x || x == s || *x || errno)
     511          15 :                 return errno ? -errno : -EINVAL;
     512             : 
     513       16057 :         *ret_llu = l;
     514       16057 :         return 0;
     515             : }
     516             : 
     517           2 : int safe_atolli(const char *s, long long int *ret_lli) {
     518           2 :         char *x = NULL;
     519             :         long long l;
     520             : 
     521           2 :         assert(s);
     522           2 :         assert(ret_lli);
     523             : 
     524           2 :         errno = 0;
     525           2 :         l = strtoll(s, &x, 0);
     526             : 
     527           2 :         if (!x || x == s || *x || errno)
     528           1 :                 return errno ? -errno : -EINVAL;
     529             : 
     530           1 :         *ret_lli = l;
     531           1 :         return 0;
     532             : }
     533             : 
     534           7 : int safe_atod(const char *s, double *ret_d) {
     535           7 :         char *x = NULL;
     536           7 :         double d = 0;
     537             :         locale_t loc;
     538             : 
     539           7 :         assert(s);
     540           7 :         assert(ret_d);
     541             : 
     542           7 :         loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
     543           7 :         if (loc == (locale_t) 0)
     544           0 :                 return -errno;
     545             : 
     546           7 :         errno = 0;
     547           7 :         d = strtod_l(s, &x, loc);
     548             : 
     549           7 :         if (!x || x == s || *x || errno) {
     550           4 :                 freelocale(loc);
     551           4 :                 return errno ? -errno : -EINVAL;
     552             :         }
     553             : 
     554           3 :         freelocale(loc);
     555           3 :         *ret_d = (double) d;
     556           3 :         return 0;
     557             : }
     558             : 
     559         568 : static size_t strcspn_escaped(const char *s, const char *reject) {
     560         568 :         bool escaped = false;
     561             :         int n;
     562             : 
     563       10405 :         for (n=0; s[n]; n++) {
     564       10018 :                 if (escaped)
     565           0 :                         escaped = false;
     566       10018 :                 else if (s[n] == '\\')
     567           1 :                         escaped = true;
     568       10017 :                 else if (strchr(reject, s[n]))
     569         181 :                         break;
     570             :         }
     571             : 
     572             :         /* if s ends in \, return index of previous char */
     573         568 :         return n - escaped;
     574             : }
     575             : 
     576             : /* Split a string into words. */
     577       28540 : const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
     578             :         const char *current;
     579             : 
     580       28540 :         current = *state;
     581             : 
     582       28540 :         if (!*current) {
     583       11675 :                 assert(**state == '\0');
     584       11675 :                 return NULL;
     585             :         }
     586             : 
     587       16865 :         current += strspn(current, separator);
     588       16865 :         if (!*current) {
     589           1 :                 *state = current;
     590           1 :                 return NULL;
     591             :         }
     592             : 
     593       16871 :         if (quoted && strchr("\'\"", *current)) {
     594           8 :                 char quotechars[2] = {*current, '\0'};
     595             : 
     596           8 :                 *l = strcspn_escaped(current + 1, quotechars);
     597          15 :                 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
     598          13 :                     (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
     599             :                         /* right quote missing or garbage at the end */
     600           1 :                         *state = current;
     601           1 :                         return NULL;
     602             :                 }
     603           7 :                 *state = current++ + *l + 2;
     604       16856 :         } else if (quoted) {
     605         560 :                 *l = strcspn_escaped(current, separator);
     606         560 :                 if (current[*l] && !strchr(separator, current[*l])) {
     607             :                         /* unfinished escape */
     608           1 :                         *state = current;
     609           1 :                         return NULL;
     610             :                 }
     611         559 :                 *state = current + *l;
     612             :         } else {
     613       16296 :                 *l = strcspn(current, separator);
     614       16296 :                 *state = current + *l;
     615             :         }
     616             : 
     617       16862 :         return current;
     618             : }
     619             : 
     620           2 : int fchmod_umask(int fd, mode_t m) {
     621             :         mode_t u;
     622             :         int r;
     623             : 
     624           2 :         u = umask(0777);
     625           2 :         r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
     626           2 :         umask(u);
     627             : 
     628           2 :         return r;
     629             : }
     630             : 
     631       20251 : char *truncate_nl(char *s) {
     632       20251 :         assert(s);
     633             : 
     634       20251 :         s[strcspn(s, NEWLINE)] = 0;
     635       20251 :         return s;
     636             : }
     637             : 
     638        1550 : char *strnappend(const char *s, const char *suffix, size_t b) {
     639             :         size_t a;
     640             :         char *r;
     641             : 
     642        1550 :         if (!s && !suffix)
     643           1 :                 return strdup("");
     644             : 
     645        1549 :         if (!s)
     646           8 :                 return strndup(suffix, b);
     647             : 
     648        1541 :         if (!suffix)
     649           1 :                 return strdup(s);
     650             : 
     651        1540 :         assert(s);
     652        1540 :         assert(suffix);
     653             : 
     654        1540 :         a = strlen(s);
     655        1540 :         if (b > ((size_t) -1) - a)
     656           0 :                 return NULL;
     657             : 
     658        1540 :         r = new(char, a+b+1);
     659        1540 :         if (!r)
     660           0 :                 return NULL;
     661             : 
     662        1540 :         memcpy(r, s, a);
     663        1540 :         memcpy(r+a, suffix, b);
     664        1540 :         r[a+b] = 0;
     665             : 
     666        1540 :         return r;
     667             : }
     668             : 
     669        1538 : char *strappend(const char *s, const char *suffix) {
     670        1538 :         return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
     671             : }
     672             : 
     673        3872 : int readlinkat_malloc(int fd, const char *p, char **ret) {
     674        3872 :         size_t l = 100;
     675             :         int r;
     676             : 
     677        3872 :         assert(p);
     678        3872 :         assert(ret);
     679             : 
     680             :         for (;;) {
     681             :                 char *c;
     682             :                 ssize_t n;
     683             : 
     684        3892 :                 c = new(char, l);
     685        3892 :                 if (!c)
     686           0 :                         return -ENOMEM;
     687             : 
     688        3892 :                 n = readlinkat(fd, p, c, l-1);
     689        3892 :                 if (n < 0) {
     690         376 :                         r = -errno;
     691         376 :                         free(c);
     692         376 :                         return r;
     693             :                 }
     694             : 
     695        3516 :                 if ((size_t) n < l-1) {
     696        3496 :                         c[n] = 0;
     697        3496 :                         *ret = c;
     698        3496 :                         return 0;
     699             :                 }
     700             : 
     701          20 :                 free(c);
     702          20 :                 l *= 2;
     703          20 :         }
     704             : }
     705             : 
     706        3870 : int readlink_malloc(const char *p, char **ret) {
     707        3870 :         return readlinkat_malloc(AT_FDCWD, p, ret);
     708             : }
     709             : 
     710         435 : int readlink_value(const char *p, char **ret) {
     711         870 :         _cleanup_free_ char *link = NULL;
     712             :         char *value;
     713             :         int r;
     714             : 
     715         435 :         r = readlink_malloc(p, &link);
     716         435 :         if (r < 0)
     717          40 :                 return r;
     718             : 
     719         395 :         value = basename(link);
     720         395 :         if (!value)
     721           0 :                 return -ENOENT;
     722             : 
     723         395 :         value = strdup(value);
     724         395 :         if (!value)
     725           0 :                 return -ENOMEM;
     726             : 
     727         395 :         *ret = value;
     728             : 
     729         395 :         return 0;
     730             : }
     731             : 
     732        3329 : int readlink_and_make_absolute(const char *p, char **r) {
     733        6658 :         _cleanup_free_ char *target = NULL;
     734             :         char *k;
     735             :         int j;
     736             : 
     737        3329 :         assert(p);
     738        3329 :         assert(r);
     739             : 
     740        3329 :         j = readlink_malloc(p, &target);
     741        3329 :         if (j < 0)
     742         233 :                 return j;
     743             : 
     744        3096 :         k = file_in_same_dir(p, target);
     745        3096 :         if (!k)
     746           0 :                 return -ENOMEM;
     747             : 
     748        3096 :         *r = k;
     749        3096 :         return 0;
     750             : }
     751             : 
     752        3261 : int readlink_and_canonicalize(const char *p, char **r) {
     753             :         char *t, *s;
     754             :         int j;
     755             : 
     756        3261 :         assert(p);
     757        3261 :         assert(r);
     758             : 
     759        3261 :         j = readlink_and_make_absolute(p, &t);
     760        3261 :         if (j < 0)
     761         233 :                 return j;
     762             : 
     763        3028 :         s = canonicalize_file_name(t);
     764        3028 :         if (s) {
     765        3028 :                 free(t);
     766        3028 :                 *r = s;
     767             :         } else
     768           0 :                 *r = t;
     769             : 
     770        3028 :         path_kill_slashes(*r);
     771             : 
     772        3028 :         return 0;
     773             : }
     774             : 
     775       11217 : char *strstrip(char *s) {
     776             :         char *e;
     777             : 
     778             :         /* Drops trailing whitespace. Modifies the string in
     779             :          * place. Returns pointer to first non-space character */
     780             : 
     781       11217 :         s += strspn(s, WHITESPACE);
     782             : 
     783       11938 :         for (e = strchr(s, 0); e > s; e --)
     784       11262 :                 if (!strchr(WHITESPACE, e[-1]))
     785       10541 :                         break;
     786             : 
     787       11217 :         *e = 0;
     788             : 
     789       11217 :         return s;
     790             : }
     791             : 
     792           1 : char *delete_chars(char *s, const char *bad) {
     793             :         char *f, *t;
     794             : 
     795             :         /* Drops all whitespace, regardless where in the string */
     796             : 
     797          23 :         for (f = s, t = s; *f; f++) {
     798          22 :                 if (strchr(bad, *f))
     799           7 :                         continue;
     800             : 
     801          15 :                 *(t++) = *f;
     802             :         }
     803             : 
     804           1 :         *t = 0;
     805             : 
     806           1 :         return s;
     807             : }
     808             : 
     809        3101 : char *file_in_same_dir(const char *path, const char *filename) {
     810             :         char *e, *ret;
     811             :         size_t k;
     812             : 
     813        3101 :         assert(path);
     814        3101 :         assert(filename);
     815             : 
     816             :         /* This removes the last component of path and appends
     817             :          * filename, unless the latter is absolute anyway or the
     818             :          * former isn't */
     819             : 
     820        3101 :         if (path_is_absolute(filename))
     821        2825 :                 return strdup(filename);
     822             : 
     823         276 :         e = strrchr(path, '/');
     824         276 :         if (!e)
     825           1 :                 return strdup(filename);
     826             : 
     827         275 :         k = strlen(filename);
     828         275 :         ret = new(char, (e + 1 - path) + k + 1);
     829         275 :         if (!ret)
     830           0 :                 return NULL;
     831             : 
     832         275 :         memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
     833         275 :         return ret;
     834             : }
     835             : 
     836           0 : int rmdir_parents(const char *path, const char *stop) {
     837             :         size_t l;
     838           0 :         int r = 0;
     839             : 
     840           0 :         assert(path);
     841           0 :         assert(stop);
     842             : 
     843           0 :         l = strlen(path);
     844             : 
     845             :         /* Skip trailing slashes */
     846           0 :         while (l > 0 && path[l-1] == '/')
     847           0 :                 l--;
     848             : 
     849           0 :         while (l > 0) {
     850             :                 char *t;
     851             : 
     852             :                 /* Skip last component */
     853           0 :                 while (l > 0 && path[l-1] != '/')
     854           0 :                         l--;
     855             : 
     856             :                 /* Skip trailing slashes */
     857           0 :                 while (l > 0 && path[l-1] == '/')
     858           0 :                         l--;
     859             : 
     860           0 :                 if (l <= 0)
     861           0 :                         break;
     862             : 
     863           0 :                 if (!(t = strndup(path, l)))
     864           0 :                         return -ENOMEM;
     865             : 
     866           0 :                 if (path_startswith(stop, t)) {
     867           0 :                         free(t);
     868           0 :                         return 0;
     869             :                 }
     870             : 
     871           0 :                 r = rmdir(t);
     872           0 :                 free(t);
     873             : 
     874           0 :                 if (r < 0)
     875           0 :                         if (errno != ENOENT)
     876           0 :                                 return -errno;
     877             :         }
     878             : 
     879           0 :         return 0;
     880             : }
     881             : 
     882       40835 : char hexchar(int x) {
     883             :         static const char table[16] = "0123456789abcdef";
     884             : 
     885       40835 :         return table[x & 15];
     886             : }
     887             : 
     888       37637 : int unhexchar(char c) {
     889             : 
     890       37637 :         if (c >= '0' && c <= '9')
     891       23801 :                 return c - '0';
     892             : 
     893       13836 :         if (c >= 'a' && c <= 'f')
     894       13399 :                 return c - 'a' + 10;
     895             : 
     896         437 :         if (c >= 'A' && c <= 'F')
     897           7 :                 return c - 'A' + 10;
     898             : 
     899         430 :         return -EINVAL;
     900             : }
     901             : 
     902          12 : char *hexmem(const void *p, size_t l) {
     903             :         char *r, *z;
     904             :         const uint8_t *x;
     905             : 
     906          12 :         z = r = malloc(l * 2 + 1);
     907          12 :         if (!r)
     908           0 :                 return NULL;
     909             : 
     910         517 :         for (x = p; x < (const uint8_t*) p + l; x++) {
     911         505 :                 *(z++) = hexchar(*x >> 4);
     912         505 :                 *(z++) = hexchar(*x & 15);
     913             :         }
     914             : 
     915          12 :         *z = 0;
     916          12 :         return r;
     917             : }
     918             : 
     919          11 : int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
     920          22 :         _cleanup_free_ uint8_t *r = NULL;
     921             :         uint8_t *z;
     922             :         const char *x;
     923             : 
     924          11 :         assert(mem);
     925          11 :         assert(len);
     926          11 :         assert(p);
     927             : 
     928          11 :         z = r = malloc((l + 1) / 2 + 1);
     929          11 :         if (!r)
     930           0 :                 return -ENOMEM;
     931             : 
     932          61 :         for (x = p; x < p + l; x += 2) {
     933             :                 int a, b;
     934             : 
     935          52 :                 a = unhexchar(x[0]);
     936          52 :                 if (a < 0)
     937           0 :                         return a;
     938          52 :                 else if (x+1 < p + l) {
     939          51 :                         b = unhexchar(x[1]);
     940          51 :                         if (b < 0)
     941           2 :                                 return b;
     942             :                 } else
     943           1 :                         b = 0;
     944             : 
     945          50 :                 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
     946             :         }
     947             : 
     948           9 :         *z = 0;
     949             : 
     950           9 :         *mem = r;
     951           9 :         r = NULL;
     952           9 :         *len = (l + 1) / 2;
     953             : 
     954           9 :         return 0;
     955             : }
     956             : 
     957             : /* https://tools.ietf.org/html/rfc4648#section-6
     958             :  * Notice that base32hex differs from base32 in the alphabet it uses.
     959             :  * The distinction is that the base32hex representation preserves the
     960             :  * order of the underlying data when compared as bytestrings, this is
     961             :  * useful when representing NSEC3 hashes, as one can then verify the
     962             :  * order of hashes directly from their representation. */
     963          76 : char base32hexchar(int x) {
     964             :         static const char table[32] = "0123456789"
     965             :                                       "ABCDEFGHIJKLMNOPQRSTUV";
     966             : 
     967          76 :         return table[x & 31];
     968             : }
     969             : 
     970         132 : int unbase32hexchar(char c) {
     971             :         unsigned offset;
     972             : 
     973         132 :         if (c >= '0' && c <= '9')
     974          10 :                 return c - '0';
     975             : 
     976         122 :         offset = '9' - '0' + 1;
     977             : 
     978         122 :         if (c >= 'A' && c <= 'V')
     979         119 :                 return c - 'A' + offset;
     980             : 
     981           3 :         return -EINVAL;
     982             : }
     983             : 
     984          14 : char *base32hexmem(const void *p, size_t l, bool padding) {
     985             :         char *r, *z;
     986             :         const uint8_t *x;
     987             :         size_t len;
     988             : 
     989          14 :         if (padding)
     990             :                 /* five input bytes makes eight output bytes, padding is added so we must round up */
     991           7 :                 len = 8 * (l + 4) / 5;
     992             :         else {
     993             :                 /* same, but round down as there is no padding */
     994           7 :                 len = 8 * l / 5;
     995             : 
     996           7 :                 switch (l % 5) {
     997             :                 case 4:
     998           1 :                         len += 7;
     999           1 :                         break;
    1000             :                 case 3:
    1001           1 :                         len += 5;
    1002           1 :                         break;
    1003             :                 case 2:
    1004           1 :                         len += 4;
    1005           1 :                         break;
    1006             :                 case 1:
    1007           2 :                         len += 2;
    1008           2 :                         break;
    1009             :                 }
    1010             :         }
    1011             : 
    1012          14 :         z = r = malloc(len + 1);
    1013          14 :         if (!r)
    1014           0 :                 return NULL;
    1015             : 
    1016          18 :         for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
    1017             :                 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
    1018             :                    x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
    1019           4 :                 *(z++) = base32hexchar(x[0] >> 3);                    /* 000XXXXX */
    1020           4 :                 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6);  /* 000XXXYY */
    1021           4 :                 *(z++) = base32hexchar((x[1] & 63) >> 1);             /* 000YYYYY */
    1022           4 :                 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4);  /* 000YZZZZ */
    1023           4 :                 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
    1024           4 :                 *(z++) = base32hexchar((x[3] & 127) >> 2);            /* 000QQQQQ */
    1025           4 :                 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5);  /* 000QQWWW */
    1026           4 :                 *(z++) = base32hexchar((x[4] & 31));                  /* 000WWWWW */
    1027             :         }
    1028             : 
    1029          14 :         switch (l % 5) {
    1030             :         case 4:
    1031           2 :                 *(z++) = base32hexchar(x[0] >> 3);                    /* 000XXXXX */
    1032           2 :                 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6);  /* 000XXXYY */
    1033           2 :                 *(z++) = base32hexchar((x[1] & 63) >> 1);             /* 000YYYYY */
    1034           2 :                 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4);   /* 000YZZZZ */
    1035           2 :                 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
    1036           2 :                 *(z++) = base32hexchar((x[3] & 127) >> 2);            /* 000QQQQQ */
    1037           2 :                 *(z++) = base32hexchar((x[3] & 3) << 3);              /* 000QQ000 */
    1038           2 :                 if (padding)
    1039           1 :                         *(z++) = '=';
    1040             : 
    1041           2 :                 break;
    1042             : 
    1043             :         case 3:
    1044           2 :                 *(z++) = base32hexchar(x[0] >> 3);                   /* 000XXXXX */
    1045           2 :                 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
    1046           2 :                 *(z++) = base32hexchar((x[1] & 63) >> 1);            /* 000YYYYY */
    1047           2 :                 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
    1048           2 :                 *(z++) = base32hexchar((x[2] & 15) << 1);            /* 000ZZZZ0 */
    1049           2 :                 if (padding) {
    1050           1 :                         *(z++) = '=';
    1051           1 :                         *(z++) = '=';
    1052           1 :                         *(z++) = '=';
    1053             :                 }
    1054             : 
    1055           2 :                 break;
    1056             : 
    1057             :         case 2:
    1058           2 :                 *(z++) = base32hexchar(x[0] >> 3);                   /* 000XXXXX */
    1059           2 :                 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
    1060           2 :                 *(z++) = base32hexchar((x[1] & 63) >> 1);            /* 000YYYYY */
    1061           2 :                 *(z++) = base32hexchar((x[1] & 1) << 4);             /* 000Y0000 */
    1062           2 :                 if (padding) {
    1063           1 :                         *(z++) = '=';
    1064           1 :                         *(z++) = '=';
    1065           1 :                         *(z++) = '=';
    1066           1 :                         *(z++) = '=';
    1067             :                 }
    1068             : 
    1069           2 :                 break;
    1070             : 
    1071             :         case 1:
    1072           4 :                 *(z++) = base32hexchar(x[0] >> 3);       /* 000XXXXX */
    1073           4 :                 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
    1074           4 :                 if (padding) {
    1075           2 :                         *(z++) = '=';
    1076           2 :                         *(z++) = '=';
    1077           2 :                         *(z++) = '=';
    1078           2 :                         *(z++) = '=';
    1079           2 :                         *(z++) = '=';
    1080           2 :                         *(z++) = '=';
    1081             :                 }
    1082             : 
    1083           4 :                 break;
    1084             :         }
    1085             : 
    1086          14 :         *z = 0;
    1087          14 :         return r;
    1088             : }
    1089             : 
    1090          32 : int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
    1091          64 :         _cleanup_free_ uint8_t *r = NULL;
    1092             :         int a, b, c, d, e, f, g, h;
    1093             :         uint8_t *z;
    1094             :         const char *x;
    1095             :         size_t len;
    1096          32 :         unsigned pad = 0;
    1097             : 
    1098          32 :         assert(p);
    1099             : 
    1100             :         /* padding ensures any base32hex input has input divisible by 8 */
    1101          32 :         if (padding && l % 8 != 0)
    1102           1 :                 return -EINVAL;
    1103             : 
    1104          31 :         if (padding) {
    1105             :                 /* strip the padding */
    1106          76 :                 while (l > 0 && p[l - 1] == '=' && pad < 7) {
    1107          48 :                         pad ++;
    1108          48 :                         l --;
    1109             :                 }
    1110             :         }
    1111             : 
    1112             :         /* a group of eight input bytes needs five output bytes, in case of
    1113             :            padding we need to add some extra bytes */
    1114          31 :         len = (l / 8) * 5;
    1115             : 
    1116          31 :         switch (l % 8) {
    1117             :         case 7:
    1118           4 :                 len += 4;
    1119           4 :                 break;
    1120             :         case 5:
    1121           4 :                 len += 3;
    1122           4 :                 break;
    1123             :         case 4:
    1124           4 :                 len += 2;
    1125           4 :                 break;
    1126             :         case 2:
    1127           6 :                 len += 1;
    1128           6 :                 break;
    1129             :         case 0:
    1130           6 :                 break;
    1131             :         default:
    1132           7 :                 return -EINVAL;
    1133             :         }
    1134             : 
    1135          24 :         z = r = malloc(len + 1);
    1136          24 :         if (!r)
    1137           0 :                 return -ENOMEM;
    1138             : 
    1139          29 :         for (x = p; x < p + (l / 8) * 8; x += 8) {
    1140             :                 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
    1141             :                    e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
    1142           7 :                 a = unbase32hexchar(x[0]);
    1143           7 :                 if (a < 0)
    1144           0 :                         return -EINVAL;
    1145             : 
    1146           7 :                 b = unbase32hexchar(x[1]);
    1147           7 :                 if (b < 0)
    1148           0 :                         return -EINVAL;
    1149             : 
    1150           7 :                 c = unbase32hexchar(x[2]);
    1151           7 :                 if (c < 0)
    1152           1 :                         return -EINVAL;
    1153             : 
    1154           6 :                 d = unbase32hexchar(x[3]);
    1155           6 :                 if (d < 0)
    1156           0 :                         return -EINVAL;
    1157             : 
    1158           6 :                 e = unbase32hexchar(x[4]);
    1159           6 :                 if (e < 0)
    1160           0 :                         return -EINVAL;
    1161             : 
    1162           6 :                 f = unbase32hexchar(x[5]);
    1163           6 :                 if (f < 0)
    1164           0 :                         return -EINVAL;
    1165             : 
    1166           6 :                 g = unbase32hexchar(x[6]);
    1167           6 :                 if (g < 0)
    1168           0 :                         return -EINVAL;
    1169             : 
    1170           6 :                 h = unbase32hexchar(x[7]);
    1171           6 :                 if (h < 0)
    1172           1 :                         return -EINVAL;
    1173             : 
    1174           5 :                 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
    1175           5 :                 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
    1176           5 :                 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1;                    /* WWWWSSSS */
    1177           5 :                 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
    1178           5 :                 *(z++) = (uint8_t) g << 5 | (uint8_t) h;                         /* VVVRRRRR */
    1179             :         }
    1180             : 
    1181          22 :         switch (l % 8) {
    1182             :         case 7:
    1183           4 :                 a = unbase32hexchar(x[0]);
    1184           4 :                 if (a < 0)
    1185           0 :                         return -EINVAL;
    1186             : 
    1187           4 :                 b = unbase32hexchar(x[1]);
    1188           4 :                 if (b < 0)
    1189           0 :                         return -EINVAL;
    1190             : 
    1191           4 :                 c = unbase32hexchar(x[2]);
    1192           4 :                 if (c < 0)
    1193           0 :                         return -EINVAL;
    1194             : 
    1195           4 :                 d = unbase32hexchar(x[3]);
    1196           4 :                 if (d < 0)
    1197           0 :                         return -EINVAL;
    1198             : 
    1199           4 :                 e = unbase32hexchar(x[4]);
    1200           4 :                 if (e < 0)
    1201           0 :                         return -EINVAL;
    1202             : 
    1203           4 :                 f = unbase32hexchar(x[5]);
    1204           4 :                 if (f < 0)
    1205           0 :                         return -EINVAL;
    1206             : 
    1207           4 :                 g = unbase32hexchar(x[6]);
    1208           4 :                 if (g < 0)
    1209           0 :                         return -EINVAL;
    1210             : 
    1211             :                 /* g == 000VV000 */
    1212           4 :                 if (g & 7)
    1213           2 :                         return -EINVAL;
    1214             : 
    1215           2 :                 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
    1216           2 :                 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
    1217           2 :                 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1;                    /* WWWWSSSS */
    1218           2 :                 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
    1219             : 
    1220           2 :                 break;
    1221             :         case 5:
    1222           4 :                 a = unbase32hexchar(x[0]);
    1223           4 :                 if (a < 0)
    1224           0 :                         return -EINVAL;
    1225             : 
    1226           4 :                 b = unbase32hexchar(x[1]);
    1227           4 :                 if (b < 0)
    1228           0 :                         return -EINVAL;
    1229             : 
    1230           4 :                 c = unbase32hexchar(x[2]);
    1231           4 :                 if (c < 0)
    1232           0 :                         return -EINVAL;
    1233             : 
    1234           4 :                 d = unbase32hexchar(x[3]);
    1235           4 :                 if (d < 0)
    1236           0 :                         return -EINVAL;
    1237             : 
    1238           4 :                 e = unbase32hexchar(x[4]);
    1239           4 :                 if (e < 0)
    1240           0 :                         return -EINVAL;
    1241             : 
    1242             :                 /* e == 000SSSS0 */
    1243           4 :                 if (e & 1)
    1244           2 :                         return -EINVAL;
    1245             : 
    1246           2 :                 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
    1247           2 :                 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
    1248           2 :                 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1;                    /* WWWWSSSS */
    1249             : 
    1250           2 :                 break;
    1251             :         case 4:
    1252           4 :                 a = unbase32hexchar(x[0]);
    1253           4 :                 if (a < 0)
    1254           0 :                         return -EINVAL;
    1255             : 
    1256           4 :                 b = unbase32hexchar(x[1]);
    1257           4 :                 if (b < 0)
    1258           0 :                         return -EINVAL;
    1259             : 
    1260           4 :                 c = unbase32hexchar(x[2]);
    1261           4 :                 if (c < 0)
    1262           0 :                         return -EINVAL;
    1263             : 
    1264           4 :                 d = unbase32hexchar(x[3]);
    1265           4 :                 if (d < 0)
    1266           0 :                         return -EINVAL;
    1267             : 
    1268             :                 /* d == 000W0000 */
    1269           4 :                 if (d & 15)
    1270           2 :                         return -EINVAL;
    1271             : 
    1272           2 :                 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2;                    /* XXXXXYYY */
    1273           2 :                 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
    1274             : 
    1275           2 :                 break;
    1276             :         case 2:
    1277           6 :                 a = unbase32hexchar(x[0]);
    1278           6 :                 if (a < 0)
    1279           0 :                         return -EINVAL;
    1280             : 
    1281           6 :                 b = unbase32hexchar(x[1]);
    1282           6 :                 if (b < 0)
    1283           0 :                         return -EINVAL;
    1284             : 
    1285             :                 /* b == 000YYY00 */
    1286           6 :                 if (b & 3)
    1287           2 :                         return -EINVAL;
    1288             : 
    1289           4 :                 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
    1290             : 
    1291           4 :                 break;
    1292             :         case 0:
    1293           4 :                 break;
    1294             :         default:
    1295           0 :                 return -EINVAL;
    1296             :         }
    1297             : 
    1298          14 :         *z = 0;
    1299             : 
    1300          14 :         *mem = r;
    1301          14 :         r = NULL;
    1302          14 :         *_len = len;
    1303             : 
    1304          14 :         return 0;
    1305             : }
    1306             : 
    1307             : /* https://tools.ietf.org/html/rfc4648#section-4 */
    1308          33 : char base64char(int x) {
    1309             :         static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    1310             :                                       "abcdefghijklmnopqrstuvwxyz"
    1311             :                                       "0123456789+/";
    1312          33 :         return table[x & 63];
    1313             : }
    1314             : 
    1315          39 : int unbase64char(char c) {
    1316             :         unsigned offset;
    1317             : 
    1318          39 :         if (c >= 'A' && c <= 'Z')
    1319          13 :                 return c - 'A';
    1320             : 
    1321          26 :         offset = 'Z' - 'A' + 1;
    1322             : 
    1323          26 :         if (c >= 'a' && c <= 'z')
    1324          16 :                 return c - 'a' + offset;
    1325             : 
    1326          10 :         offset += 'z' - 'a' + 1;
    1327             : 
    1328          10 :         if (c >= '0' && c <= '9')
    1329           7 :                 return c - '0' + offset;
    1330             : 
    1331           3 :         offset += '9' - '0' + 1;
    1332             : 
    1333           3 :         if (c == '+')
    1334           1 :                 return offset;
    1335             : 
    1336           2 :         offset ++;
    1337             : 
    1338           2 :         if (c == '/')
    1339           1 :                 return offset;
    1340             : 
    1341           1 :         return -EINVAL;
    1342             : }
    1343             : 
    1344           7 : char *base64mem(const void *p, size_t l) {
    1345             :         char *r, *z;
    1346             :         const uint8_t *x;
    1347             : 
    1348             :         /* three input bytes makes four output bytes, padding is added so we must round up */
    1349           7 :         z = r = malloc(4 * (l + 2) / 3 + 1);
    1350           7 :         if (!r)
    1351           0 :                 return NULL;
    1352             : 
    1353          12 :         for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
    1354             :                 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
    1355           5 :                 *(z++) = base64char(x[0] >> 2);                    /* 00XXXXXX */
    1356           5 :                 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4);  /* 00XXYYYY */
    1357           5 :                 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
    1358           5 :                 *(z++) = base64char(x[2] & 63);                    /* 00ZZZZZZ */
    1359             :         }
    1360             : 
    1361           7 :         switch (l % 3) {
    1362             :         case 2:
    1363           2 :                 *(z++) = base64char(x[0] >> 2);                   /* 00XXXXXX */
    1364           2 :                 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
    1365           2 :                 *(z++) = base64char((x[1] & 15) << 2);            /* 00YYYY00 */
    1366           2 :                 *(z++) = '=';
    1367             : 
    1368           2 :                 break;
    1369             :         case 1:
    1370           2 :                 *(z++) = base64char(x[0] >> 2);        /* 00XXXXXX */
    1371           2 :                 *(z++) = base64char((x[0] & 3) << 4);  /* 00XX0000 */
    1372           2 :                 *(z++) = '=';
    1373           2 :                 *(z++) = '=';
    1374             : 
    1375           2 :                 break;
    1376             :         }
    1377             : 
    1378           7 :         *z = 0;
    1379           7 :         return r;
    1380             : }
    1381             : 
    1382          11 : int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
    1383          22 :         _cleanup_free_ uint8_t *r = NULL;
    1384             :         int a, b, c, d;
    1385             :         uint8_t *z;
    1386             :         const char *x;
    1387             :         size_t len;
    1388             : 
    1389          11 :         assert(p);
    1390             : 
    1391             :         /* padding ensures any base63 input has input divisible by 4 */
    1392          11 :         if (l % 4 != 0)
    1393           4 :                 return -EINVAL;
    1394             : 
    1395             :         /* strip the padding */
    1396           7 :         if (l > 0 && p[l - 1] == '=')
    1397           4 :                 l --;
    1398           7 :         if (l > 0 && p[l - 1] == '=')
    1399           2 :                 l --;
    1400             : 
    1401             :         /* a group of four input bytes needs three output bytes, in case of
    1402             :            padding we need to add two or three extra bytes */
    1403           7 :         len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
    1404             : 
    1405           7 :         z = r = malloc(len + 1);
    1406           7 :         if (!r)
    1407           0 :                 return -ENOMEM;
    1408             : 
    1409          12 :         for (x = p; x < p + (l / 4) * 4; x += 4) {
    1410             :                 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
    1411           5 :                 a = unbase64char(x[0]);
    1412           5 :                 if (a < 0)
    1413           0 :                         return -EINVAL;
    1414             : 
    1415           5 :                 b = unbase64char(x[1]);
    1416           5 :                 if (b < 0)
    1417           0 :                         return -EINVAL;
    1418             : 
    1419           5 :                 c = unbase64char(x[2]);
    1420           5 :                 if (c < 0)
    1421           0 :                         return -EINVAL;
    1422             : 
    1423           5 :                 d = unbase64char(x[3]);
    1424           5 :                 if (d < 0)
    1425           0 :                         return -EINVAL;
    1426             : 
    1427           5 :                 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
    1428           5 :                 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
    1429           5 :                 *(z++) = (uint8_t) c << 6 | (uint8_t) d;      /* ZZWWWWWW */
    1430             :         }
    1431             : 
    1432           7 :         switch (l % 4) {
    1433             :         case 3:
    1434           2 :                 a = unbase64char(x[0]);
    1435           2 :                 if (a < 0)
    1436           0 :                         return -EINVAL;
    1437             : 
    1438           2 :                 b = unbase64char(x[1]);
    1439           2 :                 if (b < 0)
    1440           0 :                         return -EINVAL;
    1441             : 
    1442           2 :                 c = unbase64char(x[2]);
    1443           2 :                 if (c < 0)
    1444           0 :                         return -EINVAL;
    1445             : 
    1446             :                 /* c == 00ZZZZ00 */
    1447           2 :                 if (c & 3)
    1448           0 :                         return -EINVAL;
    1449             : 
    1450           2 :                 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
    1451           2 :                 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
    1452             : 
    1453           2 :                 break;
    1454             :         case 2:
    1455           2 :                 a = unbase64char(x[0]);
    1456           2 :                 if (a < 0)
    1457           0 :                         return -EINVAL;
    1458             : 
    1459           2 :                 b = unbase64char(x[1]);
    1460           2 :                 if (b < 0)
    1461           0 :                         return -EINVAL;
    1462             : 
    1463             :                 /* b == 00YY0000 */
    1464           2 :                 if (b & 15)
    1465           0 :                         return -EINVAL;
    1466             : 
    1467           2 :                 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
    1468             : 
    1469           2 :                 break;
    1470             :         case 0:
    1471             : 
    1472           3 :                 break;
    1473             :         default:
    1474           0 :                 return -EINVAL;
    1475             :         }
    1476             : 
    1477           7 :         *z = 0;
    1478             : 
    1479           7 :         *mem = r;
    1480           7 :         r = NULL;
    1481           7 :         *_len = len;
    1482             : 
    1483           7 :         return 0;
    1484             : }
    1485             : 
    1486          14 : char octchar(int x) {
    1487          14 :         return '0' + (x & 7);
    1488             : }
    1489             : 
    1490          38 : int unoctchar(char c) {
    1491             : 
    1492          38 :         if (c >= '0' && c <= '7')
    1493          38 :                 return c - '0';
    1494             : 
    1495           0 :         return -EINVAL;
    1496             : }
    1497             : 
    1498           2 : char decchar(int x) {
    1499           2 :         return '0' + (x % 10);
    1500             : }
    1501             : 
    1502         574 : int undecchar(char c) {
    1503             : 
    1504         574 :         if (c >= '0' && c <= '9')
    1505         574 :                 return c - '0';
    1506             : 
    1507           0 :         return -EINVAL;
    1508             : }
    1509             : 
    1510          15 : char *cescape(const char *s) {
    1511             :         char *r, *t;
    1512             :         const char *f;
    1513             : 
    1514          15 :         assert(s);
    1515             : 
    1516             :         /* Does C style string escaping. May be reversed with
    1517             :          * cunescape(). */
    1518             : 
    1519          15 :         r = new(char, strlen(s)*4 + 1);
    1520          15 :         if (!r)
    1521           0 :                 return NULL;
    1522             : 
    1523          64 :         for (f = s, t = r; *f; f++)
    1524          49 :                 t += cescape_char(*f, t);
    1525             : 
    1526          15 :         *t = 0;
    1527             : 
    1528          15 :         return r;
    1529             : }
    1530             : 
    1531          91 : static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
    1532          91 :         int r = 1;
    1533             : 
    1534          91 :         assert(p);
    1535          91 :         assert(*p);
    1536          91 :         assert(ret);
    1537             : 
    1538             :         /* Unescapes C style. Returns the unescaped character in ret,
    1539             :          * unless we encountered a \u sequence in which case the full
    1540             :          * unicode character is returned in ret_unicode, instead. */
    1541             : 
    1542          91 :         if (length != (size_t) -1 && length < 1)
    1543           0 :                 return -EINVAL;
    1544             : 
    1545          91 :         switch (p[0]) {
    1546             : 
    1547             :         case 'a':
    1548           3 :                 *ret = '\a';
    1549           3 :                 break;
    1550             :         case 'b':
    1551           7 :                 *ret = '\b';
    1552           7 :                 break;
    1553             :         case 'f':
    1554           3 :                 *ret = '\f';
    1555           3 :                 break;
    1556             :         case 'n':
    1557           3 :                 *ret = '\n';
    1558           3 :                 break;
    1559             :         case 'r':
    1560           3 :                 *ret = '\r';
    1561           3 :                 break;
    1562             :         case 't':
    1563           3 :                 *ret = '\t';
    1564           3 :                 break;
    1565             :         case 'v':
    1566           3 :                 *ret = '\v';
    1567           3 :                 break;
    1568             :         case '\\':
    1569           3 :                 *ret = '\\';
    1570           3 :                 break;
    1571             :         case '"':
    1572           3 :                 *ret = '"';
    1573           3 :                 break;
    1574             :         case '\'':
    1575           1 :                 *ret = '\'';
    1576           1 :                 break;
    1577             : 
    1578             :         case 's':
    1579             :                 /* This is an extension of the XDG syntax files */
    1580           3 :                 *ret = ' ';
    1581           3 :                 break;
    1582             : 
    1583             :         case 'x': {
    1584             :                 /* hexadecimal encoding */
    1585             :                 int a, b;
    1586             : 
    1587          11 :                 if (length != (size_t) -1 && length < 3)
    1588           4 :                         return -EINVAL;
    1589             : 
    1590           7 :                 a = unhexchar(p[1]);
    1591           7 :                 if (a < 0)
    1592           2 :                         return -EINVAL;
    1593             : 
    1594           5 :                 b = unhexchar(p[2]);
    1595           5 :                 if (b < 0)
    1596           0 :                         return -EINVAL;
    1597             : 
    1598             :                 /* Don't allow NUL bytes */
    1599           5 :                 if (a == 0 && b == 0)
    1600           1 :                         return -EINVAL;
    1601             : 
    1602           4 :                 *ret = (char) ((a << 4U) | b);
    1603           4 :                 r = 3;
    1604           4 :                 break;
    1605             :         }
    1606             : 
    1607             :         case 'u': {
    1608             :                 /* C++11 style 16bit unicode */
    1609             : 
    1610             :                 int a[4];
    1611             :                 unsigned i;
    1612             :                 uint32_t c;
    1613             : 
    1614           5 :                 if (length != (size_t) -1 && length < 5)
    1615           1 :                         return -EINVAL;
    1616             : 
    1617          25 :                 for (i = 0; i < 4; i++) {
    1618          20 :                         a[i] = unhexchar(p[1 + i]);
    1619          20 :                         if (a[i] < 0)
    1620           0 :                                 return a[i];
    1621             :                 }
    1622             : 
    1623           5 :                 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
    1624             : 
    1625             :                 /* Don't allow 0 chars */
    1626           5 :                 if (c == 0)
    1627           1 :                         return -EINVAL;
    1628             : 
    1629           4 :                 if (c < 128)
    1630           0 :                         *ret = c;
    1631             :                 else {
    1632           4 :                         if (!ret_unicode)
    1633           0 :                                 return -EINVAL;
    1634             : 
    1635           4 :                         *ret = 0;
    1636           4 :                         *ret_unicode = c;
    1637             :                 }
    1638             : 
    1639           4 :                 r = 5;
    1640           4 :                 break;
    1641             :         }
    1642             : 
    1643             :         case 'U': {
    1644             :                 /* C++11 style 32bit unicode */
    1645             : 
    1646             :                 int a[8];
    1647             :                 unsigned i;
    1648             :                 uint32_t c;
    1649             : 
    1650           4 :                 if (length != (size_t) -1 && length < 9)
    1651           0 :                         return -EINVAL;
    1652             : 
    1653          36 :                 for (i = 0; i < 8; i++) {
    1654          32 :                         a[i] = unhexchar(p[1 + i]);
    1655          32 :                         if (a[i] < 0)
    1656           0 :                                 return a[i];
    1657             :                 }
    1658             : 
    1659          12 :                 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
    1660           8 :                     ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] <<  8U) | ((uint32_t) a[6] <<  4U) |  (uint32_t) a[7];
    1661             : 
    1662             :                 /* Don't allow 0 chars */
    1663           4 :                 if (c == 0)
    1664           0 :                         return -EINVAL;
    1665             : 
    1666             :                 /* Don't allow invalid code points */
    1667           4 :                 if (!unichar_is_valid(c))
    1668           0 :                         return -EINVAL;
    1669             : 
    1670           4 :                 if (c < 128)
    1671           1 :                         *ret = c;
    1672             :                 else {
    1673           3 :                         if (!ret_unicode)
    1674           0 :                                 return -EINVAL;
    1675             : 
    1676           3 :                         *ret = 0;
    1677           3 :                         *ret_unicode = c;
    1678             :                 }
    1679             : 
    1680           4 :                 r = 9;
    1681           4 :                 break;
    1682             :         }
    1683             : 
    1684             :         case '0':
    1685             :         case '1':
    1686             :         case '2':
    1687             :         case '3':
    1688             :         case '4':
    1689             :         case '5':
    1690             :         case '6':
    1691             :         case '7': {
    1692             :                 /* octal encoding */
    1693             :                 int a, b, c;
    1694             :                 uint32_t m;
    1695             : 
    1696          16 :                 if (length != (size_t) -1 && length < 3)
    1697           4 :                         return -EINVAL;
    1698             : 
    1699          12 :                 a = unoctchar(p[0]);
    1700          12 :                 if (a < 0)
    1701           0 :                         return -EINVAL;
    1702             : 
    1703          12 :                 b = unoctchar(p[1]);
    1704          12 :                 if (b < 0)
    1705           0 :                         return -EINVAL;
    1706             : 
    1707          12 :                 c = unoctchar(p[2]);
    1708          12 :                 if (c < 0)
    1709           0 :                         return -EINVAL;
    1710             : 
    1711             :                 /* don't allow NUL bytes */
    1712          12 :                 if (a == 0 && b == 0 && c == 0)
    1713           2 :                         return -EINVAL;
    1714             : 
    1715             :                 /* Don't allow bytes above 255 */
    1716          10 :                 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
    1717          10 :                 if (m > 255)
    1718           0 :                         return -EINVAL;
    1719             : 
    1720          10 :                 *ret = m;
    1721          10 :                 r = 3;
    1722          10 :                 break;
    1723             :         }
    1724             : 
    1725             :         default:
    1726          20 :                 return -EINVAL;
    1727             :         }
    1728             : 
    1729          57 :         return r;
    1730             : }
    1731             : 
    1732         595 : int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
    1733             :         char *r, *t;
    1734             :         const char *f;
    1735             :         size_t pl;
    1736             : 
    1737         595 :         assert(s);
    1738         595 :         assert(ret);
    1739             : 
    1740             :         /* Undoes C style string escaping, and optionally prefixes it. */
    1741             : 
    1742         595 :         pl = prefix ? strlen(prefix) : 0;
    1743             : 
    1744         595 :         r = new(char, pl+length+1);
    1745         595 :         if (!r)
    1746           0 :                 return -ENOMEM;
    1747             : 
    1748         595 :         if (prefix)
    1749           0 :                 memcpy(r, prefix, pl);
    1750             : 
    1751        6721 :         for (f = s, t = r + pl; f < s + length; f++) {
    1752             :                 size_t remaining;
    1753             :                 uint32_t u;
    1754             :                 char c;
    1755             :                 int k;
    1756             : 
    1757        6133 :                 remaining = s + length - f;
    1758        6133 :                 assert(remaining > 0);
    1759             : 
    1760        6133 :                 if (*f != '\\') {
    1761             :                         /* A literal literal, copy verbatim */
    1762        6088 :                         *(t++) = *f;
    1763       12183 :                         continue;
    1764             :                 }
    1765             : 
    1766          45 :                 if (remaining == 1) {
    1767           2 :                         if (flags & UNESCAPE_RELAX) {
    1768             :                                 /* A trailing backslash, copy verbatim */
    1769           1 :                                 *(t++) = *f;
    1770           1 :                                 continue;
    1771             :                         }
    1772             : 
    1773           1 :                         free(r);
    1774           8 :                         return -EINVAL;
    1775             :                 }
    1776             : 
    1777          43 :                 k = cunescape_one(f + 1, remaining - 1, &c, &u);
    1778          43 :                 if (k < 0) {
    1779          12 :                         if (flags & UNESCAPE_RELAX) {
    1780             :                                 /* Invalid escape code, let's take it literal then */
    1781           6 :                                 *(t++) = '\\';
    1782           6 :                                 continue;
    1783             :                         }
    1784             : 
    1785           6 :                         free(r);
    1786           6 :                         return k;
    1787             :                 }
    1788             : 
    1789          31 :                 if (c != 0)
    1790             :                         /* Non-Unicode? Let's encode this directly */
    1791          28 :                         *(t++) = c;
    1792             :                 else
    1793             :                         /* Unicode? Then let's encode this in UTF-8 */
    1794           3 :                         t += utf8_encode_unichar(t, u);
    1795             : 
    1796          31 :                 f += k;
    1797             :         }
    1798             : 
    1799         588 :         *t = 0;
    1800             : 
    1801         588 :         *ret = r;
    1802         588 :         return t - r;
    1803             : }
    1804             : 
    1805         595 : int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
    1806         595 :         return cunescape_length_with_prefix(s, length, NULL, flags, ret);
    1807             : }
    1808             : 
    1809         595 : int cunescape(const char *s, UnescapeFlags flags, char **ret) {
    1810         595 :         return cunescape_length(s, strlen(s), flags, ret);
    1811             : }
    1812             : 
    1813           0 : char *xescape(const char *s, const char *bad) {
    1814             :         char *r, *t;
    1815             :         const char *f;
    1816             : 
    1817             :         /* Escapes all chars in bad, in addition to \ and all special
    1818             :          * chars, in \xFF style escaping. May be reversed with
    1819             :          * cunescape(). */
    1820             : 
    1821           0 :         r = new(char, strlen(s) * 4 + 1);
    1822           0 :         if (!r)
    1823           0 :                 return NULL;
    1824             : 
    1825           0 :         for (f = s, t = r; *f; f++) {
    1826             : 
    1827           0 :                 if ((*f < ' ') || (*f >= 127) ||
    1828           0 :                     (*f == '\\') || strchr(bad, *f)) {
    1829           0 :                         *(t++) = '\\';
    1830           0 :                         *(t++) = 'x';
    1831           0 :                         *(t++) = hexchar(*f >> 4);
    1832           0 :                         *(t++) = hexchar(*f);
    1833             :                 } else
    1834           0 :                         *(t++) = *f;
    1835             :         }
    1836             : 
    1837           0 :         *t = 0;
    1838             : 
    1839           0 :         return r;
    1840             : }
    1841             : 
    1842           2 : char *ascii_strlower(char *t) {
    1843             :         char *p;
    1844             : 
    1845           2 :         assert(t);
    1846             : 
    1847          35 :         for (p = t; *p; p++)
    1848          33 :                 if (*p >= 'A' && *p <= 'Z')
    1849          18 :                         *p = *p - 'A' + 'a';
    1850             : 
    1851           2 :         return t;
    1852             : }
    1853             : 
    1854       15922 : _pure_ static bool hidden_file_allow_backup(const char *filename) {
    1855       15922 :         assert(filename);
    1856             : 
    1857             :         return
    1858       42920 :                 filename[0] == '.' ||
    1859       22152 :                 streq(filename, "lost+found") ||
    1860       22152 :                 streq(filename, "aquota.user") ||
    1861       22152 :                 streq(filename, "aquota.group") ||
    1862       22152 :                 endswith(filename, ".rpmnew") ||
    1863       22151 :                 endswith(filename, ".rpmsave") ||
    1864       22150 :                 endswith(filename, ".rpmorig") ||
    1865       22150 :                 endswith(filename, ".dpkg-old") ||
    1866       22149 :                 endswith(filename, ".dpkg-new") ||
    1867       22148 :                 endswith(filename, ".dpkg-tmp") ||
    1868       22147 :                 endswith(filename, ".dpkg-dist") ||
    1869       22146 :                 endswith(filename, ".dpkg-bak") ||
    1870       22146 :                 endswith(filename, ".dpkg-backup") ||
    1871       38068 :                 endswith(filename, ".dpkg-remove") ||
    1872       11073 :                 endswith(filename, ".swp");
    1873             : }
    1874             : 
    1875       13943 : bool hidden_file(const char *filename) {
    1876       13943 :         assert(filename);
    1877             : 
    1878       13943 :         if (endswith(filename, "~"))
    1879           2 :                 return true;
    1880             : 
    1881       13941 :         return hidden_file_allow_backup(filename);
    1882             : }
    1883             : 
    1884          17 : int fd_nonblock(int fd, bool nonblock) {
    1885             :         int flags, nflags;
    1886             : 
    1887          17 :         assert(fd >= 0);
    1888             : 
    1889          17 :         flags = fcntl(fd, F_GETFL, 0);
    1890          17 :         if (flags < 0)
    1891           0 :                 return -errno;
    1892             : 
    1893          17 :         if (nonblock)
    1894          17 :                 nflags = flags | O_NONBLOCK;
    1895             :         else
    1896           0 :                 nflags = flags & ~O_NONBLOCK;
    1897             : 
    1898          17 :         if (nflags == flags)
    1899           0 :                 return 0;
    1900             : 
    1901          17 :         if (fcntl(fd, F_SETFL, nflags) < 0)
    1902           0 :                 return -errno;
    1903             : 
    1904          17 :         return 0;
    1905             : }
    1906             : 
    1907          18 : int fd_cloexec(int fd, bool cloexec) {
    1908             :         int flags, nflags;
    1909             : 
    1910          18 :         assert(fd >= 0);
    1911             : 
    1912          18 :         flags = fcntl(fd, F_GETFD, 0);
    1913          18 :         if (flags < 0)
    1914           0 :                 return -errno;
    1915             : 
    1916          18 :         if (cloexec)
    1917          17 :                 nflags = flags | FD_CLOEXEC;
    1918             :         else
    1919           1 :                 nflags = flags & ~FD_CLOEXEC;
    1920             : 
    1921          18 :         if (nflags == flags)
    1922           0 :                 return 0;
    1923             : 
    1924          18 :         if (fcntl(fd, F_SETFD, nflags) < 0)
    1925           0 :                 return -errno;
    1926             : 
    1927          18 :         return 0;
    1928             : }
    1929             : 
    1930           2 : _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
    1931             :         unsigned i;
    1932             : 
    1933           2 :         assert(n_fdset == 0 || fdset);
    1934             : 
    1935           3 :         for (i = 0; i < n_fdset; i++)
    1936           2 :                 if (fdset[i] == fd)
    1937           1 :                         return true;
    1938             : 
    1939           1 :         return false;
    1940             : }
    1941             : 
    1942           1 : int close_all_fds(const int except[], unsigned n_except) {
    1943           2 :         _cleanup_closedir_ DIR *d = NULL;
    1944             :         struct dirent *de;
    1945           1 :         int r = 0;
    1946             : 
    1947           1 :         assert(n_except == 0 || except);
    1948             : 
    1949           1 :         d = opendir("/proc/self/fd");
    1950           1 :         if (!d) {
    1951             :                 int fd;
    1952             :                 struct rlimit rl;
    1953             : 
    1954             :                 /* When /proc isn't available (for example in chroots)
    1955             :                  * the fallback is brute forcing through the fd
    1956             :                  * table */
    1957             : 
    1958           0 :                 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
    1959           0 :                 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
    1960             : 
    1961           0 :                         if (fd_in_set(fd, except, n_except))
    1962           0 :                                 continue;
    1963             : 
    1964           0 :                         if (close_nointr(fd) < 0)
    1965           0 :                                 if (errno != EBADF && r == 0)
    1966           0 :                                         r = -errno;
    1967             :                 }
    1968             : 
    1969           0 :                 return r;
    1970             :         }
    1971             : 
    1972          10 :         while ((de = readdir(d))) {
    1973           8 :                 int fd = -1;
    1974             : 
    1975           8 :                 if (hidden_file(de->d_name))
    1976           9 :                         continue;
    1977             : 
    1978           6 :                 if (safe_atoi(de->d_name, &fd) < 0)
    1979             :                         /* Let's better ignore this, just in case */
    1980           0 :                         continue;
    1981             : 
    1982           6 :                 if (fd < 3)
    1983           3 :                         continue;
    1984             : 
    1985           3 :                 if (fd == dirfd(d))
    1986           1 :                         continue;
    1987             : 
    1988           2 :                 if (fd_in_set(fd, except, n_except))
    1989           1 :                         continue;
    1990             : 
    1991           1 :                 if (close_nointr(fd) < 0) {
    1992             :                         /* Valgrind has its own FD and doesn't want to have it closed */
    1993           0 :                         if (errno != EBADF && r == 0)
    1994           0 :                                 r = -errno;
    1995             :                 }
    1996             :         }
    1997             : 
    1998           1 :         return r;
    1999             : }
    2000             : 
    2001           8 : bool chars_intersect(const char *a, const char *b) {
    2002             :         const char *p;
    2003             : 
    2004             :         /* Returns true if any of the chars in a are in b. */
    2005          48 :         for (p = a; *p; p++)
    2006          44 :                 if (strchr(b, *p))
    2007           4 :                         return true;
    2008             : 
    2009           4 :         return false;
    2010             : }
    2011             : 
    2012           0 : bool fstype_is_network(const char *fstype) {
    2013             :         static const char table[] =
    2014             :                 "afs\0"
    2015             :                 "cifs\0"
    2016             :                 "smbfs\0"
    2017             :                 "sshfs\0"
    2018             :                 "ncpfs\0"
    2019             :                 "ncp\0"
    2020             :                 "nfs\0"
    2021             :                 "nfs4\0"
    2022             :                 "gfs\0"
    2023             :                 "gfs2\0"
    2024             :                 "glusterfs\0";
    2025             : 
    2026             :         const char *x;
    2027             : 
    2028           0 :         x = startswith(fstype, "fuse.");
    2029           0 :         if (x)
    2030           0 :                 fstype = x;
    2031             : 
    2032           0 :         return nulstr_contains(table, fstype);
    2033             : }
    2034             : 
    2035           0 : int flush_fd(int fd) {
    2036           0 :         struct pollfd pollfd = {
    2037             :                 .fd = fd,
    2038             :                 .events = POLLIN,
    2039             :         };
    2040             : 
    2041             :         for (;;) {
    2042             :                 char buf[LINE_MAX];
    2043             :                 ssize_t l;
    2044             :                 int r;
    2045             : 
    2046           0 :                 r = poll(&pollfd, 1, 0);
    2047           0 :                 if (r < 0) {
    2048           0 :                         if (errno == EINTR)
    2049           0 :                                 continue;
    2050             : 
    2051           0 :                         return -errno;
    2052             : 
    2053           0 :                 } else if (r == 0)
    2054           0 :                         return 0;
    2055             : 
    2056           0 :                 l = read(fd, buf, sizeof(buf));
    2057           0 :                 if (l < 0) {
    2058             : 
    2059           0 :                         if (errno == EINTR)
    2060           0 :                                 continue;
    2061             : 
    2062           0 :                         if (errno == EAGAIN)
    2063           0 :                                 return 0;
    2064             : 
    2065           0 :                         return -errno;
    2066           0 :                 } else if (l == 0)
    2067           0 :                         return 0;
    2068           0 :         }
    2069             : }
    2070             : 
    2071        1030 : void safe_close_pair(int p[]) {
    2072        1030 :         assert(p);
    2073             : 
    2074        1030 :         if (p[0] == p[1]) {
    2075             :                 /* Special case pairs which use the same fd in both
    2076             :                  * directions... */
    2077           9 :                 p[0] = p[1] = safe_close(p[0]);
    2078           9 :                 return;
    2079             :         }
    2080             : 
    2081        1021 :         p[0] = safe_close(p[0]);
    2082        1021 :         p[1] = safe_close(p[1]);
    2083             : }
    2084             : 
    2085          30 : ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
    2086          30 :         uint8_t *p = buf;
    2087          30 :         ssize_t n = 0;
    2088             : 
    2089          30 :         assert(fd >= 0);
    2090          30 :         assert(buf);
    2091             : 
    2092          90 :         while (nbytes > 0) {
    2093             :                 ssize_t k;
    2094             : 
    2095          30 :                 k = read(fd, p, nbytes);
    2096          30 :                 if (k < 0) {
    2097           0 :                         if (errno == EINTR)
    2098           0 :                                 continue;
    2099             : 
    2100           0 :                         if (errno == EAGAIN && do_poll) {
    2101             : 
    2102             :                                 /* We knowingly ignore any return value here,
    2103             :                                  * and expect that any error/EOF is reported
    2104             :                                  * via read() */
    2105             : 
    2106           0 :                                 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
    2107           0 :                                 continue;
    2108             :                         }
    2109             : 
    2110           0 :                         return n > 0 ? n : -errno;
    2111             :                 }
    2112             : 
    2113          30 :                 if (k == 0)
    2114           0 :                         return n;
    2115             : 
    2116          30 :                 p += k;
    2117          30 :                 nbytes -= k;
    2118          30 :                 n += k;
    2119             :         }
    2120             : 
    2121          30 :         return n;
    2122             : }
    2123             : 
    2124          30 : int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
    2125             :         ssize_t n;
    2126             : 
    2127          30 :         n = loop_read(fd, buf, nbytes, do_poll);
    2128          30 :         if (n < 0)
    2129           0 :                 return n;
    2130          30 :         if ((size_t) n != nbytes)
    2131           0 :                 return -EIO;
    2132          30 :         return 0;
    2133             : }
    2134             : 
    2135         260 : int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
    2136         260 :         const uint8_t *p = buf;
    2137             : 
    2138         260 :         assert(fd >= 0);
    2139         260 :         assert(buf);
    2140             : 
    2141         260 :         errno = 0;
    2142             : 
    2143             :         do {
    2144             :                 ssize_t k;
    2145             : 
    2146         260 :                 k = write(fd, p, nbytes);
    2147         260 :                 if (k < 0) {
    2148           0 :                         if (errno == EINTR)
    2149           0 :                                 continue;
    2150             : 
    2151           0 :                         if (errno == EAGAIN && do_poll) {
    2152             :                                 /* We knowingly ignore any return value here,
    2153             :                                  * and expect that any error/EOF is reported
    2154             :                                  * via write() */
    2155             : 
    2156           0 :                                 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
    2157           0 :                                 continue;
    2158             :                         }
    2159             : 
    2160           0 :                         return -errno;
    2161             :                 }
    2162             : 
    2163         260 :                 if (nbytes > 0 && k == 0) /* Can't really happen */
    2164           0 :                         return -EIO;
    2165             : 
    2166         260 :                 p += k;
    2167         260 :                 nbytes -= k;
    2168         260 :         } while (nbytes > 0);
    2169             : 
    2170         260 :         return 0;
    2171             : }
    2172             : 
    2173          47 : int parse_size(const char *t, off_t base, off_t *size) {
    2174             : 
    2175             :         /* Soo, sometimes we want to parse IEC binary suffixes, and
    2176             :          * sometimes SI decimal suffixes. This function can parse
    2177             :          * both. Which one is the right way depends on the
    2178             :          * context. Wikipedia suggests that SI is customary for
    2179             :          * hardware metrics and network speeds, while IEC is
    2180             :          * customary for most data sizes used by software and volatile
    2181             :          * (RAM) memory. Hence be careful which one you pick!
    2182             :          *
    2183             :          * In either case we use just K, M, G as suffix, and not Ki,
    2184             :          * Mi, Gi or so (as IEC would suggest). That's because that's
    2185             :          * frickin' ugly. But this means you really need to make sure
    2186             :          * to document which base you are parsing when you use this
    2187             :          * call. */
    2188             : 
    2189             :         struct table {
    2190             :                 const char *suffix;
    2191             :                 unsigned long long factor;
    2192             :         };
    2193             : 
    2194             :         static const struct table iec[] = {
    2195             :                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
    2196             :                 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
    2197             :                 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
    2198             :                 { "G", 1024ULL*1024ULL*1024ULL },
    2199             :                 { "M", 1024ULL*1024ULL },
    2200             :                 { "K", 1024ULL },
    2201             :                 { "B", 1 },
    2202             :                 { "", 1 },
    2203             :         };
    2204             : 
    2205             :         static const struct table si[] = {
    2206             :                 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
    2207             :                 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
    2208             :                 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
    2209             :                 { "G", 1000ULL*1000ULL*1000ULL },
    2210             :                 { "M", 1000ULL*1000ULL },
    2211             :                 { "K", 1000ULL },
    2212             :                 { "B", 1 },
    2213             :                 { "", 1 },
    2214             :         };
    2215             : 
    2216             :         const struct table *table;
    2217             :         const char *p;
    2218          47 :         unsigned long long r = 0;
    2219          47 :         unsigned n_entries, start_pos = 0;
    2220             : 
    2221          47 :         assert(t);
    2222          47 :         assert(base == 1000 || base == 1024);
    2223          47 :         assert(size);
    2224             : 
    2225          47 :         if (base == 1000) {
    2226           9 :                 table = si;
    2227           9 :                 n_entries = ELEMENTSOF(si);
    2228             :         } else {
    2229          38 :                 table = iec;
    2230          38 :                 n_entries = ELEMENTSOF(iec);
    2231             :         }
    2232             : 
    2233          47 :         p = t;
    2234             :         do {
    2235             :                 long long l;
    2236             :                 unsigned long long l2;
    2237          65 :                 double frac = 0;
    2238             :                 char *e;
    2239             :                 unsigned i;
    2240             : 
    2241          65 :                 errno = 0;
    2242          65 :                 l = strtoll(p, &e, 10);
    2243             : 
    2244          65 :                 if (errno > 0)
    2245          20 :                         return -errno;
    2246             : 
    2247          63 :                 if (l < 0)
    2248           6 :                         return -ERANGE;
    2249             : 
    2250          57 :                 if (e == p)
    2251           8 :                         return -EINVAL;
    2252             : 
    2253          49 :                 if (*e == '.') {
    2254          13 :                         e++;
    2255          13 :                         if (*e >= '0' && *e <= '9') {
    2256             :                                 char *e2;
    2257             : 
    2258             :                                 /* strotoull itself would accept space/+/- */
    2259          11 :                                 l2 = strtoull(e, &e2, 10);
    2260             : 
    2261          11 :                                 if (errno == ERANGE)
    2262           0 :                                         return -errno;
    2263             : 
    2264             :                                 /* Ignore failure. E.g. 10.M is valid */
    2265          11 :                                 frac = l2;
    2266          22 :                                 for (; e < e2; e++)
    2267          11 :                                         frac /= 10;
    2268             :                         }
    2269             :                 }
    2270             : 
    2271          49 :                 e += strspn(e, WHITESPACE);
    2272             : 
    2273         228 :                 for (i = start_pos; i < n_entries; i++)
    2274         227 :                         if (startswith(e, table[i].suffix)) {
    2275             :                                 unsigned long long tmp;
    2276          48 :                                 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
    2277           1 :                                         return -ERANGE;
    2278          47 :                                 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
    2279          47 :                                 if (tmp > ULLONG_MAX - r)
    2280           0 :                                         return -ERANGE;
    2281             : 
    2282          47 :                                 r += tmp;
    2283             :                                 if ((unsigned long long) (off_t) r != r)
    2284             :                                         return -ERANGE;
    2285             : 
    2286          47 :                                 p = e + strlen(table[i].suffix);
    2287             : 
    2288          47 :                                 start_pos = i + 1;
    2289          47 :                                 break;
    2290             :                         }
    2291             : 
    2292          48 :                 if (i >= n_entries)
    2293           1 :                         return -EINVAL;
    2294             : 
    2295          47 :         } while (*p);
    2296             : 
    2297          29 :         *size = r;
    2298             : 
    2299          29 :         return 0;
    2300             : }
    2301             : 
    2302         223 : bool is_device_path(const char *path) {
    2303             : 
    2304             :         /* Returns true on paths that refer to a device, either in
    2305             :          * sysfs or in /dev */
    2306             : 
    2307             :         return
    2308         435 :                 path_startswith(path, "/dev/") ||
    2309         212 :                 path_startswith(path, "/sys/");
    2310             : }
    2311             : 
    2312          17 : int dir_is_empty(const char *path) {
    2313          17 :         _cleanup_closedir_ DIR *d;
    2314             : 
    2315          17 :         d = opendir(path);
    2316          17 :         if (!d)
    2317           2 :                 return -errno;
    2318             : 
    2319             :         for (;;) {
    2320             :                 struct dirent *de;
    2321             : 
    2322          45 :                 errno = 0;
    2323          45 :                 de = readdir(d);
    2324          45 :                 if (!de && errno != 0)
    2325           0 :                         return -errno;
    2326             : 
    2327          45 :                 if (!de)
    2328           2 :                         return 1;
    2329             : 
    2330          43 :                 if (!hidden_file(de->d_name))
    2331          13 :                         return 0;
    2332          30 :         }
    2333             : }
    2334             : 
    2335           1 : char* dirname_malloc(const char *path) {
    2336             :         char *d, *dir, *dir2;
    2337             : 
    2338           1 :         d = strdup(path);
    2339           1 :         if (!d)
    2340           0 :                 return NULL;
    2341           1 :         dir = dirname(d);
    2342           1 :         assert(dir);
    2343             : 
    2344           1 :         if (dir != d) {
    2345           0 :                 dir2 = strdup(dir);
    2346           0 :                 free(d);
    2347           0 :                 return dir2;
    2348             :         }
    2349             : 
    2350           1 :         return dir;
    2351             : }
    2352             : 
    2353           0 : void rename_process(const char name[8]) {
    2354           0 :         assert(name);
    2355             : 
    2356             :         /* This is a like a poor man's setproctitle(). It changes the
    2357             :          * comm field, argv[0], and also the glibc's internally used
    2358             :          * name of the process. For the first one a limit of 16 chars
    2359             :          * applies, to the second one usually one of 10 (i.e. length
    2360             :          * of "/sbin/init"), to the third one one of 7 (i.e. length of
    2361             :          * "systemd"). If you pass a longer string it will be
    2362             :          * truncated */
    2363             : 
    2364           0 :         prctl(PR_SET_NAME, name);
    2365             : 
    2366           0 :         if (program_invocation_name)
    2367           0 :                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
    2368             : 
    2369           0 :         if (saved_argc > 0) {
    2370             :                 int i;
    2371             : 
    2372           0 :                 if (saved_argv[0])
    2373           0 :                         strncpy(saved_argv[0], name, strlen(saved_argv[0]));
    2374             : 
    2375           0 :                 for (i = 1; i < saved_argc; i++) {
    2376           0 :                         if (!saved_argv[i])
    2377           0 :                                 break;
    2378             : 
    2379           0 :                         memzero(saved_argv[i], strlen(saved_argv[i]));
    2380             :                 }
    2381             :         }
    2382           0 : }
    2383             : 
    2384           0 : char *lookup_uid(uid_t uid) {
    2385             :         long bufsize;
    2386             :         char *name;
    2387           0 :         _cleanup_free_ char *buf = NULL;
    2388           0 :         struct passwd pwbuf, *pw = NULL;
    2389             : 
    2390             :         /* Shortcut things to avoid NSS lookups */
    2391           0 :         if (uid == 0)
    2392           0 :                 return strdup("root");
    2393             : 
    2394           0 :         bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
    2395           0 :         if (bufsize <= 0)
    2396           0 :                 bufsize = 4096;
    2397             : 
    2398           0 :         buf = malloc(bufsize);
    2399           0 :         if (!buf)
    2400           0 :                 return NULL;
    2401             : 
    2402           0 :         if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
    2403           0 :                 return strdup(pw->pw_name);
    2404             : 
    2405           0 :         if (asprintf(&name, UID_FMT, uid) < 0)
    2406           0 :                 return NULL;
    2407             : 
    2408           0 :         return name;
    2409             : }
    2410             : 
    2411           0 : char* getlogname_malloc(void) {
    2412             :         uid_t uid;
    2413             :         struct stat st;
    2414             : 
    2415           0 :         if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
    2416           0 :                 uid = st.st_uid;
    2417             :         else
    2418           0 :                 uid = getuid();
    2419             : 
    2420           0 :         return lookup_uid(uid);
    2421             : }
    2422             : 
    2423           8 : char *getusername_malloc(void) {
    2424             :         const char *e;
    2425             : 
    2426           8 :         e = getenv("USER");
    2427           8 :         if (e)
    2428           8 :                 return strdup(e);
    2429             : 
    2430           0 :         return lookup_uid(getuid());
    2431             : }
    2432             : 
    2433           0 : bool is_temporary_fs(const struct statfs *s) {
    2434           0 :         assert(s);
    2435             : 
    2436           0 :         return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
    2437           0 :                F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
    2438             : }
    2439             : 
    2440           0 : int fd_is_temporary_fs(int fd) {
    2441             :         struct statfs s;
    2442             : 
    2443           0 :         if (fstatfs(fd, &s) < 0)
    2444           0 :                 return -errno;
    2445             : 
    2446           0 :         return is_temporary_fs(&s);
    2447             : }
    2448             : 
    2449           1 : int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
    2450           1 :         assert(path);
    2451             : 
    2452             :         /* Under the assumption that we are running privileged we
    2453             :          * first change the access mode and only then hand out
    2454             :          * ownership to avoid a window where access is too open. */
    2455             : 
    2456           1 :         if (mode != MODE_INVALID)
    2457           1 :                 if (chmod(path, mode) < 0)
    2458           0 :                         return -errno;
    2459             : 
    2460           1 :         if (uid != UID_INVALID || gid != GID_INVALID)
    2461           1 :                 if (chown(path, uid, gid) < 0)
    2462           0 :                         return -errno;
    2463             : 
    2464           1 :         return 0;
    2465             : }
    2466             : 
    2467           0 : int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
    2468           0 :         assert(fd >= 0);
    2469             : 
    2470             :         /* Under the assumption that we are running privileged we
    2471             :          * first change the access mode and only then hand out
    2472             :          * ownership to avoid a window where access is too open. */
    2473             : 
    2474           0 :         if (mode != MODE_INVALID)
    2475           0 :                 if (fchmod(fd, mode) < 0)
    2476           0 :                         return -errno;
    2477             : 
    2478           0 :         if (uid != UID_INVALID || gid != GID_INVALID)
    2479           0 :                 if (fchown(fd, uid, gid) < 0)
    2480           0 :                         return -errno;
    2481             : 
    2482           0 :         return 0;
    2483             : }
    2484             : 
    2485           0 : cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
    2486             :         cpu_set_t *r;
    2487           0 :         unsigned n = 1024;
    2488             : 
    2489             :         /* Allocates the cpuset in the right size */
    2490             : 
    2491             :         for (;;) {
    2492           0 :                 if (!(r = CPU_ALLOC(n)))
    2493           0 :                         return NULL;
    2494             : 
    2495           0 :                 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
    2496           0 :                         CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
    2497             : 
    2498           0 :                         if (ncpus)
    2499           0 :                                 *ncpus = n;
    2500             : 
    2501           0 :                         return r;
    2502             :                 }
    2503             : 
    2504           0 :                 CPU_FREE(r);
    2505             : 
    2506           0 :                 if (errno != EINVAL)
    2507           0 :                         return NULL;
    2508             : 
    2509           0 :                 n *= 2;
    2510           0 :         }
    2511             : }
    2512             : 
    2513           2 : int files_same(const char *filea, const char *fileb) {
    2514             :         struct stat a, b;
    2515             : 
    2516           2 :         if (stat(filea, &a) < 0)
    2517           0 :                 return -errno;
    2518             : 
    2519           2 :         if (stat(fileb, &b) < 0)
    2520           0 :                 return -errno;
    2521             : 
    2522           4 :         return a.st_dev == b.st_dev &&
    2523           2 :                a.st_ino == b.st_ino;
    2524             : }
    2525             : 
    2526           0 : int running_in_chroot(void) {
    2527             :         int ret;
    2528             : 
    2529           0 :         ret = files_same("/proc/1/root", "/");
    2530           0 :         if (ret < 0)
    2531           0 :                 return ret;
    2532             : 
    2533           0 :         return ret == 0;
    2534             : }
    2535             : 
    2536           2 : static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
    2537             :         size_t x;
    2538             :         char *r;
    2539             : 
    2540           2 :         assert(s);
    2541           2 :         assert(percent <= 100);
    2542           2 :         assert(new_length >= 3);
    2543             : 
    2544           2 :         if (old_length <= 3 || old_length <= new_length)
    2545           0 :                 return strndup(s, old_length);
    2546             : 
    2547           2 :         r = new0(char, new_length+1);
    2548           2 :         if (!r)
    2549           0 :                 return NULL;
    2550             : 
    2551           2 :         x = (new_length * percent) / 100;
    2552             : 
    2553           2 :         if (x > new_length - 3)
    2554           0 :                 x = new_length - 3;
    2555             : 
    2556           2 :         memcpy(r, s, x);
    2557           2 :         r[x] = '.';
    2558           2 :         r[x+1] = '.';
    2559           2 :         r[x+2] = '.';
    2560           4 :         memcpy(r + x + 3,
    2561           2 :                s + old_length - (new_length - x - 3),
    2562           2 :                new_length - x - 3);
    2563             : 
    2564           2 :         return r;
    2565             : }
    2566             : 
    2567           8 : char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
    2568             :         size_t x;
    2569             :         char *e;
    2570             :         const char *i, *j;
    2571             :         unsigned k, len, len2;
    2572             : 
    2573           8 :         assert(s);
    2574           8 :         assert(percent <= 100);
    2575           8 :         assert(new_length >= 3);
    2576             : 
    2577             :         /* if no multibyte characters use ascii_ellipsize_mem for speed */
    2578           8 :         if (ascii_is_valid(s))
    2579           2 :                 return ascii_ellipsize_mem(s, old_length, new_length, percent);
    2580             : 
    2581           6 :         if (old_length <= 3 || old_length <= new_length)
    2582           1 :                 return strndup(s, old_length);
    2583             : 
    2584           5 :         x = (new_length * percent) / 100;
    2585             : 
    2586           5 :         if (x > new_length - 3)
    2587           0 :                 x = new_length - 3;
    2588             : 
    2589           5 :         k = 0;
    2590         174 :         for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
    2591             :                 int c;
    2592             : 
    2593         169 :                 c = utf8_encoded_to_unichar(i);
    2594         169 :                 if (c < 0)
    2595           0 :                         return NULL;
    2596         169 :                 k += unichar_iswide(c) ? 2 : 1;
    2597             :         }
    2598             : 
    2599           5 :         if (k > x) /* last character was wide and went over quota */
    2600           1 :                 x ++;
    2601             : 
    2602          82 :         for (j = s + old_length; k < new_length && j > i; ) {
    2603             :                 int c;
    2604             : 
    2605          72 :                 j = utf8_prev_char(j);
    2606          72 :                 c = utf8_encoded_to_unichar(j);
    2607          72 :                 if (c < 0)
    2608           0 :                         return NULL;
    2609          72 :                 k += unichar_iswide(c) ? 2 : 1;
    2610             :         }
    2611           5 :         assert(i <= j);
    2612             : 
    2613             :         /* we don't actually need to ellipsize */
    2614           5 :         if (i == j)
    2615           0 :                 return memdup(s, old_length + 1);
    2616             : 
    2617             :         /* make space for ellipsis */
    2618           5 :         j = utf8_next_char(j);
    2619             : 
    2620           5 :         len = i - s;
    2621           5 :         len2 = s + old_length - j;
    2622           5 :         e = new(char, len + 3 + len2 + 1);
    2623           5 :         if (!e)
    2624           0 :                 return NULL;
    2625             : 
    2626             :         /*
    2627             :         printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
    2628             :                old_length, new_length, x, len, len2, k);
    2629             :         */
    2630             : 
    2631           5 :         memcpy(e, s, len);
    2632           5 :         e[len]   = 0xe2; /* tri-dot ellipsis: … */
    2633           5 :         e[len + 1] = 0x80;
    2634           5 :         e[len + 2] = 0xa6;
    2635             : 
    2636           5 :         memcpy(e + len + 3, j, len2 + 1);
    2637             : 
    2638           5 :         return e;
    2639             : }
    2640             : 
    2641           8 : char *ellipsize(const char *s, size_t length, unsigned percent) {
    2642           8 :         return ellipsize_mem(s, strlen(s), length, percent);
    2643             : }
    2644             : 
    2645          14 : int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
    2646          14 :         _cleanup_close_ int fd;
    2647             :         int r;
    2648             : 
    2649          14 :         assert(path);
    2650             : 
    2651          14 :         if (parents)
    2652           6 :                 mkdir_parents(path, 0755);
    2653             : 
    2654          14 :         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
    2655          14 :         if (fd < 0)
    2656           0 :                 return -errno;
    2657             : 
    2658          14 :         if (mode > 0) {
    2659           0 :                 r = fchmod(fd, mode);
    2660           0 :                 if (r < 0)
    2661           0 :                         return -errno;
    2662             :         }
    2663             : 
    2664          14 :         if (uid != UID_INVALID || gid != GID_INVALID) {
    2665           0 :                 r = fchown(fd, uid, gid);
    2666           0 :                 if (r < 0)
    2667           0 :                         return -errno;
    2668             :         }
    2669             : 
    2670          14 :         if (stamp != USEC_INFINITY) {
    2671             :                 struct timespec ts[2];
    2672             : 
    2673           0 :                 timespec_store(&ts[0], stamp);
    2674           0 :                 ts[1] = ts[0];
    2675           0 :                 r = futimens(fd, ts);
    2676             :         } else
    2677          14 :                 r = futimens(fd, NULL);
    2678          14 :         if (r < 0)
    2679           0 :                 return -errno;
    2680             : 
    2681          14 :         return 0;
    2682             : }
    2683             : 
    2684           8 : int touch(const char *path) {
    2685           8 :         return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
    2686             : }
    2687             : 
    2688           4 : static char *unquote(const char *s, const char* quotes) {
    2689             :         size_t l;
    2690           4 :         assert(s);
    2691             : 
    2692             :         /* This is rather stupid, simply removes the heading and
    2693             :          * trailing quotes if there is one. Doesn't care about
    2694             :          * escaping or anything.
    2695             :          *
    2696             :          * DON'T USE THIS FOR NEW CODE ANYMORE!*/
    2697             : 
    2698           4 :         l = strlen(s);
    2699           4 :         if (l < 2)
    2700           0 :                 return strdup(s);
    2701             : 
    2702           4 :         if (strchr(quotes, s[0]) && s[l-1] == s[0])
    2703           0 :                 return strndup(s+1, l-2);
    2704             : 
    2705           4 :         return strdup(s);
    2706             : }
    2707             : 
    2708           0 : noreturn void freeze(void) {
    2709             : 
    2710             :         /* Make sure nobody waits for us on a socket anymore */
    2711           0 :         close_all_fds(NULL, 0);
    2712             : 
    2713           0 :         sync();
    2714             : 
    2715             :         for (;;)
    2716           0 :                 pause();
    2717             : }
    2718             : 
    2719         387 : bool null_or_empty(struct stat *st) {
    2720         387 :         assert(st);
    2721             : 
    2722         387 :         if (S_ISREG(st->st_mode) && st->st_size <= 0)
    2723           1 :                 return true;
    2724             : 
    2725         386 :         if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
    2726           1 :                 return true;
    2727             : 
    2728         385 :         return false;
    2729             : }
    2730             : 
    2731         292 : int null_or_empty_path(const char *fn) {
    2732             :         struct stat st;
    2733             : 
    2734         292 :         assert(fn);
    2735             : 
    2736         292 :         if (stat(fn, &st) < 0)
    2737           0 :                 return -errno;
    2738             : 
    2739         292 :         return null_or_empty(&st);
    2740             : }
    2741             : 
    2742           3 : int null_or_empty_fd(int fd) {
    2743             :         struct stat st;
    2744             : 
    2745           3 :         assert(fd >= 0);
    2746             : 
    2747           3 :         if (fstat(fd, &st) < 0)
    2748           0 :                 return -errno;
    2749             : 
    2750           3 :         return null_or_empty(&st);
    2751             : }
    2752             : 
    2753           0 : DIR *xopendirat(int fd, const char *name, int flags) {
    2754             :         int nfd;
    2755             :         DIR *d;
    2756             : 
    2757           0 :         assert(!(flags & O_CREAT));
    2758             : 
    2759           0 :         nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
    2760           0 :         if (nfd < 0)
    2761           0 :                 return NULL;
    2762             : 
    2763           0 :         d = fdopendir(nfd);
    2764           0 :         if (!d) {
    2765           0 :                 safe_close(nfd);
    2766           0 :                 return NULL;
    2767             :         }
    2768             : 
    2769           0 :         return d;
    2770             : }
    2771             : 
    2772           4 : static char *tag_to_udev_node(const char *tagvalue, const char *by) {
    2773           8 :         _cleanup_free_ char *t = NULL, *u = NULL;
    2774             :         size_t enc_len;
    2775             : 
    2776           4 :         u = unquote(tagvalue, QUOTES);
    2777           4 :         if (!u)
    2778           0 :                 return NULL;
    2779             : 
    2780           4 :         enc_len = strlen(u) * 4 + 1;
    2781           4 :         t = new(char, enc_len);
    2782           4 :         if (!t)
    2783           0 :                 return NULL;
    2784             : 
    2785           4 :         if (encode_devnode_name(u, t, enc_len) < 0)
    2786           0 :                 return NULL;
    2787             : 
    2788           4 :         return strjoin("/dev/disk/by-", by, "/", t, NULL);
    2789             : }
    2790             : 
    2791           6 : char *fstab_node_to_udev_node(const char *p) {
    2792           6 :         assert(p);
    2793             : 
    2794           6 :         if (startswith(p, "LABEL="))
    2795           1 :                 return tag_to_udev_node(p+6, "label");
    2796             : 
    2797           5 :         if (startswith(p, "UUID="))
    2798           1 :                 return tag_to_udev_node(p+5, "uuid");
    2799             : 
    2800           4 :         if (startswith(p, "PARTUUID="))
    2801           1 :                 return tag_to_udev_node(p+9, "partuuid");
    2802             : 
    2803           3 :         if (startswith(p, "PARTLABEL="))
    2804           1 :                 return tag_to_udev_node(p+10, "partlabel");
    2805             : 
    2806           2 :         return strdup(p);
    2807             : }
    2808             : 
    2809         725 : bool dirent_is_file(const struct dirent *de) {
    2810         725 :         assert(de);
    2811             : 
    2812         725 :         if (hidden_file(de->d_name))
    2813          40 :                 return false;
    2814             : 
    2815         732 :         if (de->d_type != DT_REG &&
    2816          93 :             de->d_type != DT_LNK &&
    2817          46 :             de->d_type != DT_UNKNOWN)
    2818          46 :                 return false;
    2819             : 
    2820         639 :         return true;
    2821             : }
    2822             : 
    2823        3455 : bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
    2824        3455 :         assert(de);
    2825             : 
    2826        4930 :         if (de->d_type != DT_REG &&
    2827        2949 :             de->d_type != DT_LNK &&
    2828        1474 :             de->d_type != DT_UNKNOWN)
    2829        1474 :                 return false;
    2830             : 
    2831        1981 :         if (hidden_file_allow_backup(de->d_name))
    2832           0 :                 return false;
    2833             : 
    2834        1981 :         return endswith(de->d_name, suffix);
    2835             : }
    2836             : 
    2837           1 : static int do_execute(char **directories, usec_t timeout, char *argv[]) {
    2838           1 :         _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
    2839           1 :         _cleanup_set_free_free_ Set *seen = NULL;
    2840             :         char **directory;
    2841             : 
    2842             :         /* We fork this all off from a child process so that we can
    2843             :          * somewhat cleanly make use of SIGALRM to set a time limit */
    2844             : 
    2845           1 :         (void) reset_all_signal_handlers();
    2846           1 :         (void) reset_signal_mask();
    2847             : 
    2848           1 :         assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
    2849             : 
    2850           1 :         pids = hashmap_new(NULL);
    2851           1 :         if (!pids)
    2852           0 :                 return log_oom();
    2853             : 
    2854           1 :         seen = set_new(&string_hash_ops);
    2855           1 :         if (!seen)
    2856           0 :                 return log_oom();
    2857             : 
    2858           2 :         STRV_FOREACH(directory, directories) {
    2859           1 :                 _cleanup_closedir_ DIR *d;
    2860             :                 struct dirent *de;
    2861             : 
    2862           2 :                 d = opendir(*directory);
    2863           2 :                 if (!d) {
    2864           0 :                         if (errno == ENOENT)
    2865           0 :                                 continue;
    2866             : 
    2867           0 :                         return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
    2868             :                 }
    2869             : 
    2870          12 :                 FOREACH_DIRENT(de, d, break) {
    2871          13 :                         _cleanup_free_ char *path = NULL;
    2872             :                         pid_t pid;
    2873             :                         int r;
    2874             : 
    2875           7 :                         if (!dirent_is_file(de))
    2876           0 :                                 continue;
    2877             : 
    2878           7 :                         if (set_contains(seen, de->d_name)) {
    2879           2 :                                 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
    2880           2 :                                 continue;
    2881             :                         }
    2882             : 
    2883           5 :                         r = set_put_strdup(seen, de->d_name);
    2884           5 :                         if (r < 0)
    2885           0 :                                 return log_oom();
    2886             : 
    2887           5 :                         path = strjoin(*directory, "/", de->d_name, NULL);
    2888           5 :                         if (!path)
    2889           0 :                                 return log_oom();
    2890             : 
    2891           5 :                         if (null_or_empty_path(path)) {
    2892           2 :                                 log_debug("%s is empty (a mask).", path);
    2893           2 :                                 continue;
    2894             :                         }
    2895             : 
    2896           3 :                         pid = fork();
    2897           5 :                         if (pid < 0) {
    2898           0 :                                 log_error_errno(errno, "Failed to fork: %m");
    2899           0 :                                 continue;
    2900           5 :                         } else if (pid == 0) {
    2901             :                                 char *_argv[2];
    2902             : 
    2903           3 :                                 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
    2904             : 
    2905           3 :                                 if (!argv) {
    2906           3 :                                         _argv[0] = path;
    2907           3 :                                         _argv[1] = NULL;
    2908           3 :                                         argv = _argv;
    2909             :                                 } else
    2910           0 :                                         argv[0] = path;
    2911             : 
    2912           3 :                                 execv(path, argv);
    2913           3 :                                 return log_error_errno(errno, "Failed to execute %s: %m", path);
    2914             :                         }
    2915             : 
    2916           2 :                         log_debug("Spawned %s as " PID_FMT ".", path, pid);
    2917             : 
    2918           2 :                         r = hashmap_put(pids, UINT_TO_PTR(pid), path);
    2919           2 :                         if (r < 0)
    2920           0 :                                 return log_oom();
    2921           2 :                         path = NULL;
    2922          10 :                 }
    2923             :         }
    2924             : 
    2925             :         /* Abort execution of this process after the timout. We simply
    2926             :          * rely on SIGALRM as default action terminating the process,
    2927             :          * and turn on alarm(). */
    2928             : 
    2929           0 :         if (timeout != USEC_INFINITY)
    2930           0 :                 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
    2931             : 
    2932           0 :         while (!hashmap_isempty(pids)) {
    2933           0 :                 _cleanup_free_ char *path = NULL;
    2934             :                 pid_t pid;
    2935             : 
    2936           0 :                 pid = PTR_TO_UINT(hashmap_first_key(pids));
    2937           0 :                 assert(pid > 0);
    2938             : 
    2939           0 :                 path = hashmap_remove(pids, UINT_TO_PTR(pid));
    2940           0 :                 assert(path);
    2941             : 
    2942           0 :                 wait_for_terminate_and_warn(path, pid, true);
    2943             :         }
    2944             : 
    2945           0 :         return 0;
    2946             : }
    2947             : 
    2948           1 : void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
    2949             :         pid_t executor_pid;
    2950             :         int r;
    2951             :         char *name;
    2952           1 :         char **dirs = (char**) directories;
    2953             : 
    2954           1 :         assert(!strv_isempty(dirs));
    2955             : 
    2956           1 :         name = basename(dirs[0]);
    2957           1 :         assert(!isempty(name));
    2958             : 
    2959             :         /* Executes all binaries in the directories in parallel and waits
    2960             :          * for them to finish. Optionally a timeout is applied. If a file
    2961             :          * with the same name exists in more than one directory, the
    2962             :          * earliest one wins. */
    2963             : 
    2964           1 :         executor_pid = fork();
    2965           2 :         if (executor_pid < 0) {
    2966           0 :                 log_error_errno(errno, "Failed to fork: %m");
    2967           0 :                 return;
    2968             : 
    2969           2 :         } else if (executor_pid == 0) {
    2970           1 :                 r = do_execute(dirs, timeout, argv);
    2971           0 :                 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
    2972             :         }
    2973             : 
    2974           1 :         wait_for_terminate_and_warn(name, executor_pid, true);
    2975             : }
    2976             : 
    2977         137 : bool nulstr_contains(const char*nulstr, const char *needle) {
    2978             :         const char *i;
    2979             : 
    2980         137 :         if (!nulstr)
    2981           0 :                 return false;
    2982             : 
    2983         189 :         NULSTR_FOREACH(i, nulstr)
    2984         189 :                 if (streq(i, needle))
    2985         137 :                         return true;
    2986             : 
    2987           0 :         return false;
    2988             : }
    2989             : 
    2990           0 : bool plymouth_running(void) {
    2991           0 :         return access("/run/plymouth/pid", F_OK) >= 0;
    2992             : }
    2993             : 
    2994           8 : char* strshorten(char *s, size_t l) {
    2995           8 :         assert(s);
    2996             : 
    2997           8 :         if (l < strlen(s))
    2998           2 :                 s[l] = 0;
    2999             : 
    3000           8 :         return s;
    3001             : }
    3002             : 
    3003           0 : bool machine_name_is_valid(const char *s) {
    3004             : 
    3005           0 :         if (!hostname_is_valid(s))
    3006           0 :                 return false;
    3007             : 
    3008             :         /* Machine names should be useful hostnames, but also be
    3009             :          * useful in unit names, hence we enforce a stricter length
    3010             :          * limitation. */
    3011             : 
    3012           0 :         if (strlen(s) > 64)
    3013           0 :                 return false;
    3014             : 
    3015           0 :         return true;
    3016             : }
    3017             : 
    3018           0 : int pipe_eof(int fd) {
    3019           0 :         struct pollfd pollfd = {
    3020             :                 .fd = fd,
    3021             :                 .events = POLLIN|POLLHUP,
    3022             :         };
    3023             : 
    3024             :         int r;
    3025             : 
    3026           0 :         r = poll(&pollfd, 1, 0);
    3027           0 :         if (r < 0)
    3028           0 :                 return -errno;
    3029             : 
    3030           0 :         if (r == 0)
    3031           0 :                 return 0;
    3032             : 
    3033           0 :         return pollfd.revents & POLLHUP;
    3034             : }
    3035             : 
    3036           7 : int fd_wait_for_event(int fd, int event, usec_t t) {
    3037             : 
    3038           7 :         struct pollfd pollfd = {
    3039             :                 .fd = fd,
    3040             :                 .events = event,
    3041             :         };
    3042             : 
    3043             :         struct timespec ts;
    3044             :         int r;
    3045             : 
    3046           7 :         r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
    3047           7 :         if (r < 0)
    3048           0 :                 return -errno;
    3049             : 
    3050           7 :         if (r == 0)
    3051           0 :                 return 0;
    3052             : 
    3053           7 :         return pollfd.revents;
    3054             : }
    3055             : 
    3056           7 : int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
    3057             :         FILE *f;
    3058             :         char *t;
    3059             :         int r, fd;
    3060             : 
    3061           7 :         assert(path);
    3062           7 :         assert(_f);
    3063           7 :         assert(_temp_path);
    3064             : 
    3065           7 :         r = tempfn_xxxxxx(path, NULL, &t);
    3066           7 :         if (r < 0)
    3067           0 :                 return r;
    3068             : 
    3069           7 :         fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
    3070           7 :         if (fd < 0) {
    3071           4 :                 free(t);
    3072           4 :                 return -errno;
    3073             :         }
    3074             : 
    3075           3 :         f = fdopen(fd, "we");
    3076           3 :         if (!f) {
    3077           0 :                 unlink_noerrno(t);
    3078           0 :                 free(t);
    3079           0 :                 safe_close(fd);
    3080           0 :                 return -errno;
    3081             :         }
    3082             : 
    3083           3 :         *_f = f;
    3084           3 :         *_temp_path = t;
    3085             : 
    3086           3 :         return 0;
    3087             : }
    3088             : 
    3089           0 : int symlink_atomic(const char *from, const char *to) {
    3090           0 :         _cleanup_free_ char *t = NULL;
    3091             :         int r;
    3092             : 
    3093           0 :         assert(from);
    3094           0 :         assert(to);
    3095             : 
    3096           0 :         r = tempfn_random(to, NULL, &t);
    3097           0 :         if (r < 0)
    3098           0 :                 return r;
    3099             : 
    3100           0 :         if (symlink(from, t) < 0)
    3101           0 :                 return -errno;
    3102             : 
    3103           0 :         if (rename(t, to) < 0) {
    3104           0 :                 unlink_noerrno(t);
    3105           0 :                 return -errno;
    3106             :         }
    3107             : 
    3108           0 :         return 0;
    3109             : }
    3110             : 
    3111           0 : int symlink_idempotent(const char *from, const char *to) {
    3112           0 :         _cleanup_free_ char *p = NULL;
    3113             :         int r;
    3114             : 
    3115           0 :         assert(from);
    3116           0 :         assert(to);
    3117             : 
    3118           0 :         if (symlink(from, to) < 0) {
    3119           0 :                 if (errno != EEXIST)
    3120           0 :                         return -errno;
    3121             : 
    3122           0 :                 r = readlink_malloc(to, &p);
    3123           0 :                 if (r < 0)
    3124           0 :                         return r;
    3125             : 
    3126           0 :                 if (!streq(p, from))
    3127           0 :                         return -EINVAL;
    3128             :         }
    3129             : 
    3130           0 :         return 0;
    3131             : }
    3132             : 
    3133           0 : int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
    3134           0 :         _cleanup_free_ char *t = NULL;
    3135             :         int r;
    3136             : 
    3137           0 :         assert(path);
    3138             : 
    3139           0 :         r = tempfn_random(path, NULL, &t);
    3140           0 :         if (r < 0)
    3141           0 :                 return r;
    3142             : 
    3143           0 :         if (mknod(t, mode, dev) < 0)
    3144           0 :                 return -errno;
    3145             : 
    3146           0 :         if (rename(t, path) < 0) {
    3147           0 :                 unlink_noerrno(t);
    3148           0 :                 return -errno;
    3149             :         }
    3150             : 
    3151           0 :         return 0;
    3152             : }
    3153             : 
    3154           0 : int mkfifo_atomic(const char *path, mode_t mode) {
    3155           0 :         _cleanup_free_ char *t = NULL;
    3156             :         int r;
    3157             : 
    3158           0 :         assert(path);
    3159             : 
    3160           0 :         r = tempfn_random(path, NULL, &t);
    3161           0 :         if (r < 0)
    3162           0 :                 return r;
    3163             : 
    3164           0 :         if (mkfifo(t, mode) < 0)
    3165           0 :                 return -errno;
    3166             : 
    3167           0 :         if (rename(t, path) < 0) {
    3168           0 :                 unlink_noerrno(t);
    3169           0 :                 return -errno;
    3170             :         }
    3171             : 
    3172           0 :         return 0;
    3173             : }
    3174             : 
    3175           0 : bool display_is_local(const char *display) {
    3176           0 :         assert(display);
    3177             : 
    3178             :         return
    3179           0 :                 display[0] == ':' &&
    3180           0 :                 display[1] >= '0' &&
    3181           0 :                 display[1] <= '9';
    3182             : }
    3183             : 
    3184           0 : int socket_from_display(const char *display, char **path) {
    3185             :         size_t k;
    3186             :         char *f, *c;
    3187             : 
    3188           0 :         assert(display);
    3189           0 :         assert(path);
    3190             : 
    3191           0 :         if (!display_is_local(display))
    3192           0 :                 return -EINVAL;
    3193             : 
    3194           0 :         k = strspn(display+1, "0123456789");
    3195             : 
    3196           0 :         f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
    3197           0 :         if (!f)
    3198           0 :                 return -ENOMEM;
    3199             : 
    3200           0 :         c = stpcpy(f, "/tmp/.X11-unix/X");
    3201           0 :         memcpy(c, display+1, k);
    3202           0 :         c[k] = 0;
    3203             : 
    3204           0 :         *path = f;
    3205             : 
    3206           0 :         return 0;
    3207             : }
    3208             : 
    3209          18 : int get_user_creds(
    3210             :                 const char **username,
    3211             :                 uid_t *uid, gid_t *gid,
    3212             :                 const char **home,
    3213             :                 const char **shell) {
    3214             : 
    3215             :         struct passwd *p;
    3216             :         uid_t u;
    3217             : 
    3218          18 :         assert(username);
    3219          18 :         assert(*username);
    3220             : 
    3221             :         /* We enforce some special rules for uid=0: in order to avoid
    3222             :          * NSS lookups for root we hardcode its data. */
    3223             : 
    3224          18 :         if (streq(*username, "root") || streq(*username, "0")) {
    3225          13 :                 *username = "root";
    3226             : 
    3227          13 :                 if (uid)
    3228          13 :                         *uid = 0;
    3229             : 
    3230          13 :                 if (gid)
    3231           0 :                         *gid = 0;
    3232             : 
    3233          13 :                 if (home)
    3234           0 :                         *home = "/root";
    3235             : 
    3236          13 :                 if (shell)
    3237           0 :                         *shell = "/bin/sh";
    3238             : 
    3239          13 :                 return 0;
    3240             :         }
    3241             : 
    3242           5 :         if (parse_uid(*username, &u) >= 0) {
    3243           3 :                 errno = 0;
    3244           3 :                 p = getpwuid(u);
    3245             : 
    3246             :                 /* If there are multiple users with the same id, make
    3247             :                  * sure to leave $USER to the configured value instead
    3248             :                  * of the first occurrence in the database. However if
    3249             :                  * the uid was configured by a numeric uid, then let's
    3250             :                  * pick the real username from /etc/passwd. */
    3251           3 :                 if (p)
    3252           3 :                         *username = p->pw_name;
    3253             :         } else {
    3254           2 :                 errno = 0;
    3255           2 :                 p = getpwnam(*username);
    3256             :         }
    3257             : 
    3258           5 :         if (!p)
    3259           2 :                 return errno > 0 ? -errno : -ESRCH;
    3260             : 
    3261           3 :         if (uid)
    3262           3 :                 *uid = p->pw_uid;
    3263             : 
    3264           3 :         if (gid)
    3265           0 :                 *gid = p->pw_gid;
    3266             : 
    3267           3 :         if (home)
    3268           0 :                 *home = p->pw_dir;
    3269             : 
    3270           3 :         if (shell)
    3271           0 :                 *shell = p->pw_shell;
    3272             : 
    3273           3 :         return 0;
    3274             : }
    3275             : 
    3276           6 : char* uid_to_name(uid_t uid) {
    3277             :         struct passwd *p;
    3278             :         char *r;
    3279             : 
    3280           6 :         if (uid == 0)
    3281           5 :                 return strdup("root");
    3282             : 
    3283           1 :         p = getpwuid(uid);
    3284           1 :         if (p)
    3285           1 :                 return strdup(p->pw_name);
    3286             : 
    3287           0 :         if (asprintf(&r, UID_FMT, uid) < 0)
    3288           0 :                 return NULL;
    3289             : 
    3290           0 :         return r;
    3291             : }
    3292             : 
    3293           3 : char* gid_to_name(gid_t gid) {
    3294             :         struct group *p;
    3295             :         char *r;
    3296             : 
    3297           3 :         if (gid == 0)
    3298           0 :                 return strdup("root");
    3299             : 
    3300           3 :         p = getgrgid(gid);
    3301           3 :         if (p)
    3302           3 :                 return strdup(p->gr_name);
    3303             : 
    3304           0 :         if (asprintf(&r, GID_FMT, gid) < 0)
    3305           0 :                 return NULL;
    3306             : 
    3307           0 :         return r;
    3308             : }
    3309             : 
    3310           3 : int get_group_creds(const char **groupname, gid_t *gid) {
    3311             :         struct group *g;
    3312             :         gid_t id;
    3313             : 
    3314           3 :         assert(groupname);
    3315             : 
    3316             :         /* We enforce some special rules for gid=0: in order to avoid
    3317             :          * NSS lookups for root we hardcode its data. */
    3318             : 
    3319           3 :         if (streq(*groupname, "root") || streq(*groupname, "0")) {
    3320           0 :                 *groupname = "root";
    3321             : 
    3322           0 :                 if (gid)
    3323           0 :                         *gid = 0;
    3324             : 
    3325           0 :                 return 0;
    3326             :         }
    3327             : 
    3328           3 :         if (parse_gid(*groupname, &id) >= 0) {
    3329           1 :                 errno = 0;
    3330           1 :                 g = getgrgid(id);
    3331             : 
    3332           1 :                 if (g)
    3333           1 :                         *groupname = g->gr_name;
    3334             :         } else {
    3335           2 :                 errno = 0;
    3336           2 :                 g = getgrnam(*groupname);
    3337             :         }
    3338             : 
    3339           3 :         if (!g)
    3340           0 :                 return errno > 0 ? -errno : -ESRCH;
    3341             : 
    3342           3 :         if (gid)
    3343           3 :                 *gid = g->gr_gid;
    3344             : 
    3345           3 :         return 0;
    3346             : }
    3347             : 
    3348           0 : int in_gid(gid_t gid) {
    3349             :         gid_t *gids;
    3350             :         int ngroups_max, r, i;
    3351             : 
    3352           0 :         if (getgid() == gid)
    3353           0 :                 return 1;
    3354             : 
    3355           0 :         if (getegid() == gid)
    3356           0 :                 return 1;
    3357             : 
    3358           0 :         ngroups_max = sysconf(_SC_NGROUPS_MAX);
    3359           0 :         assert(ngroups_max > 0);
    3360             : 
    3361           0 :         gids = alloca(sizeof(gid_t) * ngroups_max);
    3362             : 
    3363           0 :         r = getgroups(ngroups_max, gids);
    3364           0 :         if (r < 0)
    3365           0 :                 return -errno;
    3366             : 
    3367           0 :         for (i = 0; i < r; i++)
    3368           0 :                 if (gids[i] == gid)
    3369           0 :                         return 1;
    3370             : 
    3371           0 :         return 0;
    3372             : }
    3373             : 
    3374           0 : int in_group(const char *name) {
    3375             :         int r;
    3376             :         gid_t gid;
    3377             : 
    3378           0 :         r = get_group_creds(&name, &gid);
    3379           0 :         if (r < 0)
    3380           0 :                 return r;
    3381             : 
    3382           0 :         return in_gid(gid);
    3383             : }
    3384             : 
    3385           7 : int glob_exists(const char *path) {
    3386          14 :         _cleanup_globfree_ glob_t g = {};
    3387             :         int k;
    3388             : 
    3389           7 :         assert(path);
    3390             : 
    3391           7 :         errno = 0;
    3392           7 :         k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
    3393             : 
    3394           7 :         if (k == GLOB_NOMATCH)
    3395           3 :                 return 0;
    3396           4 :         else if (k == GLOB_NOSPACE)
    3397           0 :                 return -ENOMEM;
    3398           4 :         else if (k == 0)
    3399           4 :                 return !strv_isempty(g.gl_pathv);
    3400             :         else
    3401           0 :                 return errno ? -errno : -EIO;
    3402             : }
    3403             : 
    3404           0 : int glob_extend(char ***strv, const char *path) {
    3405           0 :         _cleanup_globfree_ glob_t g = {};
    3406             :         int k;
    3407             :         char **p;
    3408             : 
    3409           0 :         errno = 0;
    3410           0 :         k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
    3411             : 
    3412           0 :         if (k == GLOB_NOMATCH)
    3413           0 :                 return -ENOENT;
    3414           0 :         else if (k == GLOB_NOSPACE)
    3415           0 :                 return -ENOMEM;
    3416           0 :         else if (k != 0 || strv_isempty(g.gl_pathv))
    3417           0 :                 return errno ? -errno : -EIO;
    3418             : 
    3419           0 :         STRV_FOREACH(p, g.gl_pathv) {
    3420           0 :                 k = strv_extend(strv, *p);
    3421           0 :                 if (k < 0)
    3422           0 :                         break;
    3423             :         }
    3424             : 
    3425           0 :         return k;
    3426             : }
    3427             : 
    3428        7811 : int dirent_ensure_type(DIR *d, struct dirent *de) {
    3429             :         struct stat st;
    3430             : 
    3431        7811 :         assert(d);
    3432        7811 :         assert(de);
    3433             : 
    3434        7811 :         if (de->d_type != DT_UNKNOWN)
    3435        7811 :                 return 0;
    3436             : 
    3437           0 :         if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
    3438           0 :                 return -errno;
    3439             : 
    3440           0 :         de->d_type =
    3441           0 :                 S_ISREG(st.st_mode)  ? DT_REG  :
    3442           0 :                 S_ISDIR(st.st_mode)  ? DT_DIR  :
    3443           0 :                 S_ISLNK(st.st_mode)  ? DT_LNK  :
    3444           0 :                 S_ISFIFO(st.st_mode) ? DT_FIFO :
    3445           0 :                 S_ISSOCK(st.st_mode) ? DT_SOCK :
    3446           0 :                 S_ISCHR(st.st_mode)  ? DT_CHR  :
    3447           0 :                 S_ISBLK(st.st_mode)  ? DT_BLK  :
    3448             :                                        DT_UNKNOWN;
    3449             : 
    3450           0 :         return 0;
    3451             : }
    3452             : 
    3453           3 : int get_files_in_directory(const char *path, char ***list) {
    3454           6 :         _cleanup_closedir_ DIR *d = NULL;
    3455           3 :         size_t bufsize = 0, n = 0;
    3456           6 :         _cleanup_strv_free_ char **l = NULL;
    3457             : 
    3458           3 :         assert(path);
    3459             : 
    3460             :         /* Returns all files in a directory in *list, and the number
    3461             :          * of files as return value. If list is NULL returns only the
    3462             :          * number. */
    3463             : 
    3464           3 :         d = opendir(path);
    3465           3 :         if (!d)
    3466           0 :                 return -errno;
    3467             : 
    3468             :         for (;;) {
    3469             :                 struct dirent *de;
    3470             : 
    3471         721 :                 errno = 0;
    3472         721 :                 de = readdir(d);
    3473         721 :                 if (!de && errno != 0)
    3474           0 :                         return -errno;
    3475         721 :                 if (!de)
    3476           3 :                         break;
    3477             : 
    3478         718 :                 dirent_ensure_type(d, de);
    3479             : 
    3480         718 :                 if (!dirent_is_file(de))
    3481          86 :                         continue;
    3482             : 
    3483         632 :                 if (list) {
    3484             :                         /* one extra slot is needed for the terminating NULL */
    3485         316 :                         if (!GREEDY_REALLOC(l, bufsize, n + 2))
    3486           0 :                                 return -ENOMEM;
    3487             : 
    3488         316 :                         l[n] = strdup(de->d_name);
    3489         316 :                         if (!l[n])
    3490           0 :                                 return -ENOMEM;
    3491             : 
    3492         316 :                         l[++n] = NULL;
    3493             :                 } else
    3494         316 :                         n++;
    3495         718 :         }
    3496             : 
    3497           3 :         if (list) {
    3498           2 :                 *list = l;
    3499           2 :                 l = NULL; /* avoid freeing */
    3500             :         }
    3501             : 
    3502           3 :         return n;
    3503             : }
    3504             : 
    3505       12647 : char *strjoin(const char *x, ...) {
    3506             :         va_list ap;
    3507             :         size_t l;
    3508             :         char *r, *p;
    3509             : 
    3510       12647 :         va_start(ap, x);
    3511             : 
    3512       12647 :         if (x) {
    3513       12647 :                 l = strlen(x);
    3514             : 
    3515             :                 for (;;) {
    3516             :                         const char *t;
    3517             :                         size_t n;
    3518             : 
    3519       39396 :                         t = va_arg(ap, const char *);
    3520       39396 :                         if (!t)
    3521       12647 :                                 break;
    3522             : 
    3523       26749 :                         n = strlen(t);
    3524       26749 :                         if (n > ((size_t) -1) - l) {
    3525           0 :                                 va_end(ap);
    3526           0 :                                 return NULL;
    3527             :                         }
    3528             : 
    3529       26749 :                         l += n;
    3530       26749 :                 }
    3531             :         } else
    3532           0 :                 l = 0;
    3533             : 
    3534       12647 :         va_end(ap);
    3535             : 
    3536       12647 :         r = new(char, l+1);
    3537       12647 :         if (!r)
    3538           0 :                 return NULL;
    3539             : 
    3540       12647 :         if (x) {
    3541       12647 :                 p = stpcpy(r, x);
    3542             : 
    3543       12647 :                 va_start(ap, x);
    3544             : 
    3545             :                 for (;;) {
    3546             :                         const char *t;
    3547             : 
    3548       39396 :                         t = va_arg(ap, const char *);
    3549       39396 :                         if (!t)
    3550       12647 :                                 break;
    3551             : 
    3552       26749 :                         p = stpcpy(p, t);
    3553       26749 :                 }
    3554             : 
    3555       12647 :                 va_end(ap);
    3556             :         } else
    3557           0 :                 r[0] = 0;
    3558             : 
    3559       12647 :         return r;
    3560             : }
    3561             : 
    3562        7327 : bool is_main_thread(void) {
    3563             :         static thread_local int cached = 0;
    3564             : 
    3565        7327 :         if (_unlikely_(cached == 0))
    3566          55 :                 cached = getpid() == gettid() ? 1 : -1;
    3567             : 
    3568        7327 :         return cached > 0;
    3569             : }
    3570             : 
    3571           0 : int block_get_whole_disk(dev_t d, dev_t *ret) {
    3572             :         char *p, *s;
    3573             :         int r;
    3574             :         unsigned n, m;
    3575             : 
    3576           0 :         assert(ret);
    3577             : 
    3578             :         /* If it has a queue this is good enough for us */
    3579           0 :         if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
    3580           0 :                 return -ENOMEM;
    3581             : 
    3582           0 :         r = access(p, F_OK);
    3583           0 :         free(p);
    3584             : 
    3585           0 :         if (r >= 0) {
    3586           0 :                 *ret = d;
    3587           0 :                 return 0;
    3588             :         }
    3589             : 
    3590             :         /* If it is a partition find the originating device */
    3591           0 :         if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
    3592           0 :                 return -ENOMEM;
    3593             : 
    3594           0 :         r = access(p, F_OK);
    3595           0 :         free(p);
    3596             : 
    3597           0 :         if (r < 0)
    3598           0 :                 return -ENOENT;
    3599             : 
    3600             :         /* Get parent dev_t */
    3601           0 :         if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
    3602           0 :                 return -ENOMEM;
    3603             : 
    3604           0 :         r = read_one_line_file(p, &s);
    3605           0 :         free(p);
    3606             : 
    3607           0 :         if (r < 0)
    3608           0 :                 return r;
    3609             : 
    3610           0 :         r = sscanf(s, "%u:%u", &m, &n);
    3611           0 :         free(s);
    3612             : 
    3613           0 :         if (r != 2)
    3614           0 :                 return -EINVAL;
    3615             : 
    3616             :         /* Only return this if it is really good enough for us. */
    3617           0 :         if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
    3618           0 :                 return -ENOMEM;
    3619             : 
    3620           0 :         r = access(p, F_OK);
    3621           0 :         free(p);
    3622             : 
    3623           0 :         if (r >= 0) {
    3624           0 :                 *ret = makedev(m, n);
    3625           0 :                 return 0;
    3626             :         }
    3627             : 
    3628           0 :         return -ENOENT;
    3629             : }
    3630             : 
    3631             : static const char *const ioprio_class_table[] = {
    3632             :         [IOPRIO_CLASS_NONE] = "none",
    3633             :         [IOPRIO_CLASS_RT] = "realtime",
    3634             :         [IOPRIO_CLASS_BE] = "best-effort",
    3635             :         [IOPRIO_CLASS_IDLE] = "idle"
    3636             : };
    3637             : 
    3638           0 : DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
    3639             : 
    3640             : static const char *const sigchld_code_table[] = {
    3641             :         [CLD_EXITED] = "exited",
    3642             :         [CLD_KILLED] = "killed",
    3643             :         [CLD_DUMPED] = "dumped",
    3644             :         [CLD_TRAPPED] = "trapped",
    3645             :         [CLD_STOPPED] = "stopped",
    3646             :         [CLD_CONTINUED] = "continued",
    3647             : };
    3648             : 
    3649           0 : DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
    3650             : 
    3651             : static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
    3652             :         [LOG_FAC(LOG_KERN)] = "kern",
    3653             :         [LOG_FAC(LOG_USER)] = "user",
    3654             :         [LOG_FAC(LOG_MAIL)] = "mail",
    3655             :         [LOG_FAC(LOG_DAEMON)] = "daemon",
    3656             :         [LOG_FAC(LOG_AUTH)] = "auth",
    3657             :         [LOG_FAC(LOG_SYSLOG)] = "syslog",
    3658             :         [LOG_FAC(LOG_LPR)] = "lpr",
    3659             :         [LOG_FAC(LOG_NEWS)] = "news",
    3660             :         [LOG_FAC(LOG_UUCP)] = "uucp",
    3661             :         [LOG_FAC(LOG_CRON)] = "cron",
    3662             :         [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
    3663             :         [LOG_FAC(LOG_FTP)] = "ftp",
    3664             :         [LOG_FAC(LOG_LOCAL0)] = "local0",
    3665             :         [LOG_FAC(LOG_LOCAL1)] = "local1",
    3666             :         [LOG_FAC(LOG_LOCAL2)] = "local2",
    3667             :         [LOG_FAC(LOG_LOCAL3)] = "local3",
    3668             :         [LOG_FAC(LOG_LOCAL4)] = "local4",
    3669             :         [LOG_FAC(LOG_LOCAL5)] = "local5",
    3670             :         [LOG_FAC(LOG_LOCAL6)] = "local6",
    3671             :         [LOG_FAC(LOG_LOCAL7)] = "local7"
    3672             : };
    3673             : 
    3674           3 : DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
    3675             : 
    3676             : static const char *const log_level_table[] = {
    3677             :         [LOG_EMERG] = "emerg",
    3678             :         [LOG_ALERT] = "alert",
    3679             :         [LOG_CRIT] = "crit",
    3680             :         [LOG_ERR] = "err",
    3681             :         [LOG_WARNING] = "warning",
    3682             :         [LOG_NOTICE] = "notice",
    3683             :         [LOG_INFO] = "info",
    3684             :         [LOG_DEBUG] = "debug"
    3685             : };
    3686             : 
    3687          22 : DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
    3688             : 
    3689             : static const char* const sched_policy_table[] = {
    3690             :         [SCHED_OTHER] = "other",
    3691             :         [SCHED_BATCH] = "batch",
    3692             :         [SCHED_IDLE] = "idle",
    3693             :         [SCHED_FIFO] = "fifo",
    3694             :         [SCHED_RR] = "rr"
    3695             : };
    3696             : 
    3697           3 : DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
    3698             : 
    3699             : static const char* const rlimit_table[_RLIMIT_MAX] = {
    3700             :         [RLIMIT_CPU] = "LimitCPU",
    3701             :         [RLIMIT_FSIZE] = "LimitFSIZE",
    3702             :         [RLIMIT_DATA] = "LimitDATA",
    3703             :         [RLIMIT_STACK] = "LimitSTACK",
    3704             :         [RLIMIT_CORE] = "LimitCORE",
    3705             :         [RLIMIT_RSS] = "LimitRSS",
    3706             :         [RLIMIT_NOFILE] = "LimitNOFILE",
    3707             :         [RLIMIT_AS] = "LimitAS",
    3708             :         [RLIMIT_NPROC] = "LimitNPROC",
    3709             :         [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
    3710             :         [RLIMIT_LOCKS] = "LimitLOCKS",
    3711             :         [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
    3712             :         [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
    3713             :         [RLIMIT_NICE] = "LimitNICE",
    3714             :         [RLIMIT_RTPRIO] = "LimitRTPRIO",
    3715             :         [RLIMIT_RTTIME] = "LimitRTTIME"
    3716             : };
    3717             : 
    3718          36 : DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
    3719             : 
    3720             : static const char* const ip_tos_table[] = {
    3721             :         [IPTOS_LOWDELAY] = "low-delay",
    3722             :         [IPTOS_THROUGHPUT] = "throughput",
    3723             :         [IPTOS_RELIABILITY] = "reliability",
    3724             :         [IPTOS_LOWCOST] = "low-cost",
    3725             : };
    3726             : 
    3727           0 : DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
    3728             : 
    3729           0 : bool kexec_loaded(void) {
    3730           0 :        bool loaded = false;
    3731             :        char *s;
    3732             : 
    3733           0 :        if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
    3734           0 :                if (s[0] == '1')
    3735           0 :                        loaded = true;
    3736           0 :                free(s);
    3737             :        }
    3738           0 :        return loaded;
    3739             : }
    3740             : 
    3741        1365 : int prot_from_flags(int flags) {
    3742             : 
    3743        1365 :         switch (flags & O_ACCMODE) {
    3744             : 
    3745             :         case O_RDONLY:
    3746        1346 :                 return PROT_READ;
    3747             : 
    3748             :         case O_WRONLY:
    3749           0 :                 return PROT_WRITE;
    3750             : 
    3751             :         case O_RDWR:
    3752          19 :                 return PROT_READ|PROT_WRITE;
    3753             : 
    3754             :         default:
    3755           0 :                 return -EINVAL;
    3756             :         }
    3757             : }
    3758             : 
    3759          13 : char *format_bytes(char *buf, size_t l, off_t t) {
    3760             :         unsigned i;
    3761             : 
    3762             :         static const struct {
    3763             :                 const char *suffix;
    3764             :                 off_t factor;
    3765             :         } table[] = {
    3766             :                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
    3767             :                 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
    3768             :                 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
    3769             :                 { "G", 1024ULL*1024ULL*1024ULL },
    3770             :                 { "M", 1024ULL*1024ULL },
    3771             :                 { "K", 1024ULL },
    3772             :         };
    3773             : 
    3774          13 :         if (t == (off_t) -1)
    3775           0 :                 return NULL;
    3776             : 
    3777          73 :         for (i = 0; i < ELEMENTSOF(table); i++) {
    3778             : 
    3779          69 :                 if (t >= table[i].factor) {
    3780          27 :                         snprintf(buf, l,
    3781             :                                  "%llu.%llu%s",
    3782           9 :                                  (unsigned long long) (t / table[i].factor),
    3783           9 :                                  (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
    3784             :                                  table[i].suffix);
    3785             : 
    3786           9 :                         goto finish;
    3787             :                 }
    3788             :         }
    3789             : 
    3790           4 :         snprintf(buf, l, "%lluB", (unsigned long long) t);
    3791             : 
    3792             : finish:
    3793          13 :         buf[l-1] = 0;
    3794          13 :         return buf;
    3795             : 
    3796             : }
    3797             : 
    3798         143 : void* memdup(const void *p, size_t l) {
    3799             :         void *r;
    3800             : 
    3801         143 :         assert(p);
    3802             : 
    3803         143 :         r = malloc(l);
    3804         143 :         if (!r)
    3805           0 :                 return NULL;
    3806             : 
    3807         143 :         memcpy(r, p, l);
    3808         143 :         return r;
    3809             : }
    3810             : 
    3811          20 : int fd_inc_sndbuf(int fd, size_t n) {
    3812             :         int r, value;
    3813          20 :         socklen_t l = sizeof(value);
    3814             : 
    3815          20 :         r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
    3816          20 :         if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
    3817           0 :                 return 0;
    3818             : 
    3819             :         /* If we have the privileges we will ignore the kernel limit. */
    3820             : 
    3821          20 :         value = (int) n;
    3822          20 :         if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
    3823          20 :                 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
    3824           0 :                         return -errno;
    3825             : 
    3826          20 :         return 1;
    3827             : }
    3828             : 
    3829          20 : int fd_inc_rcvbuf(int fd, size_t n) {
    3830             :         int r, value;
    3831          20 :         socklen_t l = sizeof(value);
    3832             : 
    3833          20 :         r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
    3834          20 :         if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
    3835           0 :                 return 0;
    3836             : 
    3837             :         /* If we have the privileges we will ignore the kernel limit. */
    3838             : 
    3839          20 :         value = (int) n;
    3840          20 :         if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
    3841          20 :                 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
    3842           0 :                         return -errno;
    3843          20 :         return 1;
    3844             : }
    3845             : 
    3846           0 : int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
    3847             :         bool stdout_is_tty, stderr_is_tty;
    3848             :         pid_t parent_pid, agent_pid;
    3849             :         sigset_t ss, saved_ss;
    3850             :         unsigned n, i;
    3851             :         va_list ap;
    3852             :         char **l;
    3853             : 
    3854           0 :         assert(pid);
    3855           0 :         assert(path);
    3856             : 
    3857             :         /* Spawns a temporary TTY agent, making sure it goes away when
    3858             :          * we go away */
    3859             : 
    3860           0 :         parent_pid = getpid();
    3861             : 
    3862             :         /* First we temporarily block all signals, so that the new
    3863             :          * child has them blocked initially. This way, we can be sure
    3864             :          * that SIGTERMs are not lost we might send to the agent. */
    3865           0 :         assert_se(sigfillset(&ss) >= 0);
    3866           0 :         assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
    3867             : 
    3868           0 :         agent_pid = fork();
    3869           0 :         if (agent_pid < 0) {
    3870           0 :                 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
    3871           0 :                 return -errno;
    3872             :         }
    3873             : 
    3874           0 :         if (agent_pid != 0) {
    3875           0 :                 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
    3876           0 :                 *pid = agent_pid;
    3877           0 :                 return 0;
    3878             :         }
    3879             : 
    3880             :         /* In the child:
    3881             :          *
    3882             :          * Make sure the agent goes away when the parent dies */
    3883           0 :         if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
    3884           0 :                 _exit(EXIT_FAILURE);
    3885             : 
    3886             :         /* Make sure we actually can kill the agent, if we need to, in
    3887             :          * case somebody invoked us from a shell script that trapped
    3888             :          * SIGTERM or so... */
    3889           0 :         (void) reset_all_signal_handlers();
    3890           0 :         (void) reset_signal_mask();
    3891             : 
    3892             :         /* Check whether our parent died before we were able
    3893             :          * to set the death signal and unblock the signals */
    3894           0 :         if (getppid() != parent_pid)
    3895           0 :                 _exit(EXIT_SUCCESS);
    3896             : 
    3897             :         /* Don't leak fds to the agent */
    3898           0 :         close_all_fds(except, n_except);
    3899             : 
    3900           0 :         stdout_is_tty = isatty(STDOUT_FILENO);
    3901           0 :         stderr_is_tty = isatty(STDERR_FILENO);
    3902             : 
    3903           0 :         if (!stdout_is_tty || !stderr_is_tty) {
    3904             :                 int fd;
    3905             : 
    3906             :                 /* Detach from stdout/stderr. and reopen
    3907             :                  * /dev/tty for them. This is important to
    3908             :                  * ensure that when systemctl is started via
    3909             :                  * popen() or a similar call that expects to
    3910             :                  * read EOF we actually do generate EOF and
    3911             :                  * not delay this indefinitely by because we
    3912             :                  * keep an unused copy of stdin around. */
    3913           0 :                 fd = open("/dev/tty", O_WRONLY);
    3914           0 :                 if (fd < 0) {
    3915           0 :                         log_error_errno(errno, "Failed to open /dev/tty: %m");
    3916           0 :                         _exit(EXIT_FAILURE);
    3917             :                 }
    3918             : 
    3919           0 :                 if (!stdout_is_tty)
    3920           0 :                         dup2(fd, STDOUT_FILENO);
    3921             : 
    3922           0 :                 if (!stderr_is_tty)
    3923           0 :                         dup2(fd, STDERR_FILENO);
    3924             : 
    3925           0 :                 if (fd > 2)
    3926           0 :                         close(fd);
    3927             :         }
    3928             : 
    3929             :         /* Count arguments */
    3930           0 :         va_start(ap, path);
    3931           0 :         for (n = 0; va_arg(ap, char*); n++)
    3932             :                 ;
    3933           0 :         va_end(ap);
    3934             : 
    3935             :         /* Allocate strv */
    3936           0 :         l = alloca(sizeof(char *) * (n + 1));
    3937             : 
    3938             :         /* Fill in arguments */
    3939           0 :         va_start(ap, path);
    3940           0 :         for (i = 0; i <= n; i++)
    3941           0 :                 l[i] = va_arg(ap, char*);
    3942           0 :         va_end(ap);
    3943             : 
    3944           0 :         execv(path, l);
    3945           0 :         _exit(EXIT_FAILURE);
    3946             : }
    3947             : 
    3948           0 : int setrlimit_closest(int resource, const struct rlimit *rlim) {
    3949             :         struct rlimit highest, fixed;
    3950             : 
    3951           0 :         assert(rlim);
    3952             : 
    3953           0 :         if (setrlimit(resource, rlim) >= 0)
    3954           0 :                 return 0;
    3955             : 
    3956           0 :         if (errno != EPERM)
    3957           0 :                 return -errno;
    3958             : 
    3959             :         /* So we failed to set the desired setrlimit, then let's try
    3960             :          * to get as close as we can */
    3961           0 :         assert_se(getrlimit(resource, &highest) == 0);
    3962             : 
    3963           0 :         fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
    3964           0 :         fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
    3965             : 
    3966           0 :         if (setrlimit(resource, &fixed) < 0)
    3967           0 :                 return -errno;
    3968             : 
    3969           0 :         return 0;
    3970             : }
    3971             : 
    3972           0 : bool http_etag_is_valid(const char *etag) {
    3973           0 :         if (isempty(etag))
    3974           0 :                 return false;
    3975             : 
    3976           0 :         if (!endswith(etag, "\""))
    3977           0 :                 return false;
    3978             : 
    3979           0 :         if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
    3980           0 :                 return false;
    3981             : 
    3982           0 :         return true;
    3983             : }
    3984             : 
    3985          67 : bool http_url_is_valid(const char *url) {
    3986             :         const char *p;
    3987             : 
    3988          67 :         if (isempty(url))
    3989           0 :                 return false;
    3990             : 
    3991          67 :         p = startswith(url, "http://");
    3992          67 :         if (!p)
    3993          66 :                 p = startswith(url, "https://");
    3994          67 :         if (!p)
    3995          65 :                 return false;
    3996             : 
    3997           2 :         if (isempty(p))
    3998           0 :                 return false;
    3999             : 
    4000           2 :         return ascii_is_valid(p);
    4001             : }
    4002             : 
    4003          68 : bool documentation_url_is_valid(const char *url) {
    4004             :         const char *p;
    4005             : 
    4006          68 :         if (isempty(url))
    4007           1 :                 return false;
    4008             : 
    4009          67 :         if (http_url_is_valid(url))
    4010           2 :                 return true;
    4011             : 
    4012          65 :         p = startswith(url, "file:/");
    4013          65 :         if (!p)
    4014          64 :                 p = startswith(url, "info:");
    4015          65 :         if (!p)
    4016          62 :                 p = startswith(url, "man:");
    4017             : 
    4018          65 :         if (isempty(p))
    4019           2 :                 return false;
    4020             : 
    4021          63 :         return ascii_is_valid(p);
    4022             : }
    4023             : 
    4024          35 : bool in_initrd(void) {
    4025             :         static int saved = -1;
    4026             :         struct statfs s;
    4027             : 
    4028          35 :         if (saved >= 0)
    4029          30 :                 return saved;
    4030             : 
    4031             :         /* We make two checks here:
    4032             :          *
    4033             :          * 1. the flag file /etc/initrd-release must exist
    4034             :          * 2. the root file system must be a memory file system
    4035             :          *
    4036             :          * The second check is extra paranoia, since misdetecting an
    4037             :          * initrd can have bad bad consequences due the initrd
    4038             :          * emptying when transititioning to the main systemd.
    4039             :          */
    4040             : 
    4041          10 :         saved = access("/etc/initrd-release", F_OK) >= 0 &&
    4042           5 :                 statfs("/", &s) >= 0 &&
    4043           0 :                 is_temporary_fs(&s);
    4044             : 
    4045           5 :         return saved;
    4046             : }
    4047             : 
    4048         105 : int get_home_dir(char **_h) {
    4049             :         struct passwd *p;
    4050             :         const char *e;
    4051             :         char *h;
    4052             :         uid_t u;
    4053             : 
    4054         105 :         assert(_h);
    4055             : 
    4056             :         /* Take the user specified one */
    4057         105 :         e = secure_getenv("HOME");
    4058         105 :         if (e && path_is_absolute(e)) {
    4059         105 :                 h = strdup(e);
    4060         105 :                 if (!h)
    4061           0 :                         return -ENOMEM;
    4062             : 
    4063         105 :                 *_h = h;
    4064         105 :                 return 0;
    4065             :         }
    4066             : 
    4067             :         /* Hardcode home directory for root to avoid NSS */
    4068           0 :         u = getuid();
    4069           0 :         if (u == 0) {
    4070           0 :                 h = strdup("/root");
    4071           0 :                 if (!h)
    4072           0 :                         return -ENOMEM;
    4073             : 
    4074           0 :                 *_h = h;
    4075           0 :                 return 0;
    4076             :         }
    4077             : 
    4078             :         /* Check the database... */
    4079           0 :         errno = 0;
    4080           0 :         p = getpwuid(u);
    4081           0 :         if (!p)
    4082           0 :                 return errno > 0 ? -errno : -ESRCH;
    4083             : 
    4084           0 :         if (!path_is_absolute(p->pw_dir))
    4085           0 :                 return -EINVAL;
    4086             : 
    4087           0 :         h = strdup(p->pw_dir);
    4088           0 :         if (!h)
    4089           0 :                 return -ENOMEM;
    4090             : 
    4091           0 :         *_h = h;
    4092           0 :         return 0;
    4093             : }
    4094             : 
    4095           0 : int get_shell(char **_s) {
    4096             :         struct passwd *p;
    4097             :         const char *e;
    4098             :         char *s;
    4099             :         uid_t u;
    4100             : 
    4101           0 :         assert(_s);
    4102             : 
    4103             :         /* Take the user specified one */
    4104           0 :         e = getenv("SHELL");
    4105           0 :         if (e) {
    4106           0 :                 s = strdup(e);
    4107           0 :                 if (!s)
    4108           0 :                         return -ENOMEM;
    4109             : 
    4110           0 :                 *_s = s;
    4111           0 :                 return 0;
    4112             :         }
    4113             : 
    4114             :         /* Hardcode home directory for root to avoid NSS */
    4115           0 :         u = getuid();
    4116           0 :         if (u == 0) {
    4117           0 :                 s = strdup("/bin/sh");
    4118           0 :                 if (!s)
    4119           0 :                         return -ENOMEM;
    4120             : 
    4121           0 :                 *_s = s;
    4122           0 :                 return 0;
    4123             :         }
    4124             : 
    4125             :         /* Check the database... */
    4126           0 :         errno = 0;
    4127           0 :         p = getpwuid(u);
    4128           0 :         if (!p)
    4129           0 :                 return errno > 0 ? -errno : -ESRCH;
    4130             : 
    4131           0 :         if (!path_is_absolute(p->pw_shell))
    4132           0 :                 return -EINVAL;
    4133             : 
    4134           0 :         s = strdup(p->pw_shell);
    4135           0 :         if (!s)
    4136           0 :                 return -ENOMEM;
    4137             : 
    4138           0 :         *_s = s;
    4139           0 :         return 0;
    4140             : }
    4141             : 
    4142         120 : bool filename_is_valid(const char *p) {
    4143             : 
    4144         120 :         if (isempty(p))
    4145           1 :                 return false;
    4146             : 
    4147         119 :         if (strchr(p, '/'))
    4148           3 :                 return false;
    4149             : 
    4150         116 :         if (streq(p, "."))
    4151           1 :                 return false;
    4152             : 
    4153         115 :         if (streq(p, ".."))
    4154           1 :                 return false;
    4155             : 
    4156         114 :         if (strlen(p) > FILENAME_MAX)
    4157           1 :                 return false;
    4158             : 
    4159         113 :         return true;
    4160             : }
    4161             : 
    4162          83 : bool string_is_safe(const char *p) {
    4163             :         const char *t;
    4164             : 
    4165          83 :         if (!p)
    4166           0 :                 return false;
    4167             : 
    4168         908 :         for (t = p; *t; t++) {
    4169         838 :                 if (*t > 0 && *t < ' ')
    4170           8 :                         return false;
    4171             : 
    4172         830 :                 if (strchr("\\\"\'\x7f", *t))
    4173           5 :                         return false;
    4174             :         }
    4175             : 
    4176          70 :         return true;
    4177             : }
    4178             : 
    4179             : /**
    4180             :  * Check if a string contains control characters. If 'ok' is non-NULL
    4181             :  * it may be a string containing additional CCs to be considered OK.
    4182             :  */
    4183          49 : bool string_has_cc(const char *p, const char *ok) {
    4184             :         const char *t;
    4185             : 
    4186          49 :         assert(p);
    4187             : 
    4188         340 :         for (t = p; *t; t++) {
    4189         303 :                 if (ok && strchr(ok, *t))
    4190           9 :                         continue;
    4191             : 
    4192         294 :                 if (*t > 0 && *t < ' ')
    4193           6 :                         return true;
    4194             : 
    4195         288 :                 if (*t == 127)
    4196           6 :                         return true;
    4197             :         }
    4198             : 
    4199          37 :         return false;
    4200             : }
    4201             : 
    4202        1339 : bool path_is_safe(const char *p) {
    4203             : 
    4204        1339 :         if (isempty(p))
    4205           0 :                 return false;
    4206             : 
    4207        1339 :         if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
    4208           4 :                 return false;
    4209             : 
    4210        1335 :         if (strlen(p)+1 > PATH_MAX)
    4211           0 :                 return false;
    4212             : 
    4213             :         /* The following two checks are not really dangerous, but hey, they still are confusing */
    4214        1335 :         if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
    4215           2 :                 return false;
    4216             : 
    4217        1333 :         if (strstr(p, "//"))
    4218           1 :                 return false;
    4219             : 
    4220        1332 :         return true;
    4221             : }
    4222             : 
    4223             : /* hey glibc, APIs with callbacks without a user pointer are so useless */
    4224           0 : void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
    4225             :                  int (*compar) (const void *, const void *, void *), void *arg) {
    4226             :         size_t l, u, idx;
    4227             :         const void *p;
    4228             :         int comparison;
    4229             : 
    4230           0 :         l = 0;
    4231           0 :         u = nmemb;
    4232           0 :         while (l < u) {
    4233           0 :                 idx = (l + u) / 2;
    4234           0 :                 p = (void *)(((const char *) base) + (idx * size));
    4235           0 :                 comparison = compar(key, p, arg);
    4236           0 :                 if (comparison < 0)
    4237           0 :                         u = idx;
    4238           0 :                 else if (comparison > 0)
    4239           0 :                         l = idx + 1;
    4240             :                 else
    4241           0 :                         return (void *)p;
    4242             :         }
    4243           0 :         return NULL;
    4244             : }
    4245             : 
    4246           0 : void init_gettext(void) {
    4247           0 :         setlocale(LC_ALL, "");
    4248           0 :         textdomain(GETTEXT_PACKAGE);
    4249           0 : }
    4250             : 
    4251          61 : bool is_locale_utf8(void) {
    4252             :         const char *set;
    4253             :         static int cached_answer = -1;
    4254             : 
    4255          61 :         if (cached_answer >= 0)
    4256          55 :                 goto out;
    4257             : 
    4258           6 :         if (!setlocale(LC_ALL, "")) {
    4259           0 :                 cached_answer = true;
    4260           0 :                 goto out;
    4261             :         }
    4262             : 
    4263           6 :         set = nl_langinfo(CODESET);
    4264           6 :         if (!set) {
    4265           0 :                 cached_answer = true;
    4266           0 :                 goto out;
    4267             :         }
    4268             : 
    4269           6 :         if (streq(set, "UTF-8")) {
    4270           6 :                 cached_answer = true;
    4271           6 :                 goto out;
    4272             :         }
    4273             : 
    4274             :         /* For LC_CTYPE=="C" return true, because CTYPE is effectly
    4275             :          * unset and everything can do to UTF-8 nowadays. */
    4276           0 :         set = setlocale(LC_CTYPE, NULL);
    4277           0 :         if (!set) {
    4278           0 :                 cached_answer = true;
    4279           0 :                 goto out;
    4280             :         }
    4281             : 
    4282             :         /* Check result, but ignore the result if C was set
    4283             :          * explicitly. */
    4284           0 :         cached_answer =
    4285           0 :                 streq(set, "C") &&
    4286           0 :                 !getenv("LC_ALL") &&
    4287           0 :                 !getenv("LC_CTYPE") &&
    4288           0 :                 !getenv("LANG");
    4289             : 
    4290             : out:
    4291          61 :         return (bool) cached_answer;
    4292             : }
    4293             : 
    4294          61 : const char *draw_special_char(DrawSpecialChar ch) {
    4295             :         static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
    4296             : 
    4297             :                 /* UTF-8 */ {
    4298             :                         [DRAW_TREE_VERTICAL]      = "\342\224\202 ",            /* │  */
    4299             :                         [DRAW_TREE_BRANCH]        = "\342\224\234\342\224\200", /* ├─ */
    4300             :                         [DRAW_TREE_RIGHT]         = "\342\224\224\342\224\200", /* └─ */
    4301             :                         [DRAW_TREE_SPACE]         = "  ",                       /*    */
    4302             :                         [DRAW_TRIANGULAR_BULLET]  = "\342\200\243",             /* ‣ */
    4303             :                         [DRAW_BLACK_CIRCLE]       = "\342\227\217",             /* ● */
    4304             :                         [DRAW_ARROW]              = "\342\206\222",             /* → */
    4305             :                         [DRAW_DASH]               = "\342\200\223",             /* – */
    4306             :                 },
    4307             : 
    4308             :                 /* ASCII fallback */ {
    4309             :                         [DRAW_TREE_VERTICAL]      = "| ",
    4310             :                         [DRAW_TREE_BRANCH]        = "|-",
    4311             :                         [DRAW_TREE_RIGHT]         = "`-",
    4312             :                         [DRAW_TREE_SPACE]         = "  ",
    4313             :                         [DRAW_TRIANGULAR_BULLET]  = ">",
    4314             :                         [DRAW_BLACK_CIRCLE]       = "*",
    4315             :                         [DRAW_ARROW]              = "->",
    4316             :                         [DRAW_DASH]               = "-",
    4317             :                 }
    4318             :         };
    4319             : 
    4320          61 :         return draw_table[!is_locale_utf8()][ch];
    4321             : }
    4322             : 
    4323           6 : char *strreplace(const char *text, const char *old_string, const char *new_string) {
    4324             :         const char *f;
    4325             :         char *t, *r;
    4326             :         size_t l, old_len, new_len;
    4327             : 
    4328           6 :         assert(text);
    4329           6 :         assert(old_string);
    4330           6 :         assert(new_string);
    4331             : 
    4332           6 :         old_len = strlen(old_string);
    4333           6 :         new_len = strlen(new_string);
    4334             : 
    4335           6 :         l = strlen(text);
    4336           6 :         r = new(char, l+1);
    4337           6 :         if (!r)
    4338           0 :                 return NULL;
    4339             : 
    4340           6 :         f = text;
    4341           6 :         t = r;
    4342         101 :         while (*f) {
    4343             :                 char *a;
    4344             :                 size_t d, nl;
    4345             : 
    4346          89 :                 if (!startswith(f, old_string)) {
    4347          81 :                         *(t++) = *(f++);
    4348          81 :                         continue;
    4349             :                 }
    4350             : 
    4351           8 :                 d = t - r;
    4352           8 :                 nl = l - old_len + new_len;
    4353           8 :                 a = realloc(r, nl + 1);
    4354           8 :                 if (!a)
    4355           0 :                         goto oom;
    4356             : 
    4357           8 :                 l = nl;
    4358           8 :                 r = a;
    4359           8 :                 t = r + d;
    4360             : 
    4361           8 :                 t = stpcpy(t, new_string);
    4362           8 :                 f += old_len;
    4363             :         }
    4364             : 
    4365           6 :         *t = 0;
    4366           6 :         return r;
    4367             : 
    4368             : oom:
    4369           0 :         free(r);
    4370           0 :         return NULL;
    4371             : }
    4372             : 
    4373           4 : char *strip_tab_ansi(char **ibuf, size_t *_isz) {
    4374           4 :         const char *i, *begin = NULL;
    4375             :         enum {
    4376             :                 STATE_OTHER,
    4377             :                 STATE_ESCAPE,
    4378             :                 STATE_BRACKET
    4379           4 :         } state = STATE_OTHER;
    4380           4 :         char *obuf = NULL;
    4381           4 :         size_t osz = 0, isz;
    4382             :         FILE *f;
    4383             : 
    4384           4 :         assert(ibuf);
    4385           4 :         assert(*ibuf);
    4386             : 
    4387             :         /* Strips ANSI color and replaces TABs by 8 spaces */
    4388             : 
    4389           4 :         isz = _isz ? *_isz : strlen(*ibuf);
    4390             : 
    4391           4 :         f = open_memstream(&obuf, &osz);
    4392           4 :         if (!f)
    4393           0 :                 return NULL;
    4394             : 
    4395         115 :         for (i = *ibuf; i < *ibuf + isz + 1; i++) {
    4396             : 
    4397         111 :                 switch (state) {
    4398             : 
    4399             :                 case STATE_OTHER:
    4400          65 :                         if (i >= *ibuf + isz) /* EOT */
    4401           4 :                                 break;
    4402          61 :                         else if (*i == '\x1B')
    4403          13 :                                 state = STATE_ESCAPE;
    4404          48 :                         else if (*i == '\t')
    4405           5 :                                 fputs("        ", f);
    4406             :                         else
    4407          43 :                                 fputc(*i, f);
    4408          61 :                         break;
    4409             : 
    4410             :                 case STATE_ESCAPE:
    4411          13 :                         if (i >= *ibuf + isz) { /* EOT */
    4412           0 :                                 fputc('\x1B', f);
    4413           0 :                                 break;
    4414          13 :                         } else if (*i == '[') {
    4415          13 :                                 state = STATE_BRACKET;
    4416          13 :                                 begin = i + 1;
    4417             :                         } else {
    4418           0 :                                 fputc('\x1B', f);
    4419           0 :                                 fputc(*i, f);
    4420           0 :                                 state = STATE_OTHER;
    4421             :                         }
    4422             : 
    4423          13 :                         break;
    4424             : 
    4425             :                 case STATE_BRACKET:
    4426             : 
    4427          66 :                         if (i >= *ibuf + isz || /* EOT */
    4428          63 :                             (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
    4429           5 :                                 fputc('\x1B', f);
    4430           5 :                                 fputc('[', f);
    4431           5 :                                 state = STATE_OTHER;
    4432           5 :                                 i = begin-1;
    4433          28 :                         } else if (*i == 'm')
    4434           8 :                                 state = STATE_OTHER;
    4435          33 :                         break;
    4436             :                 }
    4437             :         }
    4438             : 
    4439           4 :         if (ferror(f)) {
    4440           0 :                 fclose(f);
    4441           0 :                 free(obuf);
    4442           0 :                 return NULL;
    4443             :         }
    4444             : 
    4445           4 :         fclose(f);
    4446             : 
    4447           4 :         free(*ibuf);
    4448           4 :         *ibuf = obuf;
    4449             : 
    4450           4 :         if (_isz)
    4451           0 :                 *_isz = osz;
    4452             : 
    4453           4 :         return obuf;
    4454             : }
    4455             : 
    4456           6 : int on_ac_power(void) {
    4457           6 :         bool found_offline = false, found_online = false;
    4458          12 :         _cleanup_closedir_ DIR *d = NULL;
    4459             : 
    4460           6 :         d = opendir("/sys/class/power_supply");
    4461           6 :         if (!d)
    4462           0 :                 return errno == ENOENT ? true : -errno;
    4463             : 
    4464             :         for (;;) {
    4465             :                 struct dirent *de;
    4466          72 :                 _cleanup_close_ int fd = -1, device = -1;
    4467             :                 char contents[6];
    4468             :                 ssize_t n;
    4469             : 
    4470          36 :                 errno = 0;
    4471          36 :                 de = readdir(d);
    4472          36 :                 if (!de && errno != 0)
    4473           0 :                         return -errno;
    4474             : 
    4475          36 :                 if (!de)
    4476           6 :                         break;
    4477             : 
    4478          30 :                 if (hidden_file(de->d_name))
    4479          12 :                         continue;
    4480             : 
    4481          18 :                 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
    4482          18 :                 if (device < 0) {
    4483           0 :                         if (errno == ENOENT || errno == ENOTDIR)
    4484           0 :                                 continue;
    4485             : 
    4486           0 :                         return -errno;
    4487             :                 }
    4488             : 
    4489          18 :                 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
    4490          18 :                 if (fd < 0) {
    4491           0 :                         if (errno == ENOENT)
    4492           0 :                                 continue;
    4493             : 
    4494           0 :                         return -errno;
    4495             :                 }
    4496             : 
    4497          18 :                 n = read(fd, contents, sizeof(contents));
    4498          18 :                 if (n < 0)
    4499           0 :                         return -errno;
    4500             : 
    4501          18 :                 if (n != 6 || memcmp(contents, "Mains\n", 6))
    4502          12 :                         continue;
    4503             : 
    4504           6 :                 safe_close(fd);
    4505           6 :                 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
    4506           6 :                 if (fd < 0) {
    4507           0 :                         if (errno == ENOENT)
    4508           0 :                                 continue;
    4509             : 
    4510           0 :                         return -errno;
    4511             :                 }
    4512             : 
    4513           6 :                 n = read(fd, contents, sizeof(contents));
    4514           6 :                 if (n < 0)
    4515           0 :                         return -errno;
    4516             : 
    4517           6 :                 if (n != 2 || contents[1] != '\n')
    4518           0 :                         return -EIO;
    4519             : 
    4520           6 :                 if (contents[0] == '1') {
    4521           0 :                         found_online = true;
    4522           0 :                         break;
    4523           6 :                 } else if (contents[0] == '0')
    4524           6 :                         found_offline = true;
    4525             :                 else
    4526           0 :                         return -EIO;
    4527          30 :         }
    4528             : 
    4529          12 :         return found_online || !found_offline;
    4530             : }
    4531             : 
    4532           7 : static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
    4533             :         char **i;
    4534             : 
    4535           7 :         assert(path);
    4536           7 :         assert(mode);
    4537           7 :         assert(_f);
    4538             : 
    4539           7 :         if (!path_strv_resolve_uniq(search, root))
    4540           0 :                 return -ENOMEM;
    4541             : 
    4542          18 :         STRV_FOREACH(i, search) {
    4543          28 :                 _cleanup_free_ char *p = NULL;
    4544             :                 FILE *f;
    4545             : 
    4546          14 :                 if (root)
    4547           2 :                         p = strjoin(root, *i, "/", path, NULL);
    4548             :                 else
    4549          12 :                         p = strjoin(*i, "/", path, NULL);
    4550          14 :                 if (!p)
    4551           0 :                         return -ENOMEM;
    4552             : 
    4553          14 :                 f = fopen(p, mode);
    4554          14 :                 if (f) {
    4555           3 :                         *_f = f;
    4556           3 :                         return 0;
    4557             :                 }
    4558             : 
    4559          11 :                 if (errno != ENOENT)
    4560           0 :                         return -errno;
    4561             :         }
    4562             : 
    4563           4 :         return -ENOENT;
    4564             : }
    4565             : 
    4566           6 : int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
    4567          12 :         _cleanup_strv_free_ char **copy = NULL;
    4568             : 
    4569           6 :         assert(path);
    4570           6 :         assert(mode);
    4571           6 :         assert(_f);
    4572             : 
    4573           6 :         if (path_is_absolute(path)) {
    4574             :                 FILE *f;
    4575             : 
    4576           2 :                 f = fopen(path, mode);
    4577           2 :                 if (f) {
    4578           1 :                         *_f = f;
    4579           1 :                         return 0;
    4580             :                 }
    4581             : 
    4582           1 :                 return -errno;
    4583             :         }
    4584             : 
    4585           4 :         copy = strv_copy((char**) search);
    4586           4 :         if (!copy)
    4587           0 :                 return -ENOMEM;
    4588             : 
    4589           4 :         return search_and_fopen_internal(path, mode, root, copy, _f);
    4590             : }
    4591             : 
    4592           5 : int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
    4593          10 :         _cleanup_strv_free_ char **s = NULL;
    4594             : 
    4595           5 :         if (path_is_absolute(path)) {
    4596             :                 FILE *f;
    4597             : 
    4598           2 :                 f = fopen(path, mode);
    4599           2 :                 if (f) {
    4600           1 :                         *_f = f;
    4601           1 :                         return 0;
    4602             :                 }
    4603             : 
    4604           1 :                 return -errno;
    4605             :         }
    4606             : 
    4607           3 :         s = strv_split_nulstr(search);
    4608           3 :         if (!s)
    4609           0 :                 return -ENOMEM;
    4610             : 
    4611           3 :         return search_and_fopen_internal(path, mode, root, s, _f);
    4612             : }
    4613             : 
    4614         168 : char *strextend(char **x, ...) {
    4615             :         va_list ap;
    4616             :         size_t f, l;
    4617             :         char *r, *p;
    4618             : 
    4619         168 :         assert(x);
    4620             : 
    4621         168 :         l = f = *x ? strlen(*x) : 0;
    4622             : 
    4623         168 :         va_start(ap, x);
    4624             :         for (;;) {
    4625             :                 const char *t;
    4626             :                 size_t n;
    4627             : 
    4628         393 :                 t = va_arg(ap, const char *);
    4629         393 :                 if (!t)
    4630         168 :                         break;
    4631             : 
    4632         225 :                 n = strlen(t);
    4633         225 :                 if (n > ((size_t) -1) - l) {
    4634           0 :                         va_end(ap);
    4635           0 :                         return NULL;
    4636             :                 }
    4637             : 
    4638         225 :                 l += n;
    4639         225 :         }
    4640         168 :         va_end(ap);
    4641             : 
    4642         168 :         r = realloc(*x, l+1);
    4643         168 :         if (!r)
    4644           0 :                 return NULL;
    4645             : 
    4646         168 :         p = r + f;
    4647             : 
    4648         168 :         va_start(ap, x);
    4649             :         for (;;) {
    4650             :                 const char *t;
    4651             : 
    4652         393 :                 t = va_arg(ap, const char *);
    4653         393 :                 if (!t)
    4654         168 :                         break;
    4655             : 
    4656         225 :                 p = stpcpy(p, t);
    4657         225 :         }
    4658         168 :         va_end(ap);
    4659             : 
    4660         168 :         *p = 0;
    4661         168 :         *x = r;
    4662             : 
    4663         168 :         return r + l;
    4664             : }
    4665             : 
    4666         127 : char *strrep(const char *s, unsigned n) {
    4667             :         size_t l;
    4668             :         char *r, *p;
    4669             :         unsigned i;
    4670             : 
    4671         127 :         assert(s);
    4672             : 
    4673         127 :         l = strlen(s);
    4674         127 :         p = r = malloc(l * n + 1);
    4675         127 :         if (!r)
    4676           0 :                 return NULL;
    4677             : 
    4678         616 :         for (i = 0; i < n; i++)
    4679         489 :                 p = stpcpy(p, s);
    4680             : 
    4681         127 :         *p = 0;
    4682         127 :         return r;
    4683             : }
    4684             : 
    4685      137969 : void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
    4686             :         size_t a, newalloc;
    4687             :         void *q;
    4688             : 
    4689      137969 :         assert(p);
    4690      137969 :         assert(allocated);
    4691             : 
    4692      137969 :         if (*allocated >= need)
    4693      121384 :                 return *p;
    4694             : 
    4695       16585 :         newalloc = MAX(need * 2, 64u / size);
    4696       16585 :         a = newalloc * size;
    4697             : 
    4698             :         /* check for overflows */
    4699       16585 :         if (a < size * need)
    4700           0 :                 return NULL;
    4701             : 
    4702       16585 :         q = realloc(*p, a);
    4703       16585 :         if (!q)
    4704           0 :                 return NULL;
    4705             : 
    4706       16585 :         *p = q;
    4707       16585 :         *allocated = newalloc;
    4708       16585 :         return q;
    4709             : }
    4710             : 
    4711          11 : void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
    4712             :         size_t prev;
    4713             :         uint8_t *q;
    4714             : 
    4715          11 :         assert(p);
    4716          11 :         assert(allocated);
    4717             : 
    4718          11 :         prev = *allocated;
    4719             : 
    4720          11 :         q = greedy_realloc(p, allocated, need, size);
    4721          11 :         if (!q)
    4722           0 :                 return NULL;
    4723             : 
    4724          11 :         if (*allocated > prev)
    4725           4 :                 memzero(q + prev * size, (*allocated - prev) * size);
    4726             : 
    4727          11 :         return q;
    4728             : }
    4729             : 
    4730           7 : bool id128_is_valid(const char *s) {
    4731             :         size_t i, l;
    4732             : 
    4733           7 :         l = strlen(s);
    4734           7 :         if (l == 32) {
    4735             : 
    4736             :                 /* Simple formatted 128bit hex string */
    4737             : 
    4738          33 :                 for (i = 0; i < l; i++) {
    4739          32 :                         char c = s[i];
    4740             : 
    4741          32 :                         if (!(c >= '0' && c <= '9') &&
    4742           6 :                             !(c >= 'a' && c <= 'z') &&
    4743           0 :                             !(c >= 'A' && c <= 'Z'))
    4744           0 :                                 return false;
    4745             :                 }
    4746             : 
    4747           6 :         } else if (l == 36) {
    4748             : 
    4749             :                 /* Formatted UUID */
    4750             : 
    4751          37 :                 for (i = 0; i < l; i++) {
    4752          36 :                         char c = s[i];
    4753             : 
    4754          36 :                         if ((i == 8 || i == 13 || i == 18 || i == 23)) {
    4755           8 :                                 if (c != '-')
    4756           0 :                                         return false;
    4757             :                         } else {
    4758          32 :                                 if (!(c >= '0' && c <= '9') &&
    4759           6 :                                     !(c >= 'a' && c <= 'z') &&
    4760           0 :                                     !(c >= 'A' && c <= 'Z'))
    4761           0 :                                         return false;
    4762             :                         }
    4763             :                 }
    4764             : 
    4765             :         } else
    4766           5 :                 return false;
    4767             : 
    4768           2 :         return true;
    4769             : }
    4770             : 
    4771           6 : int split_pair(const char *s, const char *sep, char **l, char **r) {
    4772             :         char *x, *a, *b;
    4773             : 
    4774           6 :         assert(s);
    4775           6 :         assert(sep);
    4776           6 :         assert(l);
    4777           6 :         assert(r);
    4778             : 
    4779           6 :         if (isempty(sep))
    4780           2 :                 return -EINVAL;
    4781             : 
    4782           4 :         x = strstr(s, sep);
    4783           4 :         if (!x)
    4784           1 :                 return -EINVAL;
    4785             : 
    4786           3 :         a = strndup(s, x - s);
    4787           3 :         if (!a)
    4788           0 :                 return -ENOMEM;
    4789             : 
    4790           3 :         b = strdup(x + strlen(sep));
    4791           3 :         if (!b) {
    4792           0 :                 free(a);
    4793           0 :                 return -ENOMEM;
    4794             :         }
    4795             : 
    4796           3 :         *l = a;
    4797           3 :         *r = b;
    4798             : 
    4799           3 :         return 0;
    4800             : }
    4801             : 
    4802           0 : int shall_restore_state(void) {
    4803           0 :         _cleanup_free_ char *value = NULL;
    4804             :         int r;
    4805             : 
    4806           0 :         r = get_proc_cmdline_key("systemd.restore_state=", &value);
    4807           0 :         if (r < 0)
    4808           0 :                 return r;
    4809           0 :         if (r == 0)
    4810           0 :                 return true;
    4811             : 
    4812           0 :         return parse_boolean(value) != 0;
    4813             : }
    4814             : 
    4815           7 : int proc_cmdline(char **ret) {
    4816           7 :         assert(ret);
    4817             : 
    4818           7 :         if (detect_container(NULL) > 0)
    4819           0 :                 return get_process_cmdline(1, 0, false, ret);
    4820             :         else
    4821           7 :                 return read_one_line_file("/proc/cmdline", ret);
    4822             : }
    4823             : 
    4824           1 : int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
    4825           2 :         _cleanup_free_ char *line = NULL;
    4826             :         const char *p;
    4827             :         int r;
    4828             : 
    4829           1 :         assert(parse_item);
    4830             : 
    4831           1 :         r = proc_cmdline(&line);
    4832           1 :         if (r < 0)
    4833           0 :                 return r;
    4834             : 
    4835           1 :         p = line;
    4836             :         for (;;) {
    4837          16 :                 _cleanup_free_ char *word = NULL;
    4838           8 :                 char *value = NULL;
    4839             : 
    4840           8 :                 r = unquote_first_word(&p, &word, UNQUOTE_RELAX);
    4841           8 :                 if (r < 0)
    4842           0 :                         return r;
    4843           8 :                 if (r == 0)
    4844           1 :                         break;
    4845             : 
    4846             :                 /* Filter out arguments that are intended only for the
    4847             :                  * initrd */
    4848           7 :                 if (!in_initrd() && startswith(word, "rd."))
    4849           0 :                         continue;
    4850             : 
    4851           7 :                 value = strchr(word, '=');
    4852           7 :                 if (value)
    4853           4 :                         *(value++) = 0;
    4854             : 
    4855           7 :                 r = parse_item(word, value);
    4856           7 :                 if (r < 0)
    4857           0 :                         return r;
    4858           7 :         }
    4859             : 
    4860           1 :         return 0;
    4861             : }
    4862             : 
    4863           4 : int get_proc_cmdline_key(const char *key, char **value) {
    4864           8 :         _cleanup_free_ char *line = NULL, *ret = NULL;
    4865           4 :         bool found = false;
    4866             :         const char *p;
    4867             :         int r;
    4868             : 
    4869           4 :         assert(key);
    4870             : 
    4871           4 :         r = proc_cmdline(&line);
    4872           4 :         if (r < 0)
    4873           0 :                 return r;
    4874             : 
    4875           4 :         p = line;
    4876             :         for (;;) {
    4877          64 :                 _cleanup_free_ char *word = NULL;
    4878             :                 const char *e;
    4879             : 
    4880          32 :                 r = unquote_first_word(&p, &word, UNQUOTE_RELAX);
    4881          32 :                 if (r < 0)
    4882           0 :                         return r;
    4883          32 :                 if (r == 0)
    4884           4 :                         break;
    4885             : 
    4886             :                 /* Filter out arguments that are intended only for the
    4887             :                  * initrd */
    4888          28 :                 if (!in_initrd() && startswith(word, "rd."))
    4889           0 :                         continue;
    4890             : 
    4891          28 :                 if (value) {
    4892           0 :                         e = startswith(word, key);
    4893           0 :                         if (!e)
    4894           0 :                                 continue;
    4895             : 
    4896           0 :                         r = free_and_strdup(&ret, e);
    4897           0 :                         if (r < 0)
    4898           0 :                                 return r;
    4899             : 
    4900           0 :                         found = true;
    4901             :                 } else {
    4902          28 :                         if (streq(word, key))
    4903           4 :                                 found = true;
    4904             :                 }
    4905          28 :         }
    4906             : 
    4907           4 :         if (value) {
    4908           0 :                 *value = ret;
    4909           0 :                 ret = NULL;
    4910             :         }
    4911             : 
    4912           4 :         return found;
    4913             : 
    4914             : }
    4915             : 
    4916           0 : int container_get_leader(const char *machine, pid_t *pid) {
    4917           0 :         _cleanup_free_ char *s = NULL, *class = NULL;
    4918             :         const char *p;
    4919             :         pid_t leader;
    4920             :         int r;
    4921             : 
    4922           0 :         assert(machine);
    4923           0 :         assert(pid);
    4924             : 
    4925           0 :         p = strjoina("/run/systemd/machines/", machine);
    4926           0 :         r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
    4927           0 :         if (r == -ENOENT)
    4928           0 :                 return -EHOSTDOWN;
    4929           0 :         if (r < 0)
    4930           0 :                 return r;
    4931           0 :         if (!s)
    4932           0 :                 return -EIO;
    4933             : 
    4934           0 :         if (!streq_ptr(class, "container"))
    4935           0 :                 return -EIO;
    4936             : 
    4937           0 :         r = parse_pid(s, &leader);
    4938           0 :         if (r < 0)
    4939           0 :                 return r;
    4940           0 :         if (leader <= 1)
    4941           0 :                 return -EIO;
    4942             : 
    4943           0 :         *pid = leader;
    4944           0 :         return 0;
    4945             : }
    4946             : 
    4947           0 : int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd) {
    4948           0 :         _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1;
    4949           0 :         int rfd = -1;
    4950             : 
    4951           0 :         assert(pid >= 0);
    4952             : 
    4953           0 :         if (mntns_fd) {
    4954             :                 const char *mntns;
    4955             : 
    4956           0 :                 mntns = procfs_file_alloca(pid, "ns/mnt");
    4957           0 :                 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
    4958           0 :                 if (mntnsfd < 0)
    4959           0 :                         return -errno;
    4960             :         }
    4961             : 
    4962           0 :         if (pidns_fd) {
    4963             :                 const char *pidns;
    4964             : 
    4965           0 :                 pidns = procfs_file_alloca(pid, "ns/pid");
    4966           0 :                 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
    4967           0 :                 if (pidnsfd < 0)
    4968           0 :                         return -errno;
    4969             :         }
    4970             : 
    4971           0 :         if (netns_fd) {
    4972             :                 const char *netns;
    4973             : 
    4974           0 :                 netns = procfs_file_alloca(pid, "ns/net");
    4975           0 :                 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
    4976           0 :                 if (netnsfd < 0)
    4977           0 :                         return -errno;
    4978             :         }
    4979             : 
    4980           0 :         if (root_fd) {
    4981             :                 const char *root;
    4982             : 
    4983           0 :                 root = procfs_file_alloca(pid, "root");
    4984           0 :                 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
    4985           0 :                 if (rfd < 0)
    4986           0 :                         return -errno;
    4987             :         }
    4988             : 
    4989           0 :         if (pidns_fd)
    4990           0 :                 *pidns_fd = pidnsfd;
    4991             : 
    4992           0 :         if (mntns_fd)
    4993           0 :                 *mntns_fd = mntnsfd;
    4994             : 
    4995           0 :         if (netns_fd)
    4996           0 :                 *netns_fd = netnsfd;
    4997             : 
    4998           0 :         if (root_fd)
    4999           0 :                 *root_fd = rfd;
    5000             : 
    5001           0 :         pidnsfd = mntnsfd = netnsfd = -1;
    5002             : 
    5003           0 :         return 0;
    5004             : }
    5005             : 
    5006           0 : int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd) {
    5007             : 
    5008           0 :         if (pidns_fd >= 0)
    5009           0 :                 if (setns(pidns_fd, CLONE_NEWPID) < 0)
    5010           0 :                         return -errno;
    5011             : 
    5012           0 :         if (mntns_fd >= 0)
    5013           0 :                 if (setns(mntns_fd, CLONE_NEWNS) < 0)
    5014           0 :                         return -errno;
    5015             : 
    5016           0 :         if (netns_fd >= 0)
    5017           0 :                 if (setns(netns_fd, CLONE_NEWNET) < 0)
    5018           0 :                         return -errno;
    5019             : 
    5020           0 :         if (root_fd >= 0) {
    5021           0 :                 if (fchdir(root_fd) < 0)
    5022           0 :                         return -errno;
    5023             : 
    5024           0 :                 if (chroot(".") < 0)
    5025           0 :                         return -errno;
    5026             :         }
    5027             : 
    5028           0 :         return reset_uid_gid();
    5029             : }
    5030             : 
    5031          17 : int getpeercred(int fd, struct ucred *ucred) {
    5032          17 :         socklen_t n = sizeof(struct ucred);
    5033             :         struct ucred u;
    5034             :         int r;
    5035             : 
    5036          17 :         assert(fd >= 0);
    5037          17 :         assert(ucred);
    5038             : 
    5039          17 :         r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
    5040          17 :         if (r < 0)
    5041           0 :                 return -errno;
    5042             : 
    5043          17 :         if (n != sizeof(struct ucred))
    5044           0 :                 return -EIO;
    5045             : 
    5046             :         /* Check if the data is actually useful and not suppressed due
    5047             :          * to namespacing issues */
    5048          17 :         if (u.pid <= 0)
    5049           0 :                 return -ENODATA;
    5050          17 :         if (u.uid == UID_INVALID)
    5051           0 :                 return -ENODATA;
    5052          17 :         if (u.gid == GID_INVALID)
    5053           0 :                 return -ENODATA;
    5054             : 
    5055          17 :         *ucred = u;
    5056          17 :         return 0;
    5057             : }
    5058             : 
    5059          17 : int getpeersec(int fd, char **ret) {
    5060          17 :         socklen_t n = 64;
    5061             :         char *s;
    5062             :         int r;
    5063             : 
    5064          17 :         assert(fd >= 0);
    5065          17 :         assert(ret);
    5066             : 
    5067          17 :         s = new0(char, n);
    5068          17 :         if (!s)
    5069           0 :                 return -ENOMEM;
    5070             : 
    5071          17 :         r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
    5072          17 :         if (r < 0) {
    5073          17 :                 free(s);
    5074             : 
    5075          17 :                 if (errno != ERANGE)
    5076          17 :                         return -errno;
    5077             : 
    5078           0 :                 s = new0(char, n);
    5079           0 :                 if (!s)
    5080           0 :                         return -ENOMEM;
    5081             : 
    5082           0 :                 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
    5083           0 :                 if (r < 0) {
    5084           0 :                         free(s);
    5085           0 :                         return -errno;
    5086             :                 }
    5087             :         }
    5088             : 
    5089           0 :         if (isempty(s)) {
    5090           0 :                 free(s);
    5091           0 :                 return -EOPNOTSUPP;
    5092             :         }
    5093             : 
    5094           0 :         *ret = s;
    5095           0 :         return 0;
    5096             : }
    5097             : 
    5098             : /* This is much like like mkostemp() but is subject to umask(). */
    5099          57 : int mkostemp_safe(char *pattern, int flags) {
    5100          57 :         _cleanup_umask_ mode_t u;
    5101             :         int fd;
    5102             : 
    5103          57 :         assert(pattern);
    5104             : 
    5105          57 :         u = umask(077);
    5106             : 
    5107          57 :         fd = mkostemp(pattern, flags);
    5108          57 :         if (fd < 0)
    5109           4 :                 return -errno;
    5110             : 
    5111          53 :         return fd;
    5112             : }
    5113             : 
    5114           4 : int open_tmpfile(const char *path, int flags) {
    5115             :         char *p;
    5116             :         int fd;
    5117             : 
    5118           4 :         assert(path);
    5119             : 
    5120             : #ifdef O_TMPFILE
    5121             :         /* Try O_TMPFILE first, if it is supported */
    5122           4 :         fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
    5123           4 :         if (fd >= 0)
    5124           4 :                 return fd;
    5125             : #endif
    5126             : 
    5127             :         /* Fall back to unguessable name + unlinking */
    5128           0 :         p = strjoina(path, "/systemd-tmp-XXXXXX");
    5129             : 
    5130           0 :         fd = mkostemp_safe(p, flags);
    5131           0 :         if (fd < 0)
    5132           0 :                 return fd;
    5133             : 
    5134           0 :         unlink(p);
    5135           0 :         return fd;
    5136             : }
    5137             : 
    5138         370 : int fd_warn_permissions(const char *path, int fd) {
    5139             :         struct stat st;
    5140             : 
    5141         370 :         if (fstat(fd, &st) < 0)
    5142           0 :                 return -errno;
    5143             : 
    5144         370 :         if (st.st_mode & 0111)
    5145           0 :                 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
    5146             : 
    5147         370 :         if (st.st_mode & 0002)
    5148           0 :                 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
    5149             : 
    5150         370 :         if (getpid() == 1 && (st.st_mode & 0044) != 0044)
    5151           0 :                 log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
    5152             : 
    5153         370 :         return 0;
    5154             : }
    5155             : 
    5156           0 : unsigned long personality_from_string(const char *p) {
    5157             : 
    5158             :         /* Parse a personality specifier. We introduce our own
    5159             :          * identifiers that indicate specific ABIs, rather than just
    5160             :          * hints regarding the register size, since we want to keep
    5161             :          * things open for multiple locally supported ABIs for the
    5162             :          * same register size. We try to reuse the ABI identifiers
    5163             :          * used by libseccomp. */
    5164             : 
    5165             : #if defined(__x86_64__)
    5166             : 
    5167           0 :         if (streq(p, "x86"))
    5168           0 :                 return PER_LINUX32;
    5169             : 
    5170           0 :         if (streq(p, "x86-64"))
    5171           0 :                 return PER_LINUX;
    5172             : 
    5173             : #elif defined(__i386__)
    5174             : 
    5175             :         if (streq(p, "x86"))
    5176             :                 return PER_LINUX;
    5177             : #endif
    5178             : 
    5179           0 :         return PERSONALITY_INVALID;
    5180             : }
    5181             : 
    5182           0 : const char* personality_to_string(unsigned long p) {
    5183             : 
    5184             : #if defined(__x86_64__)
    5185             : 
    5186           0 :         if (p == PER_LINUX32)
    5187           0 :                 return "x86";
    5188             : 
    5189           0 :         if (p == PER_LINUX)
    5190           0 :                 return "x86-64";
    5191             : 
    5192             : #elif defined(__i386__)
    5193             : 
    5194             :         if (p == PER_LINUX)
    5195             :                 return "x86";
    5196             : #endif
    5197             : 
    5198           0 :         return NULL;
    5199             : }
    5200             : 
    5201           0 : uint64_t physical_memory(void) {
    5202             :         long mem;
    5203             : 
    5204             :         /* We return this as uint64_t in case we are running as 32bit
    5205             :          * process on a 64bit kernel with huge amounts of memory */
    5206             : 
    5207           0 :         mem = sysconf(_SC_PHYS_PAGES);
    5208           0 :         assert(mem > 0);
    5209             : 
    5210           0 :         return (uint64_t) mem * (uint64_t) page_size();
    5211             : }
    5212             : 
    5213           9 : void hexdump(FILE *f, const void *p, size_t s) {
    5214           9 :         const uint8_t *b = p;
    5215           9 :         unsigned n = 0;
    5216             : 
    5217           9 :         assert(s == 0 || b);
    5218             : 
    5219          28 :         while (s > 0) {
    5220             :                 size_t i;
    5221             : 
    5222          17 :                 fprintf(f, "%04x  ", n);
    5223             : 
    5224         289 :                 for (i = 0; i < 16; i++) {
    5225             : 
    5226         272 :                         if (i >= s)
    5227          85 :                                 fputs("   ", f);
    5228             :                         else
    5229         187 :                                 fprintf(f, "%02x ", b[i]);
    5230             : 
    5231         272 :                         if (i == 7)
    5232          17 :                                 fputc(' ', f);
    5233             :                 }
    5234             : 
    5235          17 :                 fputc(' ', f);
    5236             : 
    5237         289 :                 for (i = 0; i < 16; i++) {
    5238             : 
    5239         272 :                         if (i >= s)
    5240          85 :                                 fputc(' ', f);
    5241             :                         else
    5242         187 :                                 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
    5243             :                 }
    5244             : 
    5245          17 :                 fputc('\n', f);
    5246             : 
    5247          17 :                 if (s < 16)
    5248           7 :                         break;
    5249             : 
    5250          10 :                 n += 16;
    5251          10 :                 b += 16;
    5252          10 :                 s -= 16;
    5253             :         }
    5254           9 : }
    5255             : 
    5256           0 : int update_reboot_param_file(const char *param) {
    5257           0 :         int r = 0;
    5258             : 
    5259           0 :         if (param) {
    5260             : 
    5261           0 :                 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
    5262           0 :                 if (r < 0)
    5263           0 :                         log_error("Failed to write reboot param to "
    5264             :                                   REBOOT_PARAM_FILE": %s", strerror(-r));
    5265             :         } else
    5266           0 :                 unlink(REBOOT_PARAM_FILE);
    5267             : 
    5268           0 :         return r;
    5269             : }
    5270             : 
    5271           0 : int umount_recursive(const char *prefix, int flags) {
    5272             :         bool again;
    5273           0 :         int n = 0, r;
    5274             : 
    5275             :         /* Try to umount everything recursively below a
    5276             :          * directory. Also, take care of stacked mounts, and keep
    5277             :          * unmounting them until they are gone. */
    5278             : 
    5279             :         do {
    5280           0 :                 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
    5281             : 
    5282           0 :                 again = false;
    5283           0 :                 r = 0;
    5284             : 
    5285           0 :                 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
    5286           0 :                 if (!proc_self_mountinfo)
    5287           0 :                         return -errno;
    5288             : 
    5289             :                 for (;;) {
    5290           0 :                         _cleanup_free_ char *path = NULL, *p = NULL;
    5291             :                         int k;
    5292             : 
    5293           0 :                         k = fscanf(proc_self_mountinfo,
    5294             :                                    "%*s "       /* (1) mount id */
    5295             :                                    "%*s "       /* (2) parent id */
    5296             :                                    "%*s "       /* (3) major:minor */
    5297             :                                    "%*s "       /* (4) root */
    5298             :                                    "%ms "       /* (5) mount point */
    5299             :                                    "%*s"        /* (6) mount options */
    5300             :                                    "%*[^-]"     /* (7) optional fields */
    5301             :                                    "- "         /* (8) separator */
    5302             :                                    "%*s "       /* (9) file system type */
    5303             :                                    "%*s"        /* (10) mount source */
    5304             :                                    "%*s"        /* (11) mount options 2 */
    5305             :                                    "%*[^\n]",   /* some rubbish at the end */
    5306             :                                    &path);
    5307           0 :                         if (k != 1) {
    5308           0 :                                 if (k == EOF)
    5309           0 :                                         break;
    5310             : 
    5311           0 :                                 continue;
    5312             :                         }
    5313             : 
    5314           0 :                         r = cunescape(path, UNESCAPE_RELAX, &p);
    5315           0 :                         if (r < 0)
    5316           0 :                                 return r;
    5317             : 
    5318           0 :                         if (!path_startswith(p, prefix))
    5319           0 :                                 continue;
    5320             : 
    5321           0 :                         if (umount2(p, flags) < 0) {
    5322           0 :                                 r = -errno;
    5323           0 :                                 continue;
    5324             :                         }
    5325             : 
    5326           0 :                         again = true;
    5327           0 :                         n++;
    5328             : 
    5329           0 :                         break;
    5330           0 :                 }
    5331             : 
    5332           0 :         } while (again);
    5333             : 
    5334           0 :         return r ? r : n;
    5335             : }
    5336             : 
    5337           0 : static int get_mount_flags(const char *path, unsigned long *flags) {
    5338             :         struct statvfs buf;
    5339             : 
    5340           0 :         if (statvfs(path, &buf) < 0)
    5341           0 :                 return -errno;
    5342           0 :         *flags = buf.f_flag;
    5343           0 :         return 0;
    5344             : }
    5345             : 
    5346           0 : int bind_remount_recursive(const char *prefix, bool ro) {
    5347           0 :         _cleanup_set_free_free_ Set *done = NULL;
    5348           0 :         _cleanup_free_ char *cleaned = NULL;
    5349             :         int r;
    5350             : 
    5351             :         /* Recursively remount a directory (and all its submounts)
    5352             :          * read-only or read-write. If the directory is already
    5353             :          * mounted, we reuse the mount and simply mark it
    5354             :          * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
    5355             :          * operation). If it isn't we first make it one. Afterwards we
    5356             :          * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
    5357             :          * submounts we can access, too. When mounts are stacked on
    5358             :          * the same mount point we only care for each individual
    5359             :          * "top-level" mount on each point, as we cannot
    5360             :          * influence/access the underlying mounts anyway. We do not
    5361             :          * have any effect on future submounts that might get
    5362             :          * propagated, they migt be writable. This includes future
    5363             :          * submounts that have been triggered via autofs. */
    5364             : 
    5365           0 :         cleaned = strdup(prefix);
    5366           0 :         if (!cleaned)
    5367           0 :                 return -ENOMEM;
    5368             : 
    5369           0 :         path_kill_slashes(cleaned);
    5370             : 
    5371           0 :         done = set_new(&string_hash_ops);
    5372           0 :         if (!done)
    5373           0 :                 return -ENOMEM;
    5374             : 
    5375             :         for (;;) {
    5376           0 :                 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
    5377           0 :                 _cleanup_set_free_free_ Set *todo = NULL;
    5378           0 :                 bool top_autofs = false;
    5379             :                 char *x;
    5380             :                 unsigned long orig_flags;
    5381             : 
    5382           0 :                 todo = set_new(&string_hash_ops);
    5383           0 :                 if (!todo)
    5384           0 :                         return -ENOMEM;
    5385             : 
    5386           0 :                 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
    5387           0 :                 if (!proc_self_mountinfo)
    5388           0 :                         return -errno;
    5389             : 
    5390             :                 for (;;) {
    5391           0 :                         _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
    5392             :                         int k;
    5393             : 
    5394           0 :                         k = fscanf(proc_self_mountinfo,
    5395             :                                    "%*s "       /* (1) mount id */
    5396             :                                    "%*s "       /* (2) parent id */
    5397             :                                    "%*s "       /* (3) major:minor */
    5398             :                                    "%*s "       /* (4) root */
    5399             :                                    "%ms "       /* (5) mount point */
    5400             :                                    "%*s"        /* (6) mount options (superblock) */
    5401             :                                    "%*[^-]"     /* (7) optional fields */
    5402             :                                    "- "         /* (8) separator */
    5403             :                                    "%ms "       /* (9) file system type */
    5404             :                                    "%*s"        /* (10) mount source */
    5405             :                                    "%*s"        /* (11) mount options (bind mount) */
    5406             :                                    "%*[^\n]",   /* some rubbish at the end */
    5407             :                                    &path,
    5408             :                                    &type);
    5409           0 :                         if (k != 2) {
    5410           0 :                                 if (k == EOF)
    5411           0 :                                         break;
    5412             : 
    5413           0 :                                 continue;
    5414             :                         }
    5415             : 
    5416           0 :                         r = cunescape(path, UNESCAPE_RELAX, &p);
    5417           0 :                         if (r < 0)
    5418           0 :                                 return r;
    5419             : 
    5420             :                         /* Let's ignore autofs mounts.  If they aren't
    5421             :                          * triggered yet, we want to avoid triggering
    5422             :                          * them, as we don't make any guarantees for
    5423             :                          * future submounts anyway.  If they are
    5424             :                          * already triggered, then we will find
    5425             :                          * another entry for this. */
    5426           0 :                         if (streq(type, "autofs")) {
    5427           0 :                                 top_autofs = top_autofs || path_equal(cleaned, p);
    5428           0 :                                 continue;
    5429             :                         }
    5430             : 
    5431           0 :                         if (path_startswith(p, cleaned) &&
    5432           0 :                             !set_contains(done, p)) {
    5433             : 
    5434           0 :                                 r = set_consume(todo, p);
    5435           0 :                                 p = NULL;
    5436             : 
    5437           0 :                                 if (r == -EEXIST)
    5438           0 :                                         continue;
    5439           0 :                                 if (r < 0)
    5440           0 :                                         return r;
    5441             :                         }
    5442           0 :                 }
    5443             : 
    5444             :                 /* If we have no submounts to process anymore and if
    5445             :                  * the root is either already done, or an autofs, we
    5446             :                  * are done */
    5447           0 :                 if (set_isempty(todo) &&
    5448           0 :                     (top_autofs || set_contains(done, cleaned)))
    5449           0 :                         return 0;
    5450             : 
    5451           0 :                 if (!set_contains(done, cleaned) &&
    5452           0 :                     !set_contains(todo, cleaned)) {
    5453             :                         /* The prefix directory itself is not yet a
    5454             :                          * mount, make it one. */
    5455           0 :                         if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
    5456           0 :                                 return -errno;
    5457             : 
    5458           0 :                         orig_flags = 0;
    5459           0 :                         (void) get_mount_flags(cleaned, &orig_flags);
    5460           0 :                         orig_flags &= ~MS_RDONLY;
    5461             : 
    5462           0 :                         if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
    5463           0 :                                 return -errno;
    5464             : 
    5465           0 :                         x = strdup(cleaned);
    5466           0 :                         if (!x)
    5467           0 :                                 return -ENOMEM;
    5468             : 
    5469           0 :                         r = set_consume(done, x);
    5470           0 :                         if (r < 0)
    5471           0 :                                 return r;
    5472             :                 }
    5473             : 
    5474           0 :                 while ((x = set_steal_first(todo))) {
    5475             : 
    5476           0 :                         r = set_consume(done, x);
    5477           0 :                         if (r == -EEXIST || r == 0)
    5478           0 :                                 continue;
    5479           0 :                         if (r < 0)
    5480           0 :                                 return r;
    5481             : 
    5482             :                         /* Try to reuse the original flag set, but
    5483             :                          * don't care for errors, in case of
    5484             :                          * obstructed mounts */
    5485           0 :                         orig_flags = 0;
    5486           0 :                         (void) get_mount_flags(x, &orig_flags);
    5487           0 :                         orig_flags &= ~MS_RDONLY;
    5488             : 
    5489           0 :                         if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
    5490             : 
    5491             :                                 /* Deal with mount points that are
    5492             :                                  * obstructed by a later mount */
    5493             : 
    5494           0 :                                 if (errno != ENOENT)
    5495           0 :                                         return -errno;
    5496             :                         }
    5497             : 
    5498             :                 }
    5499           0 :         }
    5500             : }
    5501             : 
    5502           2 : int fflush_and_check(FILE *f) {
    5503           2 :         assert(f);
    5504             : 
    5505           2 :         errno = 0;
    5506           2 :         fflush(f);
    5507             : 
    5508           2 :         if (ferror(f))
    5509           0 :                 return errno ? -errno : -EIO;
    5510             : 
    5511           2 :         return 0;
    5512             : }
    5513             : 
    5514           9 : int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
    5515             :         const char *fn;
    5516             :         char *t;
    5517             : 
    5518           9 :         assert(p);
    5519           9 :         assert(ret);
    5520             : 
    5521             :         /*
    5522             :          * Turns this:
    5523             :          *         /foo/bar/waldo
    5524             :          *
    5525             :          * Into this:
    5526             :          *         /foo/bar/.#<extra>waldoXXXXXX
    5527             :          */
    5528             : 
    5529           9 :         fn = basename(p);
    5530           9 :         if (!filename_is_valid(fn))
    5531           0 :                 return -EINVAL;
    5532             : 
    5533           9 :         if (extra == NULL)
    5534           8 :                 extra = "";
    5535             : 
    5536           9 :         t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
    5537           9 :         if (!t)
    5538           0 :                 return -ENOMEM;
    5539             : 
    5540           9 :         strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
    5541             : 
    5542           9 :         *ret = path_kill_slashes(t);
    5543           9 :         return 0;
    5544             : }
    5545             : 
    5546           2 : int tempfn_random(const char *p, const char *extra, char **ret) {
    5547             :         const char *fn;
    5548             :         char *t, *x;
    5549             :         uint64_t u;
    5550             :         unsigned i;
    5551             : 
    5552           2 :         assert(p);
    5553           2 :         assert(ret);
    5554             : 
    5555             :         /*
    5556             :          * Turns this:
    5557             :          *         /foo/bar/waldo
    5558             :          *
    5559             :          * Into this:
    5560             :          *         /foo/bar/.#<extra>waldobaa2a261115984a9
    5561             :          */
    5562             : 
    5563           2 :         fn = basename(p);
    5564           2 :         if (!filename_is_valid(fn))
    5565           0 :                 return -EINVAL;
    5566             : 
    5567           2 :         if (!extra)
    5568           1 :                 extra = "";
    5569             : 
    5570           2 :         t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
    5571           2 :         if (!t)
    5572           0 :                 return -ENOMEM;
    5573             : 
    5574           2 :         x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
    5575             : 
    5576           2 :         u = random_u64();
    5577          34 :         for (i = 0; i < 16; i++) {
    5578          32 :                 *(x++) = hexchar(u & 0xF);
    5579          32 :                 u >>= 4;
    5580             :         }
    5581             : 
    5582           2 :         *x = 0;
    5583             : 
    5584           2 :         *ret = path_kill_slashes(t);
    5585           2 :         return 0;
    5586             : }
    5587             : 
    5588           2 : int tempfn_random_child(const char *p, const char *extra, char **ret) {
    5589             :         char *t, *x;
    5590             :         uint64_t u;
    5591             :         unsigned i;
    5592             : 
    5593           2 :         assert(p);
    5594           2 :         assert(ret);
    5595             : 
    5596             :         /* Turns this:
    5597             :          *         /foo/bar/waldo
    5598             :          * Into this:
    5599             :          *         /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
    5600             :          */
    5601             : 
    5602           2 :         if (!extra)
    5603           1 :                 extra = "";
    5604             : 
    5605           2 :         t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
    5606           2 :         if (!t)
    5607           0 :                 return -ENOMEM;
    5608             : 
    5609           2 :         x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
    5610             : 
    5611           2 :         u = random_u64();
    5612          34 :         for (i = 0; i < 16; i++) {
    5613          32 :                 *(x++) = hexchar(u & 0xF);
    5614          32 :                 u >>= 4;
    5615             :         }
    5616             : 
    5617           2 :         *x = 0;
    5618             : 
    5619           2 :         *ret = path_kill_slashes(t);
    5620           2 :         return 0;
    5621             : }
    5622             : 
    5623           0 : int take_password_lock(const char *root) {
    5624             : 
    5625           0 :         struct flock flock = {
    5626             :                 .l_type = F_WRLCK,
    5627             :                 .l_whence = SEEK_SET,
    5628             :                 .l_start = 0,
    5629             :                 .l_len = 0,
    5630             :         };
    5631             : 
    5632             :         const char *path;
    5633             :         int fd, r;
    5634             : 
    5635             :         /* This is roughly the same as lckpwdf(), but not as awful. We
    5636             :          * don't want to use alarm() and signals, hence we implement
    5637             :          * our own trivial version of this.
    5638             :          *
    5639             :          * Note that shadow-utils also takes per-database locks in
    5640             :          * addition to lckpwdf(). However, we don't given that they
    5641             :          * are redundant as they they invoke lckpwdf() first and keep
    5642             :          * it during everything they do. The per-database locks are
    5643             :          * awfully racy, and thus we just won't do them. */
    5644             : 
    5645           0 :         if (root)
    5646           0 :                 path = strjoina(root, "/etc/.pwd.lock");
    5647             :         else
    5648           0 :                 path = "/etc/.pwd.lock";
    5649             : 
    5650           0 :         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
    5651           0 :         if (fd < 0)
    5652           0 :                 return -errno;
    5653             : 
    5654           0 :         r = fcntl(fd, F_SETLKW, &flock);
    5655           0 :         if (r < 0) {
    5656           0 :                 safe_close(fd);
    5657           0 :                 return -errno;
    5658             :         }
    5659             : 
    5660           0 :         return fd;
    5661             : }
    5662             : 
    5663          29 : int is_symlink(const char *path) {
    5664             :         struct stat info;
    5665             : 
    5666          29 :         if (lstat(path, &info) < 0)
    5667          24 :                 return -errno;
    5668             : 
    5669           5 :         return !!S_ISLNK(info.st_mode);
    5670             : }
    5671             : 
    5672         140 : int is_dir(const char* path, bool follow) {
    5673             :         struct stat st;
    5674             :         int r;
    5675             : 
    5676         140 :         if (follow)
    5677         100 :                 r = stat(path, &st);
    5678             :         else
    5679          40 :                 r = lstat(path, &st);
    5680         140 :         if (r < 0)
    5681          25 :                 return -errno;
    5682             : 
    5683         115 :         return !!S_ISDIR(st.st_mode);
    5684             : }
    5685             : 
    5686           0 : int is_device_node(const char *path) {
    5687             :         struct stat info;
    5688             : 
    5689           0 :         if (lstat(path, &info) < 0)
    5690           0 :                 return -errno;
    5691             : 
    5692           0 :         return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
    5693             : }
    5694             : 
    5695         350 : int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
    5696         700 :         _cleanup_free_ char *s = NULL;
    5697         350 :         size_t allocated = 0, sz = 0;
    5698             :         int r;
    5699             : 
    5700             :         enum {
    5701             :                 START,
    5702             :                 VALUE,
    5703             :                 VALUE_ESCAPE,
    5704             :                 SINGLE_QUOTE,
    5705             :                 SINGLE_QUOTE_ESCAPE,
    5706             :                 DOUBLE_QUOTE,
    5707             :                 DOUBLE_QUOTE_ESCAPE,
    5708             :                 SPACE,
    5709         350 :         } state = START;
    5710             : 
    5711         350 :         assert(p);
    5712         350 :         assert(*p);
    5713         350 :         assert(ret);
    5714             : 
    5715             :         /* Parses the first word of a string, and returns it in
    5716             :          * *ret. Removes all quotes in the process. When parsing fails
    5717             :          * (because of an uneven number of quotes or similar), leaves
    5718             :          * the pointer *p at the first invalid character. */
    5719             : 
    5720             :         for (;;) {
    5721        3048 :                 char c = **p;
    5722             : 
    5723        3048 :                 switch (state) {
    5724             : 
    5725             :                 case START:
    5726         397 :                         if (c == 0)
    5727         392 :                                 goto finish;
    5728         318 :                         else if (strchr(WHITESPACE, c))
    5729          47 :                                 break;
    5730             : 
    5731         271 :                         state = VALUE;
    5732             :                         /* fallthrough */
    5733             : 
    5734             :                 case VALUE:
    5735        2225 :                         if (c == 0)
    5736          81 :                                 goto finish;
    5737        2144 :                         else if (c == '\'') {
    5738          32 :                                 if (!GREEDY_REALLOC(s, allocated, sz+1))
    5739          37 :                                         return -ENOMEM;
    5740             : 
    5741          32 :                                 state = SINGLE_QUOTE;
    5742        2112 :                         } else if (c == '\\')
    5743          68 :                                 state = VALUE_ESCAPE;
    5744        2044 :                         else if (c == '\"') {
    5745          47 :                                 if (!GREEDY_REALLOC(s, allocated, sz+1))
    5746           0 :                                         return -ENOMEM;
    5747             : 
    5748          47 :                                 state = DOUBLE_QUOTE;
    5749        1997 :                         } else if (strchr(WHITESPACE, c))
    5750         138 :                                 state = SPACE;
    5751             :                         else {
    5752        1859 :                                 if (!GREEDY_REALLOC(s, allocated, sz+2))
    5753           0 :                                         return -ENOMEM;
    5754             : 
    5755        1859 :                                 s[sz++] = c;
    5756             :                         }
    5757             : 
    5758        2144 :                         break;
    5759             : 
    5760             :                 case SINGLE_QUOTE:
    5761         139 :                         if (c == 0) {
    5762          14 :                                 if (flags & UNQUOTE_RELAX)
    5763           2 :                                         goto finish;
    5764          12 :                                 return -EINVAL;
    5765         125 :                         } else if (c == '\'')
    5766          15 :                                 state = VALUE;
    5767         110 :                         else if (c == '\\')
    5768           5 :                                 state = SINGLE_QUOTE_ESCAPE;
    5769             :                         else {
    5770         105 :                                 if (!GREEDY_REALLOC(s, allocated, sz+2))
    5771           0 :                                         return -ENOMEM;
    5772             : 
    5773         105 :                                 s[sz++] = c;
    5774             :                         }
    5775             : 
    5776         125 :                         break;
    5777             : 
    5778             :                 case DOUBLE_QUOTE:
    5779         280 :                         if (c == 0)
    5780           5 :                                 return -EINVAL;
    5781         275 :                         else if (c == '\"')
    5782          31 :                                 state = VALUE;
    5783         244 :                         else if (c == '\\')
    5784          30 :                                 state = DOUBLE_QUOTE_ESCAPE;
    5785             :                         else {
    5786         214 :                                 if (!GREEDY_REALLOC(s, allocated, sz+2))
    5787           0 :                                         return -ENOMEM;
    5788             : 
    5789         214 :                                 s[sz++] = c;
    5790             :                         }
    5791             : 
    5792         275 :                         break;
    5793             : 
    5794             :                 case SINGLE_QUOTE_ESCAPE:
    5795             :                 case DOUBLE_QUOTE_ESCAPE:
    5796             :                 case VALUE_ESCAPE:
    5797         103 :                         if (!GREEDY_REALLOC(s, allocated, sz+7))
    5798           0 :                                 return -ENOMEM;
    5799             : 
    5800         103 :                         if (c == 0) {
    5801          25 :                                 if ((flags & UNQUOTE_CUNESCAPE_RELAX) &&
    5802           6 :                                     (state == VALUE_ESCAPE || flags & UNQUOTE_RELAX)) {
    5803             :                                         /* If we find an unquoted trailing backslash and we're in
    5804             :                                          * UNQUOTE_CUNESCAPE_RELAX mode, keep it verbatim in the
    5805             :                                          * output.
    5806             :                                          *
    5807             :                                          * Unbalanced quotes will only be allowed in UNQUOTE_RELAX
    5808             :                                          * mode, UNQUOTE_CUNESCAP_RELAX mode does not allow them.
    5809             :                                          */
    5810           8 :                                         s[sz++] = '\\';
    5811           8 :                                         goto finish;
    5812             :                                 }
    5813          17 :                                 if (flags & UNQUOTE_RELAX)
    5814           5 :                                         goto finish;
    5815          12 :                                 return -EINVAL;
    5816             :                         }
    5817             : 
    5818          78 :                         if (flags & UNQUOTE_CUNESCAPE) {
    5819             :                                 uint32_t u;
    5820             : 
    5821          48 :                                 r = cunescape_one(*p, (size_t) -1, &c, &u);
    5822          48 :                                 if (r < 0) {
    5823          22 :                                         if (flags & UNQUOTE_CUNESCAPE_RELAX) {
    5824          14 :                                                 s[sz++] = '\\';
    5825          14 :                                                 s[sz++] = c;
    5826          14 :                                                 goto end_escape;
    5827             :                                         }
    5828           8 :                                         return -EINVAL;
    5829             :                                 }
    5830             : 
    5831          26 :                                 (*p) += r - 1;
    5832             : 
    5833          26 :                                 if (c != 0)
    5834          22 :                                         s[sz++] = c; /* normal explicit char */
    5835             :                                 else
    5836           4 :                                         sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
    5837             :                         } else
    5838          30 :                                 s[sz++] = c;
    5839             : 
    5840             : end_escape:
    5841          70 :                         state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
    5842             :                                 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
    5843             :                                 VALUE;
    5844          70 :                         break;
    5845             : 
    5846             :                 case SPACE:
    5847         175 :                         if (c == 0)
    5848          16 :                                 goto finish;
    5849         159 :                         if (!strchr(WHITESPACE, c))
    5850         122 :                                 goto finish;
    5851             : 
    5852          37 :                         break;
    5853             :                 }
    5854             : 
    5855        2698 :                 (*p) ++;
    5856        2698 :         }
    5857             : 
    5858             : finish:
    5859         313 :         if (!s) {
    5860          79 :                 *ret = NULL;
    5861          79 :                 return 0;
    5862             :         }
    5863             : 
    5864         234 :         s[sz] = 0;
    5865         234 :         *ret = s;
    5866         234 :         s = NULL;
    5867             : 
    5868         234 :         return 1;
    5869             : }
    5870             : 
    5871         175 : int unquote_first_word_and_warn(
    5872             :                 const char **p,
    5873             :                 char **ret,
    5874             :                 UnquoteFlags flags,
    5875             :                 const char *unit,
    5876             :                 const char *filename,
    5877             :                 unsigned line,
    5878             :                 const char *rvalue) {
    5879             :         /* Try to unquote it, if it fails, warn about it and try again but this
    5880             :          * time using UNQUOTE_CUNESCAPE_RELAX to keep the backslashes verbatim
    5881             :          * in invalid escape sequences. */
    5882             :         const char *save;
    5883             :         int r;
    5884             : 
    5885         175 :         save = *p;
    5886         175 :         r = unquote_first_word(p, ret, flags);
    5887         175 :         if (r < 0 && !(flags&UNQUOTE_CUNESCAPE_RELAX)) {
    5888             :                 /* Retry it with UNQUOTE_CUNESCAPE_RELAX. */
    5889          16 :                 *p = save;
    5890          16 :                 r = unquote_first_word(p, ret, flags|UNQUOTE_CUNESCAPE_RELAX);
    5891          16 :                 if (r < 0)
    5892           7 :                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
    5893             :                                    "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
    5894             :                 else
    5895           9 :                         log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
    5896             :                                    "Invalid escape sequences in command line: \"%s\"", rvalue);
    5897             :         }
    5898         175 :         return r;
    5899             : }
    5900             : 
    5901           7 : int unquote_many_words(const char **p, UnquoteFlags flags, ...) {
    5902             :         va_list ap;
    5903             :         char **l;
    5904           7 :         int n = 0, i, c, r;
    5905             : 
    5906             :         /* Parses a number of words from a string, stripping any
    5907             :          * quotes if necessary. */
    5908             : 
    5909           7 :         assert(p);
    5910             : 
    5911             :         /* Count how many words are expected */
    5912           7 :         va_start(ap, flags);
    5913             :         for (;;) {
    5914          21 :                 if (!va_arg(ap, char **))
    5915           7 :                         break;
    5916          14 :                 n++;
    5917          14 :         }
    5918           7 :         va_end(ap);
    5919             : 
    5920           7 :         if (n <= 0)
    5921           1 :                 return 0;
    5922             : 
    5923             :         /* Read all words into a temporary array */
    5924           6 :         l = newa0(char*, n);
    5925          13 :         for (c = 0; c < n; c++) {
    5926             : 
    5927          10 :                 r = unquote_first_word(p, &l[c], flags);
    5928          10 :                 if (r < 0) {
    5929             :                         int j;
    5930             : 
    5931           0 :                         for (j = 0; j < c; j++)
    5932           0 :                                 free(l[j]);
    5933             : 
    5934           0 :                         return r;
    5935             :                 }
    5936             : 
    5937          10 :                 if (r == 0)
    5938           3 :                         break;
    5939             :         }
    5940             : 
    5941             :         /* If we managed to parse all words, return them in the passed
    5942             :          * in parameters */
    5943           6 :         va_start(ap, flags);
    5944          20 :         for (i = 0; i < n; i++) {
    5945             :                 char **v;
    5946             : 
    5947          14 :                 v = va_arg(ap, char **);
    5948          14 :                 assert(v);
    5949             : 
    5950          14 :                 *v = l[i];
    5951             :         }
    5952           6 :         va_end(ap);
    5953             : 
    5954           6 :         return c;
    5955             : }
    5956             : 
    5957         171 : int free_and_strdup(char **p, const char *s) {
    5958             :         char *t;
    5959             : 
    5960         171 :         assert(p);
    5961             : 
    5962             :         /* Replaces a string pointer with an strdup()ed new string,
    5963             :          * possibly freeing the old one. */
    5964             : 
    5965         171 :         if (streq_ptr(*p, s))
    5966           2 :                 return 0;
    5967             : 
    5968         169 :         if (s) {
    5969         169 :                 t = strdup(s);
    5970         169 :                 if (!t)
    5971           0 :                         return -ENOMEM;
    5972             :         } else
    5973           0 :                 t = NULL;
    5974             : 
    5975         169 :         free(*p);
    5976         169 :         *p = t;
    5977             : 
    5978         169 :         return 1;
    5979             : }
    5980             : 
    5981        1000 : int ptsname_malloc(int fd, char **ret) {
    5982        1000 :         size_t l = 100;
    5983             : 
    5984        1000 :         assert(fd >= 0);
    5985        1000 :         assert(ret);
    5986             : 
    5987             :         for (;;) {
    5988             :                 char *c;
    5989             : 
    5990        1000 :                 c = new(char, l);
    5991        1000 :                 if (!c)
    5992           0 :                         return -ENOMEM;
    5993             : 
    5994        1000 :                 if (ptsname_r(fd, c, l) == 0) {
    5995        1000 :                         *ret = c;
    5996        1000 :                         return 0;
    5997             :                 }
    5998           0 :                 if (errno != ERANGE) {
    5999           0 :                         free(c);
    6000           0 :                         return -errno;
    6001             :                 }
    6002             : 
    6003           0 :                 free(c);
    6004           0 :                 l *= 2;
    6005           0 :         }
    6006             : }
    6007             : 
    6008           0 : int openpt_in_namespace(pid_t pid, int flags) {
    6009           0 :         _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
    6010           0 :         _cleanup_close_pair_ int pair[2] = { -1, -1 };
    6011             :         union {
    6012             :                 struct cmsghdr cmsghdr;
    6013             :                 uint8_t buf[CMSG_SPACE(sizeof(int))];
    6014           0 :         } control = {};
    6015           0 :         struct msghdr mh = {
    6016             :                 .msg_control = &control,
    6017             :                 .msg_controllen = sizeof(control),
    6018             :         };
    6019             :         struct cmsghdr *cmsg;
    6020             :         siginfo_t si;
    6021             :         pid_t child;
    6022             :         int r;
    6023             : 
    6024           0 :         assert(pid > 0);
    6025             : 
    6026           0 :         r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &rootfd);
    6027           0 :         if (r < 0)
    6028           0 :                 return r;
    6029             : 
    6030           0 :         if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
    6031           0 :                 return -errno;
    6032             : 
    6033           0 :         child = fork();
    6034           0 :         if (child < 0)
    6035           0 :                 return -errno;
    6036             : 
    6037           0 :         if (child == 0) {
    6038             :                 int master;
    6039             : 
    6040           0 :                 pair[0] = safe_close(pair[0]);
    6041             : 
    6042           0 :                 r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
    6043           0 :                 if (r < 0)
    6044           0 :                         _exit(EXIT_FAILURE);
    6045             : 
    6046           0 :                 master = posix_openpt(flags);
    6047           0 :                 if (master < 0)
    6048           0 :                         _exit(EXIT_FAILURE);
    6049             : 
    6050           0 :                 cmsg = CMSG_FIRSTHDR(&mh);
    6051           0 :                 cmsg->cmsg_level = SOL_SOCKET;
    6052           0 :                 cmsg->cmsg_type = SCM_RIGHTS;
    6053           0 :                 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    6054           0 :                 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
    6055             : 
    6056           0 :                 mh.msg_controllen = cmsg->cmsg_len;
    6057             : 
    6058           0 :                 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
    6059           0 :                         _exit(EXIT_FAILURE);
    6060             : 
    6061           0 :                 _exit(EXIT_SUCCESS);
    6062             :         }
    6063             : 
    6064           0 :         pair[1] = safe_close(pair[1]);
    6065             : 
    6066           0 :         r = wait_for_terminate(child, &si);
    6067           0 :         if (r < 0)
    6068           0 :                 return r;
    6069           0 :         if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
    6070           0 :                 return -EIO;
    6071             : 
    6072           0 :         if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
    6073           0 :                 return -errno;
    6074             : 
    6075           0 :         CMSG_FOREACH(cmsg, &mh)
    6076           0 :                 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
    6077             :                         int *fds;
    6078             :                         unsigned n_fds;
    6079             : 
    6080           0 :                         fds = (int*) CMSG_DATA(cmsg);
    6081           0 :                         n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
    6082             : 
    6083           0 :                         if (n_fds != 1) {
    6084           0 :                                 close_many(fds, n_fds);
    6085           0 :                                 return -EIO;
    6086             :                         }
    6087             : 
    6088           0 :                         return fds[0];
    6089             :                 }
    6090             : 
    6091           0 :         return -EIO;
    6092             : }
    6093             : 
    6094           0 : ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
    6095           0 :         _cleanup_close_ int fd = -1;
    6096             :         ssize_t l;
    6097             : 
    6098             :         /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
    6099             : 
    6100           0 :         fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
    6101           0 :         if (fd < 0)
    6102           0 :                 return -errno;
    6103             : 
    6104           0 :         l = fgetxattr(fd, attribute, value, size);
    6105           0 :         if (l < 0)
    6106           0 :                 return -errno;
    6107             : 
    6108           0 :         return l;
    6109             : }
    6110             : 
    6111           0 : static int parse_crtime(le64_t le, usec_t *usec) {
    6112             :         uint64_t u;
    6113             : 
    6114           0 :         assert(usec);
    6115             : 
    6116           0 :         u = le64toh(le);
    6117           0 :         if (u == 0 || u == (uint64_t) -1)
    6118           0 :                 return -EIO;
    6119             : 
    6120           0 :         *usec = (usec_t) u;
    6121           0 :         return 0;
    6122             : }
    6123             : 
    6124           2 : int fd_getcrtime(int fd, usec_t *usec) {
    6125             :         le64_t le;
    6126             :         ssize_t n;
    6127             : 
    6128           2 :         assert(fd >= 0);
    6129           2 :         assert(usec);
    6130             : 
    6131             :         /* Until Linux gets a real concept of birthtime/creation time,
    6132             :          * let's fake one with xattrs */
    6133             : 
    6134           2 :         n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
    6135           2 :         if (n < 0)
    6136           2 :                 return -errno;
    6137           0 :         if (n != sizeof(le))
    6138           0 :                 return -EIO;
    6139             : 
    6140           0 :         return parse_crtime(le, usec);
    6141             : }
    6142             : 
    6143           0 : int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
    6144             :         le64_t le;
    6145             :         ssize_t n;
    6146             : 
    6147           0 :         n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
    6148           0 :         if (n < 0)
    6149           0 :                 return -errno;
    6150           0 :         if (n != sizeof(le))
    6151           0 :                 return -EIO;
    6152             : 
    6153           0 :         return parse_crtime(le, usec);
    6154             : }
    6155             : 
    6156           1 : int path_getcrtime(const char *p, usec_t *usec) {
    6157             :         le64_t le;
    6158             :         ssize_t n;
    6159             : 
    6160           1 :         assert(p);
    6161           1 :         assert(usec);
    6162             : 
    6163           1 :         n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
    6164           1 :         if (n < 0)
    6165           1 :                 return -errno;
    6166           0 :         if (n != sizeof(le))
    6167           0 :                 return -EIO;
    6168             : 
    6169           0 :         return parse_crtime(le, usec);
    6170             : }
    6171             : 
    6172          18 : int fd_setcrtime(int fd, usec_t usec) {
    6173             :         le64_t le;
    6174             : 
    6175          18 :         assert(fd >= 0);
    6176             : 
    6177          18 :         if (usec <= 0)
    6178          18 :                 usec = now(CLOCK_REALTIME);
    6179             : 
    6180          18 :         le = htole64((uint64_t) usec);
    6181          18 :         if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
    6182          17 :                 return -errno;
    6183             : 
    6184           1 :         return 0;
    6185             : }
    6186             : 
    6187          20 : int same_fd(int a, int b) {
    6188             :         struct stat sta, stb;
    6189             :         pid_t pid;
    6190             :         int r, fa, fb;
    6191             : 
    6192          20 :         assert(a >= 0);
    6193          20 :         assert(b >= 0);
    6194             : 
    6195             :         /* Compares two file descriptors. Note that semantics are
    6196             :          * quite different depending on whether we have kcmp() or we
    6197             :          * don't. If we have kcmp() this will only return true for
    6198             :          * dup()ed file descriptors, but not otherwise. If we don't
    6199             :          * have kcmp() this will also return true for two fds of the same
    6200             :          * file, created by separate open() calls. Since we use this
    6201             :          * call mostly for filtering out duplicates in the fd store
    6202             :          * this difference hopefully doesn't matter too much. */
    6203             : 
    6204          20 :         if (a == b)
    6205           4 :                 return true;
    6206             : 
    6207             :         /* Try to use kcmp() if we have it. */
    6208          16 :         pid = getpid();
    6209          16 :         r = kcmp(pid, pid, KCMP_FILE, a, b);
    6210          16 :         if (r == 0)
    6211           0 :                 return true;
    6212          16 :         if (r > 0)
    6213           0 :                 return false;
    6214          16 :         if (errno != ENOSYS)
    6215           0 :                 return -errno;
    6216             : 
    6217             :         /* We don't have kcmp(), use fstat() instead. */
    6218          16 :         if (fstat(a, &sta) < 0)
    6219           0 :                 return -errno;
    6220             : 
    6221          16 :         if (fstat(b, &stb) < 0)
    6222           0 :                 return -errno;
    6223             : 
    6224          16 :         if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
    6225           6 :                 return false;
    6226             : 
    6227             :         /* We consider all device fds different, since two device fds
    6228             :          * might refer to quite different device contexts even though
    6229             :          * they share the same inode and backing dev_t. */
    6230             : 
    6231          10 :         if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
    6232           0 :                 return false;
    6233             : 
    6234          10 :         if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
    6235           0 :                 return false;
    6236             : 
    6237             :         /* The fds refer to the same inode on disk, let's also check
    6238             :          * if they have the same fd flags. This is useful to
    6239             :          * distinguish the read and write side of a pipe created with
    6240             :          * pipe(). */
    6241          10 :         fa = fcntl(a, F_GETFL);
    6242          10 :         if (fa < 0)
    6243           0 :                 return -errno;
    6244             : 
    6245          10 :         fb = fcntl(b, F_GETFL);
    6246          10 :         if (fb < 0)
    6247           0 :                 return -errno;
    6248             : 
    6249          10 :         return fa == fb;
    6250             : }
    6251             : 
    6252           2 : int chattr_fd(int fd, unsigned value, unsigned mask) {
    6253             :         unsigned old_attr, new_attr;
    6254             :         struct stat st;
    6255             : 
    6256           2 :         assert(fd >= 0);
    6257             : 
    6258           2 :         if (fstat(fd, &st) < 0)
    6259           0 :                 return -errno;
    6260             : 
    6261             :         /* Explicitly check whether this is a regular file or
    6262             :          * directory. If it is anything else (such as a device node or
    6263             :          * fifo), then the ioctl will not hit the file systems but
    6264             :          * possibly drivers, where the ioctl might have different
    6265             :          * effects. Notably, DRM is using the same ioctl() number. */
    6266             : 
    6267           2 :         if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
    6268           0 :                 return -ENOTTY;
    6269             : 
    6270           2 :         if (mask == 0)
    6271           0 :                 return 0;
    6272             : 
    6273           2 :         if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
    6274           2 :                 return -errno;
    6275             : 
    6276           0 :         new_attr = (old_attr & ~mask) | (value & mask);
    6277           0 :         if (new_attr == old_attr)
    6278           0 :                 return 0;
    6279             : 
    6280           0 :         if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
    6281           0 :                 return -errno;
    6282             : 
    6283           0 :         return 1;
    6284             : }
    6285             : 
    6286           0 : int chattr_path(const char *p, unsigned value, unsigned mask) {
    6287           0 :         _cleanup_close_ int fd = -1;
    6288             : 
    6289           0 :         assert(p);
    6290             : 
    6291           0 :         if (mask == 0)
    6292           0 :                 return 0;
    6293             : 
    6294           0 :         fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
    6295           0 :         if (fd < 0)
    6296           0 :                 return -errno;
    6297             : 
    6298           0 :         return chattr_fd(fd, value, mask);
    6299             : }
    6300             : 
    6301           1 : int read_attr_fd(int fd, unsigned *ret) {
    6302             :         struct stat st;
    6303             : 
    6304           1 :         assert(fd >= 0);
    6305             : 
    6306           1 :         if (fstat(fd, &st) < 0)
    6307           0 :                 return -errno;
    6308             : 
    6309           1 :         if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
    6310           0 :                 return -ENOTTY;
    6311             : 
    6312           1 :         if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
    6313           0 :                 return -errno;
    6314             : 
    6315           1 :         return 0;
    6316             : }
    6317             : 
    6318           0 : int read_attr_path(const char *p, unsigned *ret) {
    6319           0 :         _cleanup_close_ int fd = -1;
    6320             : 
    6321           0 :         assert(p);
    6322           0 :         assert(ret);
    6323             : 
    6324           0 :         fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
    6325           0 :         if (fd < 0)
    6326           0 :                 return -errno;
    6327             : 
    6328           0 :         return read_attr_fd(fd, ret);
    6329             : }
    6330             : 
    6331          58 : static size_t nul_length(const uint8_t *p, size_t sz) {
    6332          58 :         size_t n = 0;
    6333             : 
    6334         168 :         while (sz > 0) {
    6335         105 :                 if (*p != 0)
    6336          53 :                         break;
    6337             : 
    6338          52 :                 n++;
    6339          52 :                 p++;
    6340          52 :                 sz--;
    6341             :         }
    6342             : 
    6343          58 :         return n;
    6344             : }
    6345             : 
    6346           5 : ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
    6347             :         const uint8_t *q, *w, *e;
    6348             :         ssize_t l;
    6349             : 
    6350           5 :         q = w = p;
    6351           5 :         e = q + sz;
    6352          68 :         while (q < e) {
    6353             :                 size_t n;
    6354             : 
    6355          58 :                 n = nul_length(q, e - q);
    6356             : 
    6357             :                 /* If there are more than the specified run length of
    6358             :                  * NUL bytes, or if this is the beginning or the end
    6359             :                  * of the buffer, then seek instead of write */
    6360          58 :                 if ((n > run_length) ||
    6361          10 :                     (n > 0 && q == p) ||
    6362           7 :                     (n > 0 && q + n >= e)) {
    6363           9 :                         if (q > w) {
    6364           6 :                                 l = write(fd, w, q - w);
    6365           6 :                                 if (l < 0)
    6366           0 :                                         return -errno;
    6367           6 :                                 if (l != q -w)
    6368           0 :                                         return -EIO;
    6369             :                         }
    6370             : 
    6371           9 :                         if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
    6372           0 :                                 return -errno;
    6373             : 
    6374           9 :                         q += n;
    6375           9 :                         w = q;
    6376          49 :                 } else if (n > 0)
    6377           5 :                         q += n;
    6378             :                 else
    6379          44 :                         q ++;
    6380             :         }
    6381             : 
    6382           5 :         if (q > w) {
    6383           0 :                 l = write(fd, w, q - w);
    6384           0 :                 if (l < 0)
    6385           0 :                         return -errno;
    6386           0 :                 if (l != q - w)
    6387           0 :                         return -EIO;
    6388             :         }
    6389             : 
    6390           5 :         return q - (const uint8_t*) p;
    6391             : }
    6392             : 
    6393           0 : void sigkill_wait(pid_t *pid) {
    6394           0 :         if (!pid)
    6395           0 :                 return;
    6396           0 :         if (*pid <= 1)
    6397           0 :                 return;
    6398             : 
    6399           0 :         if (kill(*pid, SIGKILL) > 0)
    6400           0 :                 (void) wait_for_terminate(*pid, NULL);
    6401             : }
    6402             : 
    6403           0 : int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
    6404           0 :         int a = 0, b = 0, c = 0;
    6405             :         int k;
    6406             : 
    6407           0 :         assert(p);
    6408           0 :         assert(*p);
    6409           0 :         assert(priority);
    6410             : 
    6411           0 :         if ((*p)[0] != '<')
    6412           0 :                 return 0;
    6413             : 
    6414           0 :         if (!strchr(*p, '>'))
    6415           0 :                 return 0;
    6416             : 
    6417           0 :         if ((*p)[2] == '>') {
    6418           0 :                 c = undecchar((*p)[1]);
    6419           0 :                 k = 3;
    6420           0 :         } else if ((*p)[3] == '>') {
    6421           0 :                 b = undecchar((*p)[1]);
    6422           0 :                 c = undecchar((*p)[2]);
    6423           0 :                 k = 4;
    6424           0 :         } else if ((*p)[4] == '>') {
    6425           0 :                 a = undecchar((*p)[1]);
    6426           0 :                 b = undecchar((*p)[2]);
    6427           0 :                 c = undecchar((*p)[3]);
    6428           0 :                 k = 5;
    6429             :         } else
    6430           0 :                 return 0;
    6431             : 
    6432           0 :         if (a < 0 || b < 0 || c < 0 ||
    6433           0 :             (!with_facility && (a || b || c > 7)))
    6434           0 :                 return 0;
    6435             : 
    6436           0 :         if (with_facility)
    6437           0 :                 *priority = a*100 + b*10 + c;
    6438             :         else
    6439           0 :                 *priority = (*priority & LOG_FACMASK) | c;
    6440             : 
    6441           0 :         *p += k;
    6442           0 :         return 1;
    6443             : }
    6444             : 
    6445       13471 : ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
    6446             :         size_t i;
    6447             : 
    6448       13471 :         if (!key)
    6449           0 :                 return -1;
    6450             : 
    6451       85104 :         for (i = 0; i < len; ++i)
    6452       84899 :                 if (streq_ptr(table[i], key))
    6453       13266 :                         return (ssize_t)i;
    6454             : 
    6455         205 :         return -1;
    6456             : }
    6457             : 
    6458           0 : void cmsg_close_all(struct msghdr *mh) {
    6459             :         struct cmsghdr *cmsg;
    6460             : 
    6461           0 :         assert(mh);
    6462             : 
    6463           0 :         CMSG_FOREACH(cmsg, mh)
    6464           0 :                 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
    6465           0 :                         close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
    6466           0 : }
    6467             : 
    6468           0 : int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
    6469             :         struct stat buf;
    6470             :         int ret;
    6471             : 
    6472           0 :         ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
    6473           0 :         if (ret >= 0)
    6474           0 :                 return 0;
    6475             : 
    6476             :         /* renameat2() exists since Linux 3.15, btrfs added support for it later.
    6477             :          * If it is not implemented, fallback to another method. */
    6478           0 :         if (!IN_SET(errno, EINVAL, ENOSYS))
    6479           0 :                 return -errno;
    6480             : 
    6481             :         /* The link()/unlink() fallback does not work on directories. But
    6482             :          * renameat() without RENAME_NOREPLACE gives the same semantics on
    6483             :          * directories, except when newpath is an *empty* directory. This is
    6484             :          * good enough. */
    6485           0 :         ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
    6486           0 :         if (ret >= 0 && S_ISDIR(buf.st_mode)) {
    6487           0 :                 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
    6488           0 :                 return ret >= 0 ? 0 : -errno;
    6489             :         }
    6490             : 
    6491             :         /* If it is not a directory, use the link()/unlink() fallback. */
    6492           0 :         ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
    6493           0 :         if (ret < 0)
    6494           0 :                 return -errno;
    6495             : 
    6496           0 :         ret = unlinkat(olddirfd, oldpath, 0);
    6497           0 :         if (ret < 0) {
    6498             :                 /* backup errno before the following unlinkat() alters it */
    6499           0 :                 ret = errno;
    6500           0 :                 (void) unlinkat(newdirfd, newpath, 0);
    6501           0 :                 errno = ret;
    6502           0 :                 return -errno;
    6503             :         }
    6504             : 
    6505           0 :         return 0;
    6506             : }
    6507             : 
    6508           7 : char *shell_maybe_quote(const char *s) {
    6509             :         const char *p;
    6510             :         char *r, *t;
    6511             : 
    6512           7 :         assert(s);
    6513             : 
    6514             :         /* Encloses a string in double quotes if necessary to make it
    6515             :          * OK as shell string. */
    6516             : 
    6517          22 :         for (p = s; *p; p++)
    6518          38 :                 if (*p <= ' ' ||
    6519          36 :                     *p >= 127 ||
    6520          18 :                     strchr(SHELL_NEED_QUOTES, *p))
    6521             :                         break;
    6522             : 
    6523           7 :         if (!*p)
    6524           2 :                 return strdup(s);
    6525             : 
    6526           5 :         r = new(char, 1+strlen(s)*2+1+1);
    6527           5 :         if (!r)
    6528           0 :                 return NULL;
    6529             : 
    6530           5 :         t = r;
    6531           5 :         *(t++) = '"';
    6532           5 :         t = mempcpy(t, s, p - s);
    6533             : 
    6534          27 :         for (; *p; p++) {
    6535             : 
    6536          22 :                 if (strchr(SHELL_NEED_ESCAPE, *p))
    6537           5 :                         *(t++) = '\\';
    6538             : 
    6539          22 :                 *(t++) = *p;
    6540             :         }
    6541             : 
    6542           5 :         *(t++)= '"';
    6543           5 :         *t = 0;
    6544             : 
    6545           5 :         return r;
    6546             : }
    6547             : 
    6548          16 : int parse_mode(const char *s, mode_t *ret) {
    6549             :         char *x;
    6550             :         long l;
    6551             : 
    6552          16 :         assert(s);
    6553          16 :         assert(ret);
    6554             : 
    6555          16 :         errno = 0;
    6556          16 :         l = strtol(s, &x, 8);
    6557          16 :         if (errno != 0)
    6558           0 :                 return -errno;
    6559             : 
    6560          16 :         if (!x || x == s || *x)
    6561           6 :                 return -EINVAL;
    6562          10 :         if (l < 0 || l  > 07777)
    6563           3 :                 return -ERANGE;
    6564             : 
    6565           7 :         *ret = (mode_t) l;
    6566           7 :         return 0;
    6567             : }
    6568             : 
    6569           0 : int mount_move_root(const char *path) {
    6570           0 :         assert(path);
    6571             : 
    6572           0 :         if (chdir(path) < 0)
    6573           0 :                 return -errno;
    6574             : 
    6575           0 :         if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
    6576           0 :                 return -errno;
    6577             : 
    6578           0 :         if (chroot(".") < 0)
    6579           0 :                 return -errno;
    6580             : 
    6581           0 :         if (chdir("/") < 0)
    6582           0 :                 return -errno;
    6583             : 
    6584           0 :         return 0;
    6585             : }
    6586             : 
    6587           0 : int reset_uid_gid(void) {
    6588             : 
    6589           0 :         if (setgroups(0, NULL) < 0)
    6590           0 :                 return -errno;
    6591             : 
    6592           0 :         if (setresgid(0, 0, 0) < 0)
    6593           0 :                 return -errno;
    6594             : 
    6595           0 :         if (setresuid(0, 0, 0) < 0)
    6596           0 :                 return -errno;
    6597             : 
    6598           0 :         return 0;
    6599             : }

Generated by: LCOV version 1.11