[comp.sources.apple2] v001SRC044: tar -- Unpack Tar Archives For Orca

jac@yoko.rutgers.edu (Jonathan A. Chandross) (05/03/91)

Submitted-by: Jawaid Bazyar (bazyar@cs.uiuc.edu)
Posting-number: Volume 1, Source:44
Archive-name: util/gs/shell/orca/tar
Architecture: ONLY_2gs
Version-number: 1.2

This package will unpack tar archives.

Requires Orca shell.

Enjoy.

###################################

=tar.doc
-===========
-    TAR
-===========
-version 1.2
-
-tar -options [archive]\n"
-
-options:  t  - list files in archive (test)
-          x  - extract files from archive
-          f  - use file [archive] instead of tape
-          v  - verbose mode
-
- tar is the standard Unix Tape ARchive utility.  This GS version only
-supports reading file-based tar files.  As soon as I get my hands on
-a SCSI tape drive, I'll include support for those.
-
- Also in the works is support for creating archives.
-
------
-
-Jawaid Bazyar
-Derek Taubert
-
-Copyright 1990 by Procyon Software
-Freeware - distribute but don't sell!
-
-This utility is FreeWare.  Distribute them as much as you like, just
-don't sell them or distribute modified versions.  Send me your comments -
-I'm eager to hear from you for suggestions and improvements.
-
-Also, if you make any modifications to the code please do not redistribute
-them. Instead, send me the changed source along with an explanation and
-I will consider including your change in the next version.
-
-	Jawaid Bazyar
-	1120 Maple Street
-	Mt. Vernon, IL 62864
-
-	Internet/ARPAnet     bazyar@cs.uiuc.edu
-	GEnie                J.BAZYAR
-
=tar.c
-
-/*
-
-        tar.c   - a GS version of the venerable Unix tape archive 
-                  utility.
-
-        Copyright 1991, Procyon Software
-        This code and the executable derived from it are hereby
-        put in the public domain.
-        Distribution/modification is free, pursuant to the rules
-        outlined in the SHELLSTUFF.DOC file.
-
-*/
-
-#include <types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include <gsos.h>
-
-byte buffer[1024];
-char filename[255];
-FILE *tarfile;
-
-int optVerbose, optFile, optExtract,
-    optTest;
-
-/* pull a file out of the archive one block at a time */
-
-GSString255Ptr MakeGSString1(char *s)
-{
-GSString255Ptr n;
-    n = malloc(sizeof(GSString255));
-    strcpy((char *) n->text,s);
-    n->length = strlen(s);
-    return n;
-}
-
-int extractFile(char *name, longword blocks, longword length)
-{
-word excess;
-int got,get,i,e;
-FILE *output;
-char *d,dirName[256];
-CreateRecGS c;
-FileInfoRecGS inf;
-
-    if (optVerbose) printf("extracting %s (%d blocks)\n",name, blocks);
-    blocks = length / 1024;
-    excess = length % 1024;
-    if (excess) blocks++;
-
-    if (name[0] == '/') {
-        fprintf(stderr, "Can't extract to a volume name!\n");
-        exit(1);
-    }
-    d = name;
-    while ((d = strchr(d, '/')) != NULL) {
-
-        strncpy(dirName, name, d-name);
-        dirName[(int) (d-name)] = '\0';
-
-        inf.pCount = 3;
-        inf.pathname = MakeGSString1(dirName);
-        GetFileInfoGS(&inf);
-        if (e = toolerror()) {
-          switch (e) {
-            case 0x46:
-            case 0x44: break;
-            default:   fprintf(stderr, "error statting file %s (%x)\n",
-                           dirName,e);
-                       exit(1); break;
-          }
-        }
-        else if (inf.fileType != 0x0F) {
-            fprintf(stderr, "can't overwrite file %s\n", dirName);
-            exit(1);
-        }
-
-        if (e) {
-            c.pCount = 3;
-            c.pathname = inf.pathname;
-            c.access = 0xC3;
-            c.fileType = 0x0F;
-            CreateGS(&c);
-            if (e = toolerror()) {
-                fprintf(stderr, "fatal GS/OS error %x\n",e);
-                exit(1);
-            }
-        }
-        free(inf.pathname);
-        while (*d == '/') d++;
-    }
-
-    if (!blocks) return 0;
-    output = fopen(name, "wb");
-    for (i = 0; i < blocks; i++) {
-        if ((i == blocks-1) && excess) get = excess;
-        else get = 1024;
-        got = fread(buffer, sizeof(byte), (size_t) get, tarfile);
-        if (got != get) { fprintf(stderr, "read error\n"); exit(1); }
-
-        if (fwrite(buffer, sizeof(byte), (size_t) got, output) < get)
-          { fprintf(stderr, "write error\n"); exit(1); }
-    }
-    fclose(output);
-}
-
-int testFile(char *name, longword blocks, longword length)
-{
-    printf("%s (%ld blocks)\n",name, blocks);
-}
-
-void usage(void)
-{
-    fprintf(stderr,"Usage: tar -options [archive]\n"
-           "  options:  t  - list files in archive (test)\n"
-           "            x  - extract files from archive\n"
-           "            f  - use file [archive] instead of tape\n"
-           "            v  - verbose mode\n");
-    exit(1);
-}
-
-void parseOpts(char *opts)
-{
-char *i = opts;
-
-    while (*i != '\0') {
-        switch (*i) {
-            case 'x': if (optTest) usage();
-                      optExtract = 1; break;
-            case 't': if (optExtract) usage();
-                      optTest = 1; break;
-            case 'f': optFile = 1; break;
-            case 'v': optVerbose = 1; break;
-            default: usage();
-        }
-        i++;
-    }
-}
-
-int main(int argc, char *argv[])
-{
-longword block;
-longword size;
-longword fileBlocks;
-word got;
-int SessionPB = 0;
-
-    block = 0;
-    optVerbose = optFile = optExtract = optTest = 0;
-
-    if (argc == 1) usage();
-    if (argv[1][0] == '-') parseOpts(&argv[1][1]);
-    else parseOpts(argv[1]);
-
-    if (optFile) tarfile = fopen(argv[2], "rb");
-    else { fprintf(stderr, "no SCSI tape found\n"); exit(1); }
-
-    if (!(optExtract || optTest)) usage();
-    BeginSession(&SessionPB);
-
-    do {
-        if (fseek(tarfile, (long) block*512, SEEK_SET)) {
-            fprintf(stderr, "Seek error- aborting\n"); exit(1);
-        }
-        got = fread(buffer, sizeof(byte), (size_t) 512, tarfile);
-        if (!buffer[0]) break;
-        if (got == 0) { fprintf(stderr, "Read error- aborting\n"); exit(1); }
-        if (got == 512) {
-            sscanf(buffer+0174, "%lo", &size);
-
-            fileBlocks = (size / 512);
-            if (size % 512) fileBlocks++;
-
-            block += fileBlocks + 1;
-            strcpy(filename, (char *) buffer); /* copy the filename for future
-                                         reeference */
-            if (optExtract) extractFile(filename, fileBlocks, size);
-            else if (optTest) testFile(filename, fileBlocks, size);
-
-            buffer[0] = 0;
-        }
-    } while (got == 512);
-    fclose(tarfile);
-    EndSession(&SessionPB);
-    return 0;
-}
-
+ END OF ARCHIVE