home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM Aktief 1995 #6 / CDA_6.iso / shell / utils / disked29.arj / SOURCE.ZIP / SETUP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-09  |  22.5 KB  |  816 lines

  1. /***
  2. *setup.c - disked setup
  3. *
  4. *Copyright (c) 1991-1995, Gregg Jennings.  All wrongs reserved.
  5. *   P O Box 200, Falmouth, MA 02541-0200
  6. *
  7. *Purpose:
  8. *   Initialization.
  9. *
  10. *Notice:
  11. *   This progam may be freely used and distributed.  Any distrubution
  12. *   with modifications must retain the above copyright statement and
  13. *   modifications noted.
  14. *   No pulp-publication, in whole or in part, permitted without
  15. *   permission (magazines or books).
  16. *******************************************************************************/
  17.  
  18. /*
  19.    Versions:
  20.  
  21.    2.7   15-Dec-1994    corrected Processor ID equate order
  22.    2.6   09-Nov-1994    general cleaning, comments,
  23.    2.5   04-Sep-1994    consolodated all extern references.
  24.                         removed some code in setup() and startup()
  25.                         and placed into functions.
  26.    2.4   18-Apr-1994    cleaned up extern defs
  27.    2.3   09-Mar-1994    hugefree() file/clusters, bump to revision
  28.    2.2   03-Feb-1994    added startup()
  29.    2.1   04-Jan-1994    added get_volume()
  30.  
  31.  
  32.    Notes:   The startup code (startup()) is just plain confusing.
  33.             It will probably be the last to be cleaned up.
  34.  
  35.    Also:    the logdisk() functions return DISKIO for no errors,
  36.             less than DISKIO for warnings, and greater than DISKIO
  37.             for unrecoverable errors.  I forgot this once and
  38.             totally messed things up!
  39. */
  40.  
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <dos.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46. #include <direct.h>
  47. #ifdef __BORLANDC__
  48. #include <conio.h>
  49. #endif
  50.  
  51. #include "disked.h"
  52. #include "diskio.h"
  53. #include "files.h"
  54. #include "mylib.h"
  55. #include "alloc.h"
  56. #include "error.h"
  57. #include "direct.h"
  58. #include "console.h"
  59.  
  60. /* globals referenced here
  61.  
  62.    All of the DISKED configuration switches (mixed case
  63.    identifiers), all of the "start-up" variables (for
  64.    initial sector position, control switches.
  65.    Some of the DISKIO globals.
  66.  
  67.    error, err_msg[]        ERROR.C
  68.    enum DISKIO_RETURNS     DISKIO.H
  69.    comspec[],promptvar[]   DISKED.C
  70.  
  71.    (probably more)
  72. */
  73.  
  74. /* gloabls defined here */
  75.  
  76. /* version nu. */
  77.  
  78. const char * const Version=" 2.9."
  79.  
  80. #ifdef _QC                                /* Compiler ID */
  81. "MQ."                                     /*  keep track of compiler */
  82. #elif defined(__BORLANDC__)               /*  for BUGZZZZ! */
  83. "BC."
  84. #elif defined(_MSC_VER)
  85. "MC."
  86. #elif defined(__WATCOMC__)
  87. "WC."
  88. #else
  89. "XX."                                     /* put others here and below */
  90. #endif
  91.  
  92. #if defined(M_I386) || defined(__386__)   /* Processor ID */
  93. "I386";                                   /*  note order */
  94. #elif defined(M_I286) || defined(__286__)
  95. "I286";
  96. #elif defined(M_I8086) || defined(M_I86)
  97. "I86";
  98. #else
  99. "x86";
  100. #endif
  101. /* Borland does not have such defines, I edit the EXE */
  102. /* Watcom's WCL does not define these either! */
  103.  
  104. /* error message stuff -- for the INT 24 handler */
  105.  
  106. const char *harderr_list[] = {
  107.    "Disk is write-protected",
  108.    "Unknown unit",
  109.    "Drive not ready",
  110.    "Unknown command",
  111.    "CRC error in data",
  112.    "Bad drive-request structure length",
  113.    "Seek error",
  114.    "Unknown media type",
  115.    "Sector not found",
  116.    "Printer out of paper",
  117.    "Write fault",
  118.    "Read fault",
  119.    "General failure",
  120. };
  121.  
  122.  
  123. /* internal data */
  124.  
  125. /* copyleft stuff */
  126.  
  127. static const char * const Author="Gregg Jennings";
  128. static const char * const Title="DISKED The DISK EDitor";
  129. static const char * const Copyr="(c) 1989-1995, All wrongs reserved";
  130. static const char * const Namep="DISKED";
  131.  
  132. static const char *disked_ini="DISKED.INI";
  133. static const char *disked_sav="DISKED.SAV";
  134. static int min_mem;                    /* for running with an IDE */
  135. static int find_flag;                  /* find string arg */
  136. static char set_file[67];              /* file being set-to/tracked */
  137.  
  138. /* internal functions */
  139.  
  140. static void setupmem(void);
  141. static void set_inifile(char *arv);
  142. static void program_args(char **argv, int drives[], unsigned int *dsk);
  143. static void drive_status(int status);
  144. static int getdriveinfo(int *drives, unsigned int *num);
  145. static void do_find(void);
  146. static void do_set(unsigned int cdisk);
  147. static int do_files(void);
  148. static void quit(int e);
  149.  
  150. #ifdef __WATCOMC__
  151. int _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr);
  152. #else
  153. void _cdecl _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr);
  154. #endif
  155.  
  156. /***
  157. *setup   -  sets up everything
  158. *
  159. *  args: char **argv    passed to option handler
  160. *        int drives[]   gets filled with system drives (boolean)
  161. *        UNIT *dsk      gets set to current drive or to drive set
  162. *                        by command line
  163. *
  164. *  Return:  void
  165. *
  166. *  2.11     23-Mar-1995    returns current drive
  167. *  2.10     25-Nov-1994    BigScreen reference
  168. *  2.9      09-Nov-1994    void return
  169. *  2.8      02-Oct-1994    fixed error of setting current disk if drive arg
  170. *  2.7      08-Apr-1994    put some code in sub-functions
  171. *  2.6      03-Feb-1994    /s, moved stuff here (startup()) from DISKED.C
  172. *  ver 2.5  21-Jan-1994    added +|-t
  173. *  ver 2.4  03-Dec-1993    added /@
  174. *  ver 2.3  20-Nov-1993    order of options parsed
  175. *  ver 2.2  13-Nov-1993    better finding of INI file, newalloc()
  176. *  ver 2.1  19-Apr-1992    Added /?
  177. ****/
  178.  
  179. extern int setup(char **argv, int drives[], unsigned int *dsk)
  180. {
  181. int cdisk;
  182.  
  183.    /* preset all non-init-structure globals */
  184.  
  185.    write_to = FALSE;                /* global booleans */
  186.    files_indexed = FALSE;
  187.    Signon = TRUE;
  188.    Save = Restore = FALSE;
  189.    BigScreen = FALSE;
  190.  
  191.    byte_cnt = 0;                    /* global object counters */
  192.    n_files = 1;
  193.    n_dirs = 1;
  194.  
  195.    find_flag = min_mem = 0;         /* start-up flags */
  196.    set_sector = -1L;
  197.    dir_cluster = 0;
  198.    set_file[0] = '\0';
  199.  
  200.    volume[0] = format[0] =          /* others */
  201.       fatsize[0] = '\0';
  202.    memset(tagged,0,sizeof(tagged));
  203.  
  204.    /* get drive info  --  set current drive and get drive count */
  205.  
  206.    cdisk = *dsk = getdriveinfo(drives,&max_drive);
  207.  
  208.    /* initialize the world */
  209.  
  210.    set_inifile(*argv);
  211.    initialize(inifile);
  212.  
  213.    /* setup video stuff */
  214.  
  215.    initvideo(Output);
  216.  
  217.    _harderr(hhandler);              /* capture INT 24 handler */
  218.  
  219.    program_args(argv,drives,dsk);   /* check command line parameters */
  220.                                     /* set disk to use if an arg */
  221.    return cdisk;
  222. }
  223.  
  224. /***
  225. *program_args  -  Check command line arguments, set global prameters etc.
  226. *
  227. *  Args: same as for setup()
  228. *  Return: void
  229. *
  230. ****/
  231.  
  232. static void program_args(char **argv, int drives[], unsigned int *dsk)
  233. {
  234. int c;
  235. int tempd;
  236.  
  237.    if (*++argv)
  238.    {
  239.       do
  240.       {
  241.          c=tolower(**argv);
  242.          if (c == '-')                 /* turn things off */
  243.          {
  244.             switch (*++*argv)
  245.             {
  246.                case '?': goto Help;
  247.                case 'D': Debug=FALSE; break;
  248.                case 't': Translate=FALSE; break;
  249.                case 's': Save=FALSE;    break;
  250.                case 'r': Restore=FALSE; break;
  251.                case 'f': Files=FALSE;   break;
  252.                case 'h': Home=FALSE;    break;
  253.                default:  break;
  254.             }
  255.          }
  256.          else if (c == '/')            /* do/set things */
  257.          {
  258.             switch (*++*argv)
  259.             {
  260.                case 's':
  261.                   ++*argv;
  262.                   if (**argv == '\0')
  263.                      ++argv;
  264.                   switch(**argv)
  265.                   {
  266.                      case 'B':
  267.                         set_sector = 0;
  268.                         break;
  269.                      case 'F':
  270.                         set_sector = reserved_secs + 1;
  271.                         break;
  272.                      default:
  273.                         if (isdigit(**argv))
  274.                            set_sector = atoi(*argv);
  275.                         if (isalpha(**argv))
  276.                            strcpy(set_file,*argv);
  277.                         break;
  278.                   }
  279.                   break;
  280.                case '@':
  281.                   Signon = 0;
  282.                   break;
  283.                case 'h':               /* help ! */
  284.  
  285.                case '?':
  286. Help:
  287.                   printc(Title);       /* display (centered) logo */
  288.                   printc(Version);
  289.                   printc(Copyr);
  290.                   disptext(com_line_text);
  291.                   exit(0);
  292.                   break;
  293.                case 'm':               /* minimize memory */
  294.                   min_mem = 1;
  295.                   break;
  296.                case 'x':               /* set INI file name */
  297.                   ++*argv;
  298.                   if (**argv)
  299.                      strcpy(inifile,*argv);
  300.                   else if (**(argv+1))
  301.                      strcpy(inifile,*++argv);
  302.                   break;
  303.                case 'r':               /* set Restore/Save file name */
  304.                   ++*argv;
  305.                   if (**argv)
  306.                      strcpy(savfile,*argv);
  307.                   else if (**(argv+1))
  308.                      strcpy(savfile,*++argv);
  309.                   break;
  310.                case 'f':               /* find string arg */
  311.                   ++*argv;
  312.                   if (**argv)          /* be careful of space after 'f' */
  313.                   {
  314.                      find_flag = 1;
  315.                      strcpy(findstr,*argv);
  316.                   }
  317.                   else if (**(argv+1))
  318.                   {
  319.                      find_flag = 1;
  320.                      strcpy(findstr,*++argv);
  321.                   }
  322.                   break;
  323.                case '5':
  324.                   BigScreen = 1;
  325.                   break;
  326.                default:
  327.                   break;
  328.             }
  329.          }
  330.          else if (c == '+')            /* turn things on */
  331.          {
  332.             switch (*++*argv)
  333.             {
  334.                case 'D': Debug=TRUE; break;
  335.                case 't': Translate=TRUE; break;
  336.                case 's': Save=TRUE; break;
  337.                case 'r': Restore=TRUE; break;
  338.                case 'f':
  339.                   if (find_flag == 1)
  340.                      find_flag = 2;          /* index files AFTER find() */
  341.                   Files = TRUE;
  342.                   break;
  343.                case 'h': Home=TRUE; break;
  344.                default: break;
  345.             }
  346.          }
  347.          else if (isalpha(c))                /* disk drive letter */
  348.          {
  349.              tempd=toupper(**argv)-'@';      /* make valid */
  350.              if (drives[tempd])              /* check it */
  351.              {
  352.                  *dsk=tempd;                 /* log it */
  353.                  Restore=FALSE;              /* drive spec higher precedence */
  354.                  /*Save=FALSE;*/             /*  than Restore */
  355.              }
  356.          }
  357.       } while (*++argv);
  358.    }
  359. }
  360.  
  361. /***
  362. *getdriveinfo  -  makes a list of all valid drives, set the number
  363. *                 of drives
  364. * RETURNS current drive
  365. *
  366. * 1.0 02-Sep-1994 moved from setup()
  367. ****/
  368.  
  369. static int getdriveinfo(int *drives, unsigned int *num)
  370. {
  371. unsigned i,tempd,cdisk;
  372.  
  373.    *num = 0;                                 /* initialize */
  374.    _dos_getdrive(&cdisk);                    /* get current drive */
  375.  
  376.    for (i = 0; i < MAX_DRIVE; i++)           /* loop to verify drives */
  377.    {
  378.       _dos_setdrive(i,&tempd);               /* try and set */
  379.       _dos_getdrive(&tempd);                 /* see if it was set */
  380.       if (i == tempd)                        /* if it was set */
  381.       {
  382.          drives[i] = TRUE;                   /*  then the drive is real */
  383.          ++(*num);                           /* increment count */
  384.       }
  385.       else
  386.          drives[i] = FALSE;
  387.    }
  388.    _dos_setdrive(cdisk,&tempd);              /* reset current disk */
  389.  
  390.    return cdisk;
  391. }
  392.  
  393. /***
  394. *set_inifile   -  Form the INI filespecs.
  395. *
  396. *  1.1   29-Nov-1994    prompt variable string now global to work
  397. *                       with MSC 8.0
  398. *
  399. ****/
  400.  
  401. static void set_inifile(char *argv)
  402. {
  403. unsigned i,tempd;
  404. char *tempc;
  405.  
  406.    strcpy(comspec,getenv("COMSPEC"));        /* get where COMMAND.COM is */
  407.    strcpy(promptvar,"PROMPT=");
  408.    strcat(promptvar,getenv("PROMPT"));       /* change prompt for shell */
  409.    strcat(promptvar,"(DE)");
  410.    putenv(promptvar);
  411.  
  412.    tempd = 1;                                /* for INI file test */
  413.  
  414.    if ((tempc = getenv("INIT")) != NULL)
  415.    {
  416.       strcpy(savfile,tempc);                 /* get env dir */
  417.       strcpy(inifile,tempc);
  418.       if (inifile[strlen(inifile)-1]!='\\')
  419.       {
  420.          strcat(savfile,"\\");
  421.          strcat(inifile,"\\");
  422.       }
  423.       strcat(savfile,disked_sav);
  424.       strcat(inifile,disked_ini);
  425.       tempd = !exist(inifile);
  426.    }
  427.    if (tempd)                               /* if INI file not in dir */
  428.    {
  429.       if (exist(disked_ini))
  430.       {
  431.          strcpy(inifile,disked_ini);
  432.          strcpy(savfile,disked_sav);
  433.          return;
  434.       }
  435.       strcpy(savfile,argv);                /* get where DISKED resides */
  436.       strcpy(inifile,argv);
  437.       i=strlen(inifile);
  438.       inifile[--i]='I';
  439.       inifile[--i]='N';
  440.       inifile[--i]='I';
  441.       i=strlen(savfile);
  442.       savfile[--i]='V';
  443.       savfile[--i]='A';
  444.       savfile[--i]='S';
  445.    }
  446. }
  447.  
  448. /***
  449. *startup() -   login drive and do startup stuff like index files,
  450. *              set to particular spot, etc.
  451. *
  452. *  Args: char *curdir      gets set to current directory
  453. *        UNIT cdisk        current disk
  454. *
  455. *  Returns: void
  456. *
  457. *  NOTES:   The disk to use is the global 'disk' which has been
  458. *           previously set (by setup()).
  459. *
  460. *
  461. *  1.1         03-Feb-1994    set_sector
  462. *  ver   1.0   22-Jan-1994
  463. ****/
  464.  
  465. extern void startup(char *ccurdir, unsigned int cdisk)
  466. {
  467. int c,status;
  468.  
  469.    /* get current directory, and save it for exit */
  470.  
  471.    _getcwd(curdir,_MAX_DIR);
  472.    _getcwd(ccurdir,_MAX_DIR);
  473.  
  474.    /* login drive and if error find out what to do */
  475.  
  476.    while ((status = logdisk(disk)) > DISK_OK)
  477.    {
  478.       printerror(Debug);
  479.       if (disk == cdisk)                     /* if disk is current disk */
  480.          exit(2);                            /* just quit */ 
  481.  
  482.       print(" %c: Use current? (or Retry) ",disk+'@');
  483.       if ((c = input()) == 'y' || c == 'Y')  /* use current drive ? */
  484.          disk = cdisk;                       /* yes, try it */
  485.       else if (tolower(c) != 'r')            /* try again ? */
  486.          exit(0);                            /* no, quit */
  487.       output('\n');
  488.    }
  489.  
  490.    /* allocate memory for sector buffers and file buffer */
  491.  
  492.    setupmem();
  493.  
  494.    /*
  495.       First do Special Commands which bypass normal start-up sequence
  496.       only one for now: /f{text}.  Note that the order of /f and +|-f
  497.       on the command line is followed.
  498.    */
  499.  
  500.    if (find_flag)             /* find text via command line */
  501.    {
  502.       do_find();
  503.    }
  504.    /* end of Special Commands */
  505.    else
  506.    {
  507.       if (Signon == TRUE)
  508.          disptext(signon_text);     /* signon text */
  509.  
  510.       if (Files > 0)
  511.          do_files();                /* index files */
  512.  
  513.       else if (Signon == TRUE)      /* use the delay of do_files() */
  514.       {                             /*  for the pause */
  515.          pause();
  516.          output('\n');
  517.       }
  518.  
  519.       if (!Files)                   /* didn't index so get volume label */
  520.           get_volume(volume);
  521.  
  522.       do_set(cdisk);                /* find out what sector to start at */
  523.  
  524.       if (!(Files && !Home && Translate)) /* display disk parameters */
  525.          dparams(curdir);                 /*  if not dir display  */
  526.  
  527.       print("\n\n\t'/' for help");
  528.    }
  529.  
  530.    /* Now display any errors */
  531.  
  532.    if (error.num != -1)                   /* if error */
  533.    {
  534.       output('\n');                       /* place the message */
  535.       printerror(Debug);                  /*  before the dump */
  536.    }
  537.  
  538.    drive_status(status);                  /* display anything weird */
  539.  
  540.    if (Restore)
  541.    {
  542.       if (Display && !Verify)
  543.          print("restoring...");
  544.       if (Verify && getver(" restore",0))
  545.          getinit(savfile,INIT_RESTORE);
  546.       else
  547.          Restore = FALSE;
  548.    }
  549. }
  550.  
  551. /***
  552. *do_find -  Search for text specified on command line.
  553. *           The complexity is due to whether or no to index the
  554. *           files before or after seaching (command line order).
  555. *
  556. ****/
  557.  
  558. static void do_find(void)
  559. {
  560. int i;
  561.  
  562.    rootsector();                 /* set to root */
  563.    if (Display)
  564.    {
  565.       printc(Title);             /* display (centered) logo */
  566.       printc(Copyr);             /*  instead of drive parameters */
  567.    }
  568.    if (Files && find_flag == 1)  /* index files first? */
  569.       i = do_files();
  570.    else
  571.       i = 1;
  572.    if (error.num != -1)          /* was there an error? */
  573.    {
  574.       output('\n');
  575.       printerror(Debug);
  576.       output('\n');
  577.    }
  578.    if (i == 0 && Verify)
  579.       getver(" find",MOV_YN);
  580.  
  581.    print("\nfind %s",findstr);
  582.  
  583.    if ((i = find(1,0,0)) >= 0)   /* find text */
  584.    {
  585.       print("found at ");
  586.       pn(i,Radix);
  587.    }
  588.    if (Files && find_flag == 2)  /* index files now? */
  589.       do_files();
  590. }
  591.  
  592. /***
  593. *do_set -   Set to the proper starting sector.  More complexity
  594. *           due to command line arguments.
  595. *
  596. *  0.1   19-Mar-1995 changed set file for filetrack()
  597. ****/
  598.  
  599. static void do_set(unsigned int cdisk)
  600. {
  601. int i,tempd;
  602. long templ;
  603. char tempstr[67];
  604.  
  605.    if (Restore)                                    /* if Restored */
  606.    {                                               /*  read current sector */
  607.       readsector();
  608.    }
  609.    else if (set_sector != -1L)                     /* set to a sector? */
  610.    {
  611.       setsector(set_sector);
  612.    }
  613.    else if (set_file[0] != '\0')                   /* set to file? */
  614.    {
  615.       if ((tempd = file_start(set_file)) != 0)     /* if found */
  616.       {
  617.          setcluster(tempd);                        /* set to first sector */
  618.          if (Files)
  619.          {
  620.             tempd = clusters[tempd];
  621.             if ((i = filetrack(gfile(tempd),tempd)) != 1)
  622.                print("file track error: %d",i);
  623.          }
  624.       }
  625.       else
  626.          rootsector();                             /* not found */
  627.    }
  628.    else if (Files && !Home)         /* if indexed files and not go home */
  629.    {                                /*  set to current directory */
  630.       strcpy(tempstr,&curdir[2]);
  631.       if ((tempd = findfile(tempstr)) != 0)
  632.          setcluster(tempd);
  633.       else
  634.          rootsector();
  635.    }
  636.    else if (cdisk == disk)         /* else goto current directory */
  637.    {
  638.       set_sector = templ = cwdstart();
  639.       dir_cluster = sectortocluster(templ);
  640.       setsector(templ);
  641.    }
  642.    else
  643.       rootsector();
  644. }
  645.  
  646. /***
  647. *do_files   -  Index the files.
  648. *
  649. ****/
  650.  
  651. static int do_files(void)
  652. {
  653.    if (Display)
  654.       bprint(" indexing...");
  655.    files_indexed = Files = initfiles();
  656.    if (Display)
  657.       clreol();
  658.    return files_indexed;
  659. }
  660.  
  661. /***
  662. *setupmem   -
  663. *
  664. ****/
  665.  
  666. static void setupmem(void)
  667. {
  668. unsigned u;
  669.  
  670.    /*
  671.       Yeah I can make it a long and get a huge pointer for a really
  672.       large buffer, but so far that large of a buffer has not been
  673.       needed.  Next time Im bored...
  674.    */
  675.  
  676.    /* try and get memory */
  677.  
  678.    for (u = (min_mem) ? 8192U : 65024U ; ; u -= 512U)
  679.       if ((data_buf = (unsigned char *)alloc(u,sizeof(char)))!=NULL)
  680.          break;
  681.    if (u < 512U*10U)
  682.       quit(NO_MEM);
  683.    max_bytes = u;
  684.  
  685.    /****** can only alloc sector buffer if sector size is known ******/
  686.  
  687.    if ((sec_buf = alloc(sec_size,sizeof(char))) == NULL)
  688.       quit(NO_MEM);
  689.  
  690.    if ((save_sec = alloc(sec_size,sizeof(char))) != NULL)
  691.       if ((spare_sec = alloc(sec_size,sizeof(char))) == NULL)
  692.          freep(save_sec);
  693. }
  694.  
  695. /***
  696. *newdisk() - consolated disk change stuff
  697. *
  698. *  1.3      23-Mar-1995    tempd != disk test for 0'ing tagged
  699. *  ver 1.2  19-Jan-1994    'removable' test
  700. ****/
  701.  
  702. extern int newdisk(int tempd)
  703. {
  704. int i;
  705. unsigned int temps;
  706.  
  707.    temps = sec_size;             /* save current sector size */
  708.    savesector();                 /* and sector data */
  709.    if ((i = logdisk(tempd)) > DISK_OK)
  710.    {
  711.       restoresector();
  712.       disk_moved = 0;
  713.       return 0;                  /* RETURN */
  714.    }
  715.  
  716.    drive_status(i);
  717.  
  718.    if (temps != sec_size)        /* new sector size */
  719.    {
  720.        sec_buf = newalloc(sec_buf,sec_size*sizeof(char));
  721.        if (sec_buf == NULL)
  722.        {
  723.            print("\nReallocation Failure.\n");
  724.            print("Sorry, but I am too confused to continue...\n");
  725.            exit(3);
  726.        }
  727.        save_sec  = newalloc(save_sec,sec_size*sizeof(char));
  728.        spare_sec = newalloc(spare_sec,sec_size*sizeof(char));
  729.    }
  730.  
  731.    _getcwd(curdir,_MAX_DIR);     /* get current directory */
  732.    n_files = 1;                  /* setup for files */
  733.    n_dirs = 1;
  734.  
  735.    if (Files)                    /* if to index them */
  736.    {
  737.       if (files_indexed)         /* if already */
  738.       {
  739.          hugefreep(clusters);    /* free them first */
  740.          hugefreep(files);
  741.       }
  742.       do_files();
  743.    }
  744.    if (!Files)
  745.       get_volume(volume);
  746.  
  747.    set_sector = -1L;             /* kill original start-sector */
  748.  
  749.    if (Home)
  750.       rootsector();
  751.    else
  752.    {
  753.       if (log_sector >= num_sectors)
  754.          lastsector();
  755.       else
  756.          readsector();
  757.    }
  758.    return 1;
  759. }
  760.  
  761. /***
  762. *  Handler to deal with hard error codes. Since DOS is not reentrant,
  763. *  it is not safe to use DOS calls for doing I/O within the DOS Critical
  764. *  Error Handler (int 24h) used by _harderr. Therefore, screen output and
  765. *  keyboard input must be done through the BIOS.
  766. ****/
  767.  
  768. #if defined (_MSC_VER) && (_MSC_VER > 600)
  769. #pragma warning (disable:4100)
  770. #endif
  771. #ifdef __BORLANDC__
  772. #pragma warn -par
  773. #endif
  774.  
  775. #ifdef __WATCOMC__
  776. int _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr)
  777. #else
  778. void _cdecl _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr)
  779. #endif
  780. {
  781.    if (doserr <= 0x0C)
  782.       error.msg = harderr_list[doserr];
  783.    error.num = doserr;
  784.    error.mod = error.func = "harderr";
  785.    _hardretn(doserr&0xff);
  786. #ifdef __WATCOMC__
  787.    return _HARDERR_IGNORE;
  788. #endif
  789. }
  790.  
  791. #ifdef __BORLANDC__
  792. #pragma warn +par
  793. #endif
  794. #if defined (_MSC_VER) && (_MSC_VER > 600)
  795. #pragma warning (default:4100)
  796. #endif
  797.  
  798.  
  799. /* exit() shell */
  800.  
  801. static void quit(int e)
  802. {
  803.    print(err_msg[e]);
  804.    exit(e);
  805. }
  806.  
  807. /* common index files stuff */
  808.  
  809. static void drive_status(int status)
  810. {
  811.    if (removable && status == USE_DPB)    /* floppy BOOT record bad */
  812.       print("\nInvalid BOOT record. Using DPB.");
  813.    if (!removable && status == USE_BOOT)  /* non-floppy no DPB available */
  814.       print("\nDPB not supported (ramdrive?)");
  815. }
  816.