From 0c71a026a7b3dbe346da9f840dfb50840e1411f4 Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Sun, 24 Oct 1999 18:00:20 +0000 Subject: [PATCH] Version 0.1.0 from FTP git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@9 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- config.c | 243 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100755 config.c diff --git a/config.c b/config.c new file mode 100755 index 0000000000..58a2741f46 --- /dev/null +++ b/config.c @@ -0,0 +1,243 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Configuration File Parser + * + * Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC + * + * Mark Spencer <markster@linux-support.net> + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <asterisk/config.h> +#include <asterisk/options.h> +#include <asterisk/logger.h> +#include "asterisk.h" + +struct ast_category { + char name[80]; + struct ast_variable *root; + struct ast_category *next; +}; + +struct ast_config { + /* Maybe this structure isn't necessary but we'll keep it + for now */ + struct ast_category *root; +}; + +static char *strip(char *buf) +{ + char *start; + /* Strip off trailing whitespace, returns, etc */ + while(strlen(buf) && (buf[strlen(buf)-1]<33)) + buf[strlen(buf)-1] = '\0'; + start = buf; + /* Strip off leading whitespace, returns, etc */ + while(*start && (*start < 33)) + *start++ = '\0'; + return start; +} + +void ast_destroy(struct ast_config *ast) +{ + struct ast_category *cat, *catn; + struct ast_variable *v, *vn; + + cat = ast->root; + while(cat) { + v = cat->root; + while(v) { + vn = v; + free(v->name); + free(v->value); + v = v->next; + free(vn); + } + catn = cat; + cat = cat->next; + free(catn); + } + free(ast); +} + +int ast_true(char *s) +{ + /* Determine if this is a true value */ + if (!strcasecmp(s, "yes") || + !strcasecmp(s, "true") || + !strcasecmp(s, "y") || + !strcasecmp(s, "t") || + !strcasecmp(s, "1")) + return -1; + return 0; +} + +struct ast_variable *ast_variable_browse(struct ast_config *config, char *category) +{ + struct ast_category *cat; + cat = config->root; + while(cat) { + if (!strcasecmp(cat->name, category)) + return cat->root; + cat = cat->next; + } + return NULL; +} + +char *ast_variable_retrieve(struct ast_config *config, char *category, char *value) +{ + struct ast_variable *v; + v = ast_variable_browse(config, category); + while (v) { + if (!strcasecmp(value, v->name)) + return v->value; + v=v->next; + } + return NULL; +} + +struct ast_config *ast_load(char *configfile) +{ + char fn[256]; + char buf[256]; + struct ast_config *tmp=NULL; + struct ast_category *tmpc=NULL; + struct ast_variable *v, *last=NULL; + FILE *f; + char *c, *cur; + int lineno=0; + if (configfile[0] == '/') { + strncpy(fn, configfile, sizeof(fn)); + } else { + snprintf(fn, sizeof(fn), "%s/%s", AST_CONFIG_DIR, configfile); + } + if ((option_verbose > 1) && !option_debug) { + ast_verbose( VERBOSE_PREFIX_2 "Parsing '%s': ", fn); + fflush(stdout); + } + if ((f = fopen(fn, "r"))) { + if (option_debug) + ast_log(LOG_DEBUG, "Parsing %s\n", fn); + else if (option_verbose > 1) + ast_verbose( "Found\n"); + tmp = malloc(sizeof(struct ast_config)); + if (!tmp) { + ast_log(LOG_WARNING, "Out of memory\n"); + fclose(f); + return NULL; + } + tmp->root = NULL; + while(!feof(f)) { + fgets(buf, sizeof(buf), f); + lineno++; + if (!feof(f)) { + /* Strip off lines using ; as comment */ + c = strchr(buf, ';'); + if (c) + *c = '\0'; + cur = strip(buf); + if (strlen(cur)) { + /* Actually parse the entry */ + if (cur[0] == '[') { + /* A category header */ + /* XXX Don't let them use the same category twice XXX */ + c = strchr(cur, ']'); + if (c) { + *c = 0; + tmpc = malloc(sizeof(struct ast_category)); + if (!tmpc) { + ast_destroy(tmp); + ast_log(LOG_WARNING, + "Out of memory, line %d\n", lineno); + fclose(f); + return NULL; + } + strncpy(tmpc->name, cur+1, sizeof(tmpc->name)); + tmpc->root = NULL; + tmpc->next = tmp->root; + tmp->root = tmpc; + last = NULL; + } else { + ast_log(LOG_WARNING, + "parse error: no closing ']', line %d\n", lineno); + ast_destroy(tmp); + fclose(f); + return NULL; + } + } else { + /* Just a line (variable = value) */ + if (!tmpc) { + ast_log(LOG_WARNING, + "parse error: No category context for line %d\n", lineno); + ast_destroy(tmp); + fclose(f); + return NULL; + } + c = strchr(cur, '='); + if (c) { + *c = 0; + c++; + v = malloc(sizeof(struct ast_variable)); + if (v) { + v->next = NULL; + v->name = strdup(strip(cur)); + v->value = strdup(strip(c)); + if (last) + last->next = v; + else + tmpc->root = v; + last = v; + } else { + ast_log(LOG_WARNING, "Out of memory, line %d\n", lineno); + fclose(f); + ast_destroy(tmp); + } + } else { + ast_log(LOG_WARNING, "No = in line %d\n", lineno); + fclose(f); + ast_destroy(tmp); + } + + } + } + } + } + fclose(f); + } else { + if (option_debug) + ast_log(LOG_DEBUG, "No file to parse: %s\n", fn); + else if (option_verbose > 1) + ast_verbose( "Not found (%s)", strerror(errno)); + } + return tmp; +} + +char *ast_category_browse(struct ast_config *config, char *prev) +{ + struct ast_category *cat; + if (!prev) { + if (config->root) + return config->root->name; + else + return NULL; + } + cat = config->root; + while(cat) { + if (!strcasecmp(cat->name, prev)) { + if (cat->next) + return cat->next->name; + else + return NULL; + } + cat = cat->next; + } + return NULL; +} -- GitLab