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