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

📄 xdb_file.c

📁 jabber server jabber server jabber server jabber server
💻 C
📖 第 1 页 / 共 2 页
字号:
    if(flag_set)    {	act = xmlnode_get_attrib(p->x,"action");	match = xmlnode_get_attrib(p->x,"match");        if(act != NULL)        {            switch(*act)            {            case 'i': /* insert action */                if(data == NULL)                { /* we're inserting into something that doesn't exist?!?!? */                    data = xmlnode_insert_tag(top,"foo");                    xmlnode_put_attrib(data,"xdbns",ns);                    xmlnode_put_attrib(data,"xmlns",ns); /* should have a top-level xmlns attrib */                }                xmlnode_hide(xmlnode_get_tag(data,match)); /* any match is a goner */                /* insert the new chunk into the existing data */                xmlnode_insert_tag_node(data, xmlnode_get_firstchild(p->x));                break;            case 'c': /* check action */                if(match != NULL)                    data = xmlnode_get_tag(data,match);                if(j_strcmp(xmlnode_get_data(data),xmlnode_get_data(xmlnode_get_firstchild(p->x))) != 0)                {                    log_debug2(ZONE, LOGT_STORAGE|LOGT_DELIVER, "xdb check action returning error to signify unsuccessful check");                    return r_ERR;                }                flag_set = 0;		/*		 * XXX Is there a bug here?		 *		 * I suspect that the check action will always return r_ERR!		 * Up to this point the ret variable has not been changed, and if		 * we arrived here I cannot imagine how it should be changed afterwards.		 * This means that the function will return r_ERR too.		 * I expect this is a bug and something like "ret = 1;" should be inserted		 * at this point.		 *		 * The problem is that I am not completely sure what the check action is		 * supposed to do. What I imagine is:		 * It is intended to compare the content of xdb with the content of the		 * xdb request and return r_ERR if it is different and r_DONE if it		 * is the same.		 *		 * It is only used in jsm/modules/mod_auth_plain.c in the function		 * mod_auth_plain_jane(...) function. At this function there is already		 * a check if the password is the same some lines above ... so it		 * would make no sence to call the check action if it does what I said		 * above as it would be always result in being different - in which		 * case it is no surprize that we have no problem, that this function		 * always returns r_ERR (which would signal that it's different too).		 *		 * It should be checked if the xdb_act(...) in mod_auth_plain_jane(...)		 * is needed. If it isn't, we could remove the check action from		 * xdb completely.		 *		 * Please see also:		 * http://web.archive.org/web/20020601233959/http://jabberd.jabberstudio.org/1.4/142changelog.html		 * In that case it seems to be a bug here ...		 */                break;            default:                log_warn("xdb_file","unable to handle unknown xdb action '%s'",act);                return r_ERR;            }        }else{            if(data != NULL)                xmlnode_hide(data);            /* copy the new data into file */            data = xmlnode_insert_tag_node(top, xmlnode_get_firstchild(p->x));            xmlnode_put_attrib(data,"xdbns",ns);        }        /* save the file if we still want to */	if (flag_set)	{	    int tmp = xmlnode2file_limited(full,file,xf->sizelimit);	    if (tmp == 0)		log_notice(p->id->server,"xdb request failed, due to the size limit of %i to file %s", xf->sizelimit, full);	    else if (tmp < 0)		log_error(p->id->server,"xdb request failed, unable to save to file %s",full);	    else		ret = 1;	}    }else{        /* a get always returns, data or not */        ret = 1;        if(data != NULL)        { /* cool, send em back a copy of the data */            xmlnode_hide_attrib(xmlnode_insert_tag_node(p->x, data),"xdbns");        }    }    if(ret)    {        xmlnode_put_attrib(p->x,"type","result");        xmlnode_put_attrib(p->x,"to",xmlnode_get_attrib(p->x,"from"));        xmlnode_put_attrib(p->x,"from",jid_full(p->id));        deliver(dpacket_new(p->x), NULL); /* dpacket_new() shouldn't ever return NULL */        /* remove the cache'd item if it was a set or we're not configured to cache */        if(xf->timeout == 0 || flag_set)        {            log_debug2(ZONE, LOGT_STORAGE, "decaching %s",full);            xhash_zap(xf->cache,full);            xmlnode_free(file);        }        return r_DONE;    }else{        return r_ERR;    }}void xdb_file_cleanup(void *arg){    xdbf xf = (xdbf)arg;    xhash_free(xf->cache);}/** * convert a spool directory for a given host from the old format * to the new one which distributes the files over several subdirs * * @param p the memory pool we can use * @param spoolroot the root folder of the spool * @param host the host for which we should try to convert */void _xdb_convert_hostspool(pool p, const char *spoolroot, char *host){    DIR *sdir;    struct dirent *dent;    char digit01[3], digit23[3];    char *hostspool;    /* get the dir location */    hostspool = spools(p, spoolroot, "/", host, p);    log_notice(ZONE, "trying to convert spool %s (this may take some time)", hostspool);    /* we have to convert the spool */    sdir = opendir(hostspool);    if (sdir == NULL)    {	log_error("xdb_file", "failed to open directory %s for conversion: %s", hostspool, strerror(errno));	return;    }    while ((dent = readdir(sdir))!=NULL)    {	char *str_ptr;	size_t filenamelength = strlen(dent->d_name);	if (filenamelength<4)	    continue;	str_ptr = (dent->d_name)+filenamelength-4;	/* do we have to convert this file? */	if (j_strcmp(str_ptr, ".xml") == 0)	{	    char *oldname, *newname;	    _xdb_get_hashes(dent->d_name, digit01, digit23);	    oldname = spools(p, hostspool, "/", dent->d_name, p);	    newname = spools(p, hostspool, "/", digit01, "/", digit23, "/", dent->d_name, p);	    if (!_xdb_gen_dirs(spool_new(p), spoolroot, host, digit01, digit23, 1))		log_error("xdb_file", "failed to create necessary directory for conversion");	    else if (rename(oldname, newname) < 0)		log_error("xdb_file", "failed to move %s to %s while converting spool: %s", oldname, newname, strerror(errno));	}    }    /* close the directory */    closedir(sdir);}/** * convert a spool directory from the old format to the new one * which distributes the files over several subdirs * * @param spoolroot the root folder of the spool */void xdb_convert_spool(const char *spoolroot){    DIR *sdir;    struct dirent *dent;    pool p;    char *flagfile;    struct stat s;    FILE *flagfileh;    /* use our own memory pool */    p = pool_new();    /* check if we already converted this spool */    flagfile = spools(p, spoolroot, "/.hashspool", p);    if (stat(flagfile, &s) == 0)    {	log_debug2(ZONE, LOGT_STORAGE, "there is already a new hashspool");	pool_free(p);	return;    }    /* what is in this directory? */    sdir = opendir(spoolroot);    if (sdir == NULL)    {	pool_free(p);	return;    }    while ((dent = readdir(sdir)) != NULL)    {	struct stat s;	char *dirname = spools(p, spoolroot, "/", dent->d_name, p);	if (stat(dirname, &s)<0)	    continue;	/* we only care about directories */	if (!S_ISDIR(s.st_mode))	    continue;	if (dent->d_name[0]!='\0' && dent->d_name[0]!='.')	    _xdb_convert_hostspool(p, spoolroot, dent->d_name);    }    closedir(sdir);    /* write the flag that we converted the spool */    flagfileh = fopen(flagfile, "w");    if (flagfileh != NULL)    {	fwrite("Please do not delete this file.\n", 1, 32, flagfileh);	fclose(flagfileh);    }    /* cleanup */    pool_free(p);}void xdb_file(instance i, xmlnode x){    char *spl, *temp;    xmlnode config;    xdbcache xc;    xdbf xf;    int timeout = 3600; /* defaults to timeout in 3600 seconds */    int sizelimit = 500000; /* defaults to 500000 bytes */    log_debug2(ZONE, LOGT_INIT, "xdb_file loading");    xc = xdb_cache(i);    config = xdb_get(xc, jid_new(xmlnode_pool(x),"config@-internal"),"jabber:config:xdb_file");    spl = xmlnode_get_tag_data(config,"spool");    if(spl == NULL)    {        log_error(NULL,"xdb_file: No filesystem spool location configured");        return;    }    if(xmlnode_get_tag(config, "sizelimit")) {        temp = xmlnode_get_tag_data(config,"sizelimit");        if(temp != NULL)            sizelimit = atoi(temp);        else /* no value: disable timeout */            sizelimit = 0;    }    if(xmlnode_get_tag(config, "timeout")) {        temp = xmlnode_get_tag_data(config,"timeout");        if(temp != NULL)            timeout = atoi(temp);        else /* no value: disable timeout */            timeout = -1;    }    xf = pmalloco(i->p,sizeof(_xdbf));    xf->spool = pstrdup(i->p,spl);    xf->timeout = timeout;    xf->sizelimit = sizelimit;    xf->i = i;    xf->cache = xhash_new(j_atoi(xmlnode_get_tag_data(config,"maxfiles"),FILES_PRIME));    xf->use_hashspool = xmlnode_get_tag(config, "use_hierarchical_spool") ? 1 : 0;    if (xf->use_hashspool)	xdb_convert_spool(spl);    register_phandler(i, o_DELIVER, xdb_file_phandler, (void *)xf);    if(timeout > 0) /* 0 is expired immediately, -1 is cached forever */        register_beat(timeout, xdb_file_purge, (void *)xf);    xmlnode_free(config);    pool_cleanup(i->p, xdb_file_cleanup, (void*)xf);}

⌨️ 快捷键说明

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