[comp.sources.atari.st] v01i002: Automatic file copier for RAMdisk

koreth@ssyx.ucsc.edu (Steven Grimm) (03/29/88)

Submitted-by: sirkm@ucscb.ucsc.edu (Greg Anderson)
Posting-number: Volume 1, Issue 2
Archive-name: bootcopy

[This is rather timely, as discussions about just this sort of program have
 been going on in comp.sys.atari.st.  It should work with any C compiler,
 but has only been tested with Laser and Megamax C. -sg]

/*-------------------------------------------------------------------
| Bootcopy version 1.0:   In the Public Domain
|		Greg Anderson
|
| This program copies everything inside the folder "AUTOCOPY" onto
| the Ramdisk on powerup.  If "AUTOCOPY" contains folders, these
| folders are created on the Ramdisk, and their contents are also
| copied.  There is no limit to the depth of folders that can be
| placed inside "AUTOCOPY".
|
| Usage:
|		Putting Bootcopy into the AUTO folder:
|
| 1. If you already have an AUTO folder on your disk, save the files
|    inside it somewhere and delete it.
| 2. Create (or recreate) your AUTO folder.
| 3. Real-time-clock setting programs (such as CLKSET for DeskCart)
|    may be copied to the AUTO folder if desired.
| 4. Copy your RamDisk to the Auto folder.  Desk accessory RamDisks
|    are not suitable, as the RamDisk MUST be installed before
|    Bootcopy runs.  VEGEMATIC (MEGEMATIC.PRG) is the recommended
|    RamDisk.  Make sure that your RamDisk is the drive with the
|    highest letter, or Bootcopy will copy its files to the wrong
|    drive.
| 5. Copy BOOTCOPY.PRG to the Auto folder
| 6. Copy any other programs you wish to place in the Auto folder.
|
|		Setting up the AUTOCOPY folder:
|
| 1. Create a folder called AUTOCOPY.  It may be placed in one of
|    two locations:  on the root, or inside the AUTO folder.
| 2. Copy any files you wish to be moved to the RamDisk on powerup
|    to the AUTOCOPY folder.
|
| That's all there is to it.  The author can be reached as follows:
|
| 1. Via E-mail to sirkm@ucscb.ucsc.edu
| 2. Call his BBS (1200/300) at (408) 462-3832.
-------------------------------------------------------------------*/
#include <OSBIND.H>

int fstatus,copi,working,RamDisk;
char *bufadr,cfile[50],folder[128],*rfolder,copies[30],str[30];
long buflen;

main()
{
	print("~---------------------------------~");
	print("       Bootcopy vrs. 1.0,~");
	print("    a Public Domain Utility~");
	print("        by Greg Anderson~");
	print("---------------------------------~");
	
	/*-----------------------------------------------------------
	| Assume RamDisk is the highest-lettered drive installed
	-----------------------------------------------------------*/
	fstatus=-1;
	for(RamDisk=16;fstatus<0;--RamDisk)
	{
		Dsetdrv(RamDisk-1);
		fstatus=Dsetpath("\\");
	}
	if(RamDisk<2)
		print("~~No RamDisk handler installed.~~");
	else
	{
		strcpy(str,"~RamDisk = D:~");
		str[11]=RamDisk+65;
		print(str);
	}
	strcpy(copies,"   0 Files copied.");
	copi=3;
	/*-----------------------------------------------------------
	| Find free memory & allocate it for the copy buffer
	-----------------------------------------------------------*/
	buflen=Malloc(-1L);
	bufadr=(char *)Malloc(buflen-2048);
	/*-----------------------------------------------------------
	| Start inside the folder "\AUTOCOPY"
	-----------------------------------------------------------*/
	strcpy(folder,"\\AUTOCOPY\\");
	rfolder = folder+9;
	working=1;
	/*-----------------------------------------------------------
	| Does "\AUTOCOPY exist?
	-----------------------------------------------------------*/
	Dsetdrv(0);
	fstatus=Dsetpath(folder);
	if(fstatus)
	{
		/*---------------------------------------------------
		| It is also permissible to place AUTOCOPY inside of
		|     the AUTO folder to avoid cluttering the root.
		---------------------------------------------------*/
		strcpy(folder,"\\AUTO\\AUTOCOPY\\");
		rfolder = folder+14;
		fstatus=Dsetpath(folder);
	}
	/*-----------------------------------------------------------
	| Exit if there is no AUTOCOPY folder.
	-----------------------------------------------------------*/
	if(fstatus)
	{
		print("~~No AUTOCOPY folder found on this disk.~");
	}
	if(fstatus | (RamDisk<2))
	{
		print("Create an AUTOCOPY folder on drive A:\\~");
		print("and place this program inside the AUTO~");
		print("folder after the RamDisk handler.  All~");
		print("files in AUTOCOPY will then be moved to~");
		print("the RamDisk on powerup.~~");
		print("Press a key:~");
		Cconin();
	}
	else
	{
		while (working)
		{
			filecopy();
			nextfolder();
		}
		print("~~Bootcopy complete. ");
		print(copies);
	}
	/*-----------------------------------------------------------
	| Return copy buffer to the system
	-----------------------------------------------------------*/
	buflen=Mfree(bufadr);
}

