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

📄 valuepair.c

📁 linux 下的radius 最新版。linux 下的radius 最新版.linux 下的radius 最新版
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * valuepair.c	Functions to handle VALUE_PAIRs * * Version:	$Id: valuepair.c,v 1.82.2.1.2.5 2007/01/30 12:58:23 aland Exp $ * *   This library is free software; you can redistribute it and/or *   modify it under the terms of the GNU Lesser General Public *   License as published by the Free Software Foundation; either *   version 2.1 of the License, or (at your option) any later version. * *   This library is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *   Lesser General Public License for more details. * *   You should have received a copy of the GNU Lesser General Public *   License along with this library; if not, write to the Free Software *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2000  The FreeRADIUS server project */static const char rcsid[] = "$Id: valuepair.c,v 1.82.2.1.2.5 2007/01/30 12:58:23 aland Exp $";#include	"autoconf.h"#include	<sys/types.h>#include	<stdio.h>#include	<stdlib.h>#include	<string.h>#include	<ctype.h>#include	"libradius.h"#ifdef HAVE_MALLOC_H#  include	<malloc.h>#endif#ifdef HAVE_REGEX_H#  include	<regex.h>#endif#include	"missing.h"static const char *months[] = {        "jan", "feb", "mar", "apr", "may", "jun",        "jul", "aug", "sep", "oct", "nov", "dec" };/* *	Create a new valuepair. */VALUE_PAIR *paircreate(int attr, int type){	VALUE_PAIR	*vp;	DICT_ATTR	*da;	if ((vp = malloc(sizeof(VALUE_PAIR))) == NULL) {		librad_log("out of memory");		return NULL;	}	memset(vp, 0, sizeof(VALUE_PAIR));	vp->attribute = attr;	vp->operator = T_OP_EQ;	vp->type = type;	/*	 *	Dictionary type over-rides what the caller says.	 */	if ((da = dict_attrbyvalue(attr)) != NULL) {		strcpy(vp->name, da->name);		vp->type = da->type;		vp->flags = da->flags;	} else if (VENDOR(attr) == 0) {		sprintf(vp->name, "Attr-%u", attr);	} else {		DICT_VENDOR *v;		v = dict_vendorbyvalue(VENDOR(attr));		if (v) {			sprintf(vp->name, "%s-Attr-%u",				v->name, attr & 0xffff);		} else {			sprintf(vp->name, "Vendor-%u-Attr-%u",				VENDOR(attr), attr & 0xffff);		}	}	switch (vp->type) {		case PW_TYPE_INTEGER:		case PW_TYPE_IPADDR:		case PW_TYPE_DATE:			vp->length = 4;			break;		default:			vp->length = 0;			break;	}	return vp;}/* *      release the memory used by a single attribute-value pair *      just a wrapper around free() for now. */void pairbasicfree(VALUE_PAIR *pair){	/* clear the memory here */	memset(pair, 0, sizeof(*pair));	free(pair);}/* *	Release the memory used by a list of attribute-value *	pairs, and sets the pair pointer to NULL. */void pairfree(VALUE_PAIR **pair_ptr){	VALUE_PAIR	*next, *pair;	if (!pair_ptr) return;	pair = *pair_ptr;	while (pair != NULL) {		next = pair->next;		pairbasicfree(pair);		pair = next;	}	*pair_ptr = NULL;}/* *	Find the pair with the matching attribute */VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr){	while(first && first->attribute != attr)		first = first->next;	return first;}/* *	Delete the pair(s) with the matching attribute */void pairdelete(VALUE_PAIR **first, int attr){	VALUE_PAIR *i, *next;	VALUE_PAIR **last = first;	for(i = *first; i; i = next) {		next = i->next;		if (i->attribute == attr) {			*last = next;			pairbasicfree(i);		} else {			last = &i->next;		}	}}/* *	Add a pair at the end of a VALUE_PAIR list. */void pairadd(VALUE_PAIR **first, VALUE_PAIR *add){	VALUE_PAIR *i;	if (*first == NULL) {		*first = add;		return;	}	for(i = *first; i->next; i = i->next)		;	i->next = add;}/* *	Add or replace a pair at the end of a VALUE_PAIR list. */void pairreplace(VALUE_PAIR **first, VALUE_PAIR *replace){	VALUE_PAIR *i, *next;	VALUE_PAIR **prev = first;	if (*first == NULL) {		*first = replace;		return;	}	/*	 *	Not an empty list, so find item if it is there, and	 *	replace it. Note, we always replace the first one, and	 *	we ignore any others that might exist.	 */	for(i = *first; i; i = next) {		next = i->next;		/*		 *	Found the first attribute, replace it,		 *	and return.		 */		if (i->attribute == replace->attribute) {			*prev = replace;			/*			 *	Should really assert that replace->next == NULL			 */			replace->next = next;			pairbasicfree(i);			return;		}		/*		 *	Point to where the attribute should go.		 */		prev = &i->next;	}	/*	 *	If we got here, we didn't find anything to replace, so	 *	stopped at the last item, which we just append to.	 */	*prev = replace;}/* *	Copy just a certain type of pairs. */VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr){	VALUE_PAIR	*first, *n, **last;	first = NULL;	last = &first;	while (vp) {		if (attr >= 0 && vp->attribute != attr) {			vp = vp->next;			continue;		}		if ((n = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) == NULL) {			librad_log("out of memory");			return first;		}		memcpy(n, vp, sizeof(VALUE_PAIR));		n->next = NULL;		*last = n;		last = &n->next;		vp = vp->next;	}	return first;}/* *	Copy a pairlist. */VALUE_PAIR *paircopy(VALUE_PAIR *vp){	return paircopy2(vp, -1);}/* *	Move attributes from one list to the other *	if not already present. */void pairmove(VALUE_PAIR **to, VALUE_PAIR **from){	VALUE_PAIR **tailto, *i, *j, *next;	VALUE_PAIR *tailfrom = NULL;	VALUE_PAIR *found;	int has_password = 0;	if (*to == NULL) {		*to = *from;		*from = NULL;		return;	}	/*	 *	First, see if there are any passwords here, and	 *	point "tailto" to the end of the "to" list.	 */	tailto = to;	for(i = *to; i; i = i->next) {		if (i->attribute == PW_PASSWORD ||		    i->attribute == PW_CRYPT_PASSWORD)			has_password = 1;		tailto = &i->next;	}	/*	 *	Loop over the "from" list.	 */	for(i = *from; i; i = next) {		next = i->next;		/*		 *	If there was a password in the "to" list,		 *	do not move any other password from the		 *	"from" to the "to" list.		 */		if (has_password &&		    (i->attribute == PW_PASSWORD ||		     i->attribute == PW_CRYPT_PASSWORD)) {			tailfrom = i;			continue;		}		/*		 *	If the attribute is already present in "to",		 *	do not move it from "from" to "to". We make		 *	an exception for "Hint" which can appear multiple		 *	times, and we never move "Fall-Through".		 */		if (i->attribute == PW_FALL_THROUGH ||		    (i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) {			found = pairfind(*to, i->attribute);			switch (i->operator) {			  /*			   *  If a similar attribute is found,			   *  delete it.			   */			case T_OP_SUB:		/* -= */				if (found) {					if (!i->strvalue[0] ||					    (strcmp((char *)found->strvalue,						    (char *)i->strvalue) == 0)){						pairdelete(to, found->attribute);						/*						 *	'tailto' may have been						 *	deleted...						 */						tailto = to;						for(j = *to; j; j = j->next) {							tailto = &j->next;						}					}				}				tailfrom = i;				continue;				break;/* really HAVE_REGEX_H */#if 0				/*				 *  Attr-Name =~ "s/find/replace/"				 *				 *  Very bad code.  Barely working,				 *  if at all.				 */			case T_OP_REG_EQ:			  if (found &&			      (i->strvalue[0] == 's')) {			    regex_t		reg;			    regmatch_t		match[1];			    char *str;			    char *p, *q;			    p = i->strvalue + 1;			    q = strchr(p + 1, *p);			    if (!q || (q[strlen(q) - 1] != *p)) {			      tailfrom = i;			      continue;			    }			    str = strdup(i->strvalue + 2);			    q = strchr(str, *p);			    *(q++) = '\0';			    q[strlen(q) - 1] = '\0';			    regcomp(&reg, str, 0);			    if (regexec(&reg, found->strvalue,					1, match, 0) == 0) {			      fprintf(stderr, "\"%s\" will have %d to %d replaced with %s\n",				      found->strvalue, match[0].rm_so,				      match[0].rm_eo, q);			    }			    regfree(&reg);			    free(str);			  }			  tailfrom = i;	/* don't copy it over */			  continue;			  break;#endif			case T_OP_EQ:		/* = */				/*				 *  FIXME: Tunnel attributes with				 *  different tags are different				 *  attributes.				 */				if (found) {					tailfrom = i;					continue; /* with the loop */				}				break;			  /*			   *  If a similar attribute is found,			   *  replace it with the new one.  Otherwise,			   *  add the new one to the list.			   */			case T_OP_SET:		/* := */				if (found) {					pairdelete(to, found->attribute);					/*					 *	'tailto' may have been					 *	deleted...					 */					tailto = to;					for(j = *to; j; j = j->next) {						tailto = &j->next;					}				}				break;			  /*			   *  Add the new element to the list, even			   *  if similar ones already exist.			   */			default:			case T_OP_ADD: /* += */				break;			}		}		if (tailfrom)			tailfrom->next = next;		else			*from = next;		/*		 *	If ALL of the 'to' attributes have been deleted,		 *	then ensure that the 'tail' is updated to point		 *	to the head.		 */		if (!*to) {			tailto = to;		}		*tailto = i;		if (i) {			i->next = NULL;			tailto = &i->next;		}	}}/* *	Move one kind of attributes from one list to the other */void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr){	VALUE_PAIR *to_tail, *i, *next;	VALUE_PAIR *iprev = NULL;	/*	 *	Find the last pair in the "to" list and put it in "to_tail".	 */	if (*to != NULL) {		to_tail = *to;		for(i = *to; i; i = i->next)			to_tail = i;	} else		to_tail = NULL;	for(i = *from; i; i = next) {		next = i->next;		/*		 *	If the attribute to move is NOT a VSA, then it		 *	ignores any attributes which do not match exactly.		 */		if ((attr != PW_VENDOR_SPECIFIC) &&		    (i->attribute != attr)) {			iprev = i;			continue;		}		/*		 *	If the attribute to move IS a VSA, then it ignores		 *	any non-VSA attribute.		 */		if ((attr == PW_VENDOR_SPECIFIC) &&		    (VENDOR(i->attribute) == 0)) {			iprev = i;			continue;		}		/*		 *	Remove the attribute from the "from" list.		 */		if (iprev)			iprev->next = next;		else			*from = next;		/*		 *	Add the attribute to the "to" list.		 */		if (to_tail)			to_tail->next = i;		else			*to = i;		to_tail = i;		i->next = NULL;	}}/* *	Sort of strtok/strsep function. */static char *mystrtok(char **ptr, const char *sep){	char	*res;	if (**ptr == 0)		return NULL;	while (**ptr && strchr(sep, **ptr))		(*ptr)++;	if (**ptr == 0)		return NULL;	res = *ptr;	while (**ptr && strchr(sep, **ptr) == NULL)		(*ptr)++;	if (**ptr != 0)		*(*ptr)++ = 0;	return res;}/* *	Turn printable string into time_t *	Returns -1 on error, 0 on OK. */static int gettime(const char *valstr, time_t *lvalue){	int		i;	time_t		t;	struct tm	*tm, s_tm;	char		buf[64];	char		*p;	char		*f[4];	char            *tail = '\0';	/*	 * Test for unix timestamp date	 */	*lvalue = strtoul(valstr, &tail, 10);	if (*tail == '\0') {		return 0;	}	tm = &s_tm;	memset(tm, 0, sizeof(*tm));	tm->tm_isdst = -1;	/* don't know, and don't care about DST */	strNcpy(buf, valstr, sizeof(buf));	p = buf;	f[0] = mystrtok(&p, " \t");	f[1] = mystrtok(&p, " \t");	f[2] = mystrtok(&p, " \t");	f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */	if (!f[0] || !f[1] || !f[2]) return -1;	/*	 *  The month is text, which allows us to find it easily.	 */	tm->tm_mon = 12;	for (i = 0; i < 3; i++) {		if (isalpha( (int) *f[i])) {			/*			 *  Bubble the month to the front of the list			 */			p = f[0];			f[0] = f[i];			f[i] = p;			for (i = 0; i < 12; i++) {				if (strncasecmp(months[i], f[0], 3) == 0) {					tm->tm_mon = i;					break;				}			}		}	}	/* month not found? */	if (tm->tm_mon == 12) return -1;	/*	 *  The year may be in f[1], or in f[2]	 */	tm->tm_year = atoi(f[1]);	tm->tm_mday = atoi(f[2]);	if (tm->tm_year >= 1900) {		tm->tm_year -= 1900;	} else {		/*		 *  We can't use 2-digit years any more, they make it		 *  impossible to tell what's the day, and what's the year.		 */		if (tm->tm_mday < 1900) return -1;		/*		 *  Swap the year and the day.		 */		i = tm->tm_year;		tm->tm_year = tm->tm_mday - 1900;		tm->tm_mday = i;	}	/*	 *  If the day is out of range, die.	 */	if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {		return -1;	}	/*	 *	There may be %H:%M:%S.  Parse it in a hacky way.	 */	if (f[3]) {		f[0] = f[3];	/* HH */		f[1] = strchr(f[0], ':'); /* find : separator */		if (!f[1]) return -1;		*(f[1]++) = '\0'; /* nuke it, and point to MM:SS */		f[2] = strchr(f[1], ':'); /* find : separator */		if (!f[2]) return -1;		*(f[2]++) = '\0';	/* nuke it, and point to SS */		tm->tm_hour = atoi(f[0]);		tm->tm_min = atoi(f[1]);		tm->tm_sec = atoi(f[2]);	}	/*	 *  Returns -1 on error.	 */	t = mktime(tm);	if (t == (time_t) -1) return -1;	*lvalue = t;	return 0;}/* *  Parse a string value into a given VALUE_PAIR */VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value){	char		*p, *s=0;	const char	*cp, *cs;	DICT_VALUE	*dval;	/*	 *	Even for integers, dates and ip addresses we	 *	keep the original string in vp->strvalue.	 */	strNcpy((char *)vp->strvalue, value, sizeof(vp->strvalue));	vp->length = strlen(vp->strvalue);	switch(vp->type) {		case PW_TYPE_STRING:			/*			 *	Already handled above.			 */			break;		case PW_TYPE_IPADDR:			/*			 *	FIXME: complain if hostname			 *	cannot be resolved, or resolve later!

⌨️ 快捷键说明

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