/***************************************************************************** * * $Id$ * Purpose ...............: Count WWW and FTP downloads * ***************************************************************************** * Copyright (C) 1997-2005 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 * 1971 BV IJmuiden * the Netherlands * * This file is part of MBSE BBS. * * This BBS 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 2, or (at your option) any * later version. * * MBSE BBS 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 MBSE BBS; see the file COPYING. If not, write to the Free * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #include "../config.h" #include "../lib/mbselib.h" #include "../lib/users.h" #include "../lib/mbsedb.h" #include "dlcount.h" static char *months[]={(char *)"Jan",(char *)"Feb",(char *)"Mar", (char *)"Apr",(char *)"May",(char *)"Jun", (char *)"Jul",(char *)"Aug",(char *)"Sep", (char *)"Oct",(char *)"Nov",(char *)"Dec"}; void count_download(char *, time_t, off_t); void dlcount(void) { char *temp, *p, *q, *date, *file, *base, month[20]; FILE *fp; int i, date_ok, file_ok, result, filesize; time_t filedate, lastcheck; struct tm tm; temp = calloc(PATH_MAX, sizeof(char)); /* * Check if we have a mark when we did this the last time. * If not, create one and don't do anything. Run the next time. */ sprintf(temp, "%s/var/dlcount.stat", getenv("MBSE_ROOT")); if ((lastcheck = file_time(temp)) == -1) { Syslog('+', "Checking WWW downloads never done before, creating timestamp"); if ((fp = fopen(temp, "a"))) { fclose(fp); } free(temp); return; } /* * Refresh timestamp */ unlink(temp); if ((fp = fopen(temp, "a"))) { fclose(fp); } date = calloc(81, sizeof(char)); file = calloc(PATH_MAX, sizeof(char)); base = calloc(PATH_MAX, sizeof(char)); if (strlen(CFG.www_logfile) && (fp = fopen(CFG.www_logfile, "r"))) { /* * Check apache logfile */ Syslog('+', "Checking WWW downloads"); while (fgets(temp, PATH_MAX-1, fp)) { date_ok = file_ok = FALSE; memset(date, 0, 80); memset(file, 0, PATH_MAX); memset(base, 0, PATH_MAX); Striplf(temp); /* * Parse logline, be aware for lots of garbage created by systems * that try to compromise the webserver. */ Syslog('f', "%s", printable(temp, 100)); p = strchr(temp, '['); if (p) { q = strchr(p, ']'); if (q && ((q-p) < 40)) { strncpy(date, p+1, q - p - 1); // Syslog('f', "\"%s\"", date); tm.tm_mday = atoi(strtok(date, "/\0")); sprintf(month, "%s", strtok(NULL, "/\0")); for (i = 0; i < 12; i++) if (strncasecmp(months[i], month, 3) == 0) break; tm.tm_mon = i; tm.tm_year = atoi(strtok(NULL, ":\0")) - 1900; tm.tm_hour = atoi(strtok(NULL, ":\0")); tm.tm_min = atoi(strtok(NULL, ":\0")); tm.tm_sec = atoi(strtok(NULL, ":\0")); // Syslog('f', "%d %d %d %d %d %d", tm.tm_mday, tm.tm_mon, tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec); filedate = mktime(&tm); // Syslog('f', "%s", rfcdate(filedate)); if (filedate > lastcheck) date_ok = TRUE; } } if (date_ok && (p = strchr(temp, '"'))) { q = strchr(p+1, '"'); if (q && ((q-p) < 128)) { strncpy(file, p+1, q - p - 1); // Syslog('f', "\"%s\"", file); if (strncmp(file, "GET ", 4) == 0) { if ((p = strstr(file, CFG.www_link2ftp))) { sprintf(base, "%s%s", CFG.ftp_base, p + strlen(CFG.www_link2ftp)); for (i = strlen(base); i; i--) { if (base[i] == ' ') { base[i] = '\0'; break; } } // Syslog('f', "%s", base); file_ok = TRUE; } } } } if (file_ok) { p = strtok(q, (char *)" \0"); result = atoi(strtok(NULL, (char *)" \0")); filesize = atoi(strtok(NULL, (char *)" \0")); if (result == 200) { /* * So far it seems that the file is possible downloaded from the bbs. * Now search the download area and filerecord. */ Syslog('f', "%s %s %d", rfcdate(filedate), base, filesize); count_download(base, filedate, filesize); } } } fclose(fp); } free(base); free(file); free(date); free(temp); } /* * Count download if file is present in the FDB. */ void count_download(char *filename, time_t filedate, off_t filesize) { char *temp; FILE *dfp; int i, j; struct _fdbarea *fdb_area = NULL; struct FILE_record frec; temp = calloc(PATH_MAX, sizeof(char)); sprintf(temp, "%s/etc/fareas.data", getenv("MBSE_ROOT")); if ((dfp = fopen(temp, "r"))) { fread(&areahdr, sizeof(areahdr), 1, dfp); sprintf(temp, "%s", filename); for (j = strlen(temp); j; j--) if (temp[j] == '/') { temp[j] = '\0'; break; } // Syslog('f', "%s", temp); i = 0; while (fread(&area, areahdr.recsize, 1, dfp) == 1) { i++; if (area.Available && (strcmp(temp, area.Path) == 0)) { sprintf(temp, "%s", basename(filename)); // Syslog('f', "Download area %d %s", i, temp); if ((fdb_area = mbsedb_OpenFDB(i, 30))) { while (fread(&frec, fdbhdr.recsize, 1, fdb_area->fp) == 1) { if (((strcmp(frec.Name, temp) == 0) || (strcmp(frec.LName, temp) == 0)) && (frec.Size == filesize)) { Syslog('+', "WWW download %s from area %d", temp, i); frec.LastDL = filedate; frec.TimesDL++; if (mbsedb_LockFDB(fdb_area, 30)) { fseek(fdb_area->fp, 0 - fdbhdr.recsize, SEEK_CUR); fwrite(&frec, fdbhdr.recsize, 1, fdb_area->fp); mbsedb_UnlockFDB(fdb_area); } break; } } mbsedb_CloseFDB(fdb_area); } break; } } fclose(dfp); } free(temp); }