/* * stats.c * (C) Peter Salanki 2002 * This program is copyright, and covered by the Gnu Public License. * The Natasha log to mIRC log converter. * sorcer@linux.se */ #include #include #include #include #include #include #include "../src/settings.h" #define ROWSPERQUERY 100 void tomirc(char *action, char *nick, char *msg, char *time, char *chan); void convchan(int cid, char *chan); void servicedbconnect (void); int remotedbconnect (char *server, int port, char *user, char *pass, char *db); void dbquery (char *query); void servicedbquery (char *query); void remotedbquery (char *query); void dbconnect (void); char *escapequery (char *query); MYSQL mysql, *sock, servicemysql, *servicesock, remotemysql, *remotesock; MYSQL_RES *res, *serviceres, *remoteres; MYSQL_ROW row, servicerow, remoterow; FILE *log; char tmp[1024]; void dbconnect (void) { if (!(sock = mysql_real_connect(&mysql,MYSQL_STATSSERVER,MYSQL_STATSUSER,MYSQL_STATSPASS,MYSQL_STATSDB,3306,NULL,0))) { fprintf(stderr,"Couldn't connect to Stats MySQL server!\n%s\n\n", mysql_error(&mysql)); perror(""); exit(1); } } void servicedbconnect (void) { if (!(servicesock = mysql_real_connect(&servicemysql,MYSQL_SERVER,MYSQL_USER,MYSQL_PASS,MYSQL_DB,MYSQL_PORT,NULL,0))) { fprintf(stderr,"Couldn't connect to Service MySQL server!\n%s\n\n", mysql_error(&servicemysql)); perror(""); exit(1); } } int remotedbconnect (char *server, int port, char *user, char *pass, char *db) { if (!(remotesock = mysql_real_connect(&remotemysql,server,user,pass,db,port,NULL,0))) { fprintf(stderr,"Couldn't connect to MySQL server!\n%s\n\n", mysql_error(&remotemysql)); perror(""); return -1; } else return 1; } void dbquery (char *query) { if(mysql_query(sock, query)) { printf("Query failed (%s)\n", mysql_error(sock)); printf("Query: %s\n", query); } else res = mysql_store_result(sock); } void servicedbquery (char *query) { if(mysql_query(servicesock, query)) { printf("Query failed (%s)\n", mysql_error(servicesock)); } else serviceres = mysql_store_result(servicesock); } void remotedbquery (char *query) { if(mysql_query(remotesock, query)) { printf("Query failed (%s)\n", mysql_error(remotesock)); } else remoteres = mysql_store_result(remotesock); } char *escapequery (char *query) { char *escaped = malloc(2*strlen(query)); mysql_real_escape_string(&mysql, escaped, query, strlen(query)); return escaped; } int main (int argc, char **argv) { char query[MAX_QUERY+1024]; char *biginsert; char tmpnick[NICKLEN*2]; char msg[1024]; time_t updatetime; long htmlsize; FILE *htmlfile, *pisgconf; char *htmlbuffer, *bigquery, *htmlbufferparsed; div_t divresult; int mqid; printf("Natasha log fetcher and stats generator v1.0.\nStats will be updated every: %d hour.\n", STATS_UPDATE_TIME); while(1) { printf("\nNew stats run.\n"); updatetime = time(NULL); /* Clean up and open pisg config */ sprintf(query, "rm %s*.html && rm *.mrc", PISG); system(query); sprintf(query, "%spisg.cfg", PISG); pisgconf = fopen(query, "w"); /* Write pisg header */ fprintf(pisgconf, "#Pisg config generated by Natasha log fetcher and stats generator (a part of The Natasha Project).\n\n#Here starts channel configs.\n\n", BOTHOUSE); dbconnect(); servicedbconnect(); servicedbquery("SELECT SQL_NO_CACHE `nick` FROM `arms`"); while((servicerow = mysql_fetch_row(serviceres))) { fprintf(pisgconf, "\n", servicerow[0]); } mysql_free_result(serviceres); #ifdef Q fprintf(pisgconf, "\n", Q_NICK); #ifdef L fprintf(pisgconf, "\n", L_NICK); #endif #endif servicedbquery("SELECT SQL_NO_CACHE `id`,`name`,`statsdb_ip`,`statsdb_port`,`statsdb_user`,`statsdb_pass`,`statsdb_db` FROM `services`"); while((servicerow = mysql_fetch_row(serviceres))) { printf("Connectig to service: %s.\n", servicerow[1]); if((remotedbconnect(servicerow[2], atoi(servicerow[3]), servicerow[4], servicerow[5], servicerow[6]))) { /* Now we transfer the logs */ printf("Transferring logs.\n"); remotedbquery("SELECT SQL_NO_CACHE SQL_BUFFER_RESULT `cid`,`action`,`nick`,`username`,`host`,`uid`,`msg`,`time` FROM `log`"); mqid = 0; biginsert = malloc(512*ROWSPERQUERY); // Malloc while((remoterow = mysql_fetch_row(remoteres))) { strncpy(msg, "", 1024); strncpy(tmpnick, "", NICKLEN); mysql_real_escape_string(&remotemysql, tmpnick, remoterow[2], strlen(remoterow[2])); mysql_real_escape_string(&remotemysql, msg, remoterow[6], strlen(remoterow[6])); if (mqid == 0) { sprintf(biginsert, "INSERT INTO `log` (`cid`, `action`, `nick`, `username`, `host`, `uid`, `msg`, `time`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", remoterow[0], remoterow[1], tmpnick, escapequery(remoterow[3]), remoterow[4], remoterow[5], msg, remoterow[7]); } else if (mqid == ROWSPERQUERY) { sprintf(query, ", ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", remoterow[0], remoterow[1], tmpnick, escapequery(remoterow[3]), remoterow[4], remoterow[5], msg, remoterow[7]); strcat(biginsert, query); mysql_query(sock, biginsert); mqid = -1; // printf("len: %i)\n", strlen(biginsert)); } else { sprintf(query, ", ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", remoterow[0], remoterow[1], tmpnick, escapequery(remoterow[3]), remoterow[4], remoterow[5], msg, remoterow[7]); strcat(biginsert, query); } ++mqid; } mysql_free_result(remoteres); if (mqid > 0) { mysql_query(sock, biginsert); mqid = 0; } free(biginsert); // Free remotedbquery("DELETE FROM `log`"); mysql_close(remotesock); } } mysql_free_result(serviceres); /* Now we are going to make mIRC logs for all channels */ printf("Generateing mIRC logs of all channel logs.\n"); /* First we get all channels and add to pisg config and generate smIRC logs */ servicedbquery("SELECT `id`,`name` FROM `channels` WHERE `stats` = 1"); while((servicerow = mysql_fetch_row(serviceres))) { fprintf(pisgconf, "\n\tformat=\"mIRC\"\n\tnetwork=\"%s\"\n\toutputfile=\"%i.html\"\n\n\n", servicerow[1], atoi(servicerow[0]), NETWORK, atoi(servicerow[0])); convchan(atoi(servicerow[0]), servicerow[1]); } mysql_free_result(serviceres); fclose(pisgconf); /* We close the pisg config */ /* Run pisg and create the stats */ printf("Running pisg.\n"); sprintf(query, "cd %s && ./pisg > pisg.log && cd ../", PISG); system(query); /* Read all HTML files and add them to SERVICE-DB */ printf("Inserting pisg outpout to database.\n"); servicedbquery("DELETE FROM `stats`"); servicedbquery("SELECT `id`,`name` FROM `channels` WHERE `stats` = 1"); while((servicerow = mysql_fetch_row(serviceres))) { sprintf(query, "%s%i.html", PISG, atoi(servicerow[0])); htmlfile = fopen(query, "rb"); if(htmlfile != NULL) { fseek (htmlfile, 0, SEEK_END); htmlsize = ftell(htmlfile); rewind(htmlfile); /* Some mallocs */ htmlbuffer = (char*) malloc(htmlsize); htmlbufferparsed = (char*) malloc(htmlsize+htmlsize); bigquery = (char*) malloc(htmlsize+htmlsize+MAX_QUERY); if(htmlbuffer != NULL && bigquery != NULL) { fread(htmlbuffer,1,htmlsize,htmlfile); /* Let's add to database */ mysql_real_escape_string(&servicemysql, htmlbufferparsed, htmlbuffer, htmlsize); sprintf(bigquery, "INSERT INTO `stats` (`name`, `cid`, `html`) VALUES ('%s', '%d', '%s')", servicerow[1], atoi(servicerow[0]), htmlbufferparsed); mysql_query(servicesock, bigquery); /* We free some memory */ free(htmlbuffer); free(htmlbufferparsed); free(bigquery); } else printf("Malloc error.\n"); fclose(htmlfile); } } mysql_free_result(serviceres); updatetime = (time(NULL) - updatetime); divresult = div(updatetime, 60); /* Now we updatet some info */ sprintf(query, "UPDATE `info` SET `stats_lastupdate` = '%i', `stats_time` = '%i'", (int) time(NULL), (int) updatetime); servicedbquery(query); /* Now we close som MySQL connections and free some memory*/ mysql_close(servicesock); mysql_close(sock); mysql_free_result(serviceres); mysql_free_result(remoteres); printf("Stats run completd in: %i minutes.\n", divresult.quot); sleep(STATS_UPDATE_TIME*3600); // Now we ZZzzz till next run. /* This is only some lazy code to solve this bug, sohould be properly fixed */ /* system("sleep 10 && ./stats &"); exit(0); */ } return 0; } void convchan(int cid, char *chan) { char query[MAX_QUERY]; /* Open the mIRC log */ sprintf(query, "%i.mrc", cid); log = fopen(query, "w"); sprintf(query, "SELECT SQL_NO_CACHE `action`,`nick`,`msg`, FROM_UNIXTIME(`time`, '%%H:%%i:%%s') FROM `log` WHERE `cid` = '%d'", cid); dbquery(query); while((row = mysql_fetch_row(res))) tomirc(row[0], row[1], row[2], row[3], chan); mysql_free_result(res); fclose(log); } void tomirc(char *action, char *nick, char *msg, char *time, char *chan) { char real_msg[500]; char real_nick[NICKLEN]; int i, j; fprintf(log, "[%s] ", time); if(strcmp(action, "PRIVMSG") == 0) { if(msg[0] == '\x1') { strncpy(real_msg, "", 500); i = 8; j = 0; while(msg[i] != '\0') { real_msg[j] = msg[i]; ++i; ++j; } fprintf(log, "* %s %s\n", nick, real_msg); } else fprintf(log, "<%s> %s\n", nick, msg); } else if(strcmp(action, "MODE") == 0) fprintf(log, "*** %s sets mode: %s\n", nick, msg); else if(strcmp(action, "JOIN") == 0) fprintf(log, "*** %s has joined %s\n", nick, chan); else if(strcmp(action, "KICK") == 0) { strncpy(real_msg, "", 500); strncpy(real_nick, "", NICKLEN); i = 0; j = 0; while(msg[i] != '\0' && msg[i] != ' ') { real_nick[j] = msg[i]; ++i; ++j; } if(msg[i] == ' ') { ++i; j = 0; while(msg[i] != '\0') { real_msg[j] = msg[i]; ++i; ++j; } } fprintf(log, "*** %s was kicked by %s (%s)\n", real_nick, nick, real_msg); } else if(strcmp(action, "PART") == 0) fprintf(log, "*** %s has left %s\n", nick, chan); else if(strcmp(action, "TOPIC") == 0) fprintf(log, "*** %s changes topic to '%s'\n", nick, msg); }