c0179e7a544699cdbf4d576ad3420e355fc0efdd
[project/ubox.git] / validate / cli.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include <ctype.h>
6
7 #include <arpa/inet.h>
8 #include <netinet/ether.h>
9 #include <sys/stat.h>
10
11 #include <uci.h>
12
13 #include "libvalidate.h"
14
15 static void
16 print_usage(char *argv)
17 {
18         fprintf(stderr, "%s <datatype> <value>\t- validate a value against a type\n", argv);
19         fprintf(stderr, "%s <package> <section_type> <section_name> 'option:datatype:default' 'option:datatype:default' ...\n", argv);
20 }
21
22 static char*
23 bool_to_num(char *val)
24 {
25         static char val0[] = "0";
26         static char val1[] = "1";
27         static char val_none[] = "";
28
29         if (!strcmp(val, "0") || !strcmp(val, "off") || !strcmp(val, "false") || !strcmp(val, "disabled"))
30                 return val0;
31         if (!strcmp(val, "1") || !strcmp(val, "on") || !strcmp(val, "true") || !strcmp(val, "enabled"))
32                 return val1;
33
34         return val_none;
35 }
36
37 static int
38 validate_option(struct uci_context *ctx, char *package, char *section, char *option)
39 {
40         char *datatype = strstr(option, ":");
41         struct uci_ptr ptr = { 0 };
42         char *val;
43         int ret = 0;
44
45         if (!datatype) {
46                 fprintf(stderr, "%s is not a valid option\n", option);
47                 return -1;
48         }
49
50         *datatype = '\0';
51         datatype++;
52         val = strstr(datatype, ":");
53         if (val) {
54                 *val = '\0';
55                 val++;
56         }
57
58         ptr.package = package;
59         ptr.section = section;
60         ptr.option = option;
61
62         if (!uci_lookup_ptr(ctx, &ptr, NULL, false))
63                 if (ptr.flags & UCI_LOOKUP_COMPLETE)
64                         if (ptr.last->type == UCI_TYPE_OPTION)
65                                 if ( ptr.o->type == UCI_TYPE_STRING)
66                                         if (ptr.o->v.string)
67                                                 val = ptr.o->v.string;
68
69         if (val) {
70                 ret = dt_parse(datatype, val);
71                 fprintf(stderr, "%s.%s.%s=%s validates as %s with %s\n", package, section, option,
72                         val, datatype, ret ? "true" : "false");
73         }
74
75         if (ret && !strcmp(datatype, "bool"))
76                 printf("%s=%s; ", option, bool_to_num(val));
77         else if (ret)
78                 printf("%s=%s; ", option, val);
79         else
80                 printf("unset -v %s; ", option);
81
82         return ret;
83 }
84
85 int
86 main(int argc, char **argv)
87 {
88         struct uci_context *ctx;
89         struct uci_package *package;
90         int len = argc - 4;
91         bool rv;
92         int i;
93
94         if (argc == 3) {
95                 rv = dt_parse(argv[1], argv[2]);
96                 fprintf(stderr, "%s - %s = %s\n", argv[1], argv[2], rv ? "true" : "false");
97                 return rv ? 0 : 1;
98         } else if (argc < 5) {
99                 print_usage(*argv);
100                 return -1;
101         }
102
103         if (*argv[3] == '\0') {
104                 printf("json_add_object; ");
105                 printf("json_add_string \"package\" \"%s\"; ", argv[1]);
106                 printf("json_add_string \"type\" \"%s\"; ", argv[2]);
107                 printf("json_add_object \"data\"; ");
108
109                 for (i = 0; i < len; i++) {
110                         char *datatype = strstr(argv[4 + i], ":");
111                         char *def;
112
113                         if (!datatype)
114                                 continue;
115                         *datatype = '\0';
116                         datatype++;
117                         def = strstr(datatype, ":");
118                         if (def)
119                                 *def = '\0';
120                         printf("json_add_string \"%s\" \"%s\"; ", argv[4 + i], datatype);
121                 }
122                 printf("json_close_object; ");
123                 printf("json_close_object; ");
124
125                 return 0;
126         }
127
128         ctx = uci_alloc_context();
129         if (!ctx)
130                 return -1;
131
132         if (uci_load(ctx, argv[1], &package))
133                 return -1;
134
135         for (i = 0; i < len; i++)
136                 validate_option(ctx, argv[1], argv[3], argv[4 + i]);
137
138         return 0;
139 }