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