/*************************************************************************** * FREE: Display free space on your disk devices. * Author: Daniel Jay Barrett, barrett@cs.jhu.edu. * Inspired by "FREE" by Tom Smythe on Fred Fish Disk #66, * but totally rewritten. One function, AvailSpace(), is an * updated version of Smythe's function avail(). * * This program is Freely Distributable. Make all the copies you want * and give them away. Use this code in any way you like. * * Changes/Improvements over Tom Smythe's program are: * * o Does not use self-modifying code, so it should work on * ALL Amigas, not just 68000-based systems. * o You can specify a device list on the command line. * o You can specify a device list using a Manx/ARP environment * variable. * o Requestors are turned off, so non-mounted devices are just * skipped. (See -m option.) * o Data is written in correct columns, regardless of the * lengths of the volume names. (See -l option.) * o Total memory free is shown, along with CHIP and FAST * subtotals. * o Command-line options added so the user can customize the * program. * o Written in ANSI C, in a modular and easy-to-read style. * * Daniel Jay Barrett makes no claims about the suitability of this program * for any particular purpose. Any damages incurred through the use of * this program are entirely the responsibility of the USER. Use at your * own risk. So there! :-) * ***************************************************************************/ #include "free.h" main(int argc, char *argv[]) { char *outArray = NULL; InitializeGlobals(); if ((argc == 2) && (EQUAL(argv[1], HELP_ARG))) Usage(argv[0]); else DoFree(argc, argv, &outArray); ExitCleanly(outArray, NO_ERROR, RETURN_OK); } /* Process the user's command-line options. * Allocate the out[] array for output. * Disable requestors, if necessary. * Measure the available RAM. * Then, measure free space on each desired device. * Print the output in a quick manner, using Write(). * Turn requestors back on, if they were turned off. */ void DoFree(int argc, char *argv[], char **out) { struct Process *proc; APTR oldWindowPtr; long chipRam, fastRam; int argIndex; argIndex = GetOptions(argc, argv); *out = MakeOutArray(); if (!(flags & FLAG_REQUESTORS)) DisableRequestors(&proc, &oldWindowPtr); GetFreeRam(&chipRam, &fastRam); if (argIndex >= argc) FreeUsingEnv(chipRam, fastRam, *out); else FreeFromArgs(argv+argIndex, chipRam, fastRam, *out); Write(Output(), *out, (long)strlen(*out)); /* For speed. */ if (!(flags & FLAG_REQUESTORS)) EnableRequestors(proc, oldWindowPtr); } /* The user specified no volumes as command-line arguments. So, check * the environment variable. If it has no value, then use DEFAULT_VOLUMES * instead. * We use the WONDERFUL function strtok() iteratively, to get the name of * each volume, one at a time. */ void FreeUsingEnv(long chipRam, long fastRam, char out[]) { static char *defaultVolumes = DEFAULT_VOLUMES; char *volume, *volumeList; volumeList = GetEnv(ENV_VARIABLE); if (!volumeList) volumeList = defaultVolumes; volume = strtok(volumeList, ENV_SEPARATOR); while (volume) { ShowFree(volume, chipRam, fastRam, out); volume = strtok(NULL, ENV_SEPARATOR); } } /* The user specified volumes on the command-line. Check each one. */ void FreeFromArgs(char *argv[], long chipRam, long fastRam, char out[]) { while (*argv) ShowFree(*argv++, chipRam, fastRam, out); } /* Process the user's command-line options. * Return the index of the first argument appearing AFTER all options. */ int GetOptions(int argc, char *argv[]) { register char c; long m; while ((c = getopt(argc, argv, OPTSTRING)) != EOF) { switch (c) { case OPT_BLOCKS: flags |= FLAG_BLOCKS; break; case OPT_REQUESTORS: flags |= FLAG_REQUESTORS; break; case OPT_MALLOC: flags |= FLAG_MALLOC; if ((m = atoi(optarg)) > 0) memSize = m; break; case OPT_VOLUME_NAME_LEN: flags |= FLAG_VOLUME_NAME_LEN; volumeNameLen = atoi(optarg); CheckVolumeNameLen(&volumeNameLen); break; case OPT_UNKNOWN: break; default: /* Sanity check! */ ExitCleanly((char *)NULL, ERROR_IMPOSSIBLE, RETURN_FAIL); break; } } return(optind); } /* Deallocate memory, print a message, and exit. */ void ExitCleanly(char *arr, ERROR errorCode, int exitCode) { if (arr) free(arr); if (errorCode) ErrorMsg(errorCode); exit(exitCode); } /* Like the name says... initialize our global variables. */ void InitializeGlobals() { flags = 0L; memSize = DEFAULT_MEMORY_LIMIT; volumeNameLen = DEFAULT_NAME_LEN; }