/* Acidblood action routines */ /* Acidblood IRC Bot Copyright (C) 1997 Bryan Schwab bryan@darkice.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "acid.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define RUSAGE_SELF 0 #define RUSAGE_CHILDREN -1 #define CTCP_DELIM_CHAR '\001' int execute( struct serverstruct *serverdata, struct botstruct *botinfo, FILE **fp_debug, FILE **fp_socket, FILE **fp_log, int *s, char *timestr, time_t starttime) { char output[5000]; int level; char *channel; char *data; int i; FILE *fp_help; char *line; time_t now; time_t min; time_t hour; time_t day; time_t uptime; time_t ping_t; char temp[50]; char key[50]; int result; struct rusage *myusage; int pid; int len; if (serverdata->extra!=NULL) { /* check for channel and nickname CTCPs */ if ( (strchr(serverdata->extra,CTCP_DELIM_CHAR)!=NULL) && ( (strstr(serverdata->message,botinfo->nick)!=NULL) || (strchr(serverdata->message,'#')!=NULL) ) ) { strip_delim(serverdata->extra); /* if ctcp is set to ON */ if (botinfo->ctcp==1) { if (!strncmp("PING",serverdata->extra,4)) { data=strtok(serverdata->extra," "); data=strtok(NULL, ""); /* if an argument exists, send the same one back */ if (data!=NULL) { len=strlen(data); if (len > 100) { /* someone is trying to overflow us */ return(0); } else { sprintf(output,"NOTICE %s :%cPING %s%c\n",serverdata->nick,CTCP_DELIM_CHAR,data,CTCP_DELIM_CHAR); } } /* if not, send the time in seconds */ else { time(&ping_t); sprintf(output,"NOTICE %s :%cPING %ld%c\n",serverdata->nick,CTCP_DELIM_CHAR,ping_t,CTCP_DELIM_CHAR); } if ((send(*s,output,strlen(output),0))==-1) { return(-1); } fprintf(*fp_log,"CTCP Ping %s %s\n",serverdata->nick,timestr); fflush(*fp_log); } if (!strncmp("VERSION",serverdata->extra,7)) { sprintf(output,"NOTICE %s :%cVERSION %s%c\n",serverdata->nick,CTCP_DELIM_CHAR,botinfo->ver,CTCP_DELIM_CHAR); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } fprintf(*fp_log,"CTCP Version %s %s\n",serverdata->nick,timestr); fflush(*fp_log); } if (!strncmp("TIME",serverdata->extra,4)) { sprintf(output,"NOTICE %s :%cTIME %s%c\n",serverdata->nick,CTCP_DELIM_CHAR,timestr,CTCP_DELIM_CHAR); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } fprintf(*fp_log,"CTCP Time %s %s\n",serverdata->nick,timestr); fflush(*fp_log); } } } } /* check for KICKS */ /* doesnt support keys yet */ /* wont work if channel key is set */ if (!strncmp(serverdata->action,"KICK",4)) { channel=strtok(serverdata->message," "); data=strtok(NULL, " "); if(!strcmp(data,botinfo->nick)) { sprintf(output,"JOIN %s\n",channel); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } fprintf(*fp_log,"Kicked from %s by %s rejoining%s\n",channel,data); fflush(*fp_log); } } /* check for JOINS */ /* must check channel */ if (botinfo->autoop==1) { if (!strncmp(serverdata->action,"JOIN",4)) { if (traverse_users(serverdata,serverdata->message)) { sprintf(output,"MODE %s +o %s\n",serverdata->message,serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } fprintf(*fp_log,"Auto-op %s %s\n",serverdata->nick,timestr); fflush(*fp_log); } fprintf(*fp_log,"%s JOIN by %s\n",serverdata->message,serverdata->nick); fflush(*fp_log); } } /* check for NOTICE */ if (!strncmp(serverdata->action,"NOTICE",6)) { /* did this come from NickServ? */ if (!strncmp(serverdata->nick,"NickServ",8)) { if (strstr(serverdata->extra,"This nickname is registered and protected.")!=NULL) { sprintf(output,"PRIVMSG %s :IDENTIFY %s\n",serverdata->nick,botinfo->nspass); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } fprintf(*fp_log,"Sent password %s to %s\n",botinfo->nspass,serverdata->nick,timestr); fflush(*fp_log); } if (strstr(serverdata->extra,"Password accepted - you are now recognized.")!=NULL) { while (get_channel(channeldata,temp,key) > 0) { sprintf(output,"JOIN %s %s\n",temp,key); if ((send(*s,output,strlen(output),0))==-1) { fprintf(*fp_log,"Error sending to server.\n"); return(-1); } } } } } /* check for PRIVMSGs */ if (!strncmp(serverdata->action,"PRIVMSG",7)) { /* No argument commands */ /* Shutdown */ if ((!strncmp(serverdata->extra,"shutdown",8)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { if (traverse_users(serverdata,NULL)) { level=check_level(serverdata); if (level==0) { sprintf(output,"QUIT :Shutdown \n"); if ((send(*s,output,strlen(output),0))==-1) { } fprintf(*fp_log,"Shutdown by %s %s\n",serverdata->nick,timestr); fflush(*fp_log); exit(0); } } } /* Help */ if ((!strncmp(serverdata->extra,"help",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { if ((line=malloc(100))==NULL) { fprintf(stderr,"Malloc error!\n"); return(-1); } if ((fp_help=fopen("../docs/help","r"))==NULL) { fprintf(*fp_log,"Cant open help file! \n"); fflush(*fp_log); free(line); return(-1); } while(fgets(line,100,fp_help)!=NULL) { sprintf(output,"PRIVMSG %s :%s\n",serverdata->nick,line); if ((send(*s,output,strlen(output),0))==-1) { free(line); return(-1); } sleep(1); fflush(*fp_log); } free(line); } } /* Reload */ if ((!strncmp(serverdata->extra,"reload",6)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { level=check_level(serverdata); /* are they a master? */ if (level==0) { read_user_data(); sprintf(output,"PRIVMSG %s :Reload complete.\n",serverdata->nick); fprintf(*fp_log,"Reload by %s %s\n",serverdata->nick,timestr); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Level too low!\n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } /* These commands have atleast one argument after them */ /* OP requests */ /* syntax: op */ /* must check channel */ if ((!strncmp(serverdata->extra,"op",2)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { channel=strtok(serverdata->extra," "); channel=strtok(NULL,""); /* do i know this user? */ if (traverse_users(serverdata,channel)) { if (channel!=NULL) { sprintf(output,"MODE %s +o %s\n",channel,serverdata->nick); fprintf(*fp_log,"Op %s on %s\n",serverdata->nick,channel); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: op \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } /* Deop requests */ /* syntax: deop */ /* must check channel */ if ((!strncmp(serverdata->extra,"deop",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { channel=strtok(serverdata->extra," "); channel=strtok(NULL," "); data=strtok(NULL, ""); /* do i know this user? */ if (traverse_users(serverdata,channel)) { level=check_level(serverdata); if (level<=1) { if (channel!=NULL && data!=NULL) { sprintf(output,"MODE %s -o %s\n",channel,data); fprintf(*fp_log,"Deop %s on %s\n",data,channel); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: deop \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } /* check for say requests */ /* syntax: say */ /* must check channel */ if ((!strncmp(serverdata->extra,"say",3)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { channel=strtok(serverdata->extra," "); channel=strtok(NULL," "); data=strtok(NULL, ""); /* do i know this user? */ if (traverse_users(serverdata,channel)) { level=check_level(serverdata); /* are they a master? */ if (level<=1) { if (channel!=NULL && data!=NULL) { sprintf(output,"PRIVMSG %s :%s\n",channel,data); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } fprintf(*fp_log,"Say %s on %s by %s\n",data,channel,serverdata->nick); fflush(*fp_log); } else { sprintf(output,"PRIVMSG %s :Syntax error: say \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } /* check for topic requests */ /* syntax: topic */ /* must check channel */ if ((!strncmp(serverdata->extra,"topic",5)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { channel=strtok(serverdata->extra," "); channel=strtok(NULL," "); data=strtok(NULL, ""); /* do i know this user? */ if (traverse_users(serverdata,channel)) { level=check_level(serverdata); /* are they a master? */ if (level<=1) { if (channel!=NULL && data!=NULL) { sprintf(output,"TOPIC %s :%s\n",channel,data); fprintf(*fp_log,"Topic on %s set to %s by %s\n",channel,data,serverdata->nick); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: topic \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } /* check for mode requests */ /* syntax: mode */ /* must check channel */ if ((!strncmp(serverdata->extra,"mode",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { channel=strtok(serverdata->extra," "); channel=strtok(NULL," "); data=strtok(NULL, ""); /* do i know this user? */ if (traverse_users(serverdata,channel)) { level=check_level(serverdata); /* are they a master? */ if (level<=1) { if (channel!=NULL && data!=NULL) { sprintf(output,"MODE %s %s\n",channel,data); fprintf(*fp_log,"Mode change %s on %s by %s\n",data,channel,serverdata->nick); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: mode \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } /* check for raw commands */ /* syntax: raw */ if ((!strncmp(serverdata->extra,"raw",3)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { level=check_level(serverdata); /* are they a master? */ if (level==0) { data=strtok(serverdata->extra," "); data=strtok(NULL, ""); if (data!=NULL) { sprintf(output,"%s\n",data); fprintf(*fp_log,"RAW: %s by %s\n",data,serverdata->nick); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: raw \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } else { sprintf(output,"PRIVMSG %s :Level too low!\n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } /* check for join commands */ /* syntax: join */ /* must check channel */ if ((!strncmp(serverdata->extra,"join",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { channel=strtok(serverdata->extra," "); channel=strtok(NULL, " "); data=strtok(NULL,""); /* do i know this user? */ if (traverse_users(serverdata,channel)) { level=check_level(serverdata); /* are they a master? */ if (level<=1) { if (channel!=NULL) { sprintf(output,"JOIN %s %s\n",channel,data); fprintf(*fp_log,"Joined %s by %s\n",channel,serverdata->nick); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } insert_channels(channel); sprintf(output,"PRIVMSG %s :Attempting to join %s\n",serverdata->nick,channel); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: join \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } else { sprintf(output,"PRIVMSG %s :Level too low!\n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } /* check for part commands */ /* syntax: part */ /* must check channel */ if ((!strncmp(serverdata->extra,"part",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { data=strtok(serverdata->extra," "); data=strtok(NULL, ""); /* do i know this user? */ if (traverse_users(serverdata,data)) { level=check_level(serverdata); /* are they a master? */ if (level<=1) { if (data!=NULL) { sprintf(output,"PART %s\n",data); fprintf(*fp_log,"Parted %s by %s\n",data,serverdata->nick); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } delete_channel(data); sprintf(output,"PRIVMSG %s :Parting %s\n",serverdata->nick,data); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: part \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } else { sprintf(output,"PRIVMSG %s :Level too low!\n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } /* uptime */ if ((!strncmp(serverdata->extra,"uptime",6)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { time( &now); uptime=now-starttime; day=uptime/86400; if (day > 0) { uptime=uptime-(day * 86400); } hour=uptime/3600; if (hour > 0) { uptime=uptime-(hour * 3600); } min=uptime/60; sprintf(output,"PRIVMSG %s :Uptime Days:%ld Hours:%ld Mins:%ld\n",serverdata->nick,day,hour,min); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } /* stats */ if ((!strncmp(serverdata->extra,"stats",5)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { result=getrusage(RUSAGE_SELF,myusage); if (result == -1) { /* perror("getrusage"); */ sprintf(output,"PRIVMSG %s :Bytes recv: %dk\n",serverdata->nick,totalbytes/1024); } else { sprintf(output,"PRIVMSG %s :Memory size: %dk Bytes recv: %dk\n",serverdata->nick,myusage->ru_maxrss,totalbytes/1024); } if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } /* version */ if ((!strncmp(serverdata->extra,"ver",3)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { sprintf(output,"PRIVMSG %s :Acidblood %s\n",serverdata->nick,VERSION); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } /* change ctcp status */ /* syntax: ctcp */ if ((!strncmp(serverdata->extra,"ctcp",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { level=check_level(serverdata); /* are they a master? */ if (level==0) { data=strtok(serverdata->extra," "); data=strtok(NULL, ""); if (data==NULL) { if (botinfo->ctcp==1) { sprintf(output,"PRIVMSG %s :CTCP ON\n",serverdata->nick); } else { sprintf(output,"PRIVMSG %s :CTCP OFF\n",serverdata->nick); } if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { if(!strncmp("off",data,3)) { botinfo->ctcp=0; sprintf(output,"PRIVMSG %s :CTCP OFF\n",serverdata->nick); } else if(!strncmp("on",data,2)) { botinfo->ctcp=1; sprintf(output,"PRIVMSG %s :CTCP ON\n",serverdata->nick); } else { sprintf(output,"PRIVMSG %s :Syntax error: ctcp \n",serverdata->nick); } if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } /* change autoop status */ /* syntax: autoop */ if ((!strncmp(serverdata->extra,"autoop",6)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { level=check_level(serverdata); /* are they a master? */ if (level==0) { data=strtok(serverdata->extra," "); data=strtok(NULL, ""); if (data==NULL) { if (botinfo->autoop==1) { sprintf(output,"PRIVMSG %s :Autoop ON\n",serverdata->nick); } else { sprintf(output,"PRIVMSG %s :Autoop OFF\n",serverdata->nick); } if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { if(!strncmp("off",data,3)) { botinfo->autoop=0; sprintf(output,"PRIVMSG %s :Autoop OFF\n",serverdata->nick); } else if(!strncmp("on",data,2)) { botinfo->autoop=1; sprintf(output,"PRIVMSG %s :Autoop ON\n",serverdata->nick); } else { sprintf(output,"PRIVMSG %s :Syntax error: autoop \n",serverdata->nick); } if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } /* check for nick requests */ /* syntax: nick */ if ((!strncmp(serverdata->extra,"nick",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { /* do i know this user? */ if (traverse_users(serverdata,NULL)) { level=check_level(serverdata); /* are they a master? */ if (level==0) { data=strtok(serverdata->extra," "); data=strtok(NULL, ""); if (data!=NULL) { free(botinfo->nick); botinfo->nick=malloc(strlen(data)+1); strcpy(botinfo->nick, data); sprintf(output,"NICK %s\n",botinfo->nick); fprintf(*fp_log,"NICK %s\n",botinfo->nick); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } else { sprintf(output,"PRIVMSG %s :Syntax error: nick \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } /* check for kick requests */ /* syntax: kick */ /* must check channel */ if ((!strncmp(serverdata->extra,"kick",4)) && (strstr(serverdata->message,botinfo->nick)!=NULL)) { channel=strtok(serverdata->extra," "); channel=strtok(NULL," "); data=strtok(NULL, ""); /* do i know this user? */ if (traverse_users(serverdata,channel)) { level=check_level(serverdata); /* are they a master? */ if (level<=1) { if (channel!=NULL && data!=NULL) { if(!strcmp(data,botinfo->nick)) {} else { sprintf(output,"KICK %s %s\n",channel,data); fprintf(*fp_log,"KICK %s %s\n",channel,data); fflush(*fp_log); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } else { sprintf(output,"PRIVMSG %s :Syntax error: kick \n",serverdata->nick); if ((send(*s,output,strlen(output),0))==-1) { return(-1); } } } } } } return(0); }