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
main(argc,argv)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
proc_file(fp)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
extract(fname,size,mode,mtime,ifp)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