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 + -
显示快捷键?