/* enough.c */ /* */ /* Run from a CLI execute file. If the resources you are */ /* checking for exist enough returns a return code of zero */ /* (0), if not it returns a warning value of five (5). */ /* Enough can be used to check for available memory and/or */ /* disk space, along with the existence of files. */ /* */ /* Syntax: */ /* enough [{MEM|FAST|CHIP} nnn[K]] [EXISTS file] */ /* [DISK drv: fff[K]] */ /* */ /* Typical usage (in startup script): */ /* failat 10 */ /* enough MEM 880k */ /* if NOT warn */ /* copy df0: ram: all */ /* assign c: ram:c */ /* assign .... */ /* endif */ /* */ /* Logic: * 1. verify CLI parameters, as they are used. * 2. For memory (MEM, FAST and CHIP) checks use Avail() to * see if there is enough memory. * 3. For disk (DISK) checks use Info() * 4. For existence testing (EXISTS) disable requesters and * use Lock(). * 5. If any of them fail return 5. * 6. If there is a syntax error in the command line return 20. * * Notes and cautions: * 1. the do_() functions should be stand-alone. * freeing any resources they might allocate. * 2. the do_() functions should increment the * cur_argc pointer past their keyword and any parameters * they use. This is a global. * 3. MAX_KEYWD_LEN is the length of the longest keyword, or more * * New featues that might be added: * 1. enough currently does nothing, could add a check for * this case and return DIE_BADARGS. * 2. Be nice to add something that would test for enough room * on a disk for a given file (enough FILESPACE foo bar:) */ #include "exec/types.h" #include "exec/memory.h" #include "libraries/dos.h" #include "libraries/dosextens.h" /* #include "stdio.h" #include "clib/macros.h" */ /* ------------ Constant Definitions ------------ */ /* version release and date information */ #define VERNO 1 #define RELNO 0 #define DATE "13-May-86" #define AUTHOR Bruce A. Barrett #define PUBLIC_DOMAIN TRUE /* reason for terminating through cleanup() */ #define DIE_OK 0 #define DIE_MEM 1 #define DIE_NOOUTPUT 2 #define DIE_BADARGS 3 #define DIE_S_DIR 4 #define DIE_D_DIR 5 #define DIE_S_FILE 6 #define DIE_D_FILE 7 #define DIE_FIBOVERFLOW 8 #define DIE_FIBUNDERFLOW 9 #define DIE_CTRL_C 10 #define DIE_NOT_ENOUGH 11 #define MAX_KEYWD_LEN 12 /* For debugging, as required */ #define FIX FALSE #if FIX #define ROUTINE(foo) kprintf(foo) /* debug */ #else #define ROUTINE(foo) /* don't */ #endif /* ------------ Global Variables ------------ */ int f_lock; struct FileInfoBlock *file_info_block; int cur_argc; int gl_argc; main(argc, argv) int argc; char *argv[]; { /* ------------ Local Variables ------------ */ char key_wd[MAX_KEYWD_LEN]; int ret_val; /* */ /* M A I N L O G I C */ /* */ /* setup */ ROUTINE("main\n"); /* kprintf("\n---------------------------------\n"); kprintf("%s: Version %ld.%ld, %s\n", argv[0], VERNO, RELNO, DATE); */ gl_argc = argc; ret_val = DIE_OK; cur_argc = 1; while ( (cur_argc < argc) && (ret_val == DIE_OK)) { testbreak(); uc_copy(key_wd, argv[cur_argc]); if (0 == strcmp(&key_wd[0],"MEM")) ret_val = do_mem(argv); else if (0 == strcmp(&key_wd[0],"CHIP")) ret_val = do_chip(argv); else if (0 == strcmp(&key_wd[0],"FAST")) ret_val = do_fast(argv); else if (0 == strcmp(&key_wd[0],"DISK")) ret_val = do_disk(argv); else if (0 == strcmp(&key_wd[0],"EXISTS")) ret_val = do_exists(argv); else {ret_val = DIE_BADARGS; printf("%s: Version %ld.%ld, %s\n", argv[0], VERNO, RELNO, DATE); } } cleanup(argv, ret_val); } /* ------------ suppress_IO_err() ------------ */ /* Prevent AmigaDOS from putting up a "Please insert */ /* volume..." requester. */ APTR suppress_IO_err() { struct Process *my_proc, *FindTask(); APTR old_window; ROUTINE("suppress_IO_err\n"); my_proc = FindTask(""); old_window = my_proc->pr_WindowPtr; my_proc->pr_WindowPtr = (APTR) -1; return(old_window); } /* ------------ allow_IO_err() ------------ */ /* Allow AmigaDOS to put up a "Please insert volume..." */ /* requester. */ void allow_IO_err(old_wind) APTR old_wind; { struct Process *my_proc; ROUTINE("allow_IO_err\n"); my_proc = FindTask(""); my_proc->pr_WindowPtr = old_wind; } /* ---------- do_mem_type() ------------------------------ */ /* Given a memory type, see if there is enough available */ do_mem_type(argv, type) char *argv[]; int type; { int avail; /* memory available of this type */ int need; /* memory of this type needed */ ROUTINE("do_mem_type\n"); if (cur_argc >= gl_argc) return(DIE_BADARGS); avail = AvailMem(type); sscanf(argv[cur_argc], "%d", &need); cur_argc++; if (need == 0) return(DIE_BADARGS); if ((need*1024) <= avail) return(DIE_OK); else return(DIE_NOT_ENOUGH); } /* ---------- do_mem() ------------------------------ */ do_mem(argv) char *argv[]; { ROUTINE("do_mem\n"); cur_argc++; return(do_mem_type(argv, MEMF_LARGEST)); } /* ---------- do_chip() ------------------------------ */ do_chip(argv) char *argv[]; { ROUTINE("do_chip\n"); cur_argc++; return(do_mem_type(argv, MEMF_CHIP|MEMF_LARGEST)); } /* ---------- do_fast() ------------------------------ */ do_fast(argv) char *argv[]; { ROUTINE("do_fast\n"); cur_argc++; return(do_mem_type(argv, MEMF_FAST|MEMF_LARGEST)); } /* ---------- do_disk() ------------------------------ */ /* Format is: ENOUGH DISK disk_name: fff[k] */ do_disk(argv) char *argv[]; { /* do_disk */ int need; int ret_val; LONG my_lock; LONG free; BOOL result; APTR old_ptr; struct InfoData *info_data; ROUTINE("do_disk\n"); info_data = 0; /* remove a Lattice warning */ cur_argc++; /* Skip "DISK" keyword */ ret_val = DIE_NOT_ENOUGH; /* -- test for enough arguments on the command line -- */ if ((cur_argc+1) >= gl_argc) return(DIE_BADARGS); /* -- test for the existence of the drive/volume -- */ old_ptr = (APTR) suppress_IO_err(); /* defeat "insert vol" requester */ my_lock = Lock(argv[cur_argc], MODE_OLDFILE); allow_IO_err(old_ptr); /* re-enable requesters. */ cur_argc++; if (my_lock == 0) return(ret_val); /* -- get info about the drive -- */ info_data = (struct InfoData *) AllocMem(sizeof(*info_data), 0); if (info_data == 0) { UnLock(my_lock); return(ret_val); } result = Info(my_lock, info_data); if (!result) { UnLock(my_lock); FreeMem(info_data, sizeof(*info_data)); return(ret_val); } /* -- get the amount of disk space needed -- */ sscanf(argv[cur_argc], "%d", &need); cur_argc++; if (need == 0) { UnLock(my_lock); FreeMem(info_data, sizeof(*info_data)); return(DIE_BADARGS); } free = (info_data->id_NumBlocks - info_data->id_NumBlocksUsed) * info_data->id_BytesPerBlock; UnLock(my_lock); FreeMem(info_data, sizeof(*info_data)); if (free > (need*1024) ) ret_val = DIE_OK; return(ret_val); } /* ---------- do_exists() ------------------------------ */ do_exists(argv) char *argv[]; { LONG my_lock; APTR old_ptr; ROUTINE("do_exists\n"); cur_argc++; old_ptr = (APTR) suppress_IO_err(); /* defeat "insert vol" requester */ if (cur_argc >= gl_argc) return(DIE_BADARGS); my_lock = Lock(argv[cur_argc], MODE_OLDFILE); allow_IO_err(old_ptr); cur_argc++; if (my_lock == 0) return(DIE_NOT_ENOUGH); UnLock(my_lock); return(DIE_OK); } /* ==================================================== */ /* ================== Subroutines ===================== */ /* enough.h /* ==================================================== */ /* ---------- uc_copy() ------------------------------ */ /* Copy characters from one string to another, making */ /* it upper case at it goes. */ uc_copy(to, from) char *to; char *from; { ROUTINE("uc_copy\n"); while (*to++ = toupper(*from++)) ; } /* ---------- testbreak() ------------------------------ */ /* tests for a ^C (CTRL-C), calls cleanup() if found, */ /* otherwise returns. */ testbreak(argv) char *argv[]; { LONG newsigs; LONG oldsigs; ROUTINE("testbreak\n"); newsigs = 0; oldsigs = SetSignal(newsigs, SIGBREAKF_CTRL_C); if (oldsigs & (SIGBREAKF_CTRL_C) ) { cleanup(argv, DIE_CTRL_C); } /* end of if */ } /* end of testbreak() */ /* ------------ cleanup(argv, cause) ------------ */ cleanup(argv, cause) int cause; char *argv[]; { ROUTINE("cleanup\n"); /* kprintf ("cleanup # %ld, IoErr() = %ld\n", cause, IoErr()); */ switch (cause) { case DIE_OK: case DIE_MEM: case DIE_NOOUTPUT: case DIE_S_DIR: case DIE_D_DIR: case DIE_S_FILE: case DIE_D_FILE: case DIE_FIBOVERFLOW: case DIE_FIBUNDERFLOW: case DIE_NOT_ENOUGH: break; case DIE_BADARGS: printf("%s: Error -- Bad command line arguments.\n", argv[0]); /* enough */ /* */ printf("%s: Syntax is %s [{MEM|FAST|CHIP} nnn[K]] [EXISTS file]\n", argv[0], argv[0]); printf(" [DISK drv: fff[K]]\n"); printf("nnn is the number of K in RAM required, fff is the\n"); printf("number of K on the disk \"drv:\" required, file is a\n"); printf("path name you want to check for the existence of.\n"); break; case DIE_CTRL_C: printf("%s: *Break* Stopped by user.\n", argv[0]); break; } ROUTINE("exit\n"); if (cause == DIE_OK) exit(0); else if (cause == DIE_BADARGS) exit(20); /* syntax error!! */ else exit(5); }