19832Ssam #ifndef lint
2*56929Sbostic static char sccsid[] = "@(#)tp3.c 4.2 12/01/92";
39832Ssam #endif
49832Ssam
59832Ssam #include "tp.h"
69832Ssam
79832Ssam gettape(how)
89832Ssam int (*how)();
99832Ssam {
109832Ssam register char *ptr0, *ptr1;
119832Ssam register struct dent *d;
129832Ssam int count;
139832Ssam
149832Ssam do {
159832Ssam d = &dir[0];
169832Ssam count = 0;
179832Ssam do {
189832Ssam if (d->d_namep == 0) continue;
199832Ssam decode(name,d);
209832Ssam if (rnarg > 2) {
219832Ssam ptr0 = name;
229832Ssam ptr1 = *parg;
239832Ssam while (*ptr1)
249832Ssam if (*ptr0++ != *ptr1++) goto cont;
259832Ssam if (*ptr0 && *ptr0 != '/') goto cont;
269832Ssam }
279832Ssam (*how)(d); /* delete, extract, or taboc */
289832Ssam ++count;
299832Ssam cont: continue;
309832Ssam } while (++d <= lastd);
319832Ssam if (count == 0 && rnarg > 2)
329832Ssam printf("%s not found\n", *parg);
339832Ssam ++parg;
349832Ssam } while (--narg > 2);
359832Ssam }
369832Ssam
379832Ssam delete(dd)
389832Ssam struct dent *dd;
399832Ssam {
409832Ssam if (verify('d') >= 0)
419832Ssam clrent(dd);
429832Ssam }
439832Ssam
449832Ssam
update()459832Ssam update()
469832Ssam {
479832Ssam register struct dent *d;
489832Ssam register b, last;
499832Ssam int first, size;
509832Ssam
519832Ssam
529832Ssam bitmap();
539832Ssam d = &dir[0];
549832Ssam do {
559832Ssam if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue;
569832Ssam if (d->d_size == 0) continue;
579832Ssam /* find a place on the tape for this file */
589832Ssam size = (d->d_size+BSIZE-1)/BSIZE;
599832Ssam first = ndentb;
609832Ssam toosmall: ++first;
619832Ssam if ((last = first + size) >= tapsiz) maperr();
629832Ssam for (b = first; b < last; ++b)
639832Ssam if (map[(b>>3) & MAPMASK] & (1<<(b&7))) {
649832Ssam first = b;
659832Ssam goto toosmall;
669832Ssam };
679832Ssam d->d_tapea = first;
689832Ssam setmap(d);
699832Ssam } while (++d <= lastd);
709832Ssam wrdir();
719832Ssam update1();
729832Ssam }
739832Ssam
749832Ssam
update1()759832Ssam update1()
769832Ssam {
779832Ssam register struct dent *d, *id;
789832Ssam register index;
799832Ssam int f;
809832Ssam
819832Ssam for (;;) {
829832Ssam d = &dir[0];
839832Ssam index = MTSIZ;
849832Ssam id = 0;
859832Ssam do { /* find new dent with lowest tape address */
869832Ssam if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue;
879832Ssam if (d->d_tapea < index) {
889832Ssam index = d->d_tapea;
899832Ssam id = d;
909832Ssam }
919832Ssam } while (++d <= lastd);
929832Ssam if ((d = id) == 0) return;
939832Ssam d->d_mode &= ~OK; /* change from new to old */
949832Ssam if (d->d_size == 0) continue;
959832Ssam decode(name,d);
969832Ssam wseek(index);
979832Ssam if ((f = open(name,0)) < 0) {
989832Ssam printf("Can't open %s\n", name);
999832Ssam continue;
1009832Ssam }
1019832Ssam for (index = d->d_size/BSIZE; index != 0; --index) {
1029832Ssam if (read(f,(char *)tapeb,BSIZE) != BSIZE) phserr();
1039832Ssam twrite();
1049832Ssam }
1059832Ssam if (index = d->d_size % BSIZE) {
1069832Ssam if (read(f,(char *)tapeb,index) != index) phserr();
1079832Ssam twrite();
1089832Ssam }
1099832Ssam if (read(f,(char *)tapeb,1) != 0) phserr();
1109832Ssam close(f);
1119832Ssam }
1129832Ssam }
1139832Ssam
phserr()1149832Ssam phserr()
1159832Ssam { printf("%s -- Phase error \n", name); }
1169832Ssam
1179832Ssam
bitmap()1189832Ssam bitmap() /* place old files in the map */
1199832Ssam {
1209832Ssam register char *m;
1219832Ssam register count;
1229832Ssam register struct dent *d;
1239832Ssam
1249832Ssam for(m=map;m<&map[MAPSIZE];) *m++ = 0;
1259832Ssam count = ndirent;
1269832Ssam d = dir;
1279832Ssam do {
1289832Ssam if(d->d_namep != 0 && (d->d_mode&OK) == 0
1299832Ssam && d->d_size != 0) setmap(d);
1309832Ssam d++;
1319832Ssam } while (--count);
1329832Ssam }
1339832Ssam
setmap(d)1349832Ssam setmap(d)
1359832Ssam register struct dent *d;
1369832Ssam {
1379832Ssam unsigned c, block;
1389832Ssam char bit;
1399832Ssam int i;
1409832Ssam
1419832Ssam c = d->d_size/BSIZE;
1429832Ssam if (d->d_size % BSIZE) c++;
1439832Ssam block = d->d_tapea;
1449832Ssam if ((c += block) >= tapsiz) maperr();
1459832Ssam do {
1469832Ssam bit = 1 << (block & 7);
1479832Ssam i = (block>>3) & MAPMASK;
1489832Ssam if (bit & map[i]) maperr();
1499832Ssam map[i] |= bit;
1509832Ssam } while (++block < c);
1519832Ssam }
1529832Ssam
maperr()1539832Ssam maperr()
1549832Ssam {
1559832Ssam printf("Tape overflow\n");
1569832Ssam done();
1579832Ssam }
1589832Ssam
1599832Ssam
usage()1609832Ssam usage()
1619832Ssam {
1629832Ssam register reg,count;
1639832Ssam int nused, nentr, nfree;
1649832Ssam static lused;
1659832Ssam
1669832Ssam bitmap();
1679832Ssam for(count=0,nentr=0;count<ndirent;count++)
1689832Ssam if(dir[count].d_namep != 0) nentr++;
1699832Ssam nused = nfree = 0;
1709832Ssam reg = ndentb;
1719832Ssam ++reg; /* address of first non-directory tape block */
1729832Ssam count = tapsiz - reg;
1739832Ssam do {
1749832Ssam if (reg >= tapsiz) {
1759832Ssam printf("Tape overflow\n");
1769832Ssam done();
1779832Ssam }
1789832Ssam if (map[(reg>>3) & MAPMASK] & (1 << (reg&7))) {
1799832Ssam nused++;
1809832Ssam lused = reg;
1819832Ssam } else {
1829832Ssam if (flags & flm) break;
1839832Ssam nfree++;
1849832Ssam }
1859832Ssam reg++;
1869832Ssam } while (--count);
1879832Ssam printf("%4d entries\n%4d used\n", nentr, nused);
1889832Ssam if ((flags & flm)==0)
1899832Ssam printf("%4d free\n", nfree);
1909832Ssam printf("%4d last\n", lused);
1919832Ssam }
1929832Ssam
1939832Ssam
1949832Ssam taboc(dd)
1959832Ssam struct dent *dd;
1969832Ssam {
1979832Ssam register mode;
1989832Ssam register *m;
1999832Ssam register char *s;
200*56929Sbostic int count;
2019832Ssam char work[20];
2029832Ssam
2039832Ssam if (flags & flv) {
2049832Ssam mode = dd->d_mode;
2059832Ssam s = &work[19];
2069832Ssam *s = 0;
2079832Ssam for (count = 3; count; --count) {
2089832Ssam if (mode&1) *--s = 'x';
2099832Ssam else *--s = '-';
2109832Ssam if (mode&2) *--s = 'w';
2119832Ssam else *--s = '-';
2129832Ssam if (mode&4) *--s = 'r';
2139832Ssam else *--s = '-';
2149832Ssam mode >>= 3;
2159832Ssam }
2169832Ssam if (mode&4) s[2] = 's';
2179832Ssam if (mode&2) s[5] = 's';
2189832Ssam printf("%s%4d%4d%5d%9D ",s,dd->d_uid, dd->d_gid,dd->d_tapea,dd->d_size);
2199832Ssam m = localtime(&dd->d_time);
2209832Ssam printf("%2d/%2d/%2d %2d:%2d ",m[5],m[4]+1,m[3],m[2],m[1]);
2219832Ssam }
2229832Ssam printf("%s\n", name);
2239832Ssam }
2249832Ssam
225*56929Sbostic #include <sys/time.h>
2269832Ssam
extract(d)2279832Ssam extract(d)
2289832Ssam register struct dent *d;
2299832Ssam {
2309832Ssam register count, id;
231*56929Sbostic struct timeval times[2];
2329832Ssam
2339832Ssam if (d->d_size==0) return;
2349832Ssam if (verify('x') < 0) return;
2359832Ssam rseek(d->d_tapea);
2369832Ssam unlink(name);
2379832Ssam if ((id = creat(name,d->d_mode)) < 0)
2389832Ssam printf("%s -- create error\n", name);
2399832Ssam count = d->d_size/BSIZE;
2409832Ssam while (count--) {
2419832Ssam tread();
2429832Ssam if (write(id, (char *)tapeb, BSIZE) != BSIZE) goto ng;
2439832Ssam }
2449832Ssam if (count = d->d_size % BSIZE) {
2459832Ssam tread();
2469832Ssam if (write(id, (char *)tapeb, count) != count) {
2479832Ssam ng: printf("%s -- write error\n", name);
2489832Ssam close(id);
2499832Ssam return;
2509832Ssam }
2519832Ssam }
2529832Ssam close(id);
2539832Ssam chown(name,d->d_uid & 0377, d->d_gid&0377);
254*56929Sbostic times[0].tv_sec = d->d_time;
255*56929Sbostic times[0].tv_usec = 0;
256*56929Sbostic times[1] = times[0];
257*56929Sbostic utimes(name, times);
2589832Ssam }
259