043ba1a05d90063093c3d50c1b07916b3a6664e9
[project/uci.git] / cli.c
1 /*
2  * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2
6  * as published by the Free Software Foundation
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 #include <strings.h>
14 #include <stdlib.h>
15 #include "uci.h"
16
17 static const char *appname = "uci";
18
19 static struct uci_context *ctx;
20 enum {
21         CMD_GET,
22         CMD_SET,
23         CMD_DEL
24 };
25
26 static void uci_usage(int argc, char **argv)
27 {
28         fprintf(stderr,
29                 "Usage: %s [<options>] <command> [<arguments>]\n\n"
30                 "Commands:\n"
31                 "\texport   [<config>]\n"
32                 "\tshow     [<config>[.<section>[.<option>]]]\n"
33                 "\tget      <config>.<section>[.<option>]\n"
34                 "\tset      <config>.<section>[.<option>]=<value>\n"
35                 "\n",
36                 argv[0]
37         );
38         exit(255);
39 }
40
41 static void uci_show_section(struct uci_section *p)
42 {
43         struct uci_element *e;
44         const char *cname, *sname;
45
46         cname = p->package->e.name;
47         sname = p->e.name;
48         printf("%s.%s=%s\n", cname, sname, p->type);
49         uci_foreach_element(&p->options, e) {
50                 printf("%s.%s.%s=%s\n", cname, sname, e->name, uci_to_option(e)->value);
51         }
52 }
53
54 static void uci_show_package(struct uci_package *p, char *section)
55 {
56         struct uci_element *e;
57
58         uci_foreach_element( &p->sections, e) {
59                 if (!section || !strcmp(e->name, section))
60                         uci_show_section(uci_to_section(e));
61         }
62 }
63
64 static int uci_show(int argc, char **argv)
65 {
66         char *section = (argc > 2 ? argv[2] : NULL);
67         struct uci_package *package;
68         char **configs;
69         char **p;
70
71         configs = uci_list_configs(ctx);
72         if (!configs)
73                 return 0;
74
75         if (argc >= 2) {
76                 if (uci_load(ctx, argv[1], &package) != UCI_OK) {
77                         uci_perror(ctx, NULL);
78                         return 1;
79                 }
80                 uci_show_package(package, section);
81                 uci_unload(ctx, package);
82                 return 0;
83         }
84
85         for (p = configs; *p; p++) {
86                 if ((argc < 2) || !strcmp(argv[1], *p)) {
87                         if (uci_load(ctx, *p, &package) != UCI_OK) {
88                                 uci_perror(ctx, NULL);
89                                 return 1;
90                         }
91                         uci_show_package(package, section);
92                         uci_unload(ctx, package);
93                 }
94         }
95
96         return 0;
97 }
98
99 static int uci_do_export(int argc, char **argv)
100 {
101         char **configs = uci_list_configs(ctx);
102         char **p;
103
104         if (!configs)
105                 return 0;
106
107         for (p = configs; *p; p++) {
108                 if ((argc < 2) || !strcmp(argv[1], *p)) {
109                         struct uci_package *package = NULL;
110                         int ret;
111
112                         ret = uci_load(ctx, *p, &package);
113                         if (ret)
114                                 continue;
115                         uci_export(ctx, stdout, package, true);
116                         uci_unload(ctx, package);
117                 }
118         }
119         return 0;
120 }
121
122 static int uci_do_cmd(int cmd, int argc, char **argv)
123 {
124         char *package = NULL;
125         char *section = NULL;
126         char *option = NULL;
127         char *value = NULL;
128         struct uci_package *p = NULL;
129         struct uci_element *e = NULL;
130
131         if (argc != 2)
132                 return 255;
133
134         if (uci_parse_tuple(ctx, argv[1], &package, &section, &option, (cmd == CMD_SET ? &value : NULL)) != UCI_OK)
135                 return 1;
136
137         if (uci_load(ctx, package, &p) != UCI_OK) {
138                 uci_perror(ctx, appname);
139                 return 1;
140         }
141
142         if (uci_lookup(ctx, &e, p, section, option) != UCI_OK)
143                 return 1;
144
145         switch(cmd) {
146         case CMD_GET:
147                 switch(e->type) {
148                 case UCI_TYPE_SECTION:
149                         value = uci_to_section(e)->type;
150                         break;
151                 case UCI_TYPE_OPTION:
152                         value = uci_to_option(e)->value;
153                         break;
154                 default:
155                         /* should not happen */
156                         return 1;
157                 }
158                 /* throw the value to stdout */
159                 printf("%s\n", value);
160                 break;
161         case CMD_SET:
162                 if (uci_set(ctx, p, section, option, value) != UCI_OK) {
163                         uci_perror(ctx, appname);
164                         return 1;
165                 }
166                 break;
167         case CMD_DEL:
168                 if (uci_del(ctx, p, section, option) != UCI_OK) {
169                         uci_perror(ctx, appname);
170                         return 1;
171                 }
172                 break;
173         }
174
175         /* no save necessary for get */
176         if (cmd == CMD_GET)
177                 return 0;
178
179         /* save changes, but don't commit them yet */
180         if (uci_save(ctx, p) != UCI_OK) {
181                 uci_perror(ctx, appname);
182                 return 1;
183         }
184
185         return 0;
186 }
187
188 static int uci_cmd(int argc, char **argv)
189 {
190         int cmd;
191
192         if (!strcasecmp(argv[0], "show"))
193                 return uci_show(argc, argv);
194         if (!strcasecmp(argv[0], "export"))
195                 return uci_do_export(argc, argv);
196
197         if (!strcasecmp(argv[0], "get"))
198                 cmd = CMD_GET;
199         else if (!strcasecmp(argv[0], "set"))
200                 cmd = CMD_SET;
201         else if (!strcasecmp(argv[0], "del"))
202                 cmd = CMD_DEL;
203         else
204                 return 255;
205         return uci_do_cmd(cmd, argc, argv);
206 }
207
208 int main(int argc, char **argv)
209 {
210         int ret;
211
212         ctx = uci_alloc_context();
213         if (argc < 2)
214                 uci_usage(argc, argv);
215         ret = uci_cmd(argc - 1, argv + 1);
216         if (ret == 255)
217                 uci_usage(argc, argv);
218         uci_free_context(ctx);
219
220         return ret;
221 }