jac@paul.rutgers.edu (Jonathan A. Chandross) (11/19/90)
Submitted-by: gwyn@brl.mil
Posting-number: Volume 1, Source:3
Archive-name: archive/aaf_gwyn
Architecture: ANY_2
Version-number: 1.00
Enclosed is Doug Gwyn's version of the AAF tools. These implement
the same functionality as my tools but may be more appropriate to
a different set of C compilers or to your view of how the AAF tools
should work.
You can unpack this with the upaaf.c program I posted earlier.
Enjoy.
*************************************
=Read.Me
-
-Program: apack
-Function: pack text files into archive for convenient shipment
-Author: Douglas A. Gwyn <Gwyn@BRL.MIL>
-Restrictions: PUBLIC DOMAIN; no restrictions
-
-This program creates an Apple Archive Format (AAF) archive file that
-contains copies of any number of text files; the corresponding "aunpack"
-program may be used to unpack AAF archives back into a set of text files
-with the same contents as the originals. AAF archives are suitable for
-transmission of collections of text files, including source code, among
-different computer systems, for example via electronic mail and USEnet
-newsgroups. AAF is the official archive format for the USEnet
-comp.sources.apple2 newsgroup; the article having subject header
-"V001INF001: Apple Archive Format" in that newsgroup contains the AAF
-specifications. Note that AAF is not specific to Apple computers, and
-may be used for archiving text files on practically any computer system.
-AAF archives are intentionally not compressed, so that they may be read
-directly, edited, etc. without having to first be unpacked.
-
-See the "apack" source for instructions and further information.
-
=apack.c
-/*
- apack -- pack text files into archive for convenient shipment
-
- This source code is the original creation of Douglas A. Gwyn, who
- has released it into the PUBLIC DOMAIN; there are no restrictions
- whatever on its further use. However, it would be unwise to make
- altered versions that are incompatible with the AAF specification.
-
- last edit: 31-Oct-1990 D A Gwyn
-
- INSTRUCTIONS: Compile this source using almost any hosted
- implementation of C, and link with the standard C system library,
- according to whatever procedures are necessary for your particular
- environment. To use this program, you must invoke it from an
- environment that allows you to specify arguments and/or file
- redirection.
-
- Usage: apack files... > archive
-
- The specified text files are written into the archive, each file
- preceded by a header line containing "=" followed by the filename.
- Each line of file data is preceded by "-". After all files are
- written, an additional line consisting of "+END" is appended to
- the archive. This conforms to the Apple Archive Format (AAF)
- used for postings to the USEnet comp.sources.apple2 newsgroup.
-
- Since file contents are copied untranslated into the archive,
- it is a good idea to not use control characters in the files,
- as they may be mangled during transmission of the archive.
- In particular, embedded carriage-returns might be mapped to
- new-lines on the target system, resulting in incorrect unpacking
- of the archive. It is recommended that text lines not exceed 79
- characters. For filenames to be maximally portable, they should
- each consist of an alphabetic character followed by no more than
- five alphanumeric characters, optionally followed by a "." then
- one to three additional alphanumeric characters.
-
- The archive is printable as it stands; the companion program
- "aunpack" may be used to unpack the archive into files having the
- same names as the original files. Because "aunpack" does not
- check filenames for "funny" characters, but merely attempts to
- open the named files for writing, if filenames that are not
- suitable for the target environment were used, those files may
- not be extracted; in particular, directory path syntax may not
- be understood. Fortunately, it is easy to edit an "apack"ed
- archive to change the filenames when necessary before unpacking.
-
- If "aunpack" is not available, an "apack"ed archive can fairly
- easily be manually unpacked with a decent text editor.
-*/
-
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#include <string.h>
-#else
-extern void exit();
-extern char *strcat(), *strcpy();
-
-#define EXIT_SUCCESS 0
-#define EXIT_FAILURE 1
-#endif
-
-static char buffer[BUFSIZ];
-
-int
-main( argc, argv )
- int argc;
- char *argv[];
- {
- register int i; /* file number */
- register FILE *fp = NULL; /* input text stream */
-
- for ( i = 1; i < argc; ++i )
- if ( (fp = fopen( argv[i], "r" )) == NULL )
- (void)fprintf( stderr, "apack: can't open \"%s\"\n",
- argv[i]
- );
- else {
- buffer[0] = '=';
- /*(void)*/strcpy( &buffer[1], argv[i] );
- /*(void)*/strcat( &buffer[1], "\n" );
-
- if ( fputs( buffer, stdout ) == EOF )
- {
- (void)fprintf( stderr, "apack: write error\n" );
- exit( EXIT_FAILURE );
- }
-
- buffer[0] = '-';
-
- while ( fgets( &buffer[1], BUFSIZ - 1, fp ) != NULL )
- if ( fputs( buffer, stdout ) == EOF )
- {
- (void)fprintf( stderr,
- "apack: write error\n"
- );
- exit( EXIT_FAILURE );
- }
-
- (void)fclose( fp );
- }
-
- (void)printf( "+END\n" );
-
- if ( fflush( stdout ) != 0 )
- {
- (void)fprintf( stderr, "apack: write error\n" );
- exit( EXIT_FAILURE );
- }
-
- return EXIT_SUCCESS;
- }
=aunpack.c
-/*
- aunpack -- unpack text files from archive for convenient shipment
-
- This source code is the original creation of Douglas A. Gwyn, who
- has released it into the PUBLIC DOMAIN; there are no restrictions
- whatever on its further use. However, it would be unwise to make
- altered versions that are incompatible with the PAAF specification.
-
- last edit: 31-Oct-1990 D A Gwyn
-
- INSTRUCTIONS: Save this article, minus the header information,
- as "aunpack.c". This particular source is not distributed in
- PAAF (archived) format, because it is the program that unpacks
- PAAF files, and if you didn't already have it you would have to
- manually unpack it, which could be tedious. Compile this source
- using almost any hosted implementation of C, and link with the
- standard C system library, according to whatever procedures are
- necessary for your particular environment. It , like the PAAF
- format, is not Apple-specific, and indeed I use it on several
- UNIX systems, as well as on my Apple II. To use this program,
- you must invoke it from an environment that allows you to specify
- arguments and/or file redirection.
-
- Usage: aunpack [-c] [-r] [-v] < archive
- or aunpack [-c] [-r] [-v] archive
-
- The archive must be in PAAF format, as created by the companion
- program "apack". Any line found in the archive that does not
- start with one of the expected characters ("=", "-", or "+")
- will be copied to the standard output; anything following a
- filename header will be sent to that named file. The -c option
- permits the continued recognition of tagged lines after a "+"
- line; the default is for the first "+" to end the archive. (-c
- is useful when you have concatenated several PAAF archives into
- a single file.) The -r option causes carriage-return characters
- in the archive to be taken as line terminators; this is not
- normally necessary, but may be helpful in some special situations.
- The -v option causes each filename to be printed to the standard
- error output immediately after successfully opening the file for
- writing.
-
- See the "apack" source for further information and the PAAF spec.
-*/
-
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#include <string.h>
-#else
-extern void exit();
-/* #define strchr index /* if necessary for your system */
-extern char *strcat(), *strchr(), *strcpy(), *strncpy();
-extern int strcmp();
-
-#define EXIT_SUCCESS 0
-#define EXIT_FAILURE 1
-#endif
-
-static char buffer[BUFSIZ];
-static char iname[BUFSIZ] = { "stdin" }; /* archive input filename */
-static char oname[BUFSIZ - 1]; /* current output filename */
-static int status = EXIT_SUCCESS; /* EXIT_FAILURE if stdout write fails */
-
-int
-main( argc, argv )
- int argc;
- char *argv[];
- {
- register FILE *ifp = stdin; /* input stream */
- register FILE *ofp = NULL; /* current output stream */
- register char *bp;
- int concat = 0; /* indicates -c flag was specified */
- int map_crs = 0; /* indicates -r flag was specified */
- int verbose = 0; /* indicates -v flag was specified */
- int end_seen = 0; /* indicates "+" record was seen */
-
- for ( ; argc > 1; ++argv, --argc )
- if ( strcmp( argv[1], "-v" ) == 0 )
- verbose = 1;
- else if ( strcmp( argv[1], "-c" ) == 0 )
- concat = 1;
- else if ( strcmp( argv[1], "-r" ) == 0 )
- map_crs = 1;
- else /* not an option */
- break;
-
- if ( argc > 1 )
- if ( (ifp = fopen( argv[1], "r" )) == NULL )
- {
- (void)fprintf( stderr, "aunpack: can't open \"%s\"\n",
- argv[1]
- );
- exit( EXIT_FAILURE );
- }
- else {
- iname[0] = '"';
- /*(void)*/strncpy( &iname[1], argv[1], BUFSIZ - 3 );
- iname[BUFSIZ - 2] = '\0'; /* just in case */
- /*(void)*/strcat( &iname[1], "\"" );
- }
-
- for ( ; ; )
- {
- if ( map_crs )
- {
- register int c;
-
- bp = buffer;
-
- do {
- if ( (c = getc( ifp )) == EOF )
- goto eof_or_error;
-
- if ( c == '\r' )
- c = '\n';
-
- *bp++ = c;
- }
- while ( c != '\n' && bp < &buffer[BUFSIZ - 1] );
-
- *bp = '\0';
- }
- else
- if ( fgets( buffer, BUFSIZ, ifp ) == NULL )
- goto eof_or_error;
-
- if ( (bp = strchr( buffer, '\n' )) == NULL )
- {
- (void)fprintf( stderr,
- "aunpack: excessively long input line:\n%s\n",
- buffer
- );
- goto look_out;
- }
-
- switch ( buffer[0] )
- {
- case '=':
- if ( end_seen && !concat )
- goto junk_line;
-
- if ( ofp != NULL && fclose( ofp ) != 0 )
- goto write_error;
-
- *bp = '\0'; /* remove new-line */
-
- /*(void)*/strcpy( oname, &buffer[1] );
-
- if ( (ofp = fopen( oname, "w" )) == NULL )
- {
- (void)fprintf( stderr,
- "aunpack: can't create \"%s\"\n",
- oname
- );
- exit( EXIT_FAILURE );
- }
-
- if ( verbose )
- (void)fprintf( stderr, "%s\n", oname );
-
- break;
-
- case '-':
- if ( end_seen && !concat )
- goto junk_line;
-
- if ( ofp == NULL )
- {
- (void)fprintf( stderr,
- "aunpack: data before filename\n",
- oname
- );
- exit( EXIT_FAILURE );
- }
-
- if ( fputs( &buffer[1], ofp ) == EOF )
- goto write_error;
-
- break;
-
- case '+':
- end_seen = 1;
-
- if ( ofp != NULL && fclose( ofp ) != 0 )
- goto write_error;
-
- ofp = NULL;
-
- break; /* keep going, in case of more stdout */
-
- default:
- junk_line:
- if ( status == EXIT_SUCCESS
- && fputs( buffer, stdout ) == EOF
- ) {
- (void)fprintf( stderr,
- "aunpack: error writing stdout\n"
- );
-
- status = EXIT_FAILURE; /* keep going, though */
- }
-
- break;
- }
- }
-
- write_error:
-
- (void)fprintf( stderr, "aunpack: error writing \"%s\"\n", oname );
-/* goto look_out; */
-
- look_out:
-
- if ( ofp != NULL )
- (void)fprintf( stderr, "aunpack: \"%s\" may be corrupted!\n",
- oname
- );
-
- exit( EXIT_FAILURE );
-
- eof_or_error:
-
- if ( ferror( ifp ) )
- {
- (void)fprintf( stderr, "aunpack: error reading %s\n", iname );
- goto look_out;
- }
-
- if ( !end_seen )
- {
- (void)fprintf( stderr, "aunpack: missing \"+\" record\n" );
- goto look_out;
- }
-
- if ( ofp != NULL && fclose( ofp ) != 0 )
- {
- (void)fprintf( stderr, "aunpack: error writing \"%s\"\n", oname
- );
- goto look_out;
- }
-
- return status; /* failure is relatively unimportant */
- }
-
+ END OF ARCHIVE