home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / TOPUSE4S / TOPUSERS.C next >
Text File  |  1992-01-13  |  21KB  |  781 lines

  1. #include <dir.h>
  2. #include <dos.h>
  3. #include <io.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <time.h>
  9.  
  10. #include "user.h"
  11. #include "topusers.h"
  12.  
  13. void qsort2(void *base, unsigned nel, unsigned width,
  14.             int (*comp)(const void *, const void *));
  15.  
  16. int s_len, userfile, num_users, calls = 0;
  17. unsigned long length, uploads = 0L, downloads = 0L, syscalls = 0L;
  18.  
  19. char configfile[80] = "topusers.cfg";
  20.  
  21. FILE *out, *cnf;
  22.  
  23. int tencalls[100], tenups[100], tendowns[100], node[99];
  24.  
  25. main(int argc, char *argv[])
  26. {
  27.    struct _usr users[1];
  28.  
  29.    int x, y, z;
  30.  
  31.    if(argc == 2) strcpy(configfile, argv[1]);
  32.  
  33.    printf("\n\nTOPUSER4      By Erik VanRiper     (1:107/230@fidonet.org)\n\n" \
  34.            "This program is free for non-commercial use.\n");
  35.  
  36.    if((cnf = fopen(configfile,"rb")) == NULL)
  37.    {
  38.       puts("Usage:");
  39.       puts("          TOPUSERS [config_file]");
  40.       puts("Example: ");
  41.       puts("          TOPUSERS");
  42.       puts(" Or: ");
  43.       puts("          TOPUSERS topusers.cfg");
  44.       exit(255);
  45.    }
  46.  
  47.    defaults();
  48.    for(x = 0; x < 99; x++) node[x] = 0;
  49.  
  50.    ParseConfig();
  51.  
  52.    if ((userfile=open(config.userfile,O_RDONLY | O_BINARY))==-1)
  53.    {
  54.       printf("Error opening %s",config.userfile);
  55.       exit(255);
  56.    }
  57.  
  58.    read(userfile,&users[0],sizeof(struct _usr));
  59.  
  60.    s_len=users[0].struct_len ? users[0].struct_len*20 : 180;
  61.  
  62.    length = filelength(userfile);
  63.  
  64.    num_users = length / s_len;
  65.  
  66.    if((out = fopen(config.outfile,"w+b")) == NULL)
  67.    {
  68.       printf("Error opening %s",config.outfile);
  69.       exit(0);
  70.    }
  71.  
  72.    printf("\nTop %d of %d Users on %s\nWriting output to: %s\n",
  73.               config.topnumber,
  74.               num_users,
  75.               config.bbsname,
  76.               config.outfile);
  77.  
  78.    for(x = 0; x < num_users - config.sysop; x++)
  79.    {
  80.       if((ind[x] = malloc(sizeof(IND))) == NULL)
  81.       {
  82.          printf("\nOut of memory!\n");
  83.          exit(255);
  84.       }
  85.    }
  86.  
  87.    for(x = 0; x < (config.topnumber * 3); x++)
  88.    {
  89.       if((info[x] = malloc(sizeof(INFO))) == NULL)
  90.       {
  91.          printf("\nOut of memory!\n");
  92.          exit(255);
  93.       }
  94.    }
  95.  
  96.    printf("Reading . . .");
  97.    z = read_user(num_users);
  98.  
  99.    printf("\rSorting . . .");
  100.    qsort2(ind, z, sizeof(IND *), compare_times);
  101.    for(x = 0; x < config.topnumber; x++)
  102.    {
  103.       info[x]->user_num = ind[x]->index;
  104.       info[x]->upk      = ind[x]->upk;
  105.       info[x]->downk    = ind[x]->downk;
  106.       info[x]->times    = ind[x]->times;
  107.    }
  108.  
  109.    qsort2(ind, z, sizeof(IND *), compare_ups);
  110.    for(x = config.topnumber; x < (config.topnumber * 2); x++)
  111.    {
  112.       info[x]->user_num = ind[x - config.topnumber]->index;
  113.       info[x]->upk      = ind[x - config.topnumber]->upk;
  114.       info[x]->downk    = ind[x - config.topnumber]->downk;
  115.       info[x]->times    = ind[x - config.topnumber]->times;
  116.    }
  117.  
  118.    qsort2(ind, z, sizeof(IND *), compare_downs);
  119.    for(x = (config.topnumber * 2); x < (config.topnumber * 3); x++)
  120.    {
  121.       info[x]->user_num = ind[x - (config.topnumber * 2)]->index;
  122.       info[x]->upk      = ind[x - (config.topnumber * 2)]->upk;
  123.       info[x]->downk    = ind[x - (config.topnumber * 2)]->downk;
  124.       info[x]->times    = ind[x - (config.topnumber * 2)]->times;
  125.    }
  126.  
  127.    printf("\rReading . . .");
  128.    read_user2(config.topnumber);
  129.    close(userfile);
  130.    x = strlen(config.bbsname);
  131.  
  132.    if(config.topnumber < 10)  x += 16;
  133.    else if(config.topnumber < 99)  x += 17;
  134.    else x += 18;
  135.  
  136.    y = (80 - x) / 2;
  137.  
  138.    printf("\rWriting . . .");
  139.    if(!(config.more)) fprintf(out," ");
  140.  
  141.    for(z = 0; z < y; z++) fprintf(out," ");
  142.  
  143.    fprintf(out,"%sTop %d Users for %s\n%s",
  144.                 config.banner,
  145.                 config.topnumber,
  146.                 config.bbsname,
  147.                 config.line);
  148.    
  149.    for(z = 0; z < y; z++) fprintf(out," ");
  150.    for(y = 0;y < x;y++)
  151.    {
  152.       fprintf(out,"%c",config.shoriz ? 196 : 205);
  153.    }
  154.  
  155.    if(config.shoriz)
  156.    {
  157.       if(config.svert) fprintf(out,"\n\n%s┌─┬─┬─┐\n",config.topsides);
  158.       else             fprintf(out,"\n\n%s╓─╥─╥─╖\n",config.topsides);
  159.    }
  160.    else
  161.    {
  162.       if(config.svert) fprintf(out,"\n\n%s╒═╤═╤═╕\n",config.topsides);
  163.       else             fprintf(out,"\n\n%s╔═╦═╦═╗\n",config.topsides);
  164.    }
  165.  
  166.    fprintf(out,"%c%s TOP CALLERS       CALLS %s%c%s TOP UPLOADERS        KB %s%c%s TOP DOWNLOADERS      KB %s%c\n",
  167.                 config.svert ? 179 : 186,
  168.                 config.callheader, config.topsides,
  169.                 config.svert ? 179 : 186,
  170.                 config.upldheader, config.topsides,
  171.                 config.svert ? 179 : 186,
  172.                 config.dnldheader, config.topsides,
  173.                 config.svert ? 179 : 186);
  174.  
  175.    if(config.shoriz)
  176.    {
  177.       if(config.svert) fprintf(out,"├─┼─┼─┤\n");
  178.       else             fprintf(out,"╟─╫─╫─╢\n");
  179.    }
  180.    else
  181.    {
  182.       if(config.svert) fprintf(out,"╞═╪═╪═╡\n");
  183.       else             fprintf(out,"╠═╬═╬═╣\n");
  184.    }
  185.  
  186.  
  187.    printf("\rSorting . . .");
  188.  
  189.    printf("\rWriting . . .");
  190.    for(x = 0; x < config.topnumber; x++)
  191.    {
  192.       top_ten(0,x,x);
  193.       top_ten(1,x + config.topnumber, x);
  194.       top_ten(2,x + (config.topnumber * 2), x);
  195.    }
  196.  
  197.    if((config.totals) || (config.avg) || (config.sys))
  198.    if(config.shoriz)
  199.    {
  200.       if(config.svert) fprintf(out,"%s├─┼─┼─┤\n",config.topsides);
  201.       else             fprintf(out,"%s╟─╫─╫─╢\n",config.topsides);
  202.    }
  203.    else
  204.    {
  205.       if(config.svert) fprintf(out,"%s╞═╪═╪═╡\n",config.topsides);
  206.       else             fprintf(out,"%s╠═╬═╬═╣\n",config.topsides);
  207.    }
  208.  
  209.    if(config.totals)
  210.    fprintf(out,"%c%sTotal User Calls:  %6d%s%c%sTotal Upld KB:  %9ld%s%c%sTotal Dnld KB:  %9ld%s%c\n",
  211.                 config.svert ? 179 : 186,
  212.                 config.totalcalls, calls,
  213.                 config.topsides,
  214.                 config.svert ? 179 : 186,
  215.                 config.totaluplds, (unsigned long) uploads,
  216.                 config.topsides,
  217.                 config.svert ? 179 : 186,
  218.                 config.totaldnlds, (unsigned long) downloads,
  219.                 config.topsides,
  220.                 config.svert ? 179 : 186);
  221.  
  222.    if(config.avg)
  223.    {
  224.       fprintf(out,"%c%sAverage / User:    %6d%s%c%sAverage / User: %9d%s%c%sAverage / User: %9d%s%c\n",
  225.                 config.svert ? 179 : 186,
  226.                 config.avgcalls, calls / (num_users - config.sysop),
  227.                 config.topsides,
  228.                 config.svert ? 179 : 186,
  229.                 config.avguplds, (unsigned int) ((unsigned long) uploads / (num_users - config.sysop)),
  230.                 config.topsides,
  231.                 config.svert ? 179 : 186,
  232.                 config.avgdnlds, (unsigned int) ((unsigned long) downloads / (num_users - config.sysop)),
  233.                 config.topsides,
  234.                 config.svert ? 179 : 186);
  235.  
  236.    }
  237.    if(config.sys)
  238.    {
  239.       uploads = 0L;
  240.       downloads = 0L;
  241.       z = 0;
  242.       for(x = 0; x < 99; x++)
  243.       {
  244.          if(node[x])
  245.          {
  246.             z = 1;
  247.             ProcessStats(x);
  248.          }
  249.       }
  250.       if(!z) ProcessStats(0);
  251.       fprintf(out,"%c%sCalls to System:   %6ld%s%c%sSystem Uploads: %9lu%s%c%sSystem Dnloads: %9lu%s%c\n",
  252.                 config.svert ? 179 : 186,
  253.                 config.syscalls, syscalls,
  254.                 config.topsides,
  255.                 config.svert ? 179 : 186,
  256.                 config.sysuplds, (unsigned long) uploads,
  257.                 config.topsides,
  258.                 config.svert ? 179 : 186,
  259.                 config.sysdnlds, (unsigned long) downloads,
  260.                 config.topsides,
  261.                 config.svert ? 179 : 186);
  262.    }
  263.    else printf("\nSystem stats not processed!\n");
  264.    if(config.shoriz)
  265.    {
  266.       if(config.svert) fprintf(out,"└─┴─┴─┘\n");
  267.       else             fprintf(out,"╙─╨─╨─╜\n");
  268.    }
  269.    else
  270.    {
  271.       if(config.svert) fprintf(out,"╘═╧═╧═╛\n");
  272.       else             fprintf(out,"╚═╩═╩═╝\n");
  273.    }
  274.  
  275.    fprintf(out,"\n%c",config.more ? 32 : 5);
  276.    
  277.    fclose(out);
  278.    for(x = 0; x < num_users - config.sysop; x++)
  279.       free(ind[x]);
  280.    for(x = 0; x < config.topnumber * 3; x++)
  281.       free(info[x]);
  282.    printf("\rDone!        \n");
  283.    return(1);
  284. }
  285.  
  286. top_ten(int e, int x, int y)
  287. {
  288.    if(x == -1) return(-1);
  289.  
  290.    if(e == 0)
  291.    {
  292.       fprintf(out,"%s%c%s",
  293.                    config.topsides,
  294.                    config.svert ? 179 : 186,
  295.                    ((y == 0)                ||
  296.                     (y == config.topnumber) ||
  297.                     (y == config.topnumber * 2)) ?
  298.                     config.topcall : config.rest);
  299.  
  300.       if(info[x]->times == 0)
  301.       fprintf(out,"%s   ----- Vacant! -----   ",config.vacant);
  302.       else
  303.       fprintf(out,"%-19.19s %5d",info[x]->name,info[x]->times);
  304.    }
  305.    if(e == 1)
  306.    {
  307.       fprintf(out,"%s%c%s",
  308.                    config.topsides,
  309.                    config.svert ? 179 : 186,
  310.                    ((y == 0)                ||
  311.                     (y == config.topnumber) ||
  312.                     (y == config.topnumber * 2)) ?
  313.                    config.topupld : config.rest);
  314.  
  315.       if(info[x]->upk == 0)
  316.       fprintf(out,"%s   ----- Vacant! -----   ",config.vacant);
  317.       else
  318.       fprintf(out,"%-18.18s %6lu",info[x]->name,info[x]->upk);
  319.    }
  320.    if(e == 2)
  321.    {
  322.       fprintf(out,"%s%c%s",
  323.                    config.topsides,
  324.                    config.svert ? 179 : 186,
  325.                    ((y == 0)                ||
  326.                     (y == config.topnumber) ||
  327.                     (y == config.topnumber * 2)) ?
  328.                    config.topdnld : config.rest);
  329.  
  330.       if(info[x]->downk == 0)
  331.       fprintf(out,"%s   ----- Vacant! -----   ",config.vacant);
  332.       else
  333.       fprintf(out,"%-18.18s %6lu",info[x]->name,info[x]->downk);
  334.       fprintf(out,"%s%c\n",config.topsides,config.svert ? 179 : 186);
  335.  
  336.       if(y == 0)
  337.       if(config.shoriz)
  338.       {
  339.          if(config.svert) fprintf(out,"├─┼─┼─┤\n");
  340.          else             fprintf(out,"╟─╫─╫─╢\n");
  341.       }
  342.       else
  343.       {
  344.          if(config.svert) fprintf(out,"╞═╪═╪═╡\n");
  345.          else             fprintf(out,"╠═╬═╬═╣\n");
  346.       }
  347.    }
  348.    return(1);
  349. }
  350.  
  351. read_user(int p)
  352. {
  353.    struct _usr users[1];
  354.  
  355.    int x, y = 0;
  356.  
  357.    for (x = (0 + config.sysop);x < p;x++)
  358.    {
  359.       lseek(userfile,(long)x*(long)s_len,SEEK_SET);
  360.       read(userfile,&users[0],sizeof(struct _usr));
  361.       
  362.       uploads   += (unsigned long) users[0].up;
  363.       downloads += (unsigned long) users[0].down;
  364.       calls     += (unsigned long) users[0].times;
  365.  
  366.       if(!(users[0].bits & BITS_NOULIST)) /* If "paranoia" flag not set */
  367.       {
  368.          ind[y]->times    = users[0].times;
  369.          ind[y]->downk    = users[0].down;
  370.          ind[y]->upk      = users[0].up;
  371.          ind[y]->index    = x;
  372.          y++;
  373.       }
  374.    }
  375.    return(y);
  376. }
  377.  
  378. read_user2(int p)
  379. {
  380.    struct _usr users[1];
  381.  
  382.    int x, y;
  383.  
  384.    for (x = 0; x < p; x++)
  385.    {
  386.       lseek(userfile,(long)info[x]->user_num*(long)s_len,SEEK_SET);
  387.       read(userfile,&users[0],sizeof(struct _usr));
  388.       strncpy(info[x]->name,users[0].name,19);
  389.       y = strlen(users[0].name);
  390.       if(y > 19) info[x]->name[20] = '\0';
  391.       else info[x]->name[y] = '\0';
  392.    }
  393.  
  394.    for (x = p; x < (p * 2); x++)
  395.    {
  396.       lseek(userfile,(long)info[x]->user_num*(long)s_len,SEEK_SET);
  397.       read(userfile,&users[0],sizeof(struct _usr));
  398.       strncpy(info[x]->name,users[0].name,19);
  399.       y = strlen(users[0].name);
  400.       if(y > 19) info[x]->name[20] = '\0';
  401.       else info[x]->name[y] = '\0';
  402.    }
  403.  
  404.    for (x = (p * 2); x < (p * 3); x++)
  405.    {
  406.       lseek(userfile,(long)info[x]->user_num*(long)s_len,SEEK_SET);
  407.       read(userfile,&users[0],sizeof(struct _usr));
  408.       strncpy(info[x]->name,users[0].name,19);
  409.       y = strlen(users[0].name);
  410.       if(y > 19) info[x]->name[20] = '\0';
  411.       else info[x]->name[y] = '\0';
  412.    }
  413.    return(1);
  414. }
  415.  
  416. int compare_times(const void *a, const void *b)
  417. {
  418.    IND *ai = *((IND **)a);
  419.    IND *bi = *((IND **)b);
  420.    if(ai->times == bi->times) return(0);
  421.    return((ai->times < bi->times) ? 1 : -1);
  422. }
  423.  
  424. int compare_downs(const void *a, const void *b)
  425. {
  426.    IND *ai = *((IND **)a);
  427.    IND *bi = *((IND **)b);
  428.    if(ai->downk == bi->downk) return(0);
  429.    return((ai->downk < bi->downk) ? 1 : -1);
  430. }
  431.  
  432. int compare_ups(const void *a, const void *b)
  433. {
  434.    IND *ai = *((IND **)a);
  435.    IND *bi = *((IND **)b);
  436.    if(ai->upk == bi->upk) return(0);
  437.    return((ai->upk < bi->upk) ? 1 : -1);
  438. }
  439.  
  440. ParseConfigLine(char *line)
  441. {
  442.    char *delim = " \t\n\r";
  443.    char *s;
  444.    int x, t;
  445.  
  446.    /*
  447.    ** Strip off any comments
  448.    */
  449.  
  450.    if((s = strchr(line, ';')) != NULL)  *s='\0';
  451.  
  452.    /*
  453.    ** Grab a word from the config
  454.    */
  455.   
  456.    s=strtok(line, delim);
  457.   
  458.    if(s==NULL)  return(2);
  459.  
  460.    t = strlen(s);
  461.    if((t == 1) || (t == 2))
  462.    {
  463.       node[atoi(s)] = 1;
  464.       return(1);
  465.    }
  466.  
  467.    for(x = 0; x < (sizeof((char *)parse) / 2); x++)
  468.    {
  469.       if(eqstri(s, parse[x]))
  470.       {
  471.          switch(x)
  472.          {
  473.             case 0:
  474.             s = strtok(NULL,"\r\n");
  475.             if(s==NULL) return(0);
  476.             strcpy(config.bbsname,s);
  477.             break;
  478.  
  479.             case 1:
  480.             s = strtok(NULL,"\r\n");
  481.             if(s==NULL) return(0);
  482.             strcpy(config.userfile,s);
  483.             break;
  484.  
  485.             case 2:
  486.             s = strtok(NULL,"\r\n");
  487.             if(s==NULL) return(0);
  488.             strcpy(config.outfile,s);
  489.             break;
  490.  
  491.             case 3:
  492.             s = strtok(NULL,"\r\n");
  493.             if(s==NULL) return(0);
  494.             config.topnumber = atoi(s);
  495.             if(atoi(s) > 100) config.topnumber = 10;
  496.             if(atoi(s) < 2)   config.topnumber = 10;
  497.             break;
  498.  
  499.             case 4:
  500.             config.sysop = 0;  /* 0 == TRUE! */
  501.             break;
  502.  
  503.             case 5:
  504.             config.dhoriz = 1;
  505.             config.shoriz = 0;
  506.             break;
  507.  
  508.             case 6:
  509.             config.dvert = 1;
  510.             config.svert = 0;
  511.             break;
  512.  
  513.             case 7:
  514.             s = strtok(NULL,"\r\n");
  515.             if(s==NULL) return(0);
  516.             strcpy(config.topsides,s);
  517.             break;                            
  518.                                               
  519.             case 8:                           
  520.             s = strtok(NULL,"\r\n");          
  521.             if(s==NULL) return(0);            
  522.             strcpy(config.callheader,s);         
  523.             break;
  524.  
  525.             case 9:
  526.             s = strtok(NULL,"\r\n");
  527.             if(s==NULL) return(0);
  528.             strcpy(config.upldheader,s);
  529.             break;
  530.  
  531.             case 10:
  532.             s = strtok(NULL,"\r\n");
  533.             if(s==NULL) return(0);
  534.             strcpy(config.dnldheader,s);
  535.             break;
  536.  
  537.             case 11:
  538.             s = strtok(NULL,"\r\n");
  539.             if(s==NULL) return(0);
  540.             strcpy(config.topcall,s);
  541.             break;
  542.  
  543.             case 12:
  544.             s = strtok(NULL,"\r\n");
  545.             if(s==NULL) return(0);
  546.             strcpy(config.topupld,s);
  547.             break;
  548.  
  549.             case 13:
  550.             s = strtok(NULL,"\r\n");
  551.             if(s==NULL) return(0);
  552.             strcpy(config.topdnld,s);
  553.             break;
  554.  
  555.             case 14:
  556.             s = strtok(NULL,"\r\n");          
  557.             if(s==NULL) return(0);            
  558.             strcpy(config.rest,s);                
  559.             break;                            
  560.  
  561.             case 15:
  562.             s = strtok(NULL,"\r\n");
  563.             if(s==NULL) return(0);
  564.             strcpy(config.totalcalls,s);
  565.             break;
  566.  
  567.             case 16:
  568.             s = strtok(NULL,"\r\n");
  569.             if(s==NULL) return(0);
  570.             strcpy(config.totaluplds,s);
  571.             break;
  572.  
  573.             case 17:
  574.             s = strtok(NULL,"\r\n");
  575.             if(s==NULL) return(0);
  576.             strcpy(config.totaldnlds,s);
  577.             break;
  578.  
  579.             case 18:
  580.             config.cls = 1;
  581.             break;
  582.  
  583.             case 19:
  584.             config.more = 0;
  585.             break;
  586.  
  587.             case 20:
  588.             s = strtok(NULL,"\r\n");
  589.             if(s==NULL) return(0);
  590.             strcpy(config.vacant,s);
  591.             break;
  592.  
  593.             case 21:
  594.             s = strtok(NULL,"\r\n");
  595.             if(s==NULL) return(0);
  596.             strcpy(config.banner,s);
  597.             break;
  598.  
  599.             case 22:
  600.             s = strtok(NULL,"\r\n");
  601.             if(s==NULL) return(0);
  602.             strcpy(config.line,s);
  603.             break;
  604.  
  605.             case 23:
  606.             config.avg = 0;
  607.             break;
  608.  
  609.             case 24:
  610.             s = strtok(NULL,"\r\n");
  611.             if(s==NULL) return(0);
  612.             strcpy(config.avgcalls,s);
  613.             break;
  614.  
  615.             case 25:
  616.             s = strtok(NULL,"\r\n");
  617.             if(s==NULL) return(0);
  618.             strcpy(config.avguplds,s);
  619.             break;
  620.  
  621.             case 26:
  622.             s = strtok(NULL,"\r\n");
  623.             if(s==NULL) return(0);
  624.             strcpy(config.avgdnlds,s);
  625.             break;
  626.  
  627.             case 27:
  628.             config.sys = 0;
  629.             break;
  630.  
  631.             case 28:
  632.             s = strtok(NULL,"\r\n");
  633.             if(s==NULL) return(0);
  634.             strcpy(config.syscalls,s);
  635.             break;
  636.  
  637.             case 29:
  638.             s = strtok(NULL,"\r\n");
  639.             if(s==NULL) return(0);
  640.             strcpy(config.sysdnlds,s);
  641.             break;
  642.  
  643.             case 30:
  644.             s = strtok(NULL,"\r\n");
  645.             if(s==NULL) return(0);
  646.             strcpy(config.sysuplds,s);
  647.             break;
  648.  
  649.             case 31:
  650.             s = strtok(NULL,"\r\n");
  651.             if(s==NULL) return(0);
  652.             strcpy(config.maxdir,s);
  653.             if(config.maxdir[(strlen(config.maxdir) - 1)] != 92)
  654.             {
  655.                config.maxdir[strlen(config.maxdir)] = 92;
  656.                config.maxdir[strlen(config.maxdir)] = '\0';
  657.             }
  658.             break;
  659.  
  660.             case 32:
  661.             config.totals = 0;
  662.             break;
  663.  
  664.             default: break;
  665.          }
  666.       }
  667.    }
  668.    if(x > (sizeof((char *)parse) / 2)) return(0);
  669.    return(1);
  670. }
  671.  
  672. int ParseConfig()
  673. {
  674.    static char line[81];
  675.    char temp[81];
  676.    char *delim = " \t\n\r";
  677.    char *s;
  678.    int t = 0, j = 0;
  679.  
  680.    while(fgets(line, 80, cnf))
  681.    {
  682.       j++;
  683.       strcpy(temp,line);
  684.  
  685.       if((s = strchr(temp, ';')) != NULL)  *s='\0';
  686.       s=strtok(temp, delim);
  687.  
  688.       if(s==NULL)  continue;
  689.  
  690.       t = ParseConfigLine(line);
  691.       if(!t)
  692.       {
  693.          printf("\nError in Config file.  You most likely have more than one space between" \
  694.                 "\narguments.  Or, you have an option specified with no argument following." \
  695.                 "\nPlease re-edit line %d in %s.\n",j,configfile);
  696.          fclose(cnf);
  697.          exit(254);
  698.       }
  699.    }
  700.    fclose(cnf);
  701.    return(1);
  702. }
  703.  
  704. /*   From: Ray Gardner  */
  705.  
  706. /* qsort2()  --  Shell sort   Raymond Gardner   public domain   11/91
  707. **
  708. ** A version of qsort that uses Shell's sort algorithm.
  709. */
  710. void qsort2(void *base, unsigned nel, unsigned width,
  711.             int (*comp)(const void *, const void *))
  712. {
  713.    unsigned int wnel, gap, wgap, i, j, k;
  714.    char *a, *b, tmp;
  715.  
  716.    wnel = width * nel;
  717.    for(gap = 0; ++gap < nel;)
  718.        gap *= 3;
  719.    while ( gap /= 3 )
  720.    {
  721.       wgap = width * gap;
  722.       for ( i = wgap; i < wnel; i += width )
  723.       {
  724.          for ( j = i - wgap; ;j -= wgap )
  725.          {
  726.             a = j + (char *)base;
  727.             b = a + wgap;
  728.             if((*comp)(a, b) <= 0)
  729.                break;
  730.             k = width;
  731.             do
  732.             {
  733.                tmp = *a;
  734.                *a++ = *b;
  735.                *b++ = tmp;
  736.             } while ( --k );
  737.             if(j < wgap)
  738.                break;
  739.          }
  740.       }
  741.    }
  742. }
  743.  
  744. ProcessStats(int y)
  745. {
  746.    char file[13];
  747.  
  748.    sprintf(file,"BBSTAT%-2.2d.BBS",y);
  749.    PrintStats(file);
  750.    return(1);
  751. }
  752.  
  753. PrintStats(char *filename)
  754. {
  755.    int file;
  756.    STATS *stats;
  757.  
  758.    char maxpath[80];
  759.  
  760.    sprintf(maxpath,"%s%s",config.maxdir,filename);
  761.  
  762.    if((file=open(maxpath,O_RDONLY | O_BINARY))==-1)
  763.    {
  764.       return(0);
  765.    }
  766.  
  767.    if((stats = malloc(sizeof(STATS))) == NULL)
  768.    {
  769.       exit(255);
  770.    }
  771.    read(file,stats,sizeof(STATS));
  772.  
  773.    syscalls += (dword) stats->num_callers;
  774.    uploads += (dword) stats->total_ul;
  775.    downloads += (dword) stats->total_dl;
  776.  
  777.    close(file);
  778.    free(stats);
  779.    return(1);
  780. }
  781.