21RCSID(
"$Id: 64b1eae4ca9278e86f0391cef83271d5d6e494c3 $")
23#include <freeradius-devel/server/base.h>
24#include <freeradius-devel/server/cf_file.h>
25#include <freeradius-devel/server/cf_util.h>
26#include <freeradius-devel/util/atexit.h>
27#include <freeradius-devel/util/debug.h>
28#include <freeradius-devel/util/syserror.h>
30#include <json-c/json.h>
47#define quote_token(_s) fr_token_from_quote_enum_str((_s), T_BARE_WORD)
55static char const *
json_get_str(
struct json_object *o,
char const *key)
57 struct json_object *v;
58 if (!json_object_object_get_ex(o, key, &v))
return NULL;
59 if (!v || json_object_is_type(v, json_type_null))
return NULL;
60 return json_object_get_string(v);
63static int json_get_int(
struct json_object *o,
char const *key,
int dflt)
65 struct json_object *v;
66 if (!json_object_object_get_ex(o, key, &v))
return dflt;
67 if (!v || json_object_is_type(v, json_type_null))
return dflt;
68 return json_object_get_int(v);
77 struct json_object *loc;
79 if (!json_object_object_get_ex(
item,
"location", &loc)) {
85 if (!loc || json_object_is_type(loc, json_type_null))
goto error;
101 char const *filename;
107 fprintf(stderr,
"pair without attr (line %d)\n", lineno);
120 cf_filename_set(cp, (filename && filename[0] !=
'<') ? filename :
"converted");
129 struct json_object *children;
132 char const *filename;
138 fprintf(stderr,
"section without name1 (line %d)\n", lineno);
148 if (json_object_object_get_ex(
item,
"children", &children) && children) {
149 size_t n = json_object_array_length(children);
150 for (
size_t i = 0; i <
n; i++) {
151 struct json_object *child = json_object_array_get_idx(children, i);
163 char const *filename;
171 cf_filename_set(c, (filename && filename[0] !=
'<') ? filename :
"converted");
189 static size_t item_builders_len =
NUM_ELEMENTS(item_builders);
195 fprintf(stderr,
"item without type field\n");
201 fprintf(stderr,
"unknown item type %s\n",
type);
215 struct json_object *children;
218 char const *filename;
223 if (!name1) name1 =
"main";
226 if (!cs)
return NULL;
231 if (json_object_object_get_ex(root,
"children", &children) && children) {
232 size_t n = json_object_array_length(children);
233 for (
size_t i = 0; i <
n; i++) {
234 struct json_object *child = json_object_array_get_idx(children, i);
247 FILE *fp = (rcode == 0) ? stdout : stderr;
249 fprintf(fp,
"Usage: radjson2conf [options]\n"
250 " -i <file> Read JSON from <file> (default stdin).\n"
251 " -o <file> Write conf to <file> (default stdout).\n"
252 " -r Strip the root section wrapper, emit children at file scope.\n"
253 " Use this to produce a radiusd.conf-style top-level file.\n"
258int main(
int argc,
char *argv[])
261 char const *input_file = NULL;
262 char const *output_file = NULL;
263 bool strip_root =
false;
266 struct json_object *root_json = NULL;
268 int rcode = EXIT_SUCCESS;
281 while ((c = getopt(argc, argv,
"hi:o:r")) != -1) {
291 output_file = optarg;
304 root_json = json_object_from_file(input_file);
306 fprintf(stderr,
"Failed to parse %s: %s\n", input_file, json_util_get_last_err());
313 struct json_tokener *tok = json_tokener_new();
315 while ((
n = read(STDIN_FILENO, buf,
sizeof(buf))) > 0) {
316 root_json = json_tokener_parse_ex(tok, buf,
n);
317 if (json_tokener_get_error(tok) == json_tokener_continue)
continue;
318 if (json_tokener_get_error(tok) != json_tokener_success) {
319 fprintf(stderr,
"JSON parse error: %s\n",
320 json_tokener_error_desc(json_tokener_get_error(tok)));
321 json_tokener_free(tok);
326 json_tokener_free(tok);
329 fprintf(stderr,
"No JSON read from stdin\n");
336 fprintf(stderr,
"Failed to build conf tree\n");
337 json_object_put(root_json);
342 out = fopen(output_file,
"w");
344 fprintf(stderr,
"Failed opening %s: %s\n", output_file,
fr_syserror(errno));
345 rcode = EXIT_FAILURE;
361 fprintf(stderr,
"cf_section_write_children failed\n");
362 rcode = EXIT_FAILURE;
366 fprintf(stderr,
"cf_section_write failed\n");
367 rcode = EXIT_FAILURE;
370 if (
out != stdout) fclose(
out);
374 json_object_put(root_json);
#define NEVER_RETURNS
Should be placed before the function return type.
#define L(_str)
Helper for initialising arrays of string literals.
int cf_section_write_children(FILE *fp, CONF_SECTION *cs, int depth)
Emit the children of a section at depth without an enclosing { ... }.
int cf_section_write(FILE *fp, CONF_SECTION *cs, int depth)
Configuration AVP similar to a fr_pair_t.
A section grouping multiple CONF_PAIR.
CONF_PAIR * cf_pair_alloc(CONF_SECTION *parent, char const *attr, char const *value, fr_token_t op, fr_token_t lhs_quote, fr_token_t rhs_quote)
Allocate a CONF_PAIR.
CONF_COMMENT * cf_comment_alloc(CONF_SECTION *parent, char const *text)
Allocate a new comment item attached to parent.
void cf_expand_variables_set(bool expand)
Opt out of ${var} expansion when reading config (default: enabled).
#define cf_lineno_set(_ci, _lineno)
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
#define cf_filename_set(_ci, _filename)
static NEVER_RETURNS void usage(void)
static TALLOC_CTX * autofree
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
static void json_get_location(struct json_object *item, char const **filename, int *lineno)
int main(int argc, char *argv[])
int(* build_fn_t)(CONF_SECTION *parent, struct json_object *item)
static CONF_SECTION * build_root_section(TALLOC_CTX *ctx, struct json_object *root)
static char const * json_get_str(struct json_object *o, char const *key)
static int json_get_int(struct json_object *o, char const *key, int dflt)
char const * radiusd_version
static int build_section_into(CONF_SECTION *parent, struct json_object *item)
static int build_pair(CONF_SECTION *parent, struct json_object *item)
static int build_comment(CONF_SECTION *parent, struct json_object *item)
static int build_item(CONF_SECTION *parent, struct json_object *item)
static fr_token_t op_token(char const *s)
fr_aka_sim_id_type_t type
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
An element in a lexicographically sorted array of name to ptr mappings.
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
fr_table_num_ordered_t const fr_tokens_table[]
#define RADIUSD_VERSION_BUILD(_x)
Create a version string for a utility in the suite of FreeRADIUS utilities.
static size_t char ** out