⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config.c

📁 这是一个完全开放的
💻 C
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, *                    Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA */#include "util.h"#include "expat/expat.h"/** new config structure */config_t config_new(void){    config_t c;    c = (config_t) malloc(sizeof(struct config_st));    memset(c, 0, sizeof(struct config_st));    c->hash = xhash_new(501);    c->nads = nad_cache_new();    return c;}struct build_data{    nad_t               nad;    int                 depth;};static void _config_startElement(void *arg, const char *name, const char **atts){    struct build_data *bd = (struct build_data *) arg;    int i = 0;        nad_append_elem(bd->nad, -1, (char *) name, bd->depth);    while(atts[i] != NULL)    {        nad_append_attr(bd->nad, -1, (char *) atts[i], (char *) atts[i + 1]);        i += 2;    }    bd->depth++;}static void _config_endElement(void *arg, const char *name){    struct build_data *bd = (struct build_data *) arg;    bd->depth--;}static void _config_charData(void *arg, const char *str, int len){    struct build_data *bd = (struct build_data *) arg;    nad_append_cdata(bd->nad, (char *) str, len, bd->depth);}/** turn an xml file into a config hash */int config_load(config_t c, char *file){    struct build_data bd;    FILE *f;    XML_Parser p;    int done, len, end, i, j, attr;    char buf[1024], *next;    struct nad_elem_st **path;    config_elem_t elem;    /* open the file */    f = fopen(file, "r");    if(f == NULL)    {        fprintf(stderr, "config_load: couldn't open %s for reading: %s\n", file, strerror(errno));        return 1;    }    /* new parser */    p = XML_ParserCreate(NULL);    if(p == NULL)    {        fprintf(stderr, "config_load: couldn't allocate XML parser\n");        fclose(f);        return 1;    }    /* nice new nad to parse it into */    bd.nad = nad_new(c->nads);    bd.depth = 0;    /* setup the parser */    XML_SetUserData(p, (void *) &bd);    XML_SetElementHandler(p, _config_startElement, _config_endElement);    XML_SetCharacterDataHandler(p, _config_charData);    for(;;)    {        /* read that file */        len = fread(buf, 1, 1024, f);        if(ferror(f))        {            fprintf(stderr, "config_load: read error: %s\n", strerror(errno));            XML_ParserFree(p);            fclose(f);            nad_free(bd.nad);            return 1;        }        done = feof(f);        /* parse it */        if(!XML_Parse(p, buf, len, done))        {            fprintf(stderr, "config_load: parse error at line %d: %s\n", XML_GetCurrentLineNumber(p), XML_ErrorString(XML_GetErrorCode(p)));            XML_ParserFree(p);            fclose(f);            nad_free(bd.nad);            return 1;        }        if(done)            break;    }    /* done reading */    XML_ParserFree(p);    fclose(f);    /* now, turn the nad into a config hash */    path = NULL;    len = 0, end = 0;    /* start at 1, so we skip the root element */    for(i = 1; i < bd.nad->ecur; i++)    {        /* make sure we have enough room to add this element to our path */        if(end <= bd.nad->elems[i].depth)        {            end = bd.nad->elems[i].depth + 1;            path = (struct nad_elem_st **) realloc((void *) path, sizeof(struct nad_elem_st *) * end);        }        /* save this path element */        path[bd.nad->elems[i].depth] = &bd.nad->elems[i];        len = bd.nad->elems[i].depth + 1;        /* construct the key from the current path */        next = buf;        for(j = 1; j < len; j++)        {            strncpy(next, bd.nad->cdata + path[j]->iname, path[j]->lname);            next = next + path[j]->lname;            *next = '.';            next++;        }        next--;        *next = '\0';        /* find the config element for this key */        elem = xhash_get(c->hash, buf);        if(elem == NULL)        {            /* haven't seen it before, so create it */            elem = pmalloco(xhash_pool(c->hash), sizeof(struct config_elem_st));            xhash_put(c->hash, pstrdup(xhash_pool(c->hash), buf), elem);        }        /* make room for this value .. can't easily realloc off a pool, so         * we do it this way and let _config_reaper clean up */        elem->values = realloc((void *) elem->values, sizeof(char *) * (elem->nvalues + 1));        /* and copy it in */        if(NAD_CDATA_L(bd.nad, i) > 0)            elem->values[elem->nvalues] = pstrdupx(xhash_pool(c->hash), NAD_CDATA(bd.nad, i), NAD_CDATA_L(bd.nad, i));        else            elem->values[elem->nvalues] = "1";        /* make room for the attribute lists */        elem->attrs = realloc((void *) elem->attrs, sizeof(char **) * (elem->nvalues + 1));        elem->attrs[elem->nvalues] = NULL;        /* count the attributes */        for(attr = bd.nad->elems[i].attr, j = 0; attr >= 0; attr = bd.nad->attrs[attr].next, j++);        /* make space */        elem->attrs[elem->nvalues] = pmalloc(xhash_pool(c->hash), sizeof(char *) * (j * 2 + 2));        /* if we have some */        if(j > 0)        {            /* copy them in */            j = 0;            attr = bd.nad->elems[i].attr;            while(attr >= 0)            {                elem->attrs[elem->nvalues][j] = pstrdupx(xhash_pool(c->hash), NAD_ANAME(bd.nad, attr), NAD_ANAME_L(bd.nad, attr));                elem->attrs[elem->nvalues][j + 1] = pstrdupx(xhash_pool(c->hash), NAD_AVAL(bd.nad, attr), NAD_AVAL_L(bd.nad, attr));                j += 2;                attr = bd.nad->attrs[attr].next;            }        }        /* do this and we can use j_attr */        elem->attrs[elem->nvalues][j] = NULL;        elem->attrs[elem->nvalues][j + 1] = NULL;        elem->nvalues++;    }    if(path != NULL)        free(path);    if(c->nad != NULL)        nad_free(c->nad);    c->nad = bd.nad;    return 0;}/** get the config element for this key */config_elem_t config_get(config_t c, char *key){    return xhash_get(c->hash, key);}/** get config value n for this key */char *config_get_one(config_t c, char *key, int num){    config_elem_t elem = xhash_get(c->hash, key);    if(elem == NULL)        return NULL;    if(num >= elem->nvalues)        return NULL;    return elem->values[num];}/** how many values for this key? */int config_count(config_t c, char *key){    config_elem_t elem = xhash_get(c->hash, key);    if(elem == NULL)        return 0;    return elem->nvalues;}/** get an attr for this value */char *config_get_attr(config_t c, char *key, int num, char *attr){    config_elem_t elem = xhash_get(c->hash, key);    if(num >= elem->nvalues || elem->attrs == NULL || elem->attrs[num] == NULL)        return NULL;    return j_attr((const char **) elem->attrs[num], attr);}/** cleanup helper */static void _config_reaper(xht h, const char *key, void *val, void *arg){    config_elem_t elem = (config_elem_t) val;    free(elem->values);    free(elem->attrs);}/** cleanup */void config_free(config_t c){    xhash_walk(c->hash, _config_reaper, NULL);    xhash_free(c->hash);    nad_free(c->nad);    nad_cache_free(c->nads);    free(c);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -