/* * Copyright (c) 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: sm-conf-prttree.c,v 1.2 2004/08/26 22:18:55 ca Exp $") #if SM_LIBCONF_ALONE #include #include #include #include "sm-conf.h" #else /* SM_LIBCONF_ALONE */ #include "sm/string.h" #include "sm/sm-conf.h" #include "sm/sm-conf-prt.h" #include "sm/io.h" #endif /* SM_LIBCONF_ALONE */ static int Verbose = 0; static int Noquotes = 0; sm_ret_T sm_conf_dump_entry(sm_conf_T *stream, sm_conf_node_T *node, int indent, sm_file_T *fp) { char const *name, *kw; size_t name_n, kw_n; sm_conf_node_T *sub; switch (sm_conf_node_type(stream, node)) { case SM_CONF_NODE_VALUE: if (Verbose > 1) sm_io_fprintf(smioerr, "value:\t"); if (sm_conf_value(stream, node, &name, &name_n)) { sm_io_fprintf(smioerr, "%p: can't get node value!\n", (void *)node); return 1; } if (Noquotes) sm_io_fprintf(fp, "%.*s", (int)name_n, name); else sm_io_fprintf(fp, "\"%.*s\"", (int)name_n, name); break; case SM_CONF_NODE_LIST: if (Verbose > 1) sm_io_fprintf(smioerr, "list:\t"); switch (sm_conf_list_n(stream, node)) { case 0: sm_io_fprintf(fp, "{}"); break; case 1: sm_io_fprintf(fp, "{ "); sm_conf_dump_entry(stream, sm_conf_list_next(stream, node, NULL), indent + 2, fp); sm_io_fprintf(fp, " }"); break; default: sm_io_fprintf(fp, "{\n"); sub = NULL; while ((sub = sm_conf_list_next(stream, node, sub)) != NULL) { sm_io_fprintf(fp, "%*s", indent + 2, ""); sm_conf_dump_entry(stream, sub, indent + 2, fp); sm_io_fprintf(fp, ",\n"); } sm_io_fprintf(fp, "%*s}", indent, ""); break; } break; case SM_CONF_NODE_SECTION: if (Verbose > 1) sm_io_fprintf(smioerr, "section:\t"); if ( sm_conf_section_name(stream, node, &name, &name_n) || sm_conf_section_keyword(stream, node, &kw, &kw_n)) { sm_io_fprintf(smioerr, "%p: can't get section name?\n", (void*)node); return 2; } if (kw != NULL) sm_io_fprintf(fp, "%.*s ", (int)kw_n, kw); if (name != NULL) sm_io_fprintf(fp, "\"%.*s\" ", (int)name_n, name); sm_io_fprintf(fp, "{\n"); sub = NULL; while ((sub = sm_conf_section_next(stream, node, &name, &name_n, sub)) != NULL) { sm_io_fprintf(fp, "%*s", indent + 2, ""); if (name != NULL) sm_io_fprintf(fp, "%.*s = ", (int)name_n, name); sm_conf_dump_entry(stream, sub, indent + 2, fp); sm_io_fprintf(fp, ";\n"); } sm_io_fprintf(fp, "%*s}", indent, ""); break; } return SM_SUCCESS; } void sm_conf_dump_root(sm_conf_T *stream, sm_conf_node_T *node, sm_file_T *fp) { char const *name; size_t name_n; sm_conf_node_T *sub; sub = NULL; while ((sub = sm_conf_section_next(stream, node, &name, &name_n, sub)) != NULL) { if (name != NULL) sm_io_fprintf(fp, "%.*s = ", (int)name_n, name); sm_conf_dump_entry(stream, sub, 0, fp); sm_io_fprintf(fp, ";\n"); } } #if STANDALONE static int sm_conf_process(char const *name, FILE *fp) { sm_conf_T *stream; sm_conf_node_T *node; int err; if (((stream = sm_conf_new(name ? name : "*stdin*"))) == NULL) { sm_io_fprintf(smioerr, "error -- sm_conf_new() returns NULL!\n"); return 1; } if ((err = sm_conf_read_FILE(stream, name, fp)) != 0) { char buf[SM_CONF_ERROR_BUFFER_SIZE]; char const *e = NULL; sm_io_fprintf(smioerr, "%s: %s\n", name ? name : "*stdin*", sm_conf_strerror(err, buf, sizeof buf)); while ((e = sm_conf_syntax_error(stream, e)) != NULL) sm_io_fprintf(smioerr, "%s\n", e); sm_conf_destroy(stream); return 2; } node = sm_conf_root(stream); if (node != NULL) sm_conf_dump_root(stream, node, smioout); sm_conf_destroy(stream); return 0; } int main(int argc, char **argv) { int ai, r; while ((r = getopt(argc, argv, "qV")) != -1) { switch (r) { case 'q': Noquotes++; break; case 'V': Verbose++; break; default: /* usage(argv[0]); */ return 1; } } argc -= optind; argv += optind; if (argc == 0) return sm_conf_process("*stdin*", stdin); for (ai = 0; ai < argc; ai++) { int ret; ret = sm_conf_process(argv[ai], NULL); if (ret != 0) return ret; } return 0; } #endif /* STANDALONE */