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

📄 dict.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!fr_hash_table_insert(attributes_byname, attr)) {		DICT_ATTR	*a;		/*		 *	If the attribute has identical number, then		 *	ignore the duplicate.		 */		a = fr_hash_table_finddata(attributes_byname, attr);		if (a && (strcasecmp(a->name, attr->name) == 0)) {			if (a->attr != attr->attr) {				librad_log("dict_addattr: Duplicate attribute name %s", name);				fr_pool_free(attr);				return -1;			}			/*			 *	Same name, same vendor, same attr,			 *	maybe the flags and/or type is			 *	different.  Let the new value			 *	over-ride the old one.			 */		}		fr_hash_table_delete(attributes_byvalue, a);		if (!fr_hash_table_replace(attributes_byname, attr)) {			librad_log("dict_addattr: Internal error storing attribute %s", name);			fr_pool_free(attr);			return -1;		}	}	/*	 *	Insert the SAME pointer (not free'd when this entry is	 *	deleted), into another table.	 *	 *	We want this behaviour because we want OLD names for	 *	the attributes to be read from the configuration	 *	files, but when we're printing them, (and looking up	 *	by value) we want to use the NEW name.	 */	if (!fr_hash_table_replace(attributes_byvalue, attr)) {		librad_log("dict_addattr: Failed inserting attribute name %s", name);		return -1;	}	if (!vendor && (value > 0) && (value < 256)) {	 	 dict_base_attrs[value] = attr;	}	return 0;}/* *	Add a value for an attribute to the dictionary. */int dict_addvalue(const char *namestr, const char *attrstr, int value){	size_t		length;	DICT_ATTR	*dattr;	DICT_VALUE	*dval;	static DICT_ATTR *last_attr = NULL;	if (!*namestr) {		librad_log("dict_addvalue: empty names are not permitted");		return -1;	}	if ((length = strlen(namestr)) >= DICT_VALUE_MAX_NAME_LEN) {		librad_log("dict_addvalue: value name too long");		return -1;	}	if ((dval = fr_pool_alloc(sizeof(*dval) + length)) == NULL) {		librad_log("dict_addvalue: out of memory");		return -1;	}	memset(dval, 0, sizeof(*dval));	strcpy(dval->name, namestr);	dval->value = value;	/*	 *	Most VALUEs are bunched together by ATTRIBUTE.  We can	 *	save a lot of lookups on dictionary initialization by	 *	caching the last attribute.	 */	if (last_attr && (strcasecmp(attrstr, last_attr->name) == 0)) {		dattr = last_attr;	} else {		dattr = dict_attrbyname(attrstr);		last_attr = dattr;	}	/*	 *	Remember which attribute is associated with this	 *	value, if possible.	 */	if (dattr) {		if (dattr->flags.has_value_alias) {			librad_log("dict_addvalue: Cannot add VALUE for ATTRIBUTE \"%s\": It already has a VALUE-ALIAS", attrstr);			return -1;		}		dval->attr = dattr->attr;		/*		 *	Enforce valid values		 *		 *	Don't worry about fixups...		 */		switch (dattr->type) {			case PW_TYPE_BYTE:				if (value > 255) {					fr_pool_free(dval);					librad_log("dict_addvalue: ATTRIBUTEs of type 'byte' cannot have VALUEs larger than 255");					return -1;				}				break;			case PW_TYPE_SHORT:				if (value > 65535) {					fr_pool_free(dval);					librad_log("dict_addvalue: ATTRIBUTEs of type 'short' cannot have VALUEs larger than 65535");					return -1;				}				break;				/*				 *	Allow octets for now, because				 *	of dictionary.cablelabs				 */			case PW_TYPE_OCTETS:			case PW_TYPE_INTEGER:				break;			default:				fr_pool_free(dval);				librad_log("dict_addvalue: VALUEs cannot be defined for attributes of type '%s'",					   fr_int2str(type_table, dattr->type, "?Unknown?"));				return -1;		}		dattr->flags.has_value = 1;	} else {		value_fixup_t *fixup;		fixup = (value_fixup_t *) malloc(sizeof(*fixup));		if (!fixup) {			fr_pool_free(dval);			librad_log("dict_addvalue: out of memory");			return -1;		}		memset(fixup, 0, sizeof(*fixup));		strlcpy(fixup->attrstr, attrstr, sizeof(fixup->attrstr));		fixup->dval = dval;		/*		 *	Insert to the head of the list.		 */		fixup->next = value_fixup;		value_fixup = fixup;		return 0;	}	/*	 *	Add the value into the dictionary.	 */	if (!fr_hash_table_insert(values_byname, dval)) {		if (dattr) {			DICT_VALUE *old;			/*			 *	Suppress duplicates with the same			 *	name and value.  There are lots in			 *	dictionary.ascend.			 */			old = dict_valbyname(dattr->attr, namestr);			if (old && (old->value == dval->value)) {				fr_pool_free(dval);				return 0;			}		}		fr_pool_free(dval);		librad_log("dict_addvalue: Duplicate value name %s for attribute %s", namestr, attrstr);		return -1;	}	/*	 *	There are multiple VALUE's, keyed by attribute, so we	 *	take care of that here.	 */	if (!fr_hash_table_replace(values_byvalue, dval)) {		librad_log("dict_addvalue: Failed inserting value %s",			   namestr);		return -1;	}	return 0;}static int sscanf_i(const char *str, int *pvalue){	int rcode = 0;	int base = 10;	const char *tab = "0123456789";	if ((str[0] == '0') &&	    ((str[1] == 'x') || (str[1] == 'X'))) {		tab = "0123456789abcdef";		base = 16;		str += 2;	}	while (*str) {		const char *c;		c = memchr(tab, tolower((int) *str), base);		if (!c) return 0;		rcode *= base;		rcode += (c - tab);		str++;	}	*pvalue = rcode;	return 1;}/* *	Process the ATTRIBUTE command */static int process_attribute(const char* fn, const int line,			     const int block_vendor, char **argv,			     int argc){	int		vendor = 0;	int		value;	int		type;	ATTR_FLAGS	flags;	if ((argc < 3) || (argc > 4)) {		librad_log("dict_init: %s[%d]: invalid ATTRIBUTE line",			fn, line);		return -1;	}	/*	 *	Validate all entries	 */	if (!sscanf_i(argv[1], &value)) {		librad_log("dict_init: %s[%d]: invalid value", fn, line);		return -1;	}	/*	 *	find the type of the attribute.	 */	type = fr_str2int(type_table, argv[2], -1);	if (type < 0) {		librad_log("dict_init: %s[%d]: invalid type \"%s\"",			fn, line, argv[2]);		return -1;	}	/*	 *	Only look up the vendor if the string	 *	is non-empty.	 */	memset(&flags, 0, sizeof(flags));	if (argc == 4) {		char *key, *next, *last;		key = argv[3];		do {			next = strchr(key, ',');			if (next) *(next++) = '\0';			if (strcmp(key, "has_tag") == 0 ||			    strcmp(key, "has_tag=1") == 0) {				/* Boolean flag, means this is a				   tagged attribute */				flags.has_tag = 1;							} else if (strncmp(key, "encrypt=", 8) == 0) {				/* Encryption method, defaults to 0 (none).				   Currently valid is just type 2,				   Tunnel-Password style, which can only				   be applied to strings. */				flags.encrypt = strtol(key + 8, &last, 0);				if (*last) {					librad_log( "dict_init: %s[%d] invalid option %s",						    fn, line, key);					return -1;				}							} else if (strncmp(key, "array", 8) == 0) {				flags.array = 1;								switch (type) {					case PW_TYPE_IPADDR:					case PW_TYPE_BYTE:					case PW_TYPE_SHORT:					case PW_TYPE_INTEGER:					case PW_TYPE_DATE:						break;					default:						librad_log( "dict_init: %s[%d] Only IP addresses can have the \"array\" flag set.",							    fn, line);						return -1;				}							} else if (block_vendor) {				librad_log( "dict_init: %s[%d]: unknown option \"%s\"",					    fn, line, key);				return -1;			} else {				/* Must be a vendor 'flag'... */				if (strncmp(key, "vendor=", 7) == 0) {					/* New format */					key += 7;				}				vendor = dict_vendorbyname(key);				if (!vendor) {					librad_log( "dict_init: %s[%d]: unknown vendor \"%s\"",						    fn, line, key);					return -1;				}				if (block_vendor && argv[3][0] &&				    (block_vendor != vendor)) {					librad_log("dict_init: %s[%d]: mismatched vendor %s within BEGIN-VENDOR/END-VENDOR block",						   fn, line, argv[3]);					return -1;				}			}			key = next;			if (key && !*key) break;		} while (key);	}	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,				   fr_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 (!sscanf_i(argv[2], &value)) {		librad_log("dict_init: %s[%d]: invalid value",			fn, line);		return -1;	}	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 VALUE-ALIAS command * *	This allows VALUE mappings to be shared among multiple *	attributes. */static int process_value_alias(const char* fn, const int line, char **argv,			       int argc){	DICT_ATTR *my_da, *da;	DICT_VALUE *dval;	if (argc != 2) {		librad_log("dict_init: %s[%d]: invalid VALUE-ALIAS line",			fn, line);		return -1;	}	my_da = dict_attrbyname(argv[0]);	if (!my_da) {		librad_log("dict_init: %s[%d]: ATTRIBUTE \"%s\" does not exist",			   fn, line, argv[1]);		return -1;	}	if (my_da->flags.has_value) {		librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" with pre-existing VALUE",			   fn, line, argv[0]);		return -1;	}	if (my_da->flags.has_value_alias) {		librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" with pre-existing VALUE-ALIAS",			   fn, line, argv[0]);		return -1;	}	da = dict_attrbyname(argv[1]);	if (!da) {		librad_log("dict_init: %s[%d]: Cannot find ATTRIBUTE \"%s\" for alias",			   fn, line, argv[1]);		return -1;	}	if (!da->flags.has_value) {		librad_log("dict_init: %s[%d]: VALUE-ALIAS cannot refer to ATTRIBUTE %s: It has no values",			   fn, line, argv[1]);		return -1;	}	if (da->flags.has_value_alias) {		librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" which itself has a VALUE-ALIAS",			   fn, line, argv[1]);		return -1;	}	if (my_da->type != da->type) {		librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS between attributes of differing type",			   fn, line);		return -1;	}	if ((dval = fr_pool_alloc(sizeof(*dval))) == NULL) {		librad_log("dict_addvalue: out of memory");		return -1;	}	memset(dval, 0, sizeof(*dval));	dval->name[0] = '\0';	/* empty name */	dval->attr = my_da->attr;	dval->value = da->attr;	if (!fr_hash_table_insert(values_byname, dval)) {		librad_log("dict_init: %s[%d]: Error create alias",			   fn, line);		fr_pool_free(dval);		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] != ',') ||

⌨️ 快捷键说明

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