/* deal with msgs from people */ #include #include #include #include #include "eggdrop.h" extern int serv; extern int spymode; extern char botname[]; extern char botuser[]; extern char bothost[]; extern char curchan[]; extern int dcc_total; extern struct dcc_t dcc[]; extern char version[]; extern char dccdir[]; extern char notefile[]; extern char helpbot[]; extern int helpsock; extern char helpdir[]; #define STDOUT 1 /* let unknown users greet us and become known */ int learn_users=0; /* total messages queued on main bot */ int mtot=0; /* total messages queued on the help bot */ int htot=0; /* new server? */ char newserver[121]; /* new server port? */ int newserverport=0; /* msg queue for sending out msgs */ struct msgq { int sock; char *msg; struct msgq *next; } *mq=NULL,*hq=NULL; char *get_user_by_handle(); /* expected memory usage */ int expmem_cmds() { int tot=0; struct msgq *m=mq,*h=hq; while (m!=NULL) { tot+=strlen(m->msg)+1; tot+=sizeof(struct msgq); m=m->next; } while (h!=NULL) { tot+=strlen(h->msg)+1; tot+=sizeof(struct msgq); h=h->next; } return tot; } /* use when sending msgs... only send one msg at a time */ void mprintf(va_alist) va_dcl { char s[512]; int sock; char *format; va_list va; struct msgq *q; int cnt=0; va_start(va); sock=va_arg(va,int); format=va_arg(va,char *); vsprintf(s,format,va); va_end(va); if (mq==NULL) { mq=(struct msgq *)nmalloc(sizeof(struct msgq)); mq->sock=sock; mq->next=NULL; mq->msg=(char *)nmalloc(strlen(s)+1); mtot++; strcpy(mq->msg,s); return; } q=mq; while (q->next != NULL) { q=q->next; cnt++; } if (cnt>MAXQMSG) { console("!!! OVER MAXIMUM MSG QUEUE"); return; } q->next=(struct msgq *)nmalloc(sizeof(struct msgq)); q=q->next; q->sock=sock; q->next=NULL; q->msg=(char *)nmalloc(strlen(s)+1); strcpy(q->msg,s); mtot++; } /* like mprintf, for the helpbot */ void hprintf(va_alist) va_dcl { char s[512]; int sock; char *format; va_list va; struct msgq *q; int cnt=0; va_start(va); sock=va_arg(va,int); format=va_arg(va,char *); vsprintf(s,format,va); va_end(va); if (!helpbot[0]) { /* no helpbot! */ mprintf(serv,"%s",s); return; } if (hq==NULL) { hq=(struct msgq *)nmalloc(sizeof(struct msgq)); hq->sock=sock; hq->next=NULL; hq->msg=(char *)nmalloc(strlen(s)+1); htot++; strcpy(hq->msg,s); return; } q=hq; while (q->next != NULL) { q=q->next; cnt++; } if (cnt>MAXQMSG) { console("!!! OVER MAXIMUM HELP MSG QUEUE"); return; } q->next=(struct msgq *)nmalloc(sizeof(struct msgq)); q=q->next; q->sock=sock; q->next=NULL; q->msg=(char *)nmalloc(strlen(s)+1); strcpy(q->msg,s); htot++; } /* call this once a second to send out another msg if any are still queued */ void deq_msg() { struct msgq *q; if (mq==NULL) return; write(mq->sock,mq->msg,strlen(mq->msg)); q=mq; mq=mq->next; nfree(q->msg); nfree(q); mtot--; } /* call this once a second to send out another msg from the helpbot */ void deq_helpmsg() { struct msgq *h; if (hq==NULL) return; write(hq->sock,hq->msg,strlen(hq->msg)); h=hq; hq=hq->next; nfree(h->msg); nfree(h); htot--; } void maskhost(s,nw) char *s,*nw; { char *p,*q,xx[150]; strcpy(xx,s); p=strchr(xx,'!'); if (p!=NULL) strcpy(xx,p+1); p=strchr(xx,'@'); if (p!=NULL) { q=strchr(p,'.'); if (strchr(q+1,'.')==NULL) { /* form xx@yy.com -> don't truncate */ sprintf(nw,"*!%s",xx); return; } if ((xx[strlen(xx)-1] >= '0') && (xx[strlen(xx)-1]<='9')) { /* ip number -> xx@#.#.#.* */ q=strrchr(p,'.'); if (q!=NULL) strcpy(q,".*"); sprintf(nw,"*!%s",xx); return; } /* form xx@yy.zz.etc.edu or whatever -> xx@*zz.etc.edu */ if (q!=NULL) { *(p+1)='*'; strcpy(p+2,q+1); } sprintf(nw,"*!%s",xx); } else strcpy(nw,"*"); } void gotcmd(nick,from,msg) char *nick,*from,*msg; { char s[121],code[512],total[512],s1[81]; sprintf(s,"%s!%s",nick,from); strcpy(total,msg); split(code,msg); if (code[0]==0) { strcpy(code,msg); msg[0]=0; } /* the few commands allowed to normal people? */ if ((learn_users) && (strcasecmp(code,"hello")==0)) { char xx[20],host[120],*p,*q; get_handle_by_host(xx,s); if (xx[0]=='*') { maskhost(s,host); adduser(nick,host,"nopass",0); console("Introduced to [%s]%s",nick,host); hprintf(helpsock,"PRIVMSG %s :Hi %s! I'm %s, an eggdrop bot.\n",nick, nick,botname); hprintf(helpsock,"PRIVMSG %s :I'll recognize you by hostmask '%s' %s\n", nick,host,"from now on."); showhelp(nick,"intro",0,0); } else mprintf(serv,"PRIVMSG %s :Hi, %s.\n",nick,xx); } else if (strcasecmp(code,"pass")==0) { char xx[20],old[20]; split(old,msg); if (get_user_by_handle(nick)==NULL) mprintf(serv,"PRIVMSG %s :I don't know you.\n",nick); else { get_handle_by_host(xx,s); if (strcasecmp(xx,nick)!=0) mprintf(serv,"PRIVMSG %s :Host mismatch.\n",nick); else { if (!msg[0]) { mprintf(serv,"PRIVMSG %s :You %s a password set.\n",nick, pass_match_by_handle("nopass",nick)?"don't have":"have"); console("(%s!%s) PASS?",nick,from); } else if ((!pass_match_by_handle("nopass",nick)) && (!old[0])) mprintf(serv,"PRIVMSG %s :You already have a password set.\n",nick); else if (!old[0]) { console("(%s!%s) PASS...",nick,from); msg[10]=0; change_pass_by_handle(nick,msg); mprintf(serv,"PRIVMSG %s :Password set!\n",nick); } else if (!pass_match_by_handle(old,nick)) mprintf(serv,"PRIVMSG %s :Incorrect password.\n",nick); else { console("(%s!%s) PASS...",nick,from); msg[10]=0; change_pass_by_handle(nick,msg); mprintf(serv,"PRIVMSG %s :Password changed.\n",nick); } } } } else if (strcasecmp(code,"ident")==0) { char xx[20],host[120],*p,*q; if (get_user_by_handle(nick)==NULL) mprintf(serv,"PRIVMSG %s :I don't know you.\n",nick); else { if (pass_match_by_handle("nopass",nick)) mprintf(serv,"PRIVMSG %s :You have no password set.\n",nick); else if (!pass_match_by_handle(msg,nick)) mprintf(serv,"PRIVMSG %s :Access denied.\n",nick); else { get_handle_by_host(xx,s); if (strcasecmp(xx,nick)==0) mprintf(serv,"PRIVMSG %s :I already recognize you there.\n",nick); else if (strcasecmp(xx,"*")!=0) mprintf(serv,"PRIVMSG %s :Wrong nickname.\n",nick); else { console("(%s!%s) IDENT",nick,from); maskhost(s,host); mprintf(serv,"PRIVMSG %s :New hostmask: %s\n",nick,host); addhost_by_handle(nick,host); } } } } else if (strcasecmp(code,"info")==0) { char xx[20]; get_handle_by_host(xx,s); if (strcasecmp(xx,nick)!=0) mprintf(serv,"PRIVMSG %s :I don't know who you are.\n",nick); else { if (msg[0]) { console("(%s!%s) INFO...",nick,from); set_handle_info(nick,msg); mprintf(serv,"PRIVMSG %s :Now: %s\n",nick,msg); } else { console("(%s!%s) INFO?",nick,from); get_handle_info(nick,s1); if (s1[0]) mprintf(serv,"PRIVMSG %s :Currently: %s\n",nick,s1); else mprintf(serv,"PRIVMSG %s :You have no info set.\n",nick); } } } else if (strcasecmp(code,"who")==0) { char xx[20]; get_handle_by_host(xx,s); if (strcasecmp(xx,"*")==0) ; /* ignore them */ else { console("(%s!%s) WHO"); show_all_info(nick); } } else if (strcasecmp(code,"help")==0) { char xx[20]; int i; get_handle_by_host(xx,s); if (strcasecmp(xx,"*")==0) { if (learn_users) hprintf(helpsock,"NOTICE %s :'/msg %s hello' to introduce yourself.\n", nick); } else if (helpdir[0]) { if (!msg[0]) showhelp(nick,"help",match_op(s),match_master(s)); else { for (i=0; i='A') && (msg[i]<='Z')) msg[i]+=('a'-'A'); showhelp(nick,msg,match_op(s),match_master(s)); } } else if (!msg[0]) hprintf(helpsock,"PRIVMSG %s :Help available on: pass ident info who\n", nick); else if (strcasecmp(msg,"pass")==0) { hprintf(helpsock,"PRIVMSG %s :pass -- sets your password\n",nick); hprintf(helpsock,"PRIVMSG %s :pass -- changes your %s\n", nick,"password from to "); } else if (strcasecmp(msg,"ident")==0) hprintf(helpsock,"PRIVMSG %s :ident -- makes %s recognize %s\n", nick,"you at a new hostmask"); else if (strcasecmp(msg,"info")==0) hprintf(helpsock,"PRIVMSG %s :info -- set the line to show %s\n", nick,"when you join the channel"); else if (strcasecmp(msg,"who")==0) hprintf(helpsock,"PRIVMSG %s :who -- list info of people on the %s\n", nick,"channel"); else hprintf(helpsock,"PRIVMSG %s :whatever.\n"); } /* op and ban commands: must be op */ else if (match_op(s)) { if (strcasecmp(code,"op")==0) { if (pass_match_by_host(msg,s)) { add_op(nick); flush_deop(); console("(%s!%s) OP",nick,from); } else console("(%s!%s) failed OP",nick,from); } else if (strcasecmp(code,"invite")==0) { if (pass_match_by_host(msg,s)) { mprintf(serv,"INVITE %s %s\n",nick,curchan); console("(%s!%s) INVITE",nick,from); } else console("(%s!%s) failed INVITE",nick,from); } else if (!match_master(s)) { /* can't do anything else... */ if (spymode) console("[%s!%s] %s",nick,from,total); return; } else if (match_master(s)) { if (strcasecmp(code,"status")==0) { console("(%s!%s) STATUS",nick,from); tell_chan_info(nick); } else if (strcasecmp(code,"memory")==0) { console("(%s!%s) MEMORY",nick,from); tell_mem_status(nick); } else if (strcasecmp(code,"die")==0) { console("(%s!%s) DIE",nick,from); mprintf(serv,"PRIVMSG %s :Dying.\n",nick); tprintf(serv,"QUIT :Dead by request of %s\n",nick); sleep(1); /* give the server time to understand */ sprintf(s,"DEAD BY REQUEST OF %s!%s",nick,from); fatal(s); } else if (strcasecmp(code,"rehash")==0) { console("(%s!%s) REHASH",nick,from); mprintf(serv,"PRIVMSG %s :Rehashing...\n",nick); rehash(); } else if (strcasecmp(code,"reset")==0) { console("(%s!%s) RESET",nick,from); mprintf(serv,"PRIVMSG %s :Resetting channel info...\n",nick); reset_chan_info(); } else if (strcasecmp(code,"jump")==0) { if (msg[0]) { char other[121]; split(other,msg); if (!other[0]) { strcpy(other,msg); msg[0]=0; } if (!msg[0]) strcpy(msg,"6667"); console("(%s!%s) JUMP %s %s",nick,from,other,msg); strcpy(newserver,other); newserverport=atoi(msg); } else console("(%s!%s) JUMP",nick,from); mprintf(serv,"PRIVMSG %s :Jumping servers...\n",nick); mprintf(serv,"QUIT :jumping servers\n"); } else if (spymode) console("[%s!%s] %s",nick,from,total); } else if (spymode) console("[%s!%s] %s",nick,from,total); } else if (spymode) console("[%s!%s] %s",nick,from,total); /* otherwise, ignore them. */ } void talk_cmd(idx,z,msg) int idx,z; char *msg; { if (strcasecmp(msg,"talk")==0) { dcc[idx].status|=STAT_TALK; tprintf(z,"/// OK\n"); } /* future commands go here */ } /* got command on dcc-chat link */ int got_dcc_cmd(index,z,msg) int index,z; char *msg; { char s[256],s1[121],code[41]; int i; split(code,msg); if (code[0]==0) { strcpy(code,msg); msg[0]=0; } /* op-access commands */ if ((strcasecmp(code,"help")==0) || (strcmp(code,"?")==0)) { if (msg[0]) { console("#%s# help %s",dcc[index].nick,msg); tellhelp(z,msg,1,dcc[index].status&STAT_MASTER); } else { console("#%s# help",dcc[index].nick); tprintf(z,"DCC COMMANDS (so far) for %s, %s:\n",botname,version); tprintf(z," .who list people in dcc chat\n"); tprintf(z," .quit leave dcc chat\n"); tprintf(z," .motd redisplay message of the day\n"); tprintf(z," .+ban x!y@z add autoban to list (.-ban will remove)\n"); tprintf(z," .bans show the autoban list\n"); tprintf(z," .resetbans clear off bans the bot doesn't need\n"); tprintf(z," .newpass xx change your password to xx\n"); tprintf(z," .note xx yy store note 'yy' for user xx (private msg)\n"); if (dccdir[0]) tprintf(z," .files enter file transfer area\n"); strcpy(s,"actions"); tprintf(z,"To talk on the party line, just type stuff in.\n"); if (dcc[index].status&STAT_MASTER) { tprintf(z," .boot xx knock someone off the party line\n"); tprintf(z," .+blind xx hide public msgs from xx on party line\n"); tprintf(z," .+console xx turn on console for xx\n"); tprintf(z,"Text starting with ',' is sent ONLY to bot-masters.\n"); strcat(s," users stats"); } tprintf(z,"Additional help available on: %s\n",s); tprintf(z,"--- End of help.\n"); } } else if (strcasecmp(code,"quit")==0) return 1; else if (strcasecmp(code,"who")==0) { console("#%s# who",dcc[index].nick); tell_who(z); } else if (strcasecmp(code,"///")==0) talk_cmd(index,z,msg); else if (strcasecmp(code,"me")==0) { console("#%s# me %s",dcc[index].nick,msg); mprintf(serv,"PRIVMSG %s :\001ACTION %s\001\n",curchan,msg); } else if (strcasecmp(code,"msg")==0) { char nk[20]; split(nk,msg); console("#%s# msg %s %s",dcc[index].nick,nk,msg); mprintf(serv,"PRIVMSG %s :%s\n",nk,msg); } else if (strcasecmp(code,"say")==0) { console("#%s# say %s",dcc[index].nick,msg); mprintf(serv,"PRIVMSG %s :%s\n",curchan,msg); } else if (strcasecmp(code,"kickban")==0) { console("#%s# kickban %s",dcc[index].nick,msg); user_kickban(z,msg); } else if (strcasecmp(code,"op")==0) { console("#%s# op %s",dcc[index].nick,msg); give_op(msg,z); } else if (strcasecmp(code,"deop")==0) { console("#%s# deop %s",dcc[index].nick,msg); give_deop(msg,z); } else if (strcasecmp(code,"kick")==0) { console("#%s# kick %s",dcc[index].nick,msg); tprintf(z,"Attempting to kick %s ...\n",msg); tprintf(serv,"KICK %s %s :requested\n",curchan,msg); } else if (strcasecmp(code,"invite")==0) { console("#%s# invite %s",dcc[index].nick,msg); tprintf(z,"Attempting to invite %s ...\n",msg); mprintf(serv,"PRIVMSG %s :%s invites you to join the party line.\n",msg, dcc[index].nick); mprintf(serv,"PRIVMSG %s :Type /DCC CHAT %s\n",msg,botname); } else if (strcasecmp(code,"newpass")==0) { console("#%s# newpass...",dcc[index].nick); change_pass_by_handle(dcc[index].nick,msg); tprintf(z,"Changed password to '%s'\n",msg); } else if (strcasecmp(code,"resetbans")==0) { console("#%s# resetbans",dcc[index].nick); tprintf(z,"Resetting bans...\n"); resetbans(); } else if (strcasecmp(code,"motd")==0) { console("#%s# motd",dcc[index].nick); show_motd(z); } else if ((strcasecmp(code,"files")==0) && (dccdir[0])) { if (dccdir[0]==0) tprintf(z,"File transfer area deactivated.\n"); else { console("#%s# files",dcc[index].nick); tprintf(z,"Entering file system...\n"); for (i=0; i \n"); } else add_note(handle,dcc[index].nick,msg,z); } else if (!(dcc[index].status&STAT_MASTER)) { tprintf(z,"I'm clueless. Try 'help' for a list of commands.\n"); return 0; } /* MASTER COMMANDS */ else if (strcasecmp(code,"status")==0) { console("#%s# status",dcc[index].nick); tell_verbose_status(z,1); tell_mem_status_dcc(z); } else if (strcasecmp(code,"dccstat")==0) { console("#%s# dccstat",dcc[index].nick); tell_dcc(z); } else if (strcasecmp(code,"+ignore")==0) { console("#%s# +ignore %s",dcc[index].nick,msg); tprintf(z,"Now ignoring: %s\n",msg); prog_ignore(msg); } else if (strcasecmp(code,"-ignore")==0) { if (unprog_ignore(msg)) { console("#%s# -ignore %s",dcc[index].nick,msg); tprintf(z,"No longer ignoring: %s\n",msg); } else tprintf(z,"Can't find that ignore.\n"); } else if (strcasecmp(code,"ignores")==0) { console("#%s# ignores",dcc[index].nick); tell_ignores(z); } else if (strcasecmp(code,"boot")==0) { int j=0; for (i=0; i \n"); } else { console("#%s# +user %s %s",dcc[index].nick,handle,msg); adduser(handle,msg,"nopass",0); tprintf(z,"Added [%s]%s with no password or flags.\n",handle,msg); } } else if (strcasecmp(code,"-user")==0) { if (deluser(msg)) { console("#%s# -user %s",dcc[index].nick,msg); tprintf(z,"Deleted %s.\n",msg); } else tprintf(z,"Failed.\n"); } else if (strcasecmp(code,"handle")==0) { char hand[20]; split(hand,msg); if (!hand[0]) { tprintf(z,"Format: handle \n"); } else { console("#%s# handle %s %s",dcc[index].nick,hand,msg); change_handle(hand,msg); tprintf(z,"Changed.\n"); } } else if (strcasecmp(code,"+host")==0) { char handle[20]; split(handle,msg); if (!handle[0]) { tprintf(z,"Format: +host \n"); } else { console("#%s# +host %s %s",dcc[index].nick,handle,msg); addhost_by_handle(handle,msg); tprintf(z,"Added '%s' to %s\n",msg,handle); } } else if (strcasecmp(code,"-host")==0) { char handle[20]; split(handle,msg); if (!handle[0]) { tprintf(z,"Format: -host \n"); } else { if (delhost_by_handle(handle,msg)) { console("#%s# -host %s %s",dcc[index].nick,handle,msg); tprintf(z,"Removed '%s' from %s\n",msg,handle); } else tprintf(z,"Failed.\n"); } } else if (strcasecmp(code,"chpass")==0) { char handle[20]; split(handle,msg); if (!handle[0]) { tprintf(z,"Format: chpass \n"); } else { console("#%s# chpass %s %s",dcc[index].nick,handle,msg); tprintf(z,"Changed password.\n"); change_pass_by_handle(handle,msg); } } else if (strcasecmp(code,"comment")==0) { char handle[20]; split(handle,msg); if (!handle[0]) { tprintf(z,"Format: comment \n"); } else { console("#%s# comment %s %s",dcc[index].nick,handle,msg); tprintf(z,"Changed comment.\n"); set_handle_comment(handle,msg); } } else if (strcasecmp(code,"email")==0) { char handle[20]; split(handle,msg); if (!handle[0]) { tprintf(z,"Format: email \n"); } else { console("#%s# email %s %s",dcc[index].nick,handle,msg); tprintf(z,"Changed email.\n"); set_handle_email(handle,msg); } } else if (strcasecmp(code,"dump")==0) { console("#%s# dump %s",dcc[index].nick,msg); mprintf(serv,"%s\n",msg); } else if (strcasecmp(code,"reset")==0) { console("#%s# reset",dcc[index].nick); tprintf(z,"Resetting channel info...\n"); reset_chan_info(); } else if (strcasecmp(code,"rehash")==0) { console("#%s# rehash",dcc[index].nick); tprintf(z,"Rehashing...\n"); rehash(); } else if (strcasecmp(code,"die")==0) { console("#%s# die",dcc[index].nick); tprintf(serv,"QUIT :Dead by request of %s\n",dcc[index].nick); sleep(1); /* give the server time to understand */ sprintf(s,"DEAD BY REQUEST OF %s!%s",dcc[index].nick,dcc[index].host); fatal(s); } else if (strcasecmp(code,"jump")==0) { char other[121]; if (msg[0]) { split(other,msg); if (!other[0]) { strcpy(other,msg); msg[0]=0; } if (!msg[0]) strcpy(msg,"6667"); console("#%s# jump %s %s",dcc[index].nick,other,msg); strcpy(newserver,other); newserverport=atoi(msg); } else console("#%s# jump",dcc[index].nick); tprintf(z,"Jumping servers...\n"); tprintf(serv,"QUIT :Jumping servers\n"); } else if (strcasecmp(code,"debug")==0) { console("#%s# debug",dcc[index].nick); debug_mem_to_dcc(z); } else if (strcasecmp(code,"edit")==0) { console("#%s# edit %s",dcc[index].nick,msg); enter_edit(index,z,msg); } else if (strcasecmp(code,"info")==0) { char handle[20]; split(handle,msg); if (!handle[0]) { console("#%s# info %s",dcc[index].nick,msg); get_handle_info(msg,s); if (s[0]) tprintf(z,"Info: %s\n",s); else tprintf(z,"No info for %s.\n",msg); } else { console("#%s# info %s %s",dcc[index].nick,handle,msg); set_handle_info(handle,msg); tprintf(z,"New info for %s: %s\n",handle,msg); } } else if (strcasecmp(code,"log")==0) { char xx[20]; if (!msg[0]) { console("#%s# log",dcc[index].nick); tell_log(z,60,0); } else { split(xx,msg); if (xx[0]==0) { console("#%s# log %d",dcc[index].nick,atoi(msg)); tell_log(z,atoi(msg),0); } else { console("#%s# log %d %d",dcc[index].nick,atoi(xx),atoi(msg)); tell_log(z,atoi(xx),atoi(msg)); } } } else { /* nothing... */ tprintf(z,"What?\n"); } return 0; }