1*9832Ssam #ifndef lint 2*9832Ssam static char sccsid[] = "@(#)tp3.c 4.1 12/18/82"; 3*9832Ssam #endif 4*9832Ssam 5*9832Ssam #include "tp.h" 6*9832Ssam 7*9832Ssam gettape(how) 8*9832Ssam int (*how)(); 9*9832Ssam { 10*9832Ssam register char *ptr0, *ptr1; 11*9832Ssam register struct dent *d; 12*9832Ssam int count; 13*9832Ssam 14*9832Ssam do { 15*9832Ssam d = &dir[0]; 16*9832Ssam count = 0; 17*9832Ssam do { 18*9832Ssam if (d->d_namep == 0) continue; 19*9832Ssam decode(name,d); 20*9832Ssam if (rnarg > 2) { 21*9832Ssam ptr0 = name; 22*9832Ssam ptr1 = *parg; 23*9832Ssam while (*ptr1) 24*9832Ssam if (*ptr0++ != *ptr1++) goto cont; 25*9832Ssam if (*ptr0 && *ptr0 != '/') goto cont; 26*9832Ssam } 27*9832Ssam (*how)(d); /* delete, extract, or taboc */ 28*9832Ssam ++count; 29*9832Ssam cont: continue; 30*9832Ssam } while (++d <= lastd); 31*9832Ssam if (count == 0 && rnarg > 2) 32*9832Ssam printf("%s not found\n", *parg); 33*9832Ssam ++parg; 34*9832Ssam } while (--narg > 2); 35*9832Ssam } 36*9832Ssam 37*9832Ssam delete(dd) 38*9832Ssam struct dent *dd; 39*9832Ssam { 40*9832Ssam if (verify('d') >= 0) 41*9832Ssam clrent(dd); 42*9832Ssam } 43*9832Ssam 44*9832Ssam 45*9832Ssam update() 46*9832Ssam { 47*9832Ssam register struct dent *d; 48*9832Ssam register b, last; 49*9832Ssam int first, size; 50*9832Ssam 51*9832Ssam 52*9832Ssam bitmap(); 53*9832Ssam d = &dir[0]; 54*9832Ssam do { 55*9832Ssam if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue; 56*9832Ssam if (d->d_size == 0) continue; 57*9832Ssam /* find a place on the tape for this file */ 58*9832Ssam size = (d->d_size+BSIZE-1)/BSIZE; 59*9832Ssam first = ndentb; 60*9832Ssam toosmall: ++first; 61*9832Ssam if ((last = first + size) >= tapsiz) maperr(); 62*9832Ssam for (b = first; b < last; ++b) 63*9832Ssam if (map[(b>>3) & MAPMASK] & (1<<(b&7))) { 64*9832Ssam first = b; 65*9832Ssam goto toosmall; 66*9832Ssam }; 67*9832Ssam d->d_tapea = first; 68*9832Ssam setmap(d); 69*9832Ssam } while (++d <= lastd); 70*9832Ssam wrdir(); 71*9832Ssam update1(); 72*9832Ssam } 73*9832Ssam 74*9832Ssam 75*9832Ssam update1() 76*9832Ssam { 77*9832Ssam register struct dent *d, *id; 78*9832Ssam register index; 79*9832Ssam int f; 80*9832Ssam 81*9832Ssam for (;;) { 82*9832Ssam d = &dir[0]; 83*9832Ssam index = MTSIZ; 84*9832Ssam id = 0; 85*9832Ssam do { /* find new dent with lowest tape address */ 86*9832Ssam if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue; 87*9832Ssam if (d->d_tapea < index) { 88*9832Ssam index = d->d_tapea; 89*9832Ssam id = d; 90*9832Ssam } 91*9832Ssam } while (++d <= lastd); 92*9832Ssam if ((d = id) == 0) return; 93*9832Ssam d->d_mode &= ~OK; /* change from new to old */ 94*9832Ssam if (d->d_size == 0) continue; 95*9832Ssam decode(name,d); 96*9832Ssam wseek(index); 97*9832Ssam if ((f = open(name,0)) < 0) { 98*9832Ssam printf("Can't open %s\n", name); 99*9832Ssam continue; 100*9832Ssam } 101*9832Ssam for (index = d->d_size/BSIZE; index != 0; --index) { 102*9832Ssam if (read(f,(char *)tapeb,BSIZE) != BSIZE) phserr(); 103*9832Ssam twrite(); 104*9832Ssam } 105*9832Ssam if (index = d->d_size % BSIZE) { 106*9832Ssam if (read(f,(char *)tapeb,index) != index) phserr(); 107*9832Ssam twrite(); 108*9832Ssam } 109*9832Ssam if (read(f,(char *)tapeb,1) != 0) phserr(); 110*9832Ssam close(f); 111*9832Ssam } 112*9832Ssam } 113*9832Ssam 114*9832Ssam phserr() 115*9832Ssam { printf("%s -- Phase error \n", name); } 116*9832Ssam 117*9832Ssam 118*9832Ssam bitmap() /* place old files in the map */ 119*9832Ssam { 120*9832Ssam register char *m; 121*9832Ssam register count; 122*9832Ssam register struct dent *d; 123*9832Ssam 124*9832Ssam for(m=map;m<&map[MAPSIZE];) *m++ = 0; 125*9832Ssam count = ndirent; 126*9832Ssam d = dir; 127*9832Ssam do { 128*9832Ssam if(d->d_namep != 0 && (d->d_mode&OK) == 0 129*9832Ssam && d->d_size != 0) setmap(d); 130*9832Ssam d++; 131*9832Ssam } while (--count); 132*9832Ssam } 133*9832Ssam 134*9832Ssam setmap(d) 135*9832Ssam register struct dent *d; 136*9832Ssam { 137*9832Ssam unsigned c, block; 138*9832Ssam char bit; 139*9832Ssam int i; 140*9832Ssam 141*9832Ssam c = d->d_size/BSIZE; 142*9832Ssam if (d->d_size % BSIZE) c++; 143*9832Ssam block = d->d_tapea; 144*9832Ssam if ((c += block) >= tapsiz) maperr(); 145*9832Ssam do { 146*9832Ssam bit = 1 << (block & 7); 147*9832Ssam i = (block>>3) & MAPMASK; 148*9832Ssam if (bit & map[i]) maperr(); 149*9832Ssam map[i] |= bit; 150*9832Ssam } while (++block < c); 151*9832Ssam } 152*9832Ssam 153*9832Ssam maperr() 154*9832Ssam { 155*9832Ssam printf("Tape overflow\n"); 156*9832Ssam done(); 157*9832Ssam } 158*9832Ssam 159*9832Ssam 160*9832Ssam usage() 161*9832Ssam { 162*9832Ssam register reg,count; 163*9832Ssam int nused, nentr, nfree; 164*9832Ssam static lused; 165*9832Ssam 166*9832Ssam bitmap(); 167*9832Ssam for(count=0,nentr=0;count<ndirent;count++) 168*9832Ssam if(dir[count].d_namep != 0) nentr++; 169*9832Ssam nused = nfree = 0; 170*9832Ssam reg = ndentb; 171*9832Ssam ++reg; /* address of first non-directory tape block */ 172*9832Ssam count = tapsiz - reg; 173*9832Ssam do { 174*9832Ssam if (reg >= tapsiz) { 175*9832Ssam printf("Tape overflow\n"); 176*9832Ssam done(); 177*9832Ssam } 178*9832Ssam if (map[(reg>>3) & MAPMASK] & (1 << (reg&7))) { 179*9832Ssam nused++; 180*9832Ssam lused = reg; 181*9832Ssam } else { 182*9832Ssam if (flags & flm) break; 183*9832Ssam nfree++; 184*9832Ssam } 185*9832Ssam reg++; 186*9832Ssam } while (--count); 187*9832Ssam printf("%4d entries\n%4d used\n", nentr, nused); 188*9832Ssam if ((flags & flm)==0) 189*9832Ssam printf("%4d free\n", nfree); 190*9832Ssam printf("%4d last\n", lused); 191*9832Ssam } 192*9832Ssam 193*9832Ssam 194*9832Ssam taboc(dd) 195*9832Ssam struct dent *dd; 196*9832Ssam { 197*9832Ssam register mode; 198*9832Ssam register *m; 199*9832Ssam register char *s; 200*9832Ssam int count, *localtime(); 201*9832Ssam char work[20]; 202*9832Ssam 203*9832Ssam if (flags & flv) { 204*9832Ssam mode = dd->d_mode; 205*9832Ssam s = &work[19]; 206*9832Ssam *s = 0; 207*9832Ssam for (count = 3; count; --count) { 208*9832Ssam if (mode&1) *--s = 'x'; 209*9832Ssam else *--s = '-'; 210*9832Ssam if (mode&2) *--s = 'w'; 211*9832Ssam else *--s = '-'; 212*9832Ssam if (mode&4) *--s = 'r'; 213*9832Ssam else *--s = '-'; 214*9832Ssam mode >>= 3; 215*9832Ssam } 216*9832Ssam if (mode&4) s[2] = 's'; 217*9832Ssam if (mode&2) s[5] = 's'; 218*9832Ssam printf("%s%4d%4d%5d%9D ",s,dd->d_uid, dd->d_gid,dd->d_tapea,dd->d_size); 219*9832Ssam m = localtime(&dd->d_time); 220*9832Ssam printf("%2d/%2d/%2d %2d:%2d ",m[5],m[4]+1,m[3],m[2],m[1]); 221*9832Ssam } 222*9832Ssam printf("%s\n", name); 223*9832Ssam } 224*9832Ssam 225*9832Ssam 226*9832Ssam extract(d) 227*9832Ssam register struct dent *d; 228*9832Ssam { 229*9832Ssam register count, id; 230*9832Ssam 231*9832Ssam if (d->d_size==0) return; 232*9832Ssam if (verify('x') < 0) return; 233*9832Ssam rseek(d->d_tapea); 234*9832Ssam unlink(name); 235*9832Ssam if ((id = creat(name,d->d_mode)) < 0) 236*9832Ssam printf("%s -- create error\n", name); 237*9832Ssam count = d->d_size/BSIZE; 238*9832Ssam while (count--) { 239*9832Ssam tread(); 240*9832Ssam if (write(id, (char *)tapeb, BSIZE) != BSIZE) goto ng; 241*9832Ssam } 242*9832Ssam if (count = d->d_size % BSIZE) { 243*9832Ssam tread(); 244*9832Ssam if (write(id, (char *)tapeb, count) != count) { 245*9832Ssam ng: printf("%s -- write error\n", name); 246*9832Ssam close(id); 247*9832Ssam return; 248*9832Ssam } 249*9832Ssam } 250*9832Ssam close(id); 251*9832Ssam chown(name,d->d_uid & 0377, d->d_gid&0377); 252*9832Ssam } 253