1 #ifndef lint
2 static char sccsid[] = "@(#)tp3.c 4.2 12/01/92";
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
update()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
update1()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
phserr()114 phserr()
115 { printf("%s -- Phase error \n", name); }
116
117
bitmap()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
setmap(d)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
maperr()153 maperr()
154 {
155 printf("Tape overflow\n");
156 done();
157 }
158
159
usage()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;
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 #include <sys/time.h>
226
extract(d)227 extract(d)
228 register struct dent *d;
229 {
230 register count, id;
231 struct timeval times[2];
232
233 if (d->d_size==0) return;
234 if (verify('x') < 0) return;
235 rseek(d->d_tapea);
236 unlink(name);
237 if ((id = creat(name,d->d_mode)) < 0)
238 printf("%s -- create error\n", name);
239 count = d->d_size/BSIZE;
240 while (count--) {
241 tread();
242 if (write(id, (char *)tapeb, BSIZE) != BSIZE) goto ng;
243 }
244 if (count = d->d_size % BSIZE) {
245 tread();
246 if (write(id, (char *)tapeb, count) != count) {
247 ng: printf("%s -- write error\n", name);
248 close(id);
249 return;
250 }
251 }
252 close(id);
253 chown(name,d->d_uid & 0377, d->d_gid&0377);
254 times[0].tv_sec = d->d_time;
255 times[0].tv_usec = 0;
256 times[1] = times[0];
257 utimes(name, times);
258 }
259