jac@paul.rutgers.edu (Jonathan A. Chandross) (02/17/91)
Submitted-by: marcel@duteca.tudelft.nl
Posting-number: Volume 1, Source:28
Archive-name: archive/unix/marcel/part2
Architecture: UNIX
Version-number: 1.00
This is part 2 of a 2 part posting.
=sciibin.c
-/* @(#) sciibin.c 3.01 12Feb91 */
-/*************************************************************************
- ** **
- ** Name : sciibin **
- ** Author : Marcel J.E. Mol **
- ** Date : 06Mar89 (first release) **
- ** Version : 2.00 **
- ** Files : sciibin.c Main source file **
- ** Purpose : Extract or view BinSCII files **
- ** **
- ** ------------------------- Revision List ------------------------- **
- ** Ver Date Name Remarks **
- ** 1.00 06Mar89 Marcel Mol First release **
- ** 1.10 27Mar89 Marcel Mol Fished things up, error routine, **
- ** linecount, all info fields filled **
- ** in, changed info layout. **
- ** 2.00 03Jun89 Marcel Mol Bug fixes: alphabet to unsigned **
- ** (Dave Whitney) char. Some OS's need types.h. **
- ** Fixed CRE/MOD order. **
- ** Output filenames can be wrong **
- ** when multiple files are **
- ** extracted. Made crc and file- **
- ** type arrays in seperate includes **
- ** 3.00 22Mar90 Marcel Mol Includeed ports of Bruce Kahn **
- ** 1.30 27 Feb 90 Bruce Kahn Ported to AOS/VS C 4.01 and MSC 5.1 **
- ** Added explicit long definitions **
- ** needed. **
- ** Redid layouts for dates to be US. **
- ** Modified the open routines for MSC **
- ** to include binary mode, not text. **
- ** Changed the way 8 bit integers are **
- ** handled (redone MM). **
- ** Added getopt() (see below MM). **
- ** 3.01 22Feb91 Marcel Mol Fixed bug: only close output **
- ** when output is generated. **
- ** ================================================================= **
- ** **
- ** Compile as follows: **
- ** If you don't have getopt, compile and link the given getopt.c **
- ** **
- ** UNIX: cc sciibin.c -Oso sciibin **
- ** **
- ** MSC 5.1: cl /c /Ox sciibin.c **
- ** (add /DMSDOS, if MSC didn't do it) **
- ** link /CO /STACK:10000 sciibin; **
- ** **
- ** AOS/VS: cc sciibin.c **
- ** ccl sciibin **
- ** **
- ** Defining DEBUG gives some debug information. **
- ** Defining DEBUGALL gives input and output of the decode routine. **
- ** **
- ** Usage: sciibin [-hvtc] [-o<outputfile>] <infiles> **
- ** **
- ** -v show only info on file, do not create output. **
- ** -t test file, do not create output. **
- ** -c do not check checksums. **
- ** -o create given filename instead of the one in **
- ** binscii file. Use this only if the input files **
- ** contain only one output file. **
- ** -h help. **
- ** **
- ** **
- ** This software is freeware. We can not be held responsible to **
- ** any damage this program may coase you or anyone or anything else. **
- ** **
- ** Mail bugs to: marcel@duteca.tudelft.nl **
- ** **
- ************************************************************************/
-
-
-#include <stdio.h>
-#include <sys/types.h> /* keep sun OS happy */
-#include <sys/stat.h> /* mostly includes types.h ... */
-#if defined(MSDOS)
-#include <memory.h> /* For the memset function */
-#endif
-#include "crc.h"
-#include "filetype.h"
-
-#define BUFLEN 256
-#define FILENAME_LEN 15
-#define BINSCII_HEADER "FiLeStArTfIlEsTaRt\n"
-#define MAXSEGLEN 0x3000
-
-#if defined(INT8)
-typedef long int16;
-#else
-typedef int int16;
-#endif
-
-/* ==> Expect int variables to be at least 16 bits
- * Global variables ==> and longs to be at least 32 bits
- * ==> If not, you have some work to do...
- */ /* MSDOS has 16 bit ints. */
-char buf[BUFLEN+1];
-unsigned char dec[BUFLEN+1];
-unsigned char alphabet[BUFLEN+1]; /* need $FF in alphabet */
-char outfilename[BUFLEN+1];
-
-
-unsigned char outflag = 0, /* the -o option */
- crcflag = 0, /* the -c option */
- infoflag = 0, /* the -v option */
- testflag = 0, /* the -t option */
- makeoutput, /* ! (-t | -v) */
- crcok; /* -t | -c */
-FILE *outfp; /* output file */
-
-unsigned char filetype, stortype,
- file_access; /* access -> file_access for MSDOS */
-unsigned char modyear, modmonth, modday, modhour, modmin,
- creyear, cremonth, creday, crehour, cremin;
-int namlen, linecount,
- numblocks, auxtype;
-long filesize, startbyte, segmentlen;
-char * infilename;
-
-char * progname;
-
-
-/*
- * function declarations
- */
-int main ();
-int sciibin ();
-int getheader ();
-int decode ();
-int decodestring ();
-char *myfgets ();
-void usage ();
-void error ();
-
-
-char * copyright = "@(#) sciibin.c 3.01 12Feb91 (c) 1989, 1991 M.J.E. Mol";
-
-main(argc, argv)
-int argc;
-char **argv;
-{
- FILE *fp;
- int c;
- extern int optind; /* For getopt */
- extern char * optarg; /* For getopt */
- int flag; /* Flag for getopt */
-
- progname = *argv;
-
- while ((flag = getopt(argc, argv, "hvcto:")) != EOF) { /* Process options */
- switch (flag) {
- case 'v': infoflag = 1; /* Want only info of file */
- break;
- case 'h': usage(); /* Give help */
- exit(0);
- case 'c': crcflag = 1;
- break;
- case 't': testflag = 1;
- break;
- case 'o':
-#if defined(MSDOS)
- memset(outfilename, NULL, FILENAME_LEN + 1);
-#endif
- strcpy(outfilename, optarg);
- outflag = 1;
- break;
- default : fprintf(stderr, "%s: skipping unkown flag %c, use -h.\n",
- progname, flag);
- break;
- }
- }
-
- makeoutput = !(testflag | infoflag);
- crcok = testflag | crcflag;
-
-#if defined(DEBUG)
- fprintf(stderr, "make output: %d, crcok: %d\n", makeoutput, crcok);
-#endif
-
- if (optind >= argc) { /* No files given, use stdin */
- infilename = "stdin";
- linecount = 0;
- sciibin(stdin);
- }
- else
- while (optind < argc) {
- infilename = argv[optind];
- optind++;
- if ((fp = fopen(infilename, "r")) == NULL) {
- perror(infilename);
- continue;
- }
- linecount = 0;
- sciibin(fp);
- fclose(fp);
- }
-
- exit(0);
-
-} /* main */
-
-
-
-/*
- * Walk over the file processing all segments in it
- */
-sciibin(fp)
-FILE *fp;
-{
- int processed = 0; /* number of processed binscii segments */
- int status = 0; /* return codes of calls to decode */
-
- while (myfgets(buf, BUFLEN, fp) != NULL) {
-
-#if defined(DEBUG)
- fprintf(stderr, "(%s) get start:%s", infilename, buf);
-#endif
-
- if (!strncmp(buf, BINSCII_HEADER, strlen(BINSCII_HEADER))) {
- if (!getheader(fp) && !infoflag) /* if header ok and not -v flag */
- status |= decode(fp);
- processed++;
- }
- }
-
- if (processed == 0) {
- error("not a BinSCII file");
- return 1;
- }
-
- return status;
-
-} /* sciibin */
-
-
-
-/*
- * Build the alphabet, get the output file info and open output file
- * if necessary.
- * Still contains lots of debug code to find out the header structure.
- * (every bit is known now...)
- */
-getheader(fp)
-FILE *fp;
-{
- register int i, j;
- register int16 crc = 0;
- struct stat statbuf; /* MUST know if file exists */
- char *iomod; /* write or readwrite a file */
-
- /*
- * Get the alphabet
- */
- if (myfgets(buf, BUFLEN, fp) == NULL) {
- error("reading alphabet: unexpected end of file");
- return 1;
- }
-
-#if defined(DEBUG)
- fprintf(stderr, "(%s) alphabet:%s", infilename, buf);
-#endif
-
- if (strlen(buf) != 65) {
- error("alphabet corrupted");
- return 1;
- }
-
- /*
- * Process the alphabet
- */
- for (i = 0; i < BUFLEN; i++)
- alphabet[i] = 0xff;
-
- for (i = 0; i < 64; i++) {
- j = buf[i];
- if (alphabet[j] != 0xff)
- error("Warning: double character in alphabet");
- alphabet[j] = i;
- }
-
-#if defined(DEBUG)
- for (i = 0; i < BUFLEN; i+=16) {
- fprintf(stderr, "(%s) alphabet[%3d] =", infilename, i);
- for (j = 0; j < 16; j++)
- fprintf(stderr, " %02X", alphabet[i+j]);
- putc('\n', stderr);
- }
-#endif
-
- /*
- * Get the file header
- */
- if (myfgets(buf, BUFLEN, fp) == NULL) {
- error("reading fileheader: unexpected end of file");
- return 1;
- }
-
-#if defined(DEBUG)
- fprintf(stderr, "(%s) fileheader:%s", infilename, buf);
-#endif
-
- /*
- * Extract output filename if needed
- */
- if (!outflag) {
- namlen = *buf - 'A' + 1; /* IS +1 NEEDED ?? */
-#if defined(MSDOS)
- memset(outfilename, NULL, FILENAME_LEN + 1);
-#endif
- strncpy(outfilename, buf+1, namlen);
- outfilename[namlen] = '\0';
- }
-
-#if defined(DEBUG)
- fprintf(stderr, "(%s) filename:**%s**\n", infilename, outfilename);
- fprintf(stderr, "(%s) fileinfo:**%s**", infilename, buf+16);
-#endif
-
- /*
- * Decode and process the file header information
- */
- if ((i = decodestring(buf+FILENAME_LEN+1, dec)) != 27)
- error("warning: corrupted file header length");
-
- for (i = 0; i < 24; i++)
- crc = updcrc(dec[i], crc);
-
- if (crc != (dec[24] | (dec[25] << 8))) {
- if (crcok)
- error("warning: CRC error in file header");
- else {
- error("error: CRC error in file header");
- return 1;
- }
- }
-
- /* Calculate file length */
- filesize = dec[0] + (dec[1]<<8) + ((long) dec[2]<<16);
- startbyte = dec[3] + (dec[4]<<8) + ((long) dec[5]<<16);
-
- /* Calculate file attributes and size */
- file_access= dec[6];
- filetype = dec[7];
- auxtype = dec[8] + (dec[9] << 8);
- stortype = dec[10];
- numblocks = dec[11] + (dec[12]<<8);
-
- /* Calculate creation and modification dates */
-#define MOD 13
-#define CRE 17 /* perhaps creation and modification date are swapped */
- creday = dec[CRE] & 0x1f;
- cremonth = ((dec[CRE+1] & 0x01) << 3) | (dec[CRE] >> 5);
- creyear = dec[CRE+1] >>1;
- cremin = dec[CRE+2] & 0x3f;
- crehour = dec[CRE+3] & 0x1f;
- modday = dec[MOD] & 0x1f;
- modmonth = ((dec[MOD+1] & 0x01) << 3) | (dec[MOD] >> 5);
- modyear = dec[MOD+1] >>1;
- modmin = dec[MOD+2] & 0x3f;
- modhour = dec[MOD+3] & 0x1f;
-
- segmentlen = dec[21] + (dec[22]<<8) + ((long) dec[23]<<16);
- if (segmentlen > MAXSEGLEN)
- error("warning: segmentlen probably to long");
-
-#define READ 0x01
-#define WRITE 0x02
-#define BACKUP 0x20
-#define RENAME 0x40
-#define DESTROY 0x80
-
- if (infoflag) {
-
- /* Display the files name, type and auxtype */
- printf("%-15s %3s aux: $%04X ",
- outfilename, filetypes[filetype], auxtype);
-
- /* Display the file access type */
- putchar(file_access & READ ? 'r' : '-');
- putchar(file_access & WRITE ? 'w' : '-');
- putchar(file_access & RENAME ? 'n' : '-');
- putchar(file_access & DESTROY ? 'd' : '-');
- putchar(file_access & BACKUP ? 'b' : '-');
-
- /* Display the type of file this is - ProDOS Specific */
- switch (stortype) {
- case 0x0F : printf(" voldir"); break;
- case 0x0D : printf(" dir"); break;
- case 0x01 : printf(" seed"); break;
- case 0x02 : printf(" sap"); break;
- case 0x03 : printf(" tree"); break;
- default : printf(" ???"); break;
- }
-
- /* Display modification and creation information */
- printf(" %02d/%02d/%02d(%02d:%02d) -", modmonth, modday, modyear,
- modhour, modmin);
- printf(" %02d/%02d/%02d(%02d:%02d)\n", cremonth, creday, creyear,
- crehour, cremin);
-
- /* Display segment information */
- printf("Part %4d of %4d,", (int) (startbyte / MAXSEGLEN) + 1,
- (int) ((filesize + MAXSEGLEN-1) / MAXSEGLEN));
- printf(" bytes %7ld to %7ld of %7ld bytes, %5d blocks\n",
- startbyte, startbyte+segmentlen, filesize, numblocks);
-
- } /* if (infoflag) */
-
- if (makeoutput) {
- /* will creating output, not just information so verify the access */
-#if defined(MSDOS)
- iomod = (stat(outfilename, &statbuf) == 0) ? "r+b" : "wb";
-#else
- iomod = (stat(outfilename, &statbuf) == 0) ? "r+" : "w";
-#endif
- if ((outfp = fopen(outfilename, iomod)) == NULL) {
- error("unable to open output file");
- perror(outfilename);
- return 1;
- }
- fseek(outfp, startbyte, 0);
- } /* if (makeoutput) */
-
- return 0;
-
-} /* getheader */
-
-
-
-/*
- * Do the actual decoding of the bin data.
- */
-decode(fp)
-FILE *fp;
-{
- register int i;
- register int crc = 0;
- int len;
-
- crc = 0;
- while (segmentlen > 0) {
- if (myfgets(buf, BUFLEN, fp) == NULL) {
- error("reading file: unexpected end of file");
- return 1;
- }
-
-#if defined(DEBUG)
- fprintf(stderr, "(%s) data:%s", infilename, buf);
-#endif
-
- if ((len = decodestring(buf, dec)) != 48)
- error("warning: corrupted line length");
- for (i = 0; i < 48; i++)
- crc = updcrc(dec[i], crc);
- if (makeoutput)
- for (i = 0; (i < len) && (segmentlen > 0); i++, segmentlen--)
- putc(dec[i], outfp); /* COULD CR/NL TXT FILES */
- else
- segmentlen -= len;
-
-#if defined(DEBUG)
- fprintf(stderr, "(%s) still need %d bytes\n", infilename, segmentlen);
-#endif
-
- }
-
- /*
- * must be at end of segment now, with one remaining line containing
- * the crc check.
- */
- if (myfgets(buf, BUFLEN, fp) == NULL) {
- error("reading file crc: unexpected end of file");
- return 1;
- }
-
-#if defined(DEBUG)
- fprintf(stderr, "(%s) crc:%s", infilename, buf);
-#endif
-
- if ((len = decodestring(buf, dec)) != 3)
- error("warning: corrupted crc length");
- if (crc != (dec[0] | (dec[1] << 8))) {
- if (crcok)
- error("warning: CRC error in file data");
- else {
- error("error: CRC error in file data");
- return 1;
- }
- }
-
- if (makeoutput)
- fclose(outfp);
-
- return 0;
-
-} /* decode */
-
-
-/*
- * Decode one string off scii characters to binary data, meanwhile
- * calculating crc.
- */
-decodestring(in, out)
-register char *in;
-register unsigned char *out;
-{
- register int len = 0;
-
-#if defined(DEBUGALL)
- char *b;
-
- fprintf(stderr, "(%s) decode in: %s\n", infilename, in);
- b = in;
- while (*b)
- fprintf(stderr, ".%02X", alphabet[*b++]);
- putc('\n', stderr);
- b = out;
-#endif
-
- while (strlen(in) > 3) {
- *out++ = ((alphabet[in[3]] << 2) | (alphabet[in[2]] >> 4)) & 0xFF;
- *out++ = ((alphabet[in[2]] << 4) | (alphabet[in[1]] >> 2)) & 0xFF;
- *out++ = ((alphabet[in[1]] << 6) | (alphabet[in[0]])) & 0xFF;
- len += 3;
- in += 4;
- }
-
- *out = '\0';
- if (*in != '\0' && *in != '\n')
- error("warning: line not ended by NULL or NEWLINE");
-
-#if defined(DEBUGALL)
- fprintf(stderr, "(%s) decode out:\n", infilename);
- while (b != out)
- fprintf(stderr, ".%02X", *b++);
- putc('\n', stderr);
-#endif
-
- return len;
-
-} /* decodestring */
-
-
-
-char *myfgets(buf, len, fp)
-char *buf;
-int len;
-FILE *fp;
-{
-
- linecount++;
-
- return fgets(buf, len, fp);
-
-} /* myfgets */
-
-
-
-void usage()
-{
-
- fprintf(stderr, "%s\n\n", copyright);
- fprintf(stderr, "Usage: sciibin [-vtch] [-o<outputfile>] <infiles>\n\n");
- fprintf(stderr, " -v show only info on file, do not create output.\n");
- fprintf(stderr, " -t test file, do not create output.\n");
- fprintf(stderr, " -c do not check checksums.\n");
- fprintf(stderr, " -o create given filename instead of the one in\n");
- fprintf(stderr, " binscii file. Use this only if the input files\n");
- fprintf(stderr, " contain only one output file.\n");
- fprintf(stderr, " -h this help message.\n");
-
-} /* usage */
-
-
-
-void error(str)
-char *str;
-{
-
- fprintf(stderr, "%s (%s, %d): %s\n",
- progname, infilename, linecount, str);
-
-} /* error */
-
=unblu.c
-/* @(#) unblu.c 2.2 18/06/89 */
-/*************************************************************************
- ** **
- ** Name : unblu **
- ** Author : Marcel J.E. Mol **
- ** Date : 10/05/88 (first release) **
- ** Version : 2.20 **
- ** Files : unblu.c Main source file **
- ** **
- ** ------------------------- Revision List ------------------------- **
- ** Ver Date Name Remarks **
- ** 1.00 10/05/88 Marcel Mol Raw copy of a basic program**
- ** 2.00 03/06/88 Marcel Mol Rewrite after blu info **
- ** was send to the net **
- ** 2.10 18/06/88 Marcel Mol Added filetype texts **
- ** 2.20 23/09/88 Marcel Mol Show mod and creation time **
- ** **
- ** ================================================================= **
- ** **
- ** Compile as follows: cc unblu.c -Oso unblu **
- ** **
- ** Usage: unblu [-vh] <arcfile> [<files-toextract>] **
- ** **
- ************************************************************************/
-
- /************************************************************************
- ** **
- ** NAME **
- ** unblu - Extract files from an apple binary ][ archive. **
- ** **
- ** **
- ** SYNOPSIS **
- ** unblu [-vh] arcfile [files-to-extract] **
- ** **
- ** **
- ** DESCRIPTION **
- ** Unblu list the contents of a binary ][ archive (the -v option) **
- ** or extracts the listed files from the archive (without the **
- ** -v option). If no files are listed, the comlete archive is **
- ** extracted or listed. **
- ** The -h option gives a help message on the usage of unblu. **
- ** **
- ** AUTHOR **
- ** Marcel J.E. Mol **
- ** **
- ** BUGS **
- ** Mail bugs to: marcel@duteca.tudelft.nl **
- ** **
- ************************************************************************/
-
-char * copyright = "@(#) unblu.c 2.2 18/06/89 (c) M.J.E. Mol";
-#include <stdio.h>
-#include <fcntl.h>
-#include "filetype.h"
-
-#define BUFSIZE 128 /* Blu block length */
-#define DEBUG
-
-/* Global variables */
-char * progname;
-char * blufile;
-int verbose = 0;
-
-
-/* Function declarations */
-void main ();
-void unblu ();
-void process_file ();
-void extract_file ();
-void print_global_info ();
-int want ();
-void usage ();
-void printhelp ();
-
-
-void main(argc, argv)
-int argc;
-char ** argv;
-{
- int flag; /* Flag for getopt */
- int bfd; /* File descriptor for blu file */
- extern int optind; /* For getopt */
- extern char * optarg; /* For getopt */
-
- progname = argv[0];
- while ((flag = getopt(argc, argv, "vh")) != EOF) { /* Process options */
- switch (flag) {
- case 'v': verbose = 1; /* Want only listing of archive */
- break;
- case 'h': usage(); /* Give help */
- printhelp();
- exit(0);
- default : fprintf(stderr, "%s: skipping unkown flag %c.\n",
- progname, flag);
- break;
- }
- }
-
- if (optind >= argc) { /* No archive given */
- usage();
- exit(1);
- }
-
- blufile = argv[optind++]; /* Get archive name */
- if ((bfd = open(blufile, O_RDONLY)) == -1) {
- perror(blufile);
- exit(2);
- }
-
- unblu(bfd, &argv[optind]); /* Process wanted files */
-
- close(bfd);
-
- exit(0);
-
-} /* main */
-
-
-/*
- * unblu -- process a binary II file fd, and process the filenames
- * listed in wated. If wanted is \0, all files are processed.
- */
-void unblu(fd, wanted)
-int fd;
-char ** wanted;
-{
- unsigned char buf[BUFSIZE];
- int firstblock = 1; /* First block needs special processing */
- int tofollow = 1; /* Files to follow in the archive */
- int n;
-
- while (tofollow && ((n = read(fd, buf, BUFSIZE)) != -1)) {
- /* If there is a header block */
- if (n != BUFSIZE) {
- fprintf(stderr, "%s: %s file size is broken\n", progname, blufile);
- exit(1);
- }
- if ((buf[0] != 10) || (buf[1] != 71) ||
- (buf[2] != 76) || (buf[18] != 2)) {
- fprintf(stderr, "%s: %s not a binary II file\n", progname, blufile);
- exit(1);
- }
- tofollow = buf[127]; /* How many files to follow */
- if (firstblock && verbose) {
- print_global_info(buf);
- firstblock = 0;
- }
- process_file(fd, buf, wanted); /* process the file for it */
- }
- return;
-
-} /* unblu */
-
-
-/*
- * process_file -- retrieve or print file information of file given
- * in buf
- */
-void process_file(fd, buf, wanted)
-int fd;
-unsigned char * buf;
-char ** wanted;
-{
- int tf;
- int ftype;
- int dflags;
- int fnamelen;
- int filelen;
- char fname[64];
- int nblocks;
- int modyear, modmonth, modday;
- int creyear, cremonth, creday;
- int modhour, modsec;
- int crehour, cresec;
-
- /*
- * Get fileinfo
- */
- ftype = buf[4]; /* File type */
- fnamelen = buf[23]; /* filename */
- strncpy(fname, &buf[24], fnamelen);
- fname[fnamelen] = '\0';
- dflags = buf[125]; /* Data flags */
- tf = buf[127]; /* Number of files to follow */
- filelen = buf[20] + (buf[21]<<8) + (buf[22]<<16);/* Calculate file length */
- nblocks = (filelen + BUFSIZE-1) / BUFSIZE;
- modyear = buf[11] >>1;
- modday = buf[10] & 0x1f;
- modmonth= ((buf[11] & 0x01) << 3) + (buf[10] >> 5);
- modhour = buf[13] & 0x1f;
- modsec = buf[12] & 0x3f;
- creyear = buf[15] >>1;
- creday = buf[14] & 0x1f;
- cremonth= ((buf[15] & 0x01) << 3) + (buf[14] >> 5);
- crehour = buf[17] & 0x1f;
- cresec = buf[16] & 0x3f;
-
-
- if (*wanted == NULL || want(fname, wanted)) {
- if (verbose) { /* print file information */
- printf("%-15s %3s", fname, filetypes[ftype]);
- printf(" %02d/%02d/%02d(%02d:%02d)", modyear, modmonth, modday,
- modhour, modsec);
- printf(" - %02d/%02d/%02d(%02d:%02d)", creyear, cremonth, creday,
- crehour, cresec);
- printf(" %5d bytes ", filelen);
- if (dflags == 0)
- printf("stored");
- else {
- if (dflags & 128) {
- printf("squeezed");
- }
- if (dflags & 64) {
- printf("encrypted");
- }
- if (dflags & 1)
- printf("packed");
- }
- putchar('\n');
-
- if (ftype != 15) /* If not a directory */
- lseek(fd, BUFSIZE*nblocks, 1); /* Seek to next file */
- }
- else if (ftype != 15)
- extract_file(fd, fname, filelen);
- }
- else if (ftype != 15) /* If not a directory */
- lseek(fd, BUFSIZE*nblocks, 1); /* Seek to next file */
-
- return;
-
-} /* process_file */
-
-
-/*
- * extract_file -- extract file fname from the archive fd. Fname
- * comtains filelen bytes.
- */
-void extract_file(fd, fname, filelen)
-int fd;
-char * fname;
-int filelen;
-{
- int ofd;
- int n;
- unsigned char buf[BUFSIZE];
-
- printf("x - %s\n", fname);
- if ((ofd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0644)) == -1) {
- /* Open (PRODOS) file */
- perror(fname);
- exit(1);
- }
-
- while (filelen > 0) {
- if ((n = read(fd, buf, BUFSIZE)) != BUFSIZE) { /* Read 128 bytes */
- fprintf(stderr, "%s: %s file size is broken\n", progname, blufile);
- exit(1);
- }
- write(ofd, buf, (filelen >= BUFSIZE ? BUFSIZE : filelen));
- filelen -= BUFSIZE;
- }
-
- close(ofd); /* Close (PRODOS) file */
- return;
-
-} /* extract_file */
-
-
-
-/*
- * print_global_info -- print global information of the binary II file
- */
-void print_global_info(buf)
-unsigned char * buf;
-{
- int disk_blocks;
-
- disk_blocks = buf[117] + (buf[118]<<8) + (buf[119]<<16) + (buf[120]<<24);
- printf("%s, by Blu %d, ", blufile, buf[126]);
- printf("%d files, using %d blocks\n", buf[127]+1, disk_blocks);
- return;
-
-} /* print_global_info */
-
-
-
-/*
- * want -- return 1 if name exists in array wantlist,
- * else return 0
- */
-want(name, wantlist)
-char * name;
-char ** wantlist;
-{
- while (*wantlist != NULL) {
- if (strcmp(name, *wantlist++) == NULL)
- return(1);
- }
- return(0);
-
-} /* want */
-
-
-
-void usage()
-{
- fprintf(stderr, "usage: %s [-hv] <blufile> [<filetoextract> ...]\n",
- progname);
- return;
-
-} /* usage */
-
-
-
-void printhelp()
-{
- fprintf(stderr, "\t-h show this help.\n");
- fprintf(stderr, "\t-v show contents of archive.\n");
-}
+ END OF ARCHIVE