]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/verbs.c
Merge pull request #6943 from poettering/dissect-ro
[thirdparty/systemd.git] / src / basic / verbs.c
CommitLineData
dca59f62
LP
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
11c3a366
TA
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"
07630cea 27#include "string-util.h"
dca59f62 28#include "verbs.h"
a16f96cd 29#include "virt.h"
dca59f62
LP
30
31int 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
43343ee7 58 if (name)
dca59f62 59 found = streq(name, verbs[i].verb);
43343ee7
LP
60 else
61 found = !!(verbs[i].flags & VERB_DEFAULT);
dca59f62
LP
62
63 if (found) {
64 verb = &verbs[i];
65 break;
66 }
67 }
68
43343ee7
LP
69 assert(verb);
70
71 if (!name)
72 left = 1;
73
dca59f62
LP
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) {
540d8581 82 log_error("Too many arguments.");
dca59f62
LP
83 return -EINVAL;
84 }
85
a16f96cd
LP
86 if ((verb->flags & VERB_NOCHROOT) && running_in_chroot() > 0) {
87 log_info("Running in chroot, ignoring request.");
88 return 0;
89 }
90
43343ee7
LP
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 }
dca59f62 101}