/* ******************************************************************************* * * upaaf.c * * Unpack an archive in apple format. * * Another quality product handcrafted with loving care by: * Jonathan A. Chandross * jac@paul.rutgers.edu * November 1990 * * COPYRIGHT 1990 by Jonathan A. Chandross * All rights reserved. * * Use "cc -D SHELL" to compile for use with a shell. * ******************************************************************************* */ #include /* ******************************************************************************* * * Defines * * EXPORT function is visible outside this module * IMPORT function is defined outside this module * STATIC function is invisible outside this module * * LENGTH length of strings * ******************************************************************************* */ #define EXPORT #define IMPORT extern #define LOCAL static #define SHELL #define LENGTH 255 /* ******************************************************************************* * * main * * Unpacks a file in Apple Archive Format * * Parameters: * argc number of command line arguments if compiled * for a shell * argv command line argument vector * Locals: * archive_name name of archive to unpack if not using a * shell * Returns: * * If this program is compiled for use with a shell, the first command line * argument is considered to contain the name of the archive to unpack. If * this program is compiled stand-alone, i.e. not for use with a shell, it * prompts for the archive to unpack. * * The SHELL define is an unsightly way to do things, but there is little * choice if this program is to be used on an Apple lacking some sort of * shell. * ******************************************************************************* */ #ifdef SHELL EXPORT int main(argc, argv) int argc; char *argv[]; #else EXPORT int main() #endif { IMPORT void unpack(); #ifdef SHELL IMPORT void usage(); #else char archive_name[LENGTH]; #endif #ifdef SHELL /* * If we are using a shell, then argv[1] will be the name of the * archive to unpack. */ if(argc == 2) unpack(argv[1]); else { usage(argv[0]); exit(1); } #else (void) fputs("Enter name of archive to unpack:", stdout); (void) scanf("%s", archive_name); unpack(archive_name); #endif return(0); } /* ******************************************************************************* * * usage * * Print out a message on how to use this program * * Parameters: * object_name name of object file storing this program * Locals: * Returns: * ******************************************************************************* */ #ifdef SHELL LOCAL void usage(object_name) char *object_name; { (void) fprintf(stderr, "Usage: %s archive-name\n", object_name); } #endif /* ******************************************************************************* * * unpack * * Unpack an archive * * Parameters: * archive_file_name name of archive file to unpack * Locals: * buffer holds each line as it is read out of archive * archive_file archive file * output_file current file being unpacked from archive * Returns: * ******************************************************************************* */ LOCAL void unpack(archive_file_name) char *archive_file_name; { IMPORT char *fgets(); IMPORT int fput(); IMPORT int strlen(); IMPORT int fclose(); IMPORT FILE *fopen(); char buffer[LENGTH]; FILE *archive_file; FILE *output_file = (FILE *)NULL; /* * Open the archive file and make sure it exists. */ if((archive_file = fopen(archive_file_name, "r")) == (FILE *)NULL) { (void) fprintf(stderr, "Error: could not open archive '%s'\n", archive_file_name); exit(1); } /* * As long as the file is not empty, process lines */ while(fgets(buffer, LENGTH, archive_file) != (char *)NULL) { /* * What kind of line do we have? */ switch(buffer[0]) { case '=': /* * Have a file name. Remove the trailing newline * from the file-name (left by fgets) by overwriting * with a Null. Then open the file and verify that * we can write to it. Skip over the first character * in the file-name (it is an '=') */ buffer[strlen(buffer) - 1] = '\0'; (void) fprintf(stdout, "Unpacking '%s'\n", &buffer[1]); /* * If we have an open output file, close it. */ if(output_file != (FILE *)NULL) (void) fclose(output_file); if((output_file = fopen(&buffer[1], "w")) == (FILE *)EOF) { (void) fprintf(stderr, "Error: could not open '%s'\n", buffer); exit(1); } break; case '-': /* * Have a line of source. Add the line to the output * file without the leading "-". */ if(output_file == (FILE *)NULL) { fputs("Error: no file specified.\n", stderr); exit(1); } else (void) fputs(&buffer[1], output_file); break; case '+': /* * End of archive. Exit. */ exit(0); break; default: /* * Have some other type of line (mail header, * signature, comment, etc.) Output it. */ (void) fputs(&buffer[0], stdout); break; } } }