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

📄 config.c

📁 jabber server jabber server jabber server jabber server
💻 C
字号:
/* -------------------------------------------------------------------------- * * License * * The contents of this file are subject to the Jabber Open Source License * Version 1.0 (the "JOSL").  You may not copy or use this file, in either * source code or executable form, except in compliance with the JOSL. You * may obtain a copy of the JOSL at http://www.jabber.org/ or at * http://www.opensource.org/.   * * Software distributed under the JOSL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL * for the specific language governing rights and limitations under the * JOSL. * * Copyrights *  * Portions created by or assigned to Jabber.com, Inc. are  * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact * information for Jabber.com, Inc. is available at http://www.jabber.com/. * * Portions Copyright (c) 1998-1999 Jeremie Miller. *  * Acknowledgements *  * Special thanks to the Jabber Open Source Contributors for their * suggestions and support of Jabber. *  * Alternatively, the contents of this file may be used under the terms of the * GNU General Public License Version 2 or later (the "GPL"), in which case * the provisions of the GPL are applicable instead of those above.  If you * wish to allow use of your version of this file only under the terms of the * GPL and not to allow others to use your version of this file under the JOSL, * indicate your decision by deleting the provisions above and replace them * with the notice and other provisions required by the GPL.  If you do not * delete the provisions above, a recipient may use your version of this file * under either the JOSL or the GPL.  *  *  * --------------------------------------------------------------------------*/#include "jabberd.h"#define MAX_INCLUDE_NESTING 20extern pool      jabberd__runtime;xht instance__ids=NULL;typedef struct shutdown_list{    pool p;    shutdown_func f;    void *arg;    struct shutdown_list *next;} _sd_list, *sd_list;sd_list shutdown__list=NULL;xmlnode greymatter__ = NULL;void do_include(int nesting_level,xmlnode x){    xmlnode cur;    cur=xmlnode_get_firstchild(x);    for(;cur!=NULL;)    {        if(cur->type!=NTYPE_TAG)         {            cur=xmlnode_get_nextsibling(cur);            continue;        }        if(j_strcmp(xmlnode_get_name(cur),"jabberd:include")==0)        {            xmlnode include;            char *include_file=xmlnode_get_data(cur);            xmlnode include_x=xmlnode_file(include_file);            /* check for bad nesting */            if(nesting_level>MAX_INCLUDE_NESTING)            {                fprintf(stderr, "ERROR: Included files nested %d levels deep.  Possible Recursion\n",nesting_level);                exit(1);            }            include=cur;            xmlnode_hide(include);            /* check to see what to insert...             * if root tag matches parent tag of the <include/> -- firstchild             * otherwise, insert the whole file             */             if(j_strcmp(xmlnode_get_name(xmlnode_get_parent(cur)),xmlnode_get_name(include_x))==0)                xmlnode_insert_node(x,xmlnode_get_firstchild(include_x));             else                xmlnode_insert_node(x,include_x);             do_include(nesting_level+1,include_x);             cur=xmlnode_get_nextsibling(cur);             continue;        }        else         {            do_include(nesting_level,cur);        }        cur=xmlnode_get_nextsibling(cur);    }}void cmdline_replace(xmlnode x, xht cmd_line){    char *flag;    char *replace_text;    xmlnode cur=xmlnode_get_firstchild(x);    for(;cur!=NULL;cur=xmlnode_get_nextsibling(cur))    {        if(cur->type!=NTYPE_TAG)continue;        if(j_strcmp(xmlnode_get_name(cur),"jabberd:cmdline")!=0)        {            cmdline_replace(cur, cmd_line);            continue;        }        flag=xmlnode_get_attrib(cur,"flag");        replace_text=xhash_get(cmd_line,flag);        if(replace_text==NULL) replace_text=xmlnode_get_data(cur);        xmlnode_hide(xmlnode_get_firstchild(x));        xmlnode_insert_cdata(x,replace_text,-1);        break;    }}/** * activate the configured debugging settings * * @param x the parsed XML configuration file */void _set_configured_debug(xmlnode x) {    xmlnode debug, mask, facility;    char *debugmask, *facility_str;    debug = xmlnode_get_tag(x, "debug");    if (debug == NULL) {	set_debug_flag(0);	return;    }    mask = xmlnode_get_tag(debug, "mask");    if (mask != NULL) {	debugmask = xmlnode_get_data(mask);	set_debug_flag(debugmask == NULL ? 0 : atoi(debugmask));    } else {	set_debug_flag(0);    }    facility = xmlnode_get_tag(debug, "facility");    facility_str = facility == NULL ? NULL : xmlnode_get_data(facility);    if (facility_str != NULL) {	int facility = log_get_facility(facility_str);	set_debug_facility(facility);	if (facility == -1) {	    log_alert(NULL, "debugging configuration error: unknown syslog facility: %s", facility);	}    } else {	set_debug_facility(-1);    }}/*  * <pidfile>/path/to/pid.file</pidfile> * * Ability to store the PID of the process in a file somewhere. * */void show_pid(xmlnode x){    xmlnode pidfile;    char *path;    char pidstr[16];    int fd;    pid_t pid;    /* HACKAGE: if we're reloading, ignore this check */    if(jabberd__signalflag == SIGHUP) return;    pidfile = xmlnode_get_tag(x, "pidfile");    if(pidfile == NULL)        return;    path = xmlnode_get_data(pidfile);    if(path == NULL)    {        return;    }    fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0600);    if(fd < 0)    {        if(errno == EEXIST)        {            fprintf(stderr, "A pidfile already exists at the specified location.  Check to ensure another copy of the server is not running, or remove the existing file.\n");            _exit(1);	/* no not remove the pid file */        }        close(fd);        unlink(path);    }    pid = getpid();    snprintf(pidstr, 16, "%d", pid);    write(fd, &pidstr, strlen(pidstr));    close(fd);    return;}int configurate(char *file, xht cmd_line){    char def[] = CONFIG_DIR"/jabber.xml";    char *realfile = (char *)def;    xmlnode incl;    char *c;    /* if no file name is specified, fall back to the default file */    if(file != NULL)        realfile = file;    /* read and parse file */    greymatter__ = xmlnode_file(realfile);    /* was the there a read/parse error? */    if(greymatter__ == NULL)    {        fprintf(stderr, "Configuration parsing using %s failed: %s\n",realfile,xmlnode_file_borked(realfile));        return 1;    }    /* parse -i foo.xml,bar.xml */    if((realfile = xhash_get(cmd_line,"i")) != NULL)        while(realfile != NULL)        {            c = strchr(realfile,',');            if(c != NULL)            {                *c = '\0';                c++;            }            if((incl = xmlnode_file(realfile)) == NULL)            {                fprintf(stderr, "Configuration parsing included file %s failed: %s\n",realfile,xmlnode_file_borked(realfile));                return 1;            }else{                xmlnode_insert_tag_node(greymatter__,incl);                xmlnode_free(incl);            }            realfile = c;        }    /* check greymatter for additional includes */    do_include(0,greymatter__);    cmdline_replace(greymatter__, cmd_line);    show_pid(greymatter__);    _set_configured_debug(greymatter__);    return 0;}/* private config handler list */typedef struct cfg_struct{    char *node;    cfhandler f;    void *arg;    struct cfg_struct *next;} *cfg, _cfg;cfg cfhandlers__ = NULL;pool cfhandlers__p = NULL;/* register a function to handle that node in the config file */void register_config(char *node, cfhandler f, void *arg){    cfg newg;    cfhandlers__p = jabberd__runtime;    /* create and setup */    newg = pmalloco(cfhandlers__p, sizeof(_cfg));    newg->node = pstrdup(cfhandlers__p,node);    newg->f = f;    newg->arg = arg;    /* hook into global */    newg->next = cfhandlers__;    cfhandlers__ = newg;}/* util to scan through registered config callbacks */cfg cfget(char *node){    cfg next = NULL;    for(next = cfhandlers__; next != NULL && strcmp(node,next->node) != 0; next = next->next);    return next;}/*  * walk through the instance HASH, and cleanup the instances */void _instance_cleanup(xht h, const char *key, void *data, void *arg){    instance i=(instance)data;    unregister_instance(i,i->id);    xhash_zap(instance__ids, i->id);    while(i->hds)    {        handel h=i->hds->next;        pool_free(i->hds->p);        i->hds=h;    }    pool_free(i->p);}void instance_shutdown(instance i);int instance_startup(xmlnode x, int exec){    ptype type;    xmlnode cur;    cfg c;    instance newi = NULL;    pool p;    type = p_NONE;    if(j_strcmp(xmlnode_get_name(x), "pidfile") == 0)        return 0;    if(j_strcmp(xmlnode_get_name(x), "io") == 0)        return 0;    if(j_strcmp(xmlnode_get_name(x), "debug") == 0)	return 0;    if(j_strcmp(xmlnode_get_name(x), "log") == 0)        type = p_LOG;    if(j_strcmp(xmlnode_get_name(x), "xdb") == 0)        type = p_XDB;    if(j_strcmp(xmlnode_get_name(x), "service") == 0)        type = p_NORM;    if(type == p_NONE || xmlnode_get_attrib(x, "id") == NULL || xmlnode_get_firstchild(x) == NULL)    {        fprintf(stderr, "Configuration error in:\n%s\n", xmlnode2str(x));        if(type == p_NONE)         {            fprintf(stderr, "ERROR: Invalid Tag type: %s\n",xmlnode_get_name(x));        }        if(xmlnode_get_attrib(x, "id") == NULL)        {            fprintf(stderr, "ERROR: Section needs an 'id' attribute\n");        }        if(xmlnode_get_firstchild(x)==NULL)        {            fprintf(stderr, "ERROR: Section Has no data in it\n");        }        return -1;    }    if(exec == 1)    {        newi = xhash_get(instance__ids, xmlnode_get_attrib(x,"id"));        if(newi != NULL)        {            fprintf(stderr, "ERROR: Multiple Instances with same id: %s\n",xmlnode_get_attrib(x,"id"));            return -1;        }    }    /* create the instance */    if(exec)    {        jid temp;        p = pool_new();        newi = pmalloco(p, sizeof(_instance));        newi->id = pstrdup(p,xmlnode_get_attrib(x,"id"));        newi->type = type;        newi->p = p;        newi->x = x;        /* make sure the id is valid for a hostname */        temp = jid_new(p, newi->id);        if(temp == NULL || j_strcmp(temp->server, newi->id) != 0)        {            log_alert(NULL, "ERROR: Invalid id name: %s\n",newi->id);            pool_free(p);            return -1;        }        xhash_put(instance__ids,newi->id,newi);        register_instance(newi,newi->id);	register_shutdown((shutdown_func)instance_shutdown, newi);    }    /* loop through all this sections children */    for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur))    {        /* only handle elements */        if(xmlnode_get_type(cur) != NTYPE_TAG)            continue;        /* find the registered function for this element */        c = cfget(xmlnode_get_name(cur));        /* if we don't have a handler, but we do have a namespace, we can just be ignored */        if(c == NULL && xmlnode_get_attrib(cur, "xmlns") != NULL)            continue;        /* no handler or handler returning an error, die */        if(c == NULL  || (c->f)(newi, cur, c->arg) == r_ERR)        {            char *error = pstrdup(xmlnode_pool(cur), xmlnode_get_attrib(cur,"error"));            xmlnode_hide_attrib(cur, "error");            fprintf(stderr, "Invalid Configuration in instance '%s':\n%s\n",xmlnode_get_attrib(x,"id"),xmlnode2str(cur));            if(c == NULL)                 fprintf(stderr, "ERROR: Unknown Base Tag: %s\n",xmlnode_get_name(cur));            else if(error != NULL)                fprintf(stderr, "ERROR: Base Handler Returned an Error:\n%s\n", error);            return -1;        }    }    return 0;}/* execute configuration file */int configo(int exec){    xmlnode cur;    if(instance__ids==NULL)	instance__ids = xhash_new(19);    for(cur = xmlnode_get_firstchild(greymatter__); cur != NULL; cur = xmlnode_get_nextsibling(cur))    {        if(xmlnode_get_type(cur) != NTYPE_TAG || strcmp(xmlnode_get_name(cur),"base") == 0)            continue;        if(instance_startup(cur, exec))        {            return 1;        }    }    return 0;}/* shuts down a single instance, * or all the instances, if i == NULL */void instance_shutdown(instance i){    if(i != NULL)    {        unregister_instance(i,i->id);        xhash_zap(instance__ids, i->id);        while(i->hds)        {            handel h=i->hds->next;            pool_free(i->hds->p);            i->hds=h;        }        pool_free(i->p);    }    else    {        xhash_walk(instance__ids, _instance_cleanup, NULL);    }}void shutdown_callbacks(void){    while(shutdown__list)    {        sd_list s=shutdown__list->next;        (*shutdown__list->f)(shutdown__list->arg);        pool_free(shutdown__list->p);        shutdown__list=s;    }}void register_shutdown(shutdown_func f,void *arg){    pool p;    sd_list new;    if(f==NULL) return;        p=pool_new();    new=pmalloco(p,sizeof(_sd_list));    new->p=p;    new->f=f;    new->arg=arg;    new->next=shutdown__list;    shutdown__list=new;}

⌨️ 快捷键说明

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