home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 406_01 / disked25 / source / disklib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-13  |  20.6 KB  |  754 lines

  1. /***
  2. *disklib.c - disk editor
  3. *
  4. *Copyright (c) 1991-1994, Gregg Jennings.  All wrongs reserved.
  5. *   P O Box 200, Falmouth, MA 02541-0200
  6. *
  7. *Purpose:
  8. *   MS(tm)-DOS Disk EDitor main library functions.
  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.1 04-Jan-1994   added Translate if !Files for startup
  22.                      added 'dir_cluster'
  23.                      help()
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include <conio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <dos.h>
  32. #include <malloc.h>
  33. #include <errno.h>
  34.  
  35. #include "disked.h"
  36. #include "diskio.h"
  37. #include "mylib.h"
  38. #include "files.h"
  39. #include "keys.h"
  40. #include "error.h"
  41. #include "dpb.h"
  42. #include "dirent.h"
  43.  
  44. /*********** EXTERNAL DATA ***********/
  45.  
  46. extern unsigned int byte_cnt;      /* buffer byte count: append fileio find */
  47. extern unsigned int max_bytes;     /* maximum buffer size: append fileio dparams */
  48. extern unsigned char *data_buf;    /* data buffer: append fileio find */
  49. extern int diskio_error;
  50. extern unsigned int dir_cluster;
  51.  
  52. /* display keywords */
  53.  
  54. void dkey(register struct Keys *str)
  55. {
  56. register int i;
  57.  
  58.    print("\nON:  ");
  59.    for (i=1;i<str->opt;i++)
  60.       if ((str+i)->opt)
  61.       {
  62.          print((str+i)->s);
  63.          send(' ');
  64.       }
  65.    print("\nOFF: ");
  66.    for (i=1;i<str->opt;i++)
  67.       if (!(str+i)->opt)
  68.       {
  69.          print((str+i)->s);
  70.          send(' ');
  71.       }
  72. }
  73.  
  74. /* display keyword */
  75.  
  76. void psw(char c, register struct Keys *str)
  77. {
  78. register int i;
  79.  
  80.    for (i=1;i<str->opt;i++)
  81.    {
  82.       if ((str+i)->s[0]==c)
  83.       {
  84.         print((str+i)->s);
  85.         print(((str+i)->opt)?":ON ":":OFF ");
  86.         break;
  87.       }
  88.    }
  89. }
  90.  
  91. /* set keyword */
  92.  
  93. void ckey(register char *s, register struct Keys *str)
  94. {
  95. register int i;
  96.  
  97.    do
  98.    {
  99.       for (i=1;i<str->opt;i++)
  100.       {
  101.           if ((str+i)->s[0]==*s)
  102.           {
  103.              (str+i)->opt++;
  104.              if ((str+i)->opt>1)
  105.                 (str+i)->opt-=2;
  106.              break;
  107.          }
  108.       }
  109.    } while (*++s);
  110. }
  111.  
  112. void commands(void)
  113. {
  114. print(" Commands:\n\n");
  115. print("        Drive:                  Movement:                 File Buffer: \n");
  116. print("   'ld' log disk d          'n' next sector           'a' append sector \n");
  117. print("   '^L' re-log drive        'b' back sector           'u' unappend sector \n");
  118. print("   'fs' find string s       'h' next head             'A' append cluster  \n");
  119. print("    BS  displat stats       'N' next cluster          'U' unappend cluster\n");
  120. print("                            'B' back cluster        '^An' append n bytes \n");
  121. print("        Sector Buffer:     '^N' next track          '^Un' unappend n bytes \n");
  122. print("    'c' change from n      '^B' back track           'gn' get n sectors \n");
  123. print("   '^C' change dir     'sn,n,n' set position        '^Gn' get n sectors & move \n");
  124. print("    'k' kill changes       'Sn' set to cluster n     'dn' display from n \n");
  125. print("    '>' store             '^Sn' set to sector n      'vn' view from n \n");
  126. print("    '<' retrieve            'r' range                 'e' empty \n");
  127. print("    'w' write               'H' home                 '^E' empty no ask \n");
  128. print(" SPACE  display top         'E' end                  'ps' put to file s \n");
  129. print("    CR  display rest      F10s  goto file s         '^Ps' put no options\n");
  130. print("   'tn' tag sector        ^END  end of file          'is' insert file s \n");
  131. print("  '1-9' goto tag         ^HOME  start of file       '^Is' insert no options\n");
  132. print("                        ^RIGHT  next file cluster     'I' insert current file\n");
  133. print("    'q' quit             ^LEFT  back file cluster    'Cn' change from n \n");
  134. print("    '?' more help                                    'Fs' find string s  \n");
  135. }
  136.  
  137. void ext_commands(void)
  138. {
  139. print(" Extra Commands:\n\n");
  140. print("    'z' set params          'Z' display params        ',' toggle input radix\n");
  141. print("   '^X' restore state      '^Z' save state            '!' shell to DOS\n");
  142. print("    'x' view ini file       'X' view sav file        '^Q' quit no ask \n");
  143. print("    'm' map file            'M' map free space   'Pn,n,s' put sectors to s\n");
  144. print("    F1  directory           F2  list files            F3  number of files\n");
  145. print("    F4s change directory    F5  re-read sector        F6  append w/strip\n");
  146. print("    F7  append w/convert    F8  append w/mask         F9  append w/options\n");
  147. print("   SF1  display partial    SF2  display full         SF3  display ascii\n");
  148. print("   SF4  display directory  SF6  DOS help         \n");
  149. print("SRIGHT  next free clus.  SLEFT  back free clus.  \n");
  150. }
  151.  
  152. /* set to track, sector, head
  153.  
  154.   Passed pointer to string, number of values, and struct of type
  155.   Msg which holds the messages to display for each value and
  156.   the number of digits for each value.
  157.  
  158.   Modification of get() to return immediately on an 'f' or 'b'.
  159.  
  160.   Uses Display, Radix.
  161.  
  162.   Returns a string containing the values seperated by commas
  163.   to be converted by sscanf().
  164. */
  165.  
  166. int set(struct Msg *str,int *t, int *s, int *h)
  167. {
  168. register int c,i,n;
  169. long l;
  170. char ts[7];
  171.  
  172.    for (i=n=0; n < 3; n++,i=0,str++)
  173.    {
  174.       if (Display)
  175.          print(str->msg);
  176.       while ((c=input())!='\r' && c!=' ' && c!=',')
  177.       {
  178.          if (n==0 && i==0 && (c=='f' || c=='b'))
  179.          {
  180.             conout(c);
  181.             return(c);
  182.          }
  183.          if (c=='\b'&& i!=0)           /* backspace, delete number */
  184.          {
  185.             conout(c);                 /* in buffer */
  186.             conout(' ');               /* and on screen */
  187.             conout(c);
  188.             --i;                       /* move pointer back */
  189.          }
  190.          else if (c==0x1b || c==3)     /* ESC to abort */
  191.             return(0);
  192.          else if (Radix==16 && !isxdigit(c))
  193.             continue;
  194.          else if (Radix==10 && !isdigit(c))
  195.             continue;
  196.          else
  197.          {
  198.             conout(c);
  199.             ts[i++]=(char)c;       /* save and echo numbers */
  200.             if (i==str->len)
  201.                break;
  202.          }
  203.       }
  204.       ts[i]='\0';
  205.       if (i)
  206.       {
  207.          l=strtol(ts,NULL,Radix);
  208.          if (n==0)
  209.             *t=(int)l;
  210.          else if (n==1)
  211.             *s=(int)l;
  212.          else
  213.             *h=(int)l;
  214.       }
  215.       if (c=='\r')
  216.          break;
  217.       if (!Display && n < 2)
  218.          conout(',');
  219.    }
  220.    return(1);
  221. }
  222.  
  223. /*  get a string for conversion to numbers
  224.  
  225.    Passed pointer to string, number of values, and struct of type
  226.    Msg which holds the messages to display for each value and
  227.    the number of digits for each value.
  228.  
  229.    Uses Display, Radix.
  230.  
  231.    Returns a string containing the values seperated by commas
  232.    to be converted by sscanf().
  233.  
  234. */
  235. int get(struct Msg *str,int *one, int *two)
  236. {
  237. register int t,v;
  238. char temp[7];
  239.  
  240.    for (t=0; t < 2; t++,str++)
  241.    {
  242.       if (Display)
  243.          print(str->msg);
  244.       if (getstr(temp,str->len,(Radix==16)?_HEX:_DIGIT) > 0)
  245.       {
  246.          v=atoi(temp);
  247.          if (t==0)
  248.             *one = v;
  249.          else
  250.             *two = v;
  251.       }
  252.       else
  253.          return(0);
  254.       if (!Display && t < 1)
  255.          conout(',');
  256.    }
  257.    return(1);
  258. }
  259.  
  260. /* get - long version */
  261.  
  262. int getl(struct Msg *str,long *one, int *two)
  263. {
  264. register int t;
  265. int i;
  266. char temp[7];
  267. long l;
  268.  
  269.    for (t=0; t < 2; t++,str++)
  270.    {
  271.       if (Display)
  272.          print(str->msg);
  273.       if ((i=getstr(temp,str->len,(Radix==16)?_HEX:_DIGIT)) > 0)
  274.       {
  275.          l=strtol(temp,NULL,Radix);
  276.          if (t==0)
  277.             *one = l;
  278.          else
  279.             *two = (int)l;
  280.       }
  281.       else if (!t && i == -3)
  282.          putlong(*one);
  283.       else
  284.          return(0);
  285.       if (!Display && t < 1)
  286.          conout(',');
  287.    }
  288.    return(1);
  289. }
  290.  
  291. /* displau sector header */
  292.  
  293. void header(void)
  294. {
  295. register unsigned int i,j;
  296.  
  297.    if (Logical==0)
  298.    {
  299.       if (Radix==10)
  300.          printf("\ntrack %u, sector %u(%lu), head %u",track,sector,log_sector,head);
  301.       else
  302.          printf("\ntrack %x, sector %x(%lx), head %x",track,sector,log_sector,head);
  303.    }
  304.    else
  305.    {
  306.       print("\nsector ");
  307.       putlong(log_sector);
  308.    }
  309.    i=sectortocluster(log_sector);
  310.    j=clustersector(log_sector)+1;
  311.  
  312.    if (log_sector>(dword)data_sector)
  313.    {
  314.       if (Radix==10)
  315.          printf(", cluster %u:%u",i,j);
  316.       else
  317.          printf(", cluster %x:%x",i,j);
  318.    }
  319.    else
  320.    {  unsigned sector = (word)log_sector;
  321.       if (sector < reserved_secs)
  322.       {
  323.          print("  BOOT");
  324.          if (reserved_secs>1)
  325.             printf(" %d:%d",sector+1,reserved_secs);
  326.       }
  327.       else if (sector >= reserved_secs && sector <= secs_fat)
  328.          printf("  FAT 1 %d:%d %d-BIT",
  329.             sector-reserved_secs+1,secs_fat,fat_size);
  330.       else if (num_fats > 1 && sector > secs_fat
  331.          && sector <= (secs_fat*num_fats))
  332.             printf("  FAT 2 %d:%d %d-BIT",
  333.                (sector-reserved_secs-secs_fat)+1,secs_fat,fat_size);
  334.       else if (sector >= dir_sector && sector <= data_sector)
  335.          printf("  ROOT %d:%d",(sector-dir_sector)+1,dir_sectors);
  336.    }
  337.    if (diskio_error)
  338.       print(" <BAD>");
  339.    if (Files>0 && n_files && log_sector>(dword)data_sector && i<num_clusters)
  340.    {
  341.       if (clusters[i]>0 && (unsigned)clusters[i]<=n_files)
  342.       {
  343.          send(' ');
  344.          print(gfile(clusters[i]));
  345.          if (files[clusters[i]].dir)
  346.             print(" <DIR>");
  347.       }
  348.    }
  349. }
  350.  
  351. void dparams(char *drivedir)       /* display disk drive info */
  352. {
  353.    print("\n\n\tSerial No:");print(Version);
  354.    print("\t   DOS Version: ");putbyte(_osmajor);conout('.');putbyte(_osminor);
  355.  
  356.    print("\n\tbuffer size: ");putuint(max_bytes);
  357.    print("\t   media: ");print(format);
  358.  
  359.    print("\n\tnumber of drives: ");putuint(max_drive);
  360.    print("\t   volume: ");print( (volume[0]=='\0') ? "?          " : volume);
  361.  
  362.    print("\n\tcurrent drive: ");putch(disk+'@');putch(':');
  363.    print("\t   current dir: ");print(&drivedir[2]);
  364.  
  365.    if (Logical==0)
  366.    {
  367.       print("\n\tdrive size: ");putlong(drive_size);
  368.       print("\t   reserved sectors: ");putuint(reserved_secs);
  369.  
  370.       print("\n\tsector size: ");putuint(sec_size);
  371.       print("\t   sectors/fat: ");putuint(secs_fat);
  372.  
  373.       print("\n\ttracks: 0-");putuint(max_track);
  374.       print("\t\t   number fats: ");putuint(num_fats);
  375.  
  376.       print("\n\tsectors: 1-");putuint(max_sector);
  377.       print("\t\t   root directory: ");putuint(dir_sector);
  378.  
  379.       print("\n\theads: 0-");putuint(max_head-1);
  380.       print("\t\t   data sector: ");putuint(data_sector);
  381.    }
  382.    else
  383.    {
  384.       print("\n\tdrive size: ");putlong(drive_size);
  385.       print("\t   sectors: 0-");putuint(num_sectors-1);
  386.  
  387.       print("\n\tsector size: ");putuint(sec_size);
  388.       print("\t   clusters: 2-");putuint(num_clusters);
  389.  
  390.       print("\n\tcluster size: ");putuint(cluster_size);
  391.       print("\t   sectors/cluster: ");putuint(secs_cluster);
  392.  
  393.       print("\n\tsectors/fat: ");putuint(secs_fat);
  394.       print("\t\t   number fats: ");putuint(num_fats);
  395.  
  396.       print("\n\troot directory: ");putuint(dir_sector);
  397.       print("\t   data sector: ");putuint(data_sector);
  398.    }
  399. }
  400.  
  401. /*************************************************************************
  402.                         Display Functions
  403.  ************************************************************************/
  404.  
  405. /* display databuffer, displaying all non-printable
  406.    characters enclosed in <>
  407.  
  408.    Another complicated, horrible looking function.
  409.  
  410. */
  411.  
  412. view(
  413. register unsigned char *buffer,    /* array of data */
  414. unsigned int bfptr,                /* index into array */
  415. unsigned int bufend,               /* size of array */
  416. int pause,
  417. int base)
  418. {
  419. register int c;
  420. int length;
  421. int p,n,nn,np;
  422.  
  423.    p=n=nn=np=0;
  424.    send('\n');
  425.    if (pause)
  426.    {
  427.       length=21;
  428.       pnlz(bfptr,(getlen(bfptr,base)),base);
  429.       send(':');
  430.       send('\n');
  431.    }
  432.    else
  433.    {
  434.       length=sec_size;
  435.       send('\n');
  436.    }
  437.    do
  438.    {
  439.       c=(int)buffer[bfptr++];
  440.       if (bfptr>bufend)
  441.       {
  442.          bfptr=0;
  443.          break;
  444.       }
  445.       if (p>75)
  446.       {
  447.          p=0;
  448.          ++n;
  449.          ++nn;
  450.          ++np;
  451.       }
  452.       if (!isprint(c) && !isspace(c))
  453.       {
  454.          if (Strip)           /* do we strip? */
  455.             continue;
  456.          if (Mask)            /* do we mask ? */
  457.             c&=0x7f;
  458.          else if (Convert)    /* do we convert? */
  459.          {
  460.             printf("<%02x>",c);
  461.             p+=4;
  462.             continue;
  463.          }
  464.       }
  465.       if (c==7 || c==255 || c==0 || c==8)
  466.          continue;
  467.       if (c=='\n')
  468.       {
  469.          n++;
  470.          ++nn;
  471.          p=0;
  472.       }
  473.       if (c!='\r')
  474.          p+=send(c);
  475.    } while (n<length);
  476.  
  477.    if (pause)
  478.    {
  479.       send('\n');
  480.       pnlz(bfptr,(getlen(bfptr,base)),base);
  481.       conout(':');
  482.    }
  483.    return(bfptr);
  484. }
  485.  
  486. /* lame attempt to display BOOT parameters */
  487.  
  488. void dumpboot(byte *buf)
  489. {
  490. struct BOOT b;
  491. int i;
  492.  
  493.    memcpy(&b,buf,sizeof(struct BOOT));
  494.    send('\n');
  495.    switch(b.jump[0])
  496.    {
  497.       case 0xeb:
  498.               print("JMP SHORT ");
  499.               puthex(b.jump[1]);
  500.               break;
  501.       case 0xe9:
  502.               print("JMP ");
  503.               puthex(b.jump[1]);conout(':');puthex(b.jump[2]);
  504.               break;
  505.       case 0xff:
  506.       case 0xea:
  507.               print("JMP other ");
  508.               break;
  509.       default:
  510.               print("unknown");
  511.    }
  512.    send('\n');
  513.    printf("OEM name:\t\t\t");
  514.    for (i=0;i<8;i++)
  515.            printf("%02X",b.name[i]);
  516.    printf("\nbytes per sector:                    %04X\n",b.sec_size);
  517.    printf("sectors per allocation unit:         %02X\n",b.secs_cluster);
  518.    printf("reserved sectors:                    %04X\n",b.reserved_secs);
  519.    printf("number of FATs:                      %02X\n",b.num_fats);
  520.    printf("number of root dir entries:          %04X\n",b.dir_entries);
  521.    printf("number of sectors in logical image:  %04X\n",b.num_sectors);
  522.    printf("media descriptor:                    %02X\n",b.media_desc);
  523.    printf("number of FAT sectors:               %04X\n",b.secs_fat);
  524.    printf("sectors per track:                   %04X\n",b.secs_track);
  525.    printf("number of heads:                     %04X\n",b.num_heads);
  526.    printf("number of hidden sectors:            %04X\n",b.hidden_sectors);
  527.    printf("high order number of hidden sectors: %04X\n",b.large_sectors);
  528.    printf("number of logical sectors:           %08X\n",b.total_sectors);
  529.  
  530. }
  531.  
  532. /*
  533.    Search for an ascii string ( converted by convert() ) on the disk,
  534.    sector by sector, asking to continue if not found after MAXSECTORS.
  535.  
  536.    findstr holds the "converted" string, tmpfstr holds the original string
  537.  
  538.    ver 2.0 10-93 added case test
  539.  
  540.    returns: ERROR (-1) on error, stopped, or not found
  541.             ABORT (-2) on user cancelled
  542.             or the byte position of the string
  543. */
  544.  
  545. char findstr[SEARCH+1];          /* string to search disk for */
  546. char tmpfstr[SEARCH+1];          /* plus a bunch extra */
  547. unsigned int findlen=0;
  548.  
  549. int find(int val, int get, int kase)
  550. {
  551. int findval;                     /* return value */
  552. unsigned long ntimes;
  553. register int io;
  554. char str[SEARCH+1];              /* 4 times max string length */
  555.  
  556.    findval=-1;
  557.    io=0;
  558.    ntimes=0L;
  559.    str[0]='\0';
  560.    if (get)
  561.    {
  562.       if (getstr(str,SEARCH,_PUNCT)==ABORT)  /* get string */
  563.          return(ABORT);                      /* return on ESC or ^C */
  564.       if (str[0]=='\0' && findlen==0)        /* is no string to search for */
  565.          return(ABORT);                      /* then return ABORT */
  566.       if (str[0])                            /* save the string in tempstr */
  567.       {
  568.          strcpy(findstr,str);                /* to search for the same string */
  569.          strcpy(tmpfstr,str);                /* tmpfstr holds the un-converted */
  570.          findlen=convert(findstr);           /* convert if needed */
  571.       }
  572.       else
  573.          print(tmpfstr);
  574.    }
  575.    else
  576.    {
  577.       strcpy(tmpfstr,findstr);               /* tmpfstr holds the un-converted */
  578.       findlen=convert(findstr);              /* convert if needed */
  579.    }
  580.    conout(' ');
  581.    if (val==0)                               /* search buffer */
  582.    {
  583.       register unsigned int i;
  584.       register int j,k=-1;
  585.       if (byte_cnt<findlen)
  586.          return(ERROR);
  587.       for (i=0,j=0;j>=0 && i<byte_cnt;i+=(j+findlen))
  588.       {
  589.          if (kase)
  590.             j=isearch(&data_buf[i],(unsigned char *)findstr,byte_cnt-i,findlen);
  591.          else
  592.             j=search(&data_buf[i],(unsigned char *)findstr,byte_cnt-i,findlen);
  593.          if (j > 0)
  594.          {
  595.             conout(' ');
  596.             pn(j+i,Radix);
  597.             conout(' ');
  598.             k++;
  599.             if (kbhit())
  600.                return(ABORT);
  601.          }
  602.       }
  603.       return(k);
  604.    }
  605.  
  606.    if (Display)
  607.    {
  608.         /*conout(' ');*/
  609.       conout((val==1)?'+':'-');
  610.    }
  611.    do                                           /* search disk */
  612.    {
  613.       if (Display)
  614.       {
  615.          pln(ntimes,Radix);
  616.          put((int)length(ntimes),8);
  617.       }
  618.       if ((io=movesector(val)) != DISK_OK)
  619.       {
  620.          if (Display)
  621.             conout(8);
  622.          printerror(Debug);
  623.          if (io==DISK_NREADY && !getver("continue",CLR_ARG))
  624.          {
  625.             put(2,8);
  626.             break;
  627.          }
  628.          if (Display)
  629.             conout((val==1)?'+':'-');
  630.       }
  631.       if (++ntimes >= num_sectors)
  632.       {
  633.          if (Display)
  634.             conout(8);
  635.          if (!getver(" not found, continue",CLR_ARG))
  636.             break;
  637.          ntimes=0;
  638.       }
  639.       else if (kbhit())            /* check for abort */
  640.          break;
  641.       if (kase)
  642.          findval=isearch(sec_buf,(unsigned char *)findstr,sec_size,findlen);
  643.       else
  644.          findval=search(sec_buf,(unsigned char *)findstr,sec_size,findlen);
  645.    } while (findval == -1);
  646.  
  647.    if (Display)
  648.    {
  649.       conout(8);
  650.       clreol();
  651.    }
  652.    return(findval);
  653. }
  654.  
  655. /*
  656.    Read the next sector, display, continue.  Checks console for
  657.    speed control and abort.
  658.    pass: direction, forward or backward. value, number of sectors
  659.  
  660.    ver 1.1     9/91  added +1 to kbhit loop to correct '0' bug
  661. */
  662.  
  663. void range(int val)
  664. {
  665. register int i;
  666. static int speed=4*50;
  667. int io;
  668. int c='4',b='4';
  669.  
  670.    for (;;)
  671.    {
  672.       if ((io=movesector(val)) != DISK_OK)
  673.       {
  674.          send('\n');
  675.          printerror(Debug);
  676.          if (io==DISK_NREADY)     /* door open! */
  677.             break;
  678.       }
  679.       dumpsector();
  680.       for (i=0;i<speed;i++)      /* loop in wait */
  681.          if (kbhit())
  682.             c=getch();
  683.       if (isdigit(c))            /* reset speed, the same if c */
  684.       {
  685.          speed=((c-'0')*50+1);   /*  did not change */
  686.          b=c;
  687.       }
  688.       else if (c==' ')
  689.       {
  690.          cconin();
  691.          c=b;
  692.       }
  693.       else
  694.          break;
  695.    }
  696. }
  697.  
  698. /***
  699. *dumpsector() - display sector buffer (front-end)
  700. *
  701. *  2.1 04-Jan-1994   added Translate if !Files for startup
  702. ****/
  703.  
  704. void dumpsector()
  705. {
  706. int i=sectortocluster(log_sector);
  707. word sector = (word)log_sector;
  708.  
  709.    send('\n');
  710.    header();
  711.    if (Translate)
  712.    if (  (Files && clusters[i]>0 && files[clusters[i]].dir)
  713.       || (sector >= dir_sector && sector <= data_sector)
  714.       || sectortocluster(log_sector) == dir_cluster
  715.       )
  716.    {
  717.       dumpdir(sec_buf,sec_size);
  718.       return;
  719.    }
  720.    if (!Ascii)
  721.    {
  722.       if (Partial)
  723.          dump(sec_buf,0,sec_size,128,Radix);
  724.       else
  725.          dumpf(sec_buf,sec_size,Radix);
  726.    }
  727.    else
  728.       view(sec_buf,0,sec_size,NOPAUSE,Radix);
  729.    if (Partial || Ascii)
  730.       send('\n');
  731. }
  732.  
  733. void help(void)
  734. {
  735. int c;
  736.  
  737.    print(" Dir Boot Fat ?");
  738.    c = (int)(char)conin();
  739.    if (c == 'd')
  740.    {
  741.       print("\n\n\tDirectory Entry:\n");
  742.       print("\t00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
  743.       print("\t|     filename         |  ext   |at| reserved |\n");
  744.       print("\t10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F\n");
  745.       print("\t|    reserved    |time |date |start|file size |\n\n");
  746.       print("\tnote: DRDOS uses the reserved area for deleted \n");
  747.       print("\t      file first char and password info. \n");
  748.    }
  749.    else if (c == 'b')
  750.       print(" not yet");
  751.    else if (c == 'f')
  752.       print(" not yet");
  753. }
  754.