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