chiark / gitweb /
machined: add new call OpenMachineLogin() that starts a getty in a container on a...
[elogind.git] / src / shared / strv.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include "util.h"
29 #include "strv.h"
30
31 char *strv_find(char **l, const char *name) {
32         char **i;
33
34         assert(name);
35
36         STRV_FOREACH(i, l)
37                 if (streq(*i, name))
38                         return *i;
39
40         return NULL;
41 }
42
43 char *strv_find_prefix(char **l, const char *name) {
44         char **i;
45
46         assert(name);
47
48         STRV_FOREACH(i, l)
49                 if (startswith(*i, name))
50                         return *i;
51
52         return NULL;
53 }
54
55 char *strv_find_startswith(char **l, const char *name) {
56         char **i, *e;
57
58         assert(name);
59
60         /* Like strv_find_prefix, but actually returns only the
61          * suffix, not the whole item */
62
63         STRV_FOREACH(i, l) {
64                 e = startswith(*i, name);
65                 if (e)
66                         return e;
67         }
68
69         return NULL;
70 }
71
72 void strv_clear(char **l) {
73         char **k;
74
75         if (!l)
76                 return;
77
78         for (k = l; *k; k++)
79                 free(*k);
80
81         *l = NULL;
82 }
83
84 void strv_free(char **l) {
85         strv_clear(l);
86         free(l);
87 }
88
89 char **strv_copy(char * const *l) {
90         char **r, **k;
91
92         k = r = new(char*, strv_length(l) + 1);
93         if (!r)
94                 return NULL;
95
96         if (l)
97                 for (; *l; k++, l++) {
98                         *k = strdup(*l);
99                         if (!*k) {
100                                 strv_free(r);
101                                 return NULL;
102                         }
103                 }
104
105         *k = NULL;
106         return r;
107 }
108
109 unsigned strv_length(char * const *l) {
110         unsigned n = 0;
111
112         if (!l)
113                 return 0;
114
115         for (; *l; l++)
116                 n++;
117
118         return n;
119 }
120
121 char **strv_new_ap(const char *x, va_list ap) {
122         const char *s;
123         char **a;
124         unsigned n = 0, i = 0;
125         va_list aq;
126
127         /* As a special trick we ignore all listed strings that equal
128          * (const char*) -1. This is supposed to be used with the
129          * STRV_IFNOTNULL() macro to include possibly NULL strings in
130          * the string list. */
131
132         if (x) {
133                 n = x == (const char*) -1 ? 0 : 1;
134
135                 va_copy(aq, ap);
136                 while ((s = va_arg(aq, const char*))) {
137                         if (s == (const char*) -1)
138                                 continue;
139
140                         n++;
141                 }
142
143                 va_end(aq);
144         }
145
146         a = new(char*, n+1);
147         if (!a)
148                 return NULL;
149
150         if (x) {
151                 if (x != (const char*) -1) {
152                         a[i] = strdup(x);
153                         if (!a[i])
154                                 goto fail;
155                         i++;
156                 }
157
158                 while ((s = va_arg(ap, const char*))) {
159
160                         if (s == (const char*) -1)
161                                 continue;
162
163                         a[i] = strdup(s);
164                         if (!a[i])
165                                 goto fail;
166
167                         i++;
168                 }
169         }
170
171         a[i] = NULL;
172
173         return a;
174
175 fail:
176         strv_free(a);
177         return NULL;
178 }
179
180 char **strv_new(const char *x, ...) {
181         char **r;
182         va_list ap;
183
184         va_start(ap, x);
185         r = strv_new_ap(x, ap);
186         va_end(ap);
187
188         return r;
189 }
190
191 int strv_extend_strv(char ***a, char **b) {
192         int r;
193         char **s;
194
195         STRV_FOREACH(s, b) {
196                 r = strv_extend(a, *s);
197                 if (r < 0)
198                         return r;
199         }
200
201         return 0;
202 }
203
204 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
205         int r;
206         char **s;
207
208         STRV_FOREACH(s, b) {
209                 char *v;
210
211                 v = strappend(*s, suffix);
212                 if (!v)
213                         return -ENOMEM;
214
215                 r = strv_push(a, v);
216                 if (r < 0) {
217                         free(v);
218                         return r;
219                 }
220         }
221
222         return 0;
223 }
224
225 char **strv_split(const char *s, const char *separator) {
226         const char *word, *state;
227         size_t l;
228         unsigned n, i;
229         char **r;
230
231         assert(s);
232
233         n = 0;
234         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
235                 n++;
236
237         r = new(char*, n+1);
238         if (!r)
239                 return NULL;
240
241         i = 0;
242         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
243                 r[i] = strndup(word, l);
244                 if (!r[i]) {
245                         strv_free(r);
246                         return NULL;
247                 }
248
249                 i++;
250         }
251
252         r[i] = NULL;
253         return r;
254 }
255
256 char **strv_split_newlines(const char *s) {
257         char **l;
258         unsigned n;
259
260         assert(s);
261
262         /* Special version of strv_split() that splits on newlines and
263          * suppresses an empty string at the end */
264
265         l = strv_split(s, NEWLINE);
266         if (!l)
267                 return NULL;
268
269         n = strv_length(l);
270         if (n <= 0)
271                 return l;
272
273         if (isempty(l[n-1])) {
274                 free(l[n-1]);
275                 l[n-1] = NULL;
276         }
277
278         return l;
279 }
280
281 int strv_split_quoted(char ***t, const char *s, bool relax) {
282         size_t n = 0, allocated = 0;
283         _cleanup_strv_free_ char **l = NULL;
284         int r;
285
286         assert(t);
287         assert(s);
288
289         for (;;) {
290                 _cleanup_free_ char *word = NULL;
291
292                 r = unquote_first_word(&s, &word, relax);
293                 if (r < 0)
294                         return r;
295                 if (r == 0)
296                         break;
297
298                 if (!GREEDY_REALLOC(l, allocated, n + 2))
299                         return -ENOMEM;
300
301                 l[n++] = word;
302                 word = NULL;
303
304                 l[n] = NULL;
305         }
306
307         if (!l)
308                 l = new0(char*, 1);
309
310         *t = l;
311         l = NULL;
312
313         return 0;
314 }
315
316 char *strv_join(char **l, const char *separator) {
317         char *r, *e;
318         char **s;
319         size_t n, k;
320
321         if (!separator)
322                 separator = " ";
323
324         k = strlen(separator);
325
326         n = 0;
327         STRV_FOREACH(s, l) {
328                 if (n != 0)
329                         n += k;
330                 n += strlen(*s);
331         }
332
333         r = new(char, n+1);
334         if (!r)
335                 return NULL;
336
337         e = r;
338         STRV_FOREACH(s, l) {
339                 if (e != r)
340                         e = stpcpy(e, separator);
341
342                 e = stpcpy(e, *s);
343         }
344
345         *e = 0;
346
347         return r;
348 }
349
350 char *strv_join_quoted(char **l) {
351         char *buf = NULL;
352         char **s;
353         size_t allocated = 0, len = 0;
354
355         STRV_FOREACH(s, l) {
356                 /* assuming here that escaped string cannot be more
357                  * than twice as long, and reserving space for the
358                  * separator and quotes.
359                  */
360                 _cleanup_free_ char *esc = NULL;
361                 size_t needed;
362
363                 if (!GREEDY_REALLOC(buf, allocated,
364                                     len + strlen(*s) * 2 + 3))
365                         goto oom;
366
367                 esc = cescape(*s);
368                 if (!esc)
369                         goto oom;
370
371                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
372                                   len > 0 ? " " : "", esc);
373                 assert(needed < allocated - len);
374                 len += needed;
375         }
376
377         if (!buf)
378                 buf = malloc0(1);
379
380         return buf;
381
382  oom:
383         free(buf);
384         return NULL;
385 }
386
387 int strv_push(char ***l, char *value) {
388         char **c;
389         unsigned n, m;
390
391         if (!value)
392                 return 0;
393
394         n = strv_length(*l);
395
396         /* Increase and check for overflow */
397         m = n + 2;
398         if (m < n)
399                 return -ENOMEM;
400
401         c = realloc_multiply(*l, sizeof(char*), m);
402         if (!c)
403                 return -ENOMEM;
404
405         c[n] = value;
406         c[n+1] = NULL;
407
408         *l = c;
409         return 0;
410 }
411
412 int strv_push_pair(char ***l, char *a, char *b) {
413         char **c;
414         unsigned n, m;
415
416         if (!a && !b)
417                 return 0;
418
419         n = strv_length(*l);
420
421         /* increase and check for overflow */
422         m = n + !!a + !!b + 1;
423         if (m < n)
424                 return -ENOMEM;
425
426         c = realloc_multiply(*l, sizeof(char*), m);
427         if (!c)
428                 return -ENOMEM;
429
430         if (a)
431                 c[n++] = a;
432         if (b)
433                 c[n++] = b;
434         c[n] = NULL;
435
436         *l = c;
437         return 0;
438 }
439
440 int strv_push_prepend(char ***l, char *value) {
441         char **c;
442         unsigned n, m, i;
443
444         if (!value)
445                 return 0;
446
447         n = strv_length(*l);
448
449         /* increase and check for overflow */
450         m = n + 2;
451         if (m < n)
452                 return -ENOMEM;
453
454         c = new(char*, m);
455         if (!c)
456                 return -ENOMEM;
457
458         for (i = 0; i < n; i++)
459                 c[i+1] = (*l)[i];
460
461         c[0] = value;
462         c[n+1] = NULL;
463
464         free(*l);
465         *l = c;
466
467         return 0;
468 }
469
470 int strv_consume(char ***l, char *value) {
471         int r;
472
473         r = strv_push(l, value);
474         if (r < 0)
475                 free(value);
476
477         return r;
478 }
479
480 int strv_consume_pair(char ***l, char *a, char *b) {
481         int r;
482
483         r = strv_push_pair(l, a, b);
484         if (r < 0) {
485                 free(a);
486                 free(b);
487         }
488
489         return r;
490 }
491
492 int strv_consume_prepend(char ***l, char *value) {
493         int r;
494
495         r = strv_push_prepend(l, value);
496         if (r < 0)
497                 free(value);
498
499         return r;
500 }
501
502 int strv_extend(char ***l, const char *value) {
503         char *v;
504
505         if (!value)
506                 return 0;
507
508         v = strdup(value);
509         if (!v)
510                 return -ENOMEM;
511
512         return strv_consume(l, v);
513 }
514
515 char **strv_uniq(char **l) {
516         char **i;
517
518         /* Drops duplicate entries. The first identical string will be
519          * kept, the others dropped */
520
521         STRV_FOREACH(i, l)
522                 strv_remove(i+1, *i);
523
524         return l;
525 }
526
527 bool strv_is_uniq(char **l) {
528         char **i;
529
530         STRV_FOREACH(i, l)
531                 if (strv_find(i+1, *i))
532                         return false;
533
534         return true;
535 }
536
537 char **strv_remove(char **l, const char *s) {
538         char **f, **t;
539
540         if (!l)
541                 return NULL;
542
543         assert(s);
544
545         /* Drops every occurrence of s in the string list, edits
546          * in-place. */
547
548         for (f = t = l; *f; f++)
549                 if (streq(*f, s))
550                         free(*f);
551                 else
552                         *(t++) = *f;
553
554         *t = NULL;
555         return l;
556 }
557
558 char **strv_parse_nulstr(const char *s, size_t l) {
559         const char *p;
560         unsigned c = 0, i = 0;
561         char **v;
562
563         assert(s || l <= 0);
564
565         if (l <= 0)
566                 return new0(char*, 1);
567
568         for (p = s; p < s + l; p++)
569                 if (*p == 0)
570                         c++;
571
572         if (s[l-1] != 0)
573                 c++;
574
575         v = new0(char*, c+1);
576         if (!v)
577                 return NULL;
578
579         p = s;
580         while (p < s + l) {
581                 const char *e;
582
583                 e = memchr(p, 0, s + l - p);
584
585                 v[i] = strndup(p, e ? e - p : s + l - p);
586                 if (!v[i]) {
587                         strv_free(v);
588                         return NULL;
589                 }
590
591                 i++;
592
593                 if (!e)
594                         break;
595
596                 p = e + 1;
597         }
598
599         assert(i == c);
600
601         return v;
602 }
603
604 char **strv_split_nulstr(const char *s) {
605         const char *i;
606         char **r = NULL;
607
608         NULSTR_FOREACH(i, s)
609                 if (strv_extend(&r, i) < 0) {
610                         strv_free(r);
611                         return NULL;
612                 }
613
614         if (!r)
615                 return strv_new(NULL, NULL);
616
617         return r;
618 }
619
620 bool strv_overlap(char **a, char **b) {
621         char **i;
622
623         STRV_FOREACH(i, a)
624                 if (strv_contains(b, *i))
625                         return true;
626
627         return false;
628 }
629
630 static int str_compare(const void *_a, const void *_b) {
631         const char **a = (const char**) _a, **b = (const char**) _b;
632
633         return strcmp(*a, *b);
634 }
635
636 char **strv_sort(char **l) {
637
638         if (strv_isempty(l))
639                 return l;
640
641         qsort(l, strv_length(l), sizeof(char*), str_compare);
642         return l;
643 }
644
645 bool strv_equal(char **a, char **b) {
646         if (!a || !b)
647                 return a == b;
648
649         for ( ; *a || *b; ++a, ++b)
650                 if (!streq_ptr(*a, *b))
651                         return false;
652
653         return true;
654 }
655
656 void strv_print(char **l) {
657         char **s;
658
659         STRV_FOREACH(s, l)
660                 puts(*s);
661 }
662
663 int strv_extendf(char ***l, const char *format, ...) {
664         va_list ap;
665         char *x;
666         int r;
667
668         va_start(ap, format);
669         r = vasprintf(&x, format, ap);
670         va_end(ap);
671
672         if (r < 0)
673                 return -ENOMEM;
674
675         return strv_consume(l, x);
676 }
677
678 char **strv_reverse(char **l) {
679         unsigned n, i;
680
681         n = strv_length(l);
682         if (n <= 1)
683                 return l;
684
685         for (i = 0; i < n / 2; i++) {
686                 char *t;
687
688                 t = l[i];
689                 l[i] = l[n-1-i];
690                 l[n-1-i] = t;
691         }
692
693         return l;
694 }