1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif /* HAVE_CONFIG_H */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 #include <errno.h>
12 #include <assert.h>
13 #if WITH_INTERNAL_GETOPT
14 #include "libc/getopt.h"
15 #else
16 #ifdef HAVE_GETOPT_H
17 #include <getopt.h>
18 #endif
19 #endif
20
21 #include "lub/types.h"
22 #include "lub/argv.h"
23 #include "lub/string.h"
24 #include "lub/conv.h"
25 #include "private.h"
26
27 /*-------------------------------------------------------- */
konf_query_new(void)28 konf_query_t *konf_query_new(void)
29 {
30 konf_query_t *this;
31
32 if (!(this = malloc(sizeof(*this))))
33 return NULL;
34
35 this->op = KONF_QUERY_OP_NONE;
36 this->pattern = NULL;
37 this->priority = 0;
38 this->seq = BOOL_FALSE;
39 this->seq_num = 0;
40 this->pwdc = 0;
41 this->pwd = NULL;
42 this->line = NULL;
43 this->path = NULL;
44 this->splitter = BOOL_TRUE;
45 this->unique = BOOL_TRUE;
46 this->depth = -1;
47
48 return this;
49 }
50
51 /*-------------------------------------------------------- */
konf_query_add_pwd(konf_query_t * this,char * str)52 void konf_query_add_pwd(konf_query_t *this, char *str)
53 {
54 size_t new_size;
55 char **tmp;
56
57 if (!this)
58 return;
59
60 new_size = ((this->pwdc + 1) * sizeof(char *));
61
62 /* resize the pwd vector */
63 tmp = realloc(this->pwd, new_size);
64 assert(tmp);
65 this->pwd = tmp;
66 /* insert reference to the pwd component */
67 this->pwd[this->pwdc++] = strdup(str);
68 }
69
70 /*-------------------------------------------------------- */
konf_query_free(konf_query_t * this)71 void konf_query_free(konf_query_t *this)
72 {
73 unsigned i;
74
75 free(this->pattern);
76 free(this->line);
77 free(this->path);
78 if (this->pwdc > 0) {
79 for (i = 0; i < this->pwdc; i++)
80 free(this->pwd[i]);
81 free(this->pwd);
82 }
83
84 free(this);
85 }
86
87 /*-------------------------------------------------------- */
88 /* Parse query */
konf_query_parse(konf_query_t * this,int argc,char ** argv)89 int konf_query_parse(konf_query_t *this, int argc, char **argv)
90 {
91 int i = 0;
92 int pwdc = 0;
93
94 static const char *shortopts = "suoedtp:q:r:l:f:inh:";
95 #ifdef HAVE_GETOPT_LONG
96 static const struct option longopts[] = {
97 {"set", 0, NULL, 's'},
98 {"unset", 0, NULL, 'u'},
99 {"ok", 0, NULL, 'o'},
100 {"error", 0, NULL, 'e'},
101 {"dump", 0, NULL, 'd'},
102 {"stream", 0, NULL, 't'},
103 {"priority", 1, NULL, 'p'},
104 {"seq", 1, NULL, 'q'},
105 {"pattern", 1, NULL, 'r'},
106 {"line", 1, NULL, 'l'},
107 {"file", 1, NULL, 'f'},
108 {"splitter", 0, NULL, 'i'},
109 {"non-unique", 0, NULL, 'n'},
110 {"depth", 1, NULL, 'h'},
111 {NULL, 0, NULL, 0}
112 };
113 #endif
114
115 optind = 0; /* It must be 1 for QNX6. This system has no getopt.h */
116 while(1) {
117 int opt;
118 #ifdef HAVE_GETOPT_LONG
119 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
120 #else
121 opt = getopt(argc, argv, shortopts);
122 #endif
123 if (-1 == opt)
124 break;
125 switch (opt) {
126 case 'o':
127 this->op = KONF_QUERY_OP_OK;
128 break;
129 case 'e':
130 this->op = KONF_QUERY_OP_ERROR;
131 break;
132 case 's':
133 this->op = KONF_QUERY_OP_SET;
134 break;
135 case 'u':
136 this->op = KONF_QUERY_OP_UNSET;
137 break;
138 case 'd':
139 this->op = KONF_QUERY_OP_DUMP;
140 break;
141 case 't':
142 this->op = KONF_QUERY_OP_STREAM;
143 break;
144 case 'p':
145 {
146 unsigned short val = 0;
147 if (lub_conv_atous(optarg, &val, 0) < 0)
148 break;
149 this->priority = val;
150 break;
151 }
152 case 'q':
153 {
154 unsigned short val = 0;
155 this->seq = BOOL_TRUE;
156 if (lub_conv_atous(optarg, &val, 0) < 0)
157 break;
158 this->seq_num = val;
159 break;
160 }
161 case 'r':
162 this->pattern = strdup(optarg);
163 break;
164 case 'l':
165 this->line = strdup(optarg);
166 break;
167 case 'f':
168 this->path = strdup(optarg);
169 break;
170 case 'i':
171 this->splitter = BOOL_FALSE;
172 break;
173 case 'n':
174 this->unique = BOOL_FALSE;
175 break;
176 case 'h':
177 {
178 unsigned short val = 0;
179 if (lub_conv_atous(optarg, &val, 0) < 0)
180 break;
181 this->depth = val;
182 break;
183 }
184 default:
185 break;
186 }
187 }
188
189 /* Check options */
190 if (KONF_QUERY_OP_NONE == this->op)
191 return -1;
192 if (KONF_QUERY_OP_SET == this->op) {
193 if (!this->pattern)
194 return -1;
195 if (!this->line)
196 return -1;
197 }
198
199 if ((pwdc = argc - optind) < 0)
200 return -1;
201
202 for (i = 0; i < pwdc; i++)
203 konf_query_add_pwd(this, argv[optind + i]);
204
205 return 0;
206 }
207
208 /*-------------------------------------------------------- */
209 /* Parse query string */
konf_query_parse_str(konf_query_t * this,char * str)210 int konf_query_parse_str(konf_query_t *this, char *str)
211 {
212 int res;
213 lub_argv_t *lub_argv;
214 char **str_argv;
215 int str_argc;
216
217 /* Make args from string */
218 lub_argv = lub_argv_new(str, 0);
219 str_argv = lub_argv__get_argv(lub_argv, "");
220 str_argc = lub_argv__get_count(lub_argv) + 1;
221
222 /* Parse query */
223 res = konf_query_parse(this, str_argc, str_argv);
224 lub_argv__free_argv(str_argv);
225 lub_argv_delete(lub_argv);
226
227 return res;
228 }
229
230 /*-------------------------------------------------------- */
konf_query__get_pwd(konf_query_t * this,unsigned index)231 char * konf_query__get_pwd(konf_query_t *this, unsigned index)
232 {
233 if (!this)
234 return NULL;
235 if (index >= this->pwdc)
236 return NULL;
237
238 return this->pwd[index];
239 }
240
241 /*-------------------------------------------------------- */
konf_query__get_pwdc(konf_query_t * this)242 int konf_query__get_pwdc(konf_query_t *this)
243 {
244 return this->pwdc;
245 }
246
247 /*-------------------------------------------------------- */
konf_query__get_op(konf_query_t * this)248 konf_query_op_e konf_query__get_op(konf_query_t *this)
249 {
250 return this->op;
251 }
252
253 /*-------------------------------------------------------- */
konf_query__get_path(konf_query_t * this)254 char * konf_query__get_path(konf_query_t *this)
255 {
256 return this->path;
257 }
258
259 /*-------------------------------------------------------- */
konf_query__get_pattern(konf_query_t * this)260 const char * konf_query__get_pattern(konf_query_t *this)
261 {
262 return this->pattern;
263 }
264
265 /*-------------------------------------------------------- */
konf_query__get_line(konf_query_t * this)266 const char * konf_query__get_line(konf_query_t *this)
267 {
268 return this->line;
269 }
270
271 /*-------------------------------------------------------- */
konf_query__get_priority(konf_query_t * this)272 unsigned short konf_query__get_priority(konf_query_t *this)
273 {
274 return this->priority;
275 }
276
277 /*-------------------------------------------------------- */
konf_query__get_splitter(konf_query_t * this)278 bool_t konf_query__get_splitter(konf_query_t *this)
279 {
280 return this->splitter;
281 }
282
283 /*-------------------------------------------------------- */
konf_query__get_seq(konf_query_t * this)284 bool_t konf_query__get_seq(konf_query_t *this)
285 {
286 return this->seq;
287 }
288
289 /*-------------------------------------------------------- */
konf_query__get_seq_num(konf_query_t * this)290 unsigned short konf_query__get_seq_num(konf_query_t *this)
291 {
292 return this->seq_num;
293 }
294
295 /*-------------------------------------------------------- */
konf_query__get_unique(konf_query_t * this)296 bool_t konf_query__get_unique(konf_query_t *this)
297 {
298 return this->unique;
299 }
300
301 /*-------------------------------------------------------- */
konf_query__get_depth(konf_query_t * this)302 int konf_query__get_depth(konf_query_t *this)
303 {
304 return this->depth;
305 }
306