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