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