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

📄 xlat.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	int spaces = FALSE;	p = *from;	q = *to;	pa = &xlat_name[0];	*q = '\0';	/*	 * Skip the '{' at the front of 'p'	 * Increment open braces	 */	p++;	openbraces++;	if (*p == '#') {		p++;		do_length = 1;	}	/*	 *	Handle %{%{foo}:-%{bar}}, which is useful, too.	 *	 *	Did I mention that this parser is garbage?	 */	if ((p[0] == '%') && (p[1] == '{')) {		/*		 *	This is really bad, but it works.		 */		int len1, len2;		size_t mylen = strlen(p);		char *first = rad_malloc(mylen);		char *second = rad_malloc(mylen);		int expand2 = FALSE;		len1 = rad_copy_variable(first, p);		if (len1 < 0) {			DEBUG2("Badly formatted variable: %s", p);			goto free_and_done;		}		if ((p[len1] != ':') || (p[len1 + 1] != '-')) {			DEBUG2("No trailing :- after variable at %s", p);			goto free_and_done;		}		p += len1 + 2;		if ((p[0] == '%') && (p[1] == '{')) {			len2 = rad_copy_variable(second, p);			expand2 = TRUE;			if (len2 < 0) {				DEBUG2("Invalid text after :- at %s", p);				goto free_and_done;			}			p += len2;		} else if ((p[0] == '"') || p[0] == '\'') {			getstring(&p, second, mylen);		} else {			char *s = second;			while (*p && (*p != '}')) {				*(s++) = *(p++);			}			*s = '\0';		}		if (*p != '}') {			DEBUG2("Failed to find trailing '}' in string");			goto free_and_done;		}		mylen = radius_xlat(q, freespace, first, request, func);		if (mylen) {			q += mylen;			goto free_and_done;		}		if (!expand2) {			strlcpy(q, second, freespace);			q += strlen(q);		} else {			mylen = radius_xlat(q, freespace, second,					    request, func);			if (mylen) {				q += mylen;				goto free_and_done;			}		}		/*		 *	Else the output is an empty string.		 */	free_and_done:		free(first);		free(second);		goto done;	}	/*	 *	First, copy the xlat key name to one buffer	 */	while (*p && (*p != '}') && (*p != ':')) {		*pa++ = *p++;		if (pa >= (xlat_name + sizeof(xlat_name) - 1)) {			/*			 *	Skip to the end of the input			 */			p += strlen(p);			DEBUG("xlat: Module name is too long in string %%%s",			      *from);			goto done;		}	}	*pa = '\0';	if (!*p) {		DEBUG("xlat: Invalid syntax in %s", *from);		/*		 *	%{name} is a simple attribute reference,		 *	or regex reference.		 */	} else if (*p == '}') {		openbraces--;		rad_assert(openbraces == *open_p);		p++;		xlat_string = xlat_name;		goto do_xlat;	} else if ((p[0] == ':') && (p[1] == '-')) { /* handle ':- */		DEBUG2("WARNING: Deprecated conditional expansion \":-\".  See \"man unlang\" for details");		p += 2;		xlat_string = xlat_name;		goto do_xlat;	} else {      /* module name, followed by per-module string */		int stop = 0;		int delimitbrace = *open_p;		rad_assert(*p == ':');		p++;			/* skip the ':' */		/*		 *  If there's a brace immediately following the colon,		 *  then we've chosen to delimite the per-module string,		 *  so keep track of that.		 */		if (*p == '{') {			delimitbrace = openbraces;			openbraces++;			p++;		}		xlat_string = rad_malloc(strlen(p) + 1); /* always returns */		free_xlat_string = TRUE;		pa = xlat_string;		/*		 *  Copy over the rest of the string, which is per-module		 *  data.		 */		while (*p && !stop) {			switch(*p) {				/*				 *	What the heck is this supposed				 *	to be doing?				 */			case '\\':				p++; /* skip it */				*pa++ = *p++;				break;			case ':':				if (!spaces && p[1] == '-') {					p += 2;					stop = 1;					break;				}				*pa++ = *p++;				break;				/*				 *	This is pretty hokey...  we				 *	should use the functions in				 *	util.c				 */			case '{':				openbraces++;				*pa++ = *p++;				break;			case '}':				openbraces--;				if (openbraces == delimitbrace) {					p++;					stop=1;				} else {					*pa++ = *p++;				}				break;			case ' ':			case '\t':				spaces = TRUE;				/* FALL-THROUGH */			default:				*pa++ = *p++;				break;			}		}		*pa = '\0';		/*		 *	Now check to see if we're at the end of the string		 *	we were sent.  If we're not, check for :-		 */		if (openbraces == delimitbrace) {			if (p[0] == ':' && p[1] == '-') {				p += 2;			}		}		/*		 *	Look up almost everything in the new tree of xlat		 *	functions.  This makes it a little quicker...		 */	do_xlat:		if ((c = xlat_find(xlat_name)) != NULL) {			if (!c->internal) DEBUG3("radius_xlat: Running registered xlat function of module %s for string \'%s\'",						c->module, xlat_string);			retlen = c->do_xlat(c->instance, request, xlat_string,					    q, freespace, func);			/* If retlen is 0, treat it as not found */			if (retlen > 0) found = 1;#ifndef NDEBUG		} else {			/*			 *	No attribute by that name, return an error.			 */			DEBUG2("WARNING: Unknown module \"%s\" in string expansion \"%%%s\"", xlat_name, *from);#endif		}	}	/*	 * Skip to last '}' if attr is found	 * The rest of the stuff within the braces is	 * useless if we found what we need	 */	if (found) {		if (do_length) {			snprintf(q, freespace, "%d", retlen);			retlen = strlen(q);		}		q += retlen;		while((*p != '\0') && (openbraces > *open_p)) {			/*			 *	Handle escapes outside of the loop.			 */			if (*p == '\\') {				p++;				if (!*p) break;				p++; /* get & ignore next character */				continue;			}			switch (*p) {			default:				break;				/*				 *  Bare brace				 */			case '{':				openbraces++;				break;			case '}':				openbraces--;				break;			}			p++;	/* skip the character */		}	}	done:	if (free_xlat_string) free(xlat_string);	*open_p = openbraces;	*from = p;	*to = q;}/* *  If the caller doesn't pass xlat an escape function, then *  we use this one.  It simplifies the coding, as the check for *  func == NULL only happens once. */static size_t xlat_copy(char *out, size_t outlen, const char *in){	int freespace = outlen;	rad_assert(outlen > 0);	while ((*in) && (freespace > 1)) {		/*		 *  Copy data.		 *		 *  FIXME: Do escaping of bad stuff!		 */		*(out++) = *(in++);		freespace--;	}	*out = '\0';	return (outlen - freespace); /* count does not include NUL */}/* *	Replace %<whatever> in a string. * *	See 'doc/variables.txt' for more information. */int radius_xlat(char *out, int outlen, const char *fmt,		REQUEST *request, RADIUS_ESCAPE_STRING func){	int c, len, freespace;	const char *p;	char *q;	char *nl;	VALUE_PAIR *tmp;	struct tm *TM, s_TM;	char tmpdt[40]; /* For temporary storing of dates */	int openbraces=0;	/*	 *	Catch bad modules.	 */	if (!fmt || !out || !request) return 0;	/*	 *  Ensure that we always have an escaping function.	 */	if (func == NULL) {		func = xlat_copy;	}       	q = out;	p = fmt;	while (*p) {		/* Calculate freespace in output */		freespace = outlen - (q - out);		if (freespace <= 1)			break;		c = *p;		if ((c != '%') && (c != '$') && (c != '\\')) {			/*			 * We check if we're inside an open brace.  If we are			 * then we assume this brace is NOT literal, but is			 * a closing brace and apply it			 */			if ((c == '}') && openbraces) {				openbraces--;				p++; /* skip it */				continue;			}			*q++ = *p++;			continue;		}		/*		 *	There's nothing after this character, copy		 *	the last '%' or "$' or '\\' over to the output		 *	buffer, and exit.		 */		if (*++p == '\0') {			*q++ = c;			break;		}		if (c == '\\') {			switch(*p) {			case '\\':				*q++ = *p;				break;			case 't':				*q++ = '\t';				break;			case 'n':				*q++ = '\n';				break;			default:				*q++ = c;				*q++ = *p;				break;			}			p++;		} else if (c == '%') switch(*p) {			case '{':				decode_attribute(&p, &q, freespace, &openbraces, request, func);				break;			case '%':				*q++ = *p++;				break;			case 'a': /* Protocol: */				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_PROTOCOL),PW_TYPE_INTEGER, func);				p++;				break;			case 'c': /* Callback-Number */				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_CALLBACK_NUMBER),PW_TYPE_STRING, func);				p++;				break;			case 'd': /* request day */				TM = localtime_r(&request->timestamp, &s_TM);				len = strftime(tmpdt, sizeof(tmpdt), "%d", TM);				if (len > 0) {					strlcpy(q, tmpdt, freespace);					q += strlen(q);				}				p++;				break;			case 'f': /* Framed IP address */				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_IP_ADDRESS),PW_TYPE_IPADDR, func);				p++;				break;			case 'i': /* Calling station ID */				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CALLING_STATION_ID),PW_TYPE_STRING, func);				p++;				break;			case 'l': /* request timestamp */				snprintf(tmpdt, sizeof(tmpdt), "%lu",					 (unsigned long) request->received.tv_sec);				strlcpy(q,tmpdt,freespace);				q += strlen(q);				p++;				break;			case 'm': /* request month */				TM = localtime_r(&request->timestamp, &s_TM);				len = strftime(tmpdt, sizeof(tmpdt), "%m", TM);				if (len > 0) {					strlcpy(q, tmpdt, freespace);					q += strlen(q);				}				p++;				break;			case 'n': /* NAS IP address */				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_IP_ADDRESS),PW_TYPE_IPADDR, func);				p++;				break;			case 'p': /* Port number */				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_PORT),PW_TYPE_INTEGER, func);				p++;				break;			case 's': /* Speed */				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CONNECT_INFO),PW_TYPE_STRING, func);				p++;				break;			case 't': /* request timestamp */				CTIME_R(&request->timestamp, tmpdt, sizeof(tmpdt));				nl = strchr(tmpdt, '\n');				if (nl) *nl = '\0';				strlcpy(q, tmpdt, freespace);				q += strlen(q);				p++;				break;			case 'u': /* User name */				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_USER_NAME),PW_TYPE_STRING, func);				p++;				break;			case 'A': /* radacct_dir */				strlcpy(q,radacct_dir,freespace);				q += strlen(q);				p++;				break;			case 'C': /* ClientName */				strlcpy(q,request->client->shortname,freespace);				q += strlen(q);				p++;				break;			case 'D': /* request date */				TM = localtime_r(&request->timestamp, &s_TM);				len = strftime(tmpdt, sizeof(tmpdt), "%Y%m%d", TM);				if (len > 0) {					strlcpy(q, tmpdt, freespace);					q += strlen(q);				}				p++;				break;			case 'H': /* request hour */				TM = localtime_r(&request->timestamp, &s_TM);				len = strftime(tmpdt, sizeof(tmpdt), "%H", TM);				if (len > 0) {					strlcpy(q, tmpdt, freespace);					q += strlen(q);				}				p++;				break;			case 'L': /* radlog_dir */				strlcpy(q,radlog_dir,freespace);				q += strlen(q);				p++;				break;			case 'M': /* MTU */				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_MTU),PW_TYPE_INTEGER, func);				p++;				break;			case 'R': /* radius_dir */				strlcpy(q,radius_dir,freespace);				q += strlen(q);				p++;				break;			case 'S': /* request timestamp in SQL format*/				TM = localtime_r(&request->timestamp, &s_TM);				len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d %H:%M:%S", TM);				if (len > 0) {					strlcpy(q, tmpdt, freespace);					q += strlen(q);				}				p++;				break;			case 'T': /* request timestamp */				TM = localtime_r(&request->timestamp, &s_TM);				len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d-%H.%M.%S.000000", TM);				if (len > 0) {					strlcpy(q, tmpdt, freespace);					q += strlen(q);				}				p++;				break;			case 'U': /* Stripped User name */				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_STRIPPED_USER_NAME),PW_TYPE_STRING, func);				p++;				break;			case 'V': /* Request-Authenticator */				strlcpy(q,"Verified",freespace);				q += strlen(q);				p++;				break;			case 'Y': /* request year */				TM = localtime_r(&request->timestamp, &s_TM);				len = strftime(tmpdt, sizeof(tmpdt), "%Y", TM);				if (len > 0) {					strlcpy(q, tmpdt, freespace);					q += strlen(q);				}				p++;				break;			case 'Z': /* Full request pairs except password */				tmp = request->packet->vps;				while (tmp && (freespace > 3)) {					if (tmp->attribute != PW_USER_PASSWORD) {						*q++ = '\t';						len = vp_prints(q, freespace - 2, tmp);						q += len;						freespace -= (len + 2);						*q++ = '\n';					}					tmp = tmp->next;				}				p++;				break;			default:				DEBUG2("WARNING: Unknown variable '%%%c': See 'doc/variables.txt'", *p);				if (freespace > 2) {					*q++ = '%';					*q++ = *p++;				}				break;		}	}	*q = '\0';	DEBUG2("\texpand: %s -> %s", fmt, out);	return strlen(out);}

⌨️ 快捷键说明

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