/***************************** ** woho's MRTG Logfile cgi ** *****************************/ /* 2007-09-01: v1.3: modified mrtglog-1.2 by Roman Vasiyarov aka Winex, rvasiyarov@gmail.com */ #define VERSION "1.3" #include "./mrtglog.h" #include #include #include #include #include #define DBG_LVL 1 #define MAX_LOG_FILES 2 // how we were called, from shell (i.e. standalone) or from httpd (as .cgi) #define IS_STANDALONE (getenv("GATEWAY_INTERFACE") == NULL) #define TO_MBYTES(inbytes) ((inbytes)/1048576.0f) typedef struct { time_t t; float in; float out; } mrtg; int str2time(char *s); /************************************/ int main(int argc, char *argv[]) { mrtg ar[3000]; int i, y, a1, a2, a3, a4 , a5, diff, newmon, oldmon=13, year; char s[128], *str, *ctmp, *start, *stop, ch, ch2, ch3, hex[8]; char *reqmethod = NULL; char *logs[MAX_LOG_FILES]; char hostname[256]; int log_num = 0; time_t t1, t2; struct tm *zeit; float IN, OUT, ISUM=0.0f, OSUM=0.0f; FILE *fp; memset(logs, 0, sizeof(logs)*sizeof(char*)); if (argc >= 4) { // we are called from shell start = argv[1]; stop = argv[2]; for (i = 3; i < argc ; i++) { if (i >= MAX_LOG_FILES+3) { printf("Possibly truncated list of files, see MAX_LOG_FILES variable which has value of %d\n", MAX_LOG_FILES); fflush (stdout); break; } logs[i-3] = argv[i]; } log_num = i-3; #if (DBG_LVL == 1) for (i = 0; i < log_num; i++) printf("logs[%d]: %s\n", i, logs[i]); #endif } else if ( (reqmethod = (char*)getenv("REQUEST_METHOD")) != NULL ) { // we are called from httpd if (strcmp(reqmethod, "POST") == 0) { // method is "POST" i = 0; fgets(s, 100, stdin); printf("line %d: %s\n", i, s); while (fgets(s, 100, stdin)) { printf("line %d: %s\n", i, s); i++; } } else if ( (ctmp = (char*)getenv("QUERY_STRING")) != NULL ) { // method is "GET" (or "HEAD" :) ) #if (DBG_LVL == 1) if (*ctmp == '\0') { printf("%squery string is empty\n
REQUEST_METHOD is %s\n", HTMLHEAD, reqmethod); fflush(stdout); //return -1; } printf("%sQUERY_STRING: '%s'\n", HTMLHEAD, ctmp); fflush(stdout); #endif y = strlen(ctmp) + 1; str = (char *)malloc (y * sizeof(char)); *str = '\0'; for (i = 0; i < strlen(ctmp); i++) { ch = ctmp[i]; // fflush (stdout); if (ctmp[i] == '+') ch = ' '; if (ctmp[i] == '%') { ch2 = ctmp[i+1]; ch3 = ctmp[i+2]; i += 2; snprintf(hex, sizeof(hex), "%c%c", ch2, ch3); ch = strtol (hex, NULL, 16); if ((ch == 10) || (ch == 13)) ch = ' '; } snprintf(&str[strlen(str)], y-strlen(str), "%c", ch); } while (str) { ctmp = str; while (*ctmp != '=' && *ctmp != '&') { *ctmp = tolower (*ctmp); ctmp++; } if ((char *)strstr(str, "start") == str) { start = ctmp+1; ctmp = (char *) strchr(start, '&'); } else if ((char *)strstr(str, "stop") == str) { stop = ctmp+1; ctmp = (char *) strchr(stop, '&'); } else if ((char *)strstr(str, "log") == str) { logs[0] = ctmp+1; ctmp = (char *) strchr(logs[0], '&'); str = logs[0]; while ((str = strchr(str, ' ')) != NULL) { *str = '\0'; logs[log_num++] = str+1; } } else { printf("%sParameter '%s' is wrong
\n", HTMLHEAD, str); exit(1); } if (ctmp) { str = ctmp+1; *ctmp = '\0'; } else str = NULL; } } } if (!start || !stop || (log_num < 1) || (logs[0] == NULL)) { printf("%sUsage: mrtglog 2007-08-01 2003-08-31 mrtg.log [logfile2] ... # Count all traffic in August 2007 for specified log files
\n", HTMLHEAD); exit(1); } i = y = IN = OUT = 0; t1 = str2time(start); t2 = str2time(stop); // test how we were called and set path to mrtg logs accordingly // i.e. from httpd or shell if (IS_STANDALONE) ctmp = MRTGLOGS_SHELL_PATH; else ctmp = MRTGLOGS_CGI_RELATIVE_PATH; snprintf(s, sizeof(s), "%s%s", ctmp, logs[0]); fp = fopen(s, "r"); if (fp) { while (fgets(s, 100, fp)) { if (sscanf(s, "%d %d %d %d %d\n", &a1, &a2, &a3, &a4, &a5) == 5) { ar[y].t = a1; ar[y].in = a2; ar[y].out = a3; y++; } } fclose(fp); } else { printf("%scan't open '%s'!
\n", HTMLHEAD, s); exit(1); } // we need to cut '.log' only for title, not changing log string itself strncpy(s, logs[0], sizeof(s)); // our cutted string is stored in s str = (char *)strrchr(s, '/'); if (str) *str++; else str = s; if (ctmp = (char *)strstr(str, ".log")) *ctmp = '\0'; if (IS_STANDALONE) gethostname(hostname, sizeof(hostname)); else strncpy(hostname, getenv("SERVER_NAME"), sizeof(hostname)); printf("%s\n\n%s - Statistics from %s to %s for %s\n" "\n\n\ \n\ \n\ \n\ \n", HTMLHEAD, hostname, start, stop, s, s, start, stop); // sum data and output as table rows for (i = 0; i < y; i++) // trying to turn upside-down :) //for (i = y-2; i > 0; i--) { if ((t1 <= ar[i].t) && (ar[i].t <= t2)) { zeit = gmtime((const time_t *)&ar[i].t); newmon = zeit->tm_mon; if ((oldmon != 13 && newmon != oldmon) || i+1 == y) { if ((i+1) == y) { diff = ar[i].t - ar[i+1].t; IN = IN + ar[i].in * diff; OUT = OUT + ar[i].out * diff; } if ((IN == 0) && (OUT == 0)) break; ISUM += IN; OSUM += OUT; printf("\n", year+1900, oldmon+1, TO_MBYTES(IN), TO_MBYTES(OUT), TO_MBYTES(IN+OUT)); IN = OUT = 0; } if (i+1 < y) { oldmon = newmon; year = zeit->tm_year; diff = ar[i].t - ar[i+1].t; IN = IN + ar[i].in * diff; OUT = OUT + ar[i].out * diff; } } } /* // what is this??? //if (IN != 0 || OUT != 0) { ISUM += IN; OSUM += OUT; printf("\n", year+1900,oldmon+1,TO_MBYTES(IN),TO_MBYTES(OUT),TO_MBYTES(IN+OUT)); } */ // end table printf("

