xref: /csrg-svn/old/tp/tp2.c (revision 9831)
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