home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / FARCL21B.ZIP / FARCL.C < prev    next >
C/C++ Source or Header  |  1993-11-21  |  16KB  |  493 lines

  1. /*    FARCL - Fms ARChive Lister for RBBS         */
  2. /*   Version: 2.10                                */
  3. /*    Author: Bob Hampton                         */
  4. /*  Compiler: Borland C++ 2.0 - Huge memory model */
  5. /*  Copyright (c) 1990-93 by S3-Technologies      */
  6.  
  7. #include <stdlib.h>
  8. #include <dos.h>
  9. #include <string.h>
  10. #include <alloc.h>
  11. #include <dir.h>
  12. #include <io.h>
  13. #include <stdio.h>
  14. #include <conio.h>
  15.  
  16. #define MAXLINE 84
  17. #define MAXDLD 100
  18. #ifndef OFF
  19.   #define OFF 0
  20.   #define ON !OFF
  21. #endif
  22. #define SINGLE 1
  23. #define DOUBLE 2
  24.  
  25. typedef struct
  26. {                    /* current window:                 */
  27.     int left,            /* - left coordinate               */
  28.         top,            /* - top coordinate                */
  29.         right,            /* - right coordinate              */
  30.         bottom,            /* - bottom coordinate             */
  31.         fore,            /* - normal foreground color       */
  32.         back,            /* - normal background color       */
  33.         hifore,            /* - hilight foreground color      */
  34.         hiback,            /* - hilight background color      */
  35.         bstyle,            /* - border style                  */
  36.         bcolor,            /* - border color                  */
  37.         shadow;            /* - flag for 3-D shadow           */
  38. } WININFO;
  39.  
  40.  
  41.  
  42. typedef struct
  43. {
  44.     char fms_filename[MAXDIR];     /*  name of FMS directory file         */
  45.     char ofl_char[2];              /*  character to mark offline files    */
  46.     char new_catcode[4];           /*  new category code for archives     */
  47.     char ofldir[MAXDIR];           /*  name of directory to create dummies */
  48.     char chng_filename[MAXDIR];    /*  file to write changes to           */
  49.     char dl_direc[MAXDLD][MAXDIR]; /*  array of D/L directories to search */
  50. } CONFIG;
  51.  
  52. typedef struct
  53. {
  54.     char filename[13],
  55.          *filepath;
  56.     int infms;
  57. } FLIST;
  58.  
  59. void        read_cnfgfile    (char *cnfg_filename, CONFIG *cnfg_rec, WININFO *win);
  60. int        process_fmsfile  (CONFIG *cnfg_rec, char huge *filelist[], int num_files, int num_ndx, FILE *chng_file);
  61. int        create_filelist  (CONFIG *cnfg_rec, char huge *filelist[], int *num_ndx, WININFO *win);
  62. int           fcompare         (void *elem1, void *elem2);
  63. void          make_wallpaper   (unsigned char c, int back);
  64. void          make_window      (WININFO *win);
  65. void          cursor           (int cmnd);
  66. void          fail             (char *message, char *filename);
  67.  
  68. extern unsigned _stklen = 49152;
  69.  
  70. void main (int argc, char **argv)
  71. {
  72.     CONFIG    cnfg_rec;        /*  config file record                  */
  73.     char    cnfg_filename[MAXDIR],    /*  name of config file for FARCL       */
  74.         huge *filelist[10];    /*  array of buffer pointers            */
  75.     FILE    *chng_file;        /*  pointer to changes file             */
  76.     int    num_files = 0,        /*  number of files in D/L directories  */
  77.         num_ndx = 0;        /*  max. index number for filelist[]    */
  78.  
  79.     WININFO    header = {2, 2, 77, 4, YELLOW, MAGENTA, YELLOW, RED,
  80.               DOUBLE, LIGHTGRAY, ON},
  81.         center = {2, 9, 77, 16, WHITE, CYAN, YELLOW, RED,
  82.               DOUBLE, DARKGRAY, ON};
  83.  
  84.     switch (argc)
  85.     {
  86.         case 1:
  87.             strcpy (cnfg_filename, "FARCL.CFG");     /*  default config    */
  88.             break;
  89.         case 2:
  90.             strcpy (cnfg_filename, *(argv + 1));     /*  get config file   */
  91.             break;                                   /*  from command line */
  92.         default:
  93.             fprintf (stderr, "\nInvalid command line\n");
  94.             fprintf (stderr, "\nUSAGE: FARCL [config file]\n");
  95.             exit(0);
  96.     }
  97.     cursor (OFF);
  98.     make_wallpaper ('.', BLUE);
  99.     make_window (&header);
  100.     cputs ("  FARCL version 2.10                          (c) 1990-93 by Bob Hampton");
  101.     make_window (¢er);
  102.     read_cnfgfile (cnfg_filename, &cnfg_rec, ¢er);        /* read config file            */
  103.     if (strcmp (cnfg_rec.ofl_char, "") == 0)            /* if not specified in config  */
  104.         strcpy (cnfg_rec.ofl_char, "*");            /* use * to mark offline files */
  105.     num_files = create_filelist (&cnfg_rec, filelist, &num_ndx, ¢er);    /*  set pointer to sorted  */
  106.                                     /*  list of filenames from */
  107.                                     /*  D/L directories        */
  108.  
  109.     if ((chng_file = fopen (cnfg_rec.chng_filename, "w")) == NULL)
  110.     {
  111.         fprintf (stderr, "\nUnable to create changes file %s\n", strupr (cnfg_rec.chng_filename));
  112.         exit(0);
  113.     }
  114.     while (process_fmsfile (&cnfg_rec, filelist, num_files, num_ndx, chng_file));
  115.     fclose (chng_file);
  116.     textattr(7);
  117.     window (1, 1, 80, 25);
  118.     clrscr();
  119.     cursor (ON);
  120. }
  121.  
  122.  
  123.  
  124. void read_cnfgfile (char *cnfg_filename, CONFIG *cnfg_rec, WININFO *win)
  125. {
  126.     FILE    *cnfg_file;        /* pointer to config file            */
  127.     int    dl_ptr = 0;        /* pointer to entries in D/L array   */
  128.     char    buffer[MAXLINE];    /* buffer for line reads             */
  129.  
  130.     if ((cnfg_file = fopen (cnfg_filename, "r")) == NULL)
  131.         fail ("Unable to open config file", strupr (cnfg_filename));
  132.     gotoxy (16, 2);
  133.     cputs ("reading config file: ");
  134.     textattr (win->hifore + (win->hiback << 4));
  135.     cprintf ("%s", strupr (cnfg_filename));
  136.     textattr (win->fore + (win->back << 4));
  137.  
  138.     if (fgets (buffer, MAXLINE, cnfg_file) != NULL && *buffer != '\n')
  139.         strcpy (cnfg_rec->fms_filename, strtok (buffer, "\n"));
  140.     else
  141.         strcpy (cnfg_rec->fms_filename, "");
  142.  
  143.     if (fgets (buffer, MAXLINE, cnfg_file) != NULL && *buffer != '\n')
  144.         strcpy (cnfg_rec->ofl_char, strtok (buffer, "\n"));
  145.     else
  146.         strcpy (cnfg_rec->ofl_char, "");
  147.  
  148.     if (fgets (buffer, MAXLINE, cnfg_file) != NULL && *buffer != '\n')
  149.         strcpy (cnfg_rec->new_catcode, strtok (buffer, "\n"));
  150.     else
  151.         strcpy (cnfg_rec->new_catcode, "");
  152.  
  153.  
  154.     if (fgets (buffer, MAXLINE, cnfg_file) != NULL && *buffer != '\n')
  155.         strcpy (cnfg_rec->ofldir, strtok (buffer, "\n"));
  156.     else
  157.         strcpy (cnfg_rec->ofldir, "");
  158.  
  159.  
  160.     if (fgets (buffer, MAXLINE, cnfg_file) != NULL && *buffer != '\n')
  161.         strcpy (cnfg_rec->chng_filename, strtok (buffer, "\n"));
  162.     else
  163.         strcpy (cnfg_rec->chng_filename, "");
  164.  
  165.     while ((fgets (buffer, MAXLINE, cnfg_file)) != NULL  && dl_ptr < MAXDLD)
  166.         strcpy (cnfg_rec->dl_direc[dl_ptr++], strtok (buffer, "\n"));
  167.     if (dl_ptr < MAXDLD)
  168.         strcpy (cnfg_rec->dl_direc[dl_ptr], "END");    /* mark end of array  */
  169.  
  170.     fclose (cnfg_file);
  171.     clrscr();
  172. }
  173.  
  174.  
  175.  
  176. int create_filelist (CONFIG *cnfg_rec, char huge *filelist[], int *num_ndx, WININFO *win)
  177. {
  178.     FILE *tempfile;            /*  pointer to work file               */
  179.     struct ffblk *ffblk;        /*  pointer to file info block         */
  180.     int dl_ptr,            /*  index to D/L array element         */
  181.         disk,            /*  disk number                        */
  182.         done,            /*  flag                               */
  183.         num_files = 0,        /*  total number of files              */
  184.         workfiles,            /*  work counter for # of files        */
  185.         i,j;            /*  work variables                     */
  186.     char filename[15],        /*  holder for filename                */
  187.          orig_path[MAXDIR],        /*  original path                      */
  188.          *temp_name,        /*  name of work file                  */
  189.          file_name[13];        /*  name of file in D/L directory      */
  190.     unsigned long memleft;
  191.  
  192.     ffblk = (struct ffblk *) malloc (sizeof (struct ffblk));
  193.     temp_name = mktemp ("RBARCXXXXXX");
  194.     if ((tempfile = fopen (temp_name, "w+b")) == NULL)     /* create workfile */
  195.         fail ("Unable to create work file", temp_name);
  196.     dl_ptr = 0;
  197.     getcwd (orig_path, MAXDIR);
  198.     gotoxy (16, 2);
  199.     cputs ("Searching directory:");
  200.     textattr (win->hifore + (win->hiback << 4));
  201.     while (strcmp (cnfg_rec->dl_direc[dl_ptr], "END") && dl_ptr < MAXDLD)   /* search all dirs for files */
  202.     {
  203.         gotoxy (38, 2);
  204.         cprintf ("%s", cnfg_rec->dl_direc[dl_ptr]);
  205.         textattr (win->fore + (win->back << 4));
  206.         clreol();
  207.         textattr (win->hifore + (win->hiback << 4));
  208.         disk = toupper (*cnfg_rec->dl_direc[dl_ptr]) - 65;
  209.         setdisk (disk);
  210.         chdir (cnfg_rec->dl_direc[dl_ptr++]);
  211.         done = findfirst ("*.*", ffblk, 0x3F);
  212.         while (!done)
  213.         {
  214.             if (!(ffblk->ff_attrib & FA_DIREC))
  215.             {
  216.                 num_files++;
  217.                 strcpy (filename, ffblk->ff_name);
  218.                 strncat (filename, "       ", 12 - strlen(filename));
  219.                 fwrite (filename, 13, 1, tempfile);
  220.             }
  221.             done = findnext (ffblk);
  222.         }
  223.     }
  224.  
  225. /*      GO BACK TO START OF FILE */
  226.  
  227.     if (fseek (tempfile, 0L, SEEK_SET))
  228.         printf ("error seeking...\n");
  229.     textattr (win->fore + (win->back << 4));
  230.  
  231. /*      CREATE WORK BUFFER(S) IN MEMORY */
  232.  
  233.     workfiles = num_files;
  234.     while (workfiles > 5000)
  235.     {
  236.         clrscr();
  237.         gotoxy (16, 2);
  238.         cputs ("Reading file list.....");
  239.         filelist[*num_ndx] = (char huge *) farmalloc ((unsigned long) 5000 * 13);
  240.         if (filelist[*num_ndx] == NULL)
  241.             fail ("Unable to allocate","filelist");
  242.         fread ((void *) filelist[*num_ndx], 13, 5000, tempfile);
  243.         clrscr();
  244.         gotoxy (16, 2);
  245.         cputs ("Sorting file list.....");
  246.         qsort ((void *) filelist[*num_ndx], 5000, 13, (int (*) (const void *, const void *))fcompare);
  247.         workfiles -= 5000;
  248.         (*num_ndx)++;
  249.     }
  250.  
  251.     clrscr();
  252.     gotoxy (16, 2);
  253.     cputs ("Reading file list.....");
  254.     filelist[*num_ndx] = (char huge *) farmalloc ((unsigned long) workfiles * 13);
  255.     if (filelist[*num_ndx] == NULL)
  256.         fail ("Unable to allocate","filelist");
  257.     fread ((void *) filelist[*num_ndx], 13, workfiles, tempfile);
  258.     clrscr();
  259.     gotoxy (16, 2);
  260.     cputs ("Sorting file list.....");
  261.     qsort ((void *) filelist[*num_ndx], workfiles, 13, (int (*) (const void *, const void *))fcompare);
  262.  
  263.     fclose (tempfile);
  264.     disk = toupper (*orig_path) - 65;
  265.     setdisk (disk);                                     /* change back to original */
  266.     chdir (orig_path);                                  /* drive and directory     */
  267.     unlink (temp_name);                                 /* delete the work file    */
  268.     clrscr();
  269.     return (num_files);
  270. }
  271.  
  272.  
  273. int process_fmsfile (CONFIG *cnfg_rec, char huge *filelist[], int num_files, int num_ndx, FILE *chng_file)
  274. {
  275.     FILE *fms_file,                 /*  pointer to FMS file                */
  276.          *temp_file,                /*  pointer to temp file               */
  277.          *ofl_file;                 /*  pointer to offline file            */
  278.     char fms_line[MAXLINE],         /*  buffer for FMS file text line      */
  279.          *line_buf,                /*  work buffer for FMS line           */
  280.          fname[9],                  /*  file name                          */
  281.          fext[4],                   /*  file ext                           */
  282.          file_name[13],             /*  file to search for                 */
  283.          ofl_name[MAXPATH],         /*  path/name of offline file          */
  284.          buffer[MAXLINE],        /*  buffer for line reads              */
  285.          *work,
  286.          *fmsarg;
  287.     int more = 0,                   /*  set to 1 if chain to another FMS   */
  288.         listndx,            /*  index to filelist[]                */
  289.         workfiles,            /*  number of files in filelist[listndx]  */
  290.         found;            /*  flag for found file                */
  291.     long offset;                    /*  used to back-up and rewrite record */
  292.  
  293.     line_buf = (char *) malloc (MAXLINE);
  294.     if ((fms_file = fopen (cnfg_rec->fms_filename, "r+")) == NULL)
  295.         fail ("Unable to open FMS file", strupr (cnfg_rec->fms_filename));
  296.  
  297.     while ((fgets (buffer, MAXLINE, fms_file)) != NULL)
  298.     {
  299.         strcpy (fms_line, strtok (buffer, "\n"));
  300.         if (*fms_line != ' ' && *fms_line != '\\' &&
  301.             *fms_line != '*')
  302.         {
  303.  
  304.             strcpy (line_buf, fms_line);
  305.             if (*line_buf == '=')
  306.                 line_buf++;
  307.             strcpy (fname, strtok (line_buf, " ."));
  308.             strcpy (fext, strtok (NULL, " ."));
  309.             strcpy (file_name, fname);
  310.             strcat (file_name, ".");
  311.             strcat (file_name, fext);
  312.             strncat (file_name, "       ", 12 - strlen(file_name));
  313.  
  314.             found = listndx = 0;
  315.             workfiles = num_files;
  316.             while (!found && listndx <= num_ndx)
  317.             {
  318.                 if (workfiles > 5000)
  319.                 {
  320.                     if (bsearch (file_name, (const void *) filelist[listndx++], 5000, 13, (int (*) (const void *, const void *)) fcompare))
  321.                         found = 1;
  322.                     workfiles -= 5000;
  323.                 }
  324.                 else if (bsearch (file_name, (const void *) filelist[listndx++], workfiles, 13, (int (*) (const void *, const void *)) fcompare))
  325.                     found = 1;
  326.             }
  327.             if (!found)
  328.             {
  329.                 *(fms_line + 32) = *(cnfg_rec->ofl_char);
  330.                 if (strcmp (cnfg_rec->new_catcode, ""))
  331.                     strcpy ((fms_line + strlen (fms_line) - 3), cnfg_rec->new_catcode);
  332.                 strncpy (line_buf, fms_line, 73);
  333.                 line_buf[73] = '\0';
  334.                 cprintf ("\r\n%s", line_buf);
  335.                 offset = (long) (strlen (fms_line) + 2) * -1;
  336.                 fseek (fms_file, offset, SEEK_CUR);
  337.                 fprintf (fms_file, "%s\n", fms_line);
  338.                 fseek (fms_file, 0L, SEEK_CUR);
  339.                 fprintf (chng_file, "%s was marked offline\n", file_name);
  340.                 if (strcmp (cnfg_rec->ofldir, "") != 0)
  341.                 {
  342.                     strcpy (ofl_name, cnfg_rec->ofldir);
  343.                     strcat (ofl_name, "\\");
  344.                     strcat (ofl_name, file_name);
  345.                     if ((ofl_file = fopen (ofl_name, "w")) == NULL)
  346.                         fail ("Unable to create dummy file", ofl_name);
  347.                     else
  348.                         fclose (ofl_file);
  349.                 }
  350.             }
  351.         }
  352.         else
  353.             if (strcmp (strtok (fms_line, " "), "\\FMS") == 0)
  354.             {
  355.                 while ((fmsarg = strtok (NULL, " ")) != NULL)
  356.                 {
  357.                     if (strncmp (fmsarg, "CH(", 3) == 0)
  358.                     {
  359.                         fmsarg += 3;
  360.                         fmsarg[strlen(fmsarg)-1] = '\0';
  361.                         strcpy (cnfg_rec->fms_filename, fmsarg);
  362.                         more = 1;
  363.                     }
  364.                 }
  365.             }
  366.     }
  367.     fclose (fms_file);
  368.     return (more);
  369. }
  370.  
  371.  
  372.  
  373.  
  374. int fcompare (void *elem1, void *elem2)
  375. {
  376.     return (strcmp (elem1, elem2));
  377. }
  378.  
  379.  
  380.  
  381.  
  382. void make_wallpaper (unsigned char c, int back)
  383. {
  384.     int far *video,
  385.         row,
  386.         col,
  387.         attr,
  388.         i;
  389.     struct text_info tinfo;
  390.  
  391.     gettextinfo (&tinfo);
  392.     if (tinfo.currmode == MONO)
  393.         video = (int far *) 0xB0000000;
  394.     else
  395.         video = (int far *) 0xB8000000;
  396.     attr = LIGHTGRAY + (back << 4);
  397.     textattr (attr);
  398.     clrscr();
  399.     for (row = 0; row < 25; row += 2)
  400.         if (row % 4 == 0)
  401.             for (col = 0; col < 80; col += 10)
  402.                 *(video + (row * 80) + col + 2) = c | (attr << 8);
  403.         else
  404.             for (col = 5; col < 80; col += 10)
  405.                 *(video + (row * 80) + col + 2) = c | (attr << 8);
  406. }
  407.  
  408.  
  409. void make_window (WININFO *win)
  410. {
  411.     int row, col, attr, pos,
  412.         far *video;
  413.     char *savetext;
  414.     struct text_info tinfo;
  415.     struct
  416.     {
  417.         int upleft, upright, dnleft, dnright,
  418.             vert, horiz;
  419.     } border[3] = {{ 32,  32,  32,  32,  32,  32},
  420.                {218, 191, 192, 217, 179, 196},
  421.                {201, 187, 200, 188, 186, 205}};
  422.  
  423.     gettextinfo (&tinfo);
  424.     if (tinfo.currmode == MONO)
  425.         video = (int far *) 0xB0000000;
  426.     else
  427.         video = (int far *) 0xB8000000;
  428.     attr = (win->bcolor + (win->back << 4)) << 8;
  429.     *(video + (win->top - 1) * 80 + win->left - 1) = border[win->bstyle].upleft | attr;
  430.     *(video + (win->top - 1) * 80 + win->right - 1) = border[win->bstyle].upright | attr;
  431.     *(video + (win->bottom - 1) * 80 + win->left - 1) = border[win->bstyle].dnleft | attr;
  432.     *(video + (win->bottom - 1) * 80 + win->right - 1) = border[win->bstyle].dnright | attr;
  433.     for (col = win->left; col < win->right-1; col++)
  434.     {
  435.         *(video + ((win->top-1)*80) + col) = border[win->bstyle].horiz | attr;
  436.         *(video + ((win->bottom-1)*80) + col) = border[win->bstyle].horiz | attr;
  437.     }
  438.     for (row = win->top; row < win->bottom-1; row++)
  439.     {
  440.         *(video + (row * 80) + win->left-1) = border[win->bstyle].vert | attr;
  441.         *(video + (row * 80) + win->right-1) = border[win->bstyle].vert | attr;
  442.     }
  443.     window (win->left+1, win->top+1, win->right-1, win->bottom-1);
  444.     textattr (win->fore + (win->back << 4));
  445.     clrscr();
  446.     if (win->shadow)
  447.     {
  448.         for (row = win->top; row <= win->bottom; row++)
  449.         {
  450.             *(video + (row * 80) + win->right) &= 0x00FF;
  451.             *(video + (row * 80) + win->right) |= (DARKGRAY + (BLACK << 4)) << 8;
  452.             *(video + (row * 80) + win->right + 1) &= 0x00FF;
  453.             *(video + (row * 80) + win->right + 1) |= (DARKGRAY + (BLACK << 4)) << 8;
  454.         }
  455.         for (col = win->left+1; col <= win->right; col++)
  456.         {
  457.             *(video + (win->bottom * 80) + col) &= 0x00FF;
  458.             *(video + (win->bottom * 80) + col) |= (DARKGRAY + (BLACK << 4)) << 8;
  459.         }
  460.     }
  461. }
  462.  
  463.  
  464.  
  465.  
  466. void cursor (int cmnd)
  467. {
  468.     union REGS regs;
  469.     int attribute;
  470.  
  471.     regs.h.ah = 0x01;
  472.     if (cmnd == OFF)
  473.         attribute = 0x01;
  474.     else
  475.         attribute = 0x00;
  476.     regs.h.ch = attribute << 5 | 6;
  477.     regs.h.cl = 7;
  478.     int86 (0x10, ®s, ®s);
  479. }
  480.  
  481.  
  482. void fail (char *message, char *filename)
  483. {
  484.     clrscr();
  485.     gotoxy (16,2);
  486.     cprintf ("%c%s %s ", 0x07, message, filename);
  487.     gotoxy (16,3);
  488.     perror ("");
  489.     textattr (7);
  490.     cursor (ON);
  491.     exit (1);
  492. }
  493.