/* stuff for adding commands via Tcl on the fly */ #include #include #include #include "tcl.h" #include "eggdrop.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_NICK 13 #define CMD_RAW 14 #define CMD_BOT 15 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_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_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; } /* 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; switch(typ) { case CMD_MSG: ht=&H_msg; break; case CMD_DCC: ht=&H_dcc; break; case CMD_FIL: ht=&H_fil; break; case CMD_PUB: ht=&H_pub; break; case CMD_MSGM: ht=&H_msgm; break; case CMD_PUBM: ht=&H_pubm; break; case CMD_JOIN: ht=&H_join; break; case CMD_PART: ht=&H_part; break; case CMD_SIGN: ht=&H_sign; break; case CMD_KICK: ht=&H_kick; break; case CMD_TOPC: ht=&H_topc; break; case CMD_MODE: ht=&H_mode; break; case CMD_CTCP: ht=&H_mode; break; case CMD_NICK: ht=&H_nick; break; case CMD_RAW: ht=&H_raw; break; case CMD_BOT: ht=&H_bot; break; } 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; he=Tcl_CreateHashEntry(ht,cmd,&new); if ((new) && (tt==NULL)) { /* erasing an entry that wasn't even there */ Tcl_DeleteHashEntry(he); } if (!new) { /* remove old entry */ tcl_cmd_t *ttx=(tcl_cmd_t *)Tcl_GetHashValue(he); 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,dcc[idx].sock,args); return 0; } set_tcl_vars(); sprintf(s,"%d",idx); 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,dcc[idx].sock,args); return 0; } set_tcl_vars(); sprintf(s,"%d",idx); 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; 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; 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; } } } } 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; 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; 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; } } } } return f; } int check_tcl_join(nick,uhost,hand) char *nick,*uhost,*hand; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc; 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; 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; } } } } return f; } int check_tcl_part(nick,uhost,hand) char *nick,*uhost,*hand; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc; 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; 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; } } } } return f; } int check_tcl_sign(nick,uhost,hand,reason) char *nick,*uhost,*hand,*reason; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc; 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; 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; } } } } return f; } int check_tcl_topc(nick,uhost,hand,topic) char *nick,*uhost,*hand,*topic; { 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_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; 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; } } } } return f; } int check_tcl_nick(nick,uhost,hand,newnick) char *nick,*uhost,*hand,*newnick; { 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_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; 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; } } } } 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; 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; 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; } } } return f; } int check_tcl_raw(raw) char *raw; { Tcl_HashSearch srch; Tcl_HashEntry *he; char *proc; 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; 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; } } } 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; } 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,*s,flg[20]; for (i=0; i<16; i++) { switch (i) { case 0: ht=&H_msg; typ="msg"; break; case 1: ht=&H_dcc; typ="dcc"; break; case 2: ht=&H_fil; typ="fil"; break; case 3: ht=&H_pub; typ="pub"; break; case 4: ht=&H_msgm; typ="msgm"; break; case 5: ht=&H_pubm; typ="pubm"; break; case 6: ht=&H_join; typ="join"; break; case 7: ht=&H_part; typ="part"; break; case 8: ht=&H_sign; typ="sign"; break; case 9: ht=&H_kick; typ="kick"; break; case 10: ht=&H_topc; typ="topc"; break; case 11: ht=&H_mode; typ="mode"; break; case 12: ht=&H_ctcp; typ="ctcp"; break; case 13: ht=&H_nick; typ="nick"; break; case 14: ht=&H_raw; typ="raw"; break; case 15: ht=&H_bot; typ="bot"; break; } 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,hand,args) char *name,*hand,*args; { set_tcl_vars(); Tcl_SetVar(interp,"_n",hand,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)); }