/*********************************************************************/
/* file: action.c - funtions related to the action command */
/* TINTIN III */
/* (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t */
/* coded by peter unold 1992 */
/*********************************************************************/
#include <ctype.h>
#include <string.h>
#include "tintin.h"
extern struct session *activesession;
extern struct listnode *common_actions;
extern char vars[10][BUFFER_SIZE]; /* the &0, &1, &2,....&9 variables */
extern int term_echoing;
extern int echo;
extern char tintin_char;
/***********************/
/* the #action command */
/***********************/
void action_command(char *arg, struct session *ses)
{
char left[BUFFER_SIZE], right[BUFFER_SIZE];
struct listnode *myactions, *ln;
myactions=(ses) ? ses->actions : common_actions;
arg=get_arg_stop_spaces(arg, left);
arg=get_arg_with_spaces(arg, right);
if(!*left) {
puts("#THESE ACTIONS HAS BEEN DEFINED:");
show_list(myactions);
prompt(ses);
}
else if(*left && !*right) {
if((ln=searchnode_list(myactions, left))!=NULL) {
shownode_list(ln);
prompt(ses);
}
else
tintin_puts("#THAT ACTION IS NOT DEFINED.", ses);
}
else {
if((ln=searchnode_list(myactions, left))!=NULL)
deletenode_list(myactions, ln);
insertnode_list(myactions, left, right);
tintin_puts("#OK. ACTION DEFINED.", ses);
}
}
/*************************/
/* the #unaction command */
/*************************/
void unaction_command(char *arg, struct session *ses)
{
char left[BUFFER_SIZE];
struct listnode *myactions, *ln;
myactions=(ses) ? ses->actions : common_actions;
arg=get_arg_with_spaces(arg, left);
if((ln=searchnode_list(myactions, left))!=NULL) {
deletenode_list(myactions, ln);
tintin_puts("#OK. ACTION DELETED", ses);
}
else
tintin_puts("#THAT ACTION IS NOT DEFINED.", ses);
}
/**************************************************************************/
/* run throught each of the commands on the right side of an alias/action */
/* expression, call substitute_text() for all commands but #alias/#action */
/**************************************************************************/
void prepare_actionalias(char *string, char *result)
{
char *cptr, command[BUFFER_SIZE], arg[BUFFER_SIZE], both[BUFFER_SIZE];
*result='\0';
cptr=string;
while(*cptr) {
cptr=get_arg_stop_spaces(cptr, command);
cptr=get_arg_all(cptr, arg);
strcpy(both, command);
if(*arg) {
strcat(both, " ");
strcat(both, arg);
}
if(*command==tintin_char && (
is_abrev(command+1, "alias") || is_abrev(command+1, "unalias") ||
is_abrev(command+1, "action") || is_abrev(command+1, "unaction") ||
is_abrev(command+1, "substitute") || is_abrev(command+1, "unsubstitute")))
strcat(result, both);
else
substitute_vars(both, result+strlen(result));
if(*cptr==';') {
strcat(result, ";");
cptr++;
}
}
}
/*************************************************************************/
/* copy the arg text into the result-space, but substitute the variables */
/* &0..&9 with the real variables */
/*************************************************************************/
void substitute_vars(char *arg, char *result)
{
while(*arg) {
if(*arg=='&' && isdigit(*(arg+1))) { /* substitute variable */
int n=*(arg+1)-'0';
strcpy(result, vars[n]);
arg+=2;
result+=strlen(vars[n]);
}
else
*result++=*arg++;
}
*result='\0';
}
/*********************************************************/
/* split the lines in the buffer and check'em for action */
/*********************************************************/
void split_check_all_actions(char *buffer, struct session *ses)
{
char linebuffer[BUFFER_SIZE], *cpsource, *cpdest;
cpsource=buffer;
cpdest=linebuffer;
while(*cpsource) { /*cut out each of the lines and check for actions */
if(*cpsource=='\n' || *cpsource=='\r') {
cpsource++;
*cpdest='\0';
check_all_actions(linebuffer, ses);
cpsource++;
if(*cpsource=='\n' || *cpsource=='\r')
cpsource++;
cpdest=linebuffer;
}
else
*cpdest++=*cpsource++;
}
*cpdest='\0';
check_all_actions(linebuffer, ses);
}
/**********************************************/
/* check actions from a sessions against line */
/**********************************************/
void check_all_actions(char *line, struct session *ses)
{
struct listnode *ln;
if(check_one_action(line, PROMPT_FOR_PW_TEXT)) {
term_noecho();
term_echoing=FALSE;
}
ln=ses->actions;
while(ln=ln->next) {
if(check_one_action(line, ln->left)) {
char buffer[BUFFER_SIZE];
prepare_actionalias(ln->right, buffer);
if(echo && activesession==ses)
printf("[ACTION: %s]\n", buffer);
parse_input(buffer, ses);
return;
}
}
}
/******************************************************************/
/* check if a text triggers an action and fill into the variables */
/* return TRUE if triggered */
/******************************************************************/
int check_one_action(char *text, char *action)
{
while(*text && !do_tricker(text, action))
text++;
while(*action && *text && do_tricker(text, action)) {
if(*action=='&' && isdigit(*(action+1))) {
int i;
char *cptr;
i=*(action+1)-'0';
for(cptr=vars[i]; *text && (!*(action+2) || !do_tricker(text, action+2)); text++, cptr++)
*cptr=*text;
*cptr='\0';
action+=2;
}
else {
text++;
action++;
}
}
return (*action=='\0');
}
/****************************************/
/* returns TRUE is text triggers action */
/****************************************/
int do_tricker(char *text, char *action)
{
if(!*action)
return TRUE;
if(!*text)
return FALSE;
if(*action=='&' && isdigit(*(action+1))) {
while(*text && !do_tricker(text, action+2))
text++;
return do_tricker(text, action+2);
}
else
return (*text==*action && do_tricker(text+1, action+1));
}