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