home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MAXTOP.LZH / MAXTOP.C < prev    next >
Text File  |  1991-01-13  |  26KB  |  707 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *  MaxTop Source Code, Version 1.00                                       *
  4.  *  Copyright 1991 by Douglas J. Hill.   All rights reserved.              *
  5.  *  COMMERCIAL  DISTRIBUTION  AND/OR  USE   PROHIBITED   WITHOUT           *
  6.  *  WRITTEN CONSENT FROM THE AUTHOR.                                       *
  7.  *                                                                         *
  8.  *  MaxTop is a small external utility for Maximus BBS (OS/2 version).     *
  9.  *  After each caller logs off the system, MaxTop will compile a list of   *
  10.  *  the top five uploaders and top five downloaders.                       *
  11.  *                                                                         *
  12.  *  Note:  This program is functional but not particularly elegant.  There *
  13.  *          are many places for improvement which I will get around to     *
  14.  *          at some point.                                                 *
  15.  *                                                                         *
  16.  *  In writing this program I have used the works of several others.  Most *
  17.  *  notably Peter Fitzsimmons for his COMM.DLL routines and Scott Dudley   *
  18.  *  for his source to Maximus BBS (and the legal mumbo jumbo that follows).*
  19.  *                                                                         *
  20.  *  Non-commercial distribution and/or use  is  permitted  under           *
  21.  *  the following terms:                                                   *
  22.  *    1)   You may copy and  distribute  verbatim  copies  of   the        *
  23.  *         MaxTop source, documentation, and executable code as you        *
  24.  *         receive  it,  in  any   medium,   provided    that   you        *
  25.  *         conspicuously and  appropriately publish on each copy  a        *
  26.  *         valid  copyright   notice  "Copyright  1991  by  Douglas        *
  27.  *         J. Hill"; keep intact the  notices  on  all  files  that        *
  28.  *         refer to this Licence Agreement and  to the  absence  of        *
  29.  *         any  warranty;    PROVIDE   UNMODIFIED  COPIES  OF   THE        *
  30.  *         DOCUMENTATION AS PROVIDED WITH  THE  PROGRAM;  and  give        *
  31.  *         any other recipients of the MaxTop program a copyof this        *
  32.  *         Licence Agreement along with the program.                       *
  33.  *         Under     no    circumstances   is    MaxTop   to     be        *
  34.  *         distributed in such a way as to  be construed as  "value        *
  35.  *         added" in a sales transaction,  such as, but not limited        *
  36.  *         to, software bundled with a  modem  or  CD-ROM  software        *
  37.  *         collections, without the prior written  consent  of  the        *
  38.  *         author.                                                         *
  39.  *                                                                         *
  40.  *    2)   Mere aggregation of another unrelated program with this         *
  41.  *         program and documentation (or derivative  works)  on  a         *
  42.  *         volume of a storage or  distribution  medium  does  not         *
  43.  *         bring the other program under the scope of these terms.         *
  44.  *                                                                         *
  45.  *                            NO WARRANTY                                  *
  46.  *                                                                         *
  47.  *                                                                         *
  48.  *    BECAUSE MAXTOP  IS  LICENSED  FREE  OF  CHARGE,  WE  PROVIDE         *
  49.  *    ABSOLUTELY NO WARRANTY.  EXCEPT  WHEN  OTHERWISE  STATED  IN         *
  50.  *    WRITING, DOUGLAS HILL AND/OR OTHER  PARTIES  PROVIDE  MAXTOP         *
  51.  *    "AS IS" WITHOUT  WARRANTY  OF  ANY  KIND,  EITHER  EXPRESSED         *
  52.  *    OR IMPLIED, INCLUDING,  BUT  NOT  LIMITED  TO,  THE  IMPLIED         *
  53.  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  A  PARTICULAR         *
  54.  *    PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND  PERFORMANCE         *
  55.  *    OF   MAXTOP,   AND   THE   ACCURACY   OF   ITS    ASSOCIATED         *
  56.  *    DOCUMENTATION, IS  WITH  YOU.     SHOULD   MAXTOP   OR   ITS         *
  57.  *    ASSOCIATED DOCUMENTATION PROVE  DEFECTIVE,  YOU  ASSUME  THE         *
  58.  *    COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.               *
  59.  *                                                                         *
  60.  *    IN NO EVENT WILL DOUGLAS HILL BE RESPONSIBLE IN ANY WAY  FOR         *
  61.  *    THE  BEHAVIOR  OF   MODIFIED   VERSIONS  OF  MAXTOP.  IN  NO         *
  62.  *    EVENT WILL DOUGLAS HILL  AND/OR  ANY  OTHER  PARTY  WHO  MAY         *
  63.  *    MODIFY   AND   REDISTRIBUTE  MAXTOP  AS PERMITTED ABOVE,  BE         *
  64.  *    LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS,  LOST         *
  65.  *    MONIES,  OR  OTHER  SPECIAL,  INCIDENTAL  OR   CONSEQUENTIAL         *
  66.  *    DAMAGES  ARISING  OUT  OF  THE  USE  OR  INABILITY  TO   USE         *
  67.  *    (INCLUDING BUT NOT LIMITED TO LOSS OF  DATA  OR  DATA  BEING         *
  68.  *    RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES  OR         *
  69.  *    A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS)         *
  70.  *    MAXTOP,  EVEN   IF  DOUGLAS HILL   HAS BEEN ADVISED  OF  THE         *
  71.  *    POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY  ANY  OTHER         *
  72.  *    PARTY.                                                               *
  73.  *                                                                         *
  74.  *  The author can be contacted at any one of the addresses below:         *
  75.  *                                                                         *
  76.  *  Douglas J. Hill        InterNet djhill@rodan.acs.syr.edu               *
  77.  *  Box 4266               BitNet   rtron@SUVM                             *
  78.  *  Rockville, MD 20850    BBS      (301) 718-4690 - 2400, 24 Hours        *
  79.  *                                                                         *
  80.  * ----------------------------------------------------------------------- *
  81.  *                                                                         *
  82.  *  The COMM.DLL and COMM.H are Copyright (C) 1990 A:WARE Inc.             *
  83.  *                                                                         *
  84.  ***************************************************************************/
  85.  
  86. /***************************************************************************
  87.  * Flag    Date       Programmer       Description of change
  88.  *--------------------------------------------------------------------------
  89.  * (none)  01/12/91   Douglas J. Hill  Original code
  90.  ***************************************************************************/
  91.  
  92. #include <io.h>
  93. #include <stdio.h>
  94. #include <fcntl.h>
  95. #include <string.h>
  96. #include <process.h>        /* exit() prototype */
  97. #include <stdlib.h>         /* atoi() prototype */
  98.  
  99. #ifndef APIENTRY            /* if APIENTRY isn't defined, we most likely  */
  100. #include <os2def.h>         /* haven't got the rest of the OS/2 types so  */
  101. typedef SHANDLE HFILE;      /* include them now.                          */
  102. #endif
  103.  
  104. #include "max_u.h"          /* maximus user file record (part of MAX source) */
  105. #include "comm.h"           /* part of COMM package from A:WARE (see above)  */
  106. #include "proto.h"          /* functional prototypes                         */
  107. #include "maxtop.h"         /* constants, macros, etc.                       */
  108. #include "global.c"         /* global variables                              */
  109.  
  110.  
  111. int main(argc, argv, envp)
  112.    int argc;
  113.    char *argv[];
  114.    char *envp[];
  115. {
  116. int   userfile;         /* USER.BBS file pointer                          */
  117. int   record_length;    /* length of each user record in USER.BBS file    */
  118. struct _usr user;       /* structure to hold one user from USER.BBS       */
  119. int   i;
  120. char  out[100],         /* buffers used to display output.                */
  121.       temp[20];
  122.  
  123.  
  124.    /*
  125.     * first print out banner and parse any arguments on the command line
  126.     */
  127.  
  128.    Banner();
  129.    if (ParseArgs(argc,argv))
  130.     {
  131.       sprintf(msg,"\n\nUnknown argument.\n\n");
  132.       Output(msg);
  133.       Terminate(1);
  134.     }
  135.  
  136.    /*
  137.     * if we're not local then we need to get the com port handle and turn the
  138.     * watch dog facility on.
  139.     */
  140.  
  141.    if (!local)
  142.     {
  143.        ComHRegister(hComm, &hCommPort, (USHORT) 0, (USHORT) 0);
  144.        ComWatchDog(hCommPort,TRUE,(USHORT)1);
  145.     }
  146.  
  147.    /*
  148.     * open and read in MAXTOP.CTL.  Parse any tokens contained inside.  If
  149.     * there are any errors we quit the whole app.
  150.     */
  151.  
  152.    if (!ReadCTLFile())
  153.       Terminate(1);
  154.  
  155.    /*
  156.     * add the file names to the paths supplied in the .CTL file.  Note that
  157.     * we don't add any backslashes here so they must be in the .CTL file.
  158.     */
  159.  
  160.    strcat(userBBSpath,"USER.BBS");
  161.    strcat(maxtoppath,"MAXTOP.DAT");
  162.  
  163.    /*
  164.     * read in the data from disk if it exists.  If it doesn't, simply
  165.     * initialize the structures.
  166.     */
  167.  
  168.    ReadTopLists();
  169.  
  170.    /*
  171.     * if we're not in display mode or we don't have any data yet then try and
  172.     * read the USER.BBS file and get some.
  173.     */
  174.  
  175.    if ((!display) || (newfile))
  176.     {
  177.       InitLists();
  178.       /*
  179.        * open the USER.BBS file in READ ONLY mode.  We also use BINARY so that
  180.        * we don't translate CRLFs to LFs
  181.        */
  182.       if ((userfile=open(userBBSpath, O_RDONLY | O_BINARY))==-1)
  183.        {
  184.         sprintf(msg,"Can't find file %s\n",userBBSpath);
  185.         Output(msg);
  186.         Terminate(2);
  187.        }
  188.       /*
  189.        * read in the first record to determine record size.  Note that this
  190.        * causes us not to check the first user's upload/download stats.  This
  191.        * is OK since it's most likely the sysop and who cares what he's done.
  192.        */
  193.       read(userfile,&user,sizeof(struct _usr));
  194.       record_length = user.struct_len ? (user.struct_len * 20) : 180;
  195.       /*
  196.        * read each user from USER.BBS until EOF.  For each user, see if his
  197.        * stats beat any of the users in either the upload or download lists.
  198.        * If so, call the appropriate function to add him in.
  199.        */
  200.       while (!eof(userfile)) {
  201.         read(userfile,&user,sizeof(struct _usr));
  202.         if (debug)
  203.           {
  204.             sprintf(msg,"Read user %s\n",user.name);
  205.             Output(msg);
  206.           }
  207.         if ((i=CheckTopDownloader(&user)))
  208.           AddTopDownloader(&user,i);
  209.         if ((i=CheckTopUploader(&user)))
  210.           AddTopUploader(&user,i);
  211.       }
  212.       /*
  213.        * All done reading.  Close the user file and write the lists out to
  214.        * disk.
  215.        */
  216.       close(userfile);
  217.       WriteTopLists();
  218.     }
  219.    /*
  220.     * if we've been asked to display the data then printf it all out to the
  221.     * console or modem (or both).
  222.     */
  223.    if (display)
  224.     {
  225.       sprintf(msg,"\n%s\n\n",title); Output(msg);
  226.       sprintf(msg,"Downloaders                             Uploaders\n");
  227.       Output(msg);
  228.       sprintf(msg,"-------------------------------------------------\n");
  229.       Output(msg);
  230.       for (i=0; i<MAX_ENTRIES ;i++ ) {
  231.         strcpy(out,TopDownloaders[i].name);
  232.         strncat(out,DOTS,31-strlen(TopDownloaders[i].name));
  233.         sprintf(temp,"%dk",TopDownloaders[i].amount);
  234.         sprintf(msg,"%s%7s  ",out,temp); Output(msg);
  235.         strcpy(out,TopUploaders[i].name);
  236.         strncat(out,DOTS,31-strlen(TopUploaders[i].name));
  237.         sprintf(temp,"%dk",TopUploaders[i].amount);
  238.         sprintf(msg,"%s%7s\n",out,temp); Output(msg);
  239.       }
  240.       strcpy(msg,"\n\n"); Output(msg);
  241.       /*
  242.        * we've now sent all the data but most likely there's some still waiting
  243.        * to be sent (especially at 1200 and 2400 baud) so let's wait until
  244.        * the queue empties before proceeding.
  245.        */
  246.       if (!local)
  247.         ComTxWait(hCommPort,-1L);
  248.     }
  249.    /*
  250.     * now that all the data's been sent, turn off the watch dog and close
  251.     * out com port.
  252.     */
  253.    if (!local)
  254.     {
  255.      ComWatchDog(hCommPort,FALSE,(USHORT)0);
  256.      ComClose(hCommPort);
  257.     }
  258.    return 0;
  259. }
  260.  
  261. /******************************************************************************
  262.  * Function:   ReadTopLists()
  263.  *
  264.  * Purpose:    This function reads the top download/upload data from disk into
  265.  *                global variables.  If the file can't be opened, the function
  266.  *                initializes the sturctures to zeros.
  267.  *
  268.  *****************************************************************************/
  269. void  ReadTopLists(void)
  270. {
  271.    if ((toplistsfile=open(maxtoppath, O_RDONLY | O_BINARY))==-1)
  272.      {
  273.         /*
  274.          *  can't open the top lists so just initialize the structures
  275.          */
  276.         newfile=TRUE;
  277.         InitLists();
  278.      }
  279.    else
  280.      {
  281.          read(toplistsfile,&TopDownloaders,sizeof(TopDownloaders));
  282.          read(toplistsfile,&TopUploaders,sizeof(TopUploaders));
  283.          close(toplistsfile);
  284.      }
  285. }
  286.  
  287. /*****************************************************************************
  288.  * Function:   WriteTopLists()
  289.  *
  290.  * Purpose:    This function opens the MaxTop data file (MAXTOP.DAT) for
  291.  *                writing and places the download/upload lists on disk closing
  292.  *                the file when done.  If the file doesn't exist, this function
  293.  *                will call creat() to create the file.
  294.  *****************************************************************************/
  295. void  WriteTopLists(void)
  296. {
  297.    if ((toplistsfile=open(maxtoppath,O_RDWR | O_BINARY))== -1)
  298.     {
  299.        if ((toplistsfile=creat(maxtoppath,S_IWRITE))==-1)
  300.         {
  301.            sprintf(msg, "Couldn't create %s\n",maxtoppath); Output(msg);
  302.            Terminate(1);
  303.         }
  304.     }
  305.    write(toplistsfile,&TopDownloaders,sizeof(TopDownloaders));
  306.    write(toplistsfile,&TopUploaders,sizeof(TopUploaders));
  307.    close(toplistsfile);
  308. }
  309.  
  310.  
  311. /****************************************************************************
  312.  * Function:   CheckTopDownloader()
  313.  *
  314.  * Purpose:    This function is called by the main routine to see if the
  315.  *                current user belongs on the top download list.  The function
  316.  *                scans all of the existing entries in the list to see if the
  317.  *                current user has downloaded more than any of them.  If so,
  318.  *                this function returns the index which the current user should
  319.  *                occupy.  AddTopDownloader() will take care of inserting the
  320.  *                user into the list.
  321.  *****************************************************************************/
  322. int   CheckTopDownloader(user)
  323. struct _usr *user;
  324. {
  325. int   i;
  326.  
  327.    for (i=0; i<MAX_ENTRIES ; i++ ) {
  328.      if (user->dnld > TopDownloaders[i].amount)
  329.        {
  330.          /*
  331.           * before we add the user to the list, make sure he's not already
  332.           * in the list as the previous entry.
  333.           */
  334.          if ((i!=0) && (strcmp(TopDownloaders[i-1].name,user->name)))
  335.           return i+1;
  336.          else if (i==0)
  337.           return 1;
  338.          else
  339.           return 0;
  340.        }
  341.    }
  342.    return 0;
  343. }
  344.  
  345. /****************************************************************************
  346.  * Function:   CheckTopUploader()
  347.  *
  348.  * Purpose:    This function is called by the main routine to see if the
  349.  *                current user belongs on the top upload list.  The function
  350.  *                scans all of the existing entries in the list to see if the
  351.  *                current user has uploaded more than any of them.  If so,
  352.  *                this function returns the index which the current user should
  353.  *                occupy.  AddTopUploader() will take care of inserting the
  354.  *                user into the list.
  355.  *****************************************************************************/
  356.  
  357. int   CheckTopUploader(user)
  358. struct _usr *user;
  359. {
  360. int   i;
  361.  
  362.    for (i=0; i<MAX_ENTRIES ; i++ ) {
  363.      if (user->upld > TopUploaders[i].amount)
  364.        {
  365.          /*
  366.           * before we add the user to the list, make sure he's not already
  367.           * in the list as the previous entry.
  368.           */
  369.          if ((i!=0) && (strcmp(TopUploaders[i-1].name,user->name)))
  370.           return i+1;
  371.          else if (i==0)
  372.           return 1;
  373.          else
  374.           return 0;
  375.        }
  376.    }
  377.    return 0;
  378. }
  379.  
  380. /****************************************************************************
  381.  * Function:   AddTopDownloader()
  382.  *
  383.  * Purpose:    This function adds the current user into the top download list
  384.  *                at element i.  All elements in the list are shuffled down to
  385.  *                make room for the new user with the last element falling off
  386.  *                the list.
  387.  ****************************************************************************/
  388. void  AddTopDownloader(user,i)
  389. struct _usr *user;
  390. int          i;
  391. {
  392. int   j;
  393.  
  394.    if (i==MAX_ENTRIES)
  395.     {
  396.       strcpy(TopDownloaders[i-1].name,user->name);
  397.       TopDownloaders[i-1].amount = user->dnld;
  398.     }
  399.    else
  400.     {
  401.       for (j=MAX_ENTRIES-2; j>i-2 ; j-- ) {
  402.         TopDownloaders[j+1]=TopDownloaders[j];
  403.       }
  404.       strcpy(TopDownloaders[i-1].name,user->name);
  405.       TopDownloaders[i-1].amount = user->dnld;
  406.     }
  407. }
  408.  
  409. /****************************************************************************
  410.  * Function:   AddTopUploader()
  411.  *
  412.  * Purpose:    This function adds the current user into the top upload list
  413.  *                at element i.  All elements in the list are shuffled up to
  414.  *                make room for the new user with the last element falling off
  415.  *                the list.
  416.  ****************************************************************************/
  417. void  AddTopUploader(user,i)
  418. struct _usr *user;
  419. int          i;
  420. {
  421. int   j;
  422.  
  423.    if (i==MAX_ENTRIES)
  424.     {
  425.       strcpy(TopUploaders[i-1].name,user->name);
  426.       TopUploaders[i-1].amount = user->upld;
  427.     }
  428.    else
  429.     {
  430.       for (j=MAX_ENTRIES-2; j>i-2 ; j-- ) {
  431.         TopUploaders[j+1]=TopUploaders[j];
  432.       }
  433.       strcpy(TopUploaders[i-1].name,user->name);
  434.       TopUploaders[i-1].amount = user->upld;
  435.     }
  436. }
  437.  
  438. /****************************************************************************
  439.  * Function:   ReadCTLFile()
  440.  *
  441.  * Purpose:    This function opens the MaxTop control file (MAXTOP.CTL) and
  442.  *                reads each line looking for tokens.  Any line that starts
  443.  *                with a % is considered a comment and is ignored.
  444.  *                Any other character in postition 1 of a line is considered
  445.  *                to be the start of a token.  The text from this character
  446.  *                to the next space character are sent for parsing.  For
  447.  *                example if a line were:
  448.  *
  449.  *     ThisIsAToken FOO FOO2 BLAH BLAH BLAH BLAH BLAH BLAH BLAH
  450.  *
  451.  *                the word 'ThisIsAToken' would be sent to ParseToken().
  452.  *                The rest of the line would be considered as data for that
  453.  *                token.
  454.  *                Blank lines are also ignored.
  455.  ****************************************************************************/
  456.  
  457. int   ReadCTLFile(void)
  458. {
  459. int   ctlfile;
  460. int   i;
  461. char  ch;
  462. char  token[40];
  463. bit   firstchar=TRUE;
  464.  
  465.    if (debug)
  466.     {
  467.       sprintf(msg,"\nReading control file...\n"); Output(msg);
  468.     }
  469.    if ((ctlfile=open("MAXTOP.CTL",O_RDONLY | O_BINARY))==-1)
  470.     {
  471.        printf("Unable to open MAXTOP.CTL\n");
  472.        return(1);
  473.     }
  474.    else
  475.     {
  476.        while (!eof(ctlfile)) {
  477.          read(ctlfile,&ch,sizeof(ch));
  478.          if ((firstchar) && (ch=='%'))
  479.           {
  480.             /*
  481.              * got a comment character so read until EOL.
  482.              */
  483.             while(ch!='\n')
  484.              read(ctlfile,&ch,sizeof(ch));
  485.           }
  486.          else if ((ch == '\r') || (ch == '\n') || (ch==0x1A))
  487.           {
  488.             /*
  489.              * ignore blank lines (CRLF) and the EOF marker
  490.              */
  491.           }
  492.          else
  493.           {
  494.             /*
  495.              * something else.  Get the first word and parse it.
  496.              */
  497.             firstchar=FALSE;
  498.             while(ch==' ')
  499.              read(ctlfile,&ch,sizeof(ch));
  500.             token[0]=ch;
  501.             i=1;
  502.             while(token[i-1]!=' ')
  503.              {
  504.                read(ctlfile,&token[i],sizeof(token[i]));
  505.                i++;
  506.              }
  507.             token[i-1]='\0';
  508.             ParseToken(token,ctlfile);
  509.             firstchar = TRUE;
  510.           }
  511.        }
  512.     }
  513.  
  514. }
  515.  
  516. /****************************************************************************
  517.  * Function:   ParseToken()
  518.  *
  519.  * Purpose:    This function is a VERY simple token parser.  Basically it's
  520.  *             nothing more than several string compares.  The simplicity is
  521.  *             due to the small number of tokens needed in the MAXTOP.CTL file.
  522.  ****************************************************************************/
  523. void  ParseToken(token,ctlfile)
  524. char *token;
  525. int   ctlfile;
  526. {
  527. char  ch;
  528. int   i=1;
  529.  
  530.    if (!stricmp(token,maxtopPathToken))
  531.     {
  532.       /*
  533.        * found the MaxTopPath token.  Skip the spaces until we come to some
  534.        * more text.  From here 'till the EOL will be considered the path.
  535.        */
  536.       if (debug)
  537.         printf("Parsed token MaxTopPath\n");
  538.       SkipSpaces(ctlfile,ch);
  539.       maxtoppath[0]=ch;
  540.       while(maxtoppath[i-1] != '\n')
  541.         {
  542.           read(ctlfile,&maxtoppath[i],sizeof(maxtoppath[i]));
  543.           i++;
  544.         }
  545.       /*
  546.        * The above loop will cause the CRLF to be inserted into the path
  547.        * variable.  To get rid of this we simply null our the CR character to
  548.        * shorten the string.  Q&D but it works.
  549.        */
  550.       ClipCRLF(maxtoppath,i);
  551.     }
  552.    else if (!stricmp(token,userBBSPathToken))
  553.     {
  554.       /*
  555.        * found the UserBBSPath token.  Skip the spaces until we come to some
  556.        * more text.  From here 'till the EOL will be considered the path.
  557.        */
  558.       if (debug)
  559.         printf("Parsed token UserBBSPath\n");
  560.       SkipSpaces(ctlfile,ch);
  561.       userBBSpath[0]=ch;
  562.       while(userBBSpath[i-1]!='\n')
  563.        {
  564.          read(ctlfile,&userBBSpath[i],sizeof(userBBSpath[i]));
  565.          i++;
  566.        }
  567.       /*
  568.        * The above loop will cause the CRLF to be inserted into the path
  569.        * variable.  To get rid of this we simply null our the CR character to
  570.        * shorten the string.  Q&D but it works.
  571.        */
  572.       ClipCRLF(userBBSpath,i);
  573.     }
  574.    else if (!stricmp(token,titleToken))
  575.     {
  576.       /*
  577.        * Got a 'Title' token.  The rest of the line will be displayed when
  578.        * the download/upload list is displayed.
  579.        */
  580.       if (debug)
  581.         printf("Parsed token Title\n");
  582.       SkipSpaces(ctlfile,ch);
  583.       title[0]=ch;
  584.       while(title[i-1]!='\n')
  585.        {
  586.          read(ctlfile,&title[i],sizeof(title[i]));
  587.          i++;
  588.        }
  589.       ClipCRLF(title,i);
  590.     }
  591.    else
  592.     {
  593.      printf("%s - Illegal token in MAXTOP.CTL",token);
  594.      ReadToEOL(ctlfile,ch);
  595.     }
  596. }
  597.  
  598. void  Banner(void)
  599. {
  600.    sprintf(msg,"\n\nMAXTOP  Top five upload/download users utility, Version %s\n",VERSION);
  601.    Output(msg);
  602.    sprintf(msg,"Copyright (C) 1991 Douglas J. Hill.   All Rights Reserved.\n\n");
  603.    Output(msg);
  604. }
  605.  
  606. /*****************************************************************************
  607.  * Function:   ParseArgs()
  608.  *
  609.  * Purpose:    This function takes the command line input and parses it looking
  610.  *                for command switches.  Available switches are:
  611.  *
  612.  *                -S:   Show download/upload lists.
  613.  *                -K:   Local use.  Do not use COMM.DLL.
  614.  *                -P:   Com port handle.  Used only when on-line.
  615.  *                -D:   Debug mode.  Prints diagnostic messages during run.
  616.  *****************************************************************************/
  617.  
  618. bit  ParseArgs(argc, argv)
  619. int     argc;
  620. char   *argv[];
  621. {
  622. int   i;
  623. char  *p_ch;
  624.  
  625.    for (i=1; i<argc ; i++ ) {
  626.    if (!strnicmp(argv[i],"-S",2))
  627.     {
  628.       display = TRUE;
  629.     }
  630.    else if (!strnicmp(argv[i],"-D",2))
  631.     {
  632.       debug = TRUE;
  633.     }
  634.    else if (!strnicmp(argv[i],"-K",2))
  635.     {
  636.       local = TRUE;
  637.     }
  638.    else if (!strnicmp(argv[i],"-P",2))
  639.     {
  640.       p_ch=argv[i];
  641.       p_ch+=2;
  642.       hComm = (HFILE) atoi(p_ch);
  643.     }
  644.    else
  645.     return 1;
  646.    }
  647.    if ((!local) && (hComm==0))
  648.     {
  649.       local=TRUE;
  650.     }
  651.    return 0;
  652. }
  653.  
  654. /***************************************************************************
  655.  * Function:   Output()
  656.  *
  657.  * Purpose:    This function takes a string and displays it on the local
  658.  *                console and if we are not in local mode it also displays
  659.  *                via the modem.
  660.  **************************************************************************/
  661. void  Output(str)
  662. char  *str;
  663. {
  664.    printf("%s",str);
  665.    if ((!local) && ComIsOnline(hCommPort))
  666.       Mdm_puts(str);
  667. }
  668.  
  669. void  Terminate(rc)
  670. int   rc;
  671. {
  672.    if (!local)
  673.      ComClose(hCommPort);
  674.    exit(rc);
  675. }
  676.  
  677. /*****************************************************************************
  678.  * Function:   Mdm_puts()
  679.  *
  680.  * Purpose:    This function takes a string destined for the modem and adds
  681.  *                carriage return characters after every linefeed character
  682.  *                it sees.
  683.  *****************************************************************************/
  684.  
  685. void pascal Mdm_puts(char *s)
  686. {
  687.   while (*s) {
  688.     ComPutc(hCommPort, *s++);
  689.     if (*s==10)
  690.      {                             /* add carriage return to all linefeeds */
  691.        ComPutc(hCommPort, CR);
  692.      }
  693.   }
  694. }
  695.  
  696. void  InitLists(void)
  697. {
  698. int   x;
  699.  
  700.   for (x=0; x < MAX_ENTRIES ; x++ ) {
  701.     TopDownloaders[x].name[0]='\0';
  702.     TopDownloaders[x].amount=0;
  703.     TopUploaders[x].name[0]='\0';
  704.     TopUploaders[x].amount=0;
  705.   }
  706. }
  707.