/*   Free.c  -  (c) 1989  Mike 'Sirius' Stilson - Sirius Software
 *   Ver1.0     January 1989.  Written, Tested, Debugged, Re-Tested, and Finished.
 *
 *                      Display free/total bytes for a volume.
 *              
 *      Notice:
 *              The author makes no claims or guarantees of the suitability of this
 * program for any given application, and I assume no responsibility or
 * liability for damages incurred through its usage.
 *
 *    Feel free to steal any or all of this code and make millions of dollars
 * from its sale and commercial use, but please..  Give credit where credit is
 * due.
 *
 *   Any similarity of this program, living, dead, deleted, or undead is purely
 * coincidental and unintentional.
 *
 */

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

struct InfoData *idata = NULL;
struct FileLock *mylock = NULL;

_wb_parse() {}          /* We don't run from the wb.. */

main(ac,av) int ac; char **av;
{
        char *GetName();

   if(!(idata=(struct InfoData *)
                AllocMem((long)sizeof(struct InfoData),(long)MEMF_CHIP|MEMF_CLEAR))) {
                puts("Not enough memory.\n");
                exit(20);
        }

if(ac==1) goto once;
        while(--ac > 0) {
once:
   if(!(mylock=Lock(*++av,ACCESS_READ))) {
                printf("Attempt to lock %s failed.\n",*av);
      FreeMem(idata,(long)sizeof(struct InfoData));
      exit(20);
   }

   if(!(Info(mylock,idata))) {
                printf(Output(),"Unable to obtain info for device %s.\n",*av);
      FreeMem(idata,(long)sizeof(struct InfoData));
                UnLock(mylock);
      exit(20);
   }

   printf("Volume Name: \2334;31;40m%s\2330;0;0m\t",GetName(mylock));

        GetFree();
   UnLock(mylock);
        }

   FreeMem(idata,(long)sizeof(struct InfoData));
   exit(0);
}


/* Macro to convert a BPTR to a CString.  Just for readability */
#define BPTR_TO_C(cast, var) ((struct cast *)(BADDR((ULONG)var)))

char *
GetName(lock)
struct FileLock *lock;
{
        struct DeviceList *dl=NULL;
        register char *p=NULL;
        register char buf[80];

        Forbid();

/* Since the InfoData structure points to a NULL BSTR all the time, this is
   the only way I can think to get the volume name */

                lock = BPTR_TO_C(FileLock, lock);
                dl = BPTR_TO_C(DeviceList, lock->fl_Volume);
                p = (char *)BADDR(dl->dl_Name);
                movmem(p+1, buf, p[0]);
                buf[p[0]] = '\0';

        Permit();
        return(buf);
}


GetFree()
{
        register ULONG usedbytes=0, totalbytes=0, freebytes=0, bpb=0;

        bpb=idata->id_BytesPerBlock;
        usedbytes=bpb * idata->id_NumBlocksUsed;
        totalbytes=bpb * idata->id_NumBlocks;
        freebytes=totalbytes-usedbytes;
        printf("Bytes per block: %-7ld\n",bpb);
        printf("Total bytes: %-7ld\t\tFree Bytes: %-7ld\n",totalbytes,freebytes);
        printf("Total blocks: %-7ld\t\tFree Blocks: %-7ld\n\n",idata->id_NumBlocks,
                (idata->id_NumBlocks - idata->id_NumBlocksUsed));
}
