Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2014 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 "util.h"
23 : #include "verbs.h"
24 :
25 7 : int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
26 : const Verb *verb;
27 : const char *name;
28 : unsigned i;
29 : int left;
30 :
31 7 : assert(verbs);
32 7 : assert(verbs[0].dispatch);
33 7 : assert(argc >= 0);
34 7 : assert(argv);
35 7 : assert(argc >= optind);
36 :
37 7 : left = argc - optind;
38 7 : name = argv[optind];
39 :
40 39 : for (i = 0;; i++) {
41 : bool found;
42 :
43 : /* At the end of the list? */
44 39 : if (!verbs[i].dispatch) {
45 2 : if (name)
46 1 : log_error("Unknown operation %s.", name);
47 : else
48 1 : log_error("Requires operation parameter.");
49 2 : return -EINVAL;
50 : }
51 :
52 37 : if (name)
53 33 : found = streq(name, verbs[i].verb);
54 : else
55 4 : found = !!(verbs[i].flags & VERB_DEFAULT);
56 :
57 37 : if (found) {
58 5 : verb = &verbs[i];
59 5 : break;
60 : }
61 32 : }
62 :
63 5 : assert(verb);
64 :
65 5 : if (!name)
66 1 : left = 1;
67 :
68 8 : if (verb->min_args != VERB_ANY &&
69 3 : (unsigned) left < verb->min_args) {
70 1 : log_error("Too few arguments.");
71 1 : return -EINVAL;
72 : }
73 :
74 6 : if (verb->max_args != VERB_ANY &&
75 2 : (unsigned) left > verb->max_args) {
76 1 : log_error("Too many arguments.");
77 1 : return -EINVAL;
78 : }
79 :
80 3 : if (name)
81 2 : return verb->dispatch(left, argv + optind, userdata);
82 : else {
83 1 : char* fake[2] = {
84 1 : (char*) verb->verb,
85 : NULL
86 : };
87 :
88 1 : return verb->dispatch(1, fake, userdata);
89 : }
90 : }
|