#ifndef lint static char sccsid[] = "@(#)tp3.c 4.1 12/18/82"; #endif #include "tp.h" gettape(how) int (*how)(); { register char *ptr0, *ptr1; register struct dent *d; int count; do { d = &dir[0]; count = 0; do { if (d->d_namep == 0) continue; decode(name,d); if (rnarg > 2) { ptr0 = name; ptr1 = *parg; while (*ptr1) if (*ptr0++ != *ptr1++) goto cont; if (*ptr0 && *ptr0 != '/') goto cont; } (*how)(d); /* delete, extract, or taboc */ ++count; cont: continue; } while (++d <= lastd); if (count == 0 && rnarg > 2) printf("%s not found\n", *parg); ++parg; } while (--narg > 2); } delete(dd) struct dent *dd; { if (verify('d') >= 0) clrent(dd); } update() { register struct dent *d; register b, last; int first, size; bitmap(); d = &dir[0]; do { if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue; if (d->d_size == 0) continue; /* find a place on the tape for this file */ size = (d->d_size+BSIZE-1)/BSIZE; first = ndentb; toosmall: ++first; if ((last = first + size) >= tapsiz) maperr(); for (b = first; b < last; ++b) if (map[(b>>3) & MAPMASK] & (1<<(b&7))) { first = b; goto toosmall; }; d->d_tapea = first; setmap(d); } while (++d <= lastd); wrdir(); update1(); } update1() { register struct dent *d, *id; register index; int f; for (;;) { d = &dir[0]; index = MTSIZ; id = 0; do { /* find new dent with lowest tape address */ if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue; if (d->d_tapea < index) { index = d->d_tapea; id = d; } } while (++d <= lastd); if ((d = id) == 0) return; d->d_mode &= ~OK; /* change from new to old */ if (d->d_size == 0) continue; decode(name,d); wseek(index); if ((f = open(name,0)) < 0) { printf("Can't open %s\n", name); continue; } for (index = d->d_size/BSIZE; index != 0; --index) { if (read(f,(char *)tapeb,BSIZE) != BSIZE) phserr(); twrite(); } if (index = d->d_size % BSIZE) { if (read(f,(char *)tapeb,index) != index) phserr(); twrite(); } if (read(f,(char *)tapeb,1) != 0) phserr(); close(f); } } phserr() { printf("%s -- Phase error \n", name); } bitmap() /* place old files in the map */ { register char *m; register count; register struct dent *d; for(m=map;m<&map[MAPSIZE];) *m++ = 0; count = ndirent; d = dir; do { if(d->d_namep != 0 && (d->d_mode&OK) == 0 && d->d_size != 0) setmap(d); d++; } while (--count); } setmap(d) register struct dent *d; { unsigned c, block; char bit; int i; c = d->d_size/BSIZE; if (d->d_size % BSIZE) c++; block = d->d_tapea; if ((c += block) >= tapsiz) maperr(); do { bit = 1 << (block & 7); i = (block>>3) & MAPMASK; if (bit & map[i]) maperr(); map[i] |= bit; } while (++block < c); } maperr() { printf("Tape overflow\n"); done(); } usage() { register reg,count; int nused, nentr, nfree; static lused; bitmap(); for(count=0,nentr=0;count= tapsiz) { printf("Tape overflow\n"); done(); } if (map[(reg>>3) & MAPMASK] & (1 << (reg&7))) { nused++; lused = reg; } else { if (flags & flm) break; nfree++; } reg++; } while (--count); printf("%4d entries\n%4d used\n", nentr, nused); if ((flags & flm)==0) printf("%4d free\n", nfree); printf("%4d last\n", lused); } taboc(dd) struct dent *dd; { register mode; register *m; register char *s; int count, *localtime(); char work[20]; if (flags & flv) { mode = dd->d_mode; s = &work[19]; *s = 0; for (count = 3; count; --count) { if (mode&1) *--s = 'x'; else *--s = '-'; if (mode&2) *--s = 'w'; else *--s = '-'; if (mode&4) *--s = 'r'; else *--s = '-'; mode >>= 3; } if (mode&4) s[2] = 's'; if (mode&2) s[5] = 's'; printf("%s%4d%4d%5d%9D ",s,dd->d_uid, dd->d_gid,dd->d_tapea,dd->d_size); m = localtime(&dd->d_time); printf("%2d/%2d/%2d %2d:%2d ",m[5],m[4]+1,m[3],m[2],m[1]); } printf("%s\n", name); } extract(d) register struct dent *d; { register count, id; if (d->d_size==0) return; if (verify('x') < 0) return; rseek(d->d_tapea); unlink(name); if ((id = creat(name,d->d_mode)) < 0) printf("%s -- create error\n", name); count = d->d_size/BSIZE; while (count--) { tread(); if (write(id, (char *)tapeb, BSIZE) != BSIZE) goto ng; } if (count = d->d_size % BSIZE) { tread(); if (write(id, (char *)tapeb, count) != count) { ng: printf("%s -- write error\n", name); close(id); return; } } close(id); chown(name,d->d_uid & 0377, d->d_gid&0377); }