]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/verbs.c
cgroup: rework which files we chown() on delegation
[thirdparty/systemd.git] / src / basic / verbs.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2014 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 <errno.h>
21 #include <getopt.h>
22 #include <stdbool.h>
23 #include <stddef.h>
24
25 #include "log.h"
26 #include "macro.h"
27 #include "string-util.h"
28 #include "verbs.h"
29 #include "virt.h"
30
31 int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
32 const Verb *verb;
33 const char *name;
34 unsigned i;
35 int left;
36
37 assert(verbs);
38 assert(verbs[0].dispatch);
39 assert(argc >= 0);
40 assert(argv);
41 assert(argc >= optind);
42
43 left = argc - optind;
44 name = argv[optind];
45
46 for (i = 0;; i++) {
47 bool found;
48
49 /* At the end of the list? */
50 if (!verbs[i].dispatch) {
51 if (name)
52 log_error("Unknown operation %s.", name);
53 else
54 log_error("Requires operation parameter.");
55 return -EINVAL;
56 }
57
58 if (name)
59 found = streq(name, verbs[i].verb);
60 else
61 found = !!(verbs[i].flags & VERB_DEFAULT);
62
63 if (found) {
64 verb = &verbs[i];
65 break;
66 }
67 }
68
69 assert(verb);
70
71 if (!name)
72 left = 1;
73
74 if (verb->min_args != VERB_ANY &&
75 (unsigned) left < verb->min_args) {
76 log_error("Too few arguments.");
77 return -EINVAL;
78 }
79
80 if (verb->max_args != VERB_ANY &&
81 (unsigned) left > verb->max_args) {
82 log_error("Too many arguments.");
83 return -EINVAL;
84 }
85
86 if ((verb->flags & VERB_NOCHROOT) && running_in_chroot() > 0) {
87 log_info("Running in chroot, ignoring request.");
88 return 0;
89 }
90
91 if (name)
92 return verb->dispatch(left, argv + optind, userdata);
93 else {
94 char* fake[2] = {
95 (char*) verb->verb,
96 NULL
97 };
98
99 return verb->dispatch(1, fake, userdata);
100 }
101 }