/************************************************************************

	Directory Utility VI		By Greg Cunningham
	my study of of AmigaDOS
	2-May-87			Code Size 35456

	Lattice 3.10-> | BLink | LC1 -cs | LC2 -v 
	Manx -> SubMain should work as is.

*************************************************************************/

#include <exec/types.h>
#include <intuition/intuition.h>
#include <libraries/dosextens.h>

#define MEMF_PUBLIC	(1<<0) /* Memory Types defs */
#define MEMF_CHIP	(1<<1)
#define MEMF_FAST	(1<<2)
#define MEMF_CLEAR	(1<<16)

#define	NAME		"Directory Utility VI      By Greg Cunningham"
#define CONFILE 	"Devs:DU.Config" /* Configure filename */
#define ESC		0x1b
#define FBSIZE		(long)(sizeof (struct FileInfoBlock))
#define MAXCHAR		30	/* Buffers & Filename diplay size */
#define MAXCD		80	/* More Buffer sizes */
#define MAXFILE		300	/* DirTable Max & command,command2 buf size */
#define WIDTH		316	/* A&BWindow Width */
#define HEIGHT		133	/* A&BWindow Height & Window top */

#define ASLIDE_GADGET	0	/* AWindow Gad */
#define BSLIDE_GADGET	1	/* BWindow Gad */

#define ERR_GADGET	2	/* Window Gads */
#define ADIR_GADGET	4
#define BDIR_GADGET	5

#define DF0_GADGET	6	/* Window Button Gads */
#define DF2_GADGET	7
#define GETDIR_GADGET	8
#define ALL_GADGET	9
#define FREE_GADGET	10
#define COPY_GADGET	11
#define RENAME_GADGET	12
#define READ_GADGET	13
#define PRINT_GADGET	14
#define ARC_GADGET	15
#define DF1_GADGET	16
#define DH0_GADGET	17
#define PARENT_GADGET	18
#define CLEAR_GADGET	19
#define BYTE_GADGET	20
#define MOVE_GADGET	21
#define LOCK_GADGET	22
#define CONFIG_GADGET	23
#define SHOW_GADGET	24
#define DEARC_GADGET	25
#define RAM_GADGET	26
#define VD0_GADGET	27
#define MAKEDIR_GADGET	28
#define COMMENT_GADGET	29
#define RUN_GADGET	30
#define DELETE_GADGET	31
#define UNLOCK_GADGET	32
#define EDIT_GADGET	33
#define COMMAND_GADGET	34
#define LISTARC_GADGET	35

#define FALSE_BUTT	50	/* Requester Gads */
#define TRUE_BUTT	51
#define REQSTR_GADGET	52

#define BUT_FIRST	DF0_GADGET
#define FIRST_GADGET	But_gad[LISTARC_GADGET - DF0_GADGET]
#define BUT_LAST	LISTARC_GADGET
#define GADFLAGS	NULL,5,5,56,8,GADGHCOMP|GADGHBOX,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,(APTR)&BUT_BORDER,NULL,NULL,NULL,NULL

/*	A&B Window IDCMP Flags */
#define WinIDCMP	CLOSEWINDOW|REFRESHWINDOW|GADGETUP|MOUSEBUTTONS|ACTIVEWINDOW

#define GADTEXT 	3,2,JAM2,0,0,NULL

char	err_buf[MAXCD+1],A_buf[MAXCD+1],B_buf[MAXCD+1],file_name[MAXCHAR+8],
	*argv[MAXCHAR+8],req_buf[MAXCD+1],REQ_COMMENT[MAXCD+1],title[MAXCD],
	COMMAND[MAXCHAR]= "NewCLI",
	SHOW[MAXCHAR] = "Show",
	ARCX[MAXCHAR] = "Arc x",
	ARCL[MAXCHAR] = "Arc v",
	EDITOR[MAXCHAR]="E -f",
	PRINT[MAXCHAR] ="Print",
	window[MAXCHAR] ="CON:0/134/640/66/";

/* Button border */
USHORT but_pairs[] = {0,0, 57,0, 57,9, 0,9, 0,0};
struct Border BUT_BORDER = {-1,-1,1,1,JAM1,5,(APTR)&but_pairs,NULL};

/* Source,Destination Border */
USHORT str_pairs[] = {-1,0, -1,9, -10,9, -10,0, 291,0, 291,9, -1,9};
struct Border str_border = {-1,-1,1,1,JAM1,7,(APTR)&str_pairs,NULL};

/* Current Dir Info */
struct IntuiText Adir_text = {1,2,JAM2,-10,0,NULL,"A",NULL};
struct StringInfo Adir_str={&A_buf,NULL,0,MAXCD+1,0,0,0,0,2,0,NULL,0,NULL};

/* Destination Dir Info */
struct IntuiText Bdir_text = {1,2,JAM2,-10,0,NULL,"B",NULL};
struct StringInfo Bdir_str ={&B_buf,NULL,0,MAXCD+1,0,0,0,0,2,0,NULL,0,NULL};

/* Error Info*/
struct StringInfo err_str = {&err_buf,NULL,0,MAXCD+1,0,0,0,0,2,0,NULL,0,NULL};

/* File Text Info */
struct IntuiText file_text = {2,0,JAM2,3,12,NULL,(UBYTE *)file_name,NULL};

/* Requester Comment Info */
struct StringInfo req_str ={&req_buf,NULL,0,MAXCD+1,0,0,0,0,2,0,NULL,0,NULL};
struct IntuiText ReqText = {3,0,JAM2,2,2,NULL,REQ_COMMENT,0};

/* Requester String Box */
USHORT reqstr_pairs[] = { 0,0, 236,0, 236,9, 0,9, 0,0};
struct Border reqstr_border = {-1,-1,1,1,JAM1,5,(APTR)&reqstr_pairs,NULL};

/* Requester Border */
SHORT ReqPairs[] = {0,0, 246,0, 246,44, 0,44, 0,0};
struct Border req_border={0,0,3,3,JAM2,5,(SHORT *)ReqPairs,NULL};

struct IntuiText TRUEtext ={GADTEXT," DO IT ",NULL};
struct IntuiText FALSEtext={GADTEXT,"NO WAY!",NULL};

struct Gadget falsebut =
{
	NULL,
	184,34,56,8,
	GADGHCOMP|GADGHBOX,GADGIMMEDIATE|RELVERIFY,
	BOOLGADGET|REQGADGET,
	(APTR)&BUT_BORDER,
	NULL,
	&FALSEtext,NULL,NULL,
	FALSE_BUTT,NULL
};
struct Gadget truebut =
{
	&falsebut,
	6,34,56,8,
	GADGHCOMP|GADGHBOX,GADGIMMEDIATE|RELVERIFY,
	BOOLGADGET|REQGADGET,
	(APTR)&BUT_BORDER,
	NULL,
	&TRUEtext,NULL,NULL,
	TRUE_BUTT,NULL
};
struct Gadget Reqstr_gad =
{
	&truebut,
	6,20,234,9,
	GADGHCOMP,GADGIMMEDIATE|RELVERIFY,
	STRGADGET|REQGADGET,
	(APTR) &reqstr_border,
	NULL,NULL,0,&req_str,
	REQSTR_GADGET,NULL
};
struct Requester req =
{
	NULL,
	40,14,247,46,
	0,0,
	&Reqstr_gad,
	&req_border,
	&ReqText,
	NULL,0,NULL,{NULL},
	{NULL},NULL,{NULL}
};
struct Gadget Err_gad =
{
	NULL,
	2,-8,600,9,
	GADGHCOMP|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY|STRINGCENTER,
	STRGADGET,NULL,NULL,NULL,NULL,
	&err_str,ERR_GADGET,NULL
};
struct Gadget Adir_gad =
{
	&Err_gad,
	15,-18,290,9,
	GADGHCOMP|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,
	STRGADGET,
	(APTR) &str_border,
	NULL,&Adir_text,0,&Adir_str,
	ADIR_GADGET,
	NULL,
};
struct Gadget Bdir_gad =
{
	&Adir_gad,
	320,-18,290,9,
	GADGHCOMP|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,
	STRGADGET,
	(APTR) &str_border,
	NULL,&Bdir_text,0,&Bdir_str,
	BDIR_GADGET,
	NULL,
};

