#include "stp.h" clrblk() { edir =+ 8*sizeof dir[0]; ndirent =+ 8; ++ndentd8; if (edir >= nptr) { printf("Out of Core\n"); done(0); } } clrent(ptr) { register *p, j; p = ptr; if (p == lastd) do { if (--lastd < &dir) { lastd = 0; break; } } while (lastd->d_namep == 0); j = DIRSIZE/2; do *p++ = 0; while (--j); } /**/ rddir() { register *p1, *tp, reg; struct dent *dptr; struct tent *tptr; int sum; int nd; int nde; sum = 0; if (flags & flo) { optap(0, 0); /* old-style directory */ tread(0); if ((reg = tpentry[7].cksum) > 0) nde = reg; else nde = 496; } else { optap(1, 0); /* open tape for reading second file */ nde = 32767; /* 'imfinity' -- EOF will signal e.o. dir. */ } dptr = &dir[0]; for (nd = 0; ;++nd) { if ((nd & 07) == 0) { /* next block */ clrblk(); if (tread(backio) < 0) /* EOF, Both files close by tread */ break; tptr = &tpentry[0]; } tp = tptr; p1 = tp + (sizeof tpentry[0])/2; reg = 0; do reg =+ *tp++; while (tpmode); ++p1; /* skip namep */ reg = (sizeof dir[0]/2) - 1; do *p1++ = *tp++; while (--reg); } } ++tptr; /* bump to next tent */ reg = dptr; reg->d_mode =& ~0100000; /* mark previous */ dptr = (reg =+ sizeof dir[0]); if (--nde == 0) break; /* old-style directory end */ } if (sum != 0) { printf("Directory checksum\n"); if ((flags & fli) == 0) done(0); } bitmap(); } /**/ wrdir() { register reg, *p3,*p2; struct dent *dptr; int count; struct tent *tptr; if (lastd == 0) ndentd8 = 0; else ndentd8 = 1 + ((lastd - &dir[0])>>3) ; ndirent = ndentd8<<3; dptr = &dir[0]; for (count=ndirent; count ; ) { p3 = &tpentry[0]; do { tptr = p3; p2 = dptr++; if (p2->d_namep) { decode(p3,p2); p3 = &(p3->mode); ++p2; /* skip namep */ do *p3++ = *p2++; while (p2 < dptr); p3 = tptr; p2 = &p3[31]; /* points to checksum */ reg = 0; do reg =- *p3++; /* form checksum */ while (p3< p2); *p3++ = reg; } else { reg = sizeof tpentry[0]/2; do *p3++ = 0; /* clear entry */ while (--reg); } } while (--count & 07); twrite(); } } /**/ tread(x) /* if x!=0, write a backup copy of read block */ { register j, n, *ptr; if ((n = read(fio,tapeb,512)) <= 0) { if (x) close(x); close(fio); return(-1); } if (n != 512) { printf("Tape read error\n"); if ((flags & fli) == 0) done(0); ptr = tapeb; j = 256; do *ptr++ = 0; while (--j); } if (x) { if (write(x,tapeb,512) != 512) { printf("Write error %s\n", backup); done(0); } } else rseeka++; return(0); } twrite() { if (write(fio,tapeb,512) != 512) { printf("Tape write error\n"); done(1); } ++wseeka; } rseek(blk) { rseeka = blk; if (seek(fio,blk,3) < 0) seekerr(0); } seekerr(how) { printf("Tape seek error\n"); done(how); } /**/ wseek(blk) { register amt, b; amt = b = blk; if ((amt =- wseeka) < 0) amt = -amt; if (amt > 25 && b) { seek(fio, b-1, 3); /* seek previous block */ read(fio, &wseeka, 1); /* read next block */ } wseeka = b; if (seek(fio, b, 3) < 0) seekerr(2); } verify(key) { register c; if ((flags & (flw | flv)) == 0) return(0); repeat: printf("%c %s ", key, name); if ((flags & flw) == 0) { printf("\n"); return(0); } c = getchar(); if (c == 'n' && getchar() == '\n') done(0); if (c == '\n') return(-1); if (c == 'y' && getchar() == '\n') return(0); while (getchar() != '\n'); goto repeat; } getfiles() { register char *r1, *r2; if ((narg =- 2) == 0) { name->integer = '.\0'; callout(); } else while (--narg >= 0) { r1 = *parg++; r2 = &name; while (*r2++ = *r1++); callout(); } } /**/ expand() { register char *p0, *p1, *save0; int n, fid; if ((fid = open(name,0)) < 0) fserr(1); for (;;) { if ((n = read(fid,catlb,16)) != 16){ if (n == 0) { close(fid); return; } fserr(2); } if (catlb[0] == 0) /* null entry */ continue; p0 = &name; p1 = &catlb[1]; if (*p1 == '.') /* don't save .xxxx */ continue; while (*p0++); save0 = --p0; /* save loc of \0 */ if (p0[-1] != '/') *p0++ = '/'; while (*p0++ = *p1++); callout(); *save0 = 0; /* restore */ } } fserr(XXXXX) { printf("fserr(%d)\n",XXXXX); printf("%s -- Cannot open file\n", name); done(0); } callout() { register struct dent *d; register char *r3, *r2; char *empty; if (stat(name,&statb) < 0) fserr(3); r2 = statb.s_flags; if ((r2 =& 060000) != 0) { if (r2 == 040000) /* directory */ expand(); return; } /* when we reach here we have recursed until we found * an ordinary file. Now we look for it in "dir". */ empty = &name; /* check for long names */ while (*empty++); if (empty > &name[32]) { printf("Name too long - %s\nIgnored\n", name); return; } empty = 0; d = &dir[0]; do { if (d->d_namep == 0) { /* empty directory slot */ if (empty == 0) /* remember the first one */ empty = d; continue; } decode(name1,d); r2 = &name; r3 = &name1; do if (*r2++ != *r3) goto cont; while (*r3++); /* veritably the same name */ if (flags & flu) { /* check the times */ if (d->d_time[0] > statb.s_modtime[0]) return; if (d->d_time[0] == statb.s_modtime[0] && d->d_time[1] >= statb.s_modtime[1]) return; } if (verify('r') < 0) return; goto copydir; cont: continue; } while (++d <= lastd); /* name not found in directory */ if ((d = empty) == 0) { d = lastd +1; while (d >= edir) clrblk(); } if (verify('a') < 0) return; if (d > lastd) lastd = d; encode(name,d); copydir: d->d_mode = statb.s_flags | 0100000; /* mark as new for update */ d->d_uid = statb.s_uid; d->d_gid = statb.s_gid; if (flags &flf) { /* fake entry */ statb.s_size0 = 0; statb.s_size1 = 0; } d->d_size0 = statb.s_size0; d->d_size1 = statb.s_size1; d->d_time[0] = statb.s_modtime[0]; d->d_time[1] = statb.s_modtime[1]; }