/* 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 <conf.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <ncurses.h>
#include <panel.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1