xref: /original-bsd/old/tp/tp3.c (revision 88ad57e1)
1 #ifndef lint
2 static char sccsid[] = "@(#)tp3.c	4.2 12/01/92";
3 #endif
4 
5 #include "tp.h"
6 
7 gettape(how)
8 int (*how)();
9 {
10 	register char *ptr0, *ptr1;
11 	register struct dent *d;
12 	int count;
13 
14 	do {
15 		d = &dir[0];
16 		count = 0;
17 		do {
18 			if (d->d_namep == 0)  continue;
19 			decode(name,d);
20 			if (rnarg > 2) {
21 				ptr0 = name;
22 				ptr1 = *parg;
23 				while (*ptr1)
24 					if (*ptr0++ != *ptr1++)  goto cont;
25 				if (*ptr0 && *ptr0 != '/')       goto cont;
26 			}
27 			(*how)(d);  /* delete, extract, or taboc */
28 			++count;
29 cont:			continue;
30 		}  while (++d <= lastd);
31 		if (count == 0 && rnarg > 2)
32 			printf("%s  not found\n", *parg);
33 		++parg;
34 	} while (--narg > 2);
35 }
36 
37 delete(dd)
38 struct dent *dd;
39 {
40 	if (verify('d') >= 0)
41 		clrent(dd);
42 }
43 
44 
45 update()
46 {
47 	register struct dent *d;
48 	register b, last;
49 	int first, size;
50 
51 
52 	bitmap();
53 	d = &dir[0];
54 	do {
55 		if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue;
56 		if (d->d_size == 0)	  continue;
57 /* find a place on the tape for this file */
58 		size = (d->d_size+BSIZE-1)/BSIZE;
59 		first = ndentb;
60 toosmall:	++first;
61 		if ((last = first + size) >= tapsiz)	maperr();
62 		for (b = first; b < last; ++b)
63 			if (map[(b>>3) & MAPMASK] & (1<<(b&7))) {
64 				first = b;
65 				goto toosmall;
66 			};
67 		d->d_tapea = first;
68 		setmap(d);
69 	}  while (++d <= lastd);
70 	wrdir();
71 	update1();
72 }
73 
74 
75 update1()
76 {
77 	register struct dent *d, *id;
78 	register index;
79 	int f;
80 
81 	for (;;) {
82 		d = &dir[0];
83 		index = MTSIZ;
84 		id = 0;
85 		do {	/* find new dent with lowest tape address */
86 			if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue;
87 			if (d->d_tapea < index) {
88 				index = d->d_tapea;
89 				id = d;
90 			}
91 		} while (++d <= lastd);
92 		if ((d = id) == 0)	return;
93 		d->d_mode &= ~OK;  /* change from new to old */
94 		if (d->d_size == 0)  continue;
95 		decode(name,d);
96 		wseek(index);
97 		if ((f = open(name,0)) < 0) {
98 			printf("Can't open %s\n", name);
99 			continue;
100 		}
101 		for (index = d->d_size/BSIZE; index != 0; --index)  {
102 			if (read(f,(char *)tapeb,BSIZE) != BSIZE)	    phserr();
103 			twrite();
104 		}
105 		if (index = d->d_size % BSIZE) {
106 			if (read(f,(char *)tapeb,index) != index)  phserr();
107 			twrite();
108 		}
109 		if (read(f,(char *)tapeb,1) != 0)		    phserr();
110 		close(f);
111 	}
112 }
113 
114 phserr()
115 {	printf("%s -- Phase error \n", name);  }
116 
117 
118 bitmap()	/* place old files in the map */
119 {
120 	register char *m;
121 	register count;
122 	register struct dent *d;
123 
124 	for(m=map;m<&map[MAPSIZE];) *m++ = 0;
125 	count = ndirent;
126 	d = dir;
127 	do {
128 		if(d->d_namep != 0 && (d->d_mode&OK) == 0
129 		   && d->d_size != 0) setmap(d);
130 		d++;
131 	}  while (--count);
132 }
133 
134 setmap(d)
135 register struct dent *d;
136 {
137 	unsigned c, block;
138 	char bit;
139 	int i;
140 
141 	c = d->d_size/BSIZE;
142 	if (d->d_size % BSIZE)  c++;
143 	block = d->d_tapea;
144 	if ((c += block) >= tapsiz)		maperr();
145 	do {
146 		bit = 1 << (block & 7);
147 		i = (block>>3) & MAPMASK;
148 		if (bit & map[i])		maperr();
149 		map[i] |= bit;
150 	} while (++block < c);
151 }
152 
153 maperr()
154 {
155 	printf("Tape overflow\n");
156 	done();
157 }
158 
159 
160 usage()
161 {
162 	register reg,count;
163 	int	nused, nentr, nfree;
164 	static lused;
165 
166 	bitmap();
167 	for(count=0,nentr=0;count<ndirent;count++)
168 		if(dir[count].d_namep != 0) nentr++;
169 	nused = nfree = 0;
170 	reg = ndentb;
171 	++reg;		/* address of first non-directory tape block */
172 	count = tapsiz - reg;
173 	do {
174 		if (reg >= tapsiz) {
175 			printf("Tape overflow\n");
176 			done();
177 		}
178 		if (map[(reg>>3) & MAPMASK] & (1 << (reg&7))) {
179 			nused++;
180 			lused = reg;
181 		} else {
182 			if (flags & flm)   break;
183 			nfree++;
184 		}
185 		reg++;
186 	} while (--count);
187 	printf("%4d entries\n%4d used\n", nentr, nused);
188 	if ((flags & flm)==0)
189 		printf("%4d free\n", nfree);
190 	printf("%4d last\n", lused);
191 }
192 
193 
194 taboc(dd)
195 struct dent *dd;
196 {
197 	register  mode;
198 	register *m;
199 	register char *s;
200 	int count;
201 	char work[20];
202 
203 	if (flags & flv)  {
204 		mode = dd->d_mode;
205 		s = &work[19];
206 		*s = 0;
207 		for (count = 3; count; --count) {
208 			if (mode&1)	*--s = 'x';
209 			  else		*--s = '-';
210 			if (mode&2)	*--s = 'w';
211 			  else		*--s = '-';
212 			if (mode&4)	*--s = 'r';
213 			  else		*--s = '-';
214 			mode >>= 3;
215 		}
216 		if (mode&4)		s[2] = 's';
217 		if (mode&2)		s[5] = 's';
218 		printf("%s%4d%4d%5d%9D ",s,dd->d_uid, dd->d_gid,dd->d_tapea,dd->d_size);
219 		m = localtime(&dd->d_time);
220 		printf("%2d/%2d/%2d %2d:%2d ",m[5],m[4]+1,m[3],m[2],m[1]);
221 	}
222 	printf("%s\n", name);
223 }
224 
225 #include <sys/time.h>
226 
227 extract(d)
228 register struct dent *d;
229 {
230 	register count, id;
231 	struct timeval times[2];
232 
233 	if (d->d_size==0)	return;
234 	if (verify('x') < 0)			return;
235 	rseek(d->d_tapea);
236 	unlink(name);
237 	if ((id = creat(name,d->d_mode)) < 0)
238 		printf("%s -- create error\n", name);
239 	count = d->d_size/BSIZE;
240 	while (count--) {
241 		tread();
242 		if (write(id, (char *)tapeb, BSIZE) != BSIZE)	goto ng;
243 	}
244 	if (count = d->d_size % BSIZE) {
245 		tread();
246 		if (write(id, (char *)tapeb, count) != count) {
247 ng:			printf("%s -- write error\n", name);
248 			close(id);
249 			return;
250 		}
251 	}
252 	close(id);
253 	chown(name,d->d_uid & 0377, d->d_gid&0377);
254 	times[0].tv_sec = d->d_time;
255 	times[0].tv_usec = 0;
256 	times[1] = times[0];
257 	utimes(name, times);
258 }
259