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

📄 pm_parse.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
字号:
/*******************************************************************  Copyright (c) 1996 by the University of Southern California  All rights reserved.  Permission to use, copy, modify, and distribute this software and its  documentation in source and binary forms for any purpose and without  fee is hereby granted, provided that both the above copyright notice  and this permission notice appear in all copies. and that any  documentation, advertising materials, and other materials related to  such distribution and use acknowledge that the software was developed  in part by the University of Southern California, Information  Sciences Institute.  The name of the University may not be used to  endorse or promote products derived from this software without  specific prior written permission.  THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about  the suitability of this software for any purpose.  THIS SOFTWARE IS  PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Other copyrights might apply to parts of this software and are so  noted when applicable.********************************************************************/#include <stdio.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <time.h>#include <netdb.h>#include "config.h"#ifdef STANDARD_C_LIBRARY#  include <stdlib.h>#  include <stddef.h>           /* for offsetof */#else#  include <malloc.h>#  include <memory.h>#endif#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "rsvp_types.h"#include "rsvp_socks.h"#include "Pm_parse.h"#ifdef INCLUDE_SYSTEM_H#include "system.h"#endifint tolower(int);int strcasecmp();/* *	Value list: output of parse machine */net_addr	Pm_addrs[20];u_int32_t	Pm_val[20];int		Pm_vi;		/* Value index: next value entry is				 *	Pm_val[Pm_vi]				 */#define val0	Pm_val[0]#define val1	Pm_val[1]#define val2	Pm_val[2]#define val3	Pm_val[3]char 	*Pm_Class_names[] = {"End", "Show", "Op", "NotOp",		"Is", "IsNot", "File", "NotFile",		"Set", "Action", "Label", "TRV"};char	*Pm_Op_names[] = {"none", "Integer", "cString", "Char", "Flag",			"Host", "EOL", "WhSp"};char	*Result_name[] = {"ERR", "NO", "OK"};#define ERR_printf(x)		fprintf(stderr, (x))#define ERR_printf2(x, y)	fprintf(stderr, (x), (y))#define ERR_printf3(x, y, z)	fprintf(stderr, (x), (y), (z))void	Pm_print(int, Pm_inst *), Pm_list(Pm_inst *), Pm_print_vals(int);#define SkipWhSp	{while (isspace(*Pm_cp)) Pm_cp++ ;}/*	Parse Machine.  Given address of program array, start recognition *		sequence whose index is in transfer vector at offset PC_base. *		Returns OK, NO, or ERR.  May recurse. */intParse_machine(Pm_inst *Pm_program, int PC_base)	{	int		 i,Pm_PC;	Pm_inst		*ip, *tip;	int		 testfor, result;	u_int32_t	 val;	int		 save_vi, first_vi;	char		*tcp, *fcp, *save_cp;	char		 tbuf[256];	int		 L, found;	FILE		*infp;	net_addr	 addr;	/*	PC_base actually points to Transfer Vector entry in	 *	bottom of memory.  Check that it is OK, then branch	 *	to actual start of recognition sequence.	 */	tip = Pm_program + PC_base;	if (PC_base <= 0 || tip->Pmi_class != PmC_TRV) {		printf("Pm: Bad locn %d\n", PC_base);		return(ERR);	}	Pm_PC = PC_base = tip->Pmi_next;	first_vi = Pm_vi;	while (1) {		save_cp = Pm_cp;		save_vi = Pm_vi;		/*	Fetch:		 */		ip = Pm_program + Pm_PC++;		if (Pm_debug) {			Pm_print(Pm_PC-1, ip);			printf("SCAN: %s\n", Pm_cp);		}		/*	Execute:		 */		testfor = OK;		result = NO;		switch (ip->Pmi_class) {				case PmC_END:			return(OK);		case PmC_SHOW:			if (ip->Pmi_parm)				ERR_printf2("%s\n", ip->Pmi_parm);			result = OK;			break;		case PmC_NOT_SUB:			testfor = NO;		case PmC_SUB:			/*	Execute subroutine, and go to next if			 *	does/does not succeed. Call parse machine			 *	recursively.			 */						result = Parse_machine(Pm_program, ip->Pmi_op);			/*			 *	If recognition failed, restore scan pointer			 *	and value list pointer.			 */			if (result != OK) {				Pm_cp = save_cp;				Pm_vi = save_vi;			}			if (result == testfor && ip->Pmi_parm)				ERR_printf2("%s\n", ip->Pmi_parm);			if (Pm_debug)				printf("\n");			break;		case PmC_ACTION:			/*	Execute semantic subroutine, and branch.			 */			if (Pm_debug) {				printf("\nAction %d (%d) vi=%d\n", ip->Pmi_op,						(int)ip->Pmi_parm, first_vi);				Pm_print_vals(first_vi);			}			result = Pm_Action(ip->Pmi_op,					first_vi, (int)ip->Pmi_parm);			break;		case PmC_SET:			/*	Create literal value and append to values list.			 */			result = OK;			val = (int)ip->Pmi_parm;			Append_Val(val);			break;		case PmC_NOT_FILE:			testfor = NO;		case PmC_FILE:			/*	Look up <keyword> in specified file, and			 *	if found, take the rest of the line of file			 *	as input and recursively parse using specified			 *	labelled rule.  Keyword is alphanumeric and dots.			 */			SkipWhSp;	/* Skip White Space */			fcp = Pm_cp;			while (isalnum(*Pm_cp) || *Pm_cp == '.')				Pm_cp++;			if (Pm_cp == fcp)				break;			/* Would be nicer to build in-memory copy of file...			 */			infp = fopen(ip->Pmi_parm, "r");			if (!infp)				break;			found = 0;			while (fgets(tbuf, sizeof(tbuf), infp)) {				char *cp1 = fcp, *cp2 = tbuf;				while(tolower(*cp1++) == tolower(*cp2++))					if (cp1 == Pm_cp)						break;				if (cp1 != Pm_cp || !isspace(*cp2))					continue;				/* Found match */				fcp = cp2;				found = 1;				break;			}			if (!found)				break;			save_cp = Pm_cp;			Pm_cp = fcp;			result = Parse_machine(Pm_program, ip->Pmi_op);			Pm_cp = save_cp;			if (result != OK)				Pm_vi = save_vi;			break;		case PmC_NOT_OP:			testfor = NO;		case PmC_OP:			/*	Execute built-in parse operation, and set			 *	result to OK/NO/ERR.			 */		    switch (ip->Pmi_op) {		    case PmO_cString:				/*	Scan for case-independent match				 *	to specified string.				 */			SkipWhSp;	/* Skip White Space */			strncpy(tbuf, Pm_cp, L = strlen(ip->Pmi_parm));			tbuf[L] = '\0';			if (!strcasecmp(tbuf, ip->Pmi_parm)) {				Pm_cp += L;				result = OK;			}			break;		    case PmO_Integer:				/*	Scan for integer, and if one is				 *	found, append to value list.  Suffixes				 *	K (1000) and M (10**6) are allowed.				 *	Parm field is string to be displayed if				 *	result is as requested.  				 */			SkipWhSp;	/* Skip White Space */			if (isdigit(*Pm_cp)) {				val = 0;				while (isdigit(*Pm_cp)) {					val = 10*val + *Pm_cp++ - '0';				}				if (tolower(*Pm_cp) == 'k') {					val *= 1000;					Pm_cp++;				}				else if (tolower(*Pm_cp) == 'm') {					val *= 1000000;					Pm_cp++;				}				Append_Val(val);				result = OK;			}			if (result == testfor && ip->Pmi_parm)				ERR_printf2("%s\n", ip->Pmi_parm);			break;		    case PmO_Flag:				/* 	Scan for any single char in given				 *	string, and if one is found, append				 *	its index to the value list.				 */		    case PmO_Char:				/* 	Scan for any single char in given 				 *	string but value list unchanged.				 */			SkipWhSp;	/* Skip White Space */			for (tcp = ip->Pmi_parm; *tcp; tcp++) {				if (*tcp == *Pm_cp) {					result = OK;					Pm_cp++;					break;				}			}			if (result == OK && ip->Pmi_op == PmO_Flag)				Append_Val(tcp - ip->Pmi_parm); 			break;		    case PmO_Host:			SkipWhSp;	/* Skip White Space */			if (!(isalnum(*Pm_cp) || *Pm_cp == ':'))				goto Nohost;			fcp = Pm_cp;			i = 0;			while (isalnum(*Pm_cp) || *Pm_cp == '.'					|| *Pm_cp == '-' || *Pm_cp == ':' ) {				if (!isdigit(*Pm_cp))					i = 1;				Pm_cp++;			}			if (i == 0)				goto Nohost;			strncpy(tbuf, fcp, L = Pm_cp - fcp);		        tbuf[L] = '\0';			if (!net_addr_ascii(&addr,tbuf)) {				ERR_printf2("Unknown host %s\n", tbuf);				result = ERR;				break;			}			result = OK;			Append_Address(addr);Nohost:			if (result == testfor && ip->Pmi_parm)				ERR_printf2("%s\n", ip->Pmi_parm);			break;		    case PmO_EOL:			SkipWhSp;	/* Skip White Space */			if (*Pm_cp == '\0')				result = OK;			if (result == testfor && ip->Pmi_parm)				ERR_printf2("%s\n", ip->Pmi_parm);			break;		    case PmO_WhSp:			if (isspace(*Pm_cp)) {				while (isspace(*Pm_cp)) Pm_cp++;				result = OK;			}			if (result == testfor && ip->Pmi_parm)				ERR_printf2("%s\n", ip->Pmi_parm);			break;		    default:			ERR_printf3("?? op %d for class %d\n",						ip->Pmi_op, ip->Pmi_class);			result = ERR;			break;		    }			/*			 *	If recognition failed, restore scan pointer.			 */		    if (result != OK)			Pm_cp = save_cp;		    break;		default:			ERR_printf2("Unknown class %d\n", ip->Pmi_class);			return(ERR);		}		if (Pm_debug)			printf("RESULT: %s\n\n", Result_name[result+Pm_Ret+3]);		if (result == ERR)			return ERR;		else if (result == testfor) {			if (ip->Pmi_next <= (OK))				return(ip->Pmi_next);			Pm_PC += ip->Pmi_next - 1;		}	}}intPm_Init(Pm_inst *Pm_mem)	{	Pm_inst *ip, *ipd;	int	i, N, L;	N = L = 0;	for (ip = Pm_mem; ; ip++, N++) {		if (ip->Pmi_class == PmC_LABEL) {			if (ip->Pmi_next == 0)				break;			L = (L > ip->Pmi_next)? L:ip->Pmi_next;		}	}	L++;	ipd = ip + L;	while (ip >= Pm_mem) {		*ipd-- = *ip--;	}	ipd = Pm_mem;	for (i=0; i < L; i++, ipd++) {		memset((char *)ipd, 0, sizeof(Pm_inst));		ipd->Pmi_class = PmC_TRV;	}	for (ip = Pm_mem + L, N = L; ; ip++, N++) {		if (ip->Pmi_class == PmC_LABEL) {			if (ip->Pmi_next == 0)				break;			(Pm_mem+ip->Pmi_next)->Pmi_next = N + 1;		}	}	return(1);}#define print_parm  (ip->Pmi_parm)? ip->Pmi_parm : "(null)"voidPm_print(int Pm_PC, Pm_inst *ip)	{	char Next[8];	Pm_inst		*tip;	if (ip->Pmi_next <= OK)		sprintf(Next, "%s", Result_name[ip->Pmi_next+Pm_Ret+3]);	else		sprintf(Next, "%d", ip->Pmi_next);			switch(ip->Pmi_class) {	    case PmC_OP:		printf("Pm: %4d:      %8s \"%s\"   -> %6s\n",			Pm_PC, Pm_Op_names[ip->Pmi_op], print_parm, Next);		break;	    case PmC_NOT_OP:		printf("Pm: %4d:  NOT %8s \"%s\"   ->%6s\n",			Pm_PC, Pm_Op_names[ip->Pmi_op], print_parm, Next);		break;	    case PmC_ACTION:		printf("Pm: %4d:       Action    %d (%d)  ->%6s\n",			Pm_PC, ip->Pmi_op, (int) ip->Pmi_parm, Next);		return;	    case PmC_SET:		printf("Pm: %4d:       Set      =%d  ->%6s\n",			Pm_PC, (int) ip->Pmi_parm, Next);		return;	    case PmC_SUB:	    case PmC_NOT_SUB:		tip = (Pm_inst *)(			(char *)ip - (Pm_PC -  ip->Pmi_op)*sizeof(Pm_inst));		printf("Pm: %4d:  %8s %d(#%d)  %s  ->%6s\n",			Pm_PC, Pm_Class_names[ip->Pmi_class],			tip->Pmi_next, ip->Pmi_op, print_parm, Next);		break;	    default:		printf("Pm: %4d:  %8s %d  ->%6s\n",			Pm_PC, Pm_Class_names[ip->Pmi_class],			ip->Pmi_op, Next);		break;	}}voidPm_list(Pm_inst *Pm_mem)	{	Pm_inst *ip;	int	 pc = 0;	for (ip = Pm_mem; ip->Pmi_class != PmC_END; ip++, pc++)		Pm_print(pc, ip);}voidPm_print_vals(int first)	{	int i;	printf("%d Vals: ", Pm_vi);	for (i=0; i < Pm_vi; i++)		printf("%s %8.8X ", (i == first)?"|>":"",			 (u_int32_t) Pm_val[i]);	printf("\n\n");}	

⌨️ 快捷键说明

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