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

📄 dict.c

📁 新的radius程序
💻 C
📖 第 1 页 / 共 2 页
字号:
				    (block_vendor != vendor)) {					librad_log("dict_init: %s[%d]: mismatched vendor %s within BEGIN-VENDOR/END-VENDOR block",						   fn, line, argv[3]);					return -1;				}			}			s = strtok(NULL, ",");		}	}	if (block_vendor) vendor = block_vendor;	/*	 *	Special checks for tags, they make our life much more	 *	difficult.	 */	if (flags.has_tag) {		/*		 *	Only string, octets, and integer can be tagged.		 */		switch (type) {		case PW_TYPE_STRING:		case PW_TYPE_INTEGER:			break;		default:			librad_log("dict_init: %s[%d]: Attributes of type %s cannot be tagged.",				   fn, line,				   lrad_int2str(type_table, type, "?Unknown?"));			return -1;					}	}	/*	 *	Add it in.	 */	if (dict_addattr(argv[0], vendor, type, value, flags) < 0) {		librad_log("dict_init: %s[%d]: %s",			   fn, line, librad_errstr);		return -1;	}	return 0;}/* *	Process the VALUE command */static int process_value(const char* fn, const int line, char **argv,			 int argc){	int	value;	if (argc != 3) {		librad_log("dict_init: %s[%d]: invalid VALUE line",			fn, line);		return -1;	}	/*	 *	For Compatibility, skip "Server-Config"	 */	if (strcasecmp(argv[0], "Server-Config") == 0)		return 0;	/*	 *	Validate all entries	 */	if (!isdigit((int) argv[2][0])) {		librad_log("dict_init: %s[%d]: invalid value",			fn, line);		return -1;	}	sscanf(argv[2], "%i", &value);	if (dict_addvalue(argv[1], argv[0], value) < 0) {		librad_log("dict_init: %s[%d]: %s",			   fn, line, librad_errstr);		return -1;	}	return 0;}/* *	Process the VENDOR command */static int process_vendor(const char* fn, const int line, char **argv,			  int argc){	int	value;	const	char *format = NULL;	if ((argc < 2) || (argc > 3)) {		librad_log( "dict_init: %s[%d] invalid VENDOR entry",			    fn, line);		return -1;	}	/*	 *	 Validate all entries	 */	if (!isdigit((int) argv[1][0])) {		librad_log("dict_init: %s[%d]: invalid value",			fn, line);		return -1;	}	value = atoi(argv[1]);	/* Create a new VENDOR entry for the list */	if (dict_addvendor(argv[0], value) < 0) {		librad_log("dict_init: %s[%d]: %s",			   fn, line, librad_errstr);		return -1;	}	/*	 *	Look for a format statement	 */	if (argc == 3) {		format = argv[2];	} else if (value == VENDORPEC_USR) { /* catch dictionary screw-ups */		format = "format=4,0";	} else if (value == VENDORPEC_LUCENT) {		format = "format=2,1";	} else if (value == VENDORPEC_STARENT) {		format = "format=2,2";	} /* else no fixups to do */	if (format) {		int type, length;		const char *p;		DICT_VENDOR *dv;		if (strncasecmp(format, "format=", 7) != 0) {			librad_log("dict_init: %s[%d]: Invalid format for VENDOR.  Expected \"format=\", got \"%s\"",				   fn, line, format);			return -1;		}		p = format + 7;		if ((strlen(p) != 3) || 		    !isdigit((int) p[0]) ||		    (p[1] != ',') ||		    !isdigit((int) p[2])) {			librad_log("dict_init: %s[%d]: Invalid format for VENDOR.  Expected text like \"1,1\", got \"%s\"",				   fn, line, p);			return -1;		}		type = (int) (p[0] - '0');		length = (int) (p[2] - '0');		dv = dict_vendorbyvalue(value);		if (!dv) {			librad_log("dict_init: %s[%d]: Failed adding format for VENDOR",				   fn, line);			return -1;		}		if ((type != 1) && (type != 2) && (type != 4)) {			librad_log("dict_init: %s[%d]: invalid type value %d for VENDOR",				   fn, line, type);			return -1;		}		if ((length != 0) && (length != 1) && (length != 2)) {			librad_log("dict_init: %s[%d]: invalid length value %d for VENDOR",				   fn, line, length);			return -1;		}		dv->type = type;		dv->length = length;	}	return 0;}/* *	String split routine.  Splits an input string IN PLACE *	into pieces, based on spaces. */static int str2argv(char *str, char **argv, int max_argc){	int argc = 0;	while (*str) {		if (argc >= max_argc) return argc;		/*		 *	Chop out comments early.		 */		if (*str == '#') {			*str = '\0';			break;		}		while ((*str == ' ') ||		       (*str == '\t') ||		       (*str == '\r') ||		       (*str == '\n')) *(str++) = '\0';		if (!*str) return argc;		argv[argc] = str;		argc++;		while (*str &&		       (*str != ' ') &&		       (*str != '\t') &&		       (*str != '\r') &&		       (*str != '\n')) str++;	}	return argc;}#define MAX_ARGV (16)/* *	Initialize the dictionary. */static int my_dict_init(const char *dir, const char *fn,			const char *src_file, int src_line){	FILE	*fp;	char 	dirtmp[256];	char	buf[256];	char	*p;	int	line = 0;	int	vendor;	int	block_vendor;	struct stat statbuf;	char	*argv[MAX_ARGV];	int	argc;	if (!dir) {		librad_log("dict_init: No directory specified");		return -1;	}	if ((strlen(fn) >= sizeof(dirtmp) / 2) ||	    (strlen(dir) >= sizeof(dirtmp) / 2)) {		librad_log("dict_init: filename name too long");		return -1;	}	/*	 *	First see if fn is relative to dir. If so, create	 *	new filename. If not, remember the absolute dir.	 */	if ((p = strrchr(fn, '/')) != NULL) {		strcpy(dirtmp, fn);		dirtmp[p - fn] = 0;		dir = dirtmp;	} else if (dir[0] && strcmp(dir, ".") != 0) {		snprintf(dirtmp, sizeof(dirtmp), "%s/%s", dir, fn);		fn = dirtmp;	}	if ((fp = fopen(fn, "r")) == NULL) {		if (!src_file) {			librad_log("dict_init: Couldn't open dictionary \"%s\": %s",				   fn, strerror(errno));		} else {			librad_log("dict_init: %s[%d]: Couldn't open dictionary \"%s\": %s",				   src_file, src_line, fn, strerror(errno));		}		return -1;	}	stat(fn, &statbuf); /* fopen() guarantees this will succeed */	if (!S_ISREG(statbuf.st_mode)) {		fclose(fp);		librad_log("dict_init: Dictionary \"%s\" is not a regular file",			   fn);		return -1;	  	}	/*	 *	Globally writable dictionaries means that users can control	 *	the server configuration with little difficulty.	 */	if ((statbuf.st_mode & S_IWOTH) != 0) {		fclose(fp);		librad_log("dict_init: Dictionary \"%s\" is globally writable.  Refusing to start due to insecure configuration.",			   fn);		return -1;	}	dict_stat_add(fn, &statbuf);	/*	 *	Seed the random pool with data.	 */	lrad_rand_seed(&statbuf, sizeof(statbuf));	block_vendor = 0;	while (fgets(buf, sizeof(buf), fp) != NULL) {		line++;		if (buf[0] == '#' || buf[0] == 0 ||		    buf[0] == '\n' || buf[0] == '\r')			continue;		/*		 *  Comment characters should NOT be appearing anywhere but		 *  as start of a comment;		 */		p = strchr(buf, '#');		if (p) *p = '\0';		argc = str2argv(buf, argv, MAX_ARGV);		if (argc == 0) continue;		if (argc == 1) {			librad_log( "dict_init: %s[%d] invalid entry",				    fn, line);			fclose(fp);			return -1;		}		if (0) {			int i;			fprintf(stderr, "ARGC = %d\n",argc);			for (i = 0; i < argc; i++) {				fprintf(stderr, "\t%s\n", argv[i]);			}		}		/*		 *	See if we need to import another dictionary.		 */		if (strcasecmp(argv[0], "$INCLUDE") == 0) {			if (my_dict_init(dir, argv[1], fn, line) < 0) {				fclose(fp);				return -1;			}			continue;		} /* $INCLUDE */		/*		 *	Perhaps this is an attribute.		 */		if (strcasecmp(argv[0], "ATTRIBUTE") == 0) {			if (process_attribute(fn, line, block_vendor,					      argv + 1, argc - 1) == -1) {				fclose(fp);				return -1;			}			continue;		}		/*		 *	Process VALUE lines.		 */		if (strcasecmp(argv[0], "VALUE") == 0) {			if (process_value(fn, line,					  argv + 1, argc - 1) == -1) {				fclose(fp);				return -1;			}			continue;		}		/*		 *	Process VENDOR lines.		 */		if (strcasecmp(argv[0], "VENDOR") == 0) {			if (process_vendor(fn, line,					   argv + 1, argc - 1) == -1) {				fclose(fp);				return -1;			}			continue;		}		if (strcasecmp(argv[0], "BEGIN-VENDOR") == 0) {			if (argc != 2) {				librad_log(				"dict_init: %s[%d] invalid BEGIN-VENDOR entry",					fn, line);				fclose(fp);				return -1;			}			vendor = dict_vendorbyname(argv[1]);			if (!vendor) {				librad_log(					"dict_init: %s[%d]: unknown vendor %s",					fn, line, argv[1]);				fclose(fp);				return -1;			}			block_vendor = vendor;			continue;		} /* BEGIN-VENDOR */		if (strcasecmp(argv[0], "END-VENDOR") == 0) {			if (argc != 2) {				librad_log(				"dict_init: %s[%d] invalid END-VENDOR entry",					fn, line);				fclose(fp);				return -1;			}			vendor = dict_vendorbyname(argv[1]);			if (!vendor) {				librad_log(					"dict_init: %s[%d]: unknown vendor %s",					fn, line, argv[1]);				fclose(fp);				return -1;			}			if (vendor != block_vendor) {				librad_log(					"dict_init: %s[%d]: END-VENDOR %s does not match any previous BEGIN-VENDOR",					fn, line, argv[1]);				fclose(fp);				return -1;			}			block_vendor = 0;			continue;		} /* END-VENDOR */		/*		 *	Any other string: We don't recognize it.		 */		librad_log(			"dict_init: %s[%d] invalid keyword \"%s\"",			fn, line, argv[0]);		fclose(fp);		return -1;	}	fclose(fp);	return 0;}/* *	Empty callback for hash table initialization. */static int null_callback(void *ctx, void *data){	ctx = ctx;		/* -Wunused */	data = data;		/* -Wunused */	return 0;}/* *	Initialize the directory, then fix the attr member of *	all attributes. */int dict_init(const char *dir, const char *fn){	if (!dir) return -1;	/*	 *	Check if we need to change anything.  If not, don't do	 *	anything.	 */	if (dict_stat_check(dir, fn)) {		return 0;	}	/*	 *	Free the dictionaries, and the stat cache.	 */	dict_free();	stat_root_dir = strdup(dir);	stat_root_file = strdup(fn);	/*	 *	Create the table of vendor by name.   There MAY NOT	 *	be multiple vendors of the same name.	 *	 *	Each vendor is malloc'd, so the free function is free.	 */	vendors_byname = lrad_hash_table_create(dict_vendor_name_hash,						dict_vendor_name_cmp,						free);	if (!vendors_byname) {		return -1;	}	/*	 *	Create the table of vendors by value.  There MAY	 *	be vendors of the same value.  If there are, we	 *	pick the latest one.	 */	vendors_byvalue = lrad_hash_table_create(dict_vendor_value_hash,						 dict_vendor_value_cmp,						 NULL);	if (!vendors_byvalue) {		return -1;	}	/*	 *	Create the table of attributes by name.   There MAY NOT	 *	be multiple attributes of the same name.	 *	 *	Each attribute is malloc'd, so the free function is free.	 */	attributes_byname = lrad_hash_table_create(dict_attr_name_hash,						   dict_attr_name_cmp,						   free);	if (!attributes_byname) {		return -1;	}	/*	 *	Create the table of attributes by value.  There MAY	 *	be attributes of the same value.  If there are, we	 *	pick the latest one.	 */	attributes_byvalue = lrad_hash_table_create(dict_attr_value_hash,						    dict_attr_value_cmp,						    NULL);	if (!attributes_byvalue) {		return -1;	}	values_byname = lrad_hash_table_create(dict_value_name_hash,					       dict_value_name_cmp,					       free);	if (!values_byname) {		return -1;	}	values_byvalue = lrad_hash_table_create(dict_value_value_hash,						dict_value_value_cmp,						NULL);	if (!values_byvalue) {		return -1;	}	value_fixup = NULL;	/* just to be safe. */	if (my_dict_init(dir, fn, NULL, 0) < 0)		return -1;	if (value_fixup) {		DICT_ATTR *a;		value_fixup_t *this, *next;		for (this = value_fixup; this != NULL; this = next) {			next = this->next;			a = dict_attrbyname(this->attrstr);			if (!a) {				librad_log(					"dict_init: No ATTRIBUTE \"%s\" defined for VALUE \"%s\"",					this->attrstr, this->dval->name);				return -1; /* leak, but they should die... */			}			this->dval->attr = a->attr;			/*			 *	Add the value into the dictionary.			 */			if (!lrad_hash_table_replace(values_byname,						     this->dval)) {				librad_log("dict_addvalue: Duplicate value name %s for attribute %s", this->dval->name, a->name);				return -1;			}						/*			 *	Allow them to use the old name, but			 *	prefer the new name when printing			 *	values.			 */			if (!lrad_hash_table_finddata(values_byvalue, this->dval)) {				lrad_hash_table_replace(values_byvalue,							this->dval);			}			free(this);			/*			 *	Just so we don't lose track of things.			 */			value_fixup = next;		}	}	/*	 *	Walk over all of the hash tables to ensure they're	 *	initialized.  We do this because the threads may perform	 *	lookups, and we don't want multi-threaded re-ordering	 *	of the table entries.  That would be bad.	 */	lrad_hash_table_walk(vendors_byname, null_callback, NULL);	lrad_hash_table_walk(vendors_byvalue, null_callback, NULL);	lrad_hash_table_walk(attributes_byname, null_callback, NULL);	lrad_hash_table_walk(attributes_byvalue, null_callback, NULL);		lrad_hash_table_walk(values_byvalue, null_callback, NULL);	lrad_hash_table_walk(values_byname, null_callback, NULL);	return 0;}/* *	Get an attribute by its numerical value. */DICT_ATTR *dict_attrbyvalue(int attr){	DICT_ATTR dattr;	dattr.attr = attr;	return lrad_hash_table_finddata(attributes_byvalue, &dattr);}/* *	Get an attribute by its name. */DICT_ATTR *dict_attrbyname(const char *name){	DICT_ATTR dattr;	if (!name) return NULL;	strNcpy(dattr.name, name, sizeof(dattr.name));	return lrad_hash_table_finddata(attributes_byname, &dattr);}/* *	Associate a value with an attribute and return it. */DICT_VALUE *dict_valbyattr(int attr, int value){	DICT_VALUE dval;	dval.attr = attr;	dval.value = value;		return lrad_hash_table_finddata(values_byvalue, &dval);}/* *	Get a value by its name, keyed off of an attribute. */DICT_VALUE *dict_valbyname(int attr, const char *name){	DICT_VALUE *dv;	uint32_t buffer[(sizeof(*dv) + DICT_VALUE_MAX_NAME_LEN + 3)/4];	if (!name) return NULL;	dv = (DICT_VALUE *) buffer;	dv->attr = attr;	strNcpy(dv->name, name, DICT_VALUE_MAX_NAME_LEN);	return lrad_hash_table_finddata(values_byname, dv);}/* *	Get the vendor PEC based on the vendor name * *	This is efficient only for small numbers of vendors. */int dict_vendorbyname(const char *name){	DICT_VENDOR *dv;	uint32_t buffer[(sizeof(*dv) + DICT_VENDOR_MAX_NAME_LEN + 3)/4];	if (!name) return 0;	dv = (DICT_VENDOR *) buffer;	strNcpy(dv->name, name, DICT_VENDOR_MAX_NAME_LEN);		dv = lrad_hash_table_finddata(vendors_byname, dv);	if (!dv) return 0;	return dv->vendorpec;}/* *	Return the vendor struct based on the PEC. */DICT_VENDOR *dict_vendorbyvalue(int vendorpec){	DICT_VENDOR dv;	dv.vendorpec = vendorpec;	return lrad_hash_table_finddata(vendors_byvalue, &dv);}

⌨️ 快捷键说明

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