Research V7 development
[unix-history] / usr / src / cmd / tp / tp2.c
CommitLineData
88f62f26
KT
1#include "tp.h"
2#include <stdio.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <sys/dir.h>
6
7struct direct direct;
8struct stat statb;
9
10clrdir()
11{
12 register j, *p;
13
14 j = ndirent * (DIRSZ/sizeof(int));
15 p = (int *)dir;
16 do (*p++ = 0); while (--j);
17 lastd = 0;
18}
19
20clrent(ptr)
21struct dent *ptr;
22{
23 register *p, j;
24
25 p = (int *)ptr;
26 j = DIRSZ/sizeof(int);
27 do *p++ = 0;
28 while (--j);
29 if (++ptr == lastd) do {
30 if (--lastd < dir) {
31 lastd = 0;
32 return;
33 }
34 } while (lastd->d_namep == 0);
35}
36
37
38rddir()
39{
40 register struct tent *tp;
41 register struct dent *p1;
42 struct dent *dptr;
43 struct tent *tptr;
44 int count, i, sum;
45 short reg, *sp;
46
47 sum = 0;
48 clrdir();
49 rseek(0);
50 tread(); /* Read the bootstrap block */
51 if ((tpentry[TPB-1].cksum != 0) && (flags & flm)) {
52 ndirent = tpentry[TPB-1].cksum;
53 if(flags & fls) swab((char *)&ndirent, (char *)&ndirent, sizeof(ndirent));
54 if(ndirent < 0 || ndirent > MDIRENT) ndirent = MDIRENT;
55 ndentb = ndirent/TPB;
56 }
57 dptr = &dir[0];
58 count = ndirent;
59 do {
60 if ((count % TPB) == 0) { /* next block */
61 tread();
62 tptr = &tpentry[0];
63 }
64 if(flags & fls)
65 swab((char *)tptr, (char *)tptr, sizeof(*tptr));
66 sp = (short *)tptr;
67 reg = 0;
68 for(i=0;i<sizeof(struct tent)/sizeof(short);i++)
69 reg += *sp++;
70 if(flags & fls) {
71 swab((char *)tptr, (char *)tptr, sizeof(*tptr));
72 swabdir(tptr);
73 }
74 sum |= reg;
75 p1 = dptr;
76 if (reg == 0) {
77 tp = tptr;
78 if(tp->pathnam[0] != '\0') {
79 lastd = p1;
80 encode(tp->pathnam,p1);
81 p1->d_mode = tp->mode;
82 p1->d_uid = tp->uid;
83 p1->d_gid = tp->gid;
84 p1->d_size = (((long)tp->size0&0377L)<<16)+(tp->size1&0177777L);
85 p1->d_time = tp->time;
86 p1->d_tapea = tp->tapea;
87 }
88 }
89 ++tptr; /* bump to next tent */
90 (dptr++)->d_mode &= ~OK;
91 } while (--count);
92 if(sum != 0)
93 if(flags & (fls|fli)) {
94 printf("Directory checksum\n");
95 if ((flags & fli) == 0) done();
96 } else {
97 flags |= fls;
98 rddir();
99 printf("Warning: swabbing required\n");
100 return;
101 }
102 bitmap();
103}
104
105
106wrdir()
107{
108 register struct tent *tp;
109 register struct dent *dp;
110 struct dent *dptr;
111 int count, i;
112 short reg, *sp;
113
114 wseek(0);
115 if (flags & flm)
116 reg = open(mheader,0);
117 else reg = open(theader,0);
118 if (reg >= 0) {
119 read(reg,(char *)tapeb,BSIZE);
120 close(reg);
121 if(flags & fls)
122 swab((char *)&ndirent, (char *)&tpentry[TPB-1].cksum, sizeof(ndirent));
123 else
124 tpentry[TPB-1].cksum = ndirent;
125 }
126 dptr = &dir[0];
127 count = ndirent;
128 for (;;) {
129 twrite();
130 if (count == 0) return;
131 tp = &tpentry[0];
132 do {
133 dp = dptr++; /* dptr set to next entry */
134 if (dp->d_namep) {
135 decode(tp->pathnam,dp);
136 tp->mode = dp->d_mode;
137 tp->uid = dp->d_uid;
138 tp->gid = dp->d_gid;
139 tp->time = dp->d_time;
140 tp->size0 = dp->d_size >> 16;
141 tp->size1 = dp->d_size;
142 tp->tapea = dp->d_tapea;
143 if(flags & fls) {
144 swabdir(tp);
145 swab((char *)tp, (char *)tp, sizeof(*tp));
146 }
147 reg = 0;
148 sp = (short *)tp;
149 for(i=0;i<sizeof(struct tent)/sizeof(short)-1;i++)
150 reg -= *sp++;
151 *sp = reg;
152 if(flags & fls)
153 swab((char *)tp, (char *)tp, sizeof(*tp));
154 } else {
155 sp = (short *)tp;
156 for(i=0;i<sizeof(struct tent)/sizeof(short);i++)
157 *sp++ = 0;
158 }
159 tp++;
160 } while (--count % TPB);
161 }
162}
163
164tread()
165{
166 register j, *ptr;
167
168 if (read(fio,(char *)tapeb,BSIZE) != BSIZE) {
169 printf("Tape read error\n");
170 if ((flags & fli) == 0) done();
171 ptr = (int *)tapeb;
172 j = BSIZE/sizeof(int);
173 while(j--) *ptr++ = 0;
174 }
175 rseeka++;
176}
177
178twrite()
179{
180 if (write(fio, (char *)tapeb,BSIZE) != BSIZE) {
181 printf("Tape write error\n");
182 done();
183 }
184 ++wseeka;
185}
186
187rseek(blk)
188{
189 rseeka = blk;
190 if (lseek(fio,(long)blk*BSIZE,0) < 0) seekerr();
191}
192
193wseek(blk)
194{
195 register amt, b;
196
197 amt = b = blk;
198 if ((amt -= wseeka) < 0) amt = -amt;
199 if (amt > 25 && b) {
200 lseek(fio, (long)(b-1)*BSIZE, 0); /* seek previous block */
201 read(fio, (char *)&wseeka, 1); /* read next block */
202 }
203 wseeka = b;
204 if (lseek(fio, (long)b*BSIZE, 0) < 0) seekerr();
205}
206
207seekerr()
208{
209 printf("Tape seek error\n");
210 done();
211}
212
213verify(key)
214{
215 register c;
216
217 if ((flags & (flw | flv)) == 0)
218 return(0);
219repeat: printf("%c %s ", key, name);
220 if ((flags & flw) == 0) {
221 printf("\n");
222 return(0);
223 }
224 c = getchar();
225 if (c == 'n' && getchar() == '\n')
226 done();
227 if (c == '\n')
228 return(-1);
229 if (c == 'y' && getchar() == '\n')
230 return(0);
231 while (getchar() != '\n');
232 goto repeat;
233}
234
235getfiles()
236{
237
238 if ((narg -= 2) == 0) {
239 strcpy(name, ".");
240 callout();
241 } else while (--narg >= 0) {
242 strcpy(name, *parg++);
243 callout();
244 }
245}
246
247
248expand()
249{
250 register char *p0, *save0;
251 int n, fid;
252
253 if ((fid = open(name,0)) < 0) fserr();
254 for (;;) {
255 if ((n = read(fid, (char *)&direct, sizeof(direct))) != sizeof(direct)) {
256 if (n == 0) {
257 close(fid);
258 return;
259 }
260 fserr();
261 }
262 if (direct.d_ino == 0) /* null entry */
263 continue;
264 p0 = name;
265 if (direct.d_name[0] == '.') /* don't save .xxxx */
266 continue;
267 while (*p0++);
268 save0 = --p0; /* save loc of \0 */
269 if (p0[-1] != '/')
270 *p0++ = '/';
271 strcpy(p0, direct.d_name);
272 callout();
273 *save0 = 0; /* restore */
274 }
275}
276
277fserr()
278{
279 printf("%s -- Cannot open file\n", name);
280 done();
281}
282
283callout()
284{
285 register struct dent *d;
286 register char *ptr1, *ptr0;
287 struct dent *empty;
288 int mode;
289
290 if (stat(name,&statb) < 0) fserr();
291 mode = statb.st_mode;
292 if ((mode &= S_IFMT) != 0) {
293 if (mode == S_IFDIR) /* directory */
294 expand();
295 if(mode != S_IFREG) return;
296 }
297 /* when we reach here we have recursed until we found
298 * an ordinary file. Now we look for it in "dir".
299 */
300 empty = 0;
301 d = &dir[0];
302 do {
303 if (d->d_namep == 0) { /* empty directory slot */
304 if (empty == 0) /* remember the first one */
305 empty = d;
306 continue;
307 }
308 decode(name1,d);
309 ptr0 = name;
310 ptr1 = name1;
311 do if (*ptr0++ != *ptr1) goto cont;
312 while (*ptr1++);
313 /* veritably the same name */
314 if (flags & flu) { /* check the times */
315 if (d->d_time >= statb.st_mtime)
316 return;
317 }
318 if (verify('r') < 0) return;
319 goto copydir;
320cont: continue;
321 } while (++d <= lastd);
322 /* name not found in directory */
323 if ((d = empty) == 0) {
324 d = lastd +1;
325 if (d >= edir) {
326 printf("Directory overflow\n");
327 done();
328 }
329 }
330 if (verify('a') < 0) return;
331 if (d > lastd) lastd = d;
332 encode(name,d);
333copydir:
334 d->d_mode = statb.st_mode | OK;
335 d->d_uid = statb.st_uid;
336 d->d_gid = statb.st_gid;
337 d->d_size = statb.st_size;
338 d->d_time = statb.st_mtime;
339}
340
341swabdir(tp)
342register struct tent *tp;
343{
344 swab((char *)tp, (char *)tp, sizeof(*tp));
345 swab(tp->pathnam, tp->pathnam, NAMELEN);
346 swab((char *)&tp->uid, (char *)&tp->uid, 4); /* uid,gid,spare,size0 */
347}