don't call setbuf, use optimal size.
[unix-history] / usr / src / old / tp / tp2.c
CommitLineData
cc4bd1b0
SL
1#ifndef lint
2static char sccsid[] = "@(#)tp2.c 4.1 %G%";
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
11struct stat statb;
12
13clrdir()
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
23clrent(ptr)
24struct 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
41rddir()
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
109wrdir()
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
168tread()
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
182twrite()
183{
184 if (write(fio, (char *)tapeb,BSIZE) != BSIZE) {
185 printf("Tape write error\n");
186 done();
187 }
188 ++wseeka;
189}
190
191rseek(blk)
192{
193 rseeka = blk;
194 if (lseek(fio,(long)blk*BSIZE,0) < 0) seekerr();
195}
196
197wseek(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
211seekerr()
212{
213 printf("Tape seek error\n");
214 done();
215}
216
217verify(key)
218{
219 register c;
220
221 if ((flags & (flw | flv)) == 0)
222 return(0);
223repeat: 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
239getfiles()
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
252expand()
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
281fserr()
282{
283 printf("%s -- Cannot open file\n", name);
284 done();
285}
286
287callout()
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;
324cont: 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);
337copydir:
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
346swabdir(tp)
347register 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}