]> git.proxmox.com Git - mirror_iproute2.git/blame - tipc/cmdl.c
Revert "tipc: add peer remove functionality"
[mirror_iproute2.git] / tipc / cmdl.c
CommitLineData
f043759d
RA
1/*
2 * cmdl.c Framework for handling command line options.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Richard Alpe <richard.alpe@ericsson.com>
10 */
11
12#include <stdio.h>
13#include <string.h>
14#include <errno.h>
15
16#include <libmnl/libmnl.h>
17
18#include "cmdl.h"
19
20const struct cmd *find_cmd(const struct cmd *cmds, char *str)
21{
22 const struct cmd *c;
23 const struct cmd *match = NULL;
24
25 for (c = cmds; c->cmd; c++) {
26 if (strstr(c->cmd, str) != c->cmd)
27 continue;
28 if (match)
29 return NULL;
30 match = c;
31 }
32
33 return match;
34}
35
36static struct opt *find_opt(struct opt *opts, char *str)
37{
38 struct opt *o;
39 struct opt *match = NULL;
40
41 for (o = opts; o->key; o++) {
42 if (strstr(o->key, str) != o->key)
43 continue;
44 if (match)
45 return NULL;
46
47 match = o;
48 }
49
50 return match;
51}
52
53struct opt *get_opt(struct opt *opts, char *key)
54{
55 struct opt *o;
56
57 for (o = opts; o->key; o++) {
58 if (strcmp(o->key, key) == 0 && o->val)
59 return o;
60 }
61
62 return NULL;
63}
64
65char *shift_cmdl(struct cmdl *cmdl)
66{
67 int next;
68
69 if (cmdl->optind < cmdl->argc)
70 next = (cmdl->optind)++;
71 else
72 next = cmdl->argc;
73
74 return cmdl->argv[next];
75}
76
77/* Returns the number of options parsed or a negative error code upon failure */
78int parse_opts(struct opt *opts, struct cmdl *cmdl)
79{
80 int i;
81 int cnt = 0;
82
83 for (i = cmdl->optind; i < cmdl->argc; i += 2) {
84 struct opt *o;
85
86 o = find_opt(opts, cmdl->argv[i]);
87 if (!o) {
88 fprintf(stderr, "error, invalid option \"%s\"\n",
89 cmdl->argv[i]);
90 return -EINVAL;
91 }
92 cnt++;
93 o->val = cmdl->argv[i + 1];
94 cmdl->optind += 2;
95 }
96
97 return cnt;
98}
99
100int run_cmd(struct nlmsghdr *nlh, const struct cmd *caller,
101 const struct cmd *cmds, struct cmdl *cmdl, void *data)
102{
103 char *name;
104 const struct cmd *cmd;
105
106 if ((cmdl->optind) >= cmdl->argc) {
107 if (caller->help)
108 (caller->help)(cmdl);
109 return -EINVAL;
110 }
111 name = cmdl->argv[cmdl->optind];
112 (cmdl->optind)++;
113
114 cmd = find_cmd(cmds, name);
115 if (!cmd) {
116 /* Show help about last command if we don't find this one */
117 if (help_flag && caller->help) {
118 (caller->help)(cmdl);
119 } else {
120 fprintf(stderr, "error, invalid command \"%s\"\n", name);
121 fprintf(stderr, "use --help for command help\n");
122 }
123 return -EINVAL;
124 }
125
126 return (cmd->func)(nlh, cmd, cmdl, data);
127}