aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/tru/tinyrad.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tru/tinyrad.c')
-rw-r--r--src/tru/tinyrad.c485
1 files changed, 485 insertions, 0 deletions
diff --git a/src/tru/tinyrad.c b/src/tru/tinyrad.c
new file mode 100644
index 0000000..79bd639
--- /dev/null
+++ b/src/tru/tinyrad.c
@@ -0,0 +1,485 @@
1/*
2 * Tiny RADIUS Client Library
3 * Copyright (C) 2021 David M. Syzdek <david@syzdek.net>.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of David M. Syzdek nor the
16 * names of its contributors may be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M. SYZDEK BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31#define _SRC_TINYRADUTIL_TINYRADUTIL_C 1
32
33///////////////
34// //
35// Headers //
36// //
37///////////////
38#pragma mark - Headers
39
40#include "tru.h"
41
42#include <tinyrad_utils.h>
43
44#include <stdio.h>
45#include <stdarg.h>
46#include <stdlib.h>
47#include <string.h>
48#include <strings.h>
49#include <unistd.h>
50#include <getopt.h>
51#include <sys/types.h>
52#include <sys/stat.h>
53#include <sys/uio.h>
54#include <unistd.h>
55#include <assert.h>
56#include <fcntl.h>
57#include <errno.h>
58
59
60///////////////////
61// //
62// Definitions //
63// //
64///////////////////
65#pragma mark - Definitions
66
67
68//////////////////
69// //
70// Data Types //
71// //
72//////////////////
73#pragma mark - Data Types
74
75
76//////////////////
77// //
78// Prototypes //
79// //
80//////////////////
81#pragma mark - Prototypes
82
83
84/////////////////
85// //
86// Variables //
87// //
88/////////////////
89#pragma mark - Variables
90
91#pragma mark tinyrad_cmdmap[]
92const TinyRadUtilWidget tru_widget_map[] =
93{
94 {
95 .name = "configuration",
96 .func = &tru_widget_config,
97 .shortopts = TINYRAD_DICT_GETOPT_SHORT TINYRAD_GETOPT_SHORT,
98 .longopts = (struct option [])
99 { TINYRAD_DICT_GETOPT_LONG
100 TINYRAD_GETOPT_LONG
101 },
102 .min_arg = 0,
103 .max_arg = 0,
104 .usage = NULL,
105 .desc = "print configuration"
106 },
107 {
108 .name = "dictionary",
109 .func = &tru_widget_dict,
110 .shortopts = TINYRAD_DICT_GETOPT_SHORT TINYRAD_GETOPT_SHORT,
111 .longopts = (struct option [])
112 { TINYRAD_DICT_GETOPT_LONG
113 TINYRAD_GETOPT_LONG
114 },
115 .min_arg = 0,
116 .max_arg = 0,
117 .usage = NULL,
118 .desc = "print processed dictionary"
119 },
120 {
121 .name = "help",
122 .func = &tru_usage,
123 .shortopts = TINYRAD_GETOPT_SHORT,
124 .longopts = (struct option []) { TINYRAD_GETOPT_LONG },
125 .min_arg = 0,
126 .max_arg = 0,
127 .usage = NULL,
128 .desc = "print command usage"
129 },
130 {
131 .name = NULL,
132 .func = NULL,
133 .shortopts = NULL,
134 .longopts = NULL,
135 .min_arg = -1,
136 .max_arg = -1,
137 .usage = NULL,
138 .desc = NULL
139 }
140};
141
142
143/////////////////
144// //
145// Functions //
146// //
147/////////////////
148#pragma mark - Functions
149
150int main(int argc, char * argv[])
151{
152 int c;
153 int opt_index;
154 int rc;
155 size_t pos;
156 TinyRadDict * dict;
157 TinyRadUtilConf cnfdata;
158 TinyRadUtilConf * cnf;
159
160 // getopt options
161 static char short_opt[] = "+" TINYRAD_GETOPT_SHORT;
162 static struct option long_opt[] = { TINYRAD_GETOPT_LONG };
163
164 trutils_initialize(PROGRAM_NAME);
165
166 memset(&cnfdata, 0, sizeof(cnfdata));
167 cnf = &cnfdata;
168 dict = NULL;
169
170 while((c = tru_getopt(cnf, argc, argv, short_opt, long_opt, &opt_index)) != -1)
171 {
172 switch(c)
173 {
174 case MY_GETOPT_MATCHED: /* captured by common options */
175 case -1: /* no more arguments */
176 case 0: /* long options toggles */
177 break;
178
179 case MY_GETOPT_EXIT:
180 tru_cleanup(cnf);
181 return(0);
182
183 case MY_GETOPT_ERROR:
184 tru_cleanup(cnf);
185 return(1);
186
187 case '?':
188 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
189 return(1);
190
191 default:
192 fprintf(stderr, "%s: unrecognized option `--%c'\n", PROGRAM_NAME, c);
193 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
194 return(1);
195 };
196 };
197 if ((argc - optind) < 1)
198 {
199 fprintf(stderr, "%s: missing required argument\n", PROGRAM_NAME);
200 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
201 return(1);
202 };
203 cnf->cmd_argc = (argc - optind);
204 cnf->cmd_argv = &argv[optind];
205 cnf->cmd_name = cnf->cmd_argv[0];
206 cnf->cmd_len = strlen(cnf->cmd_name);
207
208 // looks up widget
209 for(pos = 0; (tru_widget_map[pos].name != NULL); pos++)
210 {
211 if ((strncmp(cnf->cmd_name, tru_widget_map[pos].name, cnf->cmd_len)))
212 continue;
213 if ((cnf->cmd))
214 {
215 fprintf(stderr, "%s: ambiguous command -- \"%s\"\n", PROGRAM_NAME, cnf->cmd_name);
216 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
217 return(1);
218 };
219 cnf->cmd = &tru_widget_map[pos];
220 };
221 if (!(cnf->cmd))
222 {
223 fprintf(stderr, "%s: unknown command -- \"%s\"\n", PROGRAM_NAME, cnf->cmd_name);
224 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
225 return(1);
226 };
227 if (!(cnf->cmd->func))
228 {
229 fprintf(stderr, "%s: command not implemented -- \"%s\"\n", PROGRAM_NAME, cnf->cmd->name);
230 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
231 return(1);
232 };
233
234 // process widget cli options
235 optind = 1;
236 opt_index = 0;
237 while((c = tru_getopt(cnf, cnf->cmd_argc, cnf->cmd_argv, cnf->cmd->shortopts, cnf->cmd->longopts, &opt_index)) != -1)
238 {
239 switch(c)
240 {
241 case -2: /* captured by common options */
242 case -1: /* no more arguments */
243 case 0: /* long options toggles */
244 break;
245
246 case MY_GETOPT_EXIT:
247 tru_cleanup(cnf);
248 return(0);
249
250 case MY_GETOPT_ERROR:
251 tru_cleanup(cnf);
252 return(1);
253
254 case '?':
255 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->cmd_name);
256 return(1);
257
258 default:
259 fprintf(stderr, "%s: %s: unrecognized option `--%c'\n", PROGRAM_NAME, cnf->cmd_name, c);
260 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->cmd_name);
261 return(1);
262 };
263 };
264 if ((cnf->cmd_argc - optind) < cnf->cmd->min_arg)
265 {
266 fprintf(stderr, "%s: missing required argument\n", PROGRAM_NAME);
267 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->cmd_name);
268 return(1);
269 };
270 if ((optind+cnf->cmd->max_arg) > cnf->cmd_argc)
271 {
272 fprintf(stderr, "%s: unrecognized argument `-- %s'\n", PROGRAM_NAME, cnf->cmd_argv[optind+1]);
273 fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->cmd_name);
274 return(1);
275 };
276
277 // call widget
278 rc = cnf->cmd->func(cnf);
279 tru_cleanup(cnf);
280 return(trutils_exit_code(rc));
281}
282
283
284void
285tru_cleanup(
286 TinyRadUtilConf * cnf )
287{
288 tinyrad_free(cnf->tr);
289 tinyrad_strsfree(cnf->dict_files);
290 tinyrad_strsfree(cnf->dict_paths);
291 return;
292}
293
294
295int
296tru_widget_config(
297 TinyRadUtilConf * cnf )
298{
299 int rc;
300 TinyRadDict * dict;
301 if ((rc = tru_load_tinyrad(cnf)) != TRAD_SUCCESS)
302 return(rc);
303 tinyrad_get_option(cnf->tr, TRAD_OPT_DICTIONARY, &dict);
304 tinyrad_conf_print(cnf->tr, dict);
305 tinyrad_free(dict);
306 return(TRAD_SUCCESS);
307}
308
309
310int
311tru_widget_dict(
312 TinyRadUtilConf * cnf )
313{
314 int rc;
315 TinyRadDict * dict;
316 if ((rc = tru_load_tinyrad(cnf)) != TRAD_SUCCESS)
317 return(rc);
318 tinyrad_get_option(cnf->tr, TRAD_OPT_DICTIONARY, &dict);
319 tinyrad_dict_print(dict, 0xffff);
320 tinyrad_free(dict);
321 return(TRAD_SUCCESS);
322}
323
324
325int
326tru_getopt(
327 TinyRadUtilConf * cnf,
328 int argc,
329 char * const * argv,
330 const char * short_opt,
331 const struct option * long_opt,
332 int * opt_index )
333{
334 int c;
335 int opt;
336
337 switch(c = getopt_long(argc, argv, short_opt, long_opt, opt_index))
338 {
339 case 'b':
340 cnf->tr_opts |= TRAD_BUILTIN_DICT;
341 return(MY_GETOPT_MATCHED);
342
343 case 'D':
344 if (tinyrad_strsadd(&cnf->dict_files, optarg) != TRAD_SUCCESS)
345 {
346 trutils_error(cnf->opts, NULL, "out of virtual memory");
347 return(MY_GETOPT_ERROR);
348 };
349 return(MY_GETOPT_MATCHED);
350
351 case 'd':
352 opt = ((optarg)) ? (int)strtol(optarg, NULL, 0) : TRAD_DEBUG_ANY;
353 tinyrad_set_option(NULL, TRAD_OPT_DEBUG_LEVEL, &opt);
354 return(MY_GETOPT_MATCHED);
355
356 case 'h':
357 tru_usage(cnf);
358 return(MY_GETOPT_EXIT);
359
360 case 'I':
361 if (tinyrad_strsadd(&cnf->dict_paths, optarg) != TRAD_SUCCESS)
362 {
363 trutils_error(cnf->opts, NULL, "out of virtual memory");
364 return(MY_GETOPT_ERROR);
365 };
366 return(MY_GETOPT_MATCHED);
367
368 case 'q':
369 cnf->opts |= TRUTILS_OPT_QUIET;
370 cnf->opts &= ~TRUTILS_OPT_VERBOSE;
371 return(MY_GETOPT_MATCHED);
372
373 case 'V':
374 trutils_version();
375 return(MY_GETOPT_EXIT);
376
377 case 'v':
378 cnf->opts |= TRUTILS_OPT_VERBOSE;
379 cnf->opts &= ~TRUTILS_OPT_QUIET;
380 return(MY_GETOPT_MATCHED);
381
382 default:
383 break;
384 };
385
386 return(c);
387}
388
389
390int
391tru_load_tinyrad(
392 TinyRadUtilConf * cnf )
393{
394 int rc;
395 char ** errs;
396 size_t pos;
397 TinyRadDict * dict;
398
399 errs = NULL;
400 dict = NULL;
401
402 if ((cnf->dict_files))
403 {
404 // initialize dictionary
405 if ((rc = tinyrad_dict_initialize(&dict, cnf->tr_opts)) != TRAD_SUCCESS)
406 {
407 trutils_error(cnf->opts, NULL, "out of virtual memory");
408 return(rc);
409 };
410
411 // set paths
412 if ((cnf->dict_paths))
413 {
414 if ((rc = tinyrad_dict_set_option(dict, TRAD_DICT_OPT_PATHS, cnf->dict_paths)) != TRAD_SUCCESS)
415 {
416 trutils_error(cnf->opts, NULL, "tinyrad_dict_set_option(TRAD_DICT_OPT_PATHS): %s", tinyrad_strerror(rc));
417 tinyrad_free(dict);
418 return(rc);
419 };
420 };
421
422 // parse dictionary files
423 for(pos = 0; ( ((cnf->dict_files)) && ((cnf->dict_files[pos])) ); pos++)
424 {
425 if ((rc = tinyrad_dict_parse(dict, cnf->dict_files[pos], &errs, 0)) != TRAD_SUCCESS)
426 {
427 trutils_error(cnf->opts, errs, NULL);
428 tinyrad_strsfree(errs);
429 tinyrad_free(dict);
430 return(rc);
431 };
432 };
433 };
434
435 // initialize tinyrad handle
436 rc = tinyrad_initialize(&cnf->tr, dict, cnf->url, cnf->tr_opts);
437 tinyrad_free(dict);
438 return(rc);
439}
440
441
442int
443tru_usage(
444 TinyRadUtilConf * cnf )
445{
446 int i;
447 const char * name;
448 const char * help;
449 const char * s;
450
451 name = "COMMAND";
452 help = " ...";
453 s = TINYRAD_GETOPT_SHORT;
454
455 if ((cnf->cmd))
456 {
457 name = cnf->cmd->name;
458 help = ((cnf->cmd->usage)) ? cnf->cmd->usage : "";
459 s = ((cnf->cmd->shortopts)) ? cnf->cmd->shortopts : TINYRAD_GETOPT_SHORT;
460 };
461
462 printf("Usage: %s %s [OPTIONS]%s\n", PROGRAM_NAME, name, help);
463 printf("OPTIONS:\n");
464 if ((strchr(s, 'b'))) printf(" -b, --builtin-dict load built-in dictionary\n");
465 if ((strchr(s, 'D'))) printf(" -D dictionary include dictionary\n");
466 if ((strchr(s, 'd'))) printf(" -d level, --debug=level print debug messages\n");
467 if ((strchr(s, 'f'))) printf(" -f file, --file=file attribute list\n");
468 if ((strchr(s, 'h'))) printf(" -h, --help print this help and exit\n");
469 if ((strchr(s, 'I'))) printf(" -I path add path to dictionary search paths\n");
470 if ((strchr(s, 'q'))) printf(" -q, --quiet, --silent do not print messages\n");
471 if ((strchr(s, 'V'))) printf(" -V, --version print version number and exit\n");
472 if ((strchr(s, 'v'))) printf(" -v, --verbose print verbose messages\n");
473 if (!(cnf->cmd))
474 {
475 printf("COMMANDS:\n");
476 for(i = 0; tru_widget_map[i].name != NULL; i++)
477 if ((tru_widget_map[i].desc))
478 printf(" %-25s %s\n", tru_widget_map[i].name, tru_widget_map[i].desc);
479 };
480 printf("\n");
481 return(0);
482}
483
484
485/* end of source */