/************************************************************
* Delete an ADAM file
*************************************************************
* 1.00				Chris Braymen	Creation
* 1.01	12/1/94	Chris Braymen	Fixes writeDircetory bugs
*											with multiple directories
*************************************************************/

#define TRUE	1
#define FALSE 	0
#define BUFSIZE				1024            /* not less that 1024! */

#define	BDRESET	       	0x00
#define	BDSTATUS       	0x01
#define	BDREAD	       	0x02
#define	BDWRITE	       	0x03
#define	BDVERIFY       	0x04
#define	BDFORMAT       	0x05

#define	FLOPPY1	       	0x00
#define	HEAD0	       		0x00
#define 	HEAD1					0x01
#define	ONESECTOR			0x01



#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<bios.h>
#include	<ctype.h>
#include	"adamfcb.h"


#define MAX_FCB	8*NUM_FCB_IN_BLOCK   /* maximum # of directory entries */

unsigned char	buffer[BUFSIZE];
struct 	EOS_FCB	myDir[MAX_FCB];
char		delFileName[255];

char version[] = "v1.01";

/****************************
* Prototypes
*****************************/
int processArgs(int,char**);
int readDirectory(void);
int verifyEOS(unsigned char*);
int writeDirectory(void);
int deleteFile(char*);
int compareName(char*,char*);
int findFCB(char*);



#include	"ReadBlk.c"
#include	"WriteBlk.c"

int main(argc,argv)
	int	argc;
	char	*argv[];
{
	int	block;
	int	result;

	if(!processArgs(argc,argv))
		exit(0);

	if(!readDirectory()) {
		exit(0);
	}

	deleteFile(delFileName);
	return 0;
}

/*******************************************************
* processArgs - process the command line args
*		sets globals inFileName,outFileName
********************************************************/
processArgs(argc,argv)
   int	argc;
   char	*argv[];
{
   if(argc!=2) {
		printf("DELADAM %s - Public Domain from Bonafide Systems\n\n",version);
		puts("Usage: DELADAM <ADAM filename to delete>\n");
		return(FALSE);
	}

   strcpy(delFileName,argv[1]);

   return(TRUE);
}


/*****************************************************
* readDirectory
*	reads the EOS directory in the myDir array of FCB structures
*	returns 0 if OK, BIOSDISK error code if error
*****************************************************/
int readDirectory()
{
   int	result,i,j,done=FALSE;
   int	fcbCount=0;
   int	dirBlocks,blockCount=1;
   char	*bytePtr;

   if(result=readBlock(blockCount,buffer)) {	/* read directory block */
		printf("Error reading block: %d, errcode=%d\n",blockCount,result);
		return(FALSE);
   }

   if((dirBlocks=verifyEOS(buffer))==0)	{	/* get directory size */
   	puts("Not an EOS directory!");
		return(FALSE);
   }						
   if(dirBlocks * NUM_FCB_IN_BLOCK >  MAX_FCB) {
		printf("A %d block directory is too big!\n",dirBlocks);
		return(FALSE);
   }

   while(!done) {
		if(blockCount>dirBlocks) {
			puts("Error: No 'hole' found");
			return(FALSE);
		}
		if(result=readBlock(blockCount,buffer))	{
			printf("Error reading block: %d, errcode=%d\n",blockCount,result);
			return(FALSE);
		}

		for(i=0;i<NUM_FCB_IN_BLOCK;i++) {
			bytePtr=(char*)&myDir[fcbCount];
			for(j=0;j<FCB_SIZE;j++) {             /* copy FCB to structure */
				*bytePtr = buffer[i*FCB_SIZE+j];
				bytePtr++;
			}
			if (myDir[fcbCount].status==HOLE)
				done=TRUE;
			fcbCount++;
		}
		blockCount++;
   }
   return(TRUE);
}

/****************************************************
* verifyEOS - Verifies that the media is an EOS media
*	      and returns the size of the directory.
*	      0 if Error.
*****************************************************/
int verifyEOS(buffer)
	unsigned char buffer[];
{
   int  Count;

   for (Count=0; Count<4; Count++) {
      if (DirChk[Count] != buffer[Count+13]) { 
			return(0);
      }
   }
   return(buffer[12] & 0x7F); /* mask out bit 7 */
}


/*****************************************************
* writeDirectory
*	writes the EOS directory in the myDir array of FCB structures
*	returns TRUE if OK, FALSE if error
*****************************************************/
int writeDirectory()
{
   int	result,i,j;
   int	fcbCount;
   int	dirBlocks;
   char	*bytePtr,*bufferPtr;
   int	done=FALSE;

	dirBlocks=myDir[0].status & 0x7F;	/* number of directory blocks */
   for(i=0;i<dirBlocks && !done;i++) {
		for(j=0;j<BUFSIZE;j++) 		/* zero out buffer */
			buffer[j]=0;
		bufferPtr=buffer;

		for (fcbCount=i*NUM_FCB_IN_BLOCK;
			  fcbCount<(i+1)*NUM_FCB_IN_BLOCK && !done;
			  fcbCount++) {
			bytePtr=(char*)&myDir[fcbCount];
			for(j=0;j<FCB_SIZE;j++) {
				*bufferPtr=*bytePtr;
				bufferPtr++;
				bytePtr++;
			}
			if(myDir[fcbCount].status==HOLE)
				done=TRUE;
		}

		if((result=writeBlock(i+1,buffer))!=0) {
        	printf("[Error writing directory block %d]\n",i+1);
			return(FALSE);
		}
   }
   return(TRUE);
}



/********************************************************
* deleteFile - returns TRUE if OK, FALSE if ERROR
********************************************************/
deleteFile(fileNameP)
   char *fileNameP;
{
   int	deleteFCB;

   if((deleteFCB=findFCB(fileNameP))==0) {
      printf("Can't find file: %s\n",fileNameP);
      return(FALSE);
   }

   if(myDir[deleteFCB].status & (LOCKED+HOLE+EXECUTIVE+SYSTEM)) {
      puts("File is protected, can't delete it!");
      return(FALSE);
   }


   /* If the next FCB is a HOLE the make the current FCB the HOLE */
   if (myDir[deleteFCB+1].status==HOLE) {
      myDir[deleteFCB+1].startBlock=myDir[deleteFCB].startBlock;
      myDir[deleteFCB+1].blocksAllocated+=myDir[deleteFCB].blocksAllocated;
      myDir[deleteFCB] = myDir[deleteFCB+1];
   }
   else {
      myDir[deleteFCB].status |= DELETED;
   }
   return(writeDirectory());
}


/*********************************************************************
* compareName - returns TRUE if names are the same, FALSE if not
*		EOS terminated strings
*********************************************************************/
compareName(s1,s2)
	char *s1,*s2;
{
	while(*s1 == *s2) {
	   if(*s1=='\3') {	/* end of string? */
			return(TRUE);
		}
	   s1++;
	   s2++;
	}
	return(FALSE);
}



/*********************************************************************
* findFCB -      locates the FCB with the name at fileNameP.
*		 Returns FALSE (0) if can't find it, otherwise the
*		 FCB number to of the file.
**********************************************************************/
int findFCB(fileNameP)
	char	*fileNameP;
{
	int	i;
	char	newName[255];


	/* check for duplicate filename */
	i=0;
	while(fileNameP[i]) {
	   newName[i]=fileNameP[i];
	   i++;
	}
	newName[i]='\3';

	i=0;
	while(myDir[i].status != HOLE) {
		if(!(myDir[i].status & DELETED)) {
			if(compareName(newName,myDir[i].fileName))
	         return(i);
	   }
	   i++;
	}
	return(FALSE);
}

