/* chanprog.c -- handles: maintaining the server list revenge punishment reading the config file (non-Tcl) dprintf'ized, 1nov95 */ /* config file format changed 27jan94 (Tcl outdates that) */ #define _CHANPROG #if HAVE_CONFIG_H #include #endif #include #include #include #include /* for mips */ #include "eggdrop.h" #include "users.h" #include "proto.h" extern int serv; extern int shtime; extern int op_on_join; extern int revenge; extern int telnet_port; extern int min_servs; extern int curserv; extern char botname[]; extern char origbotname[]; extern char botuser[]; extern char bothost[]; extern char botrealname[]; extern char botserver[]; extern char botchan[]; extern char curchan[]; extern char configfile[]; extern char dccdir[]; extern char dccin[]; extern char motdfile[]; extern char admin[]; #ifdef TCL extern char need_op[]; extern char need_invite[]; #else extern char gainops[]; #endif extern char userfile[]; extern char helpbot[]; extern char helpserver[]; extern char helpdir[]; extern char initserver[]; extern char chankey[]; extern char notify_new[]; extern char tempdir[]; extern char ctcp_version[]; extern char ctcp_finger[]; extern char ctcp_userinfo[]; extern char textdir[]; extern char owner[]; extern int botserverport; extern int dcc_total; extern int use_stderr; extern int greet; extern int learn_users; extern int helpserverport; extern int helpserv; extern int flood_thr; extern int flood_pub_thr; extern int flood_join_thr; extern int require_x; extern int enforce_bans; extern int share_users; extern int use_info; extern int passive; extern int strict_host; extern int noshare; extern int require_p; extern int isolate; extern int conmask; extern int default_flags; extern int keep_all_logs; extern int chan_updates; extern int raw_files; extern int perm_bans; extern int ban_time; extern int ignore_time; extern int make_userfile; extern int upload_to_cd; extern int dcc_limit; extern int idle_kick; extern int bitch; extern int never_give_up; extern int protect_ops; extern int allow_new_telnets; extern int forbid_bans; extern int keepnick; extern int dcc_block; extern int dcc_maxsize; extern int dcc_users; extern struct dcc_t dcc[]; extern char *logfile[]; extern int logmask[]; extern char cx_file[]; extern int cx_line; extern struct userrec *userlist; extern char SBUF[]; 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 eggqueue *serverlist=NULL; /* remove space characters from beginning and end of string */ /* (more efficent by Fred1) */ void rmspace(s) char *s; { #define whitespace(c) ( ((c)==32) || ((c)==9) || ((c)==13) || ((c)==10) ) char *p; /* wipe end of string */ for (p=s+strlen(s)-1; ((whitespace(*p))&&(p>=s)); p--); if (p!=s+strlen(s)-1) *(p+1)=0; for (p=s; ((whitespace(*p)) && (*p)); p++); if (p!=s) strcpy(s,p); } /* memory we should be using */ int expmem_chanprog() { int tot; struct eggqueue *s=serverlist; tot=0; while (s!=NULL) { tot+=strlen(s->item)+1; tot+=sizeof(struct eggqueue); s=s->next; } #ifndef TCL { int i; for (i=0; inext=NULL; x->item=(char *)nmalloc(strlen(s)+1); strcpy(x->item,s); if (q==NULL) q=x; else { z=q; while (z->next!=NULL) z=z->next; z->next=x; } s[0]=0; strcpy(s,s1); } while (s[0]); return q; } /* remove someone from a queue */ struct eggqueue *delq(s,q,ok) char *s; struct eggqueue *q; int *ok; { struct eggqueue *x,*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 eggqueue *xx; { struct eggqueue *x,*x1; x=xx; while (x!=NULL) { x1=x->next; nfree(x->item); nfree(x); x=x1; } } /* new server to the list */ void add_server(s) char *s; { serverlist=addq(s,serverlist); } /* set botserver to the next available server */ /* -> if (*ptr == -1) then jump to that particular server */ void next_server(ptr,serv,port,pass) int *ptr,*port; char *serv,*pass; { struct eggqueue *x=serverlist; int ok=1,i; char s[121]; context; if (x==NULL) return; /* -1 --> go to specified server */ if (*ptr == -1) { char sv[121]; int p; ok=0; i=0; while ((x!=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); if (pass[0]) { strcat(s,":"); strcat(s,pass); } serverlist=addq(s,serverlist); *ptr=i; return; } /* find where i am and boogey */ i=(*ptr); while ((i>0) && (x!=NULL)) { x=x->next; i--; } if (x!=NULL) { x=x->next; (*ptr)++; } /* go to next server */ if (x==NULL) { x=serverlist; *ptr=0; } /* start over at the beginning */ pass[0]=0; strcpy(s,x->item); splitc(serv,s,':'); if (!serv[0]) { strcpy(serv,s); *port=6667; } else { char xs[121]; *port=atoi(s); splitc(xs,s,':'); if (xs[0]) strcpy(pass,s); } return; } /* show server list, and point out which ones the bot and helpbot are on */ void tell_servers(idx) int idx; { struct eggqueue *x=serverlist; int i,sp; char s[141],sv[121]; context; if (x==NULL) { dprintf(idx,"No servers.\n"); return; } dprintf(idx,"My server list:\n"); i=0; while (x!=NULL) { strcpy(s,x->item); splitc(sv,s,':'); if (!sv[0]) { strcpy(sv,s); sp=6667; } else sp=atoi(s); sprintf(s," %s:%d",sv,sp); if (i==curserv) strcat(s," <- I am here."); if ((helpbot[0]) && (i==helpserv)) strcat(s," <- The helpbot is here."); dprintf(idx,"%s\n",s); x=x->next; i++; } } void wipe_serverlist() { if (serverlist==NULL) return; clearq(serverlist); serverlist=NULL; } /* 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]; int i,atr; context; atr=get_attr_host(who); if (atr & USER_FRIEND) { log(LOG_MISC,"%s is a friend (%s)",who,reason); return; /* argh! */ } if (change_attr(who,'-',USER_OP)) { log(LOG_MISC,"No longer opping %s (%s)",who,reason); return; } if (match_ban(who)) { /* what more can we do? */ return; } if (atr & USER_DEOP) { /* this is out of control: BAN THEM */ log(LOG_MISC,"Now banning %s (%s)",who,reason); strcpy(s1,who); splitnick(nick,s1); maskhost(s1,s); strcpy(s1,"*!*"); strcat(s1,&s[2]); /* add extra * for ban */ prog_ban(s1,time(NULL),reason); return; } if (change_attr(who,'+',USER_DEOP)) { /* in the user list already, cool :) */ log(LOG_MISC,"Now deopping %s (%s)",who,reason); return; } strcpy(s1,who); splitnick(nick,s1); maskhost(s1,s); while (is_user(nick)) { if (strncmp(nick,"bad",3)==0) { i=atoi(&nick[3]); sprintf(nick,"bad%d",i+1); } else strcpy(nick,"bad1"); } userlist=adduser(userlist,nick,s,"nopass",USER_DEOP); sprintf(s,"%s (%s)",who,reason); set_handle_comment(userlist,nick,s); log(LOG_MISC,"Now deopping %s (%s)",who,reason); } /* clear out the programming */ void clearprog() { context; clear_userlist(userlist); userlist=NULL; clearq(serverlist); serverlist=NULL; strcpy(oldchan,curchan); strcpy(oldnick,botname); } /* Tcl has its own much simpler 'set' */ #ifndef TCL #define PSET(x) { (x)=ans; \ if (idx>=0) dprintf(idx,"Set %s %s.\n",which,ans?"on":"off"); } #define ONOFF(idx,x,y,x1,y1) dprintf(idx,"%-15s %3s %-15s %3s\n",x,y? \ "ON":"OFF",x1,(y1==(-1)?"":(y1?"ON":"OFF"))) /* set an on/off switch */ void prog_set(this,idx) char *this; int idx; { char which[41]; int ans; context; if (this[0]==0) { if (idx>=0) { ONOFF(idx,"log-time",shtime,"isolate",isolate); ONOFF(idx,"clear-bans",clearbans,"keep-all-logs",keep_all_logs); ONOFF(idx,"op-on-join",op_on_join,"chan-updates",chan_updates); ONOFF(idx,"revenge",revenge,"raw-files",raw_files); ONOFF(idx,"greet",greet,"perm-bans",perm_bans); ONOFF(idx,"learn-users",learn_users,"upload-to-cd",upload_to_cd); ONOFF(idx,"require-x",require_x,"bitch",bitch); ONOFF(idx,"require-p",require_p,"never-give-up",never_give_up); ONOFF(idx,"enforce-bans",enforce_bans,"protect-ops",protect_ops); ONOFF(idx,"use-info",use_info,"forbid-bans",forbid_bans); ONOFF(idx,"share-users",share_users,"keep-nick",keepnick); ONOFF(idx,"open-telnets",allow_new_telnets,"",-1); ONOFF(idx,"passive",passive,"",-1); ONOFF(idx,"strict-host",strict_host,"",-1); } return; } split(which,this); if (strcasecmp(this,"on")==0) ans=1; else if (strcasecmp(this,"off")==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,"log-time")==0) PSET(shtime) 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,"greet")==0) PSET(greet) else if (strcasecmp(which,"learn-users")==0) PSET(learn_users) else if (strcasecmp(which,"require-x")==0) PSET(require_x) else if (strcasecmp(which,"require-p")==0) PSET(require_p) else if (strcasecmp(which,"enforce-bans")==0) PSET(enforce_bans) else if (strcasecmp(which,"use-info")==0) PSET(use_info) else if (strcasecmp(which,"share-users")==0) PSET(share_users) else if (strcasecmp(which,"passive")==0) PSET(passive) else if (strcasecmp(which,"strict-host")==0) PSET(strict_host) else if (strcasecmp(which,"keep-all-logs")==0) PSET(keep_all_logs) else if (strcasecmp(which,"chan-updates")==0) PSET(chan_updates) else if (strcasecmp(which,"raw-files")==0) PSET(raw_files) else if (strcasecmp(which,"perm-bans")==0) PSET(perm_bans) else if (strcasecmp(which,"upload-to-cd")==0) PSET(upload_to_cd) else if (strcasecmp(which,"bitch")==0) PSET(bitch) else if (strcasecmp(which,"never-give-up")==0) PSET(never_give_up) else if (strcasecmp(which,"protect-ops")==0) PSET(protect_ops) else if (strcasecmp(which,"open-telnets")==0) PSET(allow_new_telnets) else if (strcasecmp(which,"forbid-bans")==0) PSET(forbid_bans) else if (strcasecmp(which,"keep-nick")==0) PSET(keepnick) else if (strcasecmp(which,"isolate")==0) { PSET(isolate) if (idx>=0) { if (isolate) chatout("*** Party line is now isolated.\n"); else chatout("*** Party line is now open.\n"); if (isolate) tandout("chat %s Isolating my party line.\n",origbotname); else tandout("chat %s Merging my party line.\n",origbotname); } } else { if (idx>=0) dprintf(idx,"No such variable.\n"); else { if (use_stderr) fprintf(stderr,"* Warning: Unknown set variable '%s'\n",which); } return; } } #endif (!defined TCL) int logmodes(s) char *s; { int i; int res=0; for (i=0; i=0)) { dprintf(idx,"Variable definitions:\n"); dprintf(idx," nick: %s\n",origbotname); dprintf(idx," user: %s\n",botuser); dprintf(idx," realname: %s\n",botrealname); dprintf(idx," channel: %s\n",botchan); dprintf(idx," userfile: %s\n",userfile); dprintf(idx," dcc-path: %s\n",dccdir); dprintf(idx," dcc-incoming: %s\n",dccin); dprintf(idx," dcc-limit: %d\n",dcc_limit); dprintf(idx," dcc-block: %d\n",dcc_block); dprintf(idx," dcc-maxsize: %d\n",dcc_maxsize); dprintf(idx," dcc-users: %d\n",dcc_users); dprintf(idx," telnet: %u\n",telnet_port); dprintf(idx," motd: %s\n",motdfile); dprintf(idx," servlimit: %u\n",min_servs); dprintf(idx," admin: %s\n",admin); dprintf(idx," gain-ops: %s\n",gainops); dprintf(idx," init-server: %s\n",initserver); dprintf(idx," notefile: %s\n",notefile); dprintf(idx," flood-msg: %u\n",flood_thr); dprintf(idx," flood-chan: %u\n",flood_pub_thr); dprintf(idx," flood-join: %u\n",flood_join_thr); dprintf(idx," ban-time: %u min\n",ban_time); dprintf(idx," ignore-time: %u min\n",ignore_time); dprintf(idx," idle-kick: %u min\n",idle_kick); dprintf(idx," helpbot: %s\n",helpbot); dprintf(idx," helpdir: %s\n",helpdir); dprintf(idx," tempdir: %s\n",tempdir); dprintf(idx," textdir: %s\n",textdir); dprintf(idx," channel-key: %s\n",chankey); dprintf(idx," notify-newusers: %s\n",notify_new); dprintf(idx," ctcp-version: %s\n",ctcp_version); dprintf(idx," ctcp-finger: %s\n",ctcp_finger); dprintf(idx," ctcp-userinfo: %s\n",ctcp_userinfo); dprintf(idx," owner: %s\n",owner); flags2str(default_flags,s); dprintf(idx," default-flags: %s\n",s); for (i=0; i=0) dprintf(idx,"No... it's too late for that. :)\n"); else { value[9]=0; strcpy(helpbot,value); ok=1; } } else if (strcasecmp(var,"helpdir")==0) { strcpy(helpdir,value); ok=1; if (helpdir[strlen(helpdir)-1]!='/') strcat(helpdir,"/"); } else if (strcasecmp(var,"tempdir")==0) { strcpy(tempdir,value); ok=1; if (tempdir[strlen(tempdir)-1]!='/') strcat(tempdir,"/"); } else if (strcasecmp(var,"textdir")==0) { strcpy(textdir,value); ok=1; if (textdir[strlen(textdir)-1]!='/') strcat(textdir,"/"); } else if (strcasecmp(var,"ctcp-version")==0) { strcpy(ctcp_version,value); ok=1; } else if (strcasecmp(var,"ctcp-finger")==0) { strcpy(ctcp_finger,value); ok=1; } else if (strcasecmp(var,"ctcp-userinfo")==0) { strcpy(ctcp_userinfo,value); ok=1; } else if (strcasecmp(var,"owner")==0) { strcpy(owner,value); ok=1; } else if (strcasecmp(var,"channel-key")==0) { strcpy(chankey,value); ok=1; } else if (strcasecmp(var,"notify-newusers")==0) { strcpy(notify_new,value); ok=1; } else if (strcasecmp(var,"logfile")==0) { int j=0; char xx[121]; for (i=0; i=0) dprintf(idx,"New logfile: '%s' (%s)\n",value, maskname(logmask[i])); } } else if (strcasecmp(var,"chanmode")==0) { set_mode_protect(value); ok=4; get_mode_protect(s); if (idx>=0) dprintf(idx,"Defined 'chanmode' as: %s\n",s); } else if (strcasecmp(var,"console")==0) { conmask=logmodes(value); ok=4; if (idx>=0) dprintf(idx,"Defined 'console' as: %s\n",maskname(conmask)); } else if (strcasecmp(var,"default-flags")==0) { default_flags=str2flags(value); ok=1; } else { if (idx<0) { if (use_stderr) fprintf(stderr,"* Warning: unknown misc setting '%s'\n",var); } else dprintf(idx,"Cannot define '%s'.\n",var); return; } if (idx>=0) { if (ok==1) dprintf(idx,"Defined '%s' as: %s\n",var,value); if (ok==2) dprintf(idx,"Loaded: %s\n",value); if (ok==3) dprintf(idx,"Defined '%s' to %d.\n",var,atoi(value)); } } #endif /* !Tcl */ /* zones of config file */ #define SETZONE 1 #define SERVERSZONE 2 #define MISCZONE 3 #define UNKNOWN 4 #ifndef TCL /* read in the channel programming: non-tcl */ int readprog(file) char *file; { char *p,code[41],s[121]; FILE *f; int zone=UNKNOWN,i; context; f=fopen(file,"r"); if (f==NULL) return 0; noshare=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; } define(-1,code,s); } else if (zone==SETZONE) prog_set(s,-1); else if (zone==SERVERSZONE) { p=strchr(s,','); while (p!=NULL) { splitc(code,s,','); rmspace(code); rmspace(s); if (code[0]) add_server(code); p=strchr(s,','); } if (s[0]) add_server(s); } else if (zone==UNKNOWN) ; /* do nothing */ } } } } noshare=0; fclose(f); return 1; } #endif /* !Tcl */ void chanprog() { int i; strcpy(botuser,"bot"); strcpy(botrealname,"eggdrop bot"); admin[0]=0; helpdir[0]=0; initserver[0]=0; textdir[0]=0; #ifdef TCL need_op[0]=0; need_invite[0]=0; #else gainops[0]=0; #endif notefile[0]=0; dccdir[0]=0; dccin[0]=0; tempdir[0]=0; for (i=0; i