/* stuff for adding commands via Tcl on the fly */ #if HAVE_CONFIG_H #include #endif #include #include #include #include "../lush.h" #include "eggdrop.h" #include "proto.h" /* types of commands */ #define CMD_MSG 0 #define CMD_DCC 1 #define CMD_FIL 2 #define CMD_PUB 3 #define CMD_MSGM 4 #define CMD_PUBM 5 #define CMD_JOIN 6 #define CMD_PART 7 #define CMD_SIGN 8 #define CMD_KICK 9 #define CMD_TOPC 10 #define CMD_MODE 11 #define CMD_CTCP 12 #define CMD_CTCR 13 #define CMD_NICK 14 #define CMD_RAW 15 #define CMD_BOT 16 extern Tcl_Interp *interp; extern int dcc_total; extern struct dcc_t dcc[]; extern int require_x,require_p; #define CMD_LEAVE (Function)(-1) typedef int (*Function)(); typedef struct { char *name; Function func; int access; } cmd_t; extern cmd_t C_msg[],C_dcc[],C_file[]; /* extra commands are stored in Tcl hash tables (one hash table for each type of command: msg, dcc, etc) */ typedef struct { int flags_needed; char *func_name; } tcl_cmd_t; Tcl_HashTable H_msg, H_dcc, H_fil, H_pub, H_msgm, H_pubm, H_join, H_part, H_sign, H_kick, H_topc, H_mode, H_ctcp, H_ctcr, H_nick, H_raw, H_bot; int hashtot=0; int expmem_tclhash() { return hashtot; } /* initialize hash tables */ init_hash() { Tcl_InitHashTable(&H_msg,TCL_STRING_KEYS); Tcl_InitHashTable(&H_dcc,TCL_STRING_KEYS); Tcl_InitHashTable(&H_fil,TCL_STRING_KEYS); Tcl_InitHashTable(&H_pub,TCL_STRING_KEYS); Tcl_InitHashTable(&H_msgm,TCL_STRING_KEYS); Tcl_InitHashTable(&H_pubm,TCL_STRING_KEYS); Tcl_InitHashTable(&H_join,TCL_STRING_KEYS); Tcl_InitHashTable(&H_part,TCL_STRING_KEYS); Tcl_InitHashTable(&H_sign,TCL_STRING_KEYS); Tcl_InitHashTable(&H_kick,TCL_STRING_KEYS); Tcl_InitHashTable(&H_topc,TCL_STRING_KEYS); Tcl_InitHashTable(&H_mode,TCL_STRING_KEYS); Tcl_InitHashTable(&H_ctcp,TCL_STRING_KEYS); Tcl_InitHashTable(&H_ctcr,TCL_STRING_KEYS); Tcl_InitHashTable(&H_nick,TCL_STRING_KEYS); Tcl_InitHashTable(&H_raw,TCL_STRING_KEYS); Tcl_InitHashTable(&H_bot,TCL_STRING_KEYS); } void *tclcmd_alloc(size) int size; { tcl_cmd_t *x=(tcl_cmd_t *)nmalloc(sizeof(tcl_cmd_t)); hashtot+=sizeof(tcl_cmd_t); x->func_name=(char *)nmalloc(size); hashtot+=size; return (void *)x; } /* returns hashtable for that type */ /* also sets 'stk' if stackable, and sets 'name' the name, if non-NULL */ Tcl_HashTable *gethashtable(typ,stk,name) int typ,*stk; char *name; { char *nam; int st=0; Tcl_HashTable *ht; switch(typ) { case CMD_MSG: ht=&H_msg; nam="msg"; break; case CMD_DCC: ht=&H_dcc; nam="dcc"; break; case CMD_FIL: ht=&H_fil; nam="fil"; break; case CMD_PUB: ht=&H_pub; nam="pub"; break; case CMD_MSGM: ht=&H_msgm; nam="msgm"; st=1; break; case CMD_PUBM: ht=&H_pubm; nam="pubm"; st=1; break; case CMD_JOIN: ht=&H_join; nam="join"; st=1; break; case CMD_PART: ht=&H_part; nam="part"; st=1; break; case CMD_SIGN: ht=&H_sign; nam="sign"; st=1; break; case CMD_KICK: ht=&H_kick; nam="kick"; st=1; break; case CMD_TOPC: ht=&H_topc; nam="topc"; st=1; break; case CMD_MODE: ht=&H_mode; nam="mode"; st=1; break; case CMD_CTCP: ht=&H_ctcp; nam="ctcp"; break; case CMD_CTCR: ht=&H_ctcr; nam="ctcr"; break; case CMD_NICK: ht=&H_nick; nam="nick"; st=1; break; case CMD_RAW: ht=&H_raw; nam="raw"; st=1; break; case CMD_BOT: ht=&H_bot; nam="bot"; break; } if (name!=NULL) strcpy(name,nam); if (stk!=NULL) *stk=st; return ht; } /* remove command */ int cmd_unbind(typ,flags,cmd,proc) int typ,flags; char *cmd,*proc; { tcl_cmd_t *tt; Tcl_HashEntry *he; Tcl_HashTable *ht; char *pr,*p; for (p=proc; *p!=0; p++) if (*p==' ') *p='_'; /* no spaces! */ ht=gethashtable(typ,NULL,NULL); he=Tcl_FindHashEntry(ht,cmd); if (he==NULL) return 0; /* no such binding */ tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (tt->flags_needed != flags) return 0; /* incorrect flags */ pr=tt->func_name; while (pr!=NULL) { p=strchr(pr,' '); if (p!=NULL) *p=0; if (strcasecmp(pr,proc)==0) { /* erase it */ char *n; int len=0; if (tt->func_name != pr) { /* this wasn't the first entry, so save the older entries */ *(pr-1)=0; len+=strlen(tt->func_name); *(pr-1)=' '; } if (p!=NULL) len+=strlen(p+1); /* save upcoming entries */ if ((p!=NULL) && (tt->func_name!=pr)) len++; /* middle space */ if (len==0) { /* this was the only entry */ hashtot-=(strlen(tt->func_name)+1); nfree(tt->func_name); nfree(tt); hashtot-=sizeof(tcl_cmd_t); Tcl_DeleteHashEntry(he); return 1; } n=(char *)nmalloc(len+1); *n=0; /* now fill in n */ if (tt->func_name!=pr) { *(pr-1)=0; strcat(n,tt->func_name); *(pr-1)=' '; } if ((p!=NULL) && (tt->func_name!=pr)) strcat(n," "); if (p!=NULL) { strcat(n,p+1); *p=' '; } hashtot-=(strlen(tt->func_name)+1); nfree(tt->func_name); tt->func_name=n; hashtot+=len+1; return 1; } if (p!=NULL) { pr=p+1; *p=' '; } else pr=NULL; } return 0; /* no match */ } /* add command (remove old one if necessary) */ int cmd_bind(typ,flags,cmd,proc) int typ,flags; char *cmd,*proc; { tcl_cmd_t *tt; int new; Tcl_HashEntry *he; Tcl_HashTable *ht; char *p; int stk; for (p=proc; *p!=0; p++) if (*p==' ') *p='_'; /* no spaces! */ ht=gethashtable(typ,&stk,NULL); if (proc[0]!='#') { /* not a bogus proc */ tt=(tcl_cmd_t *)nmalloc(sizeof(tcl_cmd_t)); hashtot+=sizeof(tcl_cmd_t); tt->flags_needed=flags; tt->func_name=(char *)nmalloc(strlen(proc)+1); hashtot+=strlen(proc)+1; strcpy(tt->func_name,proc); } else tt=NULL; cmd_unbind(typ,flags,cmd,proc); /* make sure we don't dup */ he=Tcl_CreateHashEntry(ht,cmd,&new); if ((new) && (tt==NULL)) { /* erasing an entry that wasn't even there */ Tcl_DeleteHashEntry(he); } if (!new) { /* replace or append */ tcl_cmd_t *ttx=(tcl_cmd_t *)Tcl_GetHashValue(he); if ((stk) && (tt!=NULL)) { /* just append this new proc to the list then */ nfree(tt->func_name); hashtot-=(strlen(proc)+1); tt->func_name=(char *)nmalloc(strlen(proc)+strlen(ttx->func_name)+2); hashtot+=strlen(proc)+strlen(ttx->func_name)+2; strcpy(tt->func_name,ttx->func_name); strcat(tt->func_name," "); strcat(tt->func_name,proc); } hashtot-=(strlen(ttx->func_name)+1); hashtot-=sizeof(tcl_cmd_t); nfree(ttx->func_name); nfree(ttx); Tcl_DeleteHashEntry(he); if (tt!=NULL) he=Tcl_CreateHashEntry(ht,cmd,&new); } if (tt!=NULL) Tcl_SetHashValue(he,tt); return 1; } /* check for tcl-bound msg command, return 1 if found */ /* msg: proc-name */ int check_tcl_msg(cmd,nick,uhost,hand,args) char *cmd,*nick,*uhost,*hand,*args; { Tcl_HashSearch srch; Tcl_HashEntry *he; int cnt=0; char *proc; tcl_cmd_t *tt; int f=0,atr; atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_msg,&srch); (he!=NULL) && (!f); he=Tcl_NextHashEntry(&srch)) { if (strncasecmp(cmd,Tcl_GetHashKey(&H_msg,he),strlen(cmd))==0) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { /* flags match */ cnt++; proc=tt->func_name; if (strcasecmp(cmd,Tcl_GetHashKey(&H_msg,he))==0) { cnt=1; f=1; /* perfect match */ } } } } if (cnt!=1) return 0; /* >1 ambigious; 0 not found */ if (proc[0]=='*') { /* calling builtin function */ int top=0,bot=0,try,xx; char pr[81]; strcpy(pr,&proc[1]); f=0; while (C_msg[bot].access!=(-1)) bot++; /* find bottom */ /* binary search: */ while (!f) { try=(top+bot)/2; xx=strcasecmp(C_msg[try].name,pr); if (xx==0) f=1; if (xx<0) top=try+1; if (xx>0) bot=try; if (top==bot) { log(LOG_MISC,"Tcl error [%s]: no such builtin function",proc); return 1; } } return (C_msg[try].func)(hand,nick,uhost,args); } set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",args,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); if (atoi(interp->result)>0) log(LOG_CMDS,"(%s!%s) !%s! %s %s",nick,uhost,hand,cmd,args); } return 1; } /* check for tcl-bound dcc command, return 1 if found */ /* dcc: proc-name */ int check_tcl_dcc(cmd,idx,args) char *cmd,*args; int idx; { Tcl_HashSearch srch; Tcl_HashEntry *he; int cnt=0; char *proc; tcl_cmd_t *tt; int f=0; char s[20]; for (he=Tcl_FirstHashEntry(&H_dcc,&srch); (he!=NULL) && (!f); he=Tcl_NextHashEntry(&srch)) { if (strncasecmp(cmd,Tcl_GetHashKey(&H_dcc,he),strlen(cmd))==0) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,get_attr_handle(dcc[idx].nick))) { cnt++; proc=tt->func_name; if (strcasecmp(cmd,Tcl_GetHashKey(&H_dcc,he))==0) { cnt=1; f=1; /* perfect match */ } } } } if (cnt>1) { tprintf(dcc[idx].sock,"Ambigious command.\n"); return 0; } if (cnt==0) { tprintf(dcc[idx].sock,"What? Try '.help'\n"); return 0; /* not found */ } if (proc[0]=='*') { /* calling builtin function */ int top=0,bot=0,try,xx; char pr[81]; strcpy(pr,&proc[1]); f=0; while (C_dcc[bot].access!=(-1)) bot++; /* find bottom */ /* binary search: */ while (!f) { try=(top+bot)/2; xx=strcasecmp(C_dcc[try].name,pr); if (xx==0) f=1; if (xx<0) top=try+1; if (xx>0) bot=try; if (top==bot) { log(LOG_MISC,"Tcl error [%s]: no such builtin function",proc); return 0; } } if (C_dcc[try].func == CMD_LEAVE) return 1; (C_dcc[try].func)(idx,args); return 0; } set_tcl_vars(); sprintf(s,"%d",dcc[idx].sock); Tcl_SetVar(interp,"_n",dcc[idx].nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_i",s,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",args,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_i $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); if (atoi(interp->result)>0) log(LOG_CMDS,"#%s# %s %s",dcc[idx].nick,cmd,args); } return 0; } /* check for tcl-bound file command, return 1 if found */ /* fil: proc-name */ int check_tcl_fil(cmd,idx,args) char *cmd,*args; int idx; { Tcl_HashSearch srch; Tcl_HashEntry *he; int cnt=0; char *proc; tcl_cmd_t *tt; int f=0; char s[20]; for (he=Tcl_FirstHashEntry(&H_fil,&srch); (he!=NULL) && (!f); he=Tcl_NextHashEntry(&srch)) { if (strncasecmp(cmd,Tcl_GetHashKey(&H_fil,he),strlen(cmd))==0) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,get_attr_handle(dcc[idx].nick))) { cnt++; proc=tt->func_name; if (strcasecmp(cmd,Tcl_GetHashKey(&H_fil,he))==0) { cnt=1; f=1; /* perfect match */ } } } } if (cnt>1) { tprintf(dcc[idx].sock,"Ambigious command.\n"); return 0; } if (cnt==0) { tprintf(dcc[idx].sock,"What? Try 'help'\n"); return 0; /* not found */ } if (proc[0]=='*') { /* calling builtin function */ int top=0,bot=0,try,xx; char pr[81]; strcpy(pr,&proc[1]); f=0; while (C_file[bot].access!=(-1)) bot++; /* find bottom */ /* binary search: */ while (!f) { try=(top+bot)/2; xx=strcasecmp(C_file[try].name,pr); if (xx==0) f=1; if (xx<0) top=try+1; if (xx>0) bot=try; if (top==bot) { log(LOG_MISC,"Tcl error [%s]: no such builtin function",proc); return 0; } } if (C_file[try].func == CMD_LEAVE) return 1; (C_file[try].func)(idx,args); return 0; } set_tcl_vars(); sprintf(s,"%d",dcc[idx].sock); Tcl_SetVar(interp,"_n",dcc[idx].nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_i",s,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",args,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_i $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); if (atoi(interp->result)>0) log(LOG_FILES,"#%s# files: %s %s",dcc[idx].nick,cmd,args); } return 1; } int check_tcl_pub(nick,from,msg) char *nick,*from,*msg; { char s[20],args[512],cmd[512],handle[21],host[161]; Tcl_HashSearch srch; Tcl_HashEntry *he; int f=0; tcl_cmd_t *tt; char *proc; strcpy(args,msg); nsplit(cmd,args); sprintf(host,"%s!%s",nick,from); for (he=Tcl_FirstHashEntry(&H_pub,&srch); (he!=NULL) && (!f); he=Tcl_NextHashEntry(&srch)) { if (strcasecmp(cmd,Tcl_GetHashKey(&H_pub,he))==0) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); get_handle_by_host(handle,host); if (flags_ok(tt->flags_needed,get_attr_handle(handle))) { f=1; proc=tt->func_name; } } } if (!f) return 0; /* not found */ set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",from,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",handle,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",args,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); if (atoi(interp->result)>0) log(LOG_CMDS,"<<%s>> !%s! %s %s",nick,handle,cmd,args); } return 1; } int check_tcl_pubm(nick,from,msg) char *nick,*from,*msg; { char args[512],host[161],handle[21],*proc,*p; int atr,f=0; Tcl_HashEntry *he; Tcl_HashSearch srch; tcl_cmd_t *tt; strcpy(args,msg); sprintf(host,"%s!%s",nick,from); for (he=Tcl_FirstHashEntry(&H_pubm,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_pubm,he),args)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); get_handle_by_host(handle,host); atr=get_attr_handle(handle); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",from,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",handle,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",args,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } } return f; } int check_tcl_msgm(cmd,nick,uhost,hand,arg) char *cmd,*nick,*uhost,*hand,*arg; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0,atr; tcl_cmd_t *tt; char args[512]; if (arg[0]) sprintf(args,"%s %s",cmd,arg); else strcpy(args,cmd); atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_msgm,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_msgm,he),args)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",args,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } } return f; } int check_tcl_join(nick,uhost,hand) char *nick,*uhost,*hand; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0,atr; tcl_cmd_t *tt; char args[512]; sprintf(args,"%s!%s",nick,uhost); atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_join,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_join,he),args)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } } return f; } int check_tcl_part(nick,uhost,hand) char *nick,*uhost,*hand; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0,atr; tcl_cmd_t *tt; char args[512]; sprintf(args,"%s!%s",nick,uhost); atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_part,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_part,he),args)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } } return f; } int check_tcl_sign(nick,uhost,hand,reason) char *nick,*uhost,*hand,*reason; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0,atr; tcl_cmd_t *tt; char args[512]; sprintf(args,"%s!%s",nick,uhost); atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_sign,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_sign,he),args)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",reason,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } } return f; } int check_tcl_topc(nick,uhost,hand,topic) char *nick,*uhost,*hand,*topic; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0,atr; tcl_cmd_t *tt; atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_topc,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_topc,he),topic)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",topic,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } } return f; } int check_tcl_nick(nick,uhost,hand,newnick) char *nick,*uhost,*hand,*newnick; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0,atr; tcl_cmd_t *tt; atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_nick,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_nick,he),newnick)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",newnick,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } } return f; } int check_tcl_kick(nick,uhost,hand,dest,reason) char *nick,*uhost,*hand,*dest,*reason; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0; tcl_cmd_t *tt; for (he=Tcl_FirstHashEntry(&H_kick,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_kick,he),dest)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",dest,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_aa",reason,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a $_aa",NULL) ==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } return f; } int check_tcl_raw(raw) char *raw; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0; tcl_cmd_t *tt; for (he=Tcl_FirstHashEntry(&H_raw,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_raw,he),raw)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_a",raw,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } return f; } int check_tcl_tand(nick,code,param) char *nick,*code,*param; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc; int f=0; tcl_cmd_t *tt; for (he=Tcl_FirstHashEntry(&H_bot,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (strcasecmp(Tcl_GetHashKey(&H_bot,he),code)==0) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); proc=tt->func_name; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",code,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",param,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } } } return f; } int check_tcl_mode(nick,uhost,hand,mode) char *nick,*uhost,*hand,*mode; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc,*p; int f=0; tcl_cmd_t *tt; for (he=Tcl_FirstHashEntry(&H_mode,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_mode,he),mode)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); proc=tt->func_name; while (proc!=NULL) { p=strchr(proc,' '); if (p!=NULL) *p=0; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",mode,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } if (p!=NULL) { proc=p+1; *p=' '; } else proc=NULL; } } } return f; } int check_tcl_ctcp(nick,uhost,hand,dest,keyword,args) char *nick,*uhost,*hand,*dest,*keyword,*args; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc; int f=0,atr; tcl_cmd_t *tt; atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_ctcp,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_ctcp,he),keyword)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",dest,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_aa",keyword,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_aaa",keyword,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a $_aa $_aaa",NULL) ==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } } } } return f; } int check_tcl_ctcr(nick,uhost,hand,dest,keyword,args) char *nick,*uhost,*hand,*dest,*keyword,*args; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc; int f=0,atr; tcl_cmd_t *tt; atr=get_attr_handle(hand); for (he=Tcl_FirstHashEntry(&H_ctcr,&srch); he!=NULL; he=Tcl_NextHashEntry(&srch)) { if (wild_match_per(Tcl_GetHashKey(&H_ctcr,he),keyword)) { tt=(tcl_cmd_t *)Tcl_GetHashValue(he); if (flags_ok(tt->flags_needed,atr)) { proc=tt->func_name; set_tcl_vars(); Tcl_SetVar(interp,"_n",nick,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_uh",uhost,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_h",hand,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",dest,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_aa",keyword,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_aaa",keyword,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,proc," $_n $_uh $_h $_a $_aa $_aaa",NULL) ==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",proc,interp->result); } else { get_tcl_vars(); f=1; } } } } return f; } void tell_binds(z) int z; { Tcl_HashEntry *he; Tcl_HashSearch srch; Tcl_HashTable *ht; int i,fnd=0; tcl_cmd_t *tt; char *proc,typ[5],*s,flg[20]; for (i=0; i<17; i++) { ht=gethashtable(i,NULL,typ); for (he=Tcl_FirstHashEntry(ht,&srch); (he!=NULL); he=Tcl_NextHashEntry(&srch)) { if (!fnd) { tprintf(z,"Command bindings:\n"); fnd=1; tprintf(z," TYPE FLGS COMMAND BINDING (TCL)\n"); } tt=(tcl_cmd_t *)Tcl_GetHashValue(he); flags2str(tt->flags_needed,flg); s=Tcl_GetHashKey(ht,he); if (strcasecmp(s,&tt->func_name[1])!=0) tprintf(z," %-4s %-4s %-20s %s\n",typ,flg,s,tt->func_name); } } if (!fnd) tprintf(z,"No command bindings.\n"); } int call_tcl_func(name,idx,args) char *name,*args; int idx; { char s[11]; set_tcl_vars(); sprintf(s,"%d",idx); Tcl_SetVar(interp,"_n",s,TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"_a",args,TCL_GLOBAL_ONLY); if (Tcl_VarEval(interp,name," $_n $_a",NULL)==TCL_ERROR) { log(LOG_MISC,"Tcl error [%s]: %s",name,interp->result); return -1; } get_tcl_vars(); return (atoi(interp->result)); }