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