/*Slide Gadget AWindow */
struct Image Aslide_img;
struct PropInfo Aslide_prop;
struct Gadget ASlide_gad ={
	NULL,
	-15,10,16,-18,	/* Left, Top edge, Width, Height*/
	GRELRIGHT|GRELHEIGHT|GADGHNONE,GADGIMMEDIATE|RELVERIFY,
	PROPGADGET,
	(APTR)&Aslide_img,/*Border definition*/
	NULL,NULL,0,
	(APTR) &Aslide_prop,
	ASLIDE_GADGET,
	NULL,
};

/*Slide Gadget BWindow */
struct Image Bslide_img;
struct PropInfo Bslide_prop;
struct Gadget BSlide_gad ={
	NULL,
	-15,10,16,-18,	/* Left, Top edge, Width, Height*/
	GRELRIGHT|GRELHEIGHT|GADGHNONE,GADGIMMEDIATE|RELVERIFY,
	PROPGADGET,
	(APTR)&Bslide_img,/*Border definition*/
	NULL,NULL,0,
	(APTR) &Bslide_prop,
	BSLIDE_GADGET,
	NULL,
};
/*
| DF0:  | DF2:  |GET DIR|  ALL  | FREE  | COPY  |RENAME | READ  | SHOW  |  ARC
| DF1:  | DH0:  |PARENT | CLEAR | BYTE  | MOVE  | LOCK  | EDIT  |COMMAND|DE-ARC 
| RAM:  | VD0:  |MAKEDIR|COMMENT|  RUN  |DELETE |UNLOCK | PRINT |CONFIG |LISTARC

Button Gadget Text,IDs */

struct IntuiText But_text[] =
{
	GADTEXT," DF0:  ",NULL,
	GADTEXT," DF2:  ",NULL,
	GADTEXT,"GET DIR",NULL,
	GADTEXT,"  ALL  ",NULL,
	GADTEXT," FREE  ",NULL,
	GADTEXT," COPY  ",NULL,
	GADTEXT,"RENAME ",NULL,
	GADTEXT," READ  ",NULL,
	GADTEXT," SHOW  ",NULL,
	GADTEXT,"  ARC  ",NULL,
	GADTEXT," DF1:  ",NULL,
	GADTEXT," DH0:  ",NULL,
	GADTEXT,"PARENT ",NULL,
	GADTEXT," CLEAR ",NULL,
	GADTEXT," BYTE  ",NULL,
	GADTEXT," MOVE  ",NULL,
	GADTEXT," LOCK  ",NULL,
	GADTEXT," EDIT  ",NULL,
	GADTEXT,"COMMAND",NULL,
	GADTEXT,"DE-ARC ",NULL,
	GADTEXT," RAM:  ",NULL,
	GADTEXT," VD0:  ",NULL,
	GADTEXT,"MAKEDIR",NULL,
	GADTEXT,"COMMENT",NULL,
	GADTEXT,"  RUN  ",NULL,
	GADTEXT,"DELETE ",NULL,
	GADTEXT,"UNLOCK ",NULL,
	GADTEXT," PRINT ",NULL,
	GADTEXT,"CONFIG ",NULL,
	GADTEXT,"LISTARC",NULL,
};

struct Gadget But_gad[] =
{
	GADFLAGS,DF0_GADGET,NULL,
	GADFLAGS,DF2_GADGET,NULL,
	GADFLAGS,GETDIR_GADGET,NULL,
	GADFLAGS,ALL_GADGET,NULL,
	GADFLAGS,FREE_GADGET,NULL,
	GADFLAGS,COPY_GADGET,NULL,
	GADFLAGS,RENAME_GADGET,NULL,
	GADFLAGS,READ_GADGET,NULL,
	GADFLAGS,SHOW_GADGET,NULL,
	GADFLAGS,ARC_GADGET,NULL,
	GADFLAGS,DF1_GADGET,NULL,
	GADFLAGS,DH0_GADGET,NULL,
	GADFLAGS,PARENT_GADGET,NULL,
	GADFLAGS,CLEAR_GADGET,NULL,
	GADFLAGS,BYTE_GADGET,NULL,
	GADFLAGS,MOVE_GADGET,NULL,
	GADFLAGS,LOCK_GADGET,NULL,
	GADFLAGS,EDIT_GADGET,NULL,
	GADFLAGS,COMMAND_GADGET,NULL,
	GADFLAGS,DEARC_GADGET,NULL,
	GADFLAGS,RAM_GADGET,NULL,
	GADFLAGS,VD0_GADGET,NULL,
	GADFLAGS,MAKEDIR_GADGET,NULL,
/* TOGGLE 'COMMENT' GAD */
	NULL,5,5,56,8,GADGHCOMP|GADGHBOX,GADGIMMEDIATE|RELVERIFY|TOGGLESELECT,
	BOOLGADGET,(APTR)&BUT_BORDER,
	NULL,NULL,NULL,NULL,COMMENT_GADGET,NULL,

	GADFLAGS,RUN_GADGET,NULL,
	GADFLAGS,DELETE_GADGET,NULL,
	GADFLAGS,UNLOCK_GADGET,NULL,
	GADFLAGS,PRINT_GADGET,NULL,
	GADFLAGS,CONFIG_GADGET,NULL,
	GADFLAGS,LISTARC_GADGET,NULL,
};

/* Window structures */

struct NewWindow Duw =
{
	12,HEIGHT,
	615,64,
	0,1,
	CLOSEWINDOW|REFRESHWINDOW|GADGETUP|REQCLEAR,
	WINDOWSIZING|WINDOWDEPTH|WINDOWDRAG|WINDOWCLOSE
		|ACTIVATE|RMBTRAP|SMART_REFRESH,
	&FIRST_GADGET,
	NULL,
	NULL,/* title */
	NULL,
	NULL,
	260,64,615,64,
	WBENCHSCREEN,
};
struct NewWindow Aw =
{
	0,0,
	WIDTH,HEIGHT,
	0,1,
	WinIDCMP,
	WINDOWSIZING|WINDOWDEPTH|WINDOWDRAG|ACTIVATE|RMBTRAP|SIMPLE_REFRESH,
	&ASlide_gad,
	NULL,
	"A",
	NULL,
	NULL,
	WIDTH,20,WIDTH,400,
	WBENCHSCREEN,
};
struct NewWindow Bw =
{
	324,0,
	WIDTH,HEIGHT,
	0,1,
	WinIDCMP,
	WINDOWSIZING|WINDOWDEPTH|WINDOWDRAG|ACTIVATE|RMBTRAP|SIMPLE_REFRESH,
	&BSlide_gad,
	NULL,
	"B",
	NULL,
	NULL,
	WIDTH,20,WIDTH,400,
	WBENCHSCREEN,
};

/*Directory Table data*/
struct DirTable
{
	char  dt_fname[MAXCHAR];
	char  dt_comment[MAXCHAR*2];
	short dt_select;
	short dt_dir;
	long  dt_size;
};

