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

📄 conffile.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		/*		 *	Not doing continuations: check for edge		 *	conditions.		 */		if (cbuf == buf) {			if (eof) break;						ptr = buf;			while (*ptr && isspace((int) *ptr)) ptr++;			if (!*ptr || (*ptr == '#')) continue;		} else if (eof || (len == 0)) {			radlog(L_ERR, "%s[%d]: Continuation at EOF is illegal",			       filename, *lineno);			return -1;		}		/*		 *	See if there's a continuation.		 */		while ((len > 0) &&		       ((cbuf[len - 1] == '\n') || (cbuf[len - 1] == '\r'))) {			len--;			cbuf[len] = '\0';		}		if ((len > 0) && (cbuf[len - 1] == '\\')) {			cbuf[len - 1] = '\0';			cbuf += len - 1;			continue;		}		ptr = cbuf = buf;		t1 = gettoken(&ptr, buf1, sizeof(buf1));		/*		 *	The caller eats "name1 name2 {", and calls us		 *	for the data inside of the section.  So if we		 *	receive a closing brace, then it must mean the		 *	end of the section.		 */	       if (t1 == T_RCBRACE) {		       if (this == current) {			       radlog(L_ERR, "%s[%d]: Too many closing braces",				      filename, *lineno);			       return -1;		       }		       this = this->item.parent;		       continue;		}		/*		 *	Allow for $INCLUDE files		 *		 *      This *SHOULD* work for any level include.		 *      I really really really hate this file.  -cparker		 */	       if ((strcasecmp(buf1, "$INCLUDE") == 0) ||		   (strcasecmp(buf1, "$-INCLUDE") == 0)) {		       int relative = 1;		        t2 = getword(&ptr, buf2, sizeof(buf2));			if (buf2[0] == '$') relative = 0;			value = cf_expand_variables(filename, lineno, this, buf, buf2);			if (!value) return -1;			if (!FR_DIR_IS_RELATIVE(value)) relative = 0;			if (relative) {				value = cf_local_file(current, value, buf3,						      sizeof(buf3));				if (!value) {					radlog(L_ERR, "%s[%d]: Directories too deep.",					       filename, *lineno);					return -1;				}			}#ifdef HAVE_DIRENT_H			/*			 *	$INCLUDE foo/			 *			 *	Include ALL non-"dot" files in the directory.			 *	careful!			 */			if (value[strlen(value) - 1] == '/') {				DIR		*dir;				struct dirent	*dp;				struct stat stat_buf;				DEBUG2("including files in directory %s", value );				dir = opendir(value);				if (!dir) {					radlog(L_ERR, "%s[%d]: Error reading directory %s: %s",					       filename, *lineno, value,					       strerror(errno));					return -1;				}				/*				 *	Read the directory, ignoring "." files.				 */				while ((dp = readdir(dir)) != NULL) {					const char *p;					if (dp->d_name[0] == '.') continue;					/*					 *	Check for valid characters					 */					for (p = dp->d_name; *p != '\0'; p++) {						if (isalpha((int)*p) ||						    isdigit((int)*p) ||						    (*p == '-') ||						    (*p == '_') ||						    (*p == '.')) continue;						break;					}					if (*p != '\0') continue;					snprintf(buf2, sizeof(buf2), "%s%s",						 value, dp->d_name);					if ((stat(buf2, &stat_buf) != 0) ||					    S_ISDIR(stat_buf.st_mode)) continue;					/*					 *	Read the file into the current					 *	configuration sectoin.					 */					if (cf_file_include(buf2, this) < 0) {						closedir(dir);						return -1;					}				}				closedir(dir);			}  else#endif			{ /* it was a normal file */				if (buf1[1] == '-') {					struct stat statbuf;					if (stat(value, &statbuf) < 0) {						DEBUG("WARNING: Not including file %s: %s", value, strerror(errno));						continue;					}				}				if (cf_file_include(value, this) < 0) {					return -1;				}			}			continue;		} /* we were in an include */	       if (strcasecmp(buf1, "$template") == 0) {		       CONF_ITEM *ci;		       CONF_SECTION *parentcs;		       t2 = getword(&ptr, buf2, sizeof(buf2));		       parentcs = cf_top_section(current);		       ci = cf_reference_item(parentcs, this, buf2);		       if (!ci || (ci->type != CONF_ITEM_SECTION)) {				radlog(L_ERR, "%s[%d]: Reference \"%s\" not found",				       filename, *lineno, buf2);				return -1;		       }		       		       if (this->template) {				radlog(L_ERR, "%s[%d]: Section already has a template",				       filename, *lineno);				return -1;		       }		       this->template = cf_itemtosection(ci);		       continue;	       }		/*		 *	Ensure that the user can't add CONF_PAIRs		 *	with 'internal' names;		 */		if (buf1[0] == '_') {			radlog(L_ERR, "%s[%d]: Illegal configuration pair name \"%s\"",					filename, *lineno, buf1);			return -1;		}		/*		 *	Grab the next token.		 */		t2 = gettoken(&ptr, buf2, sizeof(buf2));		switch (t2) {		case T_EOL:		case T_HASH:			t2 = T_OP_EQ;			value = NULL;			goto do_set;		case T_OP_ADD:		case T_OP_CMP_EQ:		case T_OP_SUB:		case T_OP_LE:		case T_OP_GE:			if (!this || (strcmp(this->name1, "update") != 0)) {				radlog(L_ERR, "%s[%d]: Invalid operator in assignment",				       filename, *lineno);				return -1;			}		case T_OP_EQ:		case T_OP_SET:		do_set:			t3 = getstring(&ptr, buf3, sizeof(buf3));			/*			 *	Handle variable substitution via ${foo}			 */			if ((t3 == T_BARE_WORD) ||			    (t3 == T_DOUBLE_QUOTED_STRING)) {				value = cf_expand_variables(filename, lineno, this,							    buf, buf3);				if (!value) return -1;			} else if ((t3 == T_EOL) ||				   (t3 == T_HASH)) {				value = NULL;			} else {				value = buf3;			}						/*			 *	Add this CONF_PAIR to our CONF_SECTION			 */			cpn = cf_pair_alloc(buf1, value, t2, t3, this);			cpn->item.filename = filename;			cpn->item.lineno = *lineno;			cf_item_add(this, cf_pairtoitem(cpn));			continue;			/*			 *	This horrible code is here to support			 *	if/then/else failover in the			 *	authorize, etc. sections.  It makes no			 *	sense anywhere else.			 */		case T_LBRACE:			if ((strcmp(buf1, "if") == 0) ||			    (strcmp(buf1, "elsif") == 0)) {				const char *end = ptr;				CONF_SECTION *server;				if (!condition_looks_ok(&end)) {					radlog(L_ERR, "%s[%d]: Parse error in condition at: %s",					       filename, *lineno, ptr);					return -1;				}				if ((size_t) (end - ptr) >= (sizeof(buf2) - 1)) {					radlog(L_ERR, "%s[%d]: Statement too complicated after \"%s\"",					       filename, *lineno, buf1);					return -1;				}				/*				 *	More sanity checking.  This is				 *	getting to be a horrible hack.				 */				server = this;				while (server) {					if (strcmp(server->name1, "server") == 0) break;					server = server->item.parent;				}								if (0 && !server) {					radlog(L_ERR, "%s[%d]: Processing directives such as \"%s\" cannot be used here.",					       filename, *lineno, buf1);					return -1;				}				buf2[0] = '(';				memcpy(buf2 + 1, ptr, end - ptr);				buf2[end - ptr + 1] = '\0';				ptr = end + 1;				t2 = T_BARE_WORD;				goto section_alloc;			} else {				radlog(L_ERR, "%s[%d]: Parse error after \"%s\"",				       filename, *lineno, buf1);				return -1;			}			/* FALL-THROUGH */			/*			 *	No '=', must be a section or sub-section.			 */		case T_BARE_WORD:		case T_DOUBLE_QUOTED_STRING:		case T_SINGLE_QUOTED_STRING:			t3 = gettoken(&ptr, buf3, sizeof(buf3));			if (t3 != T_LCBRACE) {				radlog(L_ERR, "%s[%d]: Expecting section start brace '{' after \"%s %s\"",				       filename, *lineno, buf1, buf2);				return -1;			}		case T_LCBRACE:		section_alloc:			css = cf_section_alloc(buf1,					       t2 == T_LCBRACE ? NULL : buf2,					       this);			if (!css) {				radlog(L_ERR, "%s[%d]: Failed allocating memory for section",						filename, *lineno);				return -1;			}			cf_item_add(this, cf_sectiontoitem(css));			css->item.filename = filename;			css->item.lineno = *lineno;			/*			 *	The current section is now the child section.			 */			this = css;			continue;		default:			radlog(L_ERR, "%s[%d]: Parse error after \"%s\"",			       filename, *lineno, buf1);			return -1;		}	}	/*	 *	See if EOF was unexpected ..	 */	if (feof(fp) && (this != current)) {		radlog(L_ERR, "%s[%d]: EOF reached without closing brace for section %s starting at line %d",		       filename, *lineno,		       cf_section_name1(this), cf_section_lineno(this));		return -1;	}	return 0;}/* *	Include one config file in another. */int cf_file_include(const char *filename, CONF_SECTION *cs){	FILE		*fp;	int		lineno = 0;	struct stat	statbuf;	time_t		*mtime;	CONF_DATA	*cd;	DEBUG2( "including configuration file %s", filename);	if (stat(filename, &statbuf) == 0) {#ifdef S_IWOTH		if ((statbuf.st_mode & S_IWOTH) != 0) {			radlog(L_ERR|L_CONS, "Configuration file %s is globally writable.  Refusing to start due to insecure configuration.",			       filename);			return -1;		}#endif#ifdef S_IROTH		if (0 && (statbuf.st_mode & S_IROTH) != 0) {			radlog(L_ERR|L_CONS, "Configuration file %s is globally readable.  Refusing to start due to insecure configuration.",			       filename);			return -1;		}#endif	}	fp = fopen(filename, "r");	if (!fp) {		radlog(L_ERR|L_CONS, "Unable to open file \"%s\": %s",		       filename, strerror(errno));		return -1;	}	/*	 *	Add the filename to the section	 */	mtime = rad_malloc(sizeof(*mtime));	*mtime = statbuf.st_mtime;	if (cf_data_add_internal(cs, filename, mtime, free,				 PW_TYPE_FILENAME) < 0) {		fclose(fp);		radlog(L_ERR|L_CONS, "Internal error open file \"%s\"",		       filename);		return -1;	}	cd = cf_data_find_internal(cs, filename, PW_TYPE_FILENAME);	if (!cd) {		fclose(fp);		radlog(L_ERR|L_CONS, "Internal error open file \"%s\"",		       filename);		return -1;	}	if (!cs->item.filename) cs->item.filename = filename;	/*	 *	Read the section.  It's OK to have EOF without a	 *	matching close brace.	 */	if (cf_section_read(cd->name, &lineno, fp, cs) < 0) {		fclose(fp);		return -1;	}	fclose(fp);	return 0;}/* *	Bootstrap a config file. */CONF_SECTION *cf_file_read(const char *filename){	char *p;	CONF_PAIR *cp;	CONF_SECTION *cs;	cs = cf_section_alloc("main", NULL, NULL);	if (!cs) return NULL;	cp = cf_pair_alloc("confdir", filename, T_OP_SET, T_BARE_WORD, cs);	if (!cp) return NULL;	p = strrchr(cp->value, FR_DIR_SEP);	if (p) *p = '\0';	cp->item.filename = "internal";	cp->item.lineno = 0;	cf_item_add(cs, cf_pairtoitem(cp));	if (cf_file_include(filename, cs) < 0) {		cf_section_free(&cs);		return NULL;	}	return cs;}/* * Return a CONF_PAIR within a CONF_SECTION. */CONF_PAIR *cf_pair_find(const CONF_SECTION *cs, const char *name){	CONF_ITEM	*ci;	CONF_PAIR	*cp = NULL;	if (!cs) return NULL;	/*	 *	Find the name in the tree, for speed.	 */	if (name) {		CONF_PAIR mycp;		mycp.attr = name;		cp = rbtree_finddata(cs->pair_tree, &mycp);	} else {		/*		 *	Else find the first one that matches		 */		for (ci = cs->children; ci; ci = ci->next) {			if (ci->type == CONF_ITEM_PAIR) {				return cf_itemtopair(ci);			}		}	}	if (cp || !cs->template) return cp;	return cf_pair_find(cs->template, name);}/* * Return the attr of a CONF_PAIR */const char *cf_pair_attr(CONF_PAIR *pair){	return (pair ? pair->attr : NULL);}/* * Return the value of a CONF_PAIR */const char *cf_pair_value(CONF_PAIR *pair){	return (pair ? pair->value : NULL);}/* *	Copied here for error reporting. */extern void librad_log(const char *, ...);/* * Turn a CONF_PAIR into a VALUE_PAIR * For now, ignore the "value_type" field... */VALUE_PAIR *cf_pairtovp(CONF_PAIR *pair){	VALUE_PAIR *vp;	if (!pair) {		librad_log("Internal error");		return NULL;	}	if (!pair->value) {		librad_log("No value given for attribute %s", pair->attr);		return NULL;	}	/*	 *	pairmake handles tags.  pairalloc() doesn't.	 */	vp = pairmake(pair->attr, NULL, pair->operator);	if (!vp) {		return NULL;	}	if (pair->value_type == T_BARE_WORD) {		if ((vp->type == PW_TYPE_STRING) && 		    (pair->value[0] == '0') && (pair->value[1] == 'x')) {			vp->type = PW_TYPE_OCTETS;		}		if (!pairparsevalue(vp, pair->value)) {			pairfree(&vp);			return NULL;		}		vp->flags.do_xlat = 0;	  	} else if (pair->value_type == T_SINGLE_QUOTED_STRING) {		if (!pairparsevalue(vp, pair->value)) {			pairfree(&vp);			return NULL;		}		vp->flags.do_xlat = 0;	} else {		vp->flags.do_xlat = 1;	}	return vp;}/* * Return the first label of a CONF_SECTION */const char *cf_section_name1(const CONF_SECTION *cs){	return (cs ? cs->name1 : NULL);}/* * Return the second label of a CONF_SECTION */const char *cf_section_name2(const CONF_SECTION *cs){	return (cs ? cs->name2 : NULL);}/* * Find a value in a CONF_SECTION */const char *cf_section_value_find(const CONF_SECTION *cs, const char *attr){	CONF_PAIR	*cp;	cp = cf_pair_find(cs, attr);	return (cp ? cp->value : NULL);}/* * Return the next pair after a CONF_PAIR * with a certain name (char *attr) If the requested * attr is NULL, any attr matches. */CONF_PAIR *cf_pair_find_next(const CONF_SECTION *cs,			     CONF_PAIR *pair, const char *attr){	CONF_ITEM	*ci;	/*	 * If pair is NULL this must be a first time run	 * Find the pair with correct name	 */

⌨️ 快捷键说明

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