4.4BSD/usr/src/usr.bin/tn3270/distribution/utilities/srccmd/tar/tarread.c

Compare this file to the similar file:
Show the results in this format:

/* tarread.c */
/* Copyright (c) 1985, by Carnegie-Mellon University */

#include <stdio.h>
#include <v2tov3.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "tar.h"

char usage[] = "tarread: usage: tarread tx[vwz] tarfile\n";
union hblock hbuf;

int verbose = 0;
int confirm = 0;
int binary = 0;
char cmd;

main(argc, argv)
int argc;
char *argv[];
{
	FILE *fp;
	char *cp;

	if (argc != 3) {
		fprintf(stderr, usage);
		exit(1);
	}

	for (cp = argv[1]; *cp; cp++)
		switch (*cp) {
			case 't':
			case 'x':
				cmd = *cp;
				break;

			case 'v':
				verbose++;
				break;
			case 'z':
				binary++;
				break;
			case 'w':
				confirm++;
				break;
			default:
				fprintf(stderr, "tarread: unknown switch %c\n", *cp);
				fprintf(stderr, usage);
				exit(1);
		}

	if ((fp = fopen(argv[2], "rb")) == NULL) {
		fprintf(stderr, "tarrread: cannot open %s\n", argv[2]);
		exit(1);
	}

	for (;;) {
		if (fread(&hbuf, sizeof(hbuf), 1, fp) != 1) {
			perror("fread");
			exit(1);
		}
		if (!proc_file(fp))
			break;
	}
}


int proc_file(fp)
FILE *fp;
{
	char name[NAMSIZ];
	unsigned short mode;
	short uid, gid;
	long size, mtime;
	char c;
	int confrmd;
	long skip;

	if (hbuf.dbuf.name[0] == '\0')
		return (NULL);

	strcpy(name, hbuf.dbuf.name);
	if (sscanf(hbuf.dbuf.mode, "%o", &mode) != 1)
		fprintf("Couldn't read mode\n");
	if (sscanf(hbuf.dbuf.uid, "%o", &uid) != 1)
		fprintf("Couldn't read uid\n");
	if (sscanf(hbuf.dbuf.gid, "%o", &gid) != 1)
		fprintf("Couldn't read gid\n");
	if (sscanf(hbuf.dbuf.size, "%12lo %12lo", &size, &mtime) != 2)
		fprintf("Couldn't read size or mtime\n");

	skip = (size + TBLOCK - 1) / TBLOCK * TBLOCK;

	switch (cmd) {
		case 't':
			if (verbose)
				printf("%8o %d/%d\t %6ld %.24s %s\n", mode,
					uid, gid, size, ctime(&mtime), name);
			else
				printf("%s\n", name);

			break;

		case 'x':
			if (verbose)
				printf("x %s: ", name);
			confrmd = 1;

			if (confirm) {
				confrmd = 0;
				if ((c = getchar()) == 'y')
					confrmd++;
				while (c != '\n')
					c = getchar();
				if(!confrmd)
					break;
			}

			if(extract(name, size, mode, mtime, fp))
				skip = 0;
			
			if (verbose)
				printf("\n");
			break;
	}
	if (fseek(fp, skip, 1)) {
		perror("fseek");
		exit(1);
	}
	return (1);
}


int extract(fname, size, mode, mtime, ifp)
char *fname;
long size;
unsigned short mode;
long mtime;
FILE *ifp;
{
	FILE *ofp;
	char fbuf[TBLOCK];
	long copied, left;
	char *s, *np, *strchr();
	struct stat sbuf;

	for(np = fname; s = strchr(np, '/'); np = s+1) {
		*s = '\0';
		if(stat(fname, &sbuf)) {
			if(mkdir(fname))
				perror("mkdir");
		} else if(!(sbuf.st_mode & S_IFDIR)) {
			fprintf(stderr, "\n%s: Not a directory", fname);
			*s = '/';
			fprintf(stderr, "\ntar: %s - cannot create", fname);
			return (0);
		}
		*s = '/';
	}
	if(!*np)
		return (0);

	if (binary) {
		if ((ofp = fopen(fname, "wb")) == NULL) {
			perror("extract:");
			return (0);
		}
	} else {
		if ((ofp = fopen(fname, "w")) == NULL) {
			perror("extract:");
			return (0);
		}
	}
	
	for(copied = 0; copied < size; copied += TBLOCK) {
		if(fread(fbuf, TBLOCK, 1, ifp) != 1) {
			perror("fread");
			exit(1);
		}
		left = size - copied;
		if(fwrite(fbuf, (int)min(left, TBLOCK), 1, ofp) != 1) {
			perror("fwrite");
			exit(1);
		}
	}

	if(fclose(ofp)) {
		perror("fclose");
		exit(1);
	}

	/*
	 * Now, set modification time.
	 */
	{
#include <sys\utime.h>
	    struct utimbuf utim;

	    utim.modtime = mtime;

	    if (utime(fname, &utim) == -1) {
		perror("utime");
		exit(1);
	    }
	}

	return (1);
}