Commit | Line | Data |
---|---|---|
62b54b9e SL |
1 | #ifndef lint |
2 | static char sccsid[] = "@(#)tp3.c 4.1 %G%"; | |
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 | extract(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 | ng: 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 | } |