BSD 3 development
[unix-history] / usr / src / cmd / tp / tp2.c
CommitLineData
42d6e430
BJ
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 } else
126 printf("\7\7\7Warning: cannot read prototype boot block.\n");
127 dptr = &dir[0];
128 count = ndirent;
129 for (;;) {
130 twrite();
131 if (count == 0) return;
132 tp = &tpentry[0];
133 do {
134 dp = dptr++; /* dptr set to next entry */
135 if (dp->d_namep) {
136 decode(tp->pathnam,dp);
137 tp->mode = dp->d_mode;
138 tp->uid = dp->d_uid;
139 tp->gid = dp->d_gid;
140 tp->time = dp->d_time;
141 tp->size0 = dp->d_size >> 16;
142 tp->size1 = dp->d_size;
143 tp->tapea = dp->d_tapea;
144 if(flags & fls) {
145 swabdir(tp);
146 swab((char *)tp, (char *)tp, sizeof(*tp));
147 }
148 reg = 0;
149 sp = (short *)tp;
150 for(i=0;i<sizeof(struct tent)/sizeof(short)-1;i++)
151 reg -= *sp++;
152 *sp = reg;
153 if(flags & fls)
154 swab((char *)tp, (char *)tp, sizeof(*tp));
155 } else {
156 sp = (short *)tp;
157 for(i=0;i<sizeof(struct tent)/sizeof(short);i++)
158 *sp++ = 0;
159 }
160 tp++;
161 } while (--count % TPB);
162 }
163}
164
165tread()
166{
167 register j, *ptr;
168
169 if (read(fio,(char *)tapeb,BSIZE) != BSIZE) {
170 printf("Tape read error\n");
171 if ((flags & fli) == 0) done();
172 ptr = (int *)tapeb;
173 j = BSIZE/sizeof(int);
174 while(j--) *ptr++ = 0;
175 }
176 rseeka++;
177}
178
179twrite()
180{
181 if (write(fio, (char *)tapeb,BSIZE) != BSIZE) {
182 printf("Tape write error\n");
183 done();
184 }
185 ++wseeka;
186}
187
188rseek(blk)
189{
190 rseeka = blk;
191 if (lseek(fio,(long)blk*BSIZE,0) < 0) seekerr();
192}
193
194wseek(blk)
195{
196 register amt, b;
197
198 amt = b = blk;
199 if ((amt -= wseeka) < 0) amt = -amt;
200 if (amt > 25 && b) {
201 lseek(fio, (long)(b-1)*BSIZE, 0); /* seek previous block */
202 read(fio, (char *)&wseeka, 1); /* read next block */
203 }
204 wseeka = b;
205 if (lseek(fio, (long)b*BSIZE, 0) < 0) seekerr();
206}
207
208seekerr()
209{
210 printf("Tape seek error\n");
211 done();
212}
213
214verify(key)
215{
216 register c;
217
218 if ((flags & (flw | flv)) == 0)
219 return(0);
220repeat: printf("%c %s ", key, name);
221 if ((flags & flw) == 0) {
222 printf("\n");
223 return(0);
224 }
225 c = getchar();
226 if (c == 'n' && getchar() == '\n')
227 done();
228 if (c == '\n')
229 return(-1);
230 if (c == 'y' && getchar() == '\n')
231 return(0);
232 while (getchar() != '\n');
233 goto repeat;
234}
235
236getfiles()
237{
238
239 if ((narg -= 2) == 0) {
240 strcpy(name, ".");
241 callout();
242 } else while (--narg >= 0) {
243 strcpy(name, *parg++);
244 callout();
245 }
246}
247
248
249expand()
250{
251 register char *p0, *save0;
252 int n, fid;
253
254 if ((fid = open(name,0)) < 0) fserr();
255 for (;;) {
256 if ((n = read(fid, (char *)&direct, sizeof(direct))) != sizeof(direct)) {
257 if (n == 0) {
258 close(fid);
259 return;
260 }
261 fserr();
262 }
263 if (direct.d_ino == 0) /* null entry */
264 continue;
265 p0 = name;
266 if (direct.d_name[0] == '.') /* don't save .xxxx */
267 continue;
268 while (*p0++);
269 save0 = --p0; /* save loc of \0 */
270 if (p0[-1] != '/')
271 *p0++ = '/';
272 strcpy(p0, direct.d_name);
273 callout();
274 *save0 = 0; /* restore */
275 }
276}
277
278fserr()
279{
280 printf("%s -- Cannot open file\n", name);
281 done();
282}
283
284callout()
285{
286 register struct dent *d;
287 register char *ptr1, *ptr0;
288 struct dent *empty;
289 int mode;
290
291 if (stat(name,&statb) < 0) fserr();
292 mode = statb.st_mode;
293 if ((mode &= S_IFMT) != 0) {
294 if (mode == S_IFDIR) /* directory */
295 expand();
296 if(mode != S_IFREG) return;
297 }
298 /* when we reach here we have recursed until we found
299 * an ordinary file. Now we look for it in "dir".
300 */
301 empty = 0;
302 d = &dir[0];
303 do {
304 if (d->d_namep == 0) { /* empty directory slot */
305 if (empty == 0) /* remember the first one */
306 empty = d;
307 continue;
308 }
309 decode(name1,d);
310 ptr0 = name;
311 ptr1 = name1;
312 do if (*ptr0++ != *ptr1) goto cont;
313 while (*ptr1++);
314 /* veritably the same name */
315 if (flags & flu) { /* check the times */
316 if (d->d_time >= statb.st_mtime)
317 return;
318 }
319 if (verify('r') < 0) return;
320 goto copydir;
321cont: continue;
322 } while (++d <= lastd);
323 /* name not found in directory */
324 if ((d = empty) == 0) {
325 d = lastd +1;
326 if (d >= edir) {
327 printf("Directory overflow\n");
328 done();
329 }
330 }
331 if (verify('a') < 0) return;
332 if (d > lastd) lastd = d;
333 encode(name,d);
334copydir:
335 d->d_mode = statb.st_mode | OK;
336 d->d_uid = statb.st_uid;
337 d->d_gid = statb.st_gid;
338 d->d_size = statb.st_size;
339 d->d_time = statb.st_mtime;
340}
341
342swabdir(tp)
343register struct tent *tp;
344{
345 swab((char *)tp, (char *)tp, sizeof(*tp));
346 swab(tp->pathnam, tp->pathnam, NAMELEN);
347 swab((char *)&tp->uid, (char *)&tp->uid, 4); /* uid,gid,spare,size0 */
348}