extern APTR AllocMem();
struct GfxBase		*GfxBase;
struct Gadget		*igad;
struct IntuitionBase	*IntuitionBase;
struct Window		*Window,*AWindow,*BWindow;
struct DirTable 	Atable[MAXFILE],Btable[MAXFILE];/*  *CurTable */
struct InfoData 	*InfoData;
struct FileLock 	*InitDirLock,*CurrentDirLock,*fl,*oldlock;
struct IntuiMessage	*Msg,*GetMsg();

LONG	bytes,len2,MAXANAME,MAXBNAME;
ULONG	avail1,avail2,avail3,MessageClass,AvailMem();
USHORT	code;
int	argc,files,numdirA,numdirB,numdirT,cur_indexA,cur_indexB,linecount,
	done,COMMENTMODE=FALSE,REQ=FALSE,dirflag=FALSE,_fmode;
unsigned int index;
unsigned char buffer[80],buf[512],blank[37] = "                                    ";
char	curdir[MAXCD+1],requestedcd[MAXCD+1],command[MAXFILE],
	command2[MAXFILE],r1[2];

void	copy(),new_dir(),sel_A(),sel_B(),par_dir(),DoHex(),
	Hprint_to_screen(),Print_to_screen(),MyDone(),
	WaitSpace(),MyClose();

/******** CUSTOM SubMain SETUP -FILEHANDLE ************************* TxEd 400 */

#define stdin  (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])

struct _iobuf
{
struct _iobuf *_next;
unsigned char *_ptr;
int _rcnt;
int _wcnt;
unsigned char *_base;
int _size;
int _flag;
int _file;
unsigned char _cbuff;
};

extern struct _iobuf _iob[20];

struct UFB{ int ufbflg;
	    int ufbfh; };

struct FileHandle	*w = NULL,*workfp = NULL,*Open(),*handle;
static struct Process	*process,*FindTask();
extern struct UFB	_ufbs[],*chkufb(int);
_main(line)
char *line;
{
int x;
 while(argc<32){ /* Process Args */
	line++;
	if(*line == '\0') break;
	argv[argc++] = line;
	while((*line != '\0')&&(!isspace(*line))) line++;
	if(*line == '\0') break;
	else *line++ = '\0';
 }
/* Read Config file, if it's there */
 if(fl=Lock(CONFILE,ACCESS_READ)){
   UnLock(fl);
   if(workfp = Open(CONFILE,MODE_OLDFILE)){
	Read(workfp,SHOW,   MAXCHAR);
	Read(workfp,COMMAND,MAXCHAR);
	Read(workfp,ARCX,   MAXCHAR);
	Read(workfp,ARCL,   MAXCHAR);
	Read(workfp,EDITOR, MAXCHAR);
	Read(workfp,PRINT,  MAXCHAR);
	Close(workfp);
	}
}

if(argc==0)	/* Running Under WorkBench  */
	{
	_ufbs[0].ufbfh = Open(window,MODE_NEWFILE);
	_ufbs[1].ufbfh = _ufbs[0].ufbfh;
	_ufbs[1].ufbflg= 4;
	_ufbs[2].ufbfh = _ufbs[0].ufbfh;
	_ufbs[2].ufbflg= 4;
	handle=(struct FileHandle *)(_ufbs[0].ufbfh << 2);
	process=FindTask(0);
	process->pr_ConsoleTask = handle->fh_Type;
	x=0;
	}
else		/* Running Under CLI  */
	{
	_ufbs[0].ufbfh=Input();
	_ufbs[1].ufbfh=Output();
	_ufbs[2].ufbfh=Open("*",MODE_OLDFILE);
	x=4;
	}

_ufbs[0].ufbflg|=1|0x8000|x;
_ufbs[1].ufbflg|=2|0x8000|x;
_ufbs[2].ufbflg|=1|2|0x8000;

x=(_fmode)?0:0x8000;
stdin->_file= _ufbs[0].ufbfh;
stdin->_flag= 1|x;
stdout->_file=_ufbs[1].ufbfh;
stdout->_flag=2|x;
stderr->_file=_ufbs[2].ufbfh;
stderr->_flag=128|x;
/************************ END OF SubMain *************************************/

main(argc,argv);
_exit(0);
}

/*	Where it starts						     TxEd 466 */
main()
{
 register i;
 struct Gadget		*gad_ptr;
 struct IntuiText	*text_ptr;

/* Initialize */
 strcpy(curdir,"SYS:");
 CurrentDirLock = Lock(curdir,ACCESS_READ);
 InitDirLock = CurrentDir(CurrentDirLock);

 Aslide_prop.Flags = FREEVERT|AUTOKNOB;
 Aslide_prop.VertBody=0;
 Aslide_prop.VertPot =0x8000;

 Bslide_prop.Flags = FREEVERT|AUTOKNOB;
 Bslide_prop.VertBody=0;
 Bslide_prop.VertPot =0x8000;

 /*Setup the button gadgets*/
 for (i=0;i<(BUT_LAST-BUT_FIRST)+1;i++){
	gad_ptr=&But_gad[i];
	text_ptr=&But_text[i];
	gad_ptr->LeftEdge=((i%10)*61)+5;
	gad_ptr->TopEdge=((i/10)*11)+12;
	if(i)gad_ptr->NextGadget=&But_gad[i-1];
	else gad_ptr->NextGadget=&Bdir_gad;
	gad_ptr->GadgetText=text_ptr;
	text_ptr->LeftEdge=0;
	text_ptr->TopEdge=0;
 }
 GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0);
 if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0))==NULL)
	close_things();
 if((AWindow=(struct Window *)OpenWindow(&Aw))==NULL)
	close_things();
 if((BWindow=(struct Window *)OpenWindow(&Bw))==NULL)		  /* TxEd 500 */
	close_things();
 if((Window=(struct Window *)OpenWindow(&Duw))==NULL)
	close_things();

 RefreshGadgets(&FIRST_GADGET,Window,NULL);
 RefreshGadgets(&ASlide_gad,AWindow,NULL);
 RefreshGadgets(&BSlide_gad,BWindow,NULL);

 MAXANAME=(AWindow->Height-12)/8;
 MAXBNAME=(BWindow->Height-12)/8;
 new_dir();
 dirflag=TRUE; /* TRUE = B Window is in use */
 new_dir();
 dirflag=FALSE;

/* Intuimessage process */
 for(;;){
	display_mem();
	while(Msg=GetMsg(BWindow->UserPort)){
		MessageClass = Msg->Class;
		code = Msg->Code;
		ReplyMsg(Msg);
		switch(MessageClass){
			case GADGETUP:
				do_gadgets(Msg);
				break;
			case REFRESHWINDOW:
				ModifyIDCMP(BWindow,0);
				RefreshGadgets(&BSlide_gad,BWindow,NULL);
				MAXBNAME=(BWindow->Height-12)/8;
				if(!dirflag){
					dirflag=TRUE;
					new_dir();
					dirflag=FALSE;
				}else new_dir();
				ModifyIDCMP(BWindow,WinIDCMP);
				break;
			case MOUSEBUTTONS:
				dirflag=TRUE;
				if(code==SELECTDOWN) sel_B();
				break;
			case ACTIVEWINDOW:
				dirflag=TRUE;
				break;
			default:
				break;
		}
		highlight();
	}
	while((Msg=GetMsg(Window->UserPort))||(Msg=GetMsg(AWindow->UserPort))){
		MessageClass = Msg->Class;
		code = Msg->Code;
		ReplyMsg(Msg);
		switch(MessageClass){
			case GADGETUP:
				do_gadgets(Msg);
				break;
			case REFRESHWINDOW:
				ModifyIDCMP(AWindow,0);
				BeginRefresh(Window); EndRefresh(Window);
				RefreshGadgets(&ASlide_gad,AWindow,NULL);
				MAXANAME=(AWindow->Height-12)/8;
				if(dirflag){
					dirflag=FALSE;
					new_dir();
					dirflag=TRUE;
				}else new_dir();
				ModifyIDCMP(AWindow,WinIDCMP);
				break;
			case CLOSEWINDOW:
				close_things();
				break;
			case MOUSEBUTTONS:
				dirflag=FALSE;
				if(code==SELECTDOWN) sel_A();
				break;
			case ACTIVEWINDOW:
				dirflag=FALSE;
				break;
			default:
				break;
		}
		highlight();
	}
 }/*end forever*/
}/* end of life itself */

