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

📄 print.c

📁 使用最广泛的radius的linux的源码
💻 C
字号:
/* * print.c	Routines to print stuff. * * Version:	$Id: print.c,v 1.56 2008/03/28 10:10:12 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,2006  The FreeRADIUS server project */#include	<freeradius-devel/ident.h>RCSID("$Id: print.c,v 1.56 2008/03/28 10:10:12 aland Exp $")#include	<freeradius-devel/libradius.h>#include	<ctype.h>/* *	Checks for utf-8, taken from: * *  http://www.w3.org/International/questions/qa-forms-utf-8 * *	Note that we don't care about the length of the input string, *	because '\0' is an invalid UTF-8 character. */static int utf8_char(uint8_t *str){	if (*str < 0x20) return 0;	if (*str <= 0x7e) return 1; /* 1 */	if (*str <= 0xc1) return 0;	if ((str[0] >= 0xc2) &&	/* 2 */	    (str[0] <= 0xdf) &&	    (str[1] >= 0x80) &&	    (str[1] <= 0xbf)) {		return 2;	}	if ((str[0] == 0xe0) &&	/* 3 */	    (str[1] >= 0xa0) &&	    (str[1] <= 0xbf) &&	    (str[2] >= 0x80) &&	    (str[2] <= 0xbf)) {		return 3;	}	if ((str[0] >= 0xe1) &&	/* 4a */	    (str[0] <= 0xec) &&	    (str[1] >= 0x80) &&	    (str[1] <= 0xbf) &&	    (str[2] >= 0x80) &&	    (str[2] <= 0xbf)) {		return 3;	}	if ((str[0] >= 0xee) &&	/* 4b */	    (str[0] <= 0xef) &&	    (str[1] >= 0x80) &&	    (str[1] <= 0xbf) &&	    (str[2] >= 0x80) &&	    (str[2] <= 0xbf)) {		return 3;	}	if ((str[0] == 0xed) &&	/* 5 */	    (str[1] >= 0x80) &&	    (str[1] <= 0x9f) &&	    (str[2] >= 0x80) &&	    (str[2] <= 0xbf)) {		return 3;	}	if ((str[0] == 0xf0) &&	/* 6 */	    (str[1] >= 0x90) &&	    (str[1] <= 0xbf) &&	    (str[2] >= 0x80) &&	    (str[2] <= 0xbf) &&	    (str[3] >= 0x80) &&	    (str[3] <= 0xbf)) {		return 4;	}	if ((str[0] >= 0xf1) &&	/* 6 */	    (str[1] <= 0xf3) &&	    (str[1] >= 0x80) &&	    (str[1] <= 0xbf) &&	    (str[2] >= 0x80) &&	    (str[2] <= 0xbf) &&	    (str[3] >= 0x80) &&	    (str[3] <= 0xbf)) {		return 4;	}	if ((str[0] == 0xf4) &&	/* 7 */	    (str[1] >= 0x80) &&	    (str[1] <= 0x8f) &&	    (str[2] >= 0x80) &&	    (str[2] <= 0xbf) &&	    (str[3] >= 0x80) &&	    (str[3] <= 0xbf)) {		return 4;	}	/*	 *	Invalid UTF-8 Character	 */	return 0;}/* *	Convert a string to something printable.  The output string *	has to be larger than the input string by at least 5 bytes. *	If not, the output is silently truncated... */void librad_safeprint(char *in, size_t inlen, char *out, size_t outlen){	uint8_t		*str = (uint8_t *)in;	int		sp = 0;	int		utf8 = 0;	if (inlen == 0) inlen = strlen(in);	/*	 *		 */	while ((inlen > 0) && (outlen > 4)) {		/*		 *	Hack: never print trailing zero.		 *	Some clients send strings with an off-by-one		 *	length (confused with strings in C).		 */		if ((inlen == 0) && (*str == 0)) break;		switch (*str) {			case '\\':				sp = '\\';				break;			case '\r':				sp = 'r';				break;			case '\n':				sp = 'n';				break;			case '\t':				sp = 't';				break;			case '"':				sp = '"';				break;			default:				sp = 0;				break;		}		if (sp) {			*out++ = '\\';			*out++ = sp;			outlen -= 2;			str++;			inlen--;			continue;		}		utf8 = utf8_char((uint8_t *)str);		if (!utf8) {			snprintf(out, outlen, "\\%03o", *str);			out  += 4;			outlen -= 4;			str++;			inlen--;			continue;		}		do {			*out++ = *str++;			outlen--;			inlen--;		} while (--utf8 > 0);	}	*out = 0;}/* *  Print one value into a string. *  delimitst will define if strings and dates will be delimited by '"' */int vp_prints_value(char * out, size_t outlen, VALUE_PAIR *vp, int delimitst){	DICT_VALUE  *v;	char        buf[1024];	const char  *a = NULL;	size_t      len;	time_t      t;	struct tm   s_tm;	out[0] = '\0';	if (!vp) return 0;	switch (vp->type) {		case PW_TYPE_STRING:			if ((delimitst == 1) && vp->flags.has_tag) {				/* Tagged attribute: print delimter and ignore tag */				buf[0] = '"';				librad_safeprint(vp->vp_strvalue,						 vp->length, buf + 1, sizeof(buf) - 2);				strcat(buf, "\"");			} else if (delimitst == 1) {				/* Non-tagged attribute: print delimter */				buf[0] = '"';				librad_safeprint(vp->vp_strvalue,						 vp->length, buf + 1, sizeof(buf) - 2);				strcat(buf, "\"");			} else if (delimitst < 0) { /* xlat.c */				strlcpy(out, vp->vp_strvalue, outlen);				return strlen(out);			} else {				/* Non-tagged attribute: no delimiter */				librad_safeprint(vp->vp_strvalue,						 vp->length, buf, sizeof(buf));			}			a = buf;			break;		case PW_TYPE_INTEGER:		        if ( vp->flags.has_tag ) {			        /* Attribute value has a tag, need to ignore it */			        if ((v = dict_valbyattr(vp->attribute, (vp->vp_integer & 0xffffff)))				    != NULL)				        a = v->name;				else {				        snprintf(buf, sizeof(buf), "%u", (vp->vp_integer & 0xffffff));				        a = buf;				}			} else {		case PW_TYPE_BYTE:		case PW_TYPE_SHORT:			        /* Normal, non-tagged attribute */			        if ((v = dict_valbyattr(vp->attribute, vp->vp_integer))				    != NULL)				        a = v->name;				else {				        snprintf(buf, sizeof(buf), "%u", vp->vp_integer);					a = buf;				}			}			break;		case PW_TYPE_DATE:			t = vp->vp_date;			if (delimitst == 1) {			  len = strftime(buf, sizeof(buf), "\"%b %e %Y %H:%M:%S %Z\"",					 localtime_r(&t, &s_tm));			} else {			  len = strftime(buf, sizeof(buf), "%b %e %Y %H:%M:%S %Z",					 localtime_r(&t, &s_tm));			}			if (len > 0) a = buf;			break;		case PW_TYPE_IPADDR:			a = inet_ntop(AF_INET, &(vp->vp_ipaddr),				      buf, sizeof(buf));			break;		case PW_TYPE_ABINARY:#ifdef ASCEND_BINARY			a = buf;			print_abinary(vp, buf, sizeof(buf));			break;#else		  /* FALL THROUGH */#endif		case PW_TYPE_OCTETS:			if (outlen <= (2 * (vp->length + 1))) return 0;			strcpy(buf, "0x");			fr_bin2hex(vp->vp_octets, buf + 2, vp->length);			a = buf;		  break;		case PW_TYPE_IFID:			a = ifid_ntoa(buf, sizeof(buf), vp->vp_octets);			break;		case PW_TYPE_IPV6ADDR:			a = inet_ntop(AF_INET6,				      (const struct in6_addr *) vp->vp_strvalue,				      buf, sizeof(buf));			break;		case PW_TYPE_IPV6PREFIX:		{			struct in6_addr addr;			/*			 *	Alignment issues.			 */			memcpy(&addr, vp->vp_strvalue + 2, sizeof(addr));			a = inet_ntop(AF_INET6, &addr, buf, sizeof(buf));			if (a) {				char *p = buf + strlen(buf);				snprintf(p, buf + sizeof(buf) - p - 1, "/%u",					 (unsigned int) vp->vp_octets[1]);			}		}			break;		case PW_TYPE_ETHERNET:			snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",				 vp->vp_ether[0], vp->vp_ether[1],				 vp->vp_ether[2], vp->vp_ether[3],				 vp->vp_ether[4], vp->vp_ether[5]);			a = buf;			break;		default:			a = "UNKNOWN-TYPE";			break;	}	if (a != NULL) strlcpy(out, a, outlen);	return strlen(out);}/* *  This is a hack, and has to be kept in sync with tokens.h */static const char *vp_tokens[] = {  "?",				/* T_OP_INVALID */  "EOL",			/* T_EOL */  "{",  "}",  "(",  ")",  ",",  ";",  "+=",  "-=",  ":=",  "=",  "!=",  ">=",  ">",  "<=",  "<",  "=~",  "!~",  "=*",  "!*",  "==",  "#",  "<BARE-WORD>",  "<\"STRING\">",  "<'STRING'>",  "<`STRING`>"};const char *vp_print_name(char *buffer, size_t bufsize, int attr){	int vendor;	size_t len = 0;	if (!buffer) return NULL;	vendor = VENDOR(attr);	if (vendor) {		DICT_VENDOR *v;				v = dict_vendorbyvalue(vendor);		if (v) {			snprintf(buffer, bufsize, "%s-", v->name);		} else {			snprintf(buffer, bufsize, "Vendor-%u-", vendor);		}		len = strlen(buffer);		if (len == bufsize) {			return NULL;		}	}	snprintf(buffer + len, bufsize - len, "Attr-%u", attr & 0xffff);	len += strlen(buffer + len);	if (len == bufsize) {		return NULL;	}	return buffer;}/* *	Print one attribute and value into a string. */int vp_prints(char *out, size_t outlen, VALUE_PAIR *vp){	size_t		len;	const char	*token = NULL;	const char	*name;	char		namebuf[128];	out[0] = 0;	if (!vp) return 0;	name = vp->name;	len = 0;	if (!name || !*name) {		if (!vp_print_name(namebuf, sizeof(namebuf), vp->attribute)) {			return 0;		}		name = namebuf;	}	if ((vp->operator > T_OP_INVALID) &&	    (vp->operator < T_TOKEN_LAST)) {		token = vp_tokens[vp->operator];	} else {		token = "<INVALID-TOKEN>";	}	if( vp->flags.has_tag ) {		snprintf(out, outlen, "%s:%d %s ",			 name, vp->flags.tag, token);		len = strlen(out);		vp_prints_value(out + len, outlen - len, vp, 1);	} else {	        snprintf(out, outlen, "%s %s ", name, token);		len = strlen(out);		vp_prints_value(out + len, outlen - len, vp, 1);	}	return len + strlen(out + len);}/* *	Print one attribute and value. */void vp_print(FILE *fp, VALUE_PAIR *vp){	char	buf[1024];	vp_prints(buf, sizeof(buf), vp);	fputs(buf, fp);}/* *	Print a whole list of attributes, indented by a TAB *	and with a newline at the end. */void vp_printlist(FILE *fp, VALUE_PAIR *vp){	for (; vp; vp = vp->next) {		fprintf(fp, "\t");		vp_print(fp, vp);		fprintf(fp, "\n");	}}

⌨️ 快捷键说明

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