/***
*disked.c - DISKED The DISK EDitor for MS(tm)-DOS.
*
*Copyright (c) 1991-1995, Gregg Jennings. All wrongs reserved.
* P O Box 200, Falmouth, MA 02541-0200
*
*Purpose:
* Command module.
*
*Notice:
* This progam may be freely used and distributed. Any distrubution
* with modifications must retain the above copyright statement and
* modifications noted.
* No pulp-publication, in whole or in part, permitted without
* permission (magazines or books).
*******************************************************************************/
/*
Versions:
2.7 25-Dec-1994 'y': view .SAV file (some command letter changes)
2.6 04-Sep-1994 ^T, find() changes, extern reference consolodation
2.5 18-Apr-1994 cleaning up of extern defs
input/output function pointers
2.4 23-Jan-1994 moved all startup code to SETUP.C
2.3 19-Jan-1994 'removable' test
2.2 16-Jan-1994 '^Q', replaced 'moved' with 'disk_moved'
2.1 04-Jan-1994 Translate if !Files for startup, Borland
2.0 28-Nov-1993
Release Notes:
Programming Notes:
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* _MAX_DIR */
#include <conio.h> /* kbhit() */
#include <ctype.h> /* isalpha() */
#include <dos.h> /* _dos_set_drive() */
#include <io.h> /* for exist() */
#include <direct.h> /* getcwd(),chdir() */
#include <process.h> /* spawnl() */
#include "disked.h"
#include "mylib.h"
#include "diskio.h"
#include "keys.h"
#include "alloc.h"
#include "files.h"
#include "error.h"
#include "dirent.h"
#include "direct.h"
#include "console.h"
#include "arrays.h"
/* for find() */
enum FIND_ARGUMENTS { F_BUFFER, F_DISK, F_CASE = 0, F_NOCASE };
struct Msg ps[]={ /* for inputing a two argument commnd */
{" from ",6},
{" number ",3},
};
struct Msg ap[]={ /* for inputing a two argument commnd */
{" from ",3},
{" number ",3}
};
struct Msg st[]={ /* three argument command 's' */
{" track ",3},
{" sector ",2},
{" head ",1}
};
/* shared with SETUP.C only */
char comspec[FILENAME_MAX]; /* location of COMMAND.COM */
char promptvar[40]; /* DOS prompt variable */
char inifile[FILENAME_MAX]; /* INI file path/name */
char savfile[FILENAME_MAX]; /* Save file path/name */
char curdir[_MAX_DIR]; /* current working directory */
long set_sector; /* startup sector number */
int Save,Restore;
int files_indexed;
/* shared with SETUP.C and INIT.C */
int write_to; /* double protection on write */
unsigned long tagged[10];
/* shared with SETUP.C and DISKLIB.C */
int BigScreen; /* 50 line display */
unsigned int dir_cluster; /* start up directory cluster nu. */
/* shared with many */
unsigned int byte_cnt; /* buffer byte count */
unsigned int max_bytes; /* maximum buffer size */
unsigned char *save_sec; /* duplicate sector buffer */
unsigned char *spare_sec; /* spare sector buffer */
unsigned char *data_buf; /* pointer to area for data buffer */
#ifdef __BORLANDC__
#pragma argsused
#endif
#ifdef _MSC_VER
#pragma warning(disable:4035; disable:4100)
#endif
int main(int argc,char **argv)
{
unsigned int c;
char tmpstr[MAXSTR+1];
char ccurdir[_MAX_DIR];
unsigned int cdisk;
register unsigned int u; /* vars for loops */
register int i;
unsigned int temps,tempt,temph,tempu;
long templ;
int tempd;
unsigned int bufptr; /* pointer to file buffer */
int drives[MAX_DRIVE+1]; /* valid drive number array 1-MAX_DRIVE */
int noput;
char *bufferfull=" buffer full ";
tmpstr[0] = '\0';
bufptr = 0;
noput = TRUE;
#ifdef __WATCOMC__
setvbuf(stdout,NULL,_IONBF,0); /* flush stdout every printf */
#endif
#ifndef NDEBUG
printf(""); /* for alloc/free debugging; MSC will call malloc */
/* during first printf() */
#endif
error.num = -1;
cdisk = setup(argv,drives,&disk);
startup(ccurdir,cdisk);
/*
The rest of the code is one huge switch/case in a loop.
(It is so big that MSC gives: "main() too big for global
optimizations", but I can't see trimming it any more.)
The interface I chose to use, a TTY or Teletype-like
interface (which may seem out dated to some be I find
it extremely easy to use), presents some programming
constructs that are hard to keep consistant and can
be confusing :-)
DISKED WILL NEVER HAVE A "WINDOWED" OR GUI INTERFACE!
(colors and sound board support might cool though)
*/
for (;;)
{
if (error.num != -1)
{
/*if (!Verify)*/ /* there's lots of these ' 's */
output(' '); /* it gets confusing and there may */
printerror(Debug); /* be others that aren't quite right */
}
if (disk_moved)
{
disk_moved = 0;
dumpsector();
}
c = prompt(byte_cnt,Radix);
/* translate movement keys if file tracking is on */
if (trackfile(&c) == -1)
continue;
switch (c)
{
case '!':
output(' '); /* if "File not found" */
if (spawnl(P_WAIT,comspec,NULL)!=-1)
disk_moved=1; /* display sector on return */
break;
case F1:
if (Files && n_files==1)
print(" no files");
else
{
print(" Current Directory: %s\n",curdir);
directory();
}
break;
case F2:
if (!Files)
break;
if (n_files==1)
{
print(" no files");
break;
}
for (u = 1; u < n_files; u++) /* more than 32767 files ? */
{
print("\n%s",gfile(u));
if (kbhit())
{
if ((c=input())==0)
input();
else if (c==0x1b)
break;
else if (c==' ')
pause();
}
}
break;
case SHFTF1:
dump(sec_buf,0,sec_size,128,Radix);
break;
case SHFTF2:
dumpf(sec_buf,sec_size,Radix);
break;
case SHFTF3:
case 'V'-'@':
view(sec_buf,0,sec_size,NOPAUSE,Radix);
break;
case SHFTF4:
dumpdir(sec_buf,sec_size);
break;
case SHFTF5:
dumpboot(sec_buf);
break;
case SHFTF6:
help();
break;
case SHFTF7:
break;
case F3:
if (!Files)
break;
print(" %u Files, %u Directories",n_files-1,n_dirs);
break;
case F4: /* change dir */
if (Display)
print("directory ");
else
print("cd ");
if (getstr(tmpstr,MAXSTR,_ALPHA) < 1)
break;
if (_chdir(tmpstr) == -1)
print(" not found");
_getcwd(curdir,_MAX_DIR);
break;
case F5: /* re-read */
readsector();
disk_moved = 1;
break;
case F6: case F7:
case F8: case F9:
if (byte_cnt > (max_bytes-sec_size))
break;
if (Display)
print("append w/");
tempt = temph = temps = 0;
switch (c)
{
case F6:
if (Display)
print(StripTxt);
temph = 1;
break;
case F7:
if (Display)
print(ConvertTxt);
temps = 1;
break;
case F8:
if (Display)
print(MaskTxt);
tempt = 1;
break;
case F9:
if (Display)
print("options");
tempt = Strip;
temph = Mask;
temps = Convert;
break;
default:
break;
}
append(tempt,temph,temps,sec_buf,sec_size);
break;
case F0:
if (!Files)
break;
if (n_files == 1)
{
print(" no files");
break;
}
if (Display)
print("goto ");
print("file: ");
if (getstr(tmpstr,MAXSTR,_ALPHA) < 1)
break;
if ((tempu = findfile(tmpstr)) != 0)
{
setcluster(tempu);
}
else
print(" not found");
break;
case ALTA:case ALTC:case ALTD:
case ALTF:case ALTG:case ALTH:case ALTL:
case ALTM:case ALTP:case ALTS:case ALTB:
case ALTV:case ALTW:case ALTT:
setkeyword(c,kw);
if (ft_track)
Get = FALSE;
break;
case '*':
Filter = !Filter;
print("filter:%s",(Filter) ? "ON" : "OFF");
break;
case 'T'-'@':
if (!Files) break;
if (ft_track != 0)
{
filetrack(NULL,0);
print(" file unlocked");
break;
}
tempu = sectortocluster(log_sector);
i = clusters[tempu];
if (i > 0 && (unsigned)i <= n_files)
{
char *b;
if (Display || Verify)
print(" track file ");
if (Verify && !getver("",0))
break;
print(" %s locked",b=gfile(i));
if ((i = filetrack(b,i)) != 1)
print(" lock error %d",i);
}
break;
/* **** Display **** */
case '\n':
header();
break;
case '\r':
if (!Ascii && !BigScreen && Partial)
dump(sec_buf,(sec_size==128)?(0):(128),sec_size, \
(sec_size==512)?(384):(sec_size),Radix);
else
disk_moved = 1;
break;
case ' ':
disk_moved = 1;
break;
case '\b':
dparams(curdir);
output('\n');
break;
case '/':
disptext(command_text1);
if (BigScreen)
output('\n');
else
break;
case '?':
disptext(command_text2);
break;
/* **** movement **** */
case 'Q'-'@': /* go back */
if (back_log_sector != log_sector)
{
if (Display)
print(" go back");
setsector(back_log_sector);
disk_moved = 1;
}
break;
case 'H': /* go root */
if (Display)
print(" root");
rootsector();
break;
case HOME: /* go root or */
if (Display) /* go start */
print(" home");
if (set_sector != -1L)
setsector(set_sector);
else
rootsector();
break;
case 'E': /* go drive end */
case END:
if (Display)
print(" end");
lastsector();
break;
case 'b': /* back sector */
case UP:
if (Display)
print(" back sector");
backsector();
break;
case 'n': /* next sector */
case DOWN:
if (Display)
print(" next sector");
nextsector();
break;
case 'B': /* back cluster */
case LEFT:
if (Display)
print(" back cluster");
backcluster();
break;
case 'N': /* next cluster */
case RIGHT:
if (Display)
print(" next cluster");
nextcluster();
break;
case 'B'-'@': /* back track */
case PGUP:
if (Display)
print(" back track");
backtrack();
break;
case 'N'-'@': /* next track */
case PGDN:
if (Display)
print(" next track");
nexttrack();
break;
case 'h': /* next head */
if (max_head==1)
break;
if (Display)
print(" next head");
nexthead();
break;
case 'r': /* range (continuous) */
case 'R':
case CTRLR:
if (c=='R')
tempd=secs_cluster;
else
tempd=1;
if (Display)
{
print(" range ");
if (c==CTRLR)
output('-');
putbyte(tempd);
}
tempd *= (c==CTRLR) ? -1 : 1;
range(tempd);
break;
case '-': /* plus/minus sectors */
case '+':
case '=':
if (Display)
print( (c=='-') ? " move back " : " move ahead ");
if (getlnumb(num_sectors,&templ) <= 0)
break;
if (templ == 0)
break;
if (c=='-')
templ *= -1;
movesector(templ);
break;
case 'S'-'@': /* set to sector */
if (Display)
print(" sector ");
if (getlnumb(num_sectors,&templ) <= 0)
break;
setsector(templ);
break;
case 'S': /* set to cluster */
if (Display)
print(" cluster ");
if (getnumb(num_clusters,&tempu) <= 0)
break;
if (tempu < 2)
break;
setcluster(tempu);
break;
case 's': /* set physical */
tempt=track;
temps=sector;
temph=head;
c=set(st,(int *)&tempt,(int *)&temps,(int *)&temph);
if (c=='f')
fatsector();
else if (c=='b')
bootsector();
else if (c==0)
break;
else
{
if (tempt > max_track)
tempt = track;
if (temps > max_sector || temps==0)
temps = sector;
if (temph >= max_head)
temph = head;
if (tempt==track && temps==sector && temph==head)
break;
setphysical(tempt,temps,temph);
}
break;
case SRIGHT: /* back/next free cluster */
case SLEFT:
if (!Files)
break;
tempu=sectortocluster(log_sector);
if (tempu==0)
tempu=2;
temps = (c==SLEFT) ? (-1) : (1);
if (Display)
{
print( (temps==1) ? " next" : " back");
print(" free cluster");
}
for (u=tempu+temps;;u+=temps)
{
if (u>=num_clusters)
u=2;
if (u<2)
u=num_clusters;
if (u==tempu)
break;
if (clusters[u] < 1)
{
setcluster(u);
break;
}
}
break;
case CEND: /* end of file */
if (!Files)
break;
tempu = sectortocluster(log_sector);
if (clusters[tempu] > 0 && (unsigned)clusters[tempu] <= n_files)
{
if (Display)
print(" end file");
if ((tempu=arraylast(clusters,num_clusters,clusters[tempu])) == 0)
break;
setcluster(tempu);
}
break;
case CHOME: /* start of file */
if (!Files)
break;
tempu=sectortocluster(log_sector);
if (clusters[tempu] > 0 && (unsigned)clusters[tempu] <= n_files)
{
if (Display)
print(" home file");
tempu=arrayfirst(clusters,num_clusters,clusters[tempu]);
if (tempu == num_clusters)
break;
setcluster(tempu);
}
break;
case 'j': /* back/next file cluster */
case 'J':
case CLEFT:
case CRIGHT:
if (!Files)
break;
tempu = sectortocluster(log_sector); /* get current cluster */
temps = (c=='j' || c==CRIGHT) ? 1 : -1; /* set direction */
if (clusters[tempu] == 0)
break;
if ((u = arraytrav(clusters,num_clusters,tempu,temps)) == tempu)
break; /* just one cluster? */
if (Display)
{
print((temps==1)?" next":" back");
print(" file's cluster");
}
setcluster(u); /* got it */
break;
/* **** Buffer stuff **** */
case 'a':
if (byte_cnt==max_bytes)
break;
if (Display)
print(" append sector");
if ((byte_cnt+sec_size)>max_bytes)
{
print(bufferfull);
tempu=max_bytes-byte_cnt;
}
else
tempu=sec_size;
memcpy(data_buf+byte_cnt,sec_buf,tempu);
byte_cnt+=tempu;
break;
case 'A':
if (log_sector<=data_sector)
break;
if (byte_cnt==max_bytes)
break;
if (Display)
print(" append cluster");
savesector();
i=clustersector(log_sector); /* goto 1st sector */
if (movesector(-i) != DISK_OK)
{
restoresector();
break;
}
for (u=0;;u++) /* get it loop */
{
if ((byte_cnt+sec_size)>max_bytes)
tempu=max_bytes-byte_cnt;
else
tempu=sec_size;
memcpy(data_buf+byte_cnt,sec_buf,tempu);
if ((byte_cnt+=tempu)==max_bytes)
{
print(bufferfull);
break;
}
if (u == secs_cluster-1)
break;
if (nextsector() != DISK_OK)
break;
}
restoresector();
if (readsector() != DISK_OK)
disk_moved = 1;
break;
case 'A'-'@':
if (byte_cnt==max_bytes) break;
if (Display)
print(" append bytes");
tempd=temps=0; /* tempd=from, temps=number */
if (!get(ap,&tempd,(int *)&temps))
break;
if ((temps+tempd > sec_size) || temps==0)
break;
if (byte_cnt+temps > max_bytes)
break;
memcpy(data_buf+byte_cnt,sec_buf+tempd,temps);
if ((byte_cnt+=temps)==max_bytes)
print(bufferfull);
break;
case 'u':
case 'U':
if (byte_cnt==0)
break;
if (Display)
{
print(" unappend ");
print((c=='u')?"sector":"cluster");
}
tempu = (c=='u') ? sec_size : cluster_size;
if (byte_cnt < tempu)
byte_cnt = 0;
else
byte_cnt-=tempu;
break;
case 'U'-'@':
if (byte_cnt==0)
break;
if (Display)
print(" unappend bytes ");
if (getnumb(byte_cnt,&tempu)<=0)
break;
if (byte_cnt < tempu)
byte_cnt=0;
else
byte_cnt-=tempu;
break;
case 'e':
case 'E'-'@':
if (byte_cnt==0)
break;
if (Display || Verify)
print(" empty buffer");
if (c=='e' && Verify && !getver("",0))
break;
bufptr=byte_cnt=0;
break;
case 'k':
if (save_sec==NULL)
break;
if (Display)
print(" kill changes");
if (Verify && !getver("",0))
break;
memcpy(sec_buf,save_sec,sec_size);
disk_moved=1;
break;
case '>':
if (spare_sec==NULL)
break;
if (Display || Verify)
print(" store sector");
if (Verify && !getver("",0))
break;
memcpy(spare_sec,sec_buf,sec_size);
noput=FALSE;
break;
case '<':
if (spare_sec == NULL)
break;
if (noput)
{
print(" no sector stored");
break;
}
if (Display || Verify)
print(" retrieve sector");
if (Verify && !getver("",0))
break;
memcpy(sec_buf,spare_sec,sec_size);
disk_moved = 1;
break;
case 'd':
case 'v':
if (byte_cnt == 0)
break;
if (Display)
{
print((c == 'd') ? " dump" : " view");
print(" file buffer from ");
}
if ((tempd = getlnumb(byte_cnt,&tempu)) == ABORT)
break;
if (tempd > 0)
bufptr = tempu;
if (c == 'd')
{
output('\n');
bufptr = dump(data_buf,bufptr,byte_cnt,256,Radix);
output('\n');
}
else
bufptr = view(data_buf,bufptr,byte_cnt,PAUSE,Radix);
break;
case 'c':
if (Display)
print(" change sector buffer from ");
if (change(sec_buf,sec_size,Radix))
disk_moved = 1;
break;
case 'C':
if (!byte_cnt)
break;
if (Display)
print(" change file buffer from ");
change(data_buf,byte_cnt,Radix);
break;
case 'D'-'@':
case 'C'-'@':
if (changedir(sec_buf,sec_size))
disk_moved = 1;
break;
case 'g': /*** get sectors ***/
case 'G'-'@': /* uses tempd, tempt, i */
if (byte_cnt == max_bytes) /* full? */
break;
if (Display) /* display */
{
print(" get sectors ");
if (c == 'G'-'@' || Get)
print("w/move ");
} /* get number */
if (getbyte(&tempu) <= 0)
break; /* tempd = number to get */
savesector();
if (tempu==0) /* 0 = get whole track from beginning */
{
tempu=max_sector; /* count to get */
log_sector=logicalsector(track,1,head);
}
else if (tempu == 1) /* get rest of track */
tempu = (max_sector - sector) + 1;
if (log_sector == 0)
log_sector = num_sectors-1;
else
--log_sector;
if (Display)
output(' ');
for (i = 1 ; i <= (int)tempu ; i++)
{
if (kbhit())
break;
if (Display)
{
pn(i,Radix);
put(len(i),8);
}
if ((tempd=nextsector()) != DISK_OK)
{
savecursor();
if (!Display)
output(' ');
printerror(Debug);
if (!getver("continue",0))
{
put(3,8);
break;
}
restcursor();
clreol();
}
if ((byte_cnt+sec_size)>max_bytes)
break;
memcpy(data_buf+byte_cnt,sec_buf,sec_size);
if ((byte_cnt+=sec_size)==max_bytes)
{
print(bufferfull);
break;
}
}
if (Display && tempd == DISK_OK)
clreol();
if (Get || c=='G'-'@')
nextsector();
else
{
restoresector();
readsector();
disk_moved = 0;
}
break;
/* **** Log Drive **** */
case 'l':
case 'L'-'@':
if (c == 'l')
{
if (Display)
print(" disk ");
c = input();
if (!isalpha(c))
break;
tempd = toupper(c)-'@';
if (drives[tempd]!=TRUE)
break;
output(toupper(c));
output(':');
if (Verify)
{
if (!getver("log disk",MOV_YN))
break;
}
}
else
tempd = disk;
if (newdisk(tempd))
{
disk = tempd;
if (avail_clusters == 0)
avail_clusters = get_avail_clusters();
dparams(curdir);
}
if (error.num != -1) /* if theres gonna be an error */
{
if (disk_moved == 1)
{
output('\n'); /* put it on a new line */
output('\n');
} /* if its bad BOOT, reset diskio flag */
if (strcmp(error.func,"diskio") == 0)
diskio_error = 0;
}
break;
/* **** Misc. **** */
case 'T':
for (i=1;i<10;i++)
if (tagged[i]!=0L)
break;
if (i<10)
{
if (Display)
print(" tagged sector list");
for (i=1;i<10;i++)
{
if (!tagged[i])
continue;
output(' ');
output(i+'0');
output(':');
pln(tagged[i],Radix);
}
}
else if (Display)
print(" no tagged sectors");
break;
case 't':
if (Display)
print(" number of this tag? ");
if ((c=input()) < '0' || c > '9')
break;
output(c);
if (c == '0')
{
if (getver(" clear all",0))
memset(tagged,0,sizeof(tagged));
break;
}
tagged[c-'0']=log_sector;
break;
case 'f':
case '\\':
if (Display)
print(" find ");
tempd = find(F_DISK,1,(c=='f') ? F_CASE : F_NOCASE);
if (tempd>=0)
{
print("\nfound at ");
pn(tempd,Radix);
}
if (tempd!=ABORT) /* user pressed ESC */
readsector();
break;
case 'F':
case 'F'-'@':
if (byte_cnt==0)
break;
if (Display)
print(" find ");
if (find(F_BUFFER,1,(c=='F') ? F_CASE : F_NOCASE) == -1)
print(" not found");
break;
case 'P':
if (Display)
print(" put");
templ=log_sector;
temps=0; /* templ=from, temps=number */
if (!getl(ps,&templ,(int *)&temps))
break;
if (templ+(long)temps > (long)num_sectors)
break;
if (Display)
print(" file: ");
else
output(':');
if (getstr(tmpstr,64,_ALPHA) > 0)
{
if (Verify)
{
if (!getver(" put file",MOV_YN))
break;
}
if (exist(tmpstr))
{
savecursor();
if (!Verify)
output(' ');
if (!getver("exists, overwrite",MOV_YN))
break;
restcursor();
clreol();
}
if (error.num == -1)
{
if (Display && !Verify)
output(' ');
else if (Display && Verify)
{
put(3,' ');
put(3,8);
}
putsectors(tmpstr,templ,temps);
readsector();
}
}
break;
case 'P'-'@':
case 'p':
if (byte_cnt==0)
break;
if (Display)
print(" file: ");
getstr(tmpstr,64,_ALPHA);
if (!tmpstr[0])
break;
if (Verify)
{
print(" put file ");
if (Display && c=='p')
print("w/options");
else if (Display)
print("w/o options");
if (!getver("",MOV_YN))
break;
}
if (access(tmpstr,0) == 0)
{
savecursor();
if (!Verify)
output(' ');
if (!getver("exists, overwrite",MOV_YN))
break;
restcursor();
clreol();
if (unlink(tmpstr) == -1)
break;
}
if (error.num != -1)
break;
if (Display)
{
savecursor();
if (!Verify)
output(' ');
print("putting");
restcursor();
}
putfile(tmpstr,(c=='p') ? XLATE : NOXLATE,Mask,Strip,Convert);
break;
case 'I'-'@':
case 'i':
if (byte_cnt==max_bytes)
break;
if (Display)
print(" file: ");
getstr(tmpstr,64,_ALPHA);
if (!tmpstr[0])
break;
if (Verify)
{
print(" insert file ");
if (Display && c=='i')
print("w/options");
else if (Display)
print("w/o options");
if (!getver("",MOV_YN))
break;
}
if (Display)
{
savecursor();
if (!Verify)
output(' ');
print("inserting");
restcursor();
}
tempd=getfile(tmpstr, (c=='i') ? XLATE : NOXLATE,Mask,Strip,Convert);
if (tempd == -2)
{
if (!Verify)
output(' ');
print("buffer full ");
}
break;
case 'w':
if (!write_to || !Write)
{
print(" write not enabled");
break;
}
if (Display || Verify)
print(" write sector");
if (log_sector<dir_sector)
{
print("\a Warning! This is ");
print((log_sector==0)?"the BOOT":"a FAT");
print(" sector, ");
if (!getver("write anyway",0))
break;
}
else if (Verify && !getver("",0))
break;
writesector();
break;
case 'z':
case 'Z':
if (Display || c=='Z')
{
if (Display)
print(" parameters");
dkey(kw);
if (c=='z')
output('\n');
else
break;
}
if (getstr(tmpstr,MAXSTR,_LOWER|_UPPER)>0)
ckey(tmpstr,kw);
break;
case '0':case '1':case '2':case '3':
case '4':case '5':case '6':case '7':
case '8':case '9':
c-=0x30;
if (!tagged[c])
break;
if (Display || Verify)
{
print(" goto sector ");
pln(tagged[c],Radix);
}
if (Verify && !getver("",0))
break;
if (log_sector != tagged[c])
{
log_sector = tagged[c];
readsector();
disk_moved = 1;
}
break;
case ',': /* toggle radix */
if (Radix==10)
Radix=16;
else
Radix=10;
if (Display)
{
print(" radix is now ");
print((Radix==16)?"hex":"dec");
}
break;
case 'D':
if (Debug)
debug();
break;
case 'm':
if (!Files)
break;
tempu = sectortocluster(log_sector);
if (clusters[tempu] > 0 && (unsigned)clusters[tempu] <= n_files)
{
if (Display)
print(" map file ");
print(gfile(clusters[tempu]));
output('\n');
arraymap(clusters,num_clusters,clusters[tempu],Radix);
}
break;
case 'M':
if (Files)
{
if (Display)
print(" map free space");
output('\n');
if (arraymap(clusters,num_clusters,0,Radix) == 0)
print(" no free space");
}
break;
case 'I':
if (!Files)
break;
tempd = sectortocluster(log_sector);
if (clusters[tempd] < 0 || clusters[tempd] > (int)n_files)
break;
if (files[clusters[tempd]].dir)
{
print(" can not insert directories");
break;
}
sprintf(tmpstr,gfile(clusters[tempd]));
if (Display)
{
print(" insert file ");
print(tmpstr);
}
if (Verify)
{
if (!getver("",0))
break;
}
if (Display)
{
savecursor();
if (!Verify)
output(' ');
print("inserting");
restcursor();
}
if (getfile(tmpstr,XLATE,Mask,Strip,Convert) == -2)
{
if (!Verify)
output(' ');
print("buffer full ");
}
break;
case 'Y'-'@':
if (Display && !Verify)
print(" saving");
else if (Verify && !getver(" save",0))
break;
saveinit(savfile);
break;
case 'Y':
if (Display && !Verify)
print(" restoring");
else if (Verify && !getver(" restore",0))
break;
tempd = Home;
Home = FALSE;
tempt = disk;
templ = log_sector;
if (getinit(savfile,INIT_RESTORE))
{
if (tempt != disk)
{
if (!newdisk(disk))
{
disk = tempt;
log_sector = templ;
}
}
else if ((unsigned long)templ != log_sector)
readsector();
else if (Display)
output('\n');
disk_moved = 1;
}
else
{
disk = tempt;
log_sector = tempu;
}
Home = tempd;
break;
case 'x':
viewfile(inifile,Display);
break;
case 'y':
getinit(savfile,INIT_VIEW);
break;
case 'q':
case '.':
case ESC:
case ALTX:
if (Display || Verify)
print(" exit DISKED");
if (c != ALTX && Verify && !getver("",0))
break;
_dos_setdrive(cdisk,&tempu);
if (ccurdir[0])
_chdir(ccurdir);
if (Save && c != ALTX)
{
if (Verify)
if (!getver(" save",1))
break;
if (Display)
print(" saving...");
saveinit(savfile);
}
if (files_indexed) /* free calls are for an IDE */
{ /* such as QuickC that I use */
hugefreep(files); /* which can get confused if */
hugefreep(clusters); /* if you don't do this */
}
if (spare_sec)
freep(spare_sec);
if (save_sec)
freep(save_sec);
freep(sec_buf);
freep(data_buf);
exit(0);
break;
default:
break;
}
}
}