display_mem()	/* RAM Display */
{
	avail1=AvailMem(MEMF_CHIP);
	avail2=AvailMem(MEMF_FAST);
	if(avail1+avail2!=avail3){
	 sprintf(title,"%s          RAM: %-7ld",NAME,avail1+avail2);
	 SetWindowTitles(Window,title,NAME);
	 avail3=avail1+avail2;
	}
	Delay(10); /* save the CPU */
	return(0);
}

highlight()	/* Highlight A or B box 			     TxEd 600 */
{
	if(dirflag){
		Adir_text.BackPen=2;
		Bdir_text.BackPen=3;
		}
	else{	Adir_text.BackPen=3;
		Bdir_text.BackPen=2;
		}
	RefreshGadgets(&Adir_gad,Window,NULL);
	RefreshGadgets(&Bdir_gad,Window,NULL);
	return(0);
}

BytesFree(dir)	/* Disk free mem */
char *dir;
{
InfoData = AllocMem(sizeof(struct InfoData),0);
fl = Lock(dir,ACCESS_READ);
Info(fl,InfoData);
avail3=(((InfoData->id_NumBlocks-InfoData->id_NumBlocksUsed-2)<=0)?0:
 ((InfoData->id_NumBlocks-InfoData->id_NumBlocksUsed-2)*InfoData->id_BytesPerBlock));
FreeMem(InfoData,sizeof(struct InfoData));
UnLock(fl);
return(0);
}

do_gadgets(mes)
struct IntuiMessage *mes;
{
	struct FileLock *MakeDirLock;
	unsigned short i;
	int gadgid;

	igad=(struct Gadget *) mes->IAddress;
	gadgid=igad->GadgetID;
	switch (gadgid) {
		case ADIR_GADGET:
			ModifyIDCMP(AWindow,0);
			nullterm(A_buf,MAXCD);
			Adir_str.NumChars =strlen(A_buf);
			Adir_str.BufferPos=strlen(A_buf);
			dirflag=FALSE;
			highlight();
			getdir(A_buf);
			new_dir();
			ModifyIDCMP(AWindow,WinIDCMP);
			break;
		case BDIR_GADGET:
			ModifyIDCMP(BWindow,0);
			nullterm(B_buf,MAXCD);
			Bdir_str.NumChars =strlen(B_buf);
			Bdir_str.BufferPos=strlen(B_buf);
			dirflag=TRUE;
			highlight();
			getdir(B_buf);
			new_dir();
			ModifyIDCMP(BWindow,WinIDCMP);
			break;
		case ASLIDE_GADGET:
			dirflag=FALSE;
			rdis_files();
			break;
		case BSLIDE_GADGET:
			dirflag=TRUE;
			rdis_files();
			break;
		case PARENT_GADGET:
			par_dir();
			break;
		case COMMENT_GADGET:
			if(COMMENTMODE) COMMENTMODE=FALSE;
			else COMMENTMODE=TRUE;	/* Toggle insurance */
		case DEARC_GADGET:
		case LISTARC_GADGET:
		case ARC_GADGET:
		case SHOW_GADGET:
		case EDIT_GADGET:
		case COPY_GADGET:
		case RUN_GADGET:
		case DELETE_GADGET:
		case RENAME_GADGET:
		case READ_GADGET:
		case PRINT_GADGET:
		case MOVE_GADGET:
		case LOCK_GADGET:
		case UNLOCK_GADGET:
			action_on_selected(gadgid);
			break;
		case FREE_GADGET:
			if(dirflag) BytesFree(B_buf);
			else BytesFree(A_buf);
			sprintf(command,"%d Bytes free in this dievice",avail3);
			display_error(command,0);
			break;
		case BYTE_GADGET:
			bytes = 0;
			files = 0;
			if(dirflag){ for(i=0;i<numdirB;i++)
			  if((Btable[i].dt_select==1)&&(!(Btable[i].dt_dir))){
				bytes = bytes + Btable[i].dt_size;
				files++;}
			}
			else for(i=0;i<numdirA;i++)
			  if((Atable[i].dt_select==1)&&(!(Atable[i].dt_dir))){
				bytes = bytes + Atable[i].dt_size;
				files++;
			} 
			sprintf(command,"%d Bytes in %d Files",bytes,files);
			display_error(command,0);
			break;
		case MAKEDIR_GADGET:
			do_req("Enter Directory","");
			if(REQ){
			 if(dirflag) release_and_lock(B_buf);
			 else	release_and_lock(A_buf);
			 if(MakeDirLock = Lock(req_buf,ACCESS_READ)){
				UnLock(MakeDirLock);
				display_error("Dir or File Exists" ,IoErr());
				break;
			 } 
			 if(!(MakeDirLock = CreateDir(req_buf))){
				display_error("CreateDir Failed",IoErr());
				break;
			 }
			 UnLock(MakeDirLock);
			 if(dirflag) getdir(B_buf);
			 else getdir(A_buf);
			 new_dir();
			}
			break;
		case DF0_GADGET:
			getdir("DF0:"); new_dir(); break;
		case DF1_GADGET:
			getdir("DF1:"); new_dir(); break;
		case DF2_GADGET:
			getdir("DF2:"); new_dir(); break;
		case RAM_GADGET:
			getdir("RAM:"); new_dir(); break;
		case DH0_GADGET:
			getdir("DH0:"); new_dir(); break;
		case VD0_GADGET:
			getdir("VD0:"); new_dir(); break;
		case GETDIR_GADGET:
			getdir(requestedcd);
			new_dir();
			break;
		case CLEAR_GADGET:
			if(dirflag){
			 for(i=0;i<numdirB;i++) Btable[i].dt_select=0;
			 dis_files(cur_indexB);
			}else{
			 for(i=0;i<numdirA;i++) Atable[i].dt_select=0;
			 dis_files(cur_indexA);
			}
			break;
		case ALL_GADGET:
			if(dirflag){
			 for(i=0;i<numdirB;i++)
				if(!Btable[i].dt_dir) Btable[i].dt_select=1;
			 dis_files(cur_indexB);
			}else{
			 for(i=0;i<numdirA;i++)
				if(!Atable[i].dt_dir) Atable[i].dt_select=1;
			 dis_files(cur_indexA);
			}
			break;
		case COMMAND_GADGET:
			do_req("Command line to Execute.",COMMAND);
			strcpy(COMMAND,req_buf);
			if(REQ){
				sprintf(command,"Run %s",COMMAND);
				Execute(command,0,0);}
			break;
		case CONFIG_GADGET:
			save_config();
			break;
		default:
			break;
	}
	return(0);
}

