home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / ECHOREPT.ZIP / ECHOREPT.C next >
Encoding:
C/C++ Source or Header  |  1993-12-12  |  8.1 KB  |  316 lines

  1. /* ECHOREPT is Copyright 1993 by Thomas Almy.
  2.    It may be used without charge.
  3.    It may be distributed provided no charge is made other than
  4.    actual distribution costs.  */
  5.  
  6. /* Compile with Borland C, Compact memory modem (-mc). */
  7.  
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <time.h>
  13. #include <alloc.h>
  14.  
  15. #define NAMESIZE (31)
  16. #define MAXHUD (200)
  17.  
  18. char *groups = 0;        /* new groups feature */
  19. char dbname[12] = "netrep2.dat";
  20.  
  21. char gepath[128];
  22.  
  23. FILE *dbfp;
  24.  
  25. int thisdate;
  26. struct tm *block;
  27.  
  28. int dbsize;
  29.  
  30. typedef struct   {
  31.     char echoname[NAMESIZE];
  32.     int area;       /* area number */
  33.     int tally[30];    /* 30 day record */
  34. } DBRECORD;
  35.  
  36. DBRECORD huge *db;  /* the records */
  37. DBRECORD huge **dbp;    /* array of pointers to sorted records */
  38.  
  39. #define a_area ((*(DBRECORD **)a)->area)
  40. #define b_area ((*(DBRECORD **)b)->area)
  41. #define a_name ((*(DBRECORD **)a)->echoname)
  42. #define b_name ((*(DBRECORD **)b)->echoname)
  43.  
  44. int sort_function(const void *a, const void *b) {
  45.     if (a_area == 0) return (b_area ? 1 : 0);
  46.     if (b_area == 0) return -1;
  47.     if (a_area <= MAXHUD) { /* first is hudson */
  48.         if (b_area <= MAXHUD)
  49.             return (a_area < b_area? -1 : 1);    /* no dupes are possible */
  50.         else
  51.             return -1; /* Hudson less than passthrough */
  52.     }
  53.     else { /* first is passthrough */
  54.         if (b_area <= MAXHUD)
  55.             return 1;
  56.         else 
  57.             return strcmp(a_name, b_name);
  58.     }
  59. }
  60.  
  61. void sortit(void) {
  62.     int i, i2, j;
  63.     for (i=0; i<dbsize; i++) {    /* delete entries that have no messages */
  64.         for (j=0,i2=0; i2<30; i2++) j += db[i].tally[i2];
  65.         if (j == 0) { /* clear entry */
  66.             db[i].echoname[0] = 0;    
  67.             db[i].area = 0;
  68.         }
  69.     }
  70.     qsort((void *)dbp, dbsize, sizeof(DBRECORD *), sort_function);
  71. }
  72.  
  73. void makereport(char *filename, int days, char *title) {
  74.     
  75.     FILE *fp;
  76.     char ans[64];
  77.     char areastr[6];
  78.     int st = (days>28 || days==1 ? 0 : 1);    /* starting day */
  79.     int i,j;
  80.     long gt=0;    /* grand total */
  81.     int tot;    /* total for each area */
  82.     int wtot[4];/* totals for weeks */
  83.  
  84.     days += st;    /* when we start on day 1, end is one further */
  85.     
  86.     if ((fp = fopen(filename, "w")) == NULL) {
  87.         printf( "Error--unable to create %s\n", filename);
  88.         return;    /* no error exit on this one */
  89.     }
  90.     
  91.     strcpy(ans, asctime(block));
  92.     if (groups != NULL) {
  93.         fprintf(fp, "%s          Report prepared %.10s, %.4s\nfor group", 
  94.                 title, ans, &ans[20]);
  95.         fprintf(fp, groups[1]!= '\0'? "s %s\n\n" : " %s\n\n", groups);
  96.     }
  97.     else
  98.         fprintf(fp, "%s          Report prepared %.10s, %.4s\n\n", 
  99.                 title, ans, &ans[20]);
  100.  
  101.     if (days==8) 
  102.         fputs(" #  Area Name                Daily Totals            Total Percent\n",fp);
  103.     else if (days==29)
  104.         fputs(" #  Area Name                Weekly Totals   Total Percent\n",fp);
  105.     else
  106.         fputs(" #  Area Name                      Total Percent\n",fp);
  107.  
  108.     for (i = 0; i < dbsize; i++)  /* calculate grand total messages */
  109.         for (j = st; j < days; j++) 
  110.             gt += db[i].tally[j];
  111.  
  112.     for (i = 0; i < dbsize; i++) {
  113.         tot = 0;
  114.         for (j = st; j < days; j++) tot += dbp[i]->tally[j];
  115.         if (tot == 0) continue;
  116.         if (dbp[i]->area > MAXHUD) 
  117.             strcpy(areastr, " P ");
  118.         else
  119.             sprintf(areastr, "%3d", dbp[i]->area);
  120.         if (days==8) { /* different for weekly report */
  121.             fprintf(fp, "%s %-20.20s%4d%4d%4d%4d%4d%4d%4d %5d %.1f%%\n", 
  122.                 areastr,
  123.                 dbp[i]->echoname, 
  124.                 dbp[i]->tally[7],
  125.                 dbp[i]->tally[6],
  126.                 dbp[i]->tally[5],
  127.                 dbp[i]->tally[4],
  128.                 dbp[i]->tally[3],
  129.                 dbp[i]->tally[2],
  130.                 dbp[i]->tally[1],
  131.                 tot, 
  132.                 (100.0 * tot)/gt);
  133.         }
  134.         else if (days==29) { /* and for monthly report */
  135.             wtot[0] = wtot[1] = wtot[2] = wtot[3] = 0;
  136.             for (j=1; j<8; j++) {
  137.                 wtot[0] += dbp[i]->tally[j];
  138.                 wtot[1] += dbp[i]->tally[j+7];
  139.                 wtot[2] += dbp[i]->tally[j+14];
  140.                 wtot[3] += dbp[i]->tally[j+21];
  141.             }
  142.             fprintf(fp, "%s %-20.20s%4d %4d %4d %4d  %5d  %.1f%%\n",
  143.                 areastr,
  144.                 dbp[i]->echoname,
  145.                 wtot[3], wtot[2], wtot[1], wtot[0],
  146.                 tot,
  147.                 (100.0 * tot)/gt);
  148.         }
  149.         else {
  150.             fprintf(fp, "%s %-30.30s %5d %.1f%%\n", areastr,
  151.                 dbp[i]->echoname, 
  152.                 tot, 
  153.                 (100.0 * tot)/gt);
  154.         }
  155.     }
  156.     fprintf(fp, "\n%ld total messages\n", gt);
  157.     fclose(fp);
  158. }
  159.  
  160. void readsummary(void) {
  161.     FILE *transp;
  162.     char filename[128];
  163.     char buff[128];
  164.     char area[NAMESIZE];
  165.     char gr;
  166.     int i,j, areanum;
  167.  
  168.     strcpy(filename, gepath);
  169.     strcat(filename, "summary.log");
  170.     
  171.     if ((transp = fopen(filename, "r")) == NULL) {
  172.         printf( "Note-- summary.log file not found\n");
  173.         return;
  174.     }
  175.     
  176.     i=5;
  177.     while (i--) fgets(buff, sizeof(buff), transp); /* header lines */
  178.     
  179.     while (fgets(buff, sizeof(buff), transp) != NULL) {
  180.         if (strncmp(buff, "-----", 5) == 0) break;    /* end reached */
  181.         if (sscanf(buff, "%d %30s %d %*d %c", &areanum, &area, &j, &gr) != 4 ||
  182.             areanum < 1 ) continue; /* bad record ?? */
  183.         if (groups != NULL && strchr(groups, gr) == NULL)
  184.             continue; /* not in this group */
  185.         for (i=0; i<dbsize && db[i].echoname[0] != 0; i++) 
  186.             if (strcmp(area, db[i].echoname)==0) break;
  187.         if (i < dbsize) { /* new record -- if there is room */
  188.             strcpy(db[i].echoname, area);
  189.             db[i].area = areanum;
  190.             db[i].tally[0] += j;
  191.         }
  192.     }
  193.     fclose(transp);
  194.     if (groups == NULL)
  195.         unlink(filename);    /* get rid of file if not a partial scan */
  196. }
  197.     
  198.  
  199. void getdb(void) {    /* get the database */
  200.     time_t timer;
  201.     int olddate;
  202.     int i, diff;
  203.     int actual_size;
  204.  
  205.     timer = time(NULL);
  206.     block = localtime(&timer);
  207.     thisdate = block->tm_yday;
  208.     
  209.     if ((dbfp = fopen(dbname,"rb")) == NULL) { /* no file */
  210.         actual_size = 0;
  211.     }
  212.     else {    /* file exists */
  213.         setvbuf(dbfp, NULL, _IOFBF, 8192);
  214.         fseek(dbfp, 0L, SEEK_END);
  215.         actual_size = (int) ((ftell(dbfp) - sizeof(int)) / sizeof(DBRECORD));
  216.         rewind(dbfp);
  217.     }
  218.  
  219.     dbsize=(int)((farcoreleft()-10000)/(sizeof(DBRECORD)+sizeof(DBRECORD*)));
  220.  
  221.     if ((db = farcalloc(dbsize, sizeof(DBRECORD))) == NULL ||
  222.         (dbp = farcalloc(dbsize, sizeof(DBRECORD *))) == NULL) {
  223.         printf( "Error -- insufficient memory\n");
  224.         exit(1);
  225.     }
  226.  
  227.     for (i=0; i<dbsize; i++) dbp[i] = &db[i];
  228.  
  229.     if (actual_size==0) return;
  230.  
  231.     fread(&olddate, sizeof(int), 1, dbfp);
  232.     
  233.     for (i=0; i < actual_size; i++)
  234.         if (fread(&db[i], sizeof(DBRECORD), 1, dbfp) != 1) {
  235.             printf( "Error -- bad file\n", dbname);
  236.             exit(1);
  237.         }
  238.  
  239.     fclose(dbfp);
  240.     
  241.     if (olddate == thisdate) return;
  242.     
  243.     /* Date changed -- shift the counter array for each echo by the
  244.        number of days that have passed */
  245.  
  246.     if (olddate > thisdate) {
  247.         olddate -= 365;
  248.         if (block->tm_year % 4 == 1) olddate--;
  249.     }
  250.     
  251.     diff = thisdate - olddate;
  252.  
  253.     if (diff > 29) { /* boy has time passed! */
  254.         diff = 30;
  255.     }
  256.  
  257.     for (i=0; i<dbsize; i++) {
  258.         memmove(&db[i].tally[diff], &db[i].tally[0], sizeof(int)*(30-diff));
  259.         memset(&db[i].tally[0], 0, sizeof(int)*diff);
  260.     }
  261.     return;
  262. }
  263.     
  264.  
  265. void badwrite(void) {
  266.         printf( "Error -- write of %s failed", dbname);
  267.         exit(1);
  268. }
  269.  
  270. void putdb(void) {
  271.     int i=0;
  272.     
  273.     if ((dbfp = fopen(dbname,"wb")) == NULL) { /* can't open output */
  274.         printf("Error -- can't write %s file", dbname);
  275.         exit(1);
  276.     }
  277.  
  278.     setvbuf(dbfp, NULL, _IOFBF, 8192);
  279.  
  280.     if (fwrite(&thisdate, sizeof(int), 1, dbfp) != 1) badwrite();
  281.  
  282.     while (dbp[i]->area != 0 && i < dbsize) 
  283.         if (fwrite(dbp[i++], sizeof(DBRECORD), 1, dbfp) != 1) badwrite();
  284.  
  285.     fclose(dbfp);
  286. }
  287.  
  288.  
  289. void main(int argc, char **argv) {
  290.     char *cp;
  291.     
  292.     if (argc > 1 && argv[1][0] == '-')    { /* group selection provided */
  293.         groups = argv[1] + 1;
  294.         strncpy(dbname+8, groups, 3);    /* new name extension */
  295.         argc--;
  296.         argv++;
  297.     }
  298.  
  299.     strcpy(gepath, getenv("GE"));    /* gecho path */
  300.     if ((cp = strchr(gepath, ' '))!=NULL) 
  301.         *cp = '\0'; /* ignore color argument */
  302.     if (*gepath && gepath[strlen(gepath)-1] !='\\') strcat(gepath, "\\");
  303.  
  304.     getdb();
  305.     
  306.     readsummary();    /* read summary file, if any */
  307.  
  308.     if (argc > 1) sortit();    /* sort database if we are making a report */
  309.     if(argc > 1) makereport(argv[1], 1,  "Todays's Echo Traffic    ");
  310.     if(argc > 2) makereport(argv[2], 7,  "Previous Week's Echo Traffic");
  311.     if(argc > 3) makereport(argv[3], 28, "Four Week Echo Traffic      ");
  312.     if(argc > 4) makereport(argv[4], 30, "Thirty Day Echo Traffic     ");
  313.     
  314.     putdb();
  315. }
  316.