]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxcmd/command.c
xfsprogs: handle symlinks etc in fs_table_initialise_mounts()
[thirdparty/xfsprogs-dev.git] / libxcmd / command.c
1 /*
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <xfs/xfs.h>
20 #include <xfs/command.h>
21 #include <xfs/input.h>
22
23 cmdinfo_t *cmdtab;
24 int ncmds;
25
26 static argsfunc_t args_func;
27 static checkfunc_t check_func;
28 static int ncmdline;
29 static char **cmdline;
30
31 static int
32 compare(const void *a, const void *b)
33 {
34 return strcmp(((const cmdinfo_t *)a)->name,
35 ((const cmdinfo_t *)b)->name);
36 }
37
38 void
39 add_command(
40 const cmdinfo_t *ci)
41 {
42 cmdtab = realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
43 cmdtab[ncmds - 1] = *ci;
44 qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
45 }
46
47 static int
48 check_command(
49 const cmdinfo_t *ci)
50 {
51 if (check_func)
52 return check_func(ci);
53 return 1;
54 }
55
56 void
57 add_check_command(
58 checkfunc_t cf)
59 {
60 check_func = cf;
61 }
62
63 int
64 command_usage(
65 const cmdinfo_t *ci)
66 {
67 printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
68 return 0;
69 }
70
71 int
72 command(
73 const cmdinfo_t *ct,
74 int argc,
75 char **argv)
76 {
77 char *cmd = argv[0];
78
79 if (!check_command(ct))
80 return 0;
81
82 if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) {
83 if (ct->argmax == -1)
84 fprintf(stderr,
85 _("bad argument count %d to %s, expected at least %d arguments\n"),
86 argc-1, cmd, ct->argmin);
87 else if (ct->argmin == ct->argmax)
88 fprintf(stderr,
89 _("bad argument count %d to %s, expected %d arguments\n"),
90 argc-1, cmd, ct->argmin);
91 else
92 fprintf(stderr,
93 _("bad argument count %d to %s, expected between %d and %d arguments\n"),
94 argc-1, cmd, ct->argmin, ct->argmax);
95 return 0;
96 }
97 platform_getoptreset();
98 return ct->cfunc(argc, argv);
99 }
100
101 const cmdinfo_t *
102 find_command(
103 const char *cmd)
104 {
105 cmdinfo_t *ct;
106
107 for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
108 if (strcmp(ct->name, cmd) == 0 ||
109 (ct->altname && strcmp(ct->altname, cmd) == 0))
110 return (const cmdinfo_t *)ct;
111 }
112 return NULL;
113 }
114
115 void
116 add_user_command(char *optarg)
117 {
118 ncmdline++;
119 cmdline = realloc(cmdline, sizeof(char*) * (ncmdline));
120 if (!cmdline) {
121 perror("realloc");
122 exit(1);
123 }
124 cmdline[ncmdline-1] = optarg;
125 }
126
127 static int
128 args_command(
129 int index)
130 {
131 if (args_func)
132 return args_func(index);
133 return 0;
134 }
135
136 void
137 add_args_command(
138 argsfunc_t af)
139 {
140 args_func = af;
141 }
142
143 void
144 command_loop(void)
145 {
146 int c, i, j = 0, done = 0;
147 char *input;
148 char **v;
149 const cmdinfo_t *ct;
150
151 for (i = 0; !done && i < ncmdline; i++) {
152 input = strdup(cmdline[i]);
153 if (!input) {
154 fprintf(stderr,
155 _("cannot strdup command '%s': %s\n"),
156 cmdline[i], strerror(errno));
157 exit(1);
158 }
159 v = breakline(input, &c);
160 if (c) {
161 ct = find_command(v[0]);
162 if (ct) {
163 if (ct->flags & CMD_FLAG_GLOBAL)
164 done = command(ct, c, v);
165 else {
166 j = 0;
167 while (!done && (j = args_command(j)))
168 done = command(ct, c, v);
169 }
170 } else
171 fprintf(stderr, _("command \"%s\" not found\n"),
172 v[0]);
173 }
174 doneline(input, v);
175 }
176 if (cmdline) {
177 free(cmdline);
178 return;
179 }
180 while (!done) {
181 if ((input = fetchline()) == NULL)
182 break;
183 v = breakline(input, &c);
184 if (c) {
185 ct = find_command(v[0]);
186 if (ct)
187 done = command(ct, c, v);
188 else
189 fprintf(stderr, _("command \"%s\" not found\n"),
190 v[0]);
191 }
192 doneline(input, v);
193 }
194 }