/* Bot Net Example file (c) Christophe CALMEJANE - 1999'00 aka Ze KiLleR / SkyTech */ #include "../makelib/botnet.h" #include #include #include #include #include #include #include #define BOT_NICKNAME "logger" #define BOT_USERNAME "nobody" #define BOT_REALNAME "Logger Bot v1.2" #define BOT_CHANNEL "#bottest" #define LOGGERRC ".loggerrc" #define MY_PASS "botnet" #define DCC_WAITING_FOR_PASS 1 #define DCC_PASS_ACCEPTED 2 /* Codes: A Action T Talk (normal channel talk) N Nick change J Join L Leave Q Quit t Topic change K Kill */ int lprintf(const char *str, ...) { va_list va; int i; va_start(va, str); i = vprintf(str, va); va_end(va); fflush(stdout); return i; } int Val; typedef struct _ChannelInfo { char *channel; FILE *file; } ChannelInfo; ChannelInfo **ci = 0; int nci = 0; ChannelInfo *newChannelInfo(void) { ChannelInfo *newci; newci = (ChannelInfo*)malloc(sizeof(ChannelInfo)); return newci; } void freeChannelInfo(ChannelInfo *ci) { if(!ci) return; if(ci->channel) { free(ci->channel); ci->channel = 0; } if(ci->file) { fclose(ci->file); ci->file = 0; } free(ci); } int getChannelIdx(const char *channel) { int i; for(i=0; ichannel)) { return i; } } return -1; } ChannelInfo *getChannel(const char *channel) { int i = getChannelIdx(channel); return i == -1 ? 0 : ci[i]; } int achprintf(const char *str, ...) { va_list va; int i=0,j; for(j=0; jfile, str, va); fflush(ci[j]->file); va_end(va); } return i; } int chprintf(const char *Channel, const char *str, ...) { va_list va; int i; ChannelInfo *curci = getChannel(Channel); if(!curci) return 0; va_start(va, str); i = vfprintf(curci->file, str, va); va_end(va); fflush(curci->file); return i; } void writeConfiguration(void) { FILE *conf = fopen(LOGGERRC, "wt"); int i; if(!conf) { lprintf("ERROR saving configuration\n"); return; } for(i=0; ichannel); } fflush(conf); fclose(conf); } void addChannel(const char *channel) { ChannelInfo *newci; char logfilename[100]; if(getChannelIdx(channel) != -1) return; sprintf(logfilename, "log.%s", channel); newci = newChannelInfo(); newci->channel = strdup(channel); newci->file = fopen(logfilename, "at"); if(!ci) ci = (ChannelInfo**)malloc(1); ci = (ChannelInfo**)realloc(ci, ++nci * sizeof(ChannelInfo*)); ci[nci-1] = newci; lprintf("Started logging channel '%s' into file '%s'\n", channel, logfilename); fprintf(newci->file, "%ld 1\n", time(0)); writeConfiguration(); } void removeChannel(const char *channel) { int i = getChannelIdx(channel); if(i == -1) return; lprintf("Stopped logging for channel '%s'\n", channel); fprintf(ci[i]->file, "%ld 0\n", time(0)); freeChannelInfo(ci[i]); memmove(&ci[i], &ci[i+1], nci - (i+1)); nci--; writeConfiguration(); } char *chomp(char *str) { char *pe = str + strlen(str) - 1; while(pe > str && (*pe == '\n' || *pe == '\r')) pe--; *++pe = 0; return str; } /*******************************************************************/ void ProcOnConnected(BN_PInfo I,const char HostName[]) { lprintf("Event Connected : (%s)\n",HostName); BN_EnableFloodProtection(I,100,1000,200); BN_Register(I,BOT_NICKNAME,BOT_USERNAME,BOT_REALNAME); } void ProcOnRegistered(BN_PInfo I) { FILE *conf; char str[256]; int i=0; lprintf("Event Registered\n"); lprintf("Reading configuration...\n"); conf = fopen(".loggerrc", "rt"); if(!conf) { lprintf("No configuration found, using defaults\n"); } else { while(fgets(str, 256, conf)) { chomp(str); BN_SendJoinMessage(I, str, NULL); i++; } fclose(conf); lprintf("Configuration read.\n"); } if(!i) { BN_SendJoinMessage(I,BOT_CHANNEL,NULL); } // BN_SendMessage(I,BN_MakeMessage(NULL,"MODE",BOT_CHANNEL),BN_LOW_PRIORITY); // BN_SendMessage(I,BN_MakeMessage(NULL,"LIST",""),BN_LOW_PRIORITY); Val++; // Modify the variable, main's Val will only be modified if same thread } void ProcOnError(BN_PInfo I,int err) { lprintf("Event Error : (%d)\n",err); } void ProcOnStatus(BN_PInfo I,const char Msg[],int Code) { lprintf("Event Status : %s\n",Msg); if(strstr(Msg, "Nickname")) { lprintf("(retrying in 1 secs...)\n"); sleep(1); BN_Register(I,BOT_NICKNAME,BOT_USERNAME,BOT_REALNAME); } } void ProcOnJoinChannel(BN_PInfo I,const char Channel[]) { lprintf("Channel %s joined.\n", Channel); addChannel(Channel); } void ProcOnChannelTalk(BN_PInfo I,const char Channel[],const char Who[],const char Msg[]) { lprintf("%ld T %s %s %s\n",time(0),Channel,Who,Msg); chprintf(Channel, "%ld T %s %s\n",time(0),Who,Msg); } void ProcOnAction(BN_PInfo I,const char Channel[],const char Who[],const char Msg[]) { lprintf("%ld A %s %s %s\n",time(0),Channel,Who,Msg); chprintf(Channel, "%ld A %s %s\n",time(0),Who,Msg); } void ProcOnPrivateTalk(BN_PInfo I,const char Who[],const char Whom[],const char Msg[]) { lprintf("%s -> %s %s\n",Who,Whom,Msg); if(!strcmp(Whom, BOT_NICKNAME)) { // Don't understand messages... char str[5000]; int i; lprintf("Replying to %s..\n", Who); BN_SendPrivateMessage(I, Who, "Usage: '/invite " BOT_NICKNAME "' to enable logging for the current channel and '/kick #channel " BOT_NICKNAME "' to disable logging."); strcpy(str, "Logging enabled for channel(s) "); for(i=0; ichannel); strcat(str, ", "); } strcpy(&str[strlen(str)-2], "."); BN_SendPrivateMessage(I, Who, str); } } void ProcOnNotice(BN_PInfo I,const char Who[],const char Whom[],const char Msg[]) { lprintf("Event Notice: %s -> %s %s\n",Who,Whom,Msg); } void ProcOnNick(BN_PInfo I,const char OldNick[],const char NewNick[]) { lprintf("Nick changed: %s -> %s\n",OldNick,NewNick); achprintf("%ld N %s %s\n",time(0),OldNick,NewNick); } void ProcOnJoin(BN_PInfo I,const char Channel[],const char Who[]) { lprintf("%s : %s joined\n",Channel, Who); chprintf(Channel, "%ld J %s\n",time(0),Who); } void ProcOnPart(BN_PInfo I,const char Channel[],const char Who[], const char Msg[]) { lprintf("%s : %s left\n",Channel, Who); chprintf(Channel, "%ld L %s\n",time(0),Who); } void ProcOnQuit(BN_PInfo I,const char Who[], const char Msg[]) { int i; lprintf("%s quit: %s\n", Who, Msg); for(i=0; ifile, "%ld Q %s %s\n",time(0),Who,Msg); fflush(ci[i]->file); } } void ProcOnMode(BN_PInfo I,const char Channel[],const char Who[],const char Msg[]) { lprintf("Mode for %s by %s : %s\n",Channel,Who,Msg); } void ProcOnModeIs(BN_PInfo I,const char Channel[],const char Msg[]) { lprintf("Mode for %s : %s\n",Channel,Msg); } void ProcOnTopic(BN_PInfo I,const char Channel[],const char Who[],const char Msg[]) { lprintf("Topic for %s has been changed by %s to %s\n",Channel,Who,Msg); chprintf(Channel, "%ld t %s %s\n", time(0), Who, Msg); } void ProcOnTopicIs(BN_PInfo I,const char Channel[],const char Msg[]) { lprintf("Topic for %s is %s\n",Channel,Msg); } void ProcOnTopicSetBy(BN_PInfo I,const char Channel[],const char Msg[],const char Time[]) { lprintf("Topic for %s was been changed to %s at %s\n",Channel, Msg, Time); } void ProcOnList(BN_PInfo I,const char *Channels[],const char *Counts[],const char *Topics[],const int Count) { int i; for(i=0;ifile, "%ld K %s %s\n",time(0),Who,Msg); fflush(ci[i]->file); } } void ProcOnDisconnected(BN_PInfo I,const char Msg[]) { int i; lprintf("Event Disconnected : %s\n",Msg); for(i=0; ichannel); } } void ProcOnExcessFlood(BN_PInfo I,const char Msg[]) { lprintf("Event Flood : %s\n",Msg); } void ProcOnUnknown(BN_PInfo I,const char Who[],const char Command[],const char Msg[]) { lprintf("Event Unknown from %s : %s %s\n",Who,Command,Msg); } int main(int nArgs, char **Args) { BN_TInfo Info; pid_t Res; lprintf("Logger BOT by Jonas Berlin, started 31.10.2000\n%s\n",BN_GetCopyright()); memset(&Info,0,sizeof(Info)); Info.CB.OnConnected = ProcOnConnected; Info.CB.OnRegistered = ProcOnRegistered; Info.CB.OnError = ProcOnError; Info.CB.OnStatus = ProcOnStatus; Info.CB.OnJoinChannel = ProcOnJoinChannel; Info.CB.OnChannelTalk = ProcOnChannelTalk; Info.CB.OnAction = ProcOnAction; Info.CB.OnPrivateTalk = ProcOnPrivateTalk; Info.CB.OnNotice = ProcOnNotice; Info.CB.OnNick = ProcOnNick; Info.CB.OnJoin = ProcOnJoin; Info.CB.OnPart = ProcOnPart; Info.CB.OnQuit = ProcOnQuit; Info.CB.OnMode = ProcOnMode; Info.CB.OnModeIs = ProcOnModeIs; Info.CB.OnTopic = ProcOnTopic; Info.CB.OnTopicIs = ProcOnTopicIs; Info.CB.OnTopicSetBy = ProcOnTopicSetBy; Info.CB.OnList = ProcOnList; Info.CB.OnNames = ProcOnNames; Info.CB.OnWhois = ProcOnWhois; Info.CB.OnWho = ProcOnWho; Info.CB.OnInvite = ProcOnInvite; Info.CB.OnKick = ProcOnKick; Info.CB.OnKill = ProcOnKill; Info.CB.OnDisconnected = ProcOnDisconnected; Info.CB.OnExcessFlood = ProcOnExcessFlood; Info.CB.OnUnknown = ProcOnUnknown; Val = 0; // Val initialized to 0 here... If new PROCESS, cannot change this variable... otherwise we can #ifdef DEBUG while(BN_Connect(&Info,"10.0.255.254",6667,0) != true) #else while(BN_Connect(&Info,"10.0.255.254",6667,PROCESS_NEW_THREAD) != true) #endif { lprintf("Disconnected.\n"); sleep(10); lprintf("Reconnecting...\n"); } do { Res = waitpid(-1,NULL,WNOHANG); // printf("Val = %d\n",Val); sleep(5); } while(Res <= 0); return 0; }