cfg.c
来自「The Kannel Open Source WAP and SMS gatew」· C语言 代码 · 共 732 行 · 第 1/2 页
C
732 行
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * cfg.c - configuration file handling * * Lars Wirzenius */#include "gwlib/gwlib.h"/* for include dir */#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <dirent.h>struct CfgGroup { Octstr *name; Dict *vars; Octstr *configfile; long line; };static CfgGroup *create_group(void){ CfgGroup *grp; grp = gw_malloc(sizeof(*grp)); grp->name = NULL; grp->vars = dict_create(64, octstr_destroy_item); grp->configfile = NULL; grp->line = 0; return grp;}static void destroy_group(void *arg){ CfgGroup *grp; if (arg != NULL) { grp = arg; octstr_destroy(grp->name); octstr_destroy(grp->configfile); dict_destroy(grp->vars); gw_free(grp); }}struct CfgLoc { Octstr *filename; long line_no; Octstr *line; }; static CfgLoc *cfgloc_create(Octstr *filename) { CfgLoc *cfgloc; cfgloc = gw_malloc(sizeof(*cfgloc)); cfgloc->filename = octstr_duplicate(filename); cfgloc->line_no = 0; cfgloc->line = NULL; return cfgloc; } static void cfgloc_destroy(CfgLoc *cfgloc) { if (cfgloc != NULL) { octstr_destroy(cfgloc->filename); octstr_destroy(cfgloc->line); gw_free(cfgloc); } } static void destroy_group_list(void *arg){ list_destroy(arg, destroy_group);}static void set_group_name(CfgGroup *grp, Octstr *name){ octstr_destroy(grp->name); grp->name = octstr_duplicate(name);}struct Cfg { Octstr *filename; Dict *single_groups; Dict *multi_groups;};static int is_allowed_in_group(Octstr *group, Octstr *variable){ Octstr *groupstr; groupstr = octstr_imm("group"); #define OCTSTR(name) \ if (octstr_compare(octstr_imm(#name), variable) == 0) \ return 1; #define SINGLE_GROUP(name, fields) \ if (octstr_compare(octstr_imm(#name), group) == 0) { \ if (octstr_compare(groupstr, variable) == 0) \ return 1; \ fields \ return 0; \ } #define MULTI_GROUP(name, fields) \ if (octstr_compare(octstr_imm(#name), group) == 0) { \ if (octstr_compare(groupstr, variable) == 0) \ return 1; \ fields \ return 0; \ } #include "cfg.def" return 0;}static int is_single_group(Octstr *query){ #define OCTSTR(name) #define SINGLE_GROUP(name, fields) \ if (octstr_compare(octstr_imm(#name), query) == 0) \ return 1; #define MULTI_GROUP(name, fields) \ if (octstr_compare(octstr_imm(#name), query) == 0) \ return 0; #include "cfg.def" return 0;}static int add_group(Cfg *cfg, CfgGroup *grp){ Octstr *groupname; Octstr *name; List *names; List *list; groupname = cfg_get(grp, octstr_imm("group")); if (groupname == NULL) { error(0, "Group does not contain variable 'group'."); return -1; } set_group_name(grp, groupname); names = dict_keys(grp->vars); while ((name = list_extract_first(names)) != NULL) { if (!is_allowed_in_group(groupname, name)) { error(0, "Group '%s' may not contain field '%s'.", octstr_get_cstr(groupname), octstr_get_cstr(name)); octstr_destroy(name); octstr_destroy(groupname); list_destroy(names, octstr_destroy_item); return -1; } octstr_destroy(name); } list_destroy(names, NULL); if (is_single_group(groupname)) dict_put(cfg->single_groups, groupname, grp); else { list = dict_get(cfg->multi_groups, groupname); if (list == NULL) { list = list_create(); dict_put(cfg->multi_groups, groupname, list); } list_append(list, grp); } octstr_destroy(groupname); return 0;}Cfg *cfg_create(Octstr *filename){ Cfg *cfg; cfg = gw_malloc(sizeof(*cfg)); cfg->filename = octstr_duplicate(filename); cfg->single_groups = dict_create(64, destroy_group); cfg->multi_groups = dict_create(64, destroy_group_list); return cfg;}void cfg_destroy(Cfg *cfg){ if (cfg != NULL) { octstr_destroy(cfg->filename); dict_destroy(cfg->single_groups); dict_destroy(cfg->multi_groups); gw_free(cfg); }}static void parse_value(Octstr *value){ Octstr *temp; long len; int c; octstr_strip_blanks(value); len = octstr_len(value); if (octstr_get_char(value, 0) != '"' || octstr_get_char(value, len - 1) != '"') return; octstr_delete(value, len - 1, 1); octstr_delete(value, 0, 1); temp = octstr_duplicate(value); octstr_truncate(value, 0); while (octstr_len(temp) > 0) { c = octstr_get_char(temp, 0); octstr_delete(temp, 0, 1); if (c != '\\' || octstr_len(temp) == 0) octstr_append_char(value, c); else { c = octstr_get_char(temp, 0); octstr_delete(temp, 0, 1); switch (c) { case '\\': case '"': octstr_append_char(value, c); break; default: octstr_append_char(value, '\\'); octstr_append_char(value, c); break; } } } octstr_destroy(temp);}static List *expand_file(Octstr *file, int forward) { Octstr *os; Octstr *line; List *lines; List *expand; long lineno; CfgLoc *loc; os = octstr_read_file(octstr_get_cstr(file)); if (os == NULL) return NULL; lines = octstr_split(os, octstr_imm("\n")); lineno = 0; expand = list_create(); while ((line = list_extract_first(lines)) != NULL) { ++lineno; loc = cfgloc_create(file); loc->line_no = lineno; loc->line = line; if (forward) list_append(expand, loc); else list_insert(expand, 0, loc); } /* * add newline at each end of included files to avoid * concatenating different groups by mistake */ if (lineno > 0) { loc = cfgloc_create(file); loc->line_no = lineno; loc->line = octstr_create("\n"); if (forward) list_append(expand, loc); else list_insert(expand, 0, loc); } list_destroy(lines, octstr_destroy_item); octstr_destroy(os); return expand; } int cfg_read(Cfg *cfg) { CfgLoc *loc; CfgLoc *loc_inc; List *lines; List *expand;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?