/* Multi-file action loop					    TxEd 780 */
action_on_selected(gadgid)
int gadgid;
{
 struct IntuiMessage *message;
 register	i,i1,temp;
 char		filename[MAXCD+MAXCHAR+2];
 char		*ptr;
 ModifyIDCMP(AWindow,MOUSEBUTTONS);
 ModifyIDCMP(BWindow,MOUSEBUTTONS);
 ModifyIDCMP(Window,GADGETUP);
 if(dirflag) numdirT=numdirB;
 else numdirT=numdirA;

 for(i=0;i<numdirT;i++){
	if((gadgid!=SHOW_GADGET)&&(message=(struct IntuiMessage *)GetMsg(Window->UserPort))){
		ReplyMsg(message);
		display_error("Operation Aborted: Highlighted Files Remain",0);
		break;}
	if(dirflag){
	 if(Btable[i].dt_select){
		ptr=B_buf+strlen(B_buf)-1;
		if(*ptr==':') sprintf(filename,"%s%s",B_buf,Btable[i].dt_fname);
		else	     sprintf(filename,"%s/%s",B_buf,Btable[i].dt_fname);
		}else goto END;
	}else if(Atable[i].dt_select){
		ptr = A_buf+strlen(A_buf)-1;
		if(*ptr==':') sprintf(filename,"%s%s",A_buf,Atable[i].dt_fname);
		else	     sprintf(filename,"%s/%s",A_buf,Atable[i].dt_fname);
		}else goto END;
	switch(gadgid){
		case DELETE_GADGET:
			sprintf(command2,"Deleting %s",filename);
			display_error(command2,0);
			if(!(DeleteFile(filename)))display_error("Can't Delete",IoErr());
			else	if(dirflag) Btable[i].dt_select=2;
				else Atable[i].dt_select=2;
			break;
		case COPY_GADGET:
			if(dirflag) copy(filename,A_buf);
			else	    copy(filename,B_buf);
			break;
		case SHOW_GADGET:
			do_req("Command [file]",SHOW);
			strcpy(SHOW,req_buf);
			if(REQ){display_error("Now Showing selected pictures",0);
			 sprintf(command,"%s %s",SHOW,filename);
			 Execute(command,0,0);
			}
			break;
		case DEARC_GADGET:
			do_req("Command [file]",ARCX);
			strcpy(ARCX,req_buf);
			if(REQ){
				display_error("Wait....doing something",0);
				if(dirflag)sprintf(command,"CD %s\n %s %s",B_buf,req_buf,Btable[i].dt_fname);
				else	   sprintf(command,"CD %s\n %s %s",A_buf,req_buf,Atable[i].dt_fname);
				Execute(command,0,0);
			}
			break;
		case ARC_GADGET:
			display_error("Adding Files To Archive",0);
			do_req("Destination Archive","");
			if(REQ){strcpy(command,"");
			 if(dirflag){ for(i=0;i<numdirT;i++)
				if((Btable[i].dt_select)&&(!Btable[i].dt_dir)){
				 sprintf(command,"%s %s",command,Btable[i].dt_fname);
				 Btable[i].dt_select = 0;}
			  sprintf(command2,"CD %s\n Arc a %s %s",B_buf,req_buf,command);
			 }else{ for(i=0;i<numdirT;i++)
				 if((Atable[i].dt_select)&&(!Atable[i].dt_dir)){
				 sprintf(command,"%s %s",command,Atable[i].dt_fname);
				 Atable[i].dt_select = 0;}
			  sprintf(command2,"CD %s\n Arc a %s %s",A_buf,req_buf,command);
			  }
			 Execute(command2,0,0);
			}
			break;
		case LISTARC_GADGET:
			do_req("Command [file]",ARCL);
			strcpy(ARCL,req_buf);
			if(REQ){display_error("Wait....doing something",0);
				sprintf(command,"%s %s",ARCL,filename);
				Execute(command,0,0);}
			break;
		case RUN_GADGET:
			do_req("Argument for selected file","");
			if(REQ){sprintf(command,"Run %s %s",filename,req_buf);
				Execute(command,0,0);}
			break;
		case READ_GADGET:
			done=FALSE;
			if((workfp=Open(filename,MODE_OLDFILE))==NULL) done=TRUE;
			else{	sprintf(command,"raw:0/0/640/200/Reading file - %s",filename);
				if((w=Open(command,MODE_NEWFILE))==NULL) done=TRUE;
				}
			Read(workfp,buf,1);
			Seek(workfp,0,OFFSET_BEGINNING);
			/* Normal Excutable file ----  Info file,ect. ----  Archive = 26 */
			if(((buf[0]&0xf0)==NULL)||((buf[0]&0xf0)>=127))
				Hprint_to_screen(filename);
			else	Print_to_screen(filename);
			break;
		case EDIT_GADGET:
			do_req("Command [file]",EDITOR);
			strcpy(EDITOR,req_buf);
			if(REQ){display_error("Starting Text Editor",0);
				sprintf(command,"Run %s %s",EDITOR,filename);
				Execute(command,0,0);}
			break;
		case PRINT_GADGET:
			do_req("Command [file]",PRINT);
			strcpy(PRINT,req_buf);
			if((REQ)&&(!Atable[i].dt_dir)){
				 sprintf(command2,"%s %s",PRINT,filename);
				 Execute(command2,0,0);}
			break;
		case MOVE_GADGET:
			if(dirflag){
			 ptr=A_buf+strlen(A_buf)-1;
			 if(*ptr==':')sprintf(command,"%s%s",A_buf,Btable[i].dt_fname);
			 else sprintf(command,"%s/%s",A_buf,Btable[i].dt_fname);
			 sprintf(command2,"Moving %s to %s",filename,A_buf);
			}else{
			 ptr=B_buf+strlen(B_buf)-1;
			 if(*ptr==':')sprintf(command,"%s%s",B_buf,Atable[i].dt_fname);
			 else sprintf(command,"%s/%s",B_buf,Atable[i].dt_fname);
			 sprintf(command2,"Moving %s to %s",filename,B_buf);
			}
			display_error(command2,0);
			if(!(Rename(filename,command))) display_error("Can't move file",IoErr());
			else	if(dirflag)Btable[i].dt_select=2;
				else	   Atable[i].dt_select=2;
			break;
		case RENAME_GADGET:
			if(dirflag) do_req("Rename it to what?",Btable[i].dt_fname);
			else	    do_req("Rename it to what?",Atable[i].dt_fname);
			if((REQ)&&(!(Rename(filename,req_buf))))display_error("Can't Rename",IoErr());
			break;
		case LOCK_GADGET:
			SetProtection(filename,5);/* 0101 */
			sprintf(command2,"%s Locked: R-E-",filename);
			display_error(command2,0);
			break;
		case UNLOCK_GADGET:
			SetProtection(filename,0);  /* 0000 */
			sprintf(command2,"%s UnLocked: RWED",filename);
			display_error(command2,0);
			break;
		case COMMENT_GADGET:
			if(COMMENTMODE){
			 if(dirflag){
				sprintf(command2,"Comment for %s",Btable[i].dt_fname);
			 	do_req(command2,Btable[i].dt_comment);
			 }else{
				sprintf(command2,"Comment for %s",Atable[i].dt_fname);
			 	do_req(command2,Atable[i].dt_comment);
			 }
			 if(REQ){
				nullterm(req_buf,MAXCHAR*2);
				if(!(SetComment(filename,req_buf)))
					display_error("SetComment Failed",IoErr());
				else if(dirflag)strcpy(Btable[i].dt_comment,req_buf);
				     else	strcpy(Atable[i].dt_comment,req_buf);
			 }
			}
			break;
		default:
			break;
	} /* end of switch */

if((gadgid!=DELETE_GADGET)&&(gadgid!=MOVE_GADGET))
	if(dirflag) Btable[i].dt_select=0;
	else	Atable[i].dt_select=0;

END: /* goto END - will skip to next file */

 } /* end of multi-file loop */

if((RENAME_GADGET==gadgid)||(ARC_GADGET==gadgid)||(DEARC_GADGET==gadgid))
	if(dirflag) getdir(B_buf);
	else	getdir(A_buf);
else{
 if(dirflag){
 temp = numdirB;
 for (i1=0;i1<numdirB;i1++)
	if(Btable[i1].dt_select==2){
		strcpy(Btable[i1].dt_fname,"\xff\xff\xff");
		temp--;};
 if(numdirB!=temp)qsort(Btable,numdirB,(sizeof(struct DirTable)));
 numdirB = temp;
 }else{
 temp = numdirA;
 for (i1=0;i1<numdirA;i1++)
	if(Atable[i1].dt_select==2){
		strcpy(Atable[i1].dt_fname,"\xff\xff\xff");
		temp--;};
 if(numdirA!=temp)qsort(Atable,numdirA,(sizeof(struct DirTable)));
 numdirA = temp;
 }
};

if((gadgid==MOVE_GADGET)||(gadgid==COPY_GADGET)||
	((!strcmp(B_buf,A_buf))&&(gadgid==DELETE_GADGET))){
 if(dirflag){
	new_dir();
	dirflag=FALSE;
	getdir(A_buf);
 }else{ new_dir();
	dirflag=TRUE;
	getdir(B_buf);}
}
new_dir();
ModifyIDCMP(BWindow,WinIDCMP);
ModifyIDCMP(AWindow,WinIDCMP);	/* Modify everything */
ModifyIDCMP(Window,CLOSEWINDOW|REFRESHWINDOW|GADGETUP|REQCLEAR);
return(0);
}
								/* TxEd  1000*/
