/* tcl.c -- handles: the code for every command eggdrop adds to Tcl Tcl initialization getting and setting Tcl/eggdrop variables dprintf'ized, 4feb96 */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include "../lush.h" #include "eggdrop.h" #include "users.h" #include "chan.h" #include "proto.h" #include "cmdt.h" #include "tclegg.h" /* eggdrop always uses the same interpreter */ Tcl_Interp *interp; extern int curserv, serv; extern int shtime, require_x, learn_users, share_users, use_info, passive, strict_host, require_p, isolate, keep_all_logs, copy_to_tmp, use_stderr, upload_to_cd, never_give_up, allow_new_telnets, keepnick; extern int telnet_port, botserverport, min_servs, helpserverport, default_flags, conmask, newserverport, dcc_block, dcc_limit, dcc_maxsize, dcc_users, save_users_at, switch_logfiles_at, telnet_bots_only, server_timeout, connect_timeout; extern char *logfile[]; extern char *logchan[]; extern int logmask[]; extern int flood_thr, flood_pub_thr, flood_join_thr, ban_time, ignore_time; extern char botname[], origbotname[], botuser[], botrealname[], botserver[], dccdir[], dccin[], motdfile[], admin[], userfile[], helpdir[], initserver[], notify_new[], notefile[], botuserhost[], tempdir[], newserver[], textdir[], ctcp_version[], ctcp_finger[], ctcp_userinfo[], owner[], newserverpass[]; extern char flag1, flag2, flag3, flag4, flag5, flag6, flag7, flag8, flag9, flag0; extern char cx_file[]; extern int cx_line; extern int online; extern struct userrec *userlist; extern struct eggqueue *serverlist; extern struct dcc_t dcc[]; extern int dcc_total; extern struct chanset_t *chanset; extern char egg_version[]; extern tcl_timer_t *timer,*utimer; /* prototypes for tcl */ Tcl_Interp *Tcl_CreateInterp(); int expmem_tcl() { int i,tot=0; for (i=0; i(nh))) { \ Tcl_AppendResult(irp,"wrong # args: should be \"",argv[0], \ (example),"\"",NULL); \ return TCL_ERROR; \ } /* logfile [ ] */ int tcl_logfile STDVAR { int i; char s[151]; BADARGS(1,4," ?logModes channel logFile?"); if (argc==1) { /* they just want a list of the logfiles and modes */ for (i=0; ichannel.member; if (argc==2) { /* no flag restrictions so just whiz it thru quick */ while (m->nick[0]) { Tcl_AppendElement(irp,m->nick); m=m->next; } return TCL_OK; } f=str2flags(argv[2]); /* return empty set if asked for flags but flags don't exist */ if ((f==0) && (argv[2][0]) && (argv[2][0]!='-')) return TCL_OK; while (m->nick[0]) { if (m->user==NULL) { sprintf(s1,"%s!%s",m->nick,m->userhost); get_handle_by_host(handle,s1); /* updates m->user */ } if (m->user==NULL) atr=0; else atr=m->user->flags; if ((atr & f)==f) Tcl_AppendElement(irp,m->nick); m=m->next; } return TCL_OK; } int tcl_putserv STDVAR { char s[512],*p; BADARGS(2,2," text"); strncpy(s,argv[1],511); s[511]=0; p=strchr(s,'\n'); if (p!=NULL) *p=0; p=strchr(s,'\r'); if (p!=NULL) *p=0; mprintf(serv,"%s\n",s); return TCL_OK; } int tcl_puthelp STDVAR { char s[512],*p; BADARGS(2,2," text"); strncpy(s,argv[1],511); s[511]=0; p=strchr(s,'\n'); if (p!=NULL) *p=0; p=strchr(s,'\r'); if (p!=NULL) *p=0; hprintf(serv,"%s\n",s); return TCL_OK; } int findidx(z) int z; { int j; for (j=0; j5)) { Tcl_AppendResult(irp,"level out of range (must be 1-5)",NULL); return TCL_ERROR; } switch(i) { case 1: lev=LOG_LEV1; break; case 2: lev=LOG_LEV2; break; case 3: lev=LOG_LEV3; break; case 4: lev=LOG_LEV4; break; case 5: lev=LOG_LEV5; break; } strncpy(logtext,argv[3],500); logtext[500]=0; putlog(lev,argv[2],"%s",logtext); return TCL_OK; } int tcl_countusers STDVAR { char s[40]; BADARGS(1,1,""); sprintf(s,"%d",count_users(userlist)); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_validuser STDVAR { BADARGS(2,2," handle"); if (is_user(argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_finduser STDVAR { char s[20]; BADARGS(2,2," nick!user@host"); get_handle_by_host(s,argv[1]); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_passwdOk STDVAR { BADARGS(3,3," handle passwd"); if (pass_match_by_handle(argv[2],argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_chattr STDVAR { int atr,oatr,f,i,pos=1,recheck=0; char s[20]; struct chanset_t *chan; BADARGS(2,3," handle ?changes?"); if ((argv[1][0]=='*') || (!is_user(argv[1]))) { Tcl_AppendResult(irp,"*",NULL); return TCL_OK; } oatr=atr=get_attr_handle(argv[1]); if (argc==3) { /* make changes */ for (i=0; inext; } } return TCL_OK; } int tcl_matchattr STDVAR { int i,f,ok=1; char s[2]; BADARGS(3,3," handle flags"); for (i=0; iname,argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_isvoice STDVAR { struct chanset_t *chan; BADARGS(3,3," nick channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"illegal channel: ",argv[2],NULL); return TCL_ERROR; } if (member_voice(chan->name,argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_onchan STDVAR { struct chanset_t *chan; BADARGS(3,3," nickname channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"illegal channel: ",argv[2],NULL); return TCL_ERROR; } if (!ischanmember(chan->name,argv[1])) Tcl_AppendResult(irp,"0",NULL); else Tcl_AppendResult(irp,"1",NULL); return TCL_OK; } int tcl_handonchan STDVAR { struct chanset_t *chan; BADARGS(3,3," handle channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"illegal channel: ",argv[2],NULL); return TCL_ERROR; } if (!hand_on_chan(chan,argv[1])) Tcl_AppendResult(irp,"0",NULL); else Tcl_AppendResult(irp,"1",NULL); return TCL_OK; } int tcl_ischanban STDVAR { struct chanset_t *chan; BADARGS(3,3," ban channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"illegal channel: ",argv[2],NULL); return TCL_ERROR; } if (isbanned(chan,argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_getchanhost STDVAR { struct chanset_t *chan; char s[UHOSTLEN]; BADARGS(3,3," nickname channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"illegal channel: ",argv[2],NULL); return TCL_ERROR; } getchanhost(chan->name,argv[1],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_onchansplit STDVAR { struct chanset_t *chan; BADARGS(3,3," nickname channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"illegal channel: ",argv[2],NULL); return TCL_ERROR; } if (is_split(chan->name,argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_bind STDVAR { int fl,tp; BADARGS(5,5," type flags cmdName procName"); fl=str2flags(argv[2]); tp=get_bind_type(argv[1]); #ifndef USE_CONSOLE_R if (strcasecmp(argv[1],"raw")==0) { Tcl_AppendResult(irp,"can't use raw bindings unless you compile with ", "USE_CONSOLE_R",NULL); return TCL_ERROR; } #endif if (tp<0) { Tcl_AppendResult(irp,"bad type, should be one of: dcc, msg, fil, pub, ", "msgm, pubm, join, part, sign, kick, topc, mode, ctcp, ", "nick, bot, chon, chof, sent, rcvd, chat, link, disc, ", "splt, rejn, ", #ifdef USE_CONSOLE_R "raw", #endif NULL); return TCL_ERROR; } if ((long int)cd == 1) { if (!cmd_unbind(tp,fl,argv[3],argv[4])) { /* don't error if trying to re-unbind a builtin */ if (strcmp(argv[3],&argv[4][1])!=0) { Tcl_AppendResult(irp,"no such binding",NULL); return TCL_ERROR; } } } else cmd_bind(tp,fl,argv[3],argv[4]); Tcl_AppendResult(irp,argv[3],NULL); return TCL_OK; } int tcl_adduser STDVAR { BADARGS(3,3," handle hostmask"); if (is_user(argv[1])) { Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } userlist=adduser(userlist,argv[1],argv[2],"nopass",default_flags); Tcl_AppendResult(irp,"1",NULL); return TCL_OK; } int tcl_addbot STDVAR { BADARGS(3,3," handle address"); if (is_user(argv[1])) { Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } userlist=adduser(userlist,argv[1],"none","nopass",USER_BOT); set_handle_info(userlist,argv[1],argv[2]); Tcl_AppendResult(irp,"1",NULL); return TCL_OK; } int tcl_deluser STDVAR { char s[10]; BADARGS(2,2," handle"); sprintf(s,"%d",deluser(argv[1])); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_maskhost STDVAR { char new[121]; BADARGS(2,2," nick!user@host"); maskhost(argv[1],new); Tcl_AppendResult(irp,new,NULL); return TCL_OK; } int tcl_dccsimul STDVAR { int i,idx,atr; char cmd[512]; BADARGS(3,3," idx command"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if ((dcc[idx].type!=DCC_CHAT) && (dcc[idx].type!=DCC_FILES) && (dcc[idx].type!=DCC_SCRIPT)) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (strlen(argv[2])>510) argv[2][510]=0; /* restrict length of cmd */ strcpy(cmd,argv[2]); atr=get_attr_handle(dcc[idx].nick); set_attr_handle(dcc[idx].nick,atr|USER_OWNER); dcc_activity(dcc[idx].sock,cmd,strlen(cmd)); set_attr_handle(dcc[idx].nick,atr); /* if (got_dcc_cmd(idx,cmd)) { dcc_activity(dcc[idx].sock,".quit",5); } */ return TCL_OK; } int tcl_addhost STDVAR { BADARGS(3,3," handle hostmask"); addhost_by_handle(argv[1],argv[2]); return TCL_OK; } int tcl_delhost STDVAR { BADARGS(3,3," handle hostmask"); if (delhost_by_handle(argv[1],argv[2])) { Tcl_AppendResult(irp,"1",NULL); return TCL_OK; } Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_timer STDVAR { unsigned long x; char s[41]; BADARGS(3,3," minutes command"); if (atoi(argv[1]) <= 0) { Tcl_AppendResult(irp,"time value must be positive, nonzero",NULL); return TCL_ERROR; } if (argv[2][0]!='#') { x=add_timer(&timer,atoi(argv[1]),argv[2],0L); sprintf(s,"timer%lu",x); Tcl_AppendResult(irp,s,NULL); } return TCL_OK; } int tcl_utimer STDVAR { unsigned long x; char s[41]; BADARGS(3,3," seconds command"); if (atoi(argv[1]) <= 0) { Tcl_AppendResult(irp,"time value must be positive, nonzero",NULL); return TCL_ERROR; } if (argv[2][0]!='#') { x=add_timer(&utimer,atoi(argv[1]),argv[2],0L); sprintf(s,"timer%lu",x); Tcl_AppendResult(irp,s,NULL); } return TCL_OK; } int tcl_killtimer STDVAR { BADARGS(2,2," timerID"); if (strncmp(argv[1],"timer",5)!=0) { Tcl_AppendResult(irp,"argument is not a timerID",NULL); return TCL_ERROR; } if (remove_timer(&timer,atol(&argv[1][5]))) return TCL_OK; Tcl_AppendResult(irp,"invalid timerID",NULL); return TCL_ERROR; } int tcl_killutimer STDVAR { BADARGS(2,2," timerID"); if (strncmp(argv[1],"timer",5)!=0) { Tcl_AppendResult(irp,"argument is not a timerID",NULL); return TCL_ERROR; } if (remove_timer(&utimer,atol(&argv[1][5]))) return TCL_OK; Tcl_AppendResult(irp,"invalid timerID",NULL); return TCL_ERROR; } int tcl_unixtime STDVAR { char s[20]; time_t t; BADARGS(1,1,""); t=time(NULL); sprintf(s,"%lu",(unsigned long)t); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_time STDVAR { char s[81]; time_t t; BADARGS(1,1,""); t=time(NULL); strcpy(s,ctime(&t)); strcpy(s,&s[11]); s[5]=0; Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_date STDVAR { char s[81]; time_t t; BADARGS(1,1,""); t=time(NULL); strcpy(s,ctime(&t)); s[10]=s[24]=0; strcpy(s,&s[8]); strcpy(&s[8],&s[20]); strcpy(&s[2],&s[3]); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getinfo STDVAR { char s[161]; BADARGS(2,2," handle"); get_handle_info(argv[1],s); if (s[0]=='@') strcpy(s,&s[1]); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getdccdir STDVAR { char s[161]; BADARGS(2,2," handle"); get_handle_dccdir(argv[1],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getcomment STDVAR { char s[161]; BADARGS(2,2," handle"); get_handle_comment(argv[1],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getemail STDVAR { char s[161]; BADARGS(2,2," handle"); get_handle_email(argv[1],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getxtra STDVAR { BADARGS(2,2," handle"); Tcl_AppendResult(irp,get_handle_xtra(argv[1]),NULL); return TCL_OK; } int tcl_setinfo STDVAR { BADARGS(3,3," handle info"); set_handle_info(userlist,argv[1],argv[2]); return TCL_OK; } int tcl_setdccdir STDVAR { BADARGS(3,3," handle dccdir"); set_handle_dccdir(userlist,argv[1],argv[2]); return TCL_OK; } int tcl_setcomment STDVAR { BADARGS(3,3," handle comment"); set_handle_comment(userlist,argv[1],argv[2]); return TCL_OK; } int tcl_setemail STDVAR { BADARGS(3,3," handle email"); set_handle_email(userlist,argv[1],argv[2]); return TCL_OK; } int tcl_setxtra STDVAR { BADARGS(3,3," handle xtra"); set_handle_xtra(userlist,argv[1],argv[2]); return TCL_OK; } int tcl_delglban STDVAR { struct chanset_t *chan; BADARGS(2,2," ban"); if (unprog_ban(argv[1])>0) { chan=chanset; while (chan!=NULL) { if (me_op(chan)) add_mode(chan,'-','b',argv[1]); chan=chan->next; } Tcl_AppendResult(irp,"1",NULL); } else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_delban STDVAR { struct chanset_t *chan; BADARGS(3,3," ban channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } if (u_unprog_ban(chan->bans,argv[1])>0) { if (me_op(chan)) add_mode(chan,'-','b',argv[1]); Tcl_AppendResult(irp,"1",NULL); } else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_isban STDVAR { struct chanset_t *chan; int ok=0; BADARGS(2,3," ban ?channel?"); if (argc==3) { chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } if (u_equals_ban(chan->bans,argv[1])) ok=1; } if (equals_ban(argv[1])) ok=1; if (ok) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_ispermban STDVAR { struct chanset_t *chan; int ok=0; BADARGS(2,3," ban ?channel?"); if (argc==3) { chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } if (u_equals_ban(chan->bans,argv[1])==2) ok=1; } if (equals_ban(argv[1])==2) ok=1; if (ok) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_matchban STDVAR { struct chanset_t *chan; int ok=0; BADARGS(2,3," user!nick@host ?channel?"); if (argc==3) { chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } if (u_match_ban(chan,argv[1])) ok=1; } if (match_ban(argv[1])) ok=1; if (ok) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_addban STDVAR { time_t t=time(NULL); char ban[161],cmt[71]; struct chanset_t *chan; BADARGS(3,4," ban channel ?comment?"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } strncpy(ban,argv[1],160); ban[160]=0; if (argc==3) sprintf(cmt,"%s: no comment",origbotname); else { strcpy(cmt,origbotname); strcat(cmt,": "); strncpy(&cmt[strlen(cmt)],argv[3],59); cmt[70]=0; } u_prog_ban(chan->bans,ban,t,cmt); if (me_op(chan)) { add_mode(chan,'+','b',ban); recheck_channel(chan); } return TCL_OK; } int tcl_addglban STDVAR { char ban[161],cmt[71]; struct chanset_t *chan; BADARGS(2,3," ban ?comment?"); strncpy(ban,argv[1],160); ban[160]=0; if (argc==2) sprintf(cmt,"%s: no comment",origbotname); else { strcpy(cmt,origbotname); strcat(cmt,": "); strncpy(&cmt[strlen(cmt)],argv[2],59); cmt[70]=0; } prog_ban(ban,0L,cmt); chan=chanset; while (chan!=NULL) { if (me_op(chan)) { add_mode(chan,'+','b',ban); recheck_channel(chan); } chan=chan->next; } return TCL_OK; } int tcl_getlaston STDVAR { char s[21]; time_t t; BADARGS(2,2," handle"); get_handle_laston(argv[1],&t); sprintf(s,"%lu",t); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_setlaston STDVAR { BADARGS(2,2," handle"); set_handle_laston(argv[1],time(NULL)); return TCL_OK; } int tcl_timers STDVAR { BADARGS(1,1,""); list_timers(irp,timer); return TCL_OK; } int tcl_utimers STDVAR { BADARGS(1,1,""); list_timers(irp,utimer); return TCL_OK; } int tcl_jump STDVAR { BADARGS(1,4," ?server? ?port? ?pass?"); if (argc>=2) { strcpy(newserver,argv[1]); if (argc>=3) newserverport=atoi(argv[2]); else newserverport=6667; if (argc==4) strcpy(newserverpass,argv[3]); } tprintf(serv,"QUIT :changing servers\n"); sleep(1); killsock(serv); serv=(-1); return TCL_OK; } int tcl_ctime STDVAR { time_t tt; char s[81]; BADARGS(2,2," unixtime"); tt=(time_t)atol(argv[1]); strcpy(s,ctime(&tt)); s[strlen(s)-1]=0; Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_myip STDVAR { char s[21]; BADARGS(1,1,""); sprintf(s,"%lu",getmyip()); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_dccsend STDVAR { char s[5],sys[512],*nfn; int i; FILE *f; BADARGS(3,3," filename ircnick"); f=fopen(argv[1],"r"); if (f==NULL) { /* file not found */ Tcl_AppendResult(irp,"3",NULL); return TCL_OK; } fclose(f); nfn=strrchr(argv[1],'/'); if (nfn==NULL) nfn=argv[1]; else nfn++; if (at_limit(argv[2])) { /* queue that mother */ if (nfn==argv[1]) queue_file("*",nfn,"(script)",argv[2]); else { nfn--; *nfn=0; nfn++; sprintf(sys,"*%s",argv[1]); queue_file(sys,nfn,"(script)",argv[2]); } Tcl_AppendResult(irp,"4",NULL); return TCL_OK; } if (copy_to_tmp) { sprintf(sys,"%s%s",tempdir,nfn); /* new filename, in /tmp */ copyfile(argv[1],sys); } else strcpy(sys,argv[1]); i=raw_dcc_send(sys,argv[2],"*",argv[1]); if (i>0) wipe_tmp_filename(sys,-1); sprintf(s,"%d",i); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } /*int tcl_rehash STDVAR { BADARGS(1,1,""); rehash(); return TCL_OK; }*/ int tcl_rand STDVAR { unsigned long x; char s[41]; BADARGS(2,2," limit"); x=random()%(atol(argv[1])); sprintf(s,"%lu",x); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_dccbroadcast STDVAR { char msg[401]; BADARGS(2,2," message"); strncpy(msg,argv[1],400); msg[400]=0; chatout("*** %s\n",msg); tandout("chat %s %s\n",origbotname,msg); return TCL_OK; } int tcl_hand2idx STDVAR { int i; char s[10]; BADARGS(2,2," nickname"); for (i=0; iu.chat->channel); else sprintf(s,"%d",dcc[idx].u.chat->channel); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_setchan STDVAR { int idx,i,chan; BADARGS(3,3," idx channel"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if ((dcc[idx].type!=DCC_CHAT) && (dcc[idx].type!=DCC_SCRIPT)) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if ((argv[2][0]<'0') || (argv[2][0]>'9')) { if ((strcmp(argv[2],"-1")==0) || (strcasecmp(argv[2],"off")==0)) chan=(-1); else chan=get_assoc(argv[2]); if (chan < -1) { Tcl_AppendResult(irp,"channel name is invalid",NULL); return TCL_ERROR; } } else chan=atoi(argv[2]); if ((chan<-1) || (chan>99999)) { Tcl_AppendResult(irp,"channel out of range; must be -1 thru 99999",NULL); return TCL_ERROR; } if (dcc[idx].type==DCC_SCRIPT) dcc[idx].u.script->u.chat->channel=chan; else dcc[idx].u.chat->channel=chan; return TCL_OK; } int tcl_dccputchan STDVAR { int chan; char msg[401]; BADARGS(3,3," channel message"); chan=atoi(argv[1]); if ((chan<0) || (chan>99999)) { Tcl_AppendResult(irp,"channel out of range; must be 0 thru 99999",NULL); return TCL_ERROR; } strncpy(msg,argv[2],400); msg[400]=0; chanout2(chan,"%s\n",argv[2]); return TCL_OK; } int tcl_console STDVAR { int i,j,pls,arg; BADARGS(2,4," idx ?channel? ?console-modes?"); j=atoi(argv[1]); i=findidx(j); if (i<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (dcc[i].type!=DCC_CHAT) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } pls=1; for (arg=2; argcon_chan,argv[arg],80); dcc[i].u.chat->con_chan[80]=0; } else { if ((argv[arg][0]!='+') && (argv[arg][0]!='-')) dcc[i].u.chat->con_flags=0; for (j=0; jcon_flags|=logmodes(s); else dcc[i].u.chat->con_flags&=~logmodes(s); } } } } Tcl_AppendElement(irp,dcc[i].u.chat->con_chan); Tcl_AppendElement(irp,masktype(dcc[i].u.chat->con_flags)); return TCL_OK; } int tcl_echo STDVAR { int i,j; BADARGS(2,3," idx ?status?"); j=atoi(argv[1]); i=findidx(j); if (i<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (dcc[i].type!=DCC_CHAT) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (argc==3) { if (atoi(argv[2])) dcc[i].u.chat->status|=STAT_ECHO; else dcc[i].u.chat->status&=~STAT_ECHO; } if (dcc[i].u.chat->status&STAT_ECHO) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_control STDVAR { int idx,i; BADARGS(3,3," idx command"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if ((dcc[idx].type==DCC_CHAT) && (dcc[idx].u.chat->channel >= 0)) chanout2_but(idx,dcc[idx].u.chat->channel,"%s has gone.\n",dcc[idx].nick); set_script(idx); strncpy(dcc[idx].u.script->command,argv[2],120); dcc[idx].u.script->command[119]=0; return TCL_OK; } int tcl_killdcc STDVAR { int idx,i; BADARGS(2,2," idx"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if ((dcc[idx].type!=DCC_CHAT) && (dcc[idx].type!=DCC_FILES) && (dcc[idx].type!=DCC_SCRIPT)) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } killsock(dcc[idx].sock); lostdcc(idx); return TCL_OK; } int tcl_putbot STDVAR { int i; char msg[401]; BADARGS(3,3," botnick message"); i=nextbot(argv[1]); if (i<0) { Tcl_AppendResult(irp,"bot is not in the botnet",NULL); return TCL_ERROR; } strncpy(msg,argv[2],400); msg[400]=0; tprintf(dcc[i].sock,"zapf %s %s %s\n",origbotname,argv[1],msg); return TCL_OK; } int tcl_putallbots STDVAR { char msg[401]; BADARGS(2,2," message"); strncpy(msg,argv[1],400); msg[400]=0; tandout("zapf-broad %s %s\n",origbotname,msg); return TCL_OK; } int tcl_getchanidle STDVAR { memberlist *m; time_t now=time(NULL); struct chanset_t *chan; BADARGS(3,3," nickname channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } m=chan->channel.member; while (m->nick[0]) { if (strcasecmp(m->nick,argv[1])==0) { char s[20]; int x; x=(now-(m->last))/60; sprintf(s,"%d",x); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } m=m->next; } Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_idx2hand STDVAR { int i,idx; BADARGS(2,2," idx"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } Tcl_AppendResult(irp,dcc[idx].nick,NULL); return TCL_OK; } int tcl_userlist STDVAR { struct userrec *u=userlist; int f=0; BADARGS(1,2," ?flags?"); if (argc==2) { f=str2flags(argv[1]); if ((f==0) && (argv[1][0]) && (argv[1][0]!='-')) return TCL_OK; } while (u!=NULL) { if ((u->flags & f)==f) Tcl_AppendElement(interp,u->handle); u=u->next; } return TCL_OK; } int tcl_sendnote STDVAR { char s[5],from[21],to[21],msg[451]; BADARGS(4,4," from to message"); strncpy(from,argv[1],20); from[20]=0; strncpy(to,argv[2],20); to[20]=0; strncpy(msg,argv[3],450); msg[450]=0; sprintf(s,"%d",add_note(to,from,msg,-1,0)); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_save STDVAR { write_userfile(); return TCL_OK; } int tcl_reload STDVAR { reload(); return TCL_OK; } int tcl_bots STDVAR { int i; BADARGS(1,1,""); for (i=0; ichannel.ban; while (b->ban[0]) { Tcl_AppendElement(irp,b->ban); b=b->next; } return TCL_OK; } int tcl_gethosts STDVAR { struct userrec *u; struct eggqueue *q; BADARGS(2,2," handle"); u=get_user_by_handle(userlist,argv[1]); if (u==NULL) return TCL_OK; q=u->host; while (q!=NULL) { Tcl_AppendElement(irp,q->item); q=q->next; } return TCL_OK; } int tcl_hand2nick STDVAR { memberlist *m; char s[161],h[21]; struct chanset_t *chan; BADARGS(3,3," handle channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } m=chan->channel.member; while (m->nick[0]) { sprintf(s,"%s!%s",m->nick,m->userhost); get_handle_by_host(h,s); if (strcasecmp(h,argv[1])==0) { Tcl_AppendResult(irp,m->nick,NULL); return TCL_OK; } m=m->next; } return TCL_OK; /* blank */ } int tcl_nick2hand STDVAR { memberlist *m; char s[161],h[21]; struct chanset_t *chan; BADARGS(3,3," nick channel"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[2],NULL); return TCL_ERROR; } m=ismember(chan,argv[1]); if (m==NULL) return TCL_OK; sprintf(s,"%s!%s",m->nick,m->userhost); get_handle_by_host(h,s); Tcl_AppendResult(irp,h,NULL); return TCL_OK; } /* list of { idx nick host type } */ /* type: "chat", "files", "script" */ int tcl_dcclist STDVAR { int i,ok; char s[256],typ[10]; BADARGS(1,1,""); for (i=0; iidle_kick); Tcl_AppendElement(irp,s); Tcl_AppendElement(irp,chan->need_op); Tcl_AppendElement(irp,chan->need_invite); if (chan->stat&CHAN_CLEARBANS) Tcl_AppendElement(irp,"+clearbans"); else Tcl_AppendElement(irp,"-clearbans"); if (chan->stat&CHAN_ENFORCEBANS) Tcl_AppendElement(irp,"+enforcebans"); else Tcl_AppendElement(irp,"-enforcebans"); if (chan->stat&CHAN_DYNAMICBANS) Tcl_AppendElement(irp,"+dynamicbans"); else Tcl_AppendElement(irp,"-dynamicbans"); if (chan->stat&CHAN_NOUSERBANS) Tcl_AppendElement(irp,"-userbans"); else Tcl_AppendElement(irp,"+userbans"); if (chan->stat&CHAN_OPONJOIN) Tcl_AppendElement(irp,"+autoop"); else Tcl_AppendElement(irp,"-autoop"); if (chan->stat&CHAN_BITCH) Tcl_AppendElement(irp,"+bitch"); else Tcl_AppendElement(irp,"-bitch"); if (chan->stat&CHAN_GREET) Tcl_AppendElement(irp,"+greet"); else Tcl_AppendElement(irp,"-greet"); if (chan->stat&CHAN_PROTECTOPS) Tcl_AppendElement(irp,"+protectops"); else Tcl_AppendElement(irp,"-protectops"); if (chan->stat&CHAN_LOGSTATUS) Tcl_AppendElement(irp,"+statuslog"); else Tcl_AppendElement(irp,"-statuslog"); if (chan->stat&CHAN_STOPNETHACK) Tcl_AppendElement(irp,"+stopnethack"); else Tcl_AppendElement(irp,"-stopnethack"); return TCL_OK; } /* parse options for a channel */ int tcl_channel_modify(irp,chan,items,item) Tcl_Interp *irp; struct chanset_t *chan; int items; char **item; { int i; context; for (i=0; i=items) { Tcl_AppendResult(irp,"channel need-op needs argument",NULL); return TCL_ERROR; } strncpy(chan->need_op,item[i],120); chan->need_op[120]=0; } else if (strcmp(item[i],"need-invite")==0) { i++; if (i>=items) { Tcl_AppendResult(irp,"channel need-invite needs argument",NULL); return TCL_ERROR; } strncpy(chan->need_invite,item[i],120); chan->need_invite[120]=0; } else if (strcmp(item[i],"chanmode")==0) { i++; if (i>=items) { Tcl_AppendResult(irp,"channel chanmode needs argument",NULL); return TCL_ERROR; } if (strlen(item[i])>120) item[i][120]=0; set_mode_protect(chan,item[i]); } else if (strcmp(item[i],"idle-kick")==0) { i++; if (i>=items) { Tcl_AppendResult(irp,"channel idle-kick needs argument",NULL); return TCL_ERROR; } chan->idle_kick=atoi(item[i]); } else if (strcmp(item[i],"dont-idle-kick")==0) chan->idle_kick=0; else if (strcmp(item[i],"+clearbans")==0) chan->stat|=CHAN_CLEARBANS; else if (strcmp(item[i],"-clearbans")==0) chan->stat&=~CHAN_CLEARBANS; else if (strcmp(item[i],"+enforcebans")==0) chan->stat|=CHAN_ENFORCEBANS; else if (strcmp(item[i],"-enforcebans")==0) chan->stat&=~CHAN_ENFORCEBANS; else if (strcmp(item[i],"+dynamicbans")==0) chan->stat|=CHAN_DYNAMICBANS; else if (strcmp(item[i],"-dynamicbans")==0) chan->stat&=~CHAN_DYNAMICBANS; else if (strcmp(item[i],"-userbans")==0) chan->stat|=CHAN_NOUSERBANS; else if (strcmp(item[i],"+userbans")==0) chan->stat&=~CHAN_NOUSERBANS; else if (strcmp(item[i],"+autoop")==0) chan->stat|=CHAN_OPONJOIN; else if (strcmp(item[i],"-autoop")==0) chan->stat&=~CHAN_OPONJOIN; else if (strcmp(item[i],"+bitch")==0) chan->stat|=CHAN_BITCH; else if (strcmp(item[i],"-bitch")==0) chan->stat&=~CHAN_BITCH; else if (strcmp(item[i],"+greet")==0) chan->stat|=CHAN_GREET; else if (strcmp(item[i],"-greet")==0) chan->stat&=~CHAN_GREET; else if (strcmp(item[i],"+protectops")==0) chan->stat|=CHAN_PROTECTOPS; else if (strcmp(item[i],"-protectops")==0) chan->stat&=~CHAN_PROTECTOPS; else if (strcmp(item[i],"+statuslog")==0) chan->stat|=CHAN_LOGSTATUS; else if (strcmp(item[i],"-statuslog")==0) chan->stat&=~CHAN_LOGSTATUS; else if (strcmp(item[i],"+stopnethack")==0) chan->stat|=CHAN_STOPNETHACK; else if (strcmp(item[i],"-stopnethack")==0) chan->stat&=~CHAN_STOPNETHACK; else if (strcmp(item[i],"+revenge")==0) chan->stat|=CHAN_REVENGE; else if (strcmp(item[i],"-revenge")==0) chan->stat&=~CHAN_REVENGE; else { Tcl_AppendResult(irp,"illegal channel option: ",item[i],NULL); return TCL_ERROR; } } return TCL_OK; } /* create new channel and parse commands */ int tcl_channel_add(irp,newname,options) Tcl_Interp *irp; char *newname,*options; { int i; struct chanset_t *chan; int items; char **item; context; if (Tcl_SplitList(irp,options,&items,&item) != TCL_OK) return TCL_ERROR; chan=newchanset(); chan->name[0]=0; chan->need_op[0]=0; chan->need_invite[0]=0; chan->mode_pls_prot=0; chan->mode_mns_prot=0; chan->limit_prot=(-1); chan->key_prot[0]=0; chan->stat=CHAN_ENFORCEBANS|CHAN_GREET|CHAN_PROTECTOPS|CHAN_LOGSTATUS| CHAN_STOPNETHACK; chan->pls[0]=0; chan->mns[0]=0; chan->key[0]=0; chan->rmkey[0]=0; chan->limit=(-1); chan->idle_kick=0; for (i=0; i<3; i++) { chan->cmode[i].op=NULL; chan->cmode[i].type=0; } chan->deopnick[0]=0; chan->deoptime=0L; chan->deops=0; chan->kicknick[0]=0; chan->kicktime=0L; chan->kicks=0; strncpy(chan->name,newname,80); chan->name[80]=0; if (findchan(newname)!=NULL) { /* could be from rehash: ignore re-definition of channel */ nfree(chan); /* BUT go ahead and re-parse the settings */ chan=findchan(newname); chan->stat &= ~CHANFLAGGED; /* don't delete me! :) */ if (tcl_channel_modify(irp,chan,items,item) != TCL_OK) { return TCL_ERROR; } return TCL_OK; } /* okay, parse those commands */ if (tcl_channel_modify(irp,chan,items,item) != TCL_OK) { nfree(chan); return TCL_ERROR; } /* initialize chan->channel info */ init_channel(chan); addchanset(chan); chan->bans=NULL; /* channel name is stored in info field for sharebot stuff */ chan->bans=adduser(chan->bans,"null","none","nopass",0); set_handle_info(chan->bans,"null",chan->name); if (serv>=0) mprintf(serv,"JOIN %s %s\n",chan->name,chan->key_prot); return TCL_OK; } int tcl_channel STDVAR { struct chanset_t *chan; context; BADARGS(2,999," command ?options?"); if (strcmp(argv[1],"add")==0) { BADARGS(3,999," add channel-name ?options?"); if (argc==3) return tcl_channel_add(irp,argv[2],""); return tcl_channel_add(irp,argv[2],argv[3]); } if (strcmp(argv[1],"set")==0) { BADARGS(3,999," set channel-name ?options?"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"no such channel record",NULL); return TCL_ERROR; } return tcl_channel_modify(irp,chan,argc-3,&argv[3]); } if (strcmp(argv[1],"info")==0) { BADARGS(3,3," info channel-name"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"no such channel record",NULL); return TCL_ERROR; } return tcl_channel_info(irp,chan); } if (strcmp(argv[1],"remove")==0) { BADARGS(3,3," remove channel-name"); chan=findchan(argv[2]); if (chan==NULL) { Tcl_AppendResult(irp,"no such channel record",NULL); return TCL_ERROR; } if (serv>=0) mprintf(serv,"PART %s\n",chan->name); clear_channel(chan,0); freeuser(chan->bans); killchanset(argv[2]); return TCL_OK; } Tcl_AppendResult(irp,"unknown channel command: should be one of: ", "add, set, info, remove",NULL); return TCL_ERROR; } int tcl_banlist STDVAR { struct chanset_t *chan; struct userrec *u; struct eggqueue *q; char s[256],hst[UHOSTLEN],ts[21],ts1[21],ts2[21]; char *list[5],*p; context; BADARGS(1,2," ?channel?"); if (argc==2) { chan=findchan(argv[1]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[1],NULL); return TCL_ERROR; } u=chan->bans; } else u=get_user_by_handle(userlist,BAN_NAME); if (u==NULL) return TCL_OK; q=u->host; while ((q!=NULL) && (strcmp(q->item,"none")!=0)) { strcpy(s,q->item); splitc(hst,s,':'); splitc(ts,s,':'); if (s[0]=='+') { /* extended format */ strcpy(s,&s[1]); splitc(ts1,s,':'); splitc(ts2,s,':'); } else { strcpy(ts1,"0"); strcpy(ts2,"0"); } if (s[0]) { /* decode gibberish stuff */ p=strchr(s,'~'); while (p!=NULL) { *p=' '; p=strchr(s,'~'); } p=strchr(s,'`'); while (p!=NULL) { *p=','; p=strchr(s,'`'); } } list[0]=hst; list[1]=s; list[2]=ts; list[3]=ts1; list[4]=ts2; p=Tcl_Merge(5,list); Tcl_AppendElement(irp,p); n_free(p,"",0); q=q->next; } return TCL_OK; } int tcl_channels STDVAR { struct chanset_t *chan; context; BADARGS(1,1,""); chan=chanset; while (chan!=NULL) { Tcl_AppendElement(irp,chan->name); chan=chan->next; } return TCL_OK; } int tcl_getting_users STDVAR { int i; BADARGS(1,1,""); for (i=0; istatus&STAT_GETTING)) { Tcl_AppendResult(irp,"1",NULL); return TCL_OK; } } Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_filesend STDVAR { int i,idx; char s[10]; BADARGS(3,4," idx filename ?nick?"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (dcc[idx].type!=DCC_FILES) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (argc==4) i=files_get(idx,argv[2],argv[3]); else i=files_get(idx,argv[2],""); sprintf(s,"%d",i); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getdesc STDVAR { char s[301]; BADARGS(3,3," dir file"); filedb_getdesc(argv[1],argv[2],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_setdesc STDVAR { BADARGS(4,4," dir file desc"); filedb_setdesc(argv[1],argv[2],argv[3]); return TCL_OK; } int tcl_getowner STDVAR { char s[121]; BADARGS(3,3," dir file"); filedb_getowner(argv[1],argv[2],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_setowner STDVAR { BADARGS(4,4," dir file owner"); filedb_setowner(argv[1],argv[2],argv[3]); return TCL_OK; } int tcl_getgots STDVAR { int i; char s[10]; BADARGS(3,3," dir file"); i=filedb_getgots(argv[1],argv[2]); sprintf(s,"%d",i); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_setlink STDVAR { BADARGS(4,4," dir file link"); filedb_setlink(argv[1],argv[2],argv[3]); return TCL_OK; } int tcl_getlink STDVAR { char s[121]; BADARGS(3,3," dir file"); filedb_getlink(argv[1],argv[2],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_setpwd STDVAR { int i,idx; BADARGS(3,3," idx dir"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (dcc[idx].type!=DCC_FILES) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } files_setpwd(idx,argv[2]); return TCL_OK; } int tcl_getpwd STDVAR { int i,idx; BADARGS(2,2," idx"); i=atoi(argv[1]); idx=findidx(i); if (idx<0) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if (dcc[idx].type!=DCC_FILES) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } Tcl_AppendResult(irp,dcc[idx].u.file->dir,NULL); return TCL_OK; } int tcl_getfiles STDVAR { BADARGS(2,2," dir"); filedb_getfiles(irp,argv[1]); return TCL_OK; } int tcl_getdirs STDVAR { BADARGS(2,2," dir"); filedb_getdirs(irp,argv[1]); return TCL_OK; } int tcl_hide STDVAR { BADARGS(3,3," dir file"); filedb_change(argv[1],argv[2],FILEDB_HIDE); return TCL_OK; } int tcl_unhide STDVAR { BADARGS(3,3," dir file"); filedb_change(argv[1],argv[2],FILEDB_UNHIDE); return TCL_OK; } int tcl_share STDVAR { BADARGS(3,3," dir file"); filedb_change(argv[1],argv[2],FILEDB_SHARE); return TCL_OK; } int tcl_unshare STDVAR { BADARGS(3,3," dir file"); filedb_change(argv[1],argv[2],FILEDB_UNSHARE); return TCL_OK; } int tcl_assoc STDVAR { int chan; char name[21],*p; BADARGS(2,3," chan name"); chan=atoi(argv[1]); if ((chan<1) || (chan>99999)) { Tcl_AppendResult(irp,"invalid channel #",NULL); return TCL_ERROR; } if (argc==3) { strncpy(name,argv[2],20); name[20]=0; add_assoc(name,chan); } p=get_assoc_name(chan); if (p==NULL) name[0]=0; else strcpy(name,p); Tcl_AppendResult(irp,name,NULL); return TCL_OK; } int tcl_killassoc STDVAR { int chan; BADARGS(2,2," chan"); chan=atoi(argv[1]); if ((chan<1) || (chan>99999)) { Tcl_AppendResult(irp,"invalid channel #",NULL); return TCL_ERROR; } kill_assoc(chan); return TCL_OK; } int tcl_getchanmode STDVAR { struct chanset_t *chan; BADARGS(2,2," channel"); chan=findchan(argv[1]); if (chan==NULL) { Tcl_AppendResult(irp,"invalid channel: ",argv[1],NULL); return TCL_ERROR; } Tcl_AppendResult(irp,getchanmode(chan),NULL); return TCL_OK; } /**********************************************************************/ /* called when some script tries to change flag1..flag7 */ /* (possible that the new value will be invalid, so we ignore the change) */ char *tcl_chflag(cdata,irp,name1,name2,flags) ClientData cdata; Tcl_Interp *irp; char *name1,*name2; int flags; { char s[2],*p; p=Tcl_GetVar(irp,name1,TCL_GLOBAL_ONLY); if (p==NULL) return NULL; s[0]=(*p); s[1]=0; switch ((int)cdata) { case 1: if (!(str2flags(s) & ~USER_FLAG1)) flag1=s[0]; else s[0]=flag1; break; case 2: if (!(str2flags(s) & ~USER_FLAG2)) flag2=s[0]; else s[0]=flag2; break; case 3: if (!(str2flags(s) & ~USER_FLAG3)) flag3=s[0]; else s[0]=flag3; break; case 4: if (!(str2flags(s) & ~USER_FLAG4)) flag4=s[0]; else s[0]=flag4; break; case 5: if (!(str2flags(s) & ~USER_FLAG5)) flag5=s[0]; else s[0]=flag5; break; case 6: if (!(str2flags(s) & ~USER_FLAG6)) flag6=s[0]; else s[0]=flag6; break; case 7: if (!(str2flags(s) & ~USER_FLAG7)) flag7=s[0]; else s[0]=flag7; break; case 8: if (!(str2flags(s) & ~USER_FLAG8)) flag8=s[0]; else s[0]=flag8; break; case 9: if (!(str2flags(s) & ~USER_FLAG9)) flag9=s[0]; else s[0]=flag9; break; case 0: if (!(str2flags(s) & ~USER_FLAG0)) flag0=s[0]; else s[0]=flag0; break; } Tcl_SetVar(irp,name1,s,TCL_GLOBAL_ONLY); return NULL; } /* parse the 'servers' variable */ /* save and re-set the value of curserv */ void get_tcl_servers() { int i,lc,code; char **list; char *serv; wipe_serverlist(); serv=Tcl_GetVar(interp,"servers",TCL_GLOBAL_ONLY); if (serv==NULL) { curserv=0; return; } code=Tcl_SplitList(interp,serv,&lc,&list); if (code==TCL_ERROR) { putlog(LOG_MISC,"*","Tcl error parsing server list:"); putlog(LOG_MISC,"*","%s",interp->result); return; } for (i=0; i' */ curserv=(-1); n_free(list,"",0); if (botserver[0]) next_server(&curserv,botserver,&botserverport,""); } /* weird, weird, weird... */ void set_tcl_servers() { Tcl_DString ds; char *slist; struct eggqueue *q; Tcl_DStringInit(&ds); q=serverlist; while (q!=NULL) { Tcl_DStringAppendElement(&ds,q->item); q=q->next; } slist=Tcl_DStringValue(&ds); Tcl_SetVar(interp,"servers",slist,TCL_GLOBAL_ONLY); Tcl_DStringFree(&ds); } void tcl_bool(var,val) char *var; int *val; { char *s; s=Tcl_GetVar(interp,var,TCL_GLOBAL_ONLY); if (s!=NULL) { if (Tcl_ExprBoolean(interp,s,val)==TCL_ERROR) { putlog(LOG_MISC,"*","Tcl error evaluating %s:",var); putlog(LOG_MISC,"*","%s",interp->result); } } } void tcl_setbool(var,val) char *var; int val; { char s[2]; s[1]=0; s[0]=(val?'1':'0'); Tcl_SetVar(interp,var,s,TCL_GLOBAL_ONLY); } void tcl_int(var,val) char *var; int *val; { char *s; long l; s=Tcl_GetVar(interp,var,TCL_GLOBAL_ONLY); if (s!=NULL) { if (Tcl_ExprLong(interp,s,&l)==TCL_ERROR) { putlog(LOG_MISC,"*","Tcl error evaluating %s:",var); putlog(LOG_MISC,"*","%s",interp->result); } } *val=(int)l; } void tcl_setint(var,val) char *var; int val; { char s[40]; sprintf(s,"%d",val); Tcl_SetVar(interp,var,s,TCL_GLOBAL_ONLY); } void tcl_str(var,val,max) char *var,*val; int max; { char *s; s=Tcl_GetVar(interp,var,TCL_GLOBAL_ONLY); if (s!=NULL) { if (strlen(s)>max) s[max]=0; strcpy(val,s); } } void tcl_setstr(var,val) char *var,*val; { Tcl_SetVar(interp,var,val,TCL_GLOBAL_ONLY); } void tcl_char(var,val) char *var,*val; { char *s; s=Tcl_GetVar(interp,var,TCL_GLOBAL_ONLY); if (s!=NULL) *val=s[0]; } void tcl_setchar(var,val) char *var,val; { char s[2]; s[0]=val; s[1]=0; Tcl_SetVar(interp,var,s,TCL_GLOBAL_ONLY); } /* not going through Tcl's crazy main() system (what on earth was he smoking?!) so we gotta initialize the Tcl interpreter */ void init_tcl() { /* initialize the interpreter */ interp=Tcl_CreateInterp(); Tcl_Init(interp); init_hash(); init_builtins(); /* see note (1) at the bottom of this file */ /* Tcl_DeleteCommand(interp,"exec"); */ /* put traces on the 5 flag variables */ tcl_setchar("flag1",flag1); tcl_setchar("flag2",flag2); tcl_setchar("flag3",flag3); tcl_setchar("flag4",flag4); tcl_setchar("flag5",flag5); tcl_setchar("flag6",flag6); tcl_setchar("flag7",flag7); tcl_setchar("flag8",flag8); tcl_setchar("flag9",flag9); tcl_setchar("flag0",flag0); Tcl_TraceVar(interp,"flag1",TCL_TRACE_WRITES,tcl_chflag,(ClientData)1); Tcl_TraceVar(interp,"flag2",TCL_TRACE_WRITES,tcl_chflag,(ClientData)2); Tcl_TraceVar(interp,"flag3",TCL_TRACE_WRITES,tcl_chflag,(ClientData)3); Tcl_TraceVar(interp,"flag4",TCL_TRACE_WRITES,tcl_chflag,(ClientData)4); Tcl_TraceVar(interp,"flag5",TCL_TRACE_WRITES,tcl_chflag,(ClientData)5); Tcl_TraceVar(interp,"flag6",TCL_TRACE_WRITES,tcl_chflag,(ClientData)6); Tcl_TraceVar(interp,"flag7",TCL_TRACE_WRITES,tcl_chflag,(ClientData)7); Tcl_TraceVar(interp,"flag8",TCL_TRACE_WRITES,tcl_chflag,(ClientData)8); Tcl_TraceVar(interp,"flag9",TCL_TRACE_WRITES,tcl_chflag,(ClientData)9); Tcl_TraceVar(interp,"flag0",TCL_TRACE_WRITES,tcl_chflag,(ClientData)0); /* add new commands */ Tcl_CreateCommand(interp,"logfile",tcl_logfile,NULL,NULL); Tcl_CreateCommand(interp,"putserv",tcl_putserv,NULL,NULL); Tcl_CreateCommand(interp,"puthelp",tcl_puthelp,NULL,NULL); Tcl_CreateCommand(interp,"putdcc",tcl_putdcc,NULL,NULL); Tcl_CreateCommand(interp,"putlog",tcl_putlog,NULL,NULL); Tcl_CreateCommand(interp,"putcmdlog",tcl_putcmdlog,NULL,NULL); Tcl_CreateCommand(interp,"putxferlog",tcl_putxferlog,NULL,NULL); Tcl_CreateCommand(interp,"putloglev",tcl_putloglev,NULL,NULL); Tcl_CreateCommand(interp,"countusers",tcl_countusers,NULL,NULL); Tcl_CreateCommand(interp,"validuser",tcl_validuser,NULL,NULL); Tcl_CreateCommand(interp,"finduser",tcl_finduser,NULL,NULL); Tcl_CreateCommand(interp,"passwdOk",tcl_passwdOk,NULL,NULL); Tcl_CreateCommand(interp,"passwdok",tcl_passwdOk,NULL,NULL); Tcl_CreateCommand(interp,"chattr",tcl_chattr,NULL,NULL); Tcl_CreateCommand(interp,"matchattr",tcl_matchattr,NULL,NULL); Tcl_CreateCommand(interp,"botisop",tcl_botisop,NULL,NULL); Tcl_CreateCommand(interp,"isop",tcl_isop,NULL,NULL); Tcl_CreateCommand(interp,"isvoice",tcl_isvoice,NULL,NULL); Tcl_CreateCommand(interp,"onchan",tcl_onchan,NULL,NULL); Tcl_CreateCommand(interp,"handonchan",tcl_handonchan,NULL,NULL); Tcl_CreateCommand(interp,"ischanban",tcl_ischanban,NULL,NULL); Tcl_CreateCommand(interp,"getchanhost",tcl_getchanhost,NULL,NULL); Tcl_CreateCommand(interp,"onchansplit",tcl_onchansplit,NULL,NULL); Tcl_CreateCommand(interp,"chanlist",tcl_chanlist,NULL,NULL); Tcl_CreateCommand(interp,"bind",tcl_bind,(ClientData)0,NULL); Tcl_CreateCommand(interp,"unbind",tcl_bind,(ClientData)1,NULL); Tcl_CreateCommand(interp,"adduser",tcl_adduser,NULL,NULL); Tcl_CreateCommand(interp,"addbot",tcl_addbot,NULL,NULL); Tcl_CreateCommand(interp,"deluser",tcl_deluser,NULL,NULL); Tcl_CreateCommand(interp,"maskhost",tcl_maskhost,NULL,NULL); Tcl_CreateCommand(interp,"dccsimul",tcl_dccsimul,NULL,NULL); Tcl_CreateCommand(interp,"addhost",tcl_addhost,NULL,NULL); Tcl_CreateCommand(interp,"delhost",tcl_delhost,NULL,NULL); Tcl_CreateCommand(interp,"timer",tcl_timer,NULL,NULL); Tcl_CreateCommand(interp,"killtimer",tcl_killtimer,NULL,NULL); Tcl_CreateCommand(interp,"utimer",tcl_utimer,NULL,NULL); Tcl_CreateCommand(interp,"killutimer",tcl_killutimer,NULL,NULL); Tcl_CreateCommand(interp,"unixtime",tcl_unixtime,NULL,NULL); Tcl_CreateCommand(interp,"time",tcl_time,NULL,NULL); Tcl_CreateCommand(interp,"date",tcl_date,NULL,NULL); Tcl_CreateCommand(interp,"getinfo",tcl_getinfo,NULL,NULL); Tcl_CreateCommand(interp,"getdccdir",tcl_getdccdir,NULL,NULL); Tcl_CreateCommand(interp,"getcomment",tcl_getcomment,NULL,NULL); Tcl_CreateCommand(interp,"getemail",tcl_getemail,NULL,NULL); Tcl_CreateCommand(interp,"getxtra",tcl_getxtra,NULL,NULL); Tcl_CreateCommand(interp,"setinfo",tcl_setinfo,NULL,NULL); Tcl_CreateCommand(interp,"setdccdir",tcl_setdccdir,NULL,NULL); Tcl_CreateCommand(interp,"setcomment",tcl_setcomment,NULL,NULL); Tcl_CreateCommand(interp,"setemail",tcl_setemail,NULL,NULL); Tcl_CreateCommand(interp,"setxtra",tcl_setxtra,NULL,NULL); Tcl_CreateCommand(interp,"delban",tcl_delban,NULL,NULL); Tcl_CreateCommand(interp,"delglban",tcl_delglban,NULL,NULL); Tcl_CreateCommand(interp,"isban",tcl_isban,NULL,NULL); Tcl_CreateCommand(interp,"ispermban",tcl_ispermban,NULL,NULL); Tcl_CreateCommand(interp,"matchban",tcl_matchban,NULL,NULL); Tcl_CreateCommand(interp,"addban",tcl_addban,NULL,NULL); Tcl_CreateCommand(interp,"addglban",tcl_addglban,NULL,NULL); Tcl_CreateCommand(interp,"getlaston",tcl_getlaston,NULL,NULL); Tcl_CreateCommand(interp,"setlaston",tcl_setlaston,NULL,NULL); Tcl_CreateCommand(interp,"timers",tcl_timers,NULL,NULL); Tcl_CreateCommand(interp,"utimers",tcl_utimers,NULL,NULL); Tcl_CreateCommand(interp,"jump",tcl_jump,NULL,NULL); Tcl_CreateCommand(interp,"ctime",tcl_ctime,NULL,NULL); Tcl_CreateCommand(interp,"myip",tcl_myip,NULL,NULL); Tcl_CreateCommand(interp,"dccsend",tcl_dccsend,NULL,NULL); Tcl_CreateCommand(interp,"rand",tcl_rand,NULL,NULL); Tcl_CreateCommand(interp,"dccbroadcast",tcl_dccbroadcast,NULL,NULL); Tcl_CreateCommand(interp,"hand2idx",tcl_hand2idx,NULL,NULL); Tcl_CreateCommand(interp,"getidx",tcl_hand2idx,NULL,NULL); Tcl_CreateCommand(interp,"idx2hand",tcl_idx2hand,NULL,NULL); Tcl_CreateCommand(interp,"getchan",tcl_getchan,NULL,NULL); Tcl_CreateCommand(interp,"setchan",tcl_setchan,NULL,NULL); Tcl_CreateCommand(interp,"dccputchan",tcl_dccputchan,NULL,NULL); Tcl_CreateCommand(interp,"console",tcl_console,NULL,NULL); Tcl_CreateCommand(interp,"echo",tcl_echo,NULL,NULL); Tcl_CreateCommand(interp,"control",tcl_control,NULL,NULL); Tcl_CreateCommand(interp,"putbot",tcl_putbot,NULL,NULL); Tcl_CreateCommand(interp,"putallbots",tcl_putallbots,NULL,NULL); Tcl_CreateCommand(interp,"getchanidle",tcl_getchanidle,NULL,NULL); Tcl_CreateCommand(interp,"killdcc",tcl_killdcc,NULL,NULL); Tcl_CreateCommand(interp,"userlist",tcl_userlist,NULL,NULL); Tcl_CreateCommand(interp,"sendnote",tcl_sendnote,NULL,NULL); Tcl_CreateCommand(interp,"save",tcl_save,NULL,NULL); Tcl_CreateCommand(interp,"reload",tcl_reload,NULL,NULL); Tcl_CreateCommand(interp,"bots",tcl_bots,NULL,NULL); Tcl_CreateCommand(interp,"chanbans",tcl_chanbans,NULL,NULL); Tcl_CreateCommand(interp,"gethosts",tcl_gethosts,NULL,NULL); Tcl_CreateCommand(interp,"nick2hand",tcl_nick2hand,NULL,NULL); Tcl_CreateCommand(interp,"hand2nick",tcl_hand2nick,NULL,NULL); Tcl_CreateCommand(interp,"dcclist",tcl_dcclist,NULL,NULL); Tcl_CreateCommand(interp,"dccused",tcl_dccused,NULL,NULL); Tcl_CreateCommand(interp,"getfileq",tcl_getfileq,NULL,NULL); Tcl_CreateCommand(interp,"chpass",tcl_chpass,NULL,NULL); Tcl_CreateCommand(interp,"chhandle",tcl_chhandle,NULL,NULL); Tcl_CreateCommand(interp,"link",tcl_link,NULL,NULL); Tcl_CreateCommand(interp,"unlink",tcl_unlink,NULL,NULL); Tcl_CreateCommand(interp,"channel",tcl_channel,NULL,NULL); Tcl_CreateCommand(interp,"banlist",tcl_banlist,NULL,NULL); Tcl_CreateCommand(interp,"channels",tcl_channels,NULL,NULL); Tcl_CreateCommand(interp,"getting-users",tcl_getting_users,NULL,NULL); Tcl_CreateCommand(interp,"getdesc",tcl_getdesc,NULL,NULL); Tcl_CreateCommand(interp,"getowner",tcl_getowner,NULL,NULL); Tcl_CreateCommand(interp,"setdesc",tcl_setdesc,NULL,NULL); Tcl_CreateCommand(interp,"setowner",tcl_setowner,NULL,NULL); Tcl_CreateCommand(interp,"getgots",tcl_getgots,NULL,NULL); Tcl_CreateCommand(interp,"getpwd",tcl_getpwd,NULL,NULL); Tcl_CreateCommand(interp,"setpwd",tcl_setpwd,NULL,NULL); Tcl_CreateCommand(interp,"getlink",tcl_getlink,NULL,NULL); Tcl_CreateCommand(interp,"setlink",tcl_setlink,NULL,NULL); Tcl_CreateCommand(interp,"getfiles",tcl_getfiles,NULL,NULL); Tcl_CreateCommand(interp,"getdirs",tcl_getdirs,NULL,NULL); Tcl_CreateCommand(interp,"hide",tcl_hide,NULL,NULL); Tcl_CreateCommand(interp,"unhide",tcl_unhide,NULL,NULL); Tcl_CreateCommand(interp,"share",tcl_share,NULL,NULL); Tcl_CreateCommand(interp,"unshare",tcl_unshare,NULL,NULL); Tcl_CreateCommand(interp,"filesend",tcl_filesend,NULL,NULL); Tcl_CreateCommand(interp,"assoc",tcl_assoc,NULL,NULL); Tcl_CreateCommand(interp,"killassoc",tcl_killassoc,NULL,NULL); Tcl_CreateCommand(interp,"getchanmode",tcl_getchanmode,NULL,NULL); } /* set Tcl variables to match eggdrop internal variables */ void set_tcl_vars() { char s[121]; set_tcl_servers(); /* on/off variables */ tcl_setbool("log-time",shtime); tcl_setbool("learn-users",learn_users); tcl_setbool("require-x",require_x); tcl_setbool("require-p",require_p); tcl_setbool("use-info",use_info); tcl_setbool("share-users",share_users); tcl_setbool("passive",passive); tcl_setbool("strict-host",strict_host); tcl_setbool("isolate",isolate); tcl_setbool("keep-all-logs",keep_all_logs); tcl_setbool("upload-to-cd",upload_to_cd); tcl_setbool("never-give-up",never_give_up); tcl_setbool("open-telnets",allow_new_telnets); tcl_setbool("keep-nick",keepnick); tcl_setbool("copy-to-tmp",copy_to_tmp); tcl_setbool("telnet-bots-only",telnet_bots_only); /* numbers */ tcl_setint("telnet",telnet_port); tcl_setint("servlimit",min_servs); tcl_setint("flood-msg",flood_thr); tcl_setint("flood-chan",flood_pub_thr); tcl_setint("flood-join",flood_join_thr); tcl_setint("ban-time",ban_time); tcl_setint("ignore-time",ignore_time); tcl_setint("dcc-limit",dcc_limit); tcl_setint("dcc-block",dcc_block); tcl_setint("dcc-maxsize",dcc_maxsize); tcl_setint("dcc-users",dcc_users); tcl_setint("save-users-at",save_users_at); tcl_setint("switch-logfiles-at",switch_logfiles_at); tcl_setint("server-timeout",server_timeout); tcl_setint("connect-timeout",connect_timeout); /* strings */ tcl_setstr("nick",origbotname); tcl_setstr("username",botuser); tcl_setstr("realname",botrealname); tcl_setstr("userfile",userfile); tcl_setstr("dcc-path",dccdir); tcl_setstr("dcc-incoming",dccin); tcl_setstr("motd",motdfile); tcl_setstr("admin",admin); tcl_setstr("init-server",initserver); tcl_setstr("notefile",notefile); tcl_setstr("helpdir",helpdir); tcl_setstr("tempdir",tempdir); tcl_setstr("textdir",textdir); tcl_setstr("notify-newusers",notify_new); tcl_setstr("ctcp-version",ctcp_version); tcl_setstr("ctcp-finger",ctcp_finger); tcl_setstr("ctcp-userinfo",ctcp_userinfo); tcl_setstr("owner",owner); /* weird */ strcpy(s,masktype(conmask)); tcl_setstr("console",s); flags2str(default_flags,s); tcl_setstr("default-flags",s); /* variables that we won't re-read... only for convenience of scripts */ tcl_setstr("botnick",botname); sprintf(s,"%s:%d",botserver,botserverport); tcl_setstr("server",s); sprintf(s,"%s!%s",botname,botuserhost); tcl_setstr("botname",s); tcl_setstr("version",egg_version); /* cos we have to: */ tcl_setstr("tcl_interactive","0"); } /* set eggdrop internal variables to match Tcl variables */ void get_tcl_vars() { char s[120]; int oldisol; get_tcl_servers(); /* on/off variables: */ tcl_bool("log-time",&shtime); tcl_bool("learn-users",&learn_users); tcl_bool("require-x",&require_x); tcl_bool("require-p",&require_p); tcl_bool("use-info",&use_info); tcl_bool("share-users",&share_users); tcl_bool("passive",&passive); tcl_bool("strict-host",&strict_host); oldisol=isolate; tcl_bool("isolate",&isolate); if ((isolate) && (!oldisol) && (online)) { /* suddenly isolating now */ chatout("*** Party line is now isolated.\n"); tandout("chat %s Isolating my party line.\n",origbotname); } if ((!isolate) && (oldisol) && (online)) { chatout("*** Party line is now open.\n"); tandout("chat %s Merging my party line.\n",origbotname); } tcl_bool("keep-all-logs",&keep_all_logs); tcl_bool("upload-to-cd",&upload_to_cd); tcl_bool("never-give-up",&never_give_up); tcl_bool("open-telnets",&allow_new_telnets); tcl_bool("keep-nick",&keepnick); tcl_bool("copy-to-tmp",©_to_tmp); tcl_bool("telnet-bots-only",&telnet_bots_only); /* numbers */ oldisol=telnet_port; tcl_int("telnet",&telnet_port); if (telnet_port!=oldisol) change_telnet_port(); tcl_int("servlimit",&min_servs); tcl_int("flood-msg",&flood_thr); tcl_int("flood-chan",&flood_pub_thr); tcl_int("flood-join",&flood_join_thr); tcl_int("ban-time",&ban_time); tcl_int("ignore-time",&ignore_time); tcl_int("dcc-limit",&dcc_limit); tcl_int("dcc-block",&dcc_block); tcl_int("dcc-maxsize",&dcc_maxsize); tcl_int("dcc-users",&dcc_users); tcl_int("save-users-at",&save_users_at); tcl_int("switch-logfiles-at",&switch_logfiles_at); tcl_int("server-timeout",&server_timeout); tcl_int("connect-timeout",&connect_timeout); /* strings */ strcpy(s,origbotname); tcl_str("nick",origbotname,9); if ((s[0]) && (strcasecmp(origbotname,s)!=0)) { /* trying to change bot's nickname */ if (get_tands() > 0) { putlog(LOG_MISC,"*","* Tried to change my nickname, but I'm still linked to a botnet."); putlog(LOG_MISC,"*","* (Unlink and try again.)"); strcpy(origbotname,s); } else putlog(LOG_MISC,"*","* IDENTITY CHANGE: %s -> %s",s,origbotname); } tcl_str("username",botuser,10); tcl_str("realname",botrealname,80); tcl_str("userfile",userfile,120); tcl_str("dcc-path",dccdir,120); if (dccdir[0]) if (dccdir[strlen(dccdir)-1]!='/') strcat(dccdir,"/"); tcl_str("dcc-incoming",dccin,120); if (dccin[0]) if (dccin[strlen(dccin)-1]!='/') strcat(dccin,"/"); tcl_str("motd",motdfile,120); tcl_str("admin",admin,120); tcl_str("init-server",initserver,120); tcl_str("notefile",notefile,120); tcl_str("helpdir",helpdir,120); if (helpdir[0]) if (helpdir[strlen(helpdir)-1]!='/') strcat(helpdir,"/"); tcl_str("tempdir",tempdir,120); if (tempdir[0]) if (tempdir[strlen(tempdir)-1]!='/') strcat(tempdir,"/"); tcl_str("textdir",textdir,120); if (textdir[0]) { if (textdir[strlen(textdir)-1]!='/') strcat(textdir,"/"); } else strcpy(textdir,helpdir); tcl_str("notify-newusers",notify_new,120); tcl_str("ctcp-version",ctcp_version,120); tcl_str("ctcp-finger",ctcp_finger,120); tcl_str("ctcp-userinfo",ctcp_userinfo,120); tcl_str("owner",owner,120); /* weird ones */ s[0]=0; tcl_str("console",s,20); if (s[0]) conmask=logmodes(s); else conmask=LOG_MODES|LOG_MISC|LOG_CMDS; s[0]=0; tcl_str("default-flags",s,20); default_flags=str2flags(s); } /* evaluate a Tcl command, send output to a dcc user */ void cmd_tcl(idx,msg) int idx; char *msg; { int code; context; set_tcl_vars(); code=Tcl_Eval(interp,msg); if (code==TCL_OK) dumplots(idx,"Tcl: ",interp->result); else dprintf(idx,"TCL error: %s\n",interp->result); /* refresh internal vars */ get_tcl_vars(); } /* perform a 'set' command */ void cmd_set(idx,msg) int idx; char *msg; { int code; char s[512]; context; putlog(LOG_CMDS,"*","#%s# set %s",dcc[idx].nick,msg); set_tcl_vars(); strcpy(s,"set "); strcat(s,msg); if (!msg[0]) { strcpy(s,"info globals"); Tcl_Eval(interp,s); dumplots(idx,"global vars: ",interp->result); return; } code=Tcl_Eval(interp,s); if (code==TCL_OK) { if (strchr(msg,' ')==NULL) dumplots(idx,"currently: ",interp->result); else dprintf(idx,"Ok, set.\n"); } else dprintf(idx,"Error: %s\n",interp->result); get_tcl_vars(); } void do_tcl(whatzit,script) char *whatzit,*script; { int code; #ifdef DEBUG_TCL FILE *f=fopen("DEBUG.TCL","a"); if (f!=NULL) fprintf(f,"eval: %s\n",script); #endif set_tcl_vars(); code=Tcl_Eval(interp,script); #ifdef DEBUG_TCL if (f!=NULL) { fprintf(f,"done eval, result=%d\n",code); fclose(f); } #endif if (code!=TCL_OK) { putlog(LOG_MISC,"*","Tcl error in script for '%s':",whatzit); putlog(LOG_MISC,"*","%s",interp->result); } get_tcl_vars(); } /* read and interpret the configfile given */ /* return 1 if everything was okay */ int readtclprog(fname) char *fname; { int code; FILE *f; set_tcl_vars(); f=fopen(fname,"r"); if (f==NULL) return 0; fclose(f); #ifdef DEBUG_TCL f=fopen("DEBUG.TCL","a"); if (f!=NULL) { fprintf(f,"Sourcing file %s ...\n"); fclose(f); } #endif code=Tcl_EvalFile(interp,fname); if (code!=TCL_OK) { if (use_stderr) { tprintf(STDERR,"Tcl error in file '%s':\n",fname); tprintf(STDERR,"%s\n",Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY)); } else { putlog(LOG_MISC,"*","Tcl error in file '%s':",fname); putlog(LOG_MISC,"*","%s\n",Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY)); } /* try to go on anyway (shrug) */ } /* refresh internal variables */ get_tcl_vars(); return 1; } /* note (1): the tcl 'exec' command is no longer removed, since it is assumed that the tcl command will be left at its default flag requirement, ie: only owners can do tcl commands directly. also, removing the 'exec' command doesn't block up all holes -- tcl allows you to open a "pipe" which really just executes a shell command and redirects output. so you were never truly safe anyway. gee. */