/* Acidblood parsing 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 #define CTCP_DELIM_CHAR '\001' /* parse a line from the config file */ void parse_line( char *line, char *data) { data[0]='\0'; while (*line!='=') { line++; } line++; while (*line!='\n') { *data++=*line++; } *data='\0'; } /* get action from server line */ void get_action( char *line, char *data) { while (*line!=' ') { line++; } line++; while (*line!=' ') { *data++=*line++; } *data='\0'; } /* parse channels from the config file */ void parse_channels( char *line, char *data) { char temp[100]; char key[100]; int x=0; int y=0; int keyflag=0; while (*line!='=') { line++; } line++; while (*line!='\n') { /* beginning of a key */ if (*line=='(') { keyflag=1; line++; continue; } /* ending of a key */ if (*line==')') { keyflag=0; key[y]='\0'; line++; continue; } /* we are processing a key */ if (keyflag) { key[y++]=*line; line++; continue; } /* end of a channel */ if (*line==',') { temp[x]='\0'; insert_channels(temp,key); y=0; key[y]='\0'; x=0; } else { temp[x++]=*line; } *data++=*line++; } *data='\0'; temp[x]='\0'; insert_channels(temp,key); } void strip_colon( char *data) { char *c; /* look for comma */ if (strchr(data,':')!=NULL) { if ((c=malloc(strlen(data)))==NULL) { printf("strip_colon: Malloc error!\n"); exit(-1); } strcpy(c, &data[1]); strcpy(data, c); free(c); } else { /* do nothing, no comma exists */ } } void strip_delim( char *data) { char *c; /* look for delim */ if (strchr(data,CTCP_DELIM_CHAR)!=NULL) { if ((c=malloc(strlen(data)))==NULL) { printf("strip_delim: Malloc error!\n"); exit(-1); } strcpy(c, &data[1]); strcpy(data, c); free(c); } else { /* do nothing, no comma exists */ } } void strip_return( char *unstripped) { char *c; char *d; /* look for return */ if (strchr(unstripped,'\r')!=NULL) { if ((c=malloc(strlen(unstripped)+1))==NULL) { printf("strip_return: Malloc error!\n"); exit(-1); } strcpy(c, unstripped); d=strtok(c,"\r"); strcpy(unstripped,d); /* sometimes cores here, FIX */ if (c!=NULL) { free(c); } } else { /* do nothing, doesnt have a return to strip */ } } void strip_newline( char *unstripped) { char *c; char *d; if ((c=malloc(strlen(unstripped)))==NULL) { printf("strip_newline: Malloc error!\n"); exit(-1); } strcpy(c, unstripped); d=strtok(c,"\n"); strcpy(unstripped,d); free(c); } int match_ip( char *listip, /* curr->userip */ char *serverip) /* serverdata->ip */ { int size1,size2; int nomatch=0; size1=strlen(listip); size2=strlen(serverip); size1--; size2--; for (;size1>=0 && size2>=0; size1--,size2--) { if (listip[size1]==serverip[size2]) {} else { if (listip[size1]=='*') { return(1); } else if (listip[size1]=='?') {} else { return(0); } } } } int get_channel( struct channels *channeldata, char *data, char *key) { if (curr3==NULL) { return(-1); } else { strcpy(data,curr3->channel); /* if a key exists, copy it */ if (curr3->key!=NULL) { strcpy(key,curr3->key); } if (prev3->next!=NULL) { curr3=prev3->next; prev3=curr3; } else { curr3=NULL; } } return (1); } /* read bot configuration file */ int read_config( struct botstruct *botinfo, FILE **fp_config, FILE **fp_debug) { char *line; char *data; int size; if ((line=malloc(1000))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } if ((data=malloc(1000))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } while ((fgets(line,1000,*fp_config))!=NULL) { size=strlen(line); if (*line=='\n' || *line=='\0' || *line=='/' || *line=='#' || size < 1) { /* ignore this line */ } else { if (strstr(line,"USER")!=NULL) { parse_line(line,data); if ((botinfo->user=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->user,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot username=%s\n",botinfo->user); #endif } if (strstr(line,"NICK")!=NULL) { parse_line(line,data); if ((botinfo->nick=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->nick,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot nick=%s\n",botinfo->nick); #endif } if (strstr(line,"ALT")!=NULL) { parse_line(line,data); if ((botinfo->altnick=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->altnick,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot nick=%s\n",botinfo->nick); #endif } if (strstr(line,"FULLNAME")!=NULL) { parse_line(line,data); if ((botinfo->fname=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->fname,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot fullname=%s\n",botinfo->fname); #endif } if (strstr(line,"CHANNELS")!=NULL) { /* parse_line(line,data); if ((botinfo->channel=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->channel,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot channel=%s\n",botinfo->channel); #endif */ parse_channels(line,data); } if (strstr(line,"SERVER")!=NULL) { parse_line(line,data); if ((botinfo->server=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->server,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot server=%s\n",botinfo->server); #endif } if (strstr(line,"AWAYMSG")!=NULL) { parse_line(line,data); if ((botinfo->awaymsg=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->awaymsg,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot away message=%s\n",botinfo->awaymsg); #endif } if (strstr(line,"CTCP")!=NULL) { parse_line(line,data); if (!strncmp("ON",data,2)) { botinfo->ctcp=1; } #ifdef DEBUG fprintf(*fp_debug,"CTCP response=%s\n",data); #endif } if (strstr(line,"PORT")!=NULL) { parse_line(line,data); botinfo->port=atoi(data); #ifdef DEBUG fprintf(*fp_debug,"Bot port=%d\n",botinfo->port); #endif } if (strstr(line,"VERSION")!=NULL) { parse_line(line,data); if ((botinfo->ver=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->ver,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Bot ver=%s\n",botinfo->ver); #endif } if (strstr(line,"NSERV")!=NULL) { parse_line(line,data); if (!strncmp("ON",data,2)) { botinfo->ns=1; } #ifdef DEBUG fprintf(*fp_debug,"NickServ routines=%s\n",data); #endif } if (strstr(line,"NSPASS")!=NULL) { parse_line(line,data); if ((botinfo->nspass=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->nspass,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Nickserv Pass=%s\n",botinfo->nspass); #endif } if (strstr(line,"IMAGE")!=NULL) { parse_line(line,data); if ((botinfo->image=malloc(strlen(data)+1))==NULL) { fprintf(stderr,"read_config: Malloc error!\n"); return(-1); } memcpy(botinfo->image,data,strlen(data)+1); #ifdef DEBUG fprintf(*fp_debug,"Image=%s\n",botinfo->image); #endif } /* set auto op to off initially */ botinfo->autoop=0; if (strstr(line,"AUTOOP")!=NULL) { parse_line(line,data); if (!strncmp(data, "ON", 2)) { botinfo->autoop=1; #ifdef DEBUG fprintf(*fp_debug,"Auto-op is ON\n"); #endif } } /* set keep alive */ botinfo->timer=10; if (strstr(line,"KEEPALIVE")!=NULL) { parse_line(line,data); botinfo->timer=atoi(data); #ifdef DEBUG fprintf(*fp_debug,"Keepalive is %d\n", botinfo->timer); #endif } } } return (0); } /* read in user file */ int read_user_data() { FILE *fp_users; char *data; char *servernick; char *serverip; char *statustemp; char *channels; if (free_list() < 0 ) { return (-1); } if ((data=malloc(1000))==NULL) { fprintf(stderr,"read_user_data: Malloc Error!\n"); return(-1); } if ((fp_users=fopen("../conf/acid.users","r")) == NULL) { return(-1); } fgets(data,1000,fp_users); while (!feof(fp_users)) { if (*data!='#' && (strlen(data) > 1)) { /* if (!strchr(data,'#') > 0 && (strlen(data) > 1)) { */ servernick=strtok(data,":"); serverip=strtok(NULL,":"); statustemp=strtok(NULL,":"); channels=strtok(NULL,""); strip_newline(channels); if ((insert_users(servernick,serverip,statustemp,channels)) < 0) { return(-1); } } fgets(data,80,fp_users); } fclose(fp_users); return (0); } int parse_server ( char *input, struct serverstruct *serverdata, FILE **fp_debug, FILE **fp_log) { char *c; int x=0; char temp; char *temp2; int parsed=0; char *action; int level; char *a; char *b; int size; no_parse=0; if(!strncmp(input,"ERROR",5)) { fprintf(*fp_log,"%s\n",input); fflush(*fp_log); return(-1); } if ((action=malloc(100))==NULL) { fprintf(stderr,"parse_server: Malloc error!\n"); return(-1); } get_action(input,action); /* subcube_!subcube_@borg.hotwired.com JOIN :#acidblood */ if (!strncmp(action,"JOIN",4)) { serverdata->nick=strtok(input,"!"); serverdata->username=strtok(NULL,"@"); serverdata->ip=strtok(NULL," "); serverdata->action=strtok(NULL," "); serverdata->message=strtok(NULL," "); serverdata->extra=strtok(NULL,""); strip_colon(serverdata->nick); strip_colon(serverdata->message); strip_return(serverdata->message); parsed=1; } /* subcube_!subcube_@borg.hotwired.com PART #acidblood */ if (!strncmp(action,"PART",4)) { serverdata->nick=strtok(input,"!"); serverdata->username=strtok(NULL,"@"); serverdata->ip=strtok(NULL," "); serverdata->action=strtok(NULL," "); serverdata->message=strtok(NULL," "); serverdata->extra=strtok(NULL,""); strip_colon(serverdata->nick); strip_return(serverdata->message); fprintf(*fp_log,"%s PART %s\n",serverdata->message,serverdata->nick); fflush(*fp_log); } if (!strncmp(action,"PRIVMSG",7)) { serverdata->nick=strtok(input,"!"); serverdata->username=strtok(NULL,"@"); serverdata->ip=strtok(NULL," "); serverdata->action=strtok(NULL," "); serverdata->message=strtok(NULL," "); serverdata->extra=strtok(NULL,""); strip_colon(serverdata->nick); strip_colon(serverdata->extra); strip_return(serverdata->extra); fprintf(*fp_log,"%s %s :%s\n",serverdata->message,serverdata->nick,serverdata->extra); fflush(*fp_log); parsed=1; } /* :StLouis.MO.US.UnderNet.org NOTICE acidbot :on 3 ca 1(2) ft 9(10) tr */ if (!strncmp(action,"NOTICE",6)) { if(strchr(b,'!')!=NULL) { serverdata->nick=strtok(input,"!"); /* nick */ serverdata->username=strtok(NULL,"@"); /* username */ serverdata->ip=strtok(NULL," "); /* ip */ serverdata->action=strtok(NULL," "); /* action */ serverdata->message=strtok(NULL," "); /* message */ serverdata->extra=strtok(NULL,""); /* extra */ strip_colon(serverdata->nick); strip_colon(serverdata->extra); strip_return(serverdata->extra); fprintf(*fp_log,"NOTICE from %s :%s\n",serverdata->nick,serverdata->extra); fflush(*fp_log); parsed=1; } else { /* notice from server, ignore for now */ } } /* subcube_!subcube_@borg.hotwired.com TOPIC #acidblood :test2 */ /* Banjo!mrwilson@pm0-aur-1.dialnet.net TOPIC #funfactory : */ /* extra will be size of 2 if empty */ if (!strncmp(action,"TOPIC",5)) { serverdata->nick=strtok(input,"!"); /* nickname */ serverdata->username=strtok(NULL,"@"); /* username */ serverdata->ip=strtok(NULL," "); /* ip */ serverdata->action=strtok(NULL," "); /* action */ serverdata->message=strtok(NULL," "); /* channel */ serverdata->extra=strtok(NULL,""); /* topic */ strip_colon(serverdata->nick); size=strlen(serverdata->extra); if (size <= 2) {} else { strip_colon(serverdata->extra); strip_return(serverdata->extra); fprintf(*fp_log,"%s TOPIC %s by %s\n",serverdata->message,serverdata->extra,serverdata->nick); fflush(*fp_log); } } /* subcube_!subcube_@borg.hotwired.com QUIT :Leaving */ if (!strncmp(action,"QUIT",4)) { serverdata->nick=strtok(input,"!"); /* nick */ serverdata->username=strtok(NULL,"@"); /* username */ serverdata->ip=strtok(NULL," "); /* ip */ serverdata->action=strtok(NULL,""); /* action */ /* we dont care about the reason */ strip_colon(serverdata->nick); fprintf(*fp_log,"QUIT by %s\n",serverdata->nick); fflush(*fp_log); } /* d3spise!subcube@207.238.141.237 MODE #acidblood +o subcube_ */ /* Vancouver.BC.CA.Undernet.Org MODE #warez666 +bb *!*@cr484851-a.hnsn1.on.wave.home.com *!*@*.videotron.net */ if (!strncmp(action,"MODE",4)) { if ((a=malloc(strlen(input)+1))==NULL) { return(-1); } strcpy(a,input); b=strtok(a," "); if (a!=NULL) { free(a); } /* if there is a bang in the first part, its from a user */ if(strchr(b,'!')!=NULL) { serverdata->nick=strtok(input,"!"); /* nick name */ serverdata->username=strtok(NULL,"@"); /* username */ serverdata->ip=strtok(NULL," "); /* ip address */ serverdata->action=strtok(NULL," "); /* action */ serverdata->message=strtok(NULL," "); /* channel */ serverdata->extra=strtok(NULL,""); /* mode string */ strip_colon(serverdata->nick); strip_return(serverdata->extra); fprintf(*fp_log,"%s MODE %s by %s\n",serverdata->message,serverdata->extra,serverdata->nick); fflush(*fp_log); } /* otherwise it is from a server */ else { /* sometimes the server performs MODEs on users in channel, not sure if it sets channel modes */ /* lulea-r.se.eu.undernet.org MODE #mp3 +v MP3LAND */ serverdata->nick=strtok(input," "); /* server */ serverdata->action=strtok(NULL," "); /* action */ serverdata->message=strtok(NULL," "); /* channel */ serverdata->ip=strtok(NULL," "); /* flags */ serverdata->extra=strtok(NULL,""); /* other */ strip_colon(serverdata->nick); fprintf(*fp_log,"%s MODE %s %s by %s\n",serverdata->message,serverdata->ip,serverdata->extra,serverdata->nick); fflush(*fp_log); } } /* subcube_!subcube_@borg.hotwired.com KICK #acidblood m3chanml :subcube_ */ /* Uworld.undernet.org KICK #california lipe_-Rj :see ya */ /* Y-Wing!~ywing@130.14.36.31 KICK #chatzone Coelho :Banned for channel attacks and/or advertising */ if (!strncmp(action,"KICK",4)) { if ((a=malloc(strlen(input)))==NULL) { return(-1); } strcpy(a,input); b=strtok(a," "); free(a); /* if there is a bang in the first part, its from a user */ if(strchr(b,'!')!=NULL) { serverdata->nick=strtok(input,"!"); /* nick */ serverdata->username=strtok(NULL,"@"); /* username */ serverdata->ip=strtok(NULL," "); /* ip */ serverdata->action=strtok(NULL," "); /* action, should be KICK */ serverdata->message=strtok(NULL," "); /* channel */ serverdata->extra=strtok(NULL,":"); /* nick */ /* we dont care about the extra, will use that field for the nickname */ } /* otherwise it is from a server */ else { serverdata->nick=strtok(input," "); /* server */ serverdata->action=strtok(NULL," "); /* action */ serverdata->message=strtok(NULL," "); /* channel */ serverdata->ip=strtok(NULL," "); /* nickname */ serverdata->extra=strtok(NULL,""); /* reason */ } parsed=1; } if (action!=NULL) { free(action); } if (parsed) { while (serverdata->ip[x]) { if (isalpha(serverdata->ip[x])) { temp=serverdata->ip[x]; serverdata->ip[x]=tolower(temp); } x++; } } else { no_parse=1; } #ifdef DEBUG if (parsed) { fprintf(*fp_debug,"Nick=%s\n",serverdata->nick); fprintf(*fp_debug,"Username=%s\n",serverdata->username); fprintf(*fp_debug,"IP=%s\n",serverdata->ip); fprintf(*fp_debug,"Action=%s\n",serverdata->action); fprintf(*fp_debug,"Message=%s\n",serverdata->message); if (serverdata->extra!=NULL) { fprintf(*fp_debug,"extra=%s\n",serverdata->extra); } fprintf(*fp_debug,"\n"); fflush(*fp_debug); } #endif return (0); }