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

📄 fsm.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 3 页
字号:
	dprintf(4, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	for (i = 0; events[i].ev_name != NULL; i++)	{		if (strcmp (events[i].ev_name, pevent) == 0)		{			return events[i].ev_value;		}	}	return (-2);} /* end of enum_event () *//************************************************************************* * *	Function: extra_stuff * *	Purpose: Evaluate an extra value pair (or two) for this FSM entry. * *	Returns: 0, if successful, *		 -1, if there were errors. * *************************************************************************/static intextra_stuff (buf, value, string)char           *buf;int            *value;char          **string;{	int             result;	VALUE_PAIR     *list;	VALUE_PAIR     *vp;	static char    *func = "extra_stuff";	dprintf(4, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	result = 0;	*value = 0;	*string = '\0';	vp = (VALUE_PAIR *) NULL;	list = (VALUE_PAIR *) NULL;	if (pair_parse (buf, &list, (VALUE_PAIR **) NULL) != 0)	{		dprintf(4, (LOG_DAEMON, LOG_DEBUG, "%s: error parsing '%s'",			func, (buf == (char *) NULL) ? "?" : buf ));		result = -1;	}	else	{		vp = list;		while (vp != (VALUE_PAIR *) NULL)		{			switch (vp->ap->type)			{			    case PW_TYPE_INTEGER:				*value = vp->lvalue;				break;			    case PW_TYPE_STRING:				if (strlen (vp->strvalue) < AUTH_ID_LEN)				{				    *string = add_string (vp->strvalue, ASIS);				}				break;			    default:				dprintf(4, (LOG_DAEMON, LOG_DEBUG,					"%s: unsupported type %d", func,					vp->ap->type));				result = -1;				break;			}			vp = vp->next;		}	}	list_free (list);	return result;} /* end of extra_stuff () *//************************************************************************* * *	Function: find_state * *	Purpose: Find the numer of the given state in the list of states. * *	Returns: pointer to the NAME_LIST node for this state, *		 (NAME_LIST *) NULL, if the name is not found in the list. * *************************************************************************/static NAME_LIST *find_state (list, name)STATELIST      *list;		/* list of states names already seen */char           *name;		/* the state name to search for */{	NAME_LIST      *state;	static char    *func = "find_state";	dprintf(4, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	for (state = list->states ;		state != (NAME_LIST *) NULL ;		state = state->next)	{		if (strcmp (state->name, name) == 0)		{			break;		}	}	return state;} /* end of find_state () *//************************************************************************* * *	Function: init_fsm * *	Purpose: Does all the initialization for FSM. * *	Returns: <number of states>, if the (new) FSM is initialized properly, *		 -1, if any errors are detected. * *************************************************************************/intinit_fsm (n, fsm_file, main_fsm, def_fsm)int             n;                /* INPUT: current number of FSM states */char           *fsm_file;         /* INPUT: pointer to FSM config file name */FSM_ENT      ***main_fsm;         /* OUTPUT: pointer to FSM table */FSM_ENT      ***def_fsm;          /* OUTPUT: pointer to default action table */{	int             len;	int             nfsm;	FILE           *fp;	char           *fsmfile;	struct stat     statbuf;	char            buf[MAXPATHLEN];	static char    *func = "init_fsm";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	if (n > 0)	{		rad_fsmdelete (n);	}	sprintf (buf, "%s/%s", radius_dir, fsm_file);	if ((fp = fopen (buf, "r")) == (FILE *) NULL)	{		dprintf(2, (LOG_DAEMON, LOG_DEBUG,			"%s: using built-in standard FSM table", func));		fsmfile = standard_fsm;		strcpy (buf, "built-in standard FSM table");		fsm_file = "Built-in";	}	else	{		stat (buf, &statbuf);		len = (long) statbuf.st_size;		if ((fsmfile = (char *) malloc (len)) == (char *) NULL)		{			logit (LOG_DAEMON, LOG_ALERT,				"%s: FATAL out of memory", func);			abort ();		}		fread (fsmfile, len, 1, fp);		fclose (fp);	/* Cleanup... */	}	nfsm = rad_fsminit (fsmfile, &fsm, fsm_file);	if (fsmfile != standard_fsm)	{		free (fsmfile);	}	dprintf(1, (LOG_DAEMON, LOG_DEBUG,		"%s: FSM defined with %d states from %s", func, nfsm, buf));	if (nfsm == -2)	{		return (-1);	}	/* ... and the default action table */	if (default_fsm == (FSM_ENT **) NULL)	{		len = rad_fsminit (default_actions, &default_fsm, "DEFAULT");		if (len == -2)		{			dprintf(1, (LOG_DAEMON, LOG_DEBUG,				"%s: return code %d from rad_fsminit()",				func, len));			return (-1);		}	}	*main_fsm = fsm;	*def_fsm = default_fsm;	return nfsm;} /* end of init_fsm () *//************************************************************************* * *	Function: rad_fsmdelete * *	Purpose: Destroy the finite state machine (FSM) data structure. * *************************************************************************/static voidrad_fsmdelete (nfsm)int             nfsm;{	FSM_ENT        *pe;	FSM_ENT        *pen;	static char    *func = "rad_fsmdelete";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	while (nfsm > 0) /* free the individual FSM state entries */	{		nfsm--;		for (pe = fsm[nfsm]; pe != (FSM_ENT *) NULL; pe = pen)		{			pen = pe->next;			free (pe);		}	}	free (fsm); /* free the FSM array itself */	return;} /* end of rad_fsmdelete () *//************************************************************************* * *	Function: rad_fsminit * *	Purpose: Initialize the FSM table in memory from the given file. * *	Returns: number of states parsed, if successful, *		 -2, if errors occurred. * *************************************************************************/static intrad_fsminit (fsmfile, fsm, fsm_name)char           *fsmfile;FSM_ENT      ***fsm;char           *fsm_name;{	int             i;		/* loop variable */	int             more;		/* while loop control variable */	int             nfsm;		/* state counter */	int             line_cnt;	/* config file line count */	int             err_cnt;	/* used in FSM verification */	int             ref_cnt;	/* used in FSM verification */	int             cst;		/* current state number */	int             xvalue;	FILE           *debugout = stdout;	char           *ptr;		/* pointer into given file */	char           *newline;	/* pointer into given file */	char           *p;		/* pointer into line buffer */	char           *s;		/* pointer into line buffer */	char           *b;		/* pointer into line buffer */	char           *e;		/* pointer into line buffer */	char           *a;		/* pointer into line buffer */	char           *n;		/* pointer into line buffer */	char           *xtra;		/* pointer into line buffer */	FSM_ENT        *pe;		/* pointer to an entry */	FSM_ENT        *pn;		/* temporary pointer */	FSM_ENT       **pfsm;		/* new FSM */	NAME_LIST      *node;		/* pointer to a state NAME_LIST node */	NAME_LIST      *node_state;	/* pointer to current FSM state */	NAME_LIST     **prev;		/* used to free "sts" states below */	STATELIST       sts;		/* state list data structure */	char           *xstring;	char            buf[256];	/* line buffer for file reading */	static char    *func = "rad_fsminit";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	/* allocate new FSM */	sts.nst = 0;	sts.maxst = NUMSTATES;	sts.states = (NAME_LIST *) NULL;	if ((pfsm = (FSM_ENT **) calloc (sts.maxst, sizeof (FSM_ENT *)))							== (FSM_ENT **) NULL)	{		logit (LOG_DAEMON, LOG_ALERT, "%s: FATAL out of memory for FSM",			func);		abort ();	}	line_cnt = 0;		/* line number for debugging */	nfsm = 0;		/* have seen no state yet */	more = 1;	ptr = fsmfile;	node_state = (NAME_LIST *) NULL;	/* Saftey */	while (more)	{		if ((newline = strchr (ptr, '\n')) == (char *) NULL)		{			more = 0;			break;		}		else		{			i = newline - ptr;			strncpy (buf, ptr, i);			buf[i] = '\0';			ptr = ++newline;		}		line_cnt++;		if (*buf == COMMENT || *buf == '\n' || *buf == '\0')		{			continue;		}		else		{			if (*buf == '%')			{				if ((p = strtok (buf, " \t")) != (char *) NULL)				{					/* Have found a keyword */					if (strcasecmp (p, "%FSMID") == 0)					{						/* Find end of line. */						if ((p = strtok (NULL, "\n\r"))							       != (char *) NULL)						{							int j;							if (fsm_id							       != (char *) NULL)							{								free (fsm_id);							}							j = strlen (p);							if (j > MAX_FSMID_LEN)							{							   /* Truncate. */							   p[MAX_FSMID_LEN]									= '\0';							}							fsm_id = rad_strdup (p);							fsm_name = fsm_id;						}					}				}				/* Just treat FSMID as a comment. */				continue;			}		}		while (i > 0) /* capitalize all tokens on line */		{			i--;			buf[i] = toupper (buf[i]);		}		xvalue = 0;		xstring = (char *) NULL;		if (isalpha(*buf)) /* states start in column one */		{			if ((p = strtok (buf, ":")) != NULL) /* have state */			{				if ((s = strtok (NULL, " \t\r\n")) != NULL)				{					if ((*s != '#') && (*s != '\0'))					{						logit (LOG_DAEMON, LOG_ERR,				"%s: Warning, extra junk on end of state label",							func);						logit (LOG_DAEMON, LOG_ERR,					  "%s: at line %d, for state %s, '%s'",							func, line_cnt, p, s);					}				}				if (strcmp (p, "END") == 0)				{					dprintf(4, (LOG_DAEMON, LOG_DEBUG,						"%s state detected", p));					more = 0;				}				else		/* insert new state */				{					dprintf(4, (LOG_DAEMON, LOG_DEBUG,					       "about to insert new state %s",						p));					if ((node = find_state (&sts, p))							== (NAME_LIST *) NULL)					{						cst = nfsm;						nfsm = add_state (&sts, p,						       (u_int) ST_DEFINED, cst);						node_state = find_state (&sts,									 p);					}					else /* have seen this state already */					{						node_state = node;						if (node->flag == ST_SEEN)						{							cst = node->num;							node->flag = ST_DEFINED;						}						else /* oops, was defined */

⌨️ 快捷键说明

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