/* Rename a disk.
 * Author:		Mark R. Rinfret
 * Date:		06/27/87
 *
 * This package was derived from "touch.c", written by Andy Finkel
 * and Phil Lindsay of Commodore-Amiga.  I wrote RenameDisk as a
 * support routine for my hard disk backup utility.
 */

/* Enable the next #define if you want to do testing.  This will cause
 * generation of a main program.  For practical use, the RELABEL command
 * in the C: directory is much more efficient.
 */

/* #define STAND_ALONE */

#include "exec/types.h"
#include "exec/ports.h"
#include "exec/io.h"
#include "exec/memory.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"

#ifdef AZTEC_C
#include <functions.h>
#endif

extern LONG 	sendpkt();

#ifndef AZTEC_C
extern int      strcpy();
extern int      strlen();
#endif

#define DOSTRUE 	    -1
#define MAX_NAME		30L	

#ifdef STAND_ALONE
main(argc,argv)
int     argc;
char   *argv[];
{
	unsigned code = 0;

	if(argc!=3){
		puts("Bad arguments\n");
	}
	else
		if (RenameDisk(argv[1], argv[2]))
			code = 20;

	exit(code);
}
#endif

int
RenameDisk(oldname, newname)
	char *oldname, *newname;
{
	struct MsgPort     *task;
	LONG 	arg[4];
	LONG 	rc;
	USHORT  fail = 0;
	ULONG   lock;
	ULONG   plock;
	UBYTE  *pointer;

	if (strlen(newname) >= MAX_NAME) 	/* name too long? */
		return 1;

	if(!(pointer= (UBYTE *) AllocMem(MAX_NAME,MEMF_PUBLIC))) {
		++fail;
		goto cleanup;
	}

	if (!(task=(struct MsgPort *) DeviceProc(oldname))) {
		++fail;
		goto cleanup;
	}

	/* Make sure that the old name is valid. */

	if(!(lock = (ULONG) Lock(oldname,SHARED_LOCK))) {
		++fail;
		goto cleanup;
	}
	UnLock(lock);

	/* Convert the nice C string to an ugly BSTR :-) */

	strcpy((pointer + 1),newname);
	*pointer = strlen(newname);
	arg[0]= (ULONG) &pointer[0]>> 2;	/* BSTR of filename */

	/* Now, cross all your fingers and toes... */
	rc = sendpkt(task,ACTION_RENAME_DISK,arg,1);
	if(!rc)
		++fail;
cleanup:
	if (pointer)
		FreeMem(pointer, MAX_NAME);
	return fail;
}

/* This is the actual workhorse which tells DOS what to do.  Aztec C
 * has a new function, "dos_packet", but I prefer this one.  Thanks,
 * Phil and Andy!
 */

LONG 
sendpkt(id,type,args,nargs)
struct MsgPort     *id;				/* process indentifier ... (handler's
									   message port ) */
LONG type,							/* packet type ... (what you want 
									   handler to do )   */
args[],								/* a pointer to argument list */
nargs;								/* number of arguments in list  */
{

	struct MsgPort     *replyport;
	struct StandardPacket  *packet;

	LONG count,*pargs,res1=NULL;


	if (!(replyport = (struct MsgPort   *) CreatePort(NULL,NULL)))
		return(NULL);

	packet = (struct StandardPacket *)
	           AllocMem((LONG)sizeof(*packet),MEMF_PUBLIC|MEMF_CLEAR);

	if (packet) {
		packet->sp_Msg.mn_Node.ln_Name = &(packet->sp_Pkt);/* link packet */
		packet->sp_Pkt.dp_Link = &(packet->sp_Msg);/* to message    */
		packet->sp_Pkt.dp_Port = replyport;/* set-up reply port   */
		packet->sp_Pkt.dp_Type = type;/* what to do... */

	/* move all the arguments to the packet */
		pargs = &(packet->sp_Pkt.dp_Arg1);/* address of first argument */
		for (count=0; (count < nargs) && (count < 7); count++)
			pargs[count] = args[count];

		PutMsg(id,packet);			/* send packet */
		WaitPort(replyport);		/* wait for packet to come back */
		GetMsg(replyport);			/* pull message */

		res1 = packet->sp_Pkt.dp_Res1;/* get result */
		FreeMem(packet,(LONG)sizeof(*packet));

	}
	DeletePort(replyport);
	return(res1);
}

/* Functions strcpy, strlen are defined by Aztec C library. */

#ifndef AZTEC_C
int
        strcpy(to,from )
register char  *to,*from;
{
	do {
		*to++= *from;
	}while(*from++);
}

int
        strlen(s )
register char  *s;
{
	register    i = 0;

	while(*s++)
		i++;

	return(i );
}
#endif
/* eof */
