/* eggdrop module to handle msg, notice, channel msg, channel notice, and elementary ctcp and ctcp-replies. */ #include #include #include #include #include "eggdrop.h" #define FINGER "(root@home), idle 0 seconds" #define SOURCE "EGGDROP: telnet maverick.math.uic.edu 1994 | sh" #define CLIENTINFO "FINGER PING ECHO ERRMSG VERSION SOURCE USERINFO CLIENTINFO DCC" extern int serv; extern int memused; extern int backgrd; extern int con_chan; extern int term_z; extern char botname[]; extern char helpbot[]; extern char version[]; extern char curchan[]; extern struct dcc_t dcc[]; extern int dcc_total; extern char admin[]; extern int gothelpping; extern char cx_file[]; extern int cx_line; extern int require_x; extern int require_p; extern int telnet_port; /* ctcp embedded in a privmsg */ void gotctcp(ffrom,to,msg) char *ffrom,*to,*msg; { char from[121],nick[10],code[512]; char *p; strcpy(from,ffrom); split(code,msg); splitnick(nick,from); if (code[0]==0) { strcpy(code,msg); msg[0]=0; } /* unquote if necessary */ p=strchr(msg,'\\'); while (p!=NULL) { if (*(p+1)=='a') *(p+1)=1; strcpy(p,p+1); p=strchr(msg,'\\'); } if (strcmp(code,"FINGER")==0) mprintf(serv,"NOTICE %s :\001FINGER %s %s\001\n",nick,botname,FINGER); else if ((strcmp(code,"PING")==0) || (strcmp(code,"ECHO")==0) || (strcmp(code,"ERRMSG")==0)) mprintf(serv,"NOTICE %s :\001%s %s\001\n",nick,code,msg); else if (strcmp(code,"VERSION")==0) mprintf(serv,"NOTICE %s :\001VERSION ircII 2.6 SunOS 4.1.3 :%s\001\n",nick, "ircii 2.6: almost there..."); else if (strcmp(code,"SOURCE")==0) mprintf(serv,"NOTICE %s :\001SOURCE %s\001\n",nick,SOURCE); else if (strcmp(code,"USERINFO")==0) mprintf(serv,"NOTICE %s :\001USERINFO %s\001\n",nick,admin); else if (strcmp(code,"CLIENTINFO")==0) mprintf(serv,"NOTICE %s :\001CLIENTINFO %s\001\n",nick,CLIENTINFO); /* else if (strcmp(code,"EGGDROP")==0) mprintf(serv,"NOTICE %s :\001EGGDROP %s\001\n",nick,version); */ else if (strcmp(code,"DCC")==0) gotdcc(nick,from,msg); else if (strcmp(code,"CHAT")==0) { int atr=get_attr_host(ffrom); if ((atr & (USER_MASTER|USER_PARTY|USER_XFER)) || ((atr&USER_OP) && (!require_x || !require_p))) { if (!telnet_port) mprintf(serv,"NOTICE %s :\001ERROR no telnet port\001\n",nick); else mprintf(serv,"PRIVMSG %s :\001DCC CHAT chat %lu %u\001\n",nick, getmyip(),telnet_port); } } /* don't log DCC or AWAKE */ if ((strcmp(code,"DCC")!=0) && (strcmp(code,"AWAKE")!=0)) { if ((to[0]=='#') || (to[0]=='&') || (to[0]=='+')) { if (strcmp(code,"ACTION")==0) { log(LOG_PUBLIC,"Action: %s %s",nick,msg); } else { log(LOG_PUBLIC,"CTCP %s: %s from %s (%s) to %s",code,msg,nick,from,to); } } else { if (strcmp(code,"ACTION")==0) { log(LOG_MSGS,"Action to %s: %s %s",to,nick,msg); } else { log(LOG_MSGS,"CTCP %s: %s from %s (%s)",code,msg,nick,from); } } } } /* ctcp embedded in a notice */ void gotctcpreply(ffrom,to,msg) char *ffrom,*to,*msg; { char from[81],nick[10],code[512]; char *p; strcpy(from,ffrom); split(code,msg); splitnick(nick,from); if (code[0]==0) { strcpy(code,msg); msg[0]=0; } /* unquote if necessary */ p=strchr(msg,'\\'); while (p!=NULL) { if (*(p+1)=='a') *(p+1)=1; strcpy(p,p+1); p=strchr(msg,'\\'); } /* who cares? */ if ((to[0]=='#') || (to[0]=='&') || (to[0]=='+')) log(LOG_PUBLIC,"CTCP reply %s: %s from %s (%s) to %s",code,msg,nick,from, to); else { if ((strcasecmp(nick,helpbot)==0) && (strcmp(code,"PING")==0)) gothelpping=1; /* ping response from helpbot! */ else log(LOG_MSGS,"CTCP reply %s: %s from %s (%s) to %s",code,msg,nick,from, to); } } /* public msg on channel */ void gotpublic(from,to,msg) char *from,*to,*msg; { char nick[10]; detect_flood(from,_PRIVMSG,1); splitnick(nick,from); #ifdef TCL if (check_tcl_pub(nick,from,msg)) return; if (check_tcl_pubm(nick,from,msg)) return; #endif if (strcasecmp(curchan,to)==0) log(LOG_PUBLIC,"<%s> %s",nick,msg); else log(LOG_PUBLIC,"<%s:%s> %s",nick,to,msg); } /* public notice on channel */ void gotpublicnotice(from,to,msg) char *from,*to,*msg; { char nick[10]; detect_flood(from,_NOTICE,1); splitnick(nick,from); log(LOG_PUBLIC,"-%s:%s- %s",nick,to,msg); } /* check for more than 8 control characters in a line */ /* this could indicate: beep flood CTCP avalanche color-change flood */ int detect_avalanche(msg) char *msg; { int count=0; char *p; for (p=msg; (*p)&&(count<8); p++) if ((*p<32) && (*p!=22) && (*p!=2) && (*p!=31)) count++; /* ^ don't penalize for bold/reverse/underline */ if (count>=8) return 1; else return 0; } /* private message */ void gotmsg(from,msg) char *from,*msg; { char to[81],nick[10],ctcp[512]; char *p,*p1; context; split(to,msg); fixcolon(msg); if (detect_avalanche(msg)) { splitnick(nick,from); /* discard -- kick user if it was to the channel */ if ((to[0]=='&') || (to[0]=='#')) { tprintf(serv,"KICK %s %s :that was fun, let's do it again!\n", curchan,nick); } log(LOG_CHAN,"Avalanche from %s!%s",nick,from); return; } /* check for CTCP: */ p=strchr(msg,1); while (p!=NULL) { p++; p1=p; while ((*p != 1) && (*p != 0)) p++; if (*p==1) { *p=0; strcpy(ctcp,p1); strcpy(p1-1,p+1); } else { strcpy(ctcp,p1); strcpy(p1-1,p); } detect_flood(from,_CTCP,0); gotctcp(from,to,ctcp); p=strchr(msg,1); } if (msg[0]==0) return; /* oh. no msg. well forget it then! */ if ((to[0]=='#') || (to[0]=='&') || (to[0]=='+')) { /* it's a public msg */ gotpublic(from,to,msg); } else { detect_flood(from,_PRIVMSG,0); splitnick(nick,from); gotcmd(nick,from,msg); } } /* private notice */ void gotnotice(from,msg) char *from,*msg; { char to[81],nick[10],ctcp[512]; char *p,*p1; context; split(to,msg); fixcolon(msg); if (detect_avalanche(msg)) { splitnick(nick,from); /* discard -- kick user if it was to the channel */ if ((to[0]=='&') || (to[0]=='#')) { tprintf(serv,"KICK %s %s :that was fun, let's do it again!\n", curchan,nick); } log(LOG_CHAN,"Avalanche from %s!%s",nick,from); return; } /* check for CTCP: */ p=strchr(msg,1); while (p!=NULL) { p++; p1=p; while ((*p != 1) && (*p != 0)) p++; if (*p==1) { *p=0; strcpy(ctcp,p1); strcpy(p1-1,p+1); } else { strcpy(ctcp,p1); strcpy(p1-1,p); } detect_flood(from,_CTCP,0); gotctcpreply(from,to,ctcp); p=strchr(msg,1); } if (msg[0]==0) return; /* oh. no msg. well forget it then! */ if ((to[0]=='#') || (to[0]=='&')) { /* it's a public msg */ gotpublicnotice(from,to,msg); } else { detect_flood(from,_NOTICE,0); splitnick(nick,from); /* server notice? */ if ((from[0]==0) || (nick[0]==0)) log(LOG_MISC,"-NOTICE- %s",msg); else log(LOG_MSGS,"-%s (%s)- %s",nick,from,msg); } }