The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
radmod2json.c
Go to the documentation of this file.
1/*
2 * radmod2json.c Dump FreeRADIUS v4 module conf_parser_t and call_env_parser_t
3 * definitions as JSON.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 * Copyright (C) 2026 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
20 */
21RCSID("$Id: 0e0912605fad3a45b88816c2ebd273d8cae134e3 $")
22
23#include <freeradius-devel/server/base.h>
24#include <freeradius-devel/server/cf_parse.h>
25#include <freeradius-devel/server/dl_module.h>
26#include <freeradius-devel/server/module.h>
27#include <freeradius-devel/server/module_rlm.h>
28#include <freeradius-devel/server/section.h>
29#include <freeradius-devel/unlang/call_env.h>
30#include <freeradius-devel/unlang/base.h>
31#include <freeradius-devel/util/atexit.h>
32#include <freeradius-devel/util/dl.h>
33#include <freeradius-devel/util/types.h>
34
35#include <freeradius-devel/json/base.h>
36
37#include <dirent.h>
38#include <dlfcn.h>
39#include <sys/wait.h>
40
41#ifdef HAVE_GETOPT_H
42# include <getopt.h>
43#endif
44
45char const *radiusd_version = RADIUSD_VERSION_BUILD("radmod2json");
46
47/*
48 * Symbolic names for the five quote tokens, keyed by `fr_token_t`.
49 * fr_table_str_by_value() routes us through fr_table_indexed_str_by_num
50 * via the _Generic dispatch on the table type.
51 */
52/*
53 * `fr_token_to_enum_str()` (src/lib/util/token.c) returns the
54 * source-identifier form of the token ("T_BARE_WORD" etc.) which
55 * is what the converter's rule layer greps for.
56 */
57#define quote_name(_t) fr_token_to_enum_str(_t)
58
59/*
60 * Resolve a function pointer back to its source symbol name via dladdr().
61 * macOS C symbols get a leading '_' from the linker - strip that before
62 * emitting.
63 */
64static struct json_object *func_symbol(void const *fn)
65{
66 Dl_info info;
67 char const *name;
68
69 if (!fn) return NULL;
70 if (dladdr(fn, &info) == 0) return NULL;
71 if (!info.dli_sname) return NULL;
72
73 name = info.dli_sname;
74 if (name[0] == '_') name++;
75 return json_object_new_string(name);
76}
77
78static struct json_object *build_dflt(char const *value, fr_token_t quote)
79{
80 struct json_object *o;
81
82 if (!value) return NULL;
83 o = json_object_new_object();
84 json_object_object_add(o, "value", json_object_new_string(value));
85 json_object_object_add(o, "quote", json_object_new_string(quote_name(quote)));
86 return o;
87}
88
89/*
90 * Walk every set bit of `flags`; resolve each single-bit mask
91 * through the library's `*_flag_to_enum_str()` lookup. Bits with
92 * no symbolic name are skipped. The result preserves bit-order.
93 */
94static struct json_object *build_conf_parser_flags(conf_parser_flags_t flags)
95{
96 struct json_object *a = json_object_new_array();
97
98 for (size_t bit = 0; bit < 32; bit++) {
99 uint64_t mask = UINT64_C(1) << bit;
100 char const *name;
101
102 if (!(flags & mask)) continue;
104 if (!name) continue;
105 json_object_array_add(a, json_object_new_string(name));
106 }
107 return a;
108}
109
110static struct json_object *build_conf_parser_rules(conf_parser_t const *rules);
111
112static struct json_object *build_conf_parser_rule(conf_parser_t const *r)
113{
114 struct json_object *o = json_object_new_object();
115 bool is_sub = (r->flags & CONF_FLAG_SUBSECTION) != 0;
116 char const *name1 = (r->name1 == CF_IDENT_ANY) ? NULL : r->name1;
117 char const *name2 = (r->name2 == CF_IDENT_ANY) ? NULL : r->name2;
118
119 json_object_object_add(o, "name1", name1 ? json_object_new_string(name1) : NULL);
120 json_object_object_add(o, "name2", name2 ? json_object_new_string(name2) : NULL);
121 json_object_object_add(o, "type", json_object_new_string(fr_type_to_enum_str(r->type)));
122 json_object_object_add(o, "flags", build_conf_parser_flags(r->flags));
123 json_object_object_add(o, "func", func_symbol((void const *)r->func));
124 json_object_object_add(o, "on_read", func_symbol((void const *)r->on_read));
125
126 if (is_sub) {
127 json_object_object_add(o, "subcs",
128 r->subcs ? build_conf_parser_rules(r->subcs) : json_object_new_array());
129 } else {
130 json_object_object_add(o, "dflt", build_dflt(r->dflt, r->quote));
131 }
132
133 return o;
134}
135
136static struct json_object *build_conf_parser_rules(conf_parser_t const *rules)
137{
138 struct json_object *a = json_object_new_array();
139
140 if (rules) {
141 for (conf_parser_t const *r = rules; r->name1; r++) {
142 /*
143 * A CONF_FLAG_REF rule references another
144 * conf_parser_t array whose rules are parsed as if
145 * they appeared inline in this section. Splice the
146 * referenced rules straight into this array rather
147 * than emitting a rule for the reference itself.
148 *
149 * Note that `dflt` and `subcs` share a union, so a
150 * REF rule must never reach build_conf_parser_rule():
151 * its non-subsection branch would read the `subcs`
152 * pointer as a `dflt` string.
153 */
154 if (r->flags & CONF_FLAG_REF) {
155 struct json_object *ref = build_conf_parser_rules(r->subcs);
156 size_t n = json_object_array_length(ref);
157
158 for (size_t i = 0; i < n; i++) {
159 json_object_array_add(a, json_object_get(json_object_array_get_idx(ref, i)));
160 }
161 json_object_put(ref);
162 continue;
163 }
164
165 json_object_array_add(a, build_conf_parser_rule(r));
166 }
167 }
168 return a;
169}
170
171static struct json_object *build_call_env_flags(call_env_flags_t flags)
172{
173 struct json_object *a = json_object_new_array();
174
175 for (size_t bit = 0; bit < 32; bit++) {
176 uint64_t mask = UINT64_C(1) << bit;
177 char const *name;
178
179 if (!(flags & mask)) continue;
181 if (!name) continue;
182 json_object_array_add(a, json_object_new_string(name));
183 }
184 return a;
185}
186
187static struct json_object *json_section_ident(char const *name)
188{
189 if (!name) return NULL;
190 if (name == CF_IDENT_ANY) return json_object_new_string("*");
191 return json_object_new_string(name);
192}
193
194static struct json_object *build_call_env_rules(call_env_parser_t const *rules);
195
196static struct json_object *build_call_env_rule(call_env_parser_t const *r)
197{
198 struct json_object *o = json_object_new_object();
199 bool is_sub = (r->flags & CALL_ENV_FLAG_SUBSECTION) != 0;
200
201 json_object_object_add(o, "name", json_section_ident(r->name));
202 json_object_object_add(o, "flags", build_call_env_flags(r->flags));
203
204 if (is_sub) {
205 struct json_object *s = json_object_new_object();
206 json_object_object_add(s, "name2", json_section_ident(r->section.name2));
207 json_object_object_add(s, "func", func_symbol((void const *)r->section.func));
208 json_object_object_add(s, "subcs",
209 r->section.subcs ? build_call_env_rules(r->section.subcs) :
210 json_object_new_array());
211 json_object_object_add(o, "section", s);
212 } else {
213 struct json_object *p = json_object_new_object();
214 struct json_object *parsed = json_object_new_object();
215
216 /*
217 * FR_TYPE_NULL / FR_TYPE_VOID both mean "no cast" - the
218 * framework hands the parsed value through without
219 * coercion. Collapse to a JSON null so the converter
220 * only has to check one sentinel.
221 */
222 json_object_object_add(p, "cast_type",
223 ((r->pair.cast_type == FR_TYPE_NULL) || (r->pair.cast_type == FR_TYPE_VOID)) ?
224 NULL :
225 json_object_new_string(fr_type_to_enum_str(r->pair.cast_type)));
226 json_object_object_add(p, "type",
227 json_object_new_string(call_env_result_type_to_enum_str(r->pair.type)));
228 json_object_object_add(p, "dflt", build_dflt(r->pair.dflt, r->pair.dflt_quote));
229 json_object_object_add(p, "func", func_symbol((void const *)r->pair.func));
230
231 json_object_object_add(parsed, "type",
232 json_object_new_string(call_env_parse_type_to_enum_str(r->pair.parsed.type)));
233 json_object_object_add(p, "parsed", parsed);
234
235 json_object_object_add(o, "pair", p);
236 }
237
238 return o;
239}
240
241static struct json_object *build_call_env_rules(call_env_parser_t const *rules)
242{
243 struct json_object *a = json_object_new_array();
244
245 if (rules) {
246 for (call_env_parser_t const *r = rules; r->name; r++) {
247 json_object_array_add(a, build_call_env_rule(r));
248 }
249 }
250 return a;
251}
252
253static struct json_object *build_method_bindings(module_method_binding_t const *bindings)
254{
255 struct json_object *a = json_object_new_array();
256
257 if (bindings) {
258 for (module_method_binding_t const *b = bindings; b->section; b++) {
259 struct json_object *entry = json_object_new_object();
260 struct json_object *section = json_object_new_object();
261
262 json_object_object_add(section, "name1", json_section_ident(b->section->name1));
263 json_object_object_add(section, "name2", json_section_ident(b->section->name2));
264 json_object_object_add(entry, "section", section);
265 json_object_object_add(entry, "method", func_symbol((void const *)b->method));
266 json_object_object_add(entry, "env",
267 (b->method_env && b->method_env->env) ?
268 build_call_env_rules(b->method_env->env) :
269 json_object_new_array());
270
271 json_object_array_add(a, entry);
272 }
273 }
274
275 return a;
276}
277
278/*
279 * Build the JSON for one module using the server's normal dl loader.
280 * `bare_name` is the module name without the "rlm_" prefix (so "files"
281 * for rlm_files). Returns the json object or NULL on error.
282 */
283static struct json_object *build_module(char const *bare_name)
284{
285 dl_module_t *dl_module;
286 module_rlm_t *m;
287 struct json_object *entry;
288
289 dl_module = dl_module_alloc(NULL, bare_name, DL_MODULE_TYPE_MODULE);
290 if (!dl_module) {
291 fr_perror("rlm_%s", bare_name);
292 return NULL;
293 }
294
295 m = (module_rlm_t *)dl_module->exported;
296 if (!m) return NULL;
297
298 entry = json_object_new_object();
299 json_object_object_add(entry, "module", json_object_new_string(m->common.name ? m->common.name : bare_name));
300 json_object_object_add(entry, "config", build_conf_parser_rules(m->common.config));
301 json_object_object_add(entry, "call_env", build_method_bindings(m->method_group.bindings));
302 return entry;
303}
304
305static int dump_module(struct json_object *modules, char const *bare_name)
306{
307 int fds[2];
308 pid_t pid;
309 int status;
310
311 if (pipe(fds) < 0) {
312 fprintf(stderr, "rlm_%s: pipe failed: %s\n", bare_name, fr_syserror(errno));
313 return -1;
314 }
315
316 pid = fork();
317 if (pid < 0) {
318 close(fds[0]);
319 close(fds[1]);
320 fprintf(stderr, "rlm_%s: fork failed: %s\n", bare_name, fr_syserror(errno));
321 return -1;
322 }
323
324 if (pid == 0) {
325 struct json_object *entry;
326
327 close(fds[0]);
328 entry = build_module(bare_name);
329 if (!entry) {
330 fprintf(stderr, "rlm_%s: build_module failed\n", bare_name);
331 _exit(1);
332 }
333
334 {
335 char const *s = json_object_to_json_string_ext(entry, JSON_C_TO_STRING_PLAIN |
336 JSON_C_TO_STRING_NOSLASHESCAPE);
337 size_t remaining = strlen(s);
338 ssize_t n;
339
340 while (remaining > 0) {
341 n = write(fds[1], s, remaining);
342 if (n < 0) {
343 fprintf(stderr, "rlm_%s: write to pipe failed: %s\n",
344 bare_name, fr_syserror(errno));
345 _exit(1);
346 }
347 s += n;
348 remaining -= n;
349 }
350 }
351 json_object_put(entry);
352 close(fds[1]);
353 _exit(0);
354 }
355
356 close(fds[1]);
357 {
358 char buf[262144];
359 size_t used = 0;
360 ssize_t n;
361 while ((n = read(fds[0], buf + used, sizeof(buf) - 1 - used)) > 0) {
362 used += n;
363 if (used >= sizeof(buf) - 1) break;
364 }
365 close(fds[0]);
366 if (used >= sizeof(buf) - 1) {
367 fprintf(stderr, "rlm_%s: overflowed buffer reading JSON\n", bare_name);
368 return -1;
369 }
370 buf[used] = '\0';
371
372 waitpid(pid, &status, 0);
373
374 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
375 fprintf(stderr, "rlm_%s: child %s (status=0x%x), skipping\n", bare_name,
376 WIFEXITED(status) ? "exited non-zero" : "crashed", status);
377 return -1;
378 }
379
380 if (used > 0) {
381 struct json_object *entry = json_tokener_parse(buf);
382 if (entry) {
383 json_object_array_add(modules, entry);
384 return 0;
385 }
386 fprintf(stderr, "rlm_%s: failed to parse child JSON\n", bare_name);
387 return -1;
388 }
389 }
390
391 return -1;
392}
393
394/*
395 * Discover top-level rlm_*.dylib (or .so) files in a directory, returning
396 * the bare module names (no "rlm_" prefix, no extension). The dl loader
397 * will re-prefix and resolve the full path itself.
398 */
399static int discover_modules(TALLOC_CTX *ctx, char const *dir, char ***out_names, size_t *out_count)
400{
401 DIR *d;
402 struct dirent *e;
403 char **names = NULL;
404 size_t n = 0, alloc = 0;
405 size_t extlen = strlen(DL_EXTENSION);
406
407 d = opendir(dir);
408 if (!d) {
409 fprintf(stderr, "Failed opening module dir %s: %s\n", dir, fr_syserror(errno));
410 return -1;
411 }
412
413 while ((e = readdir(d)) != NULL) {
414 size_t nlen = strlen(e->d_name);
415
416 if (nlen <= extlen) continue;
417 if (strcmp(e->d_name + nlen - extlen, DL_EXTENSION) != 0) continue;
418 if (strncmp(e->d_name, "rlm_", 4) != 0) continue;
419
420 if (n == alloc) {
421 alloc = alloc ? alloc * 2 : 16;
422 MEM(names = talloc_realloc(ctx, names, char *, alloc));
423 }
424
425 /* Strip "rlm_" prefix and DL_EXTENSION suffix */
426 MEM(names[n++] = talloc_strndup(names, e->d_name + 4, nlen - 4 - extlen));
427 }
428
429 closedir(d);
430
431 *out_names = names;
432 *out_count = n;
433 return 0;
434}
435
436static int compare_str(void const *a, void const *b)
437{
438 return strcmp(*(char *const *)a, *(char *const *)b);
439}
440
441static NEVER_RETURNS void usage(int rcode)
442{
443 FILE *fp = (rcode == 0) ? stdout : stderr;
444
445 fprintf(fp,
446 "Usage: radmod2json [options]\n"
447 " -m <list> Comma-separated list of module names without rlm_ prefix\n"
448 " (default: every rlm_*" DL_EXTENSION " under the module directory).\n"
449 " -M <dir> Module directory to load from (default: " LIBDIR ").\n"
450 " -D <dict> Dictionary directory (default: " DICTDIR ").\n"
451 " -o <file> Write JSON to <file> (default stdout).\n"
452 " -x Enable debug output (repeatable).\n"
453 " -h This help.\n");
454 exit(rcode);
455}
456
457int main(int argc, char *argv[])
458{
459 int c;
460 int rcode = EXIT_SUCCESS;
461 char const *modules_arg = NULL;
462 char const *output_file = NULL;
463 char const *module_dir = LIBDIR;
464 char const *dict_dir = DICTDIR;
465 char **names = NULL;
466 size_t n_names = 0;
467 fr_dict_t *internal = NULL;
468 TALLOC_CTX *autofree;
469
471
472 fr_debug_lvl = 0;
474 default_log.fd = STDERR_FILENO;
475
476 while ((c = getopt(argc, argv, "D:hm:M:o:x")) != -1) {
477 switch (c) {
478 case 'D':
479 dict_dir = optarg;
480 break;
481 case 'h':
482 usage(EXIT_SUCCESS);
483 case 'm':
484 modules_arg = optarg;
485 break;
486 case 'M':
487 module_dir = optarg;
488 break;
489 case 'o':
490 output_file = optarg;
491 break;
492 case 'x':
493 fr_debug_lvl++;
494 break;
495 default:
496 usage(EXIT_FAILURE);
497 }
498 }
499
501 fr_perror("radmod2json");
502 exit(EXIT_FAILURE);
503 }
504
505 /* Init the dl loader against the requested module dir. */
506 modules_init(module_dir);
507
508 /*
509 * dl_module_alloc triggers fr_dict_autoload on the loaded
510 * module, which needs a global dict ctx to exist. Some
511 * modules also autoload internal-protocol attributes that
512 * are in the dictionary tree, so load it up front.
513 */
514 if (!fr_dict_global_ctx_init(NULL, true, dict_dir)) {
515 fr_perror("radmod2json");
516 exit(EXIT_FAILURE);
517 }
518
519 if (fr_dict_internal_afrom_file(&internal, FR_DICTIONARY_INTERNAL_DIR, __FILE__) < 0) {
520 fr_perror("radmod2json");
521 exit(EXIT_FAILURE);
522 }
523
524 if (request_global_init() < 0) {
525 fr_perror("radmod2json");
526 exit(EXIT_FAILURE);
527 }
528
529 if (unlang_global_init() < 0) {
530 fr_perror("radmod2json");
531 exit(EXIT_FAILURE);
532 }
533
534 if (modules_arg) {
535 char *list = talloc_strdup(autofree, modules_arg);
536 char *p, *tok;
537 size_t alloc = 0;
538
539 for (p = list; (tok = strsep(&p, ",")) != NULL;) {
540 char const *bare = tok;
541
542 if (!*bare) continue;
543 if (strncmp(bare, "rlm_", 4) == 0) bare += 4;
544 if (n_names == alloc) {
545 alloc = alloc ? alloc * 2 : 16;
546 MEM(names = talloc_realloc(autofree, names, char *, alloc));
547 }
548 names[n_names++] = UNCONST(char *, bare);
549 }
550 } else {
551 if (discover_modules(autofree, module_dir, &names, &n_names) < 0) {
552 exit(EXIT_FAILURE);
553 }
554 if (n_names > 0) qsort(names, n_names, sizeof(names[0]), compare_str);
555 }
556
557 {
558 struct json_object *root = json_object_new_object();
559 struct json_object *modules = json_object_new_array();
560 char const *json_str;
561
562 json_object_object_add(root, "modules", modules);
563
564 for (size_t i = 0; i < n_names; i++) {
565 if (dump_module(modules, names[i]) < 0) rcode = EXIT_FAILURE;
566 }
567
568 json_str = json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_NOSLASHESCAPE);
569 if (output_file) {
570 FILE *out = fopen(output_file, "w");
571 if (!out) {
572 fprintf(stderr, "Failed opening %s: %s\n", output_file, fr_syserror(errno));
573 exit(EXIT_FAILURE);
574 }
575 fputs(json_str, out);
576 fputc('\n', out);
577 fclose(out);
578 } else {
579 fputs(json_str, stdout);
580 fputc('\n', stdout);
581 }
582
583 json_object_put(root);
584 }
585
586 return rcode;
587}
int n
Definition acutest.h:577
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:560
#define NEVER_RETURNS
Should be placed before the function return type.
Definition build.h:382
char const * call_env_flag_to_enum_str(call_env_flags_t mask)
Return the source-identifier name for a single CALL_ENV_FLAG_* bit.
Definition call_env.c:850
char const * call_env_result_type_to_enum_str(call_env_result_type_t t)
Return the source-identifier name for a call_env_result_type_t value.
Definition call_env.c:873
char const * call_env_parse_type_to_enum_str(call_env_parse_type_t t)
Return the source-identifier name for a call_env_parse_type_t value.
Definition call_env.c:862
call_env_flags_t flags
Flags controlling parser behaviour.
Definition call_env.h:182
char const * name
Of conf pair to pass to tmpl_tokenizer.
Definition call_env.h:181
call_env_flags_t
Definition call_env.h:73
@ CALL_ENV_FLAG_SUBSECTION
This is a subsection.
Definition call_env.h:87
Per method call config.
Definition call_env.h:180
char const * cf_parser_flag_to_enum_str(conf_parser_flags_t mask)
Return the source-identifier name for a single CONF_FLAG_* bit.
Definition cf_parse.c:1873
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:627
conf_parser_flags_t flags
Flags which control parsing behaviour.
Definition cf_parse.h:616
fr_type_t type
An fr_type_t value, controls the output type.
Definition cf_parse.h:614
char const * name2
Second identifier for CONF_SECTION.
Definition cf_parse.h:612
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:665
char const * name1
Name of the CONF_ITEM to parse.
Definition cf_parse.h:611
cf_parse_t on_read
Function to call as the item is being read, just after it has been allocated and initialized.
Definition cf_parse.h:630
conf_parser_flags_t
Definition cf_parse.h:425
@ CONF_FLAG_REF
reference another conf_parser_t inline in this one
Definition cf_parse.h:461
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:427
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:610
#define CF_IDENT_ANY
Definition cf_util.h:80
TALLOC_CTX * autofree
Definition common.c:29
#define MEM(x)
Definition debug.h:38
static NEVER_RETURNS void usage(void)
Definition dhcpclient.c:113
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir, char const *dependent))
(Re-)Initialize the special internal dictionary
fr_dict_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir))
Initialise the global protocol hashes.
Definition dict_util.c:4850
Test enumeration values.
Definition dict_test.h:92
dl_module_t * dl_module_alloc(dl_module_t const *parent, char const *name, dl_module_type_t type)
Load a module library using dlopen() or return a previously loaded module from the cache.
Definition dl_module.c:312
dl_module_common_t * exported
Symbol exported by the module, containing its public functions, name and behaviour control flags.
Definition dl_module.h:128
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
Definition dl_module.h:66
#define DL_EXTENSION
Definition dl_module.h:57
int unlang_global_init(void)
Definition base.c:158
int fr_debug_lvl
Definition log.c:41
fr_log_t default_log
Definition log.c:308
@ L_DST_STDERR
Log to stderr.
Definition log.h:78
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_VOID
User data.
long int ssize_t
static size_t used
char * strsep(char **stringp, char const *delim)
Definition missing.c:122
module_method_group_t method_group
named methods
Definition module_rlm.h:40
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
#define WIFEXITED(stat_val)
Definition radiusd.c:66
#define WEXITSTATUS(stat_val)
Definition radiusd.c:63
int main(int argc, char *argv[])
#define quote_name(_t)
Definition radmod2json.c:57
static int discover_modules(TALLOC_CTX *ctx, char const *dir, char ***out_names, size_t *out_count)
static struct json_object * build_conf_parser_rules(conf_parser_t const *rules)
static struct json_object * build_dflt(char const *value, fr_token_t quote)
Definition radmod2json.c:78
static struct json_object * build_module(char const *bare_name)
static int compare_str(void const *a, void const *b)
static int dump_module(struct json_object *modules, char const *bare_name)
static struct json_object * build_conf_parser_rule(conf_parser_t const *r)
static struct json_object * build_call_env_rule(call_env_parser_t const *r)
static struct json_object * build_method_bindings(module_method_binding_t const *bindings)
char const * radiusd_version
Definition radmod2json.c:45
static struct json_object * func_symbol(void const *fn)
Definition radmod2json.c:64
static struct json_object * build_call_env_flags(call_env_flags_t flags)
static struct json_object * build_call_env_rules(call_env_parser_t const *rules)
static struct json_object * json_section_ident(char const *name)
static struct json_object * build_conf_parser_flags(conf_parser_flags_t flags)
Definition radmod2json.c:94
static uint32_t mask
Definition rbmonkey.c:39
int request_global_init(void)
Definition request.c:598
static char const * name
module_method_binding_t * bindings
named methods
Definition module.h:165
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition module.h:206
section_name_t const * section
Identifier for a section.
Definition module.h:175
Named methods exported by a module.
Definition module.h:174
void modules_init(char const *lib_dir)
Perform global initialisation for modules.
Definition module.c:1981
fr_log_dst_t dst
Log destination.
Definition log.h:94
int fd
File descriptor to write messages to.
Definition log.h:109
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
#define talloc_strndup(_ctx, _str, _len)
Definition talloc.h:150
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition talloc.h:55
#define talloc_strdup(_ctx, _str)
Definition talloc.h:149
static const char * names[8]
Definition time.c:614
enum fr_token fr_token_t
#define FR_DICTIONARY_INTERNAL_DIR
Definition conf.h:7
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition strerror.c:737
char const * fr_type_to_enum_str(fr_type_t t)
Return the source-identifier name for a type (e.g.
Definition types.c:142
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
Definition version.c:40
#define RADIUSD_VERSION_BUILD(_x)
Create a version string for a utility in the suite of FreeRADIUS utilities.
Definition version.h:58
#define RADIUSD_MAGIC_NUMBER
Definition version.h:81
static fr_sbuff_err_t char ** out
Definition value.h:1062