/*********************************************************************/ /* 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; extern int acnum; extern int mesvar[6]; extern char *get_arg_in_braces(); extern struct listnode *search_node_with_wild(); extern struct listnode *searchnode_list(); void substitute_vars(); int var_len[10]; char *var_ptr[10]; /***********************/ /* the #action command */ /***********************/ /* Priority code added by Joann Ellsworth 2/2/94 */ void action_command(arg, ses) char *arg; struct session *ses; { char left[BUFFER_SIZE], right[BUFFER_SIZE], result[BUFFER_SIZE]; char pr[BUFFER_SIZE]; struct listnode *myactions, *ln; myactions=(ses) ? ses->actions : common_actions; arg=get_arg_in_braces(arg, left, 0); arg=get_arg_in_braces(arg, right, 1); arg=get_arg_in_braces(arg, pr, 1); if (!*pr) strcpy(pr, "5"); /* defaults priority to 5 if no value given */ if(!*left) { tintin_puts2("#Defined actions:", ses); show_list_action(myactions); prompt(ses); } else if(*left && !*right) { if ((ln=search_node_with_wild(myactions,left))!=NULL) { while((myactions=search_node_with_wild(myactions, left))!=NULL) { shownode_list_action(myactions); } prompt(ses); } else if (mesvar[1]) 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, pr, PRIORITY); if (mesvar[1]) { sprintf(result,"#Ok. {%s} now triggers {%s} @ {%s}",left,right,pr); tintin_puts2(result, ses); } acnum++; } } /*************************/ /* the #unaction command */ /*************************/ void unaction_command(arg, ses) char *arg; struct session *ses; { char left[BUFFER_SIZE] ,result[BUFFER_SIZE]; struct listnode *myactions, *ln, *temp; int flag; flag=FALSE; myactions=(ses) ? ses->actions : common_actions; temp=myactions; arg=get_arg_in_braces(arg,left,1); while ((ln=search_node_with_wild(temp, left))!=NULL) { if (mesvar[1]) { sprintf(result,"#Ok. {%s} is no longer a trigger.",ln->left); tintin_puts2(result, ses); } deletenode_list(myactions, ln); flag=TRUE; temp=ln; } if (!flag && mesvar[1]) { sprintf(result, "#No match(es) found for {%s}", left); tintin_puts2(result, 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(string, result, ses) char *string; char *result; struct session *ses; { char arg[BUFFER_SIZE]; *result='\0'; substitute_vars(string,arg); substitute_myvars(arg, result, ses); } /*************************************************************************/ /* copy the arg text into the result-space, but substitute the variables */ /* %0..%9 with the real variables */ /*************************************************************************/ void substitute_vars(arg, result) char *arg; char *result; { int nest=0; int numands,n; char *ptr; while(*arg) { if(*arg=='%') { /* substitute variable */ numands=0; while(*(arg+numands)=='%') numands++; if (isdigit(*(arg+numands)) && numands==(nest+1)) { n=*(arg+numands)-'0'; strcpy(result,vars[n]); arg=arg+numands+1; result+=strlen(vars[n]); } else { strncpy(result,arg,numands+1); arg+=numands+1; result+=numands+1; } } if(*arg=='$') { /* substitute variable */ numands=0; while(*(arg+numands)=='$') numands++; if (isdigit(*(arg+numands)) && numands==(nest+1)) { n=*(arg+numands)-'0'; ptr=vars[n]; while (*ptr) { if (*ptr==';') ptr++; else *result++=*ptr++; } arg=arg+numands+1; } else { strncpy(result,arg,numands); arg+=numands; result+=numands; } } else if (*arg==DEFAULT_OPEN) { nest++; *result++=*arg++; } else if (*arg==DEFAULT_CLOSE) { nest--; *result++=*arg++; } else if (*arg=='\\' && nest==0) { while(*arg=='\\') *result++=*arg++; if(*arg=='%') { result--; *result++=*arg++; *result++=*arg++; } } else *result++=*arg++; } *result='\0'; } /**********************************************/ /* check actions from a sessions against line */ /**********************************************/ void check_all_actions(line, ses) char *line; struct session *ses; { struct listnode *ln; static char temp[BUFFER_SIZE]=PROMPT_FOR_PW_TEXT; char strng[BUFFER_SIZE]; if(check_one_action(line, temp, ses) && ses==activesession) { term_noecho(); term_echoing=FALSE; } ln=(ses) ? ses->actions : common_actions; while(( ln=ln->next )) { if(check_one_action(line, ln->left,ses)) { char buffer[BUFFER_SIZE]; prepare_actionalias(ln->right, buffer,ses); if(echo && activesession==ses) { sprintf(strng, "[ACTION: %s]", buffer); tintin_puts2(strng, activesession); } parse_input(buffer, ses); return; } } } int match_a_string(line, mask) char *line; char *mask; { char *lptr, *mptr; lptr=line; mptr=mask; while (*lptr && *mptr && !(*mptr=='%' && isdigit(*(mptr+1)))) { if (*lptr++!=*mptr++) return -1; } if (!*mptr || (*mptr=='%' && isdigit(*(mptr+1)))) { return (int)(lptr-line); } return -1; } int check_one_action(line, action, ses) char *line; char *action; struct session *ses; { int i; if (check_a_action(line,action,ses)) { for(i=0; i<10; i++) { if (var_len[i]!=-1) { strncpy(vars[i], var_ptr[i], var_len[i]); *(vars[i]+var_len[i])='\0'; } } return TRUE; } else return FALSE; } /******************************************************************/ /* check if a text triggers an action and fill into the variables */ /* return TRUE if triggered */ /******************************************************************/ int check_a_action(line, action, ses) char *line; char *action; struct session *ses; { char result[BUFFER_SIZE]; char *temp2, *tptr, *lptr, *lptr2; int i,flag_anchor, count, len, flag; for (i=0; i<10; i++) var_len[i]=-1; flag_anchor=FALSE; lptr=line; substitute_myvars(action,result,ses); tptr=result; if(*tptr=='^') { tptr++; flag_anchor=TRUE; if (*tptr!=*line) return FALSE; } if (flag_anchor) { if ((len=match_a_string(lptr, tptr))==-1) return FALSE; lptr+=len; tptr+=len; } else { flag=TRUE; len=-1; while(*lptr && flag) { if((len=match_a_string(lptr, tptr))!=-1) { flag=FALSE; } else lptr++; } if (len!=-1) { lptr+=len; tptr+=len; } else return FALSE; } while(*lptr && *tptr) { temp2=tptr+2; if (!*temp2) { var_len[*(tptr+1)-48]=strlen(lptr); var_ptr[*(tptr+1)-48]=lptr; return TRUE; } lptr2=lptr; flag=TRUE; len=-1; while(*lptr2 && flag) { if ((len=match_a_string(lptr2, temp2))!=-1) { flag=FALSE; } else lptr2++; } if (len!=-1) { var_len[*(tptr+1)-48]=lptr2-lptr; var_ptr[*(tptr+1)-48]=lptr; lptr=lptr2+len; tptr=temp2+len; } else { return FALSE; } } if (*tptr) return FALSE; else return TRUE; }