/* read in programming for the channel from "channel" */ /* also some of the ban stuff is here */ /* totally different format for startup file now (27jan94) */ #include #include #include #include "eggdrop.h" extern int serv; extern int spymode; extern int spypub; extern int shtime; extern int op_on_join; extern int revenge; extern int telnet_port; extern int min_servs; extern int log_joins; extern int curserv; extern char botname[]; extern char bothost[]; extern char origbotname[]; extern char botuser[]; extern char botrealname[]; extern char botserver[]; extern char botchan[]; extern char curchan[]; extern char configfile[]; extern char logfile[]; extern char dccdir[]; extern char dccin[]; extern char motdfile[]; extern char admin[]; extern char gainops[]; extern char userfile[]; extern char helpbot[]; extern char helpserver[]; extern char helpdir[]; extern int botserverport; extern int nosave; extern int dcc_total; extern int use_stderr; extern int greet; extern int learn_users; extern int helpserverport; extern int helpserv; extern struct dcc_t dcc[]; char oldchan[121]=""; char oldnick[10]=""; /* clear old bans from the channel when we get ops? */ int clearbans=0; /* where to store notes */ char notefile[121]; /* old-style queue, still used by server list */ struct queue { char *item; struct queue *next; } *serverlist=NULL; /* remove space characters from beginning and end of string */ void rmspace(s) char *s; { while ((s[strlen(s)-1]<=32) && (strlen(s)>0)) s[strlen(s)-1]=0; while ((s[0]<=32) && (s[0]!=0)) strcpy(s,&s[1]); } /* memory we should be using */ int expmem_chanprog() { int tot; struct queue *s=serverlist; tot=0; while (s!=NULL) { tot+=strlen(s->item)+1; tot+=sizeof(struct queue); s=s->next; } return tot; } /* add someone to a queue */ struct queue *addq(ss,q) char *ss; struct queue *q; { char s[512]; struct queue *x; char s1[121],*p; strcpy(s,ss); do { p=strchr(s,','); if (p!=NULL) { *p=0; p++; strcpy(s1,p); } else s1[0]=0; rmspace(s); rmspace(s1); x=(struct queue *)nmalloc(sizeof(struct queue)); x->next=q; x->item=(char *)nmalloc(strlen(s)+1); strcpy(x->item,s); s[0]=0; strcpy(s,s1); } while (s[0]); return x; } /* remove someone from a queue */ struct queue *delq(s,q,ok) char *s; struct queue *q; int *ok; { struct queue *x,*x1,*ret,*old; x=q; ret=q; old=q; *ok=0; while (x!=NULL) { if (strcasecmp(x->item,s)==0) { if (x==ret) { ret=(x->next); nfree(x->item); nfree(x); x=ret; } else { old->next=x->next; nfree(x->item); nfree(x); x=old->next; } *ok=1; } else { old=x; x=x->next; } } return ret; } /* clear out a list */ void clearq(xx) struct queue *xx; { struct queue *x,*x1; x=xx; while (x!=NULL) { x1=x->next; nfree(x->item); nfree(x); x=x1; } } /* new server to the list */ prog_server(s) char *s; { serverlist=addq(s,serverlist); } int unprog_server(s) char *s; { int i; serverlist=delq(s,serverlist,&i); return i; } /* set botserver to the next available server */ /* we gotta move through the queue from end to front, cos the entries were */ /* pushed on from the config file stack-fashion, with the last entry ending */ /* up as the head of the queue */ /* -> if (*ptr == -1) then jump to that particular server */ void next_server(ptr,serv,port) int *ptr,*port; char *serv; { struct queue *x=serverlist; int ok=1,i; char s[121]; if (x==NULL) return; /* if it's the queue head, go to the end and start back again */ if (*ptr == -1) { char sv[121]; int p; ok=0; i=0; while ((x->next!=NULL) && (!ok)) { strcpy(s,x->item); splitc(sv,s,':'); if (!sv[0]) { strcpy(sv,s); p=6667; } else { p=atoi(s); } if ((strcasecmp(sv,serv)==0) && (p==*port)) ok=1; else { x=x->next; i++; } } if (ok) { *ptr=i; return; } /* requested server is valid */ /* gotta add it : */ sprintf(s,"%s:%d",serv,*port); serverlist=addq(s,serverlist); *ptr=0; return; } else if (*ptr == 0) { while (x->next!=NULL) { (*ptr)++; x=x->next; } strcpy(s,x->item); splitc(serv,s,':'); if (!serv[0]) { strcpy(serv,s); *port=6667; } else { *port=atoi(s); } return; } i=(*ptr)-1; *ptr=i; while ((i>0) && (ok)) { x=x->next; i--; if (x->next==NULL) ok=0; /* not in list, so just start at beginning */ } strcpy(s,x->item); splitc(serv,s,':'); if (!serv[0]) { strcpy(serv,s); *port=6667; } else { *port=atoi(s); } } /* revenge tactic: person did something bad */ /* if they're oplisted, remove them from the op list */ /* otherwise, deop them */ void unprog_op_and_deop(who,reason) char *who; char *reason; { char nick[10],s[121],s1[121],*p,*q; if (match_friend(who)) { console("%s is protected (%s)",who,reason); return; /* argh! */ } if (unprog_op(who)) { console("No longer opping %s (%s)",who,reason); return; } if (match_deop(who)) return; /* they're already deopped */ if (prog_deop(who)) { /* in the user list already, cool :) */ console("Now deopping %s (%s)",who,reason); return; } strcpy(s1,who); splitnick(nick,s1); maskhost(s1,s); adduser(nick,s,"nopass",USER_DEOP); console("Now deopping %s (%s)",who,reason); } void add_a_ban(user,plus) char *user; char plus; { static char bans[161]=""; static int bancnt=0; static char banmode[10]=""; static char last='+'; if (user[0]!='.') { bancnt++; if (bans[0]) strcat(bans," "); if (banmode[0]==0) { banmode[1]=0; banmode[0]=plus; last=plus; } if (plus!=last) { banmode[strlen(banmode)+1]=0; banmode[strlen(banmode)]=plus; } strcat(bans,user); strcat(banmode,"b"); last=plus; } if ((bancnt==3) || (user[0]=='.')) { if (bancnt) tprintf(serv,"MODE %s %s %s\n",curchan,banmode,bans); banmode[0]=0; bans[0]=0; bancnt=0; last='+'; } } void add_ban(user) char *user; { add_a_ban(user,'+'); } void add_deban(user) char *user; { add_a_ban(user,'-'); } void flush_ban() { add_a_ban(".",'.'); } /* got 368: end of ban list */ void got368(from,msg) char *from,*msg; { /* add bans that should be there but aren't */ if (clearbans) resetbans(); else recheck_bans(); /* ^this also flushes the deban if i found myself in the list */ /* (see got367 in chan.c) */ } /* clear out the programming */ void clearprog() { clear_userlist(); clearq(serverlist); serverlist=NULL; strcpy(oldchan,curchan); strcpy(oldnick,botname); } #define PSET(x) { (x)=ans; \ if (z) tprintf(z,"Set %s %s.\n",which,ans?"on":"off"); } #define ONOFF(z,x,y) tprintf(z,"%s %s\n",x,y?"ON":"OFF") /* set an on/off switch */ void prog_set(this,z) char *this; int z; { char which[41]; int ans; if (this[0]==0) { if (z) { ONOFF(z,"spy",spymode); ONOFF(z,"log-time",shtime); ONOFF(z,"spy-public",spypub); ONOFF(z,"clear-bans",clearbans); ONOFF(z,"op-on-join",op_on_join); ONOFF(z,"revenge",revenge); ONOFF(z,"log-joins",log_joins); ONOFF(z,"greet",greet); ONOFF(z,"learn-users",learn_users); } return; } split(which,this); if (strcasecmp(this,"on")==0) ans=1; else if (strcasecmp(this,"off")==0) ans=0; else if (strcasecmp(this,"yes")==0) ans=1; else if (strcasecmp(this,"no")==0) ans=0; else if (strcasecmp(this,"true")==0) ans=1; else if (strcasecmp(this,"false")==0) ans=0; else if ((this[0]=='Y') || (this[0]=='y') || (this[0]=='t') || (this[0]=='T')) ans=1; else if ((this[0]=='n') || (this[0]=='N') || (this[0]=='F') || (this[0]=='f')) ans=0; else return; if (strcasecmp(which,"spy")==0) PSET(spymode) else if (strcasecmp(which,"log-time")==0) PSET(shtime) else if (strcasecmp(which,"spy-public")==0) PSET(spypub) else if (strcasecmp(which,"clear-bans")==0) PSET(clearbans) else if (strcasecmp(which,"op-on-join")==0) PSET(op_on_join) else if (strcasecmp(which,"revenge")==0) PSET(revenge) else if (strcasecmp(which,"log-joins")==0) PSET(log_joins) else if (strcasecmp(which,"greet")==0) PSET(greet) else if (strcasecmp(which,"learn-users")==0) PSET(learn_users) else { if (z) tprintf(z,"No such variable.\n"); else { if (use_stderr) fprintf(stderr,"* Warning: Unknown set variable '%s'\n",which); } return; } } /* zones of config file */ #define SETZONE 1 #define SERVERSZONE 2 #define MISCZONE 3 #define UNKNOWN 4 /* read in the channel programming */ int readprog(file) char *file; { char *p,code[41],s[121]; FILE *f; int zone=UNKNOWN,i; f=fopen(file,"r"); if (f==NULL) return 0; nosave=1; while (!feof(f)) { fgets(s,120,f); if (!feof(f)) { p=strchr(s,';'); if (p!=NULL) *p=0; rmspace(s); if ((s[0]!='#') && (s[0]!=';') && (s[0])) { if (s[0]=='@') { /* new zone */ strcpy(s,&s[1]); if (strcasecmp(s,"set")==0) zone=SETZONE; else if (strcasecmp(s,"servers")==0) zone=SERVERSZONE; else if (strcasecmp(s,"misc")==0) zone=MISCZONE; else { if (use_stderr) fprintf(stderr,"* Warning: unknown config-file zone '%s'\n",s); zone=UNKNOWN; } } else { if (zone==MISCZONE) { split(code,s); if (code[0]==0) { strcpy(code,s); s[0]=0; } if (strcasecmp(code,"nick")==0) { s[10]=0; strcpy(botname,s); strcpy(origbotname,s); } else if (strcasecmp(code,"user")==0) { s[10]=0; strcpy(botuser,s); } else if (strcasecmp(code,"realname")==0) strcpy(botrealname,s); else if (strcasecmp(code,"channel")==0) strcpy(botchan,s); else if (strcasecmp(code,"logfile")==0) strcpy(logfile,s); else if (strcasecmp(code,"userfile")==0) strcpy(userfile,s); else if (strcasecmp(code,"dcc-path")==0) strcpy(dccdir,s); else if (strcasecmp(code,"dcc-incoming")==0) strcpy(dccin,s); else if (strcasecmp(code,"load")==0) readprog(s); else if (strcasecmp(code,"telnet")==0) telnet_port=atoi(s); else if (strcasecmp(code,"motd")==0) strcpy(motdfile,s); else if (strcasecmp(code,"servlimit")==0) min_servs=atoi(s); else if (strcasecmp(code,"admin")==0) strcpy(admin,s); else if (strcasecmp(code,"gain-ops")==0) strcpy(gainops,s); else if (strcasecmp(code,"notefile")==0) strcpy(notefile,s); else if (strcasecmp(code,"helpbot")==0) { s[10]=0; strcpy(helpbot,s); } else if (strcasecmp(code,"helpdir")==0) strcpy(helpdir,s); else { if (use_stderr) fprintf(stderr,"* Warning: unknown misc setting '%s'\n",code); } } else if (zone==SETZONE) prog_set(s,0); else if (zone==SERVERSZONE) { p=strchr(s,','); while (p!=NULL) { splitc(code,s,','); rmspace(code); rmspace(s); if (code[0]) prog_server(code); p=strchr(s,','); } if (s[0]) prog_server(s); } else if (zone==UNKNOWN) ; /* do nothing */ } } } } nosave=0; fclose(f); return 1; } void chanprog() { /* strcpy(savefile,configfile); */ if (!readprog(configfile)) fatal("CONFIGURATION FILE NOT FOUND!"); if (!botchan[0]) fatal("NO HOME CHANNEL."); if (!botname[0]) fatal("NO BOT NAME."); if (!userfile[0]) fatal("NO USER FILE."); if (!readuserfile(userfile)) fatal("USER FILE NOT FOUND!"); if (serverlist==NULL) fatal("NO SERVER."); } void rehash() { clearprog(); chanprog(); if ((strcasecmp(oldnick,botname)!=0) && (oldnick[0])) tprintf(serv,"NICK %s\n",botname); if ((strcasecmp(oldchan,curchan)!=0) && (oldchan[0])) { tprintf(serv,"PART %s\n",oldchan); tprintf(serv,"JOIN %s\n",botchan); } /* update stuff, as if we just got control of the channel again: */ recheck_channel(); } void get_first_server() { strcpy(botserver,serverlist->item); next_server(&curserv,botserver,&botserverport); next_server(&helpserv,helpserver,&helpserverport); }