/* routines for dirs, file display, select */
getdir(DirToGet)
char *DirToGet;
{
	struct FileLock *filelock;
	struct FileInfoBlock *fb;
	char EffectiveDir[MAXCD+1];

	if(!(*DirToGet)) strcpy(EffectiveDir,":");
	else strcpy(EffectiveDir,DirToGet);

TRYAGAIN:
	if (!(filelock = Lock(EffectiveDir,ACCESS_READ))) {
		strcpy(EffectiveDir,curdir);
		display_error("Can't Get Directory",IoErr());
		if(!(filelock = Lock(EffectiveDir,ACCESS_READ))) {
			display_error("Can't Get Directory",IoErr());
			strcpy(EffectiveDir,"RAM:");
			goto TRYAGAIN;
		}
	}
	/*Allocate the file info block*/
	fb = AllocMem(FBSIZE,MEMF_CLEAR|MEMF_PUBLIC);
	if(!Examine(filelock,fb)){
		FreeMem(fb,FBSIZE);
		UnLock(filelock);
		display_error("Bad Info Block:",IoErr());
		strcpy(EffectiveDir,"RAM:");
		goto TRYAGAIN;
	}
	if(fb->fib_DirEntryType<0){
		strcpy(EffectiveDir,curdir);
		FreeMem(fb,FBSIZE);
		UnLock(filelock);
		display_error("That's no Directory",IoErr());
		goto TRYAGAIN;
	}
	strcpy(curdir,EffectiveDir);
	strcpy(requestedcd,EffectiveDir);
	if(dirflag){
	 strcpy(B_buf,EffectiveDir);
	 Bdir_str.NumChars =strlen(EffectiveDir);
	 Bdir_str.BufferPos=strlen(EffectiveDir);
	 SetWindowTitles(BWindow,B_buf,NAME);
	}else{
	 strcpy(A_buf,EffectiveDir);
	 Adir_str.NumChars =strlen(EffectiveDir);
	 Adir_str.BufferPos=strlen(EffectiveDir);
	 SetWindowTitles(AWindow,A_buf,NAME);
	}
	if(dirflag){
	 cur_indexB=0;
	 numdirB = 0;
	 while(ExNext(filelock,fb)){
		if(fb->fib_DirEntryType<0) Btable[numdirB].dt_dir=0;
		else Btable[numdirB].dt_dir= -1;
		Btable[numdirB].dt_select=0;
		Btable[numdirB].dt_size=fb->fib_Size;
		strcpy(Btable[numdirB].dt_fname,fb->fib_FileName);
		nullterm(Btable[numdirB].dt_fname,MAXCHAR);
		strcpy(Btable[numdirB].dt_comment,fb->fib_Comment);
		nullterm(Btable[numdirB].dt_comment,MAXCHAR*2);
		if(++numdirB == MAXFILE){
			break;}
	 }
	 qsort(Btable,numdirB,(sizeof (struct DirTable)));
	}else{
	 cur_indexA=0;
	 numdirA = 0;
	 while (ExNext(filelock,fb)) {
		if(fb->fib_DirEntryType < 0) Atable[numdirA].dt_dir = 0;
		else Atable[numdirA].dt_dir = -1;
		Atable[numdirA].dt_select=0;
		Atable[numdirA].dt_size=fb->fib_Size;
		strcpy(Atable[numdirA].dt_fname,fb->fib_FileName);
		nullterm(Atable[numdirA].dt_fname,MAXCHAR);
		strcpy(Atable[numdirA].dt_comment,fb->fib_Comment);
		nullterm(Atable[numdirA].dt_comment,MAXCHAR*2);
		if(++numdirA == MAXFILE){
			break;}
	 }
	 qsort(Atable,numdirA,(sizeof (struct DirTable)));
	}

	sprintf(command2,"%d Entries in A    %d Entries in B",numdirA,numdirB);
	display_error(command2,0);
	FreeMem(fb,FBSIZE);
	UnLock(filelock);	/*Release new request lock*/
	release_and_lock(EffectiveDir);
	return(0);
}

release_and_lock(NewDir)
char	*NewDir;
{
	UnLock(CurrentDirLock); /*Release old CD lock */
	CurrentDirLock=Lock(NewDir);
	CurrentDir(CurrentDirLock);	/*MAKE IT THE CURRENT DIRECTORY*/
	return(0);
}

/* Redisplay files after slide positioning */
rdis_files()
{
 USHORT Vpot;
	int numd;
	int pos=0;

	if((dirflag)&&(numdirB>MAXBNAME)){
		Vpot = Bslide_prop.VertPot;
		Vpot >>= 1;
		Vpot &= 0x7fff;
		numd = numdirB - MAXBNAME;
		pos = ((float) Vpot / (float) 0x7fff) * numd;
		cur_indexB = pos;
	}
	if((!dirflag)&&(numdirA>MAXANAME)){
		Vpot = Aslide_prop.VertPot;
		Vpot >>= 1;
		Vpot &= 0x7fff;
		numd = numdirA - MAXANAME;
		pos = ((float) Vpot / (float) 0x7fff) * numd;
		cur_indexA = pos;
	}
	dis_files(pos);
	return(0);
}

/* Move slides to top & display files */ 
void new_dir()
{
	USHORT Vbody;

	if(dirflag){
		if(numdirB<=MAXBNAME){
		 Vbody = 0xffff;
		}else{
		 Vbody = ((float) 0x7fff)/(((float) numdirB)/((float) MAXBNAME));
		 Vbody <<= 1;
		}
		cur_indexB = 0;
		ModifyProp(&BSlide_gad,BWindow,NULL,Bslide_prop.Flags,0,0,0,Vbody);

	}else{	if(numdirA<=MAXANAME){
		 Vbody = 0xffff;
		}else{
		 Vbody = ((float) 0x7fff)/(((float) numdirA)/((float) MAXANAME));
		 Vbody <<= 1;
		}
		cur_indexA = 0;
		ModifyProp(&ASlide_gad,AWindow,NULL,Aslide_prop.Flags,0,0,0,Vbody);
	}
	dis_files(0);
	return;
}

