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

  1. /***
  2. *disked.c - DISKED The DISK EDitor for MS(tm)-DOS.
  3. *
  4. *Copyright (c) 1991-1995, Gregg Jennings.  All wrongs reserved.
  5. *   P O Box 200, Falmouth, MA 02541-0200
  6. *
  7. *Purpose:
  8. *   Command module.
  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   25-Dec-1994    'y': view .SAV file (some command letter changes)
  22.    2.6   04-Sep-1994    ^T, find() changes, extern reference consolodation
  23.    2.5   18-Apr-1994    cleaning up of extern defs
  24.                         input/output function pointers
  25.    2.4   23-Jan-1994    moved all startup code to SETUP.C
  26.    2.3   19-Jan-1994    'removable' test
  27.    2.2   16-Jan-1994    '^Q', replaced 'moved' with 'disk_moved'
  28.    2.1   04-Jan-1994    Translate if !Files for startup, Borland
  29.    2.0   28-Nov-1993
  30.  
  31.    Release Notes:
  32.  
  33.    Programming Notes:
  34. */
  35.  
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <stdlib.h>        /* _MAX_DIR */
  39. #include <conio.h>         /* kbhit() */
  40. #include <ctype.h>         /* isalpha() */
  41. #include <dos.h>           /* _dos_set_drive() */
  42. #include <io.h>            /* for exist() */
  43. #include <direct.h>        /* getcwd(),chdir() */
  44. #include <process.h>       /* spawnl() */
  45.  
  46. #include "disked.h"
  47. #include "mylib.h"
  48. #include "diskio.h"
  49. #include "keys.h"
  50. #include "alloc.h"
  51. #include "files.h"
  52. #include "error.h"
  53. #include "dirent.h"
  54. #include "direct.h"
  55. #include "console.h"
  56. #include "arrays.h"
  57.  
  58.  
  59. /* for find() */
  60.  
  61. enum FIND_ARGUMENTS { F_BUFFER, F_DISK, F_CASE = 0, F_NOCASE };
  62.  
  63. struct Msg ps[]={          /* for inputing a two argument commnd */
  64.    {" from ",6},
  65.    {" number ",3},
  66. };
  67.  
  68. struct Msg ap[]={          /* for inputing a two argument commnd */
  69.    {" from ",3},
  70.    {" number ",3}
  71. };
  72.  
  73. struct Msg st[]={          /* three argument command 's' */
  74.    {" track ",3},
  75.    {" sector ",2},
  76.    {" head ",1}
  77. };
  78.  
  79. /* shared with SETUP.C only */
  80.  
  81. char comspec[FILENAME_MAX];      /* location of COMMAND.COM */
  82. char promptvar[40];              /* DOS prompt variable */
  83. char inifile[FILENAME_MAX];      /* INI file path/name */
  84. char savfile[FILENAME_MAX];      /* Save file path/name */
  85. char curdir[_MAX_DIR];           /* current working directory */
  86. long set_sector;                 /* startup sector number */
  87. int Save,Restore;
  88. int files_indexed;
  89.  
  90. /* shared with SETUP.C and INIT.C */
  91.  
  92. int write_to;                    /* double protection on write */
  93. unsigned long tagged[10];
  94.  
  95. /* shared with SETUP.C and DISKLIB.C */
  96.  
  97. int BigScreen;                   /* 50 line display */
  98. unsigned int dir_cluster;        /* start up directory cluster nu. */
  99.  
  100. /* shared with many */
  101.  
  102. unsigned int byte_cnt;           /* buffer byte count */
  103. unsigned int max_bytes;          /* maximum buffer size */
  104. unsigned char *save_sec;         /* duplicate sector buffer */
  105. unsigned char *spare_sec;        /* spare sector buffer */
  106. unsigned char *data_buf;         /* pointer to area for data buffer */
  107.  
  108.  
  109. #ifdef __BORLANDC__
  110. #pragma argsused
  111. #endif
  112.  
  113. #ifdef _MSC_VER
  114. #pragma warning(disable:4035; disable:4100)
  115. #endif
  116.  
  117.  
  118.  
  119. int main(int argc,char **argv)
  120. {
  121. unsigned int c;
  122. char tmpstr[MAXSTR+1];
  123. char ccurdir[_MAX_DIR];
  124. unsigned int cdisk;
  125. register unsigned int u;        /* vars for loops */
  126. register int i;
  127. unsigned int temps,tempt,temph,tempu;
  128. long templ;
  129. int tempd;
  130. unsigned int bufptr;            /* pointer to file buffer */
  131. int drives[MAX_DRIVE+1];        /* valid drive number array  1-MAX_DRIVE */
  132. int noput;
  133. char *bufferfull=" buffer full ";
  134.  
  135.    tmpstr[0] = '\0';
  136.    bufptr = 0;
  137.    noput = TRUE;
  138.  
  139. #ifdef __WATCOMC__
  140.    setvbuf(stdout,NULL,_IONBF,0);      /* flush stdout every printf */
  141. #endif
  142.  
  143. #ifndef NDEBUG
  144.    printf("");    /* for alloc/free debugging; MSC will call malloc */
  145.                   /* during first printf() */
  146. #endif
  147.    error.num = -1;
  148.  
  149.    cdisk = setup(argv,drives,&disk);
  150.    startup(ccurdir,cdisk);
  151.  
  152.    /*
  153.       The rest of the code is one huge switch/case in a loop.
  154.       (It is so big that MSC gives: "main() too big for global
  155.       optimizations", but I can't see trimming it any more.)
  156.  
  157.       The interface I chose to use, a TTY or Teletype-like
  158.       interface (which may seem out dated to some be I find
  159.       it extremely easy to use), presents some programming
  160.       constructs that are hard to keep consistant and can
  161.       be confusing :-)
  162.  
  163.       DISKED WILL NEVER HAVE A "WINDOWED" OR GUI INTERFACE!
  164.       (colors and sound board support might cool though)
  165.    */
  166.  
  167.    for (;;)
  168.    {
  169.       if (error.num != -1)
  170.       {
  171.          /*if (!Verify)*/        /* there's lots of these ' 's */
  172.             output(' ');         /* it gets confusing and there may */
  173.          printerror(Debug);      /* be others that aren't quite right */
  174.       }
  175.       if (disk_moved)
  176.       {
  177.          disk_moved = 0;
  178.          dumpsector();
  179.       }
  180.  
  181.       c = prompt(byte_cnt,Radix);
  182.  
  183.       /* translate movement keys if file tracking is on */
  184.  
  185.       if (trackfile(&c) == -1)
  186.          continue;
  187.  
  188.       switch (c)
  189.       {
  190.          case '!':
  191.             output(' ');                  /* if "File not found" */
  192.             if (spawnl(P_WAIT,comspec,NULL)!=-1)
  193.                disk_moved=1;              /* display sector on return */
  194.             break;
  195.          case F1:
  196.             if (Files && n_files==1)
  197.                print(" no files");
  198.             else
  199.             {
  200.                print(" Current Directory: %s\n",curdir);
  201.                directory();
  202.             }
  203.             break;
  204.          case F2:
  205.             if (!Files)
  206.                break;
  207.             if (n_files==1)
  208.             {
  209.                print(" no files");
  210.                break;
  211.             }
  212.             for (u = 1; u < n_files; u++)       /* more than 32767 files ? */
  213.             {
  214.                print("\n%s",gfile(u));
  215.                if (kbhit())
  216.                {
  217.                   if ((c=input())==0)
  218.                      input();
  219.                   else if (c==0x1b)
  220.                      break;
  221.                   else if (c==' ')
  222.                      pause();
  223.                }
  224.            }
  225.            break;
  226.  
  227.          case SHFTF1:
  228.             dump(sec_buf,0,sec_size,128,Radix);
  229.             break;
  230.          case SHFTF2:
  231.             dumpf(sec_buf,sec_size,Radix);
  232.             break;
  233.          case SHFTF3:
  234.          case 'V'-'@':
  235.             view(sec_buf,0,sec_size,NOPAUSE,Radix);
  236.             break;
  237.          case SHFTF4:
  238.             dumpdir(sec_buf,sec_size);
  239.             break;
  240.          case SHFTF5:
  241.             dumpboot(sec_buf);
  242.             break;
  243.          case SHFTF6:
  244.             help();
  245.             break;
  246.          case SHFTF7:
  247.             break;
  248.          case F3:
  249.             if (!Files)
  250.                break;
  251.             print(" %u Files, %u Directories",n_files-1,n_dirs);
  252.             break;
  253.          case F4:                        /* change dir */
  254.             if (Display)
  255.                print("directory ");
  256.             else
  257.                print("cd ");
  258.             if (getstr(tmpstr,MAXSTR,_ALPHA) < 1)
  259.                break;
  260.             if (_chdir(tmpstr) == -1)
  261.                print(" not found");
  262.             _getcwd(curdir,_MAX_DIR);
  263.             break;
  264.          case F5:                        /* re-read */
  265.             readsector();
  266.             disk_moved = 1;
  267.             break;
  268.          case F6: case F7:
  269.          case F8: case F9:
  270.             if (byte_cnt > (max_bytes-sec_size))
  271.                break;
  272.             if (Display)
  273.                print("append w/");
  274.             tempt = temph = temps = 0;
  275.             switch (c)
  276.             {
  277.                case F6:
  278.                    if (Display)
  279.                        print(StripTxt);
  280.                    temph = 1;
  281.                    break;
  282.                case F7:
  283.                    if (Display)
  284.                        print(ConvertTxt);
  285.                    temps = 1;
  286.                    break;
  287.                case F8:
  288.                    if (Display)
  289.                        print(MaskTxt);
  290.                    tempt = 1;
  291.                    break;
  292.                case F9:
  293.                    if (Display)
  294.                        print("options");
  295.                    tempt = Strip;
  296.                    temph = Mask;
  297.                    temps = Convert;
  298.                    break;
  299.                default:
  300.                    break;
  301.             }
  302.             append(tempt,temph,temps,sec_buf,sec_size);
  303.             break;
  304.          case F0:
  305.             if (!Files)
  306.                break;
  307.             if (n_files == 1)
  308.             {
  309.                print(" no files");
  310.                break;
  311.             }
  312.             if (Display)
  313.                print("goto ");
  314.             print("file: ");
  315.             if (getstr(tmpstr,MAXSTR,_ALPHA) < 1)
  316.                break;
  317.             if ((tempu = findfile(tmpstr)) != 0)
  318.             {
  319.                setcluster(tempu);
  320.             }
  321.             else
  322.                print(" not found");
  323.             break;
  324.          case ALTA:case ALTC:case ALTD:
  325.          case ALTF:case ALTG:case ALTH:case ALTL:
  326.          case ALTM:case ALTP:case ALTS:case ALTB:
  327.          case ALTV:case ALTW:case ALTT:
  328.             setkeyword(c,kw);
  329.             if (ft_track)
  330.                Get = FALSE;
  331.             break;
  332.  
  333.          case '*':
  334.             Filter = !Filter;
  335.             print("filter:%s",(Filter) ? "ON" : "OFF");
  336.             break;
  337.  
  338.          case 'T'-'@':
  339.             if (!Files) break;
  340.             if (ft_track != 0)
  341.             {
  342.                filetrack(NULL,0);
  343.                print(" file unlocked");
  344.                break;
  345.             }
  346.             tempu = sectortocluster(log_sector);
  347.             i = clusters[tempu];
  348.             if (i > 0 && (unsigned)i <= n_files)
  349.             {
  350.                char *b;
  351.                if (Display || Verify)
  352.                   print(" track file ");
  353.                if (Verify && !getver("",0))
  354.                   break;
  355.                print(" %s locked",b=gfile(i));
  356.                if ((i = filetrack(b,i)) != 1)
  357.                   print(" lock error %d",i);
  358.             }
  359.             break;
  360.  
  361.          /*  **** Display ****  */
  362.  
  363.          case '\n':
  364.             header();
  365.             break;
  366.          case '\r':
  367.             if (!Ascii && !BigScreen && Partial)
  368.                   dump(sec_buf,(sec_size==128)?(0):(128),sec_size, \
  369.                   (sec_size==512)?(384):(sec_size),Radix);
  370.             else
  371.                disk_moved = 1;
  372.             break;
  373.  
  374.          case ' ':
  375.             disk_moved = 1;
  376.             break;
  377.          case '\b':
  378.             dparams(curdir);
  379.             output('\n');
  380.             break;
  381.          case '/':
  382.             disptext(command_text1);
  383.             if (BigScreen)
  384.                output('\n');
  385.             else 
  386.                break;
  387.          case '?':
  388.             disptext(command_text2);
  389.             break;
  390.  
  391.          /*  **** movement ****  */
  392.  
  393.          case 'Q'-'@':                             /* go back */
  394.             if (back_log_sector != log_sector)
  395.             {
  396.                if (Display)
  397.                   print(" go back");
  398.                setsector(back_log_sector);
  399.                disk_moved = 1;
  400.             }
  401.             break;
  402.          case 'H':                                 /* go root */
  403.             if (Display)
  404.                print(" root");
  405.             rootsector();
  406.             break;
  407.          case HOME:                                /* go root or */
  408.             if (Display)                           /*  go start */
  409.                print(" home");
  410.             if (set_sector != -1L)
  411.                setsector(set_sector);
  412.             else
  413.                rootsector();
  414.             break;
  415.          case 'E':                                 /* go drive end */
  416.          case END:
  417.             if (Display)
  418.                print(" end");
  419.             lastsector();
  420.             break;
  421.          case 'b':                                 /* back sector */
  422.          case UP:
  423.             if (Display)
  424.                print(" back sector");
  425.             backsector();
  426.             break;
  427.          case 'n':                                 /* next sector */
  428.          case DOWN:
  429.              if (Display)
  430.                  print(" next sector");
  431.              nextsector();
  432.              break;
  433.          case 'B':                                 /* back cluster */
  434.          case LEFT:
  435.             if (Display)
  436.                print(" back cluster");
  437.             backcluster();
  438.             break;
  439.          case 'N':                                 /* next cluster */
  440.          case RIGHT:
  441.             if (Display)
  442.                print(" next cluster");
  443.             nextcluster();
  444.             break;
  445.          case 'B'-'@':                             /* back track */
  446.          case PGUP:
  447.             if (Display)
  448.                print(" back track");
  449.             backtrack();
  450.             break;
  451.          case 'N'-'@':                             /* next track */
  452.          case PGDN:
  453.             if (Display)
  454.                print(" next track");
  455.             nexttrack();
  456.             break;
  457.          case 'h':                                 /* next head */
  458.             if (max_head==1)
  459.                break;
  460.             if (Display)
  461.                print(" next head");
  462.             nexthead();
  463.             break;
  464.          case 'r':                                 /* range (continuous) */
  465.          case 'R':
  466.          case CTRLR:
  467.             if (c=='R')
  468.                tempd=secs_cluster;
  469.             else
  470.                tempd=1;
  471.             if (Display)
  472.             {
  473.                print(" range ");
  474.                if (c==CTRLR)
  475.                   output('-');
  476.                putbyte(tempd);
  477.             }
  478.             tempd *= (c==CTRLR) ? -1 : 1;
  479.             range(tempd);
  480.             break;
  481.          case '-':                                 /* plus/minus sectors */
  482.          case '+':
  483.          case '=':
  484.             if (Display)
  485.                print( (c=='-') ? " move back " : " move ahead ");
  486.             if (getlnumb(num_sectors,&templ) <= 0)
  487.                break;
  488.             if (templ == 0)
  489.                break;
  490.             if (c=='-')
  491.                templ *= -1;
  492.             movesector(templ);
  493.             break;
  494.          case 'S'-'@':                             /* set to sector */
  495.             if (Display)
  496.                print(" sector ");
  497.             if (getlnumb(num_sectors,&templ) <= 0)
  498.                break;
  499.             setsector(templ);
  500.             break;
  501.          case 'S':                                 /* set to cluster */
  502.             if (Display)
  503.                print(" cluster ");
  504.             if (getnumb(num_clusters,&tempu) <= 0)
  505.                break;
  506.             if (tempu < 2)
  507.                break;
  508.             setcluster(tempu);
  509.             break;
  510.          case 's':                                 /* set physical */
  511.             tempt=track;
  512.             temps=sector;
  513.             temph=head;
  514.             c=set(st,(int *)&tempt,(int *)&temps,(int *)&temph);
  515.             if (c=='f')
  516.                fatsector();
  517.             else if (c=='b')
  518.                bootsector();
  519.             else if (c==0)
  520.                break;
  521.             else
  522.             {
  523.                if (tempt > max_track)
  524.                   tempt = track;
  525.                if (temps > max_sector || temps==0)
  526.                   temps = sector;
  527.                if (temph >= max_head)
  528.                   temph = head;
  529.                if (tempt==track && temps==sector && temph==head)
  530.                   break;
  531.                setphysical(tempt,temps,temph);
  532.              }
  533.              break;
  534.          case SRIGHT:                              /* back/next free cluster */
  535.          case SLEFT:
  536.             if (!Files)
  537.                break;
  538.             tempu=sectortocluster(log_sector);
  539.             if (tempu==0)
  540.                tempu=2;
  541.             temps = (c==SLEFT) ? (-1) : (1);
  542.             if (Display)
  543.             {
  544.                print( (temps==1) ? " next" : " back");
  545.                print(" free cluster");
  546.             }
  547.             for (u=tempu+temps;;u+=temps)
  548.             {
  549.                if (u>=num_clusters)
  550.                    u=2;
  551.                if (u<2)
  552.                    u=num_clusters;
  553.                if (u==tempu)
  554.                    break;
  555.                if (clusters[u] < 1)
  556.                {
  557.                    setcluster(u);
  558.                    break;
  559.                }
  560.             }
  561.             break;
  562.          case CEND:                                /* end of file */
  563.             if (!Files)
  564.                break;
  565.             tempu = sectortocluster(log_sector);
  566.             if (clusters[tempu] > 0 && (unsigned)clusters[tempu] <= n_files)
  567.             {
  568.                if (Display)
  569.                   print(" end file");
  570.                if ((tempu=arraylast(clusters,num_clusters,clusters[tempu])) == 0)
  571.                   break;
  572.                setcluster(tempu);
  573.             }
  574.             break;
  575.          case CHOME:                               /* start of file */
  576.             if (!Files)
  577.                break;
  578.             tempu=sectortocluster(log_sector);
  579.             if (clusters[tempu] > 0 && (unsigned)clusters[tempu] <= n_files)
  580.             {
  581.                if (Display)
  582.                   print(" home file");
  583.                tempu=arrayfirst(clusters,num_clusters,clusters[tempu]);
  584.                if (tempu == num_clusters)
  585.                   break;
  586.                setcluster(tempu);
  587.             }
  588.             break;
  589.          case 'j':                                 /* back/next file cluster */
  590.          case 'J':
  591.          case CLEFT:
  592.          case CRIGHT:
  593.             if (!Files)
  594.                break;
  595.             tempu = sectortocluster(log_sector);      /* get current cluster */
  596.             temps = (c=='j' || c==CRIGHT) ? 1 : -1;   /* set direction */
  597.             if (clusters[tempu] == 0)
  598.                break;
  599.             if ((u = arraytrav(clusters,num_clusters,tempu,temps)) == tempu)
  600.                break;                                 /* just one cluster? */
  601.             if (Display)
  602.             {
  603.                print((temps==1)?" next":" back");
  604.                print(" file's cluster");
  605.             }
  606.             setcluster(u);                         /* got it */
  607.             break;
  608.  
  609.           /*  **** Buffer stuff ****  */
  610.  
  611.          case 'a':
  612.              if (byte_cnt==max_bytes)
  613.                  break;
  614.              if (Display)
  615.                  print(" append sector");
  616.              if ((byte_cnt+sec_size)>max_bytes)
  617.              {
  618.                  print(bufferfull);
  619.                  tempu=max_bytes-byte_cnt;
  620.              }
  621.              else
  622.                  tempu=sec_size;
  623.              memcpy(data_buf+byte_cnt,sec_buf,tempu);
  624.              byte_cnt+=tempu;
  625.              break;
  626.          case 'A':
  627.             if (log_sector<=data_sector)
  628.                break;
  629.             if (byte_cnt==max_bytes)
  630.                break;
  631.             if (Display)
  632.                print(" append cluster");
  633.             savesector();
  634.  
  635.             i=clustersector(log_sector);  /* goto 1st sector */
  636.             if (movesector(-i) != DISK_OK)
  637.             {
  638.                restoresector();
  639.                break;
  640.             }
  641.             for (u=0;;u++)                     /* get it loop */
  642.             {
  643.                if ((byte_cnt+sec_size)>max_bytes)
  644.                   tempu=max_bytes-byte_cnt;
  645.                else
  646.                   tempu=sec_size;
  647.                memcpy(data_buf+byte_cnt,sec_buf,tempu);
  648.                if ((byte_cnt+=tempu)==max_bytes)
  649.                {
  650.                    print(bufferfull);
  651.                    break;
  652.                }
  653.                if (u == secs_cluster-1)
  654.                    break;
  655.                if (nextsector() != DISK_OK)
  656.                   break;
  657.             }
  658.             restoresector();
  659.             if (readsector() != DISK_OK)
  660.                disk_moved = 1;
  661.             break;
  662.          case 'A'-'@':
  663.             if (byte_cnt==max_bytes) break;
  664.             if (Display)
  665.                print(" append bytes");
  666.             tempd=temps=0;  /* tempd=from, temps=number */
  667.             if (!get(ap,&tempd,(int *)&temps))
  668.                break;
  669.             if ((temps+tempd > sec_size) || temps==0)
  670.                break;
  671.             if (byte_cnt+temps > max_bytes)
  672.                break;
  673.             memcpy(data_buf+byte_cnt,sec_buf+tempd,temps);
  674.             if ((byte_cnt+=temps)==max_bytes)
  675.                print(bufferfull);
  676.             break;
  677.          case 'u':
  678.          case 'U':
  679.             if (byte_cnt==0)
  680.                 break;
  681.             if (Display)
  682.             {
  683.                 print(" unappend ");
  684.                 print((c=='u')?"sector":"cluster");
  685.             }
  686.             tempu = (c=='u') ? sec_size : cluster_size;
  687.             if (byte_cnt < tempu)
  688.                byte_cnt = 0;
  689.             else
  690.                byte_cnt-=tempu;
  691.             break;
  692.          case 'U'-'@':
  693.             if (byte_cnt==0)
  694.                 break;
  695.             if (Display)
  696.                 print(" unappend bytes ");
  697.             if (getnumb(byte_cnt,&tempu)<=0)
  698.                 break;
  699.             if (byte_cnt < tempu)
  700.                 byte_cnt=0;
  701.             else
  702.                byte_cnt-=tempu;
  703.             break;
  704.          case 'e':
  705.          case 'E'-'@':
  706.             if (byte_cnt==0)
  707.                break;
  708.             if (Display || Verify)
  709.                print(" empty buffer");
  710.             if (c=='e' && Verify && !getver("",0))
  711.                break;
  712.             bufptr=byte_cnt=0;
  713.             break;
  714.          case 'k':
  715.             if (save_sec==NULL)
  716.                break;
  717.             if (Display)
  718.                print(" kill changes");
  719.             if (Verify && !getver("",0))
  720.                break;
  721.             memcpy(sec_buf,save_sec,sec_size);
  722.             disk_moved=1;
  723.             break;
  724.          case '>':
  725.             if (spare_sec==NULL)
  726.                break;
  727.             if (Display || Verify)
  728.                print(" store sector");
  729.             if (Verify && !getver("",0))
  730.                break;
  731.             memcpy(spare_sec,sec_buf,sec_size);
  732.             noput=FALSE;
  733.             break;
  734.          case '<':
  735.             if (spare_sec == NULL)
  736.                break;
  737.             if (noput)
  738.             {
  739.                print(" no sector stored");
  740.                break;
  741.             }
  742.             if (Display || Verify)
  743.                print(" retrieve sector");
  744.             if (Verify && !getver("",0))
  745.                break;
  746.             memcpy(sec_buf,spare_sec,sec_size);
  747.             disk_moved = 1;
  748.             break;
  749.          case 'd':
  750.          case 'v':
  751.             if (byte_cnt == 0)
  752.                break;
  753.             if (Display)
  754.             {
  755.                print((c == 'd') ? " dump" : " view");
  756.                print(" file buffer from ");
  757.             }
  758.             if ((tempd = getlnumb(byte_cnt,&tempu)) == ABORT)
  759.                break;
  760.             if (tempd > 0)
  761.                bufptr = tempu;
  762.             if (c == 'd')
  763.             {
  764.                output('\n');
  765.                bufptr = dump(data_buf,bufptr,byte_cnt,256,Radix);
  766.                output('\n');
  767.             }
  768.             else
  769.                bufptr = view(data_buf,bufptr,byte_cnt,PAUSE,Radix);
  770.             break;
  771.          case 'c':
  772.             if (Display)
  773.                print(" change sector buffer from ");
  774.             if (change(sec_buf,sec_size,Radix))
  775.                disk_moved = 1;
  776.             break;
  777.          case 'C':
  778.             if (!byte_cnt)
  779.                break;
  780.             if (Display)
  781.                print(" change file buffer from ");
  782.             change(data_buf,byte_cnt,Radix);
  783.             break;
  784.          case 'D'-'@':
  785.          case 'C'-'@':
  786.             if (changedir(sec_buf,sec_size))
  787.                disk_moved = 1;
  788.             break;
  789.          case 'g':           /*** get sectors ***/
  790.          case 'G'-'@':       /* uses tempd, tempt, i */
  791.             if (byte_cnt == max_bytes)    /* full? */
  792.                break;
  793.             if (Display)                  /* display */
  794.             {
  795.                print(" get sectors ");
  796.                if (c == 'G'-'@' || Get)
  797.                    print("w/move ");
  798.             }                             /* get number */
  799.             if (getbyte(&tempu) <= 0)
  800.                break;                     /* tempd = number to get */
  801.             savesector();
  802.             if (tempu==0)                 /* 0 = get whole track from beginning */
  803.             {
  804.                tempu=max_sector;          /* count to get */
  805.                log_sector=logicalsector(track,1,head);
  806.             }
  807.             else if (tempu == 1)              /* get rest of track */
  808.                tempu = (max_sector - sector) + 1;
  809.  
  810.             if (log_sector == 0)
  811.                log_sector = num_sectors-1;
  812.             else
  813.                --log_sector;
  814.             if (Display)
  815.                output(' ');
  816.             for (i = 1 ; i <= (int)tempu ; i++)
  817.             {
  818.                if (kbhit())
  819.                    break;
  820.                if (Display)
  821.                {
  822.                   pn(i,Radix);
  823.                   put(len(i),8);
  824.                }
  825.                if ((tempd=nextsector()) != DISK_OK)
  826.                {
  827.                   savecursor();
  828.                   if (!Display)
  829.                      output(' ');
  830.                   printerror(Debug);
  831.                   if (!getver("continue",0))
  832.                   {
  833.                      put(3,8);
  834.                      break;
  835.                   }
  836.                   restcursor();
  837.                   clreol();
  838.                }
  839.                if ((byte_cnt+sec_size)>max_bytes)
  840.                    break;
  841.                memcpy(data_buf+byte_cnt,sec_buf,sec_size);
  842.                if ((byte_cnt+=sec_size)==max_bytes)
  843.                {
  844.                   print(bufferfull);
  845.                   break;
  846.                }
  847.             }
  848.             if (Display && tempd == DISK_OK)
  849.                clreol();
  850.             if (Get || c=='G'-'@')
  851.                nextsector();
  852.             else
  853.             {
  854.                restoresector();
  855.                readsector();
  856.                disk_moved = 0;
  857.             }
  858.             break;
  859.  
  860.          /*  **** Log Drive ****  */
  861.  
  862.          case 'l':
  863.          case 'L'-'@':
  864.             if (c == 'l')
  865.             {
  866.                if (Display)
  867.                    print(" disk ");
  868.                c = input();
  869.                if (!isalpha(c))
  870.                    break;
  871.                tempd = toupper(c)-'@';
  872.                if (drives[tempd]!=TRUE)
  873.                    break;
  874.                output(toupper(c));
  875.                output(':');
  876.                if (Verify)
  877.                {
  878.                   if (!getver("log disk",MOV_YN))
  879.                      break;
  880.                }
  881.             }
  882.             else
  883.                tempd = disk;
  884.             if (newdisk(tempd))
  885.             {
  886.                disk = tempd;
  887.                if (avail_clusters == 0)
  888.                   avail_clusters = get_avail_clusters();
  889.                dparams(curdir);
  890.             }
  891.             if (error.num != -1)    /* if theres gonna be an error */
  892.             {
  893.                if (disk_moved == 1)
  894.                {
  895.                   output('\n');       /* put it on a new line */
  896.                   output('\n');
  897.                }                    /* if its bad BOOT, reset diskio flag */
  898.                if (strcmp(error.func,"diskio") == 0)
  899.                   diskio_error = 0;
  900.             }
  901.             break;
  902.  
  903.          /*  **** Misc. ****  */
  904.  
  905.          case 'T':
  906.             for (i=1;i<10;i++)
  907.                if (tagged[i]!=0L)
  908.                    break;
  909.             if (i<10)
  910.             {
  911.                if (Display)
  912.                   print(" tagged sector list");
  913.                for (i=1;i<10;i++)
  914.                {
  915.                   if (!tagged[i])
  916.                      continue;
  917.                   output(' ');
  918.                   output(i+'0');
  919.                   output(':');
  920.                   pln(tagged[i],Radix);
  921.                }
  922.             }
  923.             else if (Display)
  924.                print(" no tagged sectors");
  925.             break;
  926.          case 't':
  927.             if (Display)
  928.                print(" number of this tag? ");
  929.             if ((c=input()) < '0' || c > '9')
  930.                break;
  931.             output(c);
  932.             if (c == '0')
  933.             {
  934.                if (getver(" clear all",0))
  935.                   memset(tagged,0,sizeof(tagged));
  936.                break;
  937.             }
  938.             tagged[c-'0']=log_sector;
  939.             break;
  940.          case 'f':
  941.          case '\\':
  942.             if (Display)
  943.                print(" find ");
  944.             tempd = find(F_DISK,1,(c=='f') ? F_CASE : F_NOCASE);
  945.             if (tempd>=0)
  946.             {
  947.                print("\nfound at ");
  948.                pn(tempd,Radix);
  949.             }
  950.             if (tempd!=ABORT)             /* user pressed ESC */
  951.                readsector();
  952.             break;
  953.          case 'F':
  954.          case 'F'-'@':
  955.             if (byte_cnt==0)
  956.                break;
  957.             if (Display)
  958.                print(" find ");
  959.             if (find(F_BUFFER,1,(c=='F') ? F_CASE : F_NOCASE) == -1)
  960.                print(" not found");
  961.             break;
  962.          case 'P':
  963.             if (Display)
  964.                print(" put");
  965.             templ=log_sector;
  966.             temps=0;               /* templ=from, temps=number */
  967.             if (!getl(ps,&templ,(int *)&temps))
  968.                break;
  969.             if (templ+(long)temps > (long)num_sectors)
  970.                break;
  971.             if (Display)
  972.                print(" file: ");
  973.             else
  974.                output(':');
  975.             if (getstr(tmpstr,64,_ALPHA) > 0)
  976.             {
  977.                if (Verify)
  978.                {
  979.                   if (!getver(" put file",MOV_YN))
  980.                      break;
  981.                }
  982.                if (exist(tmpstr))
  983.                {
  984.                   savecursor();
  985.                   if (!Verify)
  986.                      output(' ');
  987.                   if (!getver("exists, overwrite",MOV_YN))
  988.                      break;
  989.                   restcursor();
  990.                   clreol();
  991.                }
  992.                if (error.num == -1)
  993.                {
  994.                   if (Display && !Verify)
  995.                      output(' ');
  996.                   else if (Display && Verify)
  997.                   {
  998.                      put(3,' ');
  999.                      put(3,8);
  1000.                   }
  1001.                   putsectors(tmpstr,templ,temps);
  1002.                   readsector();
  1003.                }
  1004.             }
  1005.             break;
  1006.          case 'P'-'@':
  1007.          case 'p':
  1008.             if (byte_cnt==0)
  1009.                break;
  1010.             if (Display)
  1011.                print(" file: ");
  1012.             getstr(tmpstr,64,_ALPHA);
  1013.             if (!tmpstr[0])
  1014.                break;
  1015.             if (Verify)
  1016.             {
  1017.                print(" put file ");
  1018.                if (Display && c=='p')
  1019.                   print("w/options");
  1020.                else if (Display)
  1021.                   print("w/o options");
  1022.                if (!getver("",MOV_YN))
  1023.                   break;
  1024.             }
  1025.             if (access(tmpstr,0) == 0)
  1026.             {
  1027.                savecursor();
  1028.                if (!Verify)
  1029.                   output(' ');
  1030.                if (!getver("exists, overwrite",MOV_YN))
  1031.                   break;
  1032.                restcursor();
  1033.                clreol();
  1034.                if (unlink(tmpstr) == -1)
  1035.                   break;
  1036.             }
  1037.             if (error.num != -1)
  1038.                break;
  1039.             if (Display)
  1040.             {
  1041.                savecursor();
  1042.                if (!Verify)
  1043.                   output(' ');
  1044.                print("putting");
  1045.                restcursor();
  1046.             }
  1047.             putfile(tmpstr,(c=='p') ? XLATE : NOXLATE,Mask,Strip,Convert);
  1048.             break;
  1049.          case 'I'-'@':
  1050.          case 'i':
  1051.             if (byte_cnt==max_bytes)
  1052.                break;
  1053.             if (Display)
  1054.                print(" file: ");
  1055.             getstr(tmpstr,64,_ALPHA);
  1056.             if (!tmpstr[0])
  1057.                break;
  1058.             if (Verify)
  1059.             {
  1060.                print(" insert file ");
  1061.                if (Display && c=='i')
  1062.                   print("w/options");
  1063.                else if (Display)
  1064.                   print("w/o options");
  1065.                if (!getver("",MOV_YN))
  1066.                   break;
  1067.             }
  1068.             if (Display)
  1069.             {
  1070.                savecursor();
  1071.                if (!Verify)
  1072.                   output(' ');
  1073.                print("inserting");
  1074.                restcursor();
  1075.             }
  1076.             tempd=getfile(tmpstr, (c=='i') ? XLATE : NOXLATE,Mask,Strip,Convert);
  1077.             if (tempd == -2)
  1078.             {
  1079.                if (!Verify)
  1080.                   output(' ');
  1081.                print("buffer full ");
  1082.             }
  1083.             break;
  1084.          case 'w':
  1085.             if (!write_to || !Write)
  1086.             {
  1087.                print(" write not enabled");
  1088.                break;
  1089.             }
  1090.             if (Display || Verify)
  1091.                print(" write sector");
  1092.             if (log_sector<dir_sector)
  1093.             {
  1094.                print("\a Warning! This is ");
  1095.                print((log_sector==0)?"the BOOT":"a FAT");
  1096.                print(" sector, ");
  1097.                if (!getver("write anyway",0))
  1098.                    break;
  1099.             }
  1100.             else if (Verify && !getver("",0))
  1101.                break;
  1102.             writesector();
  1103.             break;
  1104.          case 'z':
  1105.          case 'Z':
  1106.             if (Display || c=='Z')
  1107.             {
  1108.                if (Display)
  1109.                    print(" parameters");
  1110.                dkey(kw);
  1111.                if (c=='z')
  1112.                    output('\n');
  1113.                else
  1114.                    break;
  1115.             }
  1116.             if (getstr(tmpstr,MAXSTR,_LOWER|_UPPER)>0)
  1117.                ckey(tmpstr,kw);
  1118.             break;
  1119.          case '0':case '1':case '2':case '3':
  1120.          case '4':case '5':case '6':case '7':
  1121.          case '8':case '9':
  1122.             c-=0x30;
  1123.             if (!tagged[c])
  1124.                break;
  1125.             if (Display || Verify)
  1126.             {
  1127.                print(" goto sector ");
  1128.                pln(tagged[c],Radix);
  1129.             }
  1130.             if (Verify && !getver("",0))
  1131.                break;
  1132.             if (log_sector != tagged[c])
  1133.             {
  1134.                log_sector = tagged[c];
  1135.                readsector();
  1136.                disk_moved = 1;
  1137.             }
  1138.             break;
  1139.          case ',':       /* toggle radix */
  1140.             if (Radix==10)
  1141.                Radix=16;
  1142.             else
  1143.                Radix=10;
  1144.             if (Display)
  1145.             {
  1146.                print(" radix is now ");
  1147.                print((Radix==16)?"hex":"dec");
  1148.             }
  1149.             break;
  1150.          case 'D':
  1151.             if (Debug)
  1152.                debug();
  1153.             break;
  1154.          case 'm':
  1155.             if (!Files)
  1156.                break;
  1157.             tempu = sectortocluster(log_sector);
  1158.             if (clusters[tempu] > 0 && (unsigned)clusters[tempu] <= n_files)
  1159.             {
  1160.                if (Display)
  1161.                    print(" map file ");
  1162.                print(gfile(clusters[tempu]));
  1163.                output('\n');
  1164.                arraymap(clusters,num_clusters,clusters[tempu],Radix);
  1165.             }
  1166.             break;
  1167.          case 'M':
  1168.             if (Files)
  1169.             {
  1170.                if (Display)
  1171.                    print(" map free space");
  1172.                output('\n');
  1173.                if (arraymap(clusters,num_clusters,0,Radix) == 0)
  1174.                   print(" no free space");
  1175.             }
  1176.             break;
  1177.          case 'I':
  1178.             if (!Files)
  1179.                break;
  1180.             tempd = sectortocluster(log_sector);
  1181.             if (clusters[tempd] < 0 || clusters[tempd] > (int)n_files)
  1182.                break;
  1183.             if (files[clusters[tempd]].dir)
  1184.             {
  1185.                print(" can not insert directories");
  1186.                break;
  1187.             }
  1188.             sprintf(tmpstr,gfile(clusters[tempd]));
  1189.             if (Display)
  1190.             {
  1191.                print(" insert file ");
  1192.                print(tmpstr);
  1193.             }
  1194.             if (Verify)
  1195.             {
  1196.                if (!getver("",0))
  1197.                   break;
  1198.             }
  1199.             if (Display)
  1200.             {
  1201.                savecursor();
  1202.                if (!Verify)
  1203.                   output(' ');
  1204.                print("inserting");
  1205.                restcursor();
  1206.             }
  1207.             if (getfile(tmpstr,XLATE,Mask,Strip,Convert) == -2)
  1208.             {
  1209.                if (!Verify)
  1210.                   output(' ');
  1211.                print("buffer full ");
  1212.             }
  1213.             break;
  1214.  
  1215.          case 'Y'-'@':
  1216.             if (Display && !Verify)
  1217.                print(" saving");
  1218.             else if (Verify && !getver(" save",0))
  1219.                break;
  1220.             saveinit(savfile);
  1221.             break;
  1222.          case 'Y':
  1223.             if (Display && !Verify)
  1224.                print(" restoring");
  1225.             else if (Verify && !getver(" restore",0))
  1226.                break;
  1227.             tempd = Home;
  1228.             Home = FALSE;
  1229.             tempt = disk;
  1230.             templ = log_sector;
  1231.             if (getinit(savfile,INIT_RESTORE))
  1232.             {
  1233.                if (tempt != disk)
  1234.                {
  1235.                   if (!newdisk(disk))
  1236.                   {
  1237.                      disk = tempt;
  1238.                      log_sector = templ;
  1239.                   }
  1240.                }
  1241.                else if ((unsigned long)templ != log_sector)
  1242.                   readsector();
  1243.                else if (Display)
  1244.                   output('\n');
  1245.                disk_moved = 1;
  1246.             }
  1247.             else
  1248.             {
  1249.                disk = tempt;
  1250.                log_sector = tempu;
  1251.             }
  1252.             Home = tempd;
  1253.             break;
  1254.          case 'x':
  1255.             viewfile(inifile,Display);
  1256.             break;
  1257.          case 'y':
  1258.             getinit(savfile,INIT_VIEW);
  1259.             break;
  1260.  
  1261.          case 'q':
  1262.          case '.':
  1263.          case ESC:
  1264.          case ALTX:
  1265.             if (Display || Verify)
  1266.                print(" exit DISKED");
  1267.             if (c != ALTX && Verify && !getver("",0))
  1268.                break;
  1269.             _dos_setdrive(cdisk,&tempu);
  1270.             if (ccurdir[0])
  1271.                _chdir(ccurdir);
  1272.             if (Save && c != ALTX)
  1273.             {
  1274.                if (Verify)
  1275.                   if (!getver(" save",1))
  1276.                break;
  1277.                if (Display)
  1278.                   print(" saving...");
  1279.                saveinit(savfile);
  1280.             }
  1281.             if (files_indexed)            /* free calls are for an IDE */
  1282.             {                             /* such as QuickC that I use */
  1283.                hugefreep(files);          /* which can get confused if */
  1284.                hugefreep(clusters);       /* if you don't do this */
  1285.             }
  1286.             if (spare_sec)
  1287.                freep(spare_sec);
  1288.             if (save_sec)
  1289.                freep(save_sec);
  1290.             freep(sec_buf);
  1291.             freep(data_buf);
  1292.             exit(0);
  1293.             break;
  1294.          default:
  1295.              break;
  1296.         }
  1297.     }
  1298. }
  1299.