home *** CD-ROM | disk | FTP | other *** search
- From: jac@yoko.rutgers.edu (Jonathan A. Chandross)
- Newsgroups: comp.sources.apple2
- Subject: v001SRC044: tar -- Unpack Tar Archives For Orca (GS)
- Message-ID: <May.2.17.09.51.1991.318@yoko.rutgers.edu>
- Date: 2 May 91 21:09:53 GMT
- Approved: jac@paul.rutgers.edu
-
-
- 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
-