]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/basic/unit-name.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / basic / unit-name.c
... / ...
CommitLineData
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 <errno.h>
23#include <string.h>
24
25#include "bus-label.h"
26#include "def.h"
27#include "path-util.h"
28#include "string-util.h"
29#include "strv.h"
30#include "util.h"
31#include "unit-name.h"
32
33#define VALID_CHARS \
34 DIGITS LETTERS \
35 ":-_.\\"
36
37bool unit_name_is_valid(const char *n, UnitNameFlags flags) {
38 const char *e, *i, *at;
39
40 assert((flags & ~(UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)) == 0);
41
42 if (_unlikely_(flags == 0))
43 return false;
44
45 if (isempty(n))
46 return false;
47
48 if (strlen(n) >= UNIT_NAME_MAX)
49 return false;
50
51 e = strrchr(n, '.');
52 if (!e || e == n)
53 return false;
54
55 if (unit_type_from_string(e + 1) < 0)
56 return false;
57
58 for (i = n, at = NULL; i < e; i++) {
59
60 if (*i == '@' && !at)
61 at = i;
62
63 if (!strchr("@" VALID_CHARS, *i))
64 return false;
65 }
66
67 if (at == n)
68 return false;
69
70 if (flags & UNIT_NAME_PLAIN)
71 if (!at)
72 return true;
73
74 if (flags & UNIT_NAME_INSTANCE)
75 if (at && e > at + 1)
76 return true;
77
78 if (flags & UNIT_NAME_TEMPLATE)
79 if (at && e == at + 1)
80 return true;
81
82 return false;
83}
84
85bool unit_prefix_is_valid(const char *p) {
86
87 /* We don't allow additional @ in the prefix string */
88
89 if (isempty(p))
90 return false;
91
92 return in_charset(p, VALID_CHARS);
93}
94
95bool unit_instance_is_valid(const char *i) {
96
97 /* The max length depends on the length of the string, so we
98 * don't really check this here. */
99
100 if (isempty(i))
101 return false;
102
103 /* We allow additional @ in the instance string, we do not
104 * allow them in the prefix! */
105
106 return in_charset(i, "@" VALID_CHARS);
107}
108
109bool unit_suffix_is_valid(const char *s) {
110 if (isempty(s))
111 return false;
112
113 if (s[0] != '.')
114 return false;
115
116 if (unit_type_from_string(s + 1) < 0)
117 return false;
118
119 return true;
120}
121
122int unit_name_to_prefix(const char *n, char **ret) {
123 const char *p;
124 char *s;
125
126 assert(n);
127 assert(ret);
128
129 if (!unit_name_is_valid(n, UNIT_NAME_ANY))
130 return -EINVAL;
131
132 p = strchr(n, '@');
133 if (!p)
134 p = strrchr(n, '.');
135
136 assert_se(p);
137
138 s = strndup(n, p - n);
139 if (!s)
140 return -ENOMEM;
141
142 *ret = s;
143 return 0;
144}
145
146int unit_name_to_instance(const char *n, char **instance) {
147 const char *p, *d;
148 char *i;
149
150 assert(n);
151 assert(instance);
152
153 if (!unit_name_is_valid(n, UNIT_NAME_ANY))
154 return -EINVAL;
155
156 /* Everything past the first @ and before the last . is the instance */
157 p = strchr(n, '@');
158 if (!p) {
159 *instance = NULL;
160 return 0;
161 }
162
163 p++;
164
165 d = strrchr(p, '.');
166 if (!d)
167 return -EINVAL;
168
169 i = strndup(p, d-p);
170 if (!i)
171 return -ENOMEM;
172
173 *instance = i;
174 return 1;
175}
176
177int unit_name_to_prefix_and_instance(const char *n, char **ret) {
178 const char *d;
179 char *s;
180
181 assert(n);
182 assert(ret);
183
184 if (!unit_name_is_valid(n, UNIT_NAME_ANY))
185 return -EINVAL;
186
187 d = strrchr(n, '.');
188 if (!d)
189 return -EINVAL;
190
191 s = strndup(n, d - n);
192 if (!s)
193 return -ENOMEM;
194
195 *ret = s;
196 return 0;
197}
198
199UnitType unit_name_to_type(const char *n) {
200 const char *e;
201
202 assert(n);
203
204 if (!unit_name_is_valid(n, UNIT_NAME_ANY))
205 return _UNIT_TYPE_INVALID;
206
207 assert_se(e = strrchr(n, '.'));
208
209 return unit_type_from_string(e + 1);
210}
211
212int unit_name_change_suffix(const char *n, const char *suffix, char **ret) {
213 char *e, *s;
214 size_t a, b;
215
216 assert(n);
217 assert(suffix);
218 assert(ret);
219
220 if (!unit_name_is_valid(n, UNIT_NAME_ANY))
221 return -EINVAL;
222
223 if (!unit_suffix_is_valid(suffix))
224 return -EINVAL;
225
226 assert_se(e = strrchr(n, '.'));
227
228 a = e - n;
229 b = strlen(suffix);
230
231 s = new(char, a + b + 1);
232 if (!s)
233 return -ENOMEM;
234
235 strcpy(mempcpy(s, n, a), suffix);
236 *ret = s;
237
238 return 0;
239}
240
241int unit_name_build(const char *prefix, const char *instance, const char *suffix, char **ret) {
242 char *s;
243
244 assert(prefix);
245 assert(suffix);
246 assert(ret);
247
248 if (!unit_prefix_is_valid(prefix))
249 return -EINVAL;
250
251 if (instance && !unit_instance_is_valid(instance))
252 return -EINVAL;
253
254 if (!unit_suffix_is_valid(suffix))
255 return -EINVAL;
256
257 if (!instance)
258 s = strappend(prefix, suffix);
259 else
260 s = strjoin(prefix, "@", instance, suffix, NULL);
261 if (!s)
262 return -ENOMEM;
263
264 *ret = s;
265 return 0;
266}
267
268static char *do_escape_char(char c, char *t) {
269 assert(t);
270
271 *(t++) = '\\';
272 *(t++) = 'x';
273 *(t++) = hexchar(c >> 4);
274 *(t++) = hexchar(c);
275
276 return t;
277}
278
279static char *do_escape(const char *f, char *t) {
280 assert(f);
281 assert(t);
282
283 /* do not create units with a leading '.', like for "/.dotdir" mount points */
284 if (*f == '.') {
285 t = do_escape_char(*f, t);
286 f++;
287 }
288
289 for (; *f; f++) {
290 if (*f == '/')
291 *(t++) = '-';
292 else if (*f == '-' || *f == '\\' || !strchr(VALID_CHARS, *f))
293 t = do_escape_char(*f, t);
294 else
295 *(t++) = *f;
296 }
297
298 return t;
299}
300
301char *unit_name_escape(const char *f) {
302 char *r, *t;
303
304 assert(f);
305
306 r = new(char, strlen(f)*4+1);
307 if (!r)
308 return NULL;
309
310 t = do_escape(f, r);
311 *t = 0;
312
313 return r;
314}
315
316int unit_name_unescape(const char *f, char **ret) {
317 _cleanup_free_ char *r = NULL;
318 char *t;
319
320 assert(f);
321
322 r = strdup(f);
323 if (!r)
324 return -ENOMEM;
325
326 for (t = r; *f; f++) {
327 if (*f == '-')
328 *(t++) = '/';
329 else if (*f == '\\') {
330 int a, b;
331
332 if (f[1] != 'x')
333 return -EINVAL;
334
335 a = unhexchar(f[2]);
336 if (a < 0)
337 return -EINVAL;
338
339 b = unhexchar(f[3]);
340 if (b < 0)
341 return -EINVAL;
342
343 *(t++) = (char) (((uint8_t) a << 4U) | (uint8_t) b);
344 f += 3;
345 } else
346 *(t++) = *f;
347 }
348
349 *t = 0;
350
351 *ret = r;
352 r = NULL;
353
354 return 0;
355}
356
357int unit_name_path_escape(const char *f, char **ret) {
358 char *p, *s;
359
360 assert(f);
361 assert(ret);
362
363 p = strdupa(f);
364 if (!p)
365 return -ENOMEM;
366
367 path_kill_slashes(p);
368
369 if (STR_IN_SET(p, "/", ""))
370 s = strdup("-");
371 else {
372 char *e;
373
374 if (!path_is_safe(p))
375 return -EINVAL;
376
377 /* Truncate trailing slashes */
378 e = endswith(p, "/");
379 if (e)
380 *e = 0;
381
382 /* Truncate leading slashes */
383 if (p[0] == '/')
384 p++;
385
386 s = unit_name_escape(p);
387 }
388 if (!s)
389 return -ENOMEM;
390
391 *ret = s;
392 return 0;
393}
394
395int unit_name_path_unescape(const char *f, char **ret) {
396 char *s;
397 int r;
398
399 assert(f);
400
401 if (isempty(f))
402 return -EINVAL;
403
404 if (streq(f, "-")) {
405 s = strdup("/");
406 if (!s)
407 return -ENOMEM;
408 } else {
409 char *w;
410
411 r = unit_name_unescape(f, &w);
412 if (r < 0)
413 return r;
414
415 /* Don't accept trailing or leading slashes */
416 if (startswith(w, "/") || endswith(w, "/")) {
417 free(w);
418 return -EINVAL;
419 }
420
421 /* Prefix a slash again */
422 s = strappend("/", w);
423 free(w);
424 if (!s)
425 return -ENOMEM;
426
427 if (!path_is_safe(s)) {
428 free(s);
429 return -EINVAL;
430 }
431 }
432
433 if (ret)
434 *ret = s;
435 else
436 free(s);
437
438 return 0;
439}
440
441int unit_name_replace_instance(const char *f, const char *i, char **ret) {
442 const char *p, *e;
443 char *s;
444 size_t a, b;
445
446 assert(f);
447 assert(i);
448 assert(ret);
449
450 if (!unit_name_is_valid(f, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE))
451 return -EINVAL;
452 if (!unit_instance_is_valid(i))
453 return -EINVAL;
454
455 assert_se(p = strchr(f, '@'));
456 assert_se(e = strrchr(f, '.'));
457
458 a = p - f;
459 b = strlen(i);
460
461 s = new(char, a + 1 + b + strlen(e) + 1);
462 if (!s)
463 return -ENOMEM;
464
465 strcpy(mempcpy(mempcpy(s, f, a + 1), i, b), e);
466
467 *ret = s;
468 return 0;
469}
470
471int unit_name_template(const char *f, char **ret) {
472 const char *p, *e;
473 char *s;
474 size_t a;
475
476 assert(f);
477 assert(ret);
478
479 if (!unit_name_is_valid(f, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE))
480 return -EINVAL;
481
482 assert_se(p = strchr(f, '@'));
483 assert_se(e = strrchr(f, '.'));
484
485 a = p - f;
486
487 s = new(char, a + 1 + strlen(e) + 1);
488 if (!s)
489 return -ENOMEM;
490
491 strcpy(mempcpy(s, f, a + 1), e);
492
493 *ret = s;
494 return 0;
495}
496
497int unit_name_from_path(const char *path, const char *suffix, char **ret) {
498 _cleanup_free_ char *p = NULL;
499 char *s = NULL;
500 int r;
501
502 assert(path);
503 assert(suffix);
504 assert(ret);
505
506 if (!unit_suffix_is_valid(suffix))
507 return -EINVAL;
508
509 r = unit_name_path_escape(path, &p);
510 if (r < 0)
511 return r;
512
513 s = strappend(p, suffix);
514 if (!s)
515 return -ENOMEM;
516
517 *ret = s;
518 return 0;
519}
520
521int unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix, char **ret) {
522 _cleanup_free_ char *p = NULL;
523 char *s;
524 int r;
525
526 assert(prefix);
527 assert(path);
528 assert(suffix);
529 assert(ret);
530
531 if (!unit_prefix_is_valid(prefix))
532 return -EINVAL;
533
534 if (!unit_suffix_is_valid(suffix))
535 return -EINVAL;
536
537 r = unit_name_path_escape(path, &p);
538 if (r < 0)
539 return r;
540
541 s = strjoin(prefix, "@", p, suffix, NULL);
542 if (!s)
543 return -ENOMEM;
544
545 *ret = s;
546 return 0;
547}
548
549int unit_name_to_path(const char *name, char **ret) {
550 _cleanup_free_ char *prefix = NULL;
551 int r;
552
553 assert(name);
554
555 r = unit_name_to_prefix(name, &prefix);
556 if (r < 0)
557 return r;
558
559 return unit_name_path_unescape(prefix, ret);
560}
561
562char *unit_dbus_path_from_name(const char *name) {
563 _cleanup_free_ char *e = NULL;
564
565 assert(name);
566
567 e = bus_label_escape(name);
568 if (!e)
569 return NULL;
570
571 return strappend("/org/freedesktop/systemd1/unit/", e);
572}
573
574int unit_name_from_dbus_path(const char *path, char **name) {
575 const char *e;
576 char *n;
577
578 e = startswith(path, "/org/freedesktop/systemd1/unit/");
579 if (!e)
580 return -EINVAL;
581
582 n = bus_label_unescape(e);
583 if (!n)
584 return -ENOMEM;
585
586 *name = n;
587 return 0;
588}
589
590const char* unit_dbus_interface_from_type(UnitType t) {
591
592 static const char *const table[_UNIT_TYPE_MAX] = {
593 [UNIT_SERVICE] = "org.freedesktop.systemd1.Service",
594 [UNIT_SOCKET] = "org.freedesktop.systemd1.Socket",
595 [UNIT_BUSNAME] = "org.freedesktop.systemd1.BusName",
596 [UNIT_TARGET] = "org.freedesktop.systemd1.Target",
597 [UNIT_SNAPSHOT] = "org.freedesktop.systemd1.Snapshot",
598 [UNIT_DEVICE] = "org.freedesktop.systemd1.Device",
599 [UNIT_MOUNT] = "org.freedesktop.systemd1.Mount",
600 [UNIT_AUTOMOUNT] = "org.freedesktop.systemd1.Automount",
601 [UNIT_SWAP] = "org.freedesktop.systemd1.Swap",
602 [UNIT_TIMER] = "org.freedesktop.systemd1.Timer",
603 [UNIT_PATH] = "org.freedesktop.systemd1.Path",
604 [UNIT_SLICE] = "org.freedesktop.systemd1.Slice",
605 [UNIT_SCOPE] = "org.freedesktop.systemd1.Scope",
606 };
607
608 if (t < 0)
609 return NULL;
610 if (t >= _UNIT_TYPE_MAX)
611 return NULL;
612
613 return table[t];
614}
615
616const char *unit_dbus_interface_from_name(const char *name) {
617 UnitType t;
618
619 t = unit_name_to_type(name);
620 if (t < 0)
621 return NULL;
622
623 return unit_dbus_interface_from_type(t);
624}
625
626static char *do_escape_mangle(const char *f, UnitNameMangle allow_globs, char *t) {
627 const char *valid_chars;
628
629 assert(f);
630 assert(IN_SET(allow_globs, UNIT_NAME_GLOB, UNIT_NAME_NOGLOB));
631 assert(t);
632
633 /* We'll only escape the obvious characters here, to play
634 * safe. */
635
636 valid_chars = allow_globs == UNIT_NAME_GLOB ? "@" VALID_CHARS "[]!-*?" : "@" VALID_CHARS;
637
638 for (; *f; f++) {
639 if (*f == '/')
640 *(t++) = '-';
641 else if (!strchr(valid_chars, *f))
642 t = do_escape_char(*f, t);
643 else
644 *(t++) = *f;
645 }
646
647 return t;
648}
649
650/**
651 * Convert a string to a unit name. /dev/blah is converted to dev-blah.device,
652 * /blah/blah is converted to blah-blah.mount, anything else is left alone,
653 * except that @suffix is appended if a valid unit suffix is not present.
654 *
655 * If @allow_globs, globs characters are preserved. Otherwise they are escaped.
656 */
657int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, const char *suffix, char **ret) {
658 char *s, *t;
659 int r;
660
661 assert(name);
662 assert(suffix);
663 assert(ret);
664
665 if (isempty(name)) /* We cannot mangle empty unit names to become valid, sorry. */
666 return -EINVAL;
667
668 if (!unit_suffix_is_valid(suffix))
669 return -EINVAL;
670
671 if (unit_name_is_valid(name, UNIT_NAME_ANY)) {
672 /* No mangling necessary... */
673 s = strdup(name);
674 if (!s)
675 return -ENOMEM;
676
677 *ret = s;
678 return 0;
679 }
680
681 if (is_device_path(name)) {
682 r = unit_name_from_path(name, ".device", ret);
683 if (r >= 0)
684 return 1;
685 if (r != -EINVAL)
686 return r;
687 }
688
689 if (path_is_absolute(name)) {
690 r = unit_name_from_path(name, ".mount", ret);
691 if (r >= 0)
692 return 1;
693 if (r != -EINVAL)
694 return r;
695 }
696
697 s = new(char, strlen(name) * 4 + strlen(suffix) + 1);
698 if (!s)
699 return -ENOMEM;
700
701 t = do_escape_mangle(name, allow_globs, s);
702 *t = 0;
703
704 if (unit_name_to_type(s) < 0)
705 strcpy(t, suffix);
706
707 *ret = s;
708 return 1;
709}
710
711int slice_build_parent_slice(const char *slice, char **ret) {
712 char *s, *dash;
713 int r;
714
715 assert(slice);
716 assert(ret);
717
718 if (!slice_name_is_valid(slice))
719 return -EINVAL;
720
721 if (streq(slice, "-.slice")) {
722 *ret = NULL;
723 return 0;
724 }
725
726 s = strdup(slice);
727 if (!s)
728 return -ENOMEM;
729
730 dash = strrchr(s, '-');
731 if (dash)
732 strcpy(dash, ".slice");
733 else {
734 r = free_and_strdup(&s, "-.slice");
735 if (r < 0) {
736 free(s);
737 return r;
738 }
739 }
740
741 *ret = s;
742 return 1;
743}
744
745int slice_build_subslice(const char *slice, const char*name, char **ret) {
746 char *subslice;
747
748 assert(slice);
749 assert(name);
750 assert(ret);
751
752 if (!slice_name_is_valid(slice))
753 return -EINVAL;
754
755 if (!unit_prefix_is_valid(name))
756 return -EINVAL;
757
758 if (streq(slice, "-.slice"))
759 subslice = strappend(name, ".slice");
760 else {
761 char *e;
762
763 assert_se(e = endswith(slice, ".slice"));
764
765 subslice = new(char, (e - slice) + 1 + strlen(name) + 6 + 1);
766 if (!subslice)
767 return -ENOMEM;
768
769 stpcpy(stpcpy(stpcpy(mempcpy(subslice, slice, e - slice), "-"), name), ".slice");
770 }
771
772 *ret = subslice;
773 return 0;
774}
775
776bool slice_name_is_valid(const char *name) {
777 const char *p, *e;
778 bool dash = false;
779
780 if (!unit_name_is_valid(name, UNIT_NAME_PLAIN))
781 return false;
782
783 if (streq(name, "-.slice"))
784 return true;
785
786 e = endswith(name, ".slice");
787 if (!e)
788 return false;
789
790 for (p = name; p < e; p++) {
791
792 if (*p == '-') {
793
794 /* Don't allow initial dash */
795 if (p == name)
796 return false;
797
798 /* Don't allow multiple dashes */
799 if (dash)
800 return false;
801
802 dash = true;
803 } else
804 dash = false;
805 }
806
807 /* Don't allow trailing hash */
808 if (dash)
809 return false;
810
811 return true;
812}
813
814static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
815 [UNIT_SERVICE] = "service",
816 [UNIT_SOCKET] = "socket",
817 [UNIT_BUSNAME] = "busname",
818 [UNIT_TARGET] = "target",
819 [UNIT_SNAPSHOT] = "snapshot",
820 [UNIT_DEVICE] = "device",
821 [UNIT_MOUNT] = "mount",
822 [UNIT_AUTOMOUNT] = "automount",
823 [UNIT_SWAP] = "swap",
824 [UNIT_TIMER] = "timer",
825 [UNIT_PATH] = "path",
826 [UNIT_SLICE] = "slice",
827 [UNIT_SCOPE] = "scope",
828};
829
830DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType);
831
832static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
833 [UNIT_STUB] = "stub",
834 [UNIT_LOADED] = "loaded",
835 [UNIT_NOT_FOUND] = "not-found",
836 [UNIT_ERROR] = "error",
837 [UNIT_MERGED] = "merged",
838 [UNIT_MASKED] = "masked"
839};
840
841DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
842
843static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
844 [UNIT_ACTIVE] = "active",
845 [UNIT_RELOADING] = "reloading",
846 [UNIT_INACTIVE] = "inactive",
847 [UNIT_FAILED] = "failed",
848 [UNIT_ACTIVATING] = "activating",
849 [UNIT_DEACTIVATING] = "deactivating"
850};
851
852DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
853
854static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
855 [AUTOMOUNT_DEAD] = "dead",
856 [AUTOMOUNT_WAITING] = "waiting",
857 [AUTOMOUNT_RUNNING] = "running",
858 [AUTOMOUNT_FAILED] = "failed"
859};
860
861DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
862
863static const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
864 [BUSNAME_DEAD] = "dead",
865 [BUSNAME_MAKING] = "making",
866 [BUSNAME_REGISTERED] = "registered",
867 [BUSNAME_LISTENING] = "listening",
868 [BUSNAME_RUNNING] = "running",
869 [BUSNAME_SIGTERM] = "sigterm",
870 [BUSNAME_SIGKILL] = "sigkill",
871 [BUSNAME_FAILED] = "failed",
872};
873
874DEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
875
876static const char* const device_state_table[_DEVICE_STATE_MAX] = {
877 [DEVICE_DEAD] = "dead",
878 [DEVICE_TENTATIVE] = "tentative",
879 [DEVICE_PLUGGED] = "plugged",
880};
881
882DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
883
884static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
885 [MOUNT_DEAD] = "dead",
886 [MOUNT_MOUNTING] = "mounting",
887 [MOUNT_MOUNTING_DONE] = "mounting-done",
888 [MOUNT_MOUNTED] = "mounted",
889 [MOUNT_REMOUNTING] = "remounting",
890 [MOUNT_UNMOUNTING] = "unmounting",
891 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
892 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
893 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
894 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
895 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
896 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
897 [MOUNT_FAILED] = "failed"
898};
899
900DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
901
902static const char* const path_state_table[_PATH_STATE_MAX] = {
903 [PATH_DEAD] = "dead",
904 [PATH_WAITING] = "waiting",
905 [PATH_RUNNING] = "running",
906 [PATH_FAILED] = "failed"
907};
908
909DEFINE_STRING_TABLE_LOOKUP(path_state, PathState);
910
911static const char* const scope_state_table[_SCOPE_STATE_MAX] = {
912 [SCOPE_DEAD] = "dead",
913 [SCOPE_RUNNING] = "running",
914 [SCOPE_ABANDONED] = "abandoned",
915 [SCOPE_STOP_SIGTERM] = "stop-sigterm",
916 [SCOPE_STOP_SIGKILL] = "stop-sigkill",
917 [SCOPE_FAILED] = "failed",
918};
919
920DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState);
921
922static const char* const service_state_table[_SERVICE_STATE_MAX] = {
923 [SERVICE_DEAD] = "dead",
924 [SERVICE_START_PRE] = "start-pre",
925 [SERVICE_START] = "start",
926 [SERVICE_START_POST] = "start-post",
927 [SERVICE_RUNNING] = "running",
928 [SERVICE_EXITED] = "exited",
929 [SERVICE_RELOAD] = "reload",
930 [SERVICE_STOP] = "stop",
931 [SERVICE_STOP_SIGABRT] = "stop-sigabrt",
932 [SERVICE_STOP_SIGTERM] = "stop-sigterm",
933 [SERVICE_STOP_SIGKILL] = "stop-sigkill",
934 [SERVICE_STOP_POST] = "stop-post",
935 [SERVICE_FINAL_SIGTERM] = "final-sigterm",
936 [SERVICE_FINAL_SIGKILL] = "final-sigkill",
937 [SERVICE_FAILED] = "failed",
938 [SERVICE_AUTO_RESTART] = "auto-restart",
939};
940
941DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
942
943static const char* const slice_state_table[_SLICE_STATE_MAX] = {
944 [SLICE_DEAD] = "dead",
945 [SLICE_ACTIVE] = "active"
946};
947
948DEFINE_STRING_TABLE_LOOKUP(slice_state, SliceState);
949
950static const char* const snapshot_state_table[_SNAPSHOT_STATE_MAX] = {
951 [SNAPSHOT_DEAD] = "dead",
952 [SNAPSHOT_ACTIVE] = "active"
953};
954
955DEFINE_STRING_TABLE_LOOKUP(snapshot_state, SnapshotState);
956
957static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
958 [SOCKET_DEAD] = "dead",
959 [SOCKET_START_PRE] = "start-pre",
960 [SOCKET_START_CHOWN] = "start-chown",
961 [SOCKET_START_POST] = "start-post",
962 [SOCKET_LISTENING] = "listening",
963 [SOCKET_RUNNING] = "running",
964 [SOCKET_STOP_PRE] = "stop-pre",
965 [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
966 [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
967 [SOCKET_STOP_POST] = "stop-post",
968 [SOCKET_FINAL_SIGTERM] = "final-sigterm",
969 [SOCKET_FINAL_SIGKILL] = "final-sigkill",
970 [SOCKET_FAILED] = "failed"
971};
972
973DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
974
975static const char* const swap_state_table[_SWAP_STATE_MAX] = {
976 [SWAP_DEAD] = "dead",
977 [SWAP_ACTIVATING] = "activating",
978 [SWAP_ACTIVATING_DONE] = "activating-done",
979 [SWAP_ACTIVE] = "active",
980 [SWAP_DEACTIVATING] = "deactivating",
981 [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
982 [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
983 [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
984 [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
985 [SWAP_FAILED] = "failed"
986};
987
988DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
989
990static const char* const target_state_table[_TARGET_STATE_MAX] = {
991 [TARGET_DEAD] = "dead",
992 [TARGET_ACTIVE] = "active"
993};
994
995DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState);
996
997static const char* const timer_state_table[_TIMER_STATE_MAX] = {
998 [TIMER_DEAD] = "dead",
999 [TIMER_WAITING] = "waiting",
1000 [TIMER_RUNNING] = "running",
1001 [TIMER_ELAPSED] = "elapsed",
1002 [TIMER_FAILED] = "failed"
1003};
1004
1005DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
1006
1007static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
1008 [UNIT_REQUIRES] = "Requires",
1009 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
1010 [UNIT_REQUISITE] = "Requisite",
1011 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
1012 [UNIT_WANTS] = "Wants",
1013 [UNIT_BINDS_TO] = "BindsTo",
1014 [UNIT_PART_OF] = "PartOf",
1015 [UNIT_REQUIRED_BY] = "RequiredBy",
1016 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
1017 [UNIT_REQUISITE_OF] = "RequisiteOf",
1018 [UNIT_REQUISITE_OF_OVERRIDABLE] = "RequisiteOfOverridable",
1019 [UNIT_WANTED_BY] = "WantedBy",
1020 [UNIT_BOUND_BY] = "BoundBy",
1021 [UNIT_CONSISTS_OF] = "ConsistsOf",
1022 [UNIT_CONFLICTS] = "Conflicts",
1023 [UNIT_CONFLICTED_BY] = "ConflictedBy",
1024 [UNIT_BEFORE] = "Before",
1025 [UNIT_AFTER] = "After",
1026 [UNIT_ON_FAILURE] = "OnFailure",
1027 [UNIT_TRIGGERS] = "Triggers",
1028 [UNIT_TRIGGERED_BY] = "TriggeredBy",
1029 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
1030 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
1031 [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
1032 [UNIT_REFERENCES] = "References",
1033 [UNIT_REFERENCED_BY] = "ReferencedBy",
1034};
1035
1036DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);