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

📄 conffile.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (pair == NULL){		return cf_pair_find(cs, attr);	}	ci = cf_pairtoitem(pair)->next;	for (; ci; ci = ci->next) {		if (ci->type != CONF_ITEM_PAIR)			continue;		if (attr == NULL || strcmp(cf_itemtopair(ci)->attr, attr) == 0)			break;	}	return cf_itemtopair(ci);}/* * Find a CONF_SECTION, or return the root if name is NULL */CONF_SECTION *cf_section_find(const char *name){	if (name)		return cf_section_sub_find(mainconfig.config, name);	else		return mainconfig.config;}/* * Find a sub-section in a section */CONF_SECTION *cf_section_sub_find(const CONF_SECTION *cs, const char *name){	CONF_ITEM *ci;	/*	 *	Do the fast lookup if possible.	 */	if (name && cs->section_tree) {		CONF_SECTION mycs;		mycs.name1 = name;		mycs.name2 = NULL;		return rbtree_finddata(cs->section_tree, &mycs);	}	for (ci = cs->children; ci; ci = ci->next) {		if (ci->type != CONF_ITEM_SECTION)			continue;		if (strcmp(cf_itemtosection(ci)->name1, name) == 0)			break;	}	return cf_itemtosection(ci);}/* *	Find a CONF_SECTION with both names. */CONF_SECTION *cf_section_sub_find_name2(const CONF_SECTION *cs,					const char *name1, const char *name2){	CONF_ITEM    *ci;	if (!cs) cs = mainconfig.config;	if (name1 && (cs->section_tree)) {		CONF_SECTION mycs, *master_cs;		mycs.name1 = name1;		mycs.name2 = name2;		master_cs = rbtree_finddata(cs->section_tree, &mycs);		if (master_cs) {			return rbtree_finddata(master_cs->name2_tree, &mycs);		}	}	/*	 *	Else do it the old-fashioned way.	 */	for (ci = cs->children; ci; ci = ci->next) {		CONF_SECTION *subcs;		if (ci->type != CONF_ITEM_SECTION)			continue;		subcs = cf_itemtosection(ci);		if (!name1) {			if (!subcs->name2) {				if (strcmp(subcs->name1, name2) == 0) break;			} else {				if (strcmp(subcs->name2, name2) == 0) break;			}			continue; /* don't do the string comparisons below */		}		if ((strcmp(subcs->name1, name1) == 0) &&		    (subcs->name2 != NULL) &&		    (strcmp(subcs->name2, name2) == 0))			break;	}	return cf_itemtosection(ci);}/* * Return the next subsection after a CONF_SECTION * with a certain name1 (char *name1). If the requested * name1 is NULL, any name1 matches. */CONF_SECTION *cf_subsection_find_next(CONF_SECTION *section,				      CONF_SECTION *subsection,				      const char *name1){	CONF_ITEM	*ci;	/*	 * If subsection is NULL this must be a first time run	 * Find the subsection with correct name	 */	if (subsection == NULL){		ci = section->children;	} else {		ci = cf_sectiontoitem(subsection)->next;	}	for (; ci; ci = ci->next) {		if (ci->type != CONF_ITEM_SECTION)			continue;		if ((name1 == NULL) ||		    (strcmp(cf_itemtosection(ci)->name1, name1) == 0))			break;	}	return cf_itemtosection(ci);}/* * Return the next section after a CONF_SECTION * with a certain name1 (char *name1). If the requested * name1 is NULL, any name1 matches. */CONF_SECTION *cf_section_find_next(CONF_SECTION *section,				   CONF_SECTION *subsection,				   const char *name1){	if (!section->item.parent) return NULL;	return cf_subsection_find_next(section->item.parent, subsection, name1);}/* * Return the next item after a CONF_ITEM. */CONF_ITEM *cf_item_find_next(CONF_SECTION *section, CONF_ITEM *item){	/*	 * If item is NULL this must be a first time run	 * Return the first item	 */	if (item == NULL) {		return section->children;	} else {		return item->next;	}}int cf_section_lineno(CONF_SECTION *section){	return cf_sectiontoitem(section)->lineno;}const char *cf_pair_filename(CONF_PAIR *pair){	return cf_pairtoitem(pair)->filename;}const char *cf_section_filename(CONF_SECTION *section){	return cf_sectiontoitem(section)->filename;}int cf_pair_lineno(CONF_PAIR *pair){	return cf_pairtoitem(pair)->lineno;}int cf_item_is_section(CONF_ITEM *item){	return item->type == CONF_ITEM_SECTION;}int cf_item_is_pair(CONF_ITEM *item){	return item->type == CONF_ITEM_PAIR;}static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, const char *name,				void *data, void (*data_free)(void *)){	char *p;	size_t name_len;	CONF_DATA *cd;	name_len = strlen(name) + 1;	p = rad_malloc(sizeof(*cd) + name_len);	cd = (CONF_DATA *) p;	memset(cd, 0, sizeof(*cd));	cd->item.type = CONF_ITEM_DATA;	cd->item.parent = parent;	cd->data = data;	cd->free = data_free;	p += sizeof(*cd);	memcpy(p, name, name_len);	cd->name = p;	return cd;}static void *cf_data_find_internal(CONF_SECTION *cs, const char *name,				   int flag){	if (!cs || !name) return NULL;	/*	 *	Find the name in the tree, for speed.	 */	if (cs->data_tree) {		CONF_DATA mycd;		mycd.name = name;		mycd.flag = flag;		return rbtree_finddata(cs->data_tree, &mycd);	}	return NULL;}/* *	Find data from a particular section. */void *cf_data_find(CONF_SECTION *cs, const char *name){	CONF_DATA *cd = cf_data_find_internal(cs, name, 0);	if (cd) return cd->data;	return NULL;}/* *	Add named data to a configuration section. */static int cf_data_add_internal(CONF_SECTION *cs, const char *name,				void *data, void (*data_free)(void *),				int flag){	CONF_DATA *cd;	if (!cs || !name) return -1;	/*	 *	Already exists.  Can't add it.	 */	if (cf_data_find_internal(cs, name, flag) != NULL) return -1;	cd = cf_data_alloc(cs, name, data, data_free);	if (!cd) return -1;	cd->flag = flag;	cf_item_add(cs, cf_datatoitem(cd));	return 0;}/* *	Add named data to a configuration section. */int cf_data_add(CONF_SECTION *cs, const char *name,		void *data, void (*data_free)(void *)){	return cf_data_add_internal(cs, name, data, data_free, 0);}#if 0/* *	Copy CONF_DATA from src to dst */static void cf_section_copy_data(CONF_SECTION *s, CONF_SECTION *d){	CONF_ITEM *cd, *next, **last;	/*	 *	Don't check if s->data_tree is NULL.  It's child	 *	sections may have data, even if this section doesn't.	 */	rad_assert(d->data_tree == NULL);	d->data_tree = s->data_tree;	s->data_tree = NULL;	/*	 *	Walk through src, moving CONF_ITEM_DATA	 *	to dst, by hand.	 */	last = &(s->children);	for (cd = s->children; cd != NULL; cd = next) {		next = cd->next;		/*		 *	Recursively copy data from child sections.		 */		if (cd->type == CONF_ITEM_SECTION) {			CONF_SECTION *s1, *d1;			s1 = cf_itemtosection(cd);			d1 = cf_section_sub_find_name2(d, s1->name1, s1->name2);			if (d1) {				cf_section_copy_data(s1, d1);			}			last = &(cd->next);			continue;		}		/*		 *	Not conf data, remember last ptr.		 */		if (cd->type != CONF_ITEM_DATA) {			last = &(cd->next);			continue;		}		/*		 *	Remove it from the src list		 */		*last = cd->next;		cd->next = NULL;		/*		 *	Add it to the dst list		 */		if (!d->children) {			rad_assert(d->tail == NULL);			d->children = cd;		} else {			rad_assert(d->tail != NULL);			d->tail->next = cd;		}		d->tail = cd;	}}/* *	For a CONF_DATA element, stat the filename, if necessary. */static int filename_stat(void *context, void *data){	struct stat buf;	CONF_DATA *cd = data;	context = context;	/* -Wunused */	if (cd->flag != PW_TYPE_FILENAME) return 0;	if (stat(cd->name, &buf) < 0) return -1;	if (buf.st_mtime != *(time_t *) cd->data) return -1;	return 0;}/* *	Compare two CONF_SECTIONS.  The items MUST be in the same *	order. */static int cf_section_cmp(CONF_SECTION *a, CONF_SECTION *b){	CONF_ITEM *ca = a->children;	CONF_ITEM *cb = b->children;	while (1) {		CONF_PAIR *pa, *pb;		/*		 *	Done.  Stop.		 */		if (!ca && !cb) break;		/*		 *	Skip CONF_DATA.		 */		if (ca && ca->type == CONF_ITEM_DATA) {			ca = ca->next;			continue;		}		if (cb && cb->type == CONF_ITEM_DATA) {			cb = cb->next;			continue;		}		/*		 *	One is smaller than the other.  Exit.		 */		if (!ca || !cb) return 0;		if (ca->type != cb->type) return 0;		/*		 *	Deal with subsections.		 */		if (ca->type == CONF_ITEM_SECTION) {			CONF_SECTION *sa = cf_itemtosection(ca);			CONF_SECTION *sb = cf_itemtosection(cb);			if (!cf_section_cmp(sa, sb)) return 0;			goto next;		}		rad_assert(ca->type == CONF_ITEM_PAIR);		pa = cf_itemtopair(ca);		pb = cf_itemtopair(cb);		/*		 *	Different attr and/or value, Exit.		 */		if ((strcmp(pa->attr, pb->attr) != 0) ||		    (strcmp(pa->value, pb->value) != 0)) return 0;		/*		 *	And go to the next element.		 */	next:		ca = ca->next;		cb = cb->next;	}	/*	 *	Walk over the CONF_DATA, stat'ing PW_TYPE_FILENAME.	 */	if (a->data_tree &&	    (rbtree_walk(a->data_tree, InOrder, filename_stat, NULL) != 0)) {		return 0;	}	/*	 *	They must be the same, say so.	 */	return 1;}/* *	Migrate CONF_DATA from one section to another. */int cf_section_migrate(CONF_SECTION *dst, CONF_SECTION *src){	CONF_ITEM *ci;	CONF_SECTION *s, *d;	for (ci = src->children; ci != NULL; ci = ci->next) {		if (ci->type != CONF_ITEM_SECTION)			continue;		s = cf_itemtosection(ci);		d = cf_section_sub_find_name2(dst, s->name1, s->name2);		if (!d) continue; /* not in new one, don't migrate it */		/*		 *	A section of the same name is in BOTH src & dst,		 *	compare the CONF_PAIR's.  If they're all the same,		 *	then copy the CONF_DATA from one to the other.		 */		if (cf_section_cmp(s, d)) {			cf_section_copy_data(s, d);		}	}	return 1;		/* rcode means anything? */}#endifint cf_section_template(CONF_SECTION *cs, CONF_SECTION *template){	if (!cs || !template || cs->template || template->template) return -1;	cs->template = template;	return 0;}/* *	This is here to make the rest of the code easier to read.  It *	ties conffile.c to log.c, but it means we don't have to *	pollute every other function with the knowledge of the *	configuration internals. */void cf_log_err(CONF_ITEM *ci, const char *fmt, ...){	va_list ap;	char buffer[256];	va_start(ap, fmt);	vsnprintf(buffer, sizeof(buffer), fmt, ap);	va_end(ap);	radlog(L_ERR, "%s[%d]: %s", ci->filename, ci->lineno, buffer);}void cf_log_info(UNUSED CONF_SECTION *cs, const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	if (debug_flag > 1 && cf_log_config) vradlog(L_DBG, fmt, ap);	va_end(ap);}/* *	Wrapper to simplify the code. */void cf_log_module(UNUSED CONF_SECTION *cs, const char *fmt, ...){	va_list ap;	char buffer[256];	va_start(ap, fmt);	if (debug_flag > 1 && cf_log_modules) {		vsnprintf(buffer, sizeof(buffer), fmt, ap);		radlog(L_DBG, " Module: %s", buffer);	}	va_end(ap);}#if 0/* * JMG dump_config tries to dump the config structure in a readable format **/static int dump_config_section(CONF_SECTION *cs, int indent){	CONF_SECTION	*scs;	CONF_PAIR	*cp;	CONF_ITEM	*ci;	/* The DEBUG macro doesn't let me	 *   for(i=0;i<indent;++i) debugputchar('\t');	 * so I had to get creative. --Pac. */	for (ci = cs->children; ci; ci = ci->next) {		switch (ci->type) {		case CONF_ITEM_PAIR:			cp=cf_itemtopair(ci);			DEBUG("%.*s%s = %s",				indent, "\t\t\t\t\t\t\t\t\t\t\t",				cp->attr, cp->value);			break;		case CONF_ITEM_SECTION:			scs=cf_itemtosection(ci);			DEBUG("%.*s%s %s%s{",				indent, "\t\t\t\t\t\t\t\t\t\t\t",				scs->name1,				scs->name2 ? scs->name2 : "",				scs->name2 ?  " " : "");			dump_config_section(scs, indent+1);			DEBUG("%.*s}",				indent, "\t\t\t\t\t\t\t\t\t\t\t");			break;		default:	/* FIXME: Do more! */			break;		}	}	return 0;}int dump_config(CONF_SECTION *cs){	return dump_config_section(cs, 0);}#endif

⌨️ 快捷键说明

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