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: 7402681c512874c8b9045f43cc94396fb09a8820 $")
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 buf[used] = '\0';
367
368 waitpid(pid, &status, 0);
369
370 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
371 fprintf(stderr, "rlm_%s: child %s (status=0x%x), skipping\n", bare_name,
372 WIFEXITED(status) ? "exited non-zero" : "crashed", status);
373 return -1;
374 }
375
376 if (used > 0) {
377 struct json_object *entry = json_tokener_parse(buf);
378 if (entry) {
379 json_object_array_add(modules, entry);
380 return 0;
381 }
382 fprintf(stderr, "rlm_%s: failed to parse child JSON\n", bare_name);
383 return -1;
384 }
385 }
386
387 return -1;
388}
389
390/*
391 * Discover top-level rlm_*.dylib (or .so) files in a directory, returning
392 * the bare module names (no "rlm_" prefix, no extension). The dl loader
393 * will re-prefix and resolve the full path itself.
394 */
395static int discover_modules(TALLOC_CTX *ctx, char const *dir, char ***out_names, size_t *out_count)
396{
397 DIR *d;
398 struct dirent *e;
399 char **names = NULL;
400 size_t n = 0, alloc = 0;
401 size_t extlen = strlen(DL_EXTENSION);
402
403 d = opendir(dir);
404 if (!d) {
405 fprintf(stderr, "Failed opening module dir %s: %s\n", dir, fr_syserror(errno));
406 return -1;
407 }
408
409 while ((e = readdir(d)) != NULL) {
410 size_t nlen = strlen(e->d_name);
411
412 if (nlen <= extlen) continue;
413 if (strcmp(e->d_name + nlen - extlen, DL_EXTENSION) != 0) continue;
414 if (strncmp(e->d_name, "rlm_", 4) != 0) continue;
415
416 if (n == alloc) {
417 alloc = alloc ? alloc * 2 : 16;
418 MEM(names = talloc_realloc(ctx, names, char *, alloc));
419 }
420
421 /* Strip "rlm_" prefix and DL_EXTENSION suffix */
422 MEM(names[n++] = talloc_strndup(names, e->d_name + 4, nlen - 4 - extlen));
423 }
424
425 closedir(d);
426
427 *out_names = names;
428 *out_count = n;
429 return 0;
430}
431
432static int compare_str(void const *a, void const *b)
433{
434 return strcmp(*(char *const *)a, *(char *const *)b);
435}
436
437static NEVER_RETURNS void usage(int rcode)
438{
439 FILE *fp = (rcode == 0) ? stdout : stderr;
440
441 fprintf(fp,
442 "Usage: radmod2json [options]\n"
443 " -m <list> Comma-separated list of module names without rlm_ prefix\n"
444 " (default: every rlm_*" DL_EXTENSION " under the module directory).\n"
445 " -M <dir> Module directory to load from (default: " LIBDIR ").\n"
446 " -D <dict> Dictionary directory (default: " DICTDIR ").\n"
447 " -o <file> Write JSON to <file> (default stdout).\n"
448 " -x Enable debug output (repeatable).\n"
449 " -h This help.\n");
450 exit(rcode);
451}
452
453int main(int argc, char *argv[])
454{
455 int c;
456 int rcode = EXIT_SUCCESS;
457 char const *modules_arg = NULL;
458 char const *output_file = NULL;
459 char const *module_dir = LIBDIR;
460 char const *dict_dir = DICTDIR;
461 char **names = NULL;
462 size_t n_names = 0;
463 fr_dict_t *internal = NULL;
464 TALLOC_CTX *autofree;
465
467
468 fr_debug_lvl = 0;
470 default_log.fd = STDERR_FILENO;
471
472 while ((c = getopt(argc, argv, "D:hm:M:o:x")) != -1) {
473 switch (c) {
474 case 'D':
475 dict_dir = optarg;
476 break;
477 case 'h':
478 usage(EXIT_SUCCESS);
479 case 'm':
480 modules_arg = optarg;
481 break;
482 case 'M':
483 module_dir = optarg;
484 break;
485 case 'o':
486 output_file = optarg;
487 break;
488 case 'x':
489 fr_debug_lvl++;
490 break;
491 default:
492 usage(EXIT_FAILURE);
493 }
494 }
495
497 fr_perror("radmod2json");
498 exit(EXIT_FAILURE);
499 }
500
501 /* Init the dl loader against the requested module dir. */
502 modules_init(module_dir);
503
504 /*
505 * dl_module_alloc triggers fr_dict_autoload on the loaded
506 * module, which needs a global dict ctx to exist. Some
507 * modules also autoload internal-protocol attributes that
508 * are in the dictionary tree, so load it up front.
509 */
510 if (!fr_dict_global_ctx_init(NULL, true, dict_dir)) {
511 fr_perror("radmod2json");
512 exit(EXIT_FAILURE);
513 }
514
515 if (fr_dict_internal_afrom_file(&internal, FR_DICTIONARY_INTERNAL_DIR, __FILE__) < 0) {
516 fr_perror("radmod2json");
517 exit(EXIT_FAILURE);
518 }
519
520 if (request_global_init() < 0) {
521 fr_perror("radmod2json");
522 exit(EXIT_FAILURE);
523 }
524
525 if (unlang_global_init() < 0) {
526 fr_perror("radmod2json");
527 exit(EXIT_FAILURE);
528 }
529
530 if (modules_arg) {
531 char *list = talloc_strdup(autofree, modules_arg);
532 char *p, *tok;
533 size_t alloc = 0;
534
535 for (p = list; (tok = strsep(&p, ",")) != NULL;) {
536 char const *bare = tok;
537
538 if (!*bare) continue;
539 if (strncmp(bare, "rlm_", 4) == 0) bare += 4;
540 if (n_names == alloc) {
541 alloc = alloc ? alloc * 2 : 16;
542 MEM(names = talloc_realloc(autofree, names, char *, alloc));
543 }
544 names[n_names++] = UNCONST(char *, bare);
545 }
546 } else {
547 if (discover_modules(autofree, module_dir, &names, &n_names) < 0) {
548 exit(EXIT_FAILURE);
549 }
550 if (n_names > 0) qsort(names, n_names, sizeof(names[0]), compare_str);
551 }
552
553 {
554 struct json_object *root = json_object_new_object();
555 struct json_object *modules = json_object_new_array();
556 char const *json_str;
557
558 json_object_object_add(root, "modules", modules);
559
560 for (size_t i = 0; i < n_names; i++) {
561 if (dump_module(modules, names[i]) < 0) rcode = EXIT_FAILURE;
562 }
563
564 json_str = json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_NOSLASHESCAPE);
565 if (output_file) {
566 FILE *out = fopen(output_file, "w");
567 if (!out) {
568 fprintf(stderr, "Failed opening %s: %s\n", output_file, fr_syserror(errno));
569 exit(EXIT_FAILURE);
570 }
571 fputs(json_str, out);
572 fputc('\n', out);
573 fclose(out);
574 } else {
575 fputs(json_str, stdout);
576 fputc('\n', stdout);
577 }
578
579 json_object_put(root);
580 }
581
582 return rcode;
583}
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:512
#define NEVER_RETURNS
Should be placed before the function return type.
Definition build.h:334
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:1874
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:623
conf_parser_flags_t flags
Flags which control parsing behaviour.
Definition cf_parse.h:612
fr_type_t type
An fr_type_t value, controls the output type.
Definition cf_parse.h:610
char const * name2
Second identifier for CONF_SECTION.
Definition cf_parse.h:608
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:661
char const * name1
Name of the CONF_ITEM to parse.
Definition cf_parse.h:607
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:626
conf_parser_flags_t
Definition cf_parse.h:421
@ CONF_FLAG_REF
reference another conf_parser_t inline in this one
Definition cf_parse.h:457
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:423
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:606
#define CF_IDENT_ANY
Definition cf_util.h:80
TALLOC_CTX * autofree
Definition common.c:29
#define MEM(x)
Definition debug.h:36
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:4690
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:306
@ 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:1952
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:600
enum fr_token fr_token_t
#define FR_DICTIONARY_INTERNAL_DIR
Definition conf.h:8
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 size_t char ** out
Definition value.h:1030