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

📄 fsm.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 3 页
字号:
						{							logit (LOG_DAEMON,								LOG_ERR,						"%s: duplicate state: line %3d",								func, line_cnt);							logit (LOG_DAEMON,								LOG_ERR,								"'%s'", buf);							return (-2);						}					}				}			}			else			{				logit (LOG_DAEMON, LOG_ERR,					"%s: bad state: line %3d",					func, line_cnt);				logit (LOG_DAEMON, LOG_ERR,					"'%s'", buf); /* Log the parse error. */				return (-2);			}		}		else /* grab (state.action.event, action, nextstate) 3-tuple */		{			if (nfsm == 0)	/* do we have some/any state(s)? */			{				logit (LOG_DAEMON, LOG_ERR,					"%s: no states: line %3d",					func, line_cnt);				logit (LOG_DAEMON, LOG_ERR,					"'%s'", buf); /* Log the parse error. */				return (-2);			}			if ((s = strtok (buf, " \t.")) == NULL) /* state ? */			{				logit (LOG_DAEMON, LOG_ERR,					"%s: error parse state: line %3d",					func, line_cnt);				logit (LOG_DAEMON, LOG_ERR,					"'%s'", buf); /* Log the parse error. */				return (-2);			}			if ((b = strtok (NULL, " \t.")) == NULL) /* action ? */			{				logit (LOG_DAEMON, LOG_ERR,					"%s: error parse old action: line %3d",					func, line_cnt);				logit (LOG_DAEMON, LOG_ERR,					"'%s'", buf); /* Log the parse error. */				return (-2);			}			if ((e = strtok (NULL, " \t\n\r")) == NULL) /* event? */			{				logit (LOG_DAEMON, LOG_ERR,					"%s: error parse event: line %3d",					func, line_cnt);				logit (LOG_DAEMON, LOG_ERR,					"'%s'", buf); /* Log the parse error. */				return (-2);			}			if ((a = strtok (NULL, " \t\n\r")) == NULL) /* action?*/			{				logit (LOG_DAEMON, LOG_ERR,					"%s: error parse action: line %3d",					func, line_cnt);				logit (LOG_DAEMON, LOG_ERR,					"'%s'", buf); /* Log the parse error. */				return (-2);			}			if ((n = strtok (NULL, " \t\n\r")) == NULL) /* next ? */			{				logit (LOG_DAEMON, LOG_ERR,					"%s: error parse next state: line %3d",					func, line_cnt);				logit (LOG_DAEMON, LOG_ERR,					"'%s'", buf); /* Log the parse error. */				return (-2);			}			if ((xtra = strtok (NULL, " \t\n\r")) != NULL) /*extra*/			{				if (extra_stuff (xtra, &xvalue, &xstring) < 0)				{					logit (LOG_DAEMON, LOG_ERR,					 "%s: error with extra stuff: line %3d",						func, line_cnt);					logit (LOG_DAEMON, LOG_ERR,						"'%s'", buf); /* Log stuff. */					return (-2);				}			}			if ((pe = (FSM_ENT *) malloc (sizeof (FSM_ENT)))							== (FSM_ENT *) NULL)			{				logit (LOG_DAEMON, LOG_ALERT,					"%s: FATAL out of memory for FSM",					func);				abort ();			}			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"have 3-tuple '%s.%s.%s'", s, b, e));			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"   action '%s', next state '%s'", a, n));			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"   value %d and string '%s'", xvalue,				(xstring == (char *) NULL) ? "?" : xstring));			pe->xvalue = xvalue;			pe->xstring = xstring;			pe->fsm_name = fsm_name;			pe->state_name = node_state->name;			/* handle state part of (state.action.event) 3-tuple */			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"finding event state '%s' with number:", s));			if (strcmp (s, "*") == 0)			{				pe->event.state = ST_ANY;				dprintf(4, (LOG_DAEMON, LOG_DEBUG,					"     %u", ST_ANY));			}			else			{				if ((node = find_state (&sts, s))							== (NAME_LIST *) NULL)				{					i = nfsm; /* pick next state */					nfsm = add_state (&sts, s,							  (u_int) ST_SEEN, i);					pe->event.state = (u_char) i;					dprintf(4, (LOG_DAEMON, LOG_DEBUG,						"     %u and flag %s", i,						"ST_SEEN"));				}				else /* have seen already */				{					pe->event.state = (u_char) node->num;					dprintf(4, (LOG_DAEMON, LOG_DEBUG,						"     %u and flag %s",						node->num,						(node->flag == ST_SEEN)						? "ST_SEEN" : "ST_DEFINED"));				}			}			/* handle action part of (state.action.event) 3-tuple */			if (b[0] == '+')			{				pe->event.a.proxy = add_string (&b[1], ASIS);				pe->event.isproxy = 1;			}			else			{				pe->event.isproxy = 0;				if ((pe->event.a.aatv = find_aatv (b))							       == (AATV *) NULL)				{					/* Log invalid previous action. */					logit (LOG_DAEMON, LOG_ERR,				     "%s: invalid old AATV name: '%s' line %3d",						func, b, line_cnt);					return (-2);				}			}			/* handle event part of (state.action.event) 3-tuple */			if ((pe->event.value = enum_event (e)) == -2)			{				/* Log invalid event. */				logit (LOG_DAEMON, LOG_ERR,					"%s: invalid event name: '%s' line %3d",					func, e, line_cnt);				return (-2);			}			if ((pe->action = find_aatv (a)) == (AATV *) NULL)			{				/* Log invalid action. */				logit (LOG_DAEMON, LOG_ERR,				       "%s: invalid action name: '%s' line %3d",					func, a, line_cnt);				return (-2);			}			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"looking for next_state %s with number:", n));			if (strcmp (n, "END") == 0)			{				pe->next_state = ST_END;				dprintf(4, (LOG_DAEMON, LOG_DEBUG,					"     %d", ST_END));			}			else			{				if (strcmp (n, "SAME") == 0)				{					pe->next_state = ST_SAME;					dprintf(4, (LOG_DAEMON, LOG_DEBUG,						"     %d", ST_SAME));				}				else				{					if ((node = find_state (&sts, n))							== (NAME_LIST *) NULL)					{						i = nfsm; /* pick next state */						nfsm = add_state (&sts, n,							    (u_int) ST_SEEN, i);						pe->next_state = (u_char) i;						dprintf(4, (LOG_DAEMON,							LOG_DEBUG,							"     %u and flag %s",							i, "ST_SEEN"));					}					else /* have seen already */					{						pe->next_state =							(u_char) node->num;						dprintf(4, (LOG_DAEMON,							LOG_DEBUG,							"     %u and flag %s",							node->num,							(node->flag == ST_SEEN)							? "ST_SEEN"							: "ST_DEFINED"));					}				}			}			pe->next = (FSM_ENT *) NULL;			/* link *pe to the FSM table */			if ((pn = pfsm[cst]) == (FSM_ENT *) NULL)			{				pfsm[cst] = pe;			}			else			{				while (pn->next)				{					pn = pn->next;				}				pn->next = pe;			}			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"entry added to state %d:", cst));			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"     event [%d,%s,%d]", pe->event.state,				(pe->event.isproxy == 1) ? pe->event.a.proxy :					(char *) pe->event.a.aatv->id,				pe->event.value));			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"     action %s", pe->action->id));			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"     next_state %d", pe->next_state));			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"     value %d", pe->xvalue));			dprintf(4, (LOG_DAEMON, LOG_DEBUG,				"     string '%s'",				(pe->xstring != (char *) NULL)						? pe->xstring : "?"));		} /* end of else not isalpha() */	} /* end of while (more) */	/*	 * now check if the state machine is valid	 * 	-	See if there is any state (except Start)	 *		not-reachable from any other states;	 * 	-	See if there is any state which is	 *		not defined.	 *	-	Print out the whole state machine in debug	 *		mode for inspection.	 */	err_cnt = 0; /* indicate assumption about clean FSM table */	for (i = 1; i < nfsm; i++) /* for each state */	{		ref_cnt = 0; /* reference counter for state "i" */		for (cst = 0; cst < nfsm; cst++)		{			for (pe = pfsm[cst];				pe != (FSM_ENT *) NULL;				pe = pe->next)			{				if (i == pe->next_state)				{					ref_cnt++;				}			}		}		/* error if no FSM entry refers to state "i" */		if (ref_cnt == 0)		{			pe = pfsm[i];			logit (LOG_DAEMON, LOG_ERR,				"%s: non-reachable state %s::%s [%d]",				func, pe->fsm_name, pe->state_name, i);			err_cnt = i;		}	} /* end of for each state */	if (debug_flag >= 2)	{		if (ddt)		{			debugout = ddt;		}		fprintf (debugout, "\nState  Event                 Action        Next State Value String\n");		fprintf (debugout, "-----  --------------------  ------------  ---------- ----- ------\n\n");		fprintf (debugout, "\n");	}	for (i = 0; i < nfsm; i++) /* for each state (again) */	{		for (pe = pfsm[i]; pe != (FSM_ENT *) NULL; pe = pe->next)		{			if ((pe->next_state >= nfsm) &&				(pe->next_state < ST_RESERVED))			{				logit (LOG_DAEMON, LOG_ERR,				    "%s: non-existent state %d in %s::%s [%d]",					func, pe->next_state, pe->fsm_name,					pe->state_name, i);				err_cnt++;			}			if (debug_flag >= 2)			{				fprintf (debugout,			  "%3d   [%3d,%-13s,%2d] %-12s  %5d       %3d  '%s'\n",					i, pe->event.state,					(pe->event.isproxy == 1) ?						pe->event.a.proxy :						(char *) pe->event.a.aatv->id,					pe->event.value, pe->action->id,					pe->next_state, pe->xvalue,					pe->xstring ? pe->xstring : "");			}		}		if (debug_flag >= 2)		{			fprintf (debugout, "\n");		}	} /* end of for each state (again) */	if (debug_flag >= 2)	{		fprintf (debugout, "\n");	}	*fsm = pfsm;	/* free the states list */	if (debug_flag >= 2)	{		fprintf (debugout, "State  State Name     Number Flag\n");		fprintf (debugout, "-----  -------------- ------ ----\n\n");	}	i = 0;	while (sts.states != (NAME_LIST *) NULL)	{		prev = &sts.states;		for (node = sts.states ;			node != (NAME_LIST *) NULL ;			node = node->next)		{			if (node->next == (NAME_LIST *) NULL)			{				break;			}			prev = &(node->next);		}		if (debug_flag >= 2)		{			fprintf (debugout, " %2d    %-14s %3d    %s", i, node->name,			    node->num,			    (node->flag == ST_SEEN) ? "ST_SEEN" : "ST_DEFINED");		}		if (node->flag == ST_SEEN)		{			if (debug_flag >= 2)			{				fprintf (debugout, " <--- this is an error\n");			}			logit (LOG_DAEMON, LOG_ERR,				"%s: state %s seen but not defined",				func, node->name);			nfsm = -2;		}		else		{			if (debug_flag >= 2)			{				fprintf (debugout, "\n");			}		}		free (node);		*prev = (NAME_LIST *) NULL;		i++;	}	if (err_cnt > 0)	{		return (-2);	}	if (debug_flag >= 2)	{		fprintf (debugout, "\n");	}	return nfsm;} /* end of rad_fsminit () */

⌨️ 快捷键说明

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