1 /* tarread.c */
2 /* Copyright (c) 1985, by Carnegie-Mellon University */
3 
4 #include <stdio.h>
5 #include <v2tov3.h>
6 #include <sys\types.h>
7 #include <sys\stat.h>
8 #include "tar.h"
9 
10 char usage[] = "tarread: usage: tarread tx[vwz] tarfile\n";
11 union hblock hbuf;
12 
13 int verbose = 0;
14 int confirm = 0;
15 int binary = 0;
16 char cmd;
17 
18 main(argc, argv)
19 int argc;
20 char *argv[];
21 {
22 	FILE *fp;
23 	char *cp;
24 
25 	if (argc != 3) {
26 		fprintf(stderr, usage);
27 		exit(1);
28 	}
29 
30 	for (cp = argv[1]; *cp; cp++)
31 		switch (*cp) {
32 			case 't':
33 			case 'x':
34 				cmd = *cp;
35 				break;
36 
37 			case 'v':
38 				verbose++;
39 				break;
40 			case 'z':
41 				binary++;
42 				break;
43 			case 'w':
44 				confirm++;
45 				break;
46 			default:
47 				fprintf(stderr, "tarread: unknown switch %c\n", *cp);
48 				fprintf(stderr, usage);
49 				exit(1);
50 		}
51 
52 	if ((fp = fopen(argv[2], "rb")) == NULL) {
53 		fprintf(stderr, "tarrread: cannot open %s\n", argv[2]);
54 		exit(1);
55 	}
56 
57 	for (;;) {
58 		if (fread(&hbuf, sizeof(hbuf), 1, fp) != 1) {
59 			perror("fread");
60 			exit(1);
61 		}
62 		if (!proc_file(fp))
63 			break;
64 	}
65 }
66 
67 
68 int proc_file(fp)
69 FILE *fp;
70 {
71 	char name[NAMSIZ];
72 	unsigned short mode;
73 	short uid, gid;
74 	long size, mtime;
75 	char c;
76 	int confrmd;
77 	long skip;
78 
79 	if (hbuf.dbuf.name[0] == '\0')
80 		return (NULL);
81 
82 	strcpy(name, hbuf.dbuf.name);
83 	if (sscanf(hbuf.dbuf.mode, "%o", &mode) != 1)
84 		fprintf("Couldn't read mode\n");
85 	if (sscanf(hbuf.dbuf.uid, "%o", &uid) != 1)
86 		fprintf("Couldn't read uid\n");
87 	if (sscanf(hbuf.dbuf.gid, "%o", &gid) != 1)
88 		fprintf("Couldn't read gid\n");
89 	if (sscanf(hbuf.dbuf.size, "%12lo %12lo", &size, &mtime) != 2)
90 		fprintf("Couldn't read size or mtime\n");
91 
92 	skip = (size + TBLOCK - 1) / TBLOCK * TBLOCK;
93 
94 	switch (cmd) {
95 		case 't':
96 			if (verbose)
97 				printf("%8o %d/%d\t %6ld %.24s %s\n", mode,
98 					uid, gid, size, ctime(&mtime), name);
99 			else
100 				printf("%s\n", name);
101 
102 			break;
103 
104 		case 'x':
105 			if (verbose)
106 				printf("x %s: ", name);
107 			confrmd = 1;
108 
109 			if (confirm) {
110 				confrmd = 0;
111 				if ((c = getchar()) == 'y')
112 					confrmd++;
113 				while (c != '\n')
114 					c = getchar();
115 				if(!confrmd)
116 					break;
117 			}
118 
119 			if(extract(name, size, mode, mtime, fp))
120 				skip = 0;
121 
122 			if (verbose)
123 				printf("\n");
124 			break;
125 	}
126 	if (fseek(fp, skip, 1)) {
127 		perror("fseek");
128 		exit(1);
129 	}
130 	return (1);
131 }
132 
133 
134 int extract(fname, size, mode, mtime, ifp)
135 char *fname;
136 long size;
137 unsigned short mode;
138 long mtime;
139 FILE *ifp;
140 {
141 	FILE *ofp;
142 	char fbuf[TBLOCK];
143 	long copied, left;
144 	char *s, *np, *strchr();
145 	struct stat sbuf;
146 
147 	for(np = fname; s = strchr(np, '/'); np = s+1) {
148 		*s = '\0';
149 		if(stat(fname, &sbuf)) {
150 			if(mkdir(fname))
151 				perror("mkdir");
152 		} else if(!(sbuf.st_mode & S_IFDIR)) {
153 			fprintf(stderr, "\n%s: Not a directory", fname);
154 			*s = '/';
155 			fprintf(stderr, "\ntar: %s - cannot create", fname);
156 			return (0);
157 		}
158 		*s = '/';
159 	}
160 	if(!*np)
161 		return (0);
162 
163 	if (binary) {
164 		if ((ofp = fopen(fname, "wb")) == NULL) {
165 			perror("extract:");
166 			return (0);
167 		}
168 	} else {
169 		if ((ofp = fopen(fname, "w")) == NULL) {
170 			perror("extract:");
171 			return (0);
172 		}
173 	}
174 
175 	for(copied = 0; copied < size; copied += TBLOCK) {
176 		if(fread(fbuf, TBLOCK, 1, ifp) != 1) {
177 			perror("fread");
178 			exit(1);
179 		}
180 		left = size - copied;
181 		if(fwrite(fbuf, (int)min(left, TBLOCK), 1, ofp) != 1) {
182 			perror("fwrite");
183 			exit(1);
184 		}
185 	}
186 
187 	if(fclose(ofp)) {
188 		perror("fclose");
189 		exit(1);
190 	}
191 
192 	/*
193 	 * Now, set modification time.
194 	 */
195 	{
196 #include <sys\utime.h>
197 	    struct utimbuf utim;
198 
199 	    utim.modtime = mtime;
200 
201 	    if (utime(fname, &utim) == -1) {
202 		perror("utime");
203 		exit(1);
204 	    }
205 	}
206 
207 	return (1);
208 }
209