/* Copyright (c) 2002 * Marko Boomstra (m.boomstra@chello.nl). All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "mudix.h" void show_triggers(void) { static int current; TRIGGER *trig; char *str; int line, i, width, height, centre, wsize; width = LEN_COL-4; height = 20; wsize = height-2; centre = ((width-2)/2)-1; wresize(wMsg, height, width); werase(wMsg); move_panel(pMsg, 1, 2); if (panel_hidden(pMsg) == PANEL_HIDDEN) current = 0; for (line=1, i=0, trig = settings->trigger_list; trig; trig = trig->next) { if (!trig->in || !trig->out) continue; i+=2; if (i < (current*wsize)+2) continue; mvwprintw(wMsg, line++, 1, "%2d%c (%2d): %s", (i/2), trig->enabled? '*': ' ', trig->level, trig->in); mvwprintw(wMsg, line++, 1, "Response: %s", trig->level == TRG_PASSWORD? "*********": trig->out); if (line >= wsize && trig->next) { current++; break; } if (!trig->next) /* last one */ current = 0; } draw_border(wMsg); str = "Triggers"; mvwprintw(wMsg, 0, centre-strlen(str)/2, str); show_panel(pMsg); return; } TRIGGER *new_trigger(int level, bool last) { TRIGGER *trigger; if (!(trigger = (TRIGGER *)malloc(sizeof(TRIGGER)))) return NULL; if (last && settings->trigger_list) { TRIGGER *iTrig; for (iTrig = settings->trigger_list; iTrig; iTrig = iTrig->next) { if (!iTrig->next) break; } iTrig->next = trigger; trigger->next = NULL; } else { trigger->next = settings->trigger_list; settings->trigger_list = trigger; } trigger->in = NULL; trigger->out = NULL; trigger->inp = NULL; trigger->pArg = trigger->arg; trigger->enabled = FALSE; trigger->level = level; return trigger; } void free_trigger(TRIGGER *trigger) { TRIGGER *lookup; if (!trigger) return; for (lookup = settings->trigger_list; lookup; lookup = lookup->next) { if (lookup->next == trigger) { lookup->next = trigger->next; break; } } if (trigger == settings->trigger_list) settings->trigger_list = trigger->next; if (trigger->in) free(trigger->in); if (trigger->out) free(trigger->out); trigger->inp = NULL; free(trigger); return; } TRIGGER *trig_lookup(TRIGGER *beg, int level) { TRIGGER *trig; for (trig = (beg? beg: settings->trigger_list); trig; trig = trig->next) { if (!trig->in || !trig->out) continue; if (trig->level == level) break; } return trig; } #define MAX_TRIG_ARG_LEN (LINE_MAXIM-20) void trigger_check(char *buffer) { TRIGGER *trig; char *pBuf, *pTrg, *pArg, *pMrk; for (trig = settings->trigger_list; trig; trig = trig->next) { if (!trig->enabled) { continue; } pBuf = buffer; pTrg = trig->inp; pArg = trig->pArg; pMrk = NULL; while (*pBuf) { /* first check if the character is printable (NL/CR?) */ if (!isprint(*pBuf)) { /* nope, then set our pointers to start */ pArg = trig->pArg = trig->arg; pTrg = trig->in; pMrk = NULL; pBuf++; continue; } /* not inside an argument, and buffer unequal to trigger? */ if (*pTrg != *pBuf && *pTrg != '%' && pArg == trig->pArg) { /* backup pointers, but this time continue with next if */ pArg = trig->pArg = trig->arg; pTrg = trig->in; pMrk = NULL; } /* check for a %0-%9 */ if (*pTrg == '%') { pTrg++; if (isdigit(*pTrg++)) { /* if we are already within another %, close that one */ if (pArg != trig->pArg) { *pArg++ = '}'; trig->pArg = pArg; } /* did we place a marker? if so clear it */ if (pMrk) { pMrk = NULL; } /* start a new argument in our arg buffer */ *pArg++ = '{'; } } /* is the character in the trigger equal to the incoming buffer? */ if (*pTrg != *pBuf) { /* nope, characters not the same... check if in an argument */ if (pArg != trig->pArg) { /* yup, did we place a marker? */ if (pMrk) { char *pTmp = pMrk; /* copy everything from the marker into argument */ while (pTmp != pTrg) { *pArg++ = *pTmp++; if ((pArg - trig->arg) >= MAX_TRIG_ARG_LEN) { break; } } /* backup the trigger pointer */ pTrg = pMrk; pMrk = NULL; } /* copy character from buf into argument */ *pArg++ = *pBuf; } } else { /* characters are equal: if marker's not set, set it now */ if (!pMrk && pArg != trig->pArg) { pMrk = pTrg; } pTrg++; } /* is last argument passing max arg length? */ if ((pArg - trig->arg) >= MAX_TRIG_ARG_LEN) { /* set argument pointer to start of last argument */ pArg = trig->pArg; } pBuf++; if (*pTrg == '\0') { /* trigger reached the end of its buffer */ if (pArg != trig->pArg) { *pArg++ = '\0'; } /* call the input processor */ process_input(trig->out, trig->arg, TRUE); /* disable triggers of level LOGIN and PASSWORD */ if (trig->level == TRG_LOGIN || trig->level == TRG_PASSWORD) { trig->enabled = FALSE; } /* update the pointers */ pTrg = trig->inp = trig->in; pArg = trig->pArg = trig->arg; pMrk = NULL; } } /* continue at current position in the trigger next time */ trig->inp = pTrg; } return; }