/*-------------------------------------------------------------------
| Copy all files in the subdirectory "folder" to the Ramdisk
-------------------------------------------------------------------*/
filecopy()
{
	int rhand,whand,i;
	long len;
	char name[128];

	/*-----------------------------------------------------------
	| Set the working directory on the RamDisk to "rfolder"
	|     & make the working directory on drive A "folder".
	|     Note that "rfolder" points to the same memory space
	|     as "folder" (but past the "\AUTOCOPY" header).
	-----------------------------------------------------------*/
	Dsetdrv(RamDisk);
	Dsetpath(rfolder);
	Dsetdrv(0);
	Dsetpath(folder);
	fstatus=Fsfirst("A:*.*",0);
    
	while (! fstatus)
	{
		/*---------------------------------------------------
		| Find the next file in the directory & open for read
		---------------------------------------------------*/
		filename(cfile);
		strcpy(name,"A:");
		strcat(name,cfile);
		rhand=Fopen(name,0);
		if(rhand>-1)
		{
			/*-------------------------------------------
			| Create the file on the RamDisk
			-------------------------------------------*/
			name[0] = 65 + RamDisk;
			whand=Fcreate(name,0);
			if(whand>-1)
			{
				/*-----------------------------------
				| Copy the file from rhand to whand
				-----------------------------------*/
				do
				{
					len=Fread(rhand,buflen,bufadr);
					Fwrite(whand,len,bufadr);
				} while(len==buflen);
			}
		}
		/*---------------------------------------------------
		| Copy complete--increment the copied count
		---------------------------------------------------*/
 		++copies[copi];
 		i=copi;
 		while(copies[i]==58)
 		{
 			copies[i--]=48;
 			if(copies[i]<48)
 				copies[i]=48;
 			++copies[i];
 		}
		fstatus=Fsnext();
	}
}

/*-------------------------------------------------------------------
| Determine if there are folders in this folder that have not been
| coppied.  If there are, set the working directory, create a like
| directory on the RamDisk and return.  Otherwise, try to go up a     *
| level.  If not possible, then set 'working' to zero to indicate
| failure.  If it works, call this routine again.
-------------------------------------------------------------------*/
nextfolder()
{
	int loop,i,check;
	char savename[16],cmpname[16],newfolder[16],fspec[128];
	loop=1;
	while (loop)
	{
		/*---------------------------------------------------
		| Read past all of the folders that have already
		|     been copied onto the Ramdisk
		---------------------------------------------------*/
		Dsetdrv(0);
		Dsetpath(folder);
		strcpy(fspec,"A:");
		strcat(fspec,folder);
		strcat(fspec,"*.*");
		fstatus=Fsfirstd(fspec);
		check=0;
		
		while((fstatus == 0) & (check==0))
		{
			filename(cmpname);
			strcpy(fspec,rfolder);
			strcat(fspec,cmpname);
			strcat(fspec,"\\");
			Dsetdrv(RamDisk);
			check=Dsetpath(fspec);
			if(check>-1)
				fstatus=Fsnextd();
		}
		/*---------------------------------------------------
		| Reset working directory to where it was
		---------------------------------------------------*/
		Dsetdrv(RamDisk);
		Dsetpath(rfolder);
		/*---------------------------------------------------
		| Are there any more folders?  If so, create the
		|     next one & append its name to "folder" so it
		|     will be copied next time through the loop
		---------------------------------------------------*/
		if (fstatus==0)
		{
			Dsetdrv(RamDisk);
			Dcreate(cmpname);
			strcat(folder,cmpname);
			strcat(folder,"\\");
			loop=0;
		}
		else
		{
			/*-------------------------------------------
			| If there are no more folders to copy on
			|    this level & if we are on the root, then
			|    the copy is finished.
			-------------------------------------------*/
			i = strlen(rfolder)-2;
			if(i < 0)
			{
				working = 0;
				loop = 0;
			}
			/*-------------------------------------------
			| If there are no more folders to copy on
			|    this level but we are not on the root,
			|    then go up one level and see if there
			|    are any folders there that need copying
			-------------------------------------------*/
			else
			{
				while(rfolder[i] != 92)
					--i;
				rfolder[i+1]=0;
			}
		}
	}
}

/*-------------------------------------------------------------------
| Extract the filename from the DTA
-------------------------------------------------------------------*/
filename(string)
char *string;
{
	char *ptr;
	ptr=(char *)(Fgetdta()+30);
	strcpy(string,ptr);
}

/*-------------------------------------------------------------------
| These two routines work like Fsfirst and Fsnext, but they skip
|     any entries that are not folders.
-------------------------------------------------------------------*/
Fsnextd()
{
	char *ptr;
	int stat;
	do
	{
		stat=Fsnext();
		ptr=(char *)(Fgetdta()+21);
	} while((isfolder() == 0) & stat == 0);
	return(stat);
}

Fsfirstd(fspec)
char *fspec;
{
	int stat;
	stat=Fsfirst(fspec,16);
	if(isfolder() == 0)
		stat=Fsnextd();
	return(stat);
}

/*-------------------------------------------------------------------
| Return true if the file is a folder.
-------------------------------------------------------------------*/
isfolder()
{
	char *ptr;
	ptr=(char *)(Fgetdta());
	if(ptr[30]==46)    				/* Ignore folders */
		return(0);				/* that start with "." */

	return((ptr[21] && 16) != 0);
}

/*-------------------------------------------------------------------
| A simple print routine.  Convert ~ to CR LF.  This routine is
|     used to prevent the large printf() library from linking.
-------------------------------------------------------------------*/
print(string)
char *string;
{
	char c;
	int i;
	
	i=0;
	
	while(c=string[i++])
	{
		if(c==126)
		{
			Cconout(13);
			Cconout(10);
		}
		else
			Cconout(c);
	}
}