/* DiskMisc.c - miscellaneous disk support routines.
 * Mark Rinfret (et al), 1987
 */

/*#define DEBUG*/

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <libraries/dosextens.h>
#include <functions.h>

extern LONG 	sendpkt();

/* This routine returns the number of disk blocks remaining on the
 * drive specified by 'name'.  Though 'name' would typically be the
 * drive name or volume name, it can also be the name of any file
 * on the disk drive.
 * Called with:
 *		name:		disk device or volume name
 * Returns:
 *		> 0 => number of blocks available
 *		< 0 => error status
 */

long DiskBlocks(name)
	char *name;
{
	struct FileLock *lock = NULL;
	struct InfoData *info = NULL;
	long int blocks = -1L;
	long IoErr();

	if (lock = (struct FileLock *) Lock(name,ACCESS_READ)) {
		if (info = AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC)) {
			if (Info(lock,info)) {
				blocks = info->id_NumBlocks - info->id_NumBlocksUsed;
			}
			else {
				blocks = -IoErr();
#ifdef DEBUG
				printf("DiskBlocks: can't get Info on %s; error %ld\n",
					name, blocks);
#endif
				}
		}
		else {
			blocks = -ERROR_NO_FREE_STORE;
#ifdef DEBUG
			puts("DiskBlocks: no memory!");
#endif
		}
	}
	else {
		blocks = -IoErr();
#ifdef DEBUG
		printf("DiskBlocks: can't lock %s; error %ld\n",name,blocks);
#endif
	}

	if (lock)	UnLock(lock);
	if (info)	FreeMem(info,(long)sizeof(struct InfoData));
	return blocks;					/* bad status indicator */
}

/* Disk ACTION_INHIBIT support routine.
 * Author:		Mark R. Rinfret
 * Date:		06/29/87
 * 
 * This routine provides support for user-written disk formatting, copy
 * operations which benefit from suppressing/restoring disk validation.
 */

int
Inhibit(drivename, code)
	char *drivename; int code;
{
	struct MsgPort     *task;
	LONG 	arg[2];
	LONG 	rc;

	if (!(task=(struct MsgPort *) DeviceProc(drivename))) 
		return 1;						/* fail, darn it! */

	arg[0] = code;

	/* Now, cross all your fingers and toes... */

	return ( !sendpkt(task,ACTION_INHIBIT,arg,1));
}


#ifdef DEBUG
main()
{
	long blocks;

	blocks = DiskBlocks("df0:");
	if (blocks == -1L)
		puts("Bad status from DiskBlocks()");
	else
		printf("Disk blocks left on df0: %ld\n",blocks);
}
#endif
