📄 fsm.c
字号:
{ 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 + -