home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM Aktief 1995 #6 / CDA_6.iso / shell / utils / disked29.arj / SOURCE.ZIP / DISKLIB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-23  |  18.4 KB  |  740 lines

  1. /***
  2. *disklib.c - disked library
  3. *
  4. *Copyright (c) 1991-1995, Gregg Jennings.  All wrongs reserved.
  5. *   P O Box 200, Falmouth, MA 02541-0200
  6. *
  7. *Purpose:
  8. *   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.7   18-Mar-1995    moved find() into SEARCH.C
  22.    2.6   15-Mar-1995    file tracking stuff
  23.    2.7   05-Mar-1995    rewrote dparams() to show everything
  24.    2.6   10-Sep-1994    fixed %u on num_sectors in dparams()
  25.                          complier checks in dparams()
  26.    2.5   02-Sep-1994    consolodated print vs printf
  27.    2.4   18-Apr-1994    removed text to data.c
  28.    2.3   13-Mar-1994    find() changes
  29.    2.2   01-Feb-1994    'dir_cluster' test bug fix
  30.    2.1   04-Jan-1994    added Translate if !Files for startup
  31.                         added 'dir_cluster'
  32.                         help()
  33. */
  34.  
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. #include <conio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <dos.h>
  41. #include <malloc.h>
  42. #include <errno.h>
  43.  
  44. #include "disked.h"
  45. #include "diskio.h"
  46. #include "mylib.h"
  47. #include "files.h"
  48. #include "keys.h"
  49. #include "error.h"
  50. #include "dpb.h"
  51. #include "dirent.h"
  52. #include "console.h"
  53.  
  54. /* static functions */
  55.  
  56. static void filename(unsigned int);
  57.  
  58.  
  59. /* set to track, sector, head
  60.  
  61.    Passed pointer to string, number of values, and struct of type
  62.    Msg which holds the messages to display for each value and
  63.    the number of digits for each value.
  64.  
  65.    Modification of get() to return immediately on an 'f' or 'b'.
  66.  
  67.    Returns a string containing the values seperated by commas
  68.    to be converted by sscanf().
  69.  
  70.    Globals: Display, Radix.
  71.  
  72. */
  73.  
  74. extern int set(struct Msg *str, int *t, int *s, int *h)
  75. {
  76. register int c,i,n;
  77. long l;
  78. char ts[7];
  79.  
  80.    for (i = n = 0; n < 3; n++, i = 0, str++)
  81.    {
  82.       if (Display)
  83.          print(str->msg);
  84.       while ((c = input()) != '\r' && c != ' ' && c != ',')
  85.       {
  86.          if (n == 0 && i == 0 && (c == 'f' || c == 'b'))
  87.          {
  88.             output(c);                 /* special: Fat, Boot */
  89.             return(c);
  90.          }
  91.          if (c == '\b' && i != 0)      /* backspace, delete number */
  92.          {
  93.             output(c);                 /* in buffer */
  94.             output(' ');               /* and on screen */
  95.             output(c);
  96.             --i;                       /* move pointer back */
  97.          }
  98.          else if (c == 0x1b || c == 3) /* ESC, ^C to abort */
  99.             return 0;                  /* RETURN */
  100.  
  101.          else if (Radix == 16 && !isxdigit(c))
  102.             continue;
  103.          else if (Radix==10 && !isdigit(c))
  104.             continue;
  105.          else
  106.          {
  107.             output(c);
  108.             ts[i++] = (char)c;         /* save and echo numbers */
  109.             if (i == str->len)
  110.                break;
  111.          }
  112.       }
  113.       ts[i] = '\0';
  114.       if (i)
  115.       {
  116.          l = strtol(ts,NULL,Radix);    /* strtol() for radix */
  117.          if (n == 0)
  118.             *t = (int)l;
  119.          else if (n == 1)
  120.             *s = (int)l;
  121.          else
  122.             *h = (int)l;
  123.       }
  124.       if (c == '\r')
  125.          break;
  126.       if (!Display && n < 2)
  127.          output(',');
  128.    }
  129.    return 1;
  130. }
  131.  
  132. /*  get a string for conversion to numbers
  133.  
  134.    Passed pointer to string, number of values, and struct of type
  135.    Msg which holds the messages to display for each value and
  136.    the number of digits for each value.
  137.  
  138.    Returns a string containing the values seperated by commas
  139.    to be converted by sscanf().
  140.  
  141.    Globals: Display, Radix.
  142. */
  143.  
  144. extern int get(struct Msg *str,int *one, int *two)
  145. {
  146. register int t,v;
  147. char temp[7];
  148.  
  149.    for (t = 0; t < 2; t++, str++)
  150.    {
  151.       if (Display)
  152.          print(str->msg);
  153.       if (getstr(temp,str->len,(Radix == 16) ? _HEX : _DIGIT) > 0)
  154.       {
  155.          v = atoi(temp);
  156.          if (t == 0)
  157.             *one = v;
  158.          else
  159.             *two = v;
  160.       }
  161.       else
  162.          return 0;                     /* RETURN */
  163.  
  164.       if (!Display && t < 1)
  165.          output(',');
  166.    }
  167.    return 1;
  168. }
  169.  
  170. /* get - long version */
  171.  
  172. extern int getl(struct Msg *str, long *one, int *two)
  173. {
  174. register int t;
  175. int i;
  176. char temp[7];
  177. long l;
  178.  
  179.    for (t = 0; t < 2; t++, str++)
  180.    {
  181.       if (Display)
  182.          print(str->msg);
  183.       if ((i = getstr(temp,str->len,(Radix == 16) ? _HEX : _DIGIT)) > 0)
  184.       {
  185.          l = strtol(temp,NULL,Radix);
  186.          if (t == 0)
  187.             *one = l;
  188.          else
  189.             *two = (int)l;
  190.       }
  191.       else if (!t && i == -3)
  192.          print("%l",*one);          /* putlong(*one); */
  193.       else
  194.          return 0;
  195.       if (!Display && t < 1)
  196.          output(',');
  197.    }
  198.    return(1);
  199. }
  200.  
  201. /* display sector header */
  202.  
  203. extern void header(void)
  204. {
  205. register unsigned int i,j;
  206.  
  207.    print("\nSector %lu",log_sector);
  208.  
  209.    i = sectortocluster(log_sector);
  210.    j = clustersector(log_sector)+1;
  211.  
  212.    if (log_sector > (dword)data_sector)
  213.    {
  214.       if (Radix == 10)
  215.          print(", Cluster %u:%u",i,j);
  216.       else
  217.          print(", Cluster %x:%x",i,j);
  218.    }
  219.    else
  220.    {  unsigned sector = (word)log_sector;
  221.       if (sector < reserved_secs)
  222.       {
  223.          print("  BOOT");
  224.          if (reserved_secs > 1)
  225.             print(" %d:%d",sector+1,reserved_secs);
  226.       }
  227.       else if (sector >= reserved_secs && sector <= secs_fat)
  228.          print("  FAT 1 %d:%d %d-BIT",
  229.             sector-reserved_secs+1,secs_fat,fat_size);
  230.       else if (num_fats > 1 && sector > secs_fat
  231.          && sector <= (secs_fat*num_fats))
  232.             print("  FAT 2 %d:%d %d-BIT",
  233.                (sector-reserved_secs-secs_fat)+1,secs_fat,fat_size);
  234.       else if (sector >= dir_sector && sector <= data_sector)
  235.          print("  ROOT %d:%d",(sector-dir_sector)+1,dir_sectors);
  236.    }
  237.    if (!Logical)
  238.       print(" (t%u,h%u,s%u)",track,head,sector);
  239.  
  240.    if (diskio_error)
  241.       print(" <BAD>");
  242.    if (Files > 0 && n_files)
  243.       filename(i);
  244. }
  245.  
  246. static void filename(unsigned int i)
  247. {
  248.    if (log_sector > (dword)data_sector && i < num_clusters)
  249.    {
  250.       if (clusters[i] > 0 && (unsigned)clusters[i] <= n_files)
  251.       {
  252.          output(' ');
  253.          print(gfile(clusters[i]));
  254.          if (files[clusters[i]].dir)
  255.             print(" <DIR>");
  256.       }
  257.    }
  258. }
  259.  
  260. /* display disk drive info
  261.  
  262.    Serial No:               Drive Size:              Root Sector:
  263.    Buffer Size:             Sectors:                 Data Sector:
  264.    DOS Version:             Sector Size:             Reserved Sectors:
  265.    Number of Drives:        Clusters:                Hidden Sectors:
  266.    Current Drive:           Cluster Size:            Tracks:
  267.    Media:                   Secs/Cluster:            Heads:
  268.    Volume:                  Number FATs:             Sectors:
  269.    Serial ID:               Secs/FAT:                Sector Size:
  270.    Current Dir:
  271. */
  272.  
  273. extern void dparams(char *drivedir)
  274. {
  275.    print("\n");
  276.  
  277.    print("\n Serial No:%s",Version);
  278.    print("\t  Drive Size: %lu",drive_size);
  279.    print("\t  Root Sector: %u",dir_sector);
  280.  
  281.    print("\n Buffer Size: %u",max_bytes);
  282.    print("\t  Sectors: 0-%lu",num_sectors-1);
  283.    print("\t  Data Sector: %u",data_sector);
  284.  
  285. #if defined(_MSC_VER)
  286.    print("\n DOS Version: %d.%d.%d",_osmajor,_osminor,_osmode);
  287. #elif defined(__WATCOM__)
  288.    print("\n DOS Version: %d.%d.%d",_osmajor,_osminor,_osmode);
  289. #else
  290.    print("\n DOS Version: %d.%d",_osmajor,_osminor);
  291. #endif
  292.    print("\t  Sector Size: %u",sec_size);
  293.    print("\t  Reserved Sectors: %u",reserved_secs);
  294.  
  295.    print("\n Number of Drives: %u",max_drive);
  296.    print("\t  Clusters: 2-%u",num_clusters);
  297.    print("\t  Hidden Sectors: %lu",hidden_secs);
  298.  
  299.    print("\n Current Drive: %c:",disk+'@');
  300.    print("\t  Cluster Size: %u",cluster_size);
  301.    print("\t  Tracks: 0-%u",max_track);
  302.  
  303.    print("\n Media: %s",format);
  304.    print("\t  Sectors/Cluster: %u",secs_cluster);
  305.    print("\t  Heads: 0-%u",max_head-1);
  306.  
  307.    print("\n Volume: %-11.11s", (volume[0]=='\0') ? "?" : volume);
  308.    print("\t  Number FATs: %u",num_fats);
  309.    print("\t  Sectors: 1-%u",max_sector);
  310.  
  311.    print("\n Serial ID:");
  312.    print("\t\t  Sectors/FAT: %u",secs_fat);
  313.    print("\t  Sector Size: %u",sec_size);
  314.  
  315.    print("\n Current Dir: %s",&drivedir[2]);
  316. }
  317.  
  318. /*
  319.    Read the next sector, display, continue.  Checks console for
  320.    speed control and abort.
  321.    pass: direction, forward or backward. value, number of sectors
  322.  
  323.    ver 1.1     9/91  added +1 to kbhit loop to correct '0' bug
  324. */
  325.  
  326. extern void range(int val)
  327. {
  328. register int i;
  329. static int speed=4*50;
  330. int io;
  331. int c='4',b='4';
  332.  
  333.    for (;;)
  334.    {
  335.       if ((io = movesector(val)) != DISK_OK)
  336.       {
  337.          output('\n');
  338.          printerror(Debug);
  339.          if (io == DISK_NREADY)        /* door open! */
  340.             break;
  341.       }
  342.       dumpsector();
  343.       for (i = 0; i < speed; i++)      /* loop in wait */
  344.          if (kbhit())
  345.             c = input();
  346.       if (isdigit(c))                  /* reset speed, the same if c */
  347.       {
  348.          speed = ((c-'0')*50+1);       /*  did not change */
  349.          b = c;
  350.       }
  351.       else if (c == ' ')
  352.       {
  353.          input();
  354.          c = b;
  355.       }
  356.       else
  357.          break;
  358.    }
  359. }
  360.  
  361. /***
  362. *dumpsector() - display sector buffer (front-end)
  363. *
  364. *  2.4 25-Nov-1994   BigScreen reference
  365. *  2.3 01-Apr-1994   no '\n' if !Partial
  366. *  2.2 01-Feb-1994   (dir_cluster && ) addtition
  367. *  2.1 04-Jan-1994   added Translate if !Files for startup
  368. ****/
  369.  
  370. extern void dumpsector(void)
  371. {
  372. int i;
  373. word sector;
  374.  
  375.    i = sectortocluster(log_sector);
  376.    sector = (word)log_sector;
  377.  
  378.    if (Partial)
  379.       output('\n');
  380.    header();
  381.    if (Translate)
  382.    if (  (Files && clusters[i] > 0 && files[clusters[i]].dir)
  383.       || (sector >= dir_sector && sector <= data_sector)
  384.       || (dir_cluster && sectortocluster(log_sector) == dir_cluster)
  385.       )
  386.    {
  387.       dumpdir(sec_buf,sec_size);
  388.       return;
  389.    }
  390.    if (!Ascii)
  391.    {
  392.       if (BigScreen)
  393.          dump(sec_buf,0,sec_size,sec_size,Radix);
  394.       else if (Partial)
  395.          dump(sec_buf,0,sec_size,128,Radix);
  396.       else
  397.          dumpf(sec_buf,sec_size,Radix);
  398.    }
  399.    else
  400.       view(sec_buf,0,sec_size,NOPAUSE,Radix);
  401.    if (Partial || Ascii)
  402.       output('\n');
  403. }
  404.  
  405. /***
  406. *  display databuffer, displaying all non-printable
  407. *  characters enclosed in <>
  408. *
  409. *  Another complicated, horrible looking function.
  410. *
  411. *  0.1   15-Mar-1995    ft_track
  412. ****/
  413.  
  414. view(
  415. register unsigned char *buffer,    /* array of data */
  416. unsigned int bfptr,                /* index into array */
  417. unsigned int bufend,               /* size of array */
  418. int pause,
  419. int base)
  420. {
  421. register int c;
  422. int length;
  423. int p,n,nn,np;
  424.  
  425.    p = n = nn = np = 0;
  426.    output('\n');
  427.    if (pause)
  428.    {
  429.       length = 21;
  430.       if (ft_track)
  431.       {
  432.          long l = filebytes();
  433.          if (base == 10)
  434.             print("%ld:\n",(long)bfptr + l);
  435.          else
  436.             print("%lx:\n",(long)bfptr + l);
  437.       }
  438.       else
  439.       {
  440.          if (base == 10)
  441.             print("%u:\n",bfptr);
  442.          else
  443.             print("%x:\n",bfptr);
  444.       }
  445.    }
  446.    else
  447.    {
  448.       length=sec_size;
  449.       output('\n');
  450.    }
  451.    do
  452.    {
  453.       c = (int)buffer[bfptr++];
  454.       if (bfptr > bufend)
  455.       {
  456.          bfptr = 0;
  457.          break;
  458.       }
  459.       if (p > 75)
  460.       {
  461.          p = 0;
  462.          ++n;
  463.          ++nn;
  464.          ++np;
  465.       }
  466.       if (!isprint(c) && !isspace(c))
  467.       {
  468.          if (Strip)           /* do we strip? */
  469.             continue;
  470.          if (Mask)            /* do we mask ? */
  471.             c&=0x7f;
  472.          else if (Convert)    /* do we convert? */
  473.          {
  474.             print("<%02x>",c);
  475.             p+=4;
  476.             continue;
  477.          }
  478.       }
  479.       if (c==7 || c==255 || c==0 || c==8)
  480.          continue;
  481.       if (c=='\n')
  482.       {
  483.          n++;
  484.          ++nn;
  485.          p=0;
  486.       }
  487.       if (c!='\r')
  488.       {
  489.          output(c);
  490.          p++;
  491.       }
  492.    } while (n<length);
  493.  
  494.    if (pause)
  495.    {
  496.       output('\n');
  497.       pnlz(bfptr,(getlen(bfptr,base)),base);
  498.       output(':');
  499.    }
  500.    return(bfptr);
  501. }
  502.  
  503. /* lame attempt to display BOOT parameters */
  504.  
  505. void dumpboot(byte *buf)
  506. {
  507. struct BOOT b;
  508. int i;
  509.  
  510.    memcpy(&b,buf,sizeof(struct BOOT));
  511.    output('\n');
  512.    switch(b.jump[0])
  513.    {
  514.       case 0xeb:
  515.               print("JMP SHORT ");
  516.               puthex(b.jump[1]);
  517.               break;
  518.       case 0xe9:
  519.               print("JMP ");
  520.               puthex(b.jump[1]);output(':');puthex(b.jump[2]);
  521.               break;
  522.       case 0xff:
  523.       case 0xea:
  524.               print("JMP other ");
  525.               break;
  526.       default:
  527.               print("unknown");
  528.    }
  529.    output('\n');
  530.    print("OEM name:\t\t\t");
  531.    for (i=0;i<8;i++)
  532.            print("%02X",b.name[i]);
  533.    print("\nbytes per sector:                    %04X\n",b.sec_size);
  534.    print("sectors per allocation unit:         %02X\n",b.secs_cluster);
  535.    print("reserved sectors:                    %04X\n",b.reserved_secs);
  536.    print("number of FATs:                      %02X\n",b.num_fats);
  537.    print("number of root dir entries:          %04X\n",b.dir_entries);
  538.    print("number of sectors in logical image:  %04X\n",b.num_sectors);
  539.    print("media descriptor:                    %02X\n",b.media_desc);
  540.    print("number of FAT sectors:               %04X\n",b.secs_fat);
  541.    print("sectors per track:                   %04X\n",b.secs_track);
  542.    print("number of heads:                     %04X\n",b.num_heads);
  543.    print("number of hidden sectors:            %04X\n",b.hidden_sectors);
  544.    print("high order number of hidden sectors: %04X\n",b.large_sectors);
  545.    print("number of logical sectors:           %08X\n",b.total_sectors);
  546.  
  547. }
  548.  
  549. void help(void)
  550. {
  551. int c;
  552.  
  553.    print(" Dir Boot Fat ?");
  554.    c = (int)(char)input();
  555.    if (c == 'd')
  556.       disptext(dir_help);
  557.    else if (c == 'b')
  558.       print(" not yet");
  559.    else if (c == 'f')
  560.       print(" not yet");
  561. }
  562.  
  563. /***
  564. *  Display data in a HEX-ASCII format, starting at buf, ending at
  565. *  bufend.  Returns the number of bytes displayed.  bufend _must_
  566. *  be a multiple of 128
  567. *
  568. *    unsigned char *buffer;  - array of data
  569. *    unsigned int bfptr;     - index into array
  570. *    unsigned int bufend;    - size of array
  571. *    unsigned int len;       - number of bytes to display
  572. *    int base;
  573. *
  574. *  0.2   15-Mar-1995    ft_track
  575. *  0.1   15-Feb-1995    Filter
  576. ****/
  577.  
  578. int dump(unsigned char *buffer, unsigned int bfptr, unsigned int bufend,   \
  579.          unsigned int len, int base)
  580. {
  581. register unsigned int c;
  582. unsigned int l,n;
  583. register int b;
  584.  
  585.    if (bfptr > bufend)
  586.       bfptr = 0;
  587.    if (len > bufend)
  588.       len = bufend;
  589.    n = bfptr;
  590.    for (l = 0; l < len; l+=16)
  591.    {
  592.       if (ft_track)
  593.       {
  594.          long l = filebytes();
  595.          if (base == 10)
  596.             print("\n%08ld: ",(long)bfptr + l);
  597.          else
  598.             print("\n%06lx: ",(long)bfptr + l);
  599.       }
  600.       else
  601.          print((base==10)?"\n%0*d: ":"\n%0*x: ",getlen(bufend,base),bfptr);
  602.  
  603.       for (b = 0; b < 16; b++)
  604.       {
  605.          c = buffer[bfptr];
  606.          output( ((c>>=4) > 9) ? (c+0x57) : (c+'0'));
  607.          c=buffer[bfptr];
  608.          output( ((c&=0xf) > 9) ? (c+0x57) : (c+'0'));
  609.          output(' ');
  610.          if (++bfptr == bufend)
  611.          {
  612.             bfptr = 0;
  613.             break;
  614.          }
  615.       }
  616.       for (b = 0; b < 16; b++)
  617.       {
  618.           c = buffer[n];
  619.           if (Filter)
  620.              output( (c>=' ' && c<=0xfe) ? (c) : ('.'));
  621.           else
  622.           {
  623.              charout( (c != 0 && c != 255) ? (c) : ('.'));
  624.              curright();
  625.           }
  626.           if (++n == bufend)
  627.           {
  628.               n = 0;
  629.               if (l < (len-16))
  630.                  output('\n');
  631.               break;
  632.           }
  633.       }
  634.    }
  635.    return bfptr;
  636. }
  637.  
  638. /***
  639. *dumpf   -  Display sector contents to the screen in HEX/ASCII.
  640. *
  641. *  Notes:   This fills the entire screen width, and for the output()
  642. *           function, a CR/LF is automatically performed.  If Filter
  643. *           is OFF, the charout() function (which uses the BIOS) does
  644. *           not do this.
  645. *
  646. *  0.2   15-Mar-1995    ft_track
  647. *  0.1   15-Feb-1995    Filter
  648. ****/
  649.  
  650. void dumpf(register unsigned char *buffer, int size, int base)
  651. {
  652. register int c;
  653. int i,j;
  654. int ptr;
  655.  
  656.    output('\n');
  657.    for (ptr = i = 0; i < size; i += 24)
  658.    {
  659. #if 0                                        /* for this dump, file tracking */
  660.       if (ft_track)                          /* offset display messes things */
  661.       {                                      /* up */
  662.          long l = filebytes();
  663.          if (base == 10)
  664.             print("%08ld: ",(long)i + l);
  665.          else
  666.             print("%06lx: ",(long)i + l);
  667.       }
  668.       else
  669. #endif
  670.          print((base==10)?"%0*d: ":"%0*x: ",getlen(size,base),i);
  671.  
  672.       for (j = 1; j <= 24; j++)
  673.       {
  674.          c = buffer[ptr];
  675.          output( ((c>>=4) > 9) ? (c+0x57) : (c+'0'));
  676.          c = buffer[ptr];
  677.          output( ((c&=0xf) > 9) ? (c+0x57) : (c+'0'));
  678.          if (++ptr >= size)
  679.          {
  680.             output(' ');
  681.             j = 9;
  682.             break;
  683.          }
  684.          if (j%8 == 0)
  685.             output(' ');
  686.       }
  687.       ptr -= (j-1);
  688.       for (j = 1; j <= 24; j++)
  689.       {
  690.          c = buffer[ptr];
  691.          if (Filter)
  692.             output( (c<' ' || c>0xfe) ? ('.') : (c));
  693.          else
  694.          {
  695.             charout( (c != 0 && c != 255) ? (c) : ('.'));
  696.             if (j < 24)
  697.                curright();
  698.             else
  699.                output('\n');
  700.          }
  701.          if (++ptr >= size)
  702.             break;
  703.       }
  704.    }
  705. }
  706.  
  707. /* command prompt */
  708.  
  709. int prompt(int n, int base)
  710. {
  711. unsigned int key;
  712.  
  713.    output('\n');
  714.    output('(');
  715.    pnlz(n,(base==16)?4:5,base);
  716.    output(')');
  717.    if (byte_cnt==max_bytes)
  718.       charouta(' ',15);
  719.  
  720.    if (ft_track)
  721.       output('t');
  722.  
  723.    if (Files && n_files>1)
  724.       output(15);
  725.    else
  726.       output('*');
  727.    bdos(0x0c,0,0);
  728.    key=scankey();
  729.    if (! ((key&0xff)==0 || key>0x3920 || key<0x011B))
  730.       key&=0xff;
  731.    if (key<' ')
  732.    {
  733.       output('^');
  734.       output(key+'@');
  735.    }
  736.    else if (key<0xff)
  737.       output(key);
  738.    return key;
  739. }
  740.