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: }