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