1
2
3
4
5
6
7
8
9
10
11
12#include <stdio.h>
13#include <string.h>
14#include <errno.h>
15
16#include "cmdl.h"
17
18static const struct cmd *find_cmd(const struct cmd *cmds, char *str)
19{
20 const struct cmd *c;
21 const struct cmd *match = NULL;
22
23 for (c = cmds; c->cmd; c++) {
24 if (strstr(c->cmd, str) != c->cmd)
25 continue;
26 if (match)
27 return NULL;
28 match = c;
29 }
30
31 return match;
32}
33
34struct opt *find_opt(struct opt *opts, char *str)
35{
36 struct opt *o;
37 struct opt *match = NULL;
38
39 for (o = opts; o->key; o++) {
40 if (strstr(o->key, str) != o->key)
41 continue;
42 if (match)
43 return NULL;
44
45 match = o;
46 }
47
48 return match;
49}
50
51struct opt *get_opt(struct opt *opts, char *key)
52{
53 struct opt *o;
54
55 for (o = opts; o->key; o++) {
56 if (strcmp(o->key, key) == 0 && o->val)
57 return o;
58 }
59
60 return NULL;
61}
62
63bool has_opt(struct opt *opts, char *key)
64{
65 return get_opt(opts, key) ? true : false;
66}
67
68char *shift_cmdl(struct cmdl *cmdl)
69{
70 int next;
71
72 if (cmdl->optind < cmdl->argc)
73 next = (cmdl->optind)++;
74 else
75 next = cmdl->argc;
76
77 return cmdl->argv[next];
78}
79
80
81int parse_opts(struct opt *opts, struct cmdl *cmdl)
82{
83 int i;
84 int cnt = 0;
85
86 for (i = cmdl->optind; i < cmdl->argc; i++) {
87 struct opt *o;
88
89 o = find_opt(opts, cmdl->argv[i]);
90 if (!o) {
91 fprintf(stderr, "error, invalid option \"%s\"\n",
92 cmdl->argv[i]);
93 return -EINVAL;
94 }
95 if (o->flag & OPT_KEYVAL) {
96 cmdl->optind++;
97 i++;
98 }
99 cnt++;
100 o->val = cmdl->argv[i];
101 cmdl->optind++;
102 }
103
104 return cnt;
105}
106
107int run_cmd(struct nlmsghdr *nlh, const struct cmd *caller,
108 const struct cmd *cmds, struct cmdl *cmdl, void *data)
109{
110 char *name;
111 const struct cmd *cmd;
112
113 if ((cmdl->optind) >= cmdl->argc) {
114 if (caller->help)
115 (caller->help)(cmdl);
116 return -EINVAL;
117 }
118 name = cmdl->argv[cmdl->optind];
119 (cmdl->optind)++;
120
121 cmd = find_cmd(cmds, name);
122 if (!cmd) {
123
124 if (help_flag && caller->help) {
125 (caller->help)(cmdl);
126 } else {
127 fprintf(stderr, "error, invalid command \"%s\"\n", name);
128 fprintf(stderr, "use --help for command help\n");
129 }
130 return -EINVAL;
131 }
132
133 return (cmd->func)(nlh, cmd, cmdl, data);
134}
135