/* this file is only used if you are linking in Tcl */ #include #include #include #include "tcl.h" #include "eggdrop.h" #include "chan.h" #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 /* eggdrop always uses the same interpreter */ Tcl_Interp *interp; extern int curserv, helpserv, serv, helpsock; extern int shtime, op_on_join, revenge, greet, learn_users, require_x, enforce_bans, share_users, use_info, passive, strict_host, require_p, isolate, keep_all_logs, raw_files, perm_bans, clearbans, chan_updates, use_stderr, upload_to_cd, bitch, never_give_up, protect_ops, allow_new_telnets; extern int telnet_port, botserverport, min_servs, helpserverport, default_flags, conmask, newserverport, idle_kick, dcc_block, dcc_limit, dcc_maxsize; extern char *logfile[]; extern int logmask[]; extern int flood_thr, flood_pub_thr, flood_join_thr, ban_time, ignore_time; extern char botname[], origbotname[], botuser[], botrealname[], botserver[], botchan[], dccdir[], dccin[], motdfile[], admin[], gainops[], userfile[], helpbot[], helpserver[], helpdir[], initserver[], chankey[], notify_new[], notefile[], curchan[], botuserhost[], tempdir[], newserver[], textdir[], ctcp_version[], ctcp_finger[], owner[]; extern char flag1, flag2, flag3, flag4, flag5; extern char cx_file[]; extern int cx_line; extern struct chan_t channel; extern int online; extern struct userrec *userlist; struct queue { char *item; struct queue *next; }; extern struct queue *serverlist; extern struct dcc_t dcc[]; extern int dcc_total; typedef struct timer_str { unsigned int mins; /* time to elapse */ char *cmd; /* command linked to */ unsigned long id; /* used to remove timers */ struct timer_str *next; } tcl_timer_t; /* initialize to no timers */ tcl_timer_t *timer=NULL; /* next timer will have this number */ unsigned long timer_id=1; Tcl_Interp *Tcl_CreateInterp(); char *ismember(); char *masktype(); void set_tcl_vars(); void get_tcl_vars(); struct userrec *adduser(); int expmem_tcl() { int i,tot=0; tcl_timer_t *t=timer; for (i=0; icmd)+1; t=t->next; } return tot; } /***********************************************************************/ /* brief venture into timers */ /* add a timer */ unsigned long add_timer(mins,cmd,prev_id) int mins; char *cmd; unsigned long prev_id; { tcl_timer_t *old=timer; timer=(tcl_timer_t *)nmalloc(sizeof(tcl_timer_t)); timer->next=old; timer->mins=mins; timer->cmd=(char *)nmalloc(strlen(cmd)+1); strcpy(timer->cmd,cmd); /* if it's just being added back and already had an id, don't */ /* create a new one */ if (prev_id>0) timer->id=prev_id; else timer->id=timer_id++; return timer->id; } /* remove a timer, by id */ int remove_timer(id) unsigned long id; { tcl_timer_t *mark=timer,*old; int ok=0; context; timer=NULL; while (mark!=NULL) { if (mark->id != id) add_timer(mark->mins,mark->cmd,mark->id); else ok++; old=mark; mark=mark->next; nfree(old->cmd); nfree(old); } return ok; } /* check timers, execute the ones that have expired */ void check_timers() { tcl_timer_t *mark=timer,*old; context; /* new timers could be added by a Tcl script inside a current timer */ /* so we just clear out the timer list completely, and any unexpired */ /* timers, we'll just add back */ timer=NULL; while (mark!=NULL) { mark->mins--; if (mark->mins == 0) { int code; set_tcl_vars(); code=Tcl_Eval(interp,mark->cmd); if (code!=TCL_OK) log(LOG_MISC,"(Timer) Error for '%s': %s",mark->cmd,interp->result); get_tcl_vars(); } else add_timer(mark->mins,mark->cmd,mark->id); context; old=mark; mark=mark->next; nfree(old->cmd); nfree(old); } } /* return list of timers */ void list_timers(irp) Tcl_Interp *irp; { tcl_timer_t *mark=timer; char s[512]; while (mark!=NULL) { sprintf(s,"%u %s timer%lu",mark->mins,mark->cmd,mark->id); Tcl_AppendElement(irp,s); mark=mark->next; } } /***********************************************************************/ #define STDVAR (cd,irp,argc,argv) \ ClientData cd; Tcl_Interp *irp; int argc; char *argv[]; #define BADARGS(nl,nh,example) \ if ((argc<(nl)) || (argc>(nh))) { \ Tcl_AppendResult(irp,"wrong # args: should be \"",argv[0], \ (example),"\"",NULL); \ return TCL_ERROR; \ } int tcl_logfile STDVAR { int i,ok=0; char s[151]; BADARGS(1,3," ??logModes? logFile?"); if (argc==1) { /* they just want a list of the logfiles and modes */ for (i=0; inick[0]) { Tcl_AppendElement(irp,m->nick); m=m->next; } return TCL_OK; } int tcl_putserv STDVAR { BADARGS(2,2," text"); mprintf(serv,"%s\n",argv[1]); return TCL_OK; } int tcl_puthelp STDVAR { BADARGS(2,2," text"); if (helpbot[0]) hprintf(helpsock,"%s\n",argv[1]); else mprintf(serv,"%s\n",argv[1]); return TCL_OK; } int tcl_putdcc STDVAR { int i; BADARGS(3,3," dccHandle text"); i=atoi(argv[1]); if ((i<0) || (i>=dcc_total)) { Tcl_AppendResult(interp,"dccHandle out of range",NULL); return TCL_ERROR; } if (dcc[i].type!=DCC_CHAT) { Tcl_AppendResult(irp,"illegal dccHandle type",NULL); return TCL_ERROR; } tprintf(dcc[i].sock,"%s\n",argv[2]); return TCL_OK; } int tcl_putlog STDVAR { int mode=(int)cd; BADARGS(2,2," text"); log(mode,"%s",argv[1]); 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]; 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; i=dcc_total)) { Tcl_AppendResult(irp,"dccHandle out of range",NULL); return TCL_ERROR; } if ((dcc[idx].type!=DCC_CHAT) && (dcc[idx].type!=DCC_FILES)) { Tcl_AppendResult(irp,"illegal dccHandle type",NULL); return TCL_ERROR; } if (got_dcc_cmd(idx,dcc[idx].sock,argv[2])) { /* sent .quit */ 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(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(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[81]; BADARGS(2,2," handle"); get_handle_info(argv[1],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getdccdir STDVAR { char s[81]; BADARGS(2,2," handle"); get_handle_dccdir(argv[1],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getcomment STDVAR { char s[81]; BADARGS(2,2," handle"); get_handle_comment(argv[1],s); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_getemail STDVAR { char s[81]; BADARGS(2,2," handle"); get_handle_email(argv[1],s); Tcl_AppendResult(irp,s,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_delban STDVAR { BADARGS(2,2," ban"); if (unprog_ban(argv[1])>0) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_isban STDVAR { BADARGS(2,2," ban"); if (equals_ban(argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_ispermban STDVAR { BADARGS(2,2," ban"); if (equals_ban(argv[1])==2) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_matchban STDVAR { BADARGS(2,2," user!nick@host"); if (match_ban(argv[1])) Tcl_AppendResult(irp,"1",NULL); else Tcl_AppendResult(irp,"0",NULL); return TCL_OK; } int tcl_addban STDVAR { time_t t=time(NULL); BADARGS(2,3," ban ?comment?"); if (argc==2) { /* no comment */ prog_ban(argv[1],t,""); if (me_op()) { add_mode('+','b',argv[1]); recheck_channel(); } } else { if (strlen(argv[2])>70) argv[2][70]=0; prog_ban(argv[1],t,argv[2]); if (me_op()) { add_mode('+','b',argv[1]); recheck_channel(); } } return TCL_OK; } int tcl_addpermban STDVAR { BADARGS(2,3," ban ?comment?"); if (argc==2) prog_ban(argv[1],0L,""); else { if (strlen(argv[2])>70) argv[2][70]=0; prog_ban(argv[1],0L,argv[2]); } if (me_op()) { add_mode('+','b',argv[1]); recheck_channel(); } 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_timers STDVAR { BADARGS(1,1,""); list_timers(irp); return TCL_OK; } int tcl_jump STDVAR { int port; BADARGS(1,3," ?server ?port??"); if (argc>=2) { strcpy(newserver,argv[1]); if (argc==3) newserverport=atoi(argv[2]); else newserverport=6667; } tprintf(serv,"QUIT :jumping servers\n"); sleep(1); close(serv); shutdown(serv,2); 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; BADARGS(3,3," filename ircnick"); /* copy it to /tmp */ sprintf(sys,"cp \"%s\" \"%s\"",argv[1],tempdir); system(sys); nfn=strrchr(argv[1],'/'); if (nfn==NULL) nfn=argv[1]; else nfn++; sprintf(sys,"%s%s",tempdir,nfn); /* new filename, in /tmp */ i=raw_dcc_send(sys,argv[2]); 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 { BADARGS(2,2," message"); chatout("*** %s\n",argv[1]); tandout("chat %s %s\n",origbotname,argv[1]); return TCL_OK; } int tcl_getidx STDVAR { int i; char s[10]; BADARGS(2,2," nickname"); for (i=0; ichannel); Tcl_AppendResult(irp,s,NULL); return TCL_OK; } int tcl_setchan STDVAR { int idx; BADARGS(3,3," idx channel"); idx=atoi(argv[1]); if (dcc[idx].type!=DCC_CHAT) { Tcl_AppendResult(irp,"invalid idx",NULL); return TCL_ERROR; } if ((atoi(argv[2]) < -1) || (atoi(argv[2]) > 99999)) { Tcl_AppendResult(irp,"channel out of range; must be -1 thru 99999",NULL); return TCL_ERROR; } dcc[idx].u.chat->channel=atoi(argv[2]); return TCL_OK; } int tcl_dccputchan STDVAR { int chan; 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; } chanout(chan,"*** %s\n",argv[2]); if (!isolate) tandout("chan %s %d %s\n",origbotname,chan,argv[2]); return TCL_OK; } int tcl_console STDVAR { int i,j,ok=0,pls; BADARGS(2,3," handle ?console-modes?"); for (i=0; icon_flags=0; for (j=0; jcon_flags|=logmodes(s); else dcc[i].u.chat->con_flags&=~logmodes(s); } } } if (!ok) Tcl_AppendResult(irp,masktype(dcc[i].u.chat->con_flags),NULL); ok=1; } return TCL_OK; } /**********************************************************************/ /* parse the 'servers' variable */ /* save and re-set the values of curserv and helpserv */ 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; helpserv=0; return; } code=Tcl_SplitList(interp,serv,&lc,&list); if (code==TCL_ERROR) { log(LOG_MISC,"Tcl error parsing server list:"); log(LOG_MISC,"%s",interp->result); return; } for (i=0; i' */ curserv=(-1); helpserv=(-1); if (botserver[0]) next_server(&curserv,botserver,&botserverport); if (helpserver[0]) next_server(&helpserv,helpserver,&helpserverport); } /* weird, weird, weird... */ void set_tcl_servers() { Tcl_DString ds; char *slist; int i; struct queue *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) { log(LOG_MISC,"Tcl error evaluating %s:",var); log(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) { log(LOG_MISC,"Tcl error evaluating %s:",var); log(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(); Tcl_DeleteCommand(interp,"exec"); /* 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,"puterror",tcl_putlog, (ClientData)(LOG_MISC|LOG_CHAN),NULL); Tcl_CreateCommand(interp,"putlog",tcl_putlog,(ClientData)LOG_MISC,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,"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,"onchan",tcl_onchan,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,"onchansplit",tcl_onchanSplit,NULL,NULL); Tcl_CreateCommand(interp,"chanlist",tcl_chanlist,NULL,NULL); Tcl_CreateCommand(interp,"bind",tcl_bind,NULL,NULL); Tcl_CreateCommand(interp,"adduser",tcl_adduser,NULL,NULL); Tcl_CreateCommand(interp,"maskhost",tcl_maskhost,NULL,NULL); Tcl_CreateCommand(interp,"dccSimul",tcl_dccSimul,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,"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,"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,"delban",tcl_delban,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,"addpermban",tcl_addpermban,NULL,NULL); Tcl_CreateCommand(interp,"getlaston",tcl_getlaston,NULL,NULL); Tcl_CreateCommand(interp,"timers",tcl_timers,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,"rehash",tcl_rehash,NULL,NULL); */ Tcl_CreateCommand(interp,"rand",tcl_rand,NULL,NULL); Tcl_CreateCommand(interp,"dccbroadcast",tcl_dccbroadcast,NULL,NULL); Tcl_CreateCommand(interp,"getidx",tcl_getidx,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); } /* 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("clear-bans",clearbans); tcl_setbool("op-on-join",op_on_join); tcl_setbool("revenge",revenge); tcl_setbool("greet",greet); tcl_setbool("learn-users",learn_users); tcl_setbool("require-x",require_x); tcl_setbool("require-p",require_p); tcl_setbool("enforce-bans",enforce_bans); 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("chan-updates",chan_updates); tcl_setbool("raw-files",raw_files); tcl_setbool("perm-bans",perm_bans); tcl_setbool("upload-to-cd",upload_to_cd); tcl_setbool("bitch",bitch); tcl_setbool("never-give-up",never_give_up); tcl_setbool("protect-ops",protect_ops); tcl_setbool("open-telnets",allow_new_telnets); /* 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("idle-kick",idle_kick); tcl_setint("dcc-maxsize",dcc_maxsize); /* strings */ tcl_setstr("nick",origbotname); tcl_setstr("username",botuser); tcl_setstr("realname",botrealname); tcl_setstr("home-channel",botchan); tcl_setstr("userfile",userfile); tcl_setstr("dcc-path",dccdir); tcl_setstr("dcc-incoming",dccin); tcl_setstr("motd",motdfile); tcl_setstr("admin",admin); tcl_setstr("gain-ops",gainops); tcl_setstr("init-server",initserver); tcl_setstr("notefile",notefile); tcl_setstr("helpbot",helpbot); tcl_setstr("helpdir",helpdir); tcl_setstr("tempdir",tempdir); tcl_setstr("textdir",textdir); tcl_setstr("channel-key",chankey); tcl_setstr("notify-newusers",notify_new); tcl_setstr("ctcp-version",ctcp_version); tcl_setstr("ctcp-finger",ctcp_finger); tcl_setstr("owner",owner); /* flags */ tcl_setchar("flag1",flag1); tcl_setchar("flag2",flag2); tcl_setchar("flag3",flag3); tcl_setchar("flag4",flag4); tcl_setchar("flag5",flag5); /* weird */ strcpy(s,masktype(conmask)); tcl_setstr("console",s); get_mode_protect(s); tcl_setstr("chanmode",s); flags2str(default_flags,s); tcl_setstr("default-flags",s); /* variables that we won't re-read... only for convenience of scripts */ tcl_setstr("channel",curchan); tcl_setstr("botnick",botname); sprintf(s,"%s:%d",botserver,botserverport); tcl_setstr("server",s); sprintf(s,"%s!%s",botname,botuserhost); tcl_setstr("botname",s); /* cos we have to: */ tcl_setstr("tcl_interactive","0"); } /* set eggdrop internal variables to match Tcl variables */ void get_tcl_vars() { char s[120],c; int had_helpbot=0,oldisol; get_tcl_servers(); /* on/off variables: */ tcl_bool("log-time",&shtime); tcl_bool("clear-bans",&clearbans); tcl_bool("op-on-join",&op_on_join); tcl_bool("revenge",&revenge); tcl_bool("greet",&greet); tcl_bool("learn-users",&learn_users); tcl_bool("require-x",&require_x); tcl_bool("require-p",&require_p); tcl_bool("enforce-bans",&enforce_bans); 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("chan-updates",&chan_updates); tcl_bool("raw-files",&raw_files); tcl_bool("perm-bans",&perm_bans); tcl_bool("upload-to-cd",&upload_to_cd); tcl_bool("bitch",&bitch); tcl_bool("never-give-up",&never_give_up); tcl_bool("protect-ops",&protect_ops); tcl_bool("open-telnets",&allow_new_telnets); /* numbers */ tcl_int("telnet",&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("idle-kick",&idle_kick); tcl_int("dcc-maxsize",&dcc_maxsize); /* strings */ tcl_str("nick",origbotname,9); tcl_str("username",botuser,10); tcl_str("realname",botrealname,80); tcl_str("home-channel",botchan,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("gain-ops",gainops,120); tcl_str("init-server",initserver,120); tcl_str("notefile",notefile,120); if (helpbot[0]) had_helpbot=1; tcl_str("helpbot",helpbot,10); if ((had_helpbot) && (!helpbot[0])) { log(LOG_MISC,"Killing the helpbot."); close(helpsock); shutdown(helpsock,2); helpsock=(-1); } if ((!had_helpbot) && (helpbot[0])) { if (online) log(LOG_MISC,"Spawning helpbot: %s",helpbot); helpsock=(-1); /* bot will find out that socket is bad, and connect */ } /* nick for helpbot probably changed */ if ((had_helpbot) && (helpbot[0])) hprintf(helpsock,"NICK %s\n",helpbot); 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("channel-key",chankey,120); tcl_str("notify-newusers",notify_new,120); tcl_str("ctcp-version",ctcp_version,120); tcl_str("ctcp-finger",ctcp_finger,120); tcl_str("owner",owner,120); /* user-defined flags */ tcl_char("flag1",&c); s[0]=c; s[1]=0; if (!(str2flags(s) & ~USER_FLAG1)) flag1=c; tcl_char("flag2",&c); s[0]=c; s[1]=0; if (!(str2flags(s) & ~USER_FLAG2)) flag2=c; tcl_char("flag3",&c); s[0]=c; s[1]=0; if (!(str2flags(s) & ~USER_FLAG3)) flag3=c; tcl_char("flag4",&c); s[0]=c; s[1]=0; if (!(str2flags(s) & ~USER_FLAG4)) flag4=c; tcl_char("flag5",&c); s[0]=c; s[1]=0; if (!(str2flags(s) & ~USER_FLAG5)) flag5=c; /* 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("chanmode",s,80); set_mode_protect(s); s[0]=0; tcl_str("default-flags",s,20); default_flags=str2flags(s); } /* evaluate a Tcl command, send output to a dcc user */ int cmd_tcl(idx,z,msg) int idx,z; char *msg; { int code; context; set_tcl_vars(); code=Tcl_Eval(interp,msg); if (code==TCL_OK) tprintf(z,"Tcl: %s\n",interp->result); else tprintf(z,"Tcl error: %s\n",interp->result); /* refresh internal vars */ get_tcl_vars(); } /* perform a 'set' command */ int cmd_set(idx,z,msg) int idx,z; char *msg; { int code; char s[512]; context; log(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"); code=Tcl_Eval(interp,s); if (code==TCL_OK) { if (strchr(msg,' ')==NULL) tprintf(z,"currently: %s\n",interp->result); else tprintf(z,"Ok, set.\n"); } else tprintf(z,"Error: %s\n",interp->result); get_tcl_vars(); } /* read and interpret the configfile given */ /* return 1 if everything was okay */ int readtclprog(fname) char *fname; { int code; context; set_tcl_vars(); 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",interp->result); } else { log(LOG_MISC,"Tcl error in file '%s':",fname); log(LOG_MISC,"%s",interp->result); } return 0; } /* refresh internal variables */ get_tcl_vars(); return 1; }