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