%s

\n\

Statistics from %s to %s

DATEINOUTTOTAL
%04i-%02i%.02f MB%.02f MB%.02f MB
%04i-%02i%.02f MB%.02f MB%.02f MB
\n"); // if we were called as cgi, then action must be as in REQUEST_URI var if (IS_STANDALONE) ctmp = argv[0]; else { ctmp = getenv("REQUEST_URI"); str = strchr(ctmp, '?'); if (str) *str = '\0'; } /* printf("TOTAL%.02f MB%.02f MB%.02f MB\n\ \n
\n\ from \n\ to \n\ \n\ \n\
\n

%s\n\n\ mrtglog %s, copyleft 2000 by http://www.netpark.at
\n\ modified by Roman Vasiyarov aka Winex\n\ \n\n", TO_MBYTES(ISUM), TO_MBYTES(OSUM), TO_MBYTES(ISUM+OSUM), ctmp, start, stop, logs[0], INFOTEXT, VERSION); */ // print form printf("\n
\n
\n\ from \n\ to \n\ \n\ \n\
\n

%s

\n", ctmp, start, stop, logs[0], INFOTEXT); // print footer printf("mrtglog %s, copyleft 2000 by http://www.netpark.at
\n\ modified by Roman Vasiyarov aka Winex\n\ \n\n", VERSION); return 0; } /************************************/ // desc: converts ISO date YYYY-MM-DD to int (time_t?) int str2time(char *s) { struct tm tim; int yyyy, mm, dd; if (sscanf(s, "%d-%d-%d", &yyyy, &mm, &dd) != 3) { printf("%s: can't convert '%s' to date
\n", HTMLHEAD, s); exit(10); } if (yyyy < 100) yyyy += 2000; tim.tm_sec = tim.tm_min = tim.tm_hour = 0; tim.tm_mday = dd; tim.tm_mon = mm - 1; tim.tm_year = yyyy - 1900; return mktime(&tim); } // and in the end, the love you take, is equal to the love you make. (John Lennon)