/* file display loop */
dis_files(pos)
int pos;
{
	register i;

	if(dirflag) for(i=0;i<MAXBNAME;i++) dis_B(i+pos,i);
	else	    for(i=0;i<MAXANAME;i++) dis_A(i+pos,i);
	return(0);
}

/* print files on screen, dir,file highlight for A */
dis_A(file,pos)
register file,pos;
{
	/*Set the top position*/
	file_text.TopEdge = (pos*8)+11;

	if(file == -1 || file >= numdirA){
		sprintf(file_name,"%-37.37s","");
		file_text.FrontPen=2;
		file_text.BackPen= 2;  /*black*/
	}else{
		if(Atable[file].dt_dir){
			sprintf(file_name,"%-30.30s %-6.6s",Atable[file].dt_fname,"");
			if(Atable[file].dt_select){
				file_text.FrontPen=2; /*Dir Highlight*/
				file_text.BackPen= 3;
			}else{
				file_text.FrontPen=3; /*Dir Normal*/
				file_text.BackPen= 2;
			}
		}else{
			sprintf(file_name,"%-30.30s %6ld",Atable[file].dt_fname,Atable[file].dt_size);
			if(Atable[file].dt_select){
				file_text.FrontPen=2; /*File Highlight*/
				file_text.BackPen= 1;
			}else{
				file_text.FrontPen=1;/*File Normal*/
				file_text.BackPen= 2;
			}
		}
	}
	PrintIText(AWindow->RPort,&file_text,0,0);
	return(0);
}

/* as above for B */
dis_B(file,pos)
register file,pos;
{
	/*Set the top position*/
	file_text.TopEdge=(pos*8)+11;

	if(file == -1 || file >= numdirB){
		sprintf(file_name,"%-37.37s","");
		file_text.FrontPen=2;
		file_text.BackPen= 2;  /*black*/
	}else{
		if(Btable[file].dt_dir){
			sprintf(file_name,"%-30.30s %-6.6s",Btable[file].dt_fname,"");
			if(Btable[file].dt_select){
				file_text.FrontPen=2; /*Dir Highlight*/
				file_text.BackPen= 3;
			}else{
				file_text.FrontPen=3; /*Dir Normal*/
				file_text.BackPen= 2;
			}
		}else{
			sprintf(file_name,"%-30.30s %6ld",Btable[file].dt_fname,Btable[file].dt_size);
			if(Btable[file].dt_select){
				file_text.FrontPen=2; /*File Highlight*/
				file_text.BackPen= 1;
			}else{
				file_text.FrontPen=1;/*File Normal*/
				file_text.BackPen= 2;
			}
		}
	}
	PrintIText(BWindow->RPort,&file_text,0,0);
	return(0);
}

/* file select for A */
void sel_A()
{
	int file,i;
	char *ptr;

	file = Msg->MouseY-11;
	file /= 8;
	if((!numdirA)||(file>MAXANAME)||((file+cur_indexA)>numdirA)) return;

	if(Atable[file+cur_indexA].dt_dir){
		for(i=0;i<numdirA;i++)
		if((Atable[i].dt_dir)&&(i != file+cur_indexA))Atable[i].dt_select = 0;
		ptr = A_buf + strlen(A_buf) - 1;
		if(Atable[file+cur_indexA].dt_select ^= 1) 
			sprintf(requestedcd,"%s%s%s",A_buf,((*ptr == ':') ? "":"/"),
				Atable[file+cur_indexA].dt_fname);
		else	strcpy(requestedcd,A_buf);
		dis_files(cur_indexA);
		return;
	}
	Atable[file+cur_indexA].dt_select ^= 1;
	dis_A(file+cur_indexA,file);
	if(COMMENTMODE) display_error(Atable[file+cur_indexA].dt_comment,0);
	return;
}
/* file select for B */
void sel_B()
{
	int file,i;
	char *ptr;

	file = Msg->MouseY-11;
	file /= 8;
	if((!numdirB)||(file>MAXBNAME)||((file+cur_indexB)>numdirB)) return;

	if(Btable[file+cur_indexB].dt_dir){
		for(i=0;i<numdirB;i++)
		if((Btable[i].dt_dir)&&(i != file+cur_indexB))Btable[i].dt_select = 0;
		ptr = B_buf + strlen(B_buf) - 1;
		if(Btable[file+cur_indexB].dt_select ^= 1) 
			sprintf(requestedcd,"%s%s%s",B_buf,((*ptr == ':') ? "":"/"),
				Btable[file+cur_indexB].dt_fname);
		else	strcpy(requestedcd,B_buf);
		dis_files(cur_indexB);
		return;
	}
	Btable[file+cur_indexB].dt_select ^= 1;
	dis_B(file+cur_indexB,file);
	if(COMMENTMODE) display_error(Btable[file+cur_indexB].dt_comment,0);
	return;
}

void par_dir() /* concat curdir */
{
	char *ptr;

	ModifyIDCMP(AWindow,0);
	ModifyIDCMP(BWindow,0);
	if(dirflag) ptr=B_buf+strlen(B_buf)-1;
	else ptr=A_buf+strlen(A_buf)-1;

	if(dirflag)for(;ptr >= B_buf;ptr--){
		if(*ptr == ':'){
			*(ptr+1)=0;
			break;}
		if(*ptr == '/'){
			*ptr = 0;
			break;}
	}else for(;ptr >= A_buf;ptr--){
		if(*ptr == ':'){
			*(ptr+1)=0;
			break;}
		if(*ptr == '/'){
			*ptr = 0;
			break;}
	}
	if(dirflag) getdir(B_buf);
	else getdir(A_buf);
	new_dir();
	ModifyIDCMP(AWindow,WinIDCMP);
	ModifyIDCMP(BWindow,WinIDCMP);
	return;
}

/*compare two directory entries*/
comp(dt1,dt2)
struct DirTable *dt1,*dt2;
{
	char *ptr1,*ptr2;
	register c1,c2;

	for(ptr1=dt1->dt_fname,ptr2=dt2->dt_fname;*ptr1&&*ptr2;ptr1++,ptr2++){
		c1= *ptr1;
		c2= *ptr2;
		c1&= 0xdf;
		c2&= 0xdf;
		if(c1>c2) return(-1);
		if(c1<c2) return(1);
	}
	if(*ptr1) return(-1);
	return(0);
}

void copy(s,pc)	/* FileCopy					    TxEd 1345 */
char *s;
char *pc;
{
	struct FileHandle  *copyin;
	struct FileHandle  *copyout;
	int iosize;
	int actual;
	char *copybuf;
	struct FileLock *fl;
	char *ptr;
	char *ptr1;

	if(!(copyin = Open(s,MODE_OLDFILE))) return;

	if((fl=Lock(pc,ACCESS_READ))){
		UnLock(fl);
		ptr = strlen(pc)+pc-1;
		for(ptr1=s+strlen(s)-1;ptr1 > s;ptr1--){
			if(*ptr1=='/'||*ptr1==':') break;}
		if(*ptr1 == '/'||*ptr1 == ':') ptr1++;
		if(*ptr == ':') sprintf(command,"%s%s",pc,ptr1);
		else sprintf(command,"%s/%s",pc,ptr1);
	}
	sprintf(command2,"Copying %s to %s",s,pc);
	display_error(command2,0);

	if(!strcmp(command,s)){
		display_error("Same Dir Error",0);
		Close(copyin);
		return;}

	if(!(copyout = Open(command,MODE_NEWFILE))){
		display_error("Can't Write to Requested Path",IoErr());
		Close(copyin);
		return;
	}else{
/* Determine the length of the file '?' */
		iosize = Seek(copyin,0,OFFSET_BEGINING);
		iosize = 12288;
/* Allocate memory for the copy buffer */
		do{
			copybuf = AllocMem(iosize,MEMF_PUBLIC);
			if(copybuf==0) iosize=iosize/2;
		}while(copybuf==0 & iosize>512);

/* A-OK Copy the file */
		do{	actual = Read(copyin,copybuf,iosize);
			if(Write(copyout,copybuf,actual)!=actual)
				break;} while(actual==iosize);

		FreeMem(copybuf,iosize);
		Close(copyout);
		Close(copyin);
	}
	return;
}

