/*********************************************************************/ /* 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)); }