1 #ifndef lint 2 static char sccsid[] = "@(#)tp2.c 4.1 12/18/82"; 3 #endif 4 5 #include "tp.h" 6 #include <stdio.h> 7 #include <sys/param.h> 8 #include <sys/stat.h> 9 #include <sys/dir.h> 10 11 struct stat statb; 12 13 clrdir() 14 { 15 register j, *p; 16 17 j = ndirent * (DIRSZ/sizeof(int)); 18 p = (int *)dir; 19 do (*p++ = 0); while (--j); 20 lastd = 0; 21 } 22 23 clrent(ptr) 24 struct dent *ptr; 25 { 26 register *p, j; 27 28 p = (int *)ptr; 29 j = DIRSZ/sizeof(int); 30 do *p++ = 0; 31 while (--j); 32 if (++ptr == lastd) do { 33 if (--lastd < dir) { 34 lastd = 0; 35 return; 36 } 37 } while (lastd->d_namep == 0); 38 } 39 40 41 rddir() 42 { 43 register struct tent *tp; 44 register struct dent *p1; 45 struct dent *dptr; 46 struct tent *tptr; 47 int count, i, sum; 48 short reg, *sp; 49 50 sum = 0; 51 clrdir(); 52 rseek(0); 53 tread(); /* Read the bootstrap block */ 54 if ((tpentry[TPB-1].cksum != 0) && (flags & flm)) { 55 ndirent = tpentry[TPB-1].cksum; 56 if(flags & fls) swab((char *)&ndirent, (char *)&ndirent, sizeof(ndirent)); 57 if(ndirent < 0 || ndirent > MDIRENT) ndirent = MDIRENT; 58 ndentb = ndirent/TPB; 59 } 60 dptr = &dir[0]; 61 count = ndirent; 62 do { 63 if ((count % TPB) == 0) { /* next block */ 64 tread(); 65 tptr = &tpentry[0]; 66 } 67 if(flags & fls) 68 swab((char *)tptr, (char *)tptr, sizeof(*tptr)); 69 sp = (short *)tptr; 70 reg = 0; 71 for(i=0;i<sizeof(struct tent)/sizeof(short);i++) 72 reg += *sp++; 73 if(flags & fls) { 74 swab((char *)tptr, (char *)tptr, sizeof(*tptr)); 75 swabdir(tptr); 76 } 77 sum |= reg; 78 p1 = dptr; 79 if (reg == 0) { 80 tp = tptr; 81 if(tp->pathnam[0] != '\0') { 82 lastd = p1; 83 encode(tp->pathnam,p1); 84 p1->d_mode = tp->mode; 85 p1->d_uid = tp->uid; 86 p1->d_gid = tp->gid; 87 p1->d_size = (((long)tp->size0&0377L)<<16)+(tp->size1&0177777L); 88 p1->d_time = tp->time; 89 p1->d_tapea = tp->tapea; 90 } 91 } 92 ++tptr; /* bump to next tent */ 93 (dptr++)->d_mode &= ~OK; 94 } while (--count); 95 if(sum != 0) 96 if(flags & (fls|fli)) { 97 printf("Directory checksum\n"); 98 if ((flags & fli) == 0) done(); 99 } else { 100 flags |= fls; 101 rddir(); 102 printf("Warning: swabbing required\n"); 103 return; 104 } 105 bitmap(); 106 } 107 108 109 wrdir() 110 { 111 register struct tent *tp; 112 register struct dent *dp; 113 struct dent *dptr; 114 int count, i; 115 short reg, *sp; 116 117 wseek(0); 118 if (flags & flm) 119 reg = open(mheader,0); 120 else reg = open(theader,0); 121 if (reg >= 0) { 122 read(reg,(char *)tapeb,BSIZE); 123 close(reg); 124 if(flags & fls) 125 swab((char *)&ndirent, (char *)&tpentry[TPB-1].cksum, sizeof(ndirent)); 126 else 127 tpentry[TPB-1].cksum = ndirent; 128 } else 129 printf("\7\7\7Warning: cannot read prototype boot block.\n"); 130 dptr = &dir[0]; 131 count = ndirent; 132 for (;;) { 133 twrite(); 134 if (count == 0) return; 135 tp = &tpentry[0]; 136 do { 137 dp = dptr++; /* dptr set to next entry */ 138 if (dp->d_namep) { 139 decode(tp->pathnam,dp); 140 tp->mode = dp->d_mode; 141 tp->uid = dp->d_uid; 142 tp->gid = dp->d_gid; 143 tp->time = dp->d_time; 144 tp->size0 = dp->d_size >> 16; 145 tp->size1 = dp->d_size; 146 tp->tapea = dp->d_tapea; 147 if(flags & fls) { 148 swabdir(tp); 149 swab((char *)tp, (char *)tp, sizeof(*tp)); 150 } 151 reg = 0; 152 sp = (short *)tp; 153 for(i=0;i<sizeof(struct tent)/sizeof(short)-1;i++) 154 reg -= *sp++; 155 *sp = reg; 156 if(flags & fls) 157 swab((char *)tp, (char *)tp, sizeof(*tp)); 158 } else { 159 sp = (short *)tp; 160 for(i=0;i<sizeof(struct tent)/sizeof(short);i++) 161 *sp++ = 0; 162 } 163 tp++; 164 } while (--count % TPB); 165 } 166 } 167 168 tread() 169 { 170 register j, *ptr; 171 172 if (read(fio,(char *)tapeb,BSIZE) != BSIZE) { 173 printf("Tape read error\n"); 174 if ((flags & fli) == 0) done(); 175 ptr = (int *)tapeb; 176 j = BSIZE/sizeof(int); 177 while(j--) *ptr++ = 0; 178 } 179 rseeka++; 180 } 181 182 twrite() 183 { 184 if (write(fio, (char *)tapeb,BSIZE) != BSIZE) { 185 printf("Tape write error\n"); 186 done(); 187 } 188 ++wseeka; 189 } 190 191 rseek(blk) 192 { 193 rseeka = blk; 194 if (lseek(fio,(long)blk*BSIZE,0) < 0) seekerr(); 195 } 196 197 wseek(blk) 198 { 199 register amt, b; 200 201 amt = b = blk; 202 if ((amt -= wseeka) < 0) amt = -amt; 203 if (amt > 25 && b) { 204 lseek(fio, (long)(b-1)*BSIZE, 0); /* seek previous block */ 205 read(fio, (char *)&wseeka, 1); /* read next block */ 206 } 207 wseeka = b; 208 if (lseek(fio, (long)b*BSIZE, 0) < 0) seekerr(); 209 } 210 211 seekerr() 212 { 213 printf("Tape seek error\n"); 214 done(); 215 } 216 217 verify(key) 218 { 219 register c; 220 221 if ((flags & (flw | flv)) == 0) 222 return(0); 223 repeat: printf("%c %s ", key, name); 224 if ((flags & flw) == 0) { 225 printf("\n"); 226 return(0); 227 } 228 c = getchar(); 229 if (c == 'n' && getchar() == '\n') 230 done(); 231 if (c == '\n') 232 return(-1); 233 if (c == 'y' && getchar() == '\n') 234 return(0); 235 while (getchar() != '\n'); 236 goto repeat; 237 } 238 239 getfiles() 240 { 241 242 if ((narg -= 2) == 0) { 243 strcpy(name, "."); 244 callout(); 245 } else while (--narg >= 0) { 246 strcpy(name, *parg++); 247 callout(); 248 } 249 } 250 251 252 expand() 253 { 254 register char *p0, *save0; 255 int n; 256 register DIR *dirp; 257 struct direct *dirent; 258 259 if ((dirp = opendir(name)) == NULL) fserr(); 260 for (;;) { 261 dirent = readdir(dirp); 262 if (dirent == NULL) { 263 closedir(dirp); 264 return; 265 } 266 if (dirent->d_ino == 0) /* null entry */ 267 continue; 268 p0 = name; 269 if (dirent->d_name[0] == '.') /* don't save .xxxx */ 270 continue; 271 while (*p0++); 272 save0 = --p0; /* save loc of \0 */ 273 if (p0[-1] != '/') 274 *p0++ = '/'; 275 strcpy(p0, dirent->d_name); 276 callout(); 277 *save0 = 0; /* restore */ 278 } 279 } 280 281 fserr() 282 { 283 printf("%s -- Cannot open file\n", name); 284 done(); 285 } 286 287 callout() 288 { 289 register struct dent *d; 290 register char *ptr1, *ptr0; 291 struct dent *empty; 292 int mode; 293 294 if (stat(name,&statb) < 0) fserr(); 295 mode = statb.st_mode; 296 if ((mode &= S_IFMT) != 0) { 297 if (mode == S_IFDIR) /* directory */ 298 expand(); 299 if(mode != S_IFREG) return; 300 } 301 /* when we reach here we have recursed until we found 302 * an ordinary file. Now we look for it in "dir". 303 */ 304 empty = 0; 305 d = &dir[0]; 306 do { 307 if (d->d_namep == 0) { /* empty directory slot */ 308 if (empty == 0) /* remember the first one */ 309 empty = d; 310 continue; 311 } 312 decode(name1,d); 313 ptr0 = name; 314 ptr1 = name1; 315 do if (*ptr0++ != *ptr1) goto cont; 316 while (*ptr1++); 317 /* veritably the same name */ 318 if (flags & flu) { /* check the times */ 319 if (d->d_time >= statb.st_mtime) 320 return; 321 } 322 if (verify('r') < 0) return; 323 goto copydir; 324 cont: continue; 325 } while (++d <= lastd); 326 /* name not found in directory */ 327 if ((d = empty) == 0) { 328 d = lastd +1; 329 if (d >= edir) { 330 printf("Directory overflow\n"); 331 done(); 332 } 333 } 334 if (verify('a') < 0) return; 335 if (d > lastd) lastd = d; 336 encode(name,d); 337 copydir: 338 d->d_mode = statb.st_mode | OK; 339 d->d_uid = statb.st_uid; 340 d->d_gid = statb.st_gid; 341 d->d_size = statb.st_size; 342 d->d_time = statb.st_mtime; 343 ; 344 } 345 346 swabdir(tp) 347 register struct tent *tp; 348 { 349 swab((char *)tp, (char *)tp, sizeof(*tp)); 350 swab(tp->pathnam, tp->pathnam, NAMELEN); 351 swab((char *)&tp->uid, (char *)&tp->uid, 4); /* uid,gid,spare,size0 */ 352 } 353