nullterm(str,len) /* return a str, size of len */
char *str;
int len;
{
	register i;

	str[len]=0;
	for(i=len;len>=0;len--){
		if(str[i]!=' '&&str[i]) break;
		str[i]=0;
	}
	return(0);
}

display_error(errormsg,doserrnum)
char *errormsg;
long doserrnum;
{
	strcpy(err_buf,errormsg);
 	if(doserrnum){
		sprintf(err_buf,"%s (%d)",err_buf,doserrnum);
		DisplayBeep(0);
	}
	err_str.NumChars = strlen(err_buf);
	err_str.BufferPos = strlen(err_buf);
	RefreshGadgets(&Err_gad,Window,NULL);
	return(0);
}

qsort(v,n,size) /* ASCII sort */
char *v;
short n;
int size;
{
	short gap,i,j;
	register x;
	char temp, *p1, *p2;
	for(gap=n/2;gap>0;gap/=2)
		for(i=gap; i<n; i++)
			for(j=i-gap; j>=0; j-=gap)
			  if(comp((p1=v+j*size), (p2=v+(j+gap)*size))<0){
				/*exchange them*/
				for(x=0; x<size; x++){
					temp = *p1;
					*p1++ = *p2;
					*p2++ = temp;
				}
			  }
	return(0);
}

/* Read text files */
void Print_to_screen(ptr)
char *ptr[];
{
register i,len;
if(!done)
	do{
		len=Read(workfp,buf,512);
		len2=0;
		while(len2<len&&done==FALSE){
			for(i=len2;buf[i] != 0x0a&&i<511;i++)
			if(buf[i] == 0x0c) buf[i] = 0x20;			
			Write(w,&buf[len2],i-len2+1);
			len2 = i+1;
			if (++linecount>21 && buf[i] == 0x0a) WaitSpace();
		}
	}while(len == 512 && done == FALSE);
        MyDone();
	MyClose();
}

/* Hex read files */
void Hprint_to_screen(ptr)
char *ptr[];
{
register len;
if(!done)
strcpy(buffer,"    -                                     ");
r1[0]=0x00;r1[1]=0x00;
	do{
		index = 0;
		DoHex(r1,2);
		r1[1] += 16;
		if(!(r1[1])) r1[0]++;
		index=6;
		len = Read(workfp,buf,16);
		buf[len]=0x0a;
		DoHex(buf,len,6);
		if(len){
			Write(w,&buffer[0],index);
			if (len!=16) Write(w,&blank[0],42-index);
			Write(w,&buf[0],len+1);
		};
		if(++linecount>21) WaitSpace();
	}while((len==16)&&(!done));
	MyDone();
	MyClose();
	return;
}

/* Convert to hex */
void DoHex(ptr2,len)
int len;
char ptr2[];
{
 unsigned char c1,c2;
 unsigned int i,i2=0;
 for(i=0;i<len;i++){
	c1=((ptr2[i]&0xf0)>>4);
	c2=(ptr2[i]&0x0f);
		if(c1>9) c1+=87;
		else	 c1+=48;
		if(c2>9) c2+=87;
		else	 c2+=48; 
	buffer[index]=c1;
	buffer[index+1]=c2;
	if((buf[i]<32)||(buf[i]>127)) buf[i]=46;
	index+=2;
	if(++i2==4){
		index++;
		i2=0;
	};
 }
 return;
}

/* wait prompt for READ */
void WaitSpace()
{
unsigned char c;

	linecount = 1;
	Write(w,"\x1b[33mSPACE,RETURN,B,ESC,?> \x1b[0m",31);
	while(Read(w,&c,1),c!=' '){
		if(c==ESC){
		 done = TRUE;
		 break;
		}
		if(c=='\r'){
		 linecount=21;
		 break;
		}
		if(c=='b'){
		 Seek(workfp,0,OFFSET_BEGINNING);
		 len2 = 513;
		 r1[0]=0x00;
		 r1[1]=0x00;
		 Write(w,"\x1bc",2);
		 break;
		}
		if(c=='?'){	/* Help menu */
		 strcpy(command,"\r\x1b[32m[SPACE] : Forward one page\n[RETURN]: Forward one line\n[ B ]   : Beginning of file\n[ESC]   : Abort read\n\x1b[0m");
		 Write(w,command,strlen(command));
		 WaitSpace();
		 break;
		}
	}
/*erase over the message*/
Write(w,"\r                     \r",23);
}
void MyDone()
{
unsigned char c;
	Write(w,"\r\x1b[33mEnd. Press SPACE\x1b[0m",26);
	while(Read(w,&c,1),c!=' ');
}
void MyClose()
{
	if(workfp) Close(workfp);
	if(w) Close(w);
}

/* Do A request, cmt = BodyText , oldreq = String to change */
do_req(cmt,oldreq)
char *cmt,*oldreq;
{
 int gadgid,looping=TRUE;
 strcpy(REQ_COMMENT,cmt);
 strcpy(req_buf,oldreq);
 REQ=FALSE;
 if(Request(&req,Window) == NULL) looping=FALSE;
 while(looping){
	display_mem();
	while((Msg=GetMsg(Window->UserPort))||(Msg=GetMsg(AWindow->UserPort))){
		MessageClass=Msg->Class;
		code=Msg->Code;
		igad=(struct Gadget *)Msg->IAddress;
		gadgid=igad->GadgetID;
		ReplyMsg(Msg);
		looping=FALSE;
		EndRequest(&req,Window);
		switch(gadgid){
 			case FALSE_BUTT:
				REQ=FALSE;
				break;
			case REQSTR_GADGET:
				nullterm(req_buf,MAXCD);
			case TRUE_BUTT:
				REQ=TRUE; 
				break;
			default:
				break;
		}
	}
 }
 return(0);
} /* Get outa here */

save_config()
{
if(workfp=Open(CONFILE,MODE_NEWFILE))
	{
	Write(workfp,SHOW,   MAXCHAR);
	Write(workfp,COMMAND,MAXCHAR);
	Write(workfp,ARCX,   MAXCHAR);
	Write(workfp,ARCL,   MAXCHAR);
	Write(workfp,EDITOR, MAXCHAR);
	Write(workfp,PRINT,  MAXCHAR);
	Close(workfp);
	}
return(0);
}

close_things()
{
	if(BWindow)	CloseWindow(BWindow);
	if(AWindow)	CloseWindow(AWindow);
	if(Window)	CloseWindow(Window);
	if(IntuitionBase) CloseLibrary(IntuitionBase);
	if(GfxBase)	CloseLibrary(GfxBase);
	if(InitDirLock){
		CurrentDir(InitDirLock);
		UnLock(CurrentDirLock);
	}
	_exit();
}
