xref: /original-bsd/sys/stand.att/sys.c (revision 6c57d260)
1 /*	sys.c	4.4	81/03/22	*/
2 
3 #include <sys/param.h>
4 #include <sys/ino.h>
5 #include <sys/inode.h>
6 #include <sys/filsys.h>
7 #include <sys/dir.h>
8 #include "saio.h"
9 
10 ino_t	dlook();
11 
12 static
13 openi(n,io)
14 register struct iob *io;
15 {
16 	register struct dinode *dp;
17 
18 	io->i_offset = 0;
19 	io->i_bn = fsbtodb(itod(n)) + io->i_boff;
20 	io->i_cc = BSIZE;
21 	io->i_ma = io->i_buf;
22 	devread(io);
23 
24 	dp = (struct dinode *)io->i_buf;
25 	dp = &dp[itoo(n)];
26 	io->i_ino.i_number = n;
27 	io->i_ino.i_mode = dp->di_mode;
28 	io->i_ino.i_size = dp->di_size;
29 	l3tol((char *)io->i_ino.i_un.i_addr, (char *)dp->di_addr, NADDR);
30 }
31 
32 static
33 find(path, file)
34 register char *path;
35 struct iob *file;
36 {
37 	register char *q;
38 	char c;
39 	int n;
40 
41 	if (path==NULL || *path=='\0') {
42 		printf("null path\n");
43 		return(0);
44 	}
45 
46 	openi((ino_t) ROOTINO, file);
47 	while (*path) {
48 		while (*path == '/')
49 			path++;
50 		q = path;
51 		while(*q != '/' && *q != '\0')
52 			q++;
53 		c = *q;
54 		*q = '\0';
55 
56 		if ((n=dlook(path, file))!=0) {
57 			if (c=='\0')
58 				break;
59 			openi(n, file);
60 			*q = c;
61 			path = q;
62 			continue;
63 		} else {
64 			printf("%s not found\n",path);
65 			return(0);
66 		}
67 	}
68 	return(n);
69 }
70 
71 static daddr_t
72 sbmap(io, bn)
73 register struct iob *io;
74 daddr_t bn;
75 {
76 	register i;
77 	register struct inode *ip;
78 	int j, sh;
79 	daddr_t nb, *bap;
80 	int ibn = bn;
81 
82 	ip = &io->i_ino;
83 	if(bn < 0) {
84 		printf("bn negative\n");
85 		return((daddr_t)0);
86 	}
87 
88 	/*
89 	 * blocks 0..NADDR-4 are direct blocks
90 	 */
91 	if(bn < NADDR-3) {
92 		i = bn;
93 		nb = ip->i_un.i_addr[i];
94 		return(nb);
95 	}
96 
97 	/*
98 	 * addresses NADDR-3, NADDR-2, and NADDR-1
99 	 * have single, double, triple indirect blocks.
100 	 * the first step is to determine
101 	 * how many levels of indirection.
102 	 */
103 	sh = 0;
104 	nb = 1;
105 	bn -= NADDR-3;
106 	for(j=3; j>0; j--) {
107 		sh += NSHIFT;
108 		nb <<= NSHIFT;
109 		if(bn < nb)
110 			break;
111 		bn -= nb;
112 	}
113 	if(j == 0) {
114 		printf("bn ovf %D\n",bn);
115 		return((daddr_t)0);
116 	}
117 
118 	/*
119 	 * fetch the address from the inode
120 	 */
121 	nb = ip->i_un.i_addr[NADDR-j];
122 	if(nb == 0) {
123 		printf("bn void %D\n",bn);
124 		return((daddr_t)0);
125 	}
126 
127 	/*
128 	 * fetch through the indirect blocks
129 	 */
130 	for(; j<=3; j++) {
131 		if (blknos[j] != nb) {
132 			io->i_bn = fsbtodb(nb) + io->i_boff;
133 			io->i_ma = b[j];
134 			io->i_cc = BSIZE;
135 			devread(io);
136 			bap = (daddr_t *)b[j];
137 			blknos[j] = nb;
138 		}
139 		bap = (daddr_t *)b[j];
140 		sh -= NSHIFT;
141 		i = (bn>>sh) & NMASK;
142 		nb = bap[i];
143 		if(nb == 0) {
144 			printf("bn void %D\n",bn);
145 			return((daddr_t)0);
146 		}
147 	}
148 	return(nb);
149 }
150 
151 static ino_t
152 dlook(s, io)
153 char *s;
154 register struct iob *io;
155 {
156 	register struct direct *dp;
157 	register struct inode *ip;
158 	daddr_t bn;
159 	int n,dc;
160 
161 	if (s==NULL || *s=='\0')
162 		return(0);
163 	ip = &io->i_ino;
164 	if ((ip->i_mode&IFMT)!=IFDIR) {
165 		printf("not a directory\n");
166 		return(0);
167 	}
168 
169 	n = ip->i_size/sizeof(struct direct);
170 
171 	if (n==0) {
172 		printf("zero length directory\n");
173 		return(0);
174 	}
175 
176 	dc = BSIZE;
177 	bn = (daddr_t)0;
178 	while(n--) {
179 		if (++dc >= BSIZE/sizeof(struct direct)) {
180 			io->i_bn = fsbtodb(sbmap(io, bn++)) + io->i_boff;
181 			io->i_ma = io->i_buf;
182 			io->i_cc = BSIZE;
183 			devread(io);
184 			dp = (struct direct *)io->i_buf;
185 			dc = 0;
186 		}
187 
188 		if (match(s, dp->d_name))
189 			return(dp->d_ino);
190 		dp++;
191 	}
192 	return(0);
193 }
194 
195 static
196 match(s1,s2)
197 register char *s1,*s2;
198 {
199 	register cc;
200 
201 	cc = DIRSIZ;
202 	while (cc--) {
203 		if (*s1 != *s2)
204 			return(0);
205 		if (*s1++ && *s2++)
206 			continue; else
207 			return(1);
208 	}
209 	return(1);
210 }
211 
212 lseek(fdesc, addr, ptr)
213 int	fdesc;
214 off_t	addr;
215 int	ptr;
216 {
217 	register struct iob *io;
218 
219 	if (ptr != 0) {
220 		printf("Seek not from beginning of file\n");
221 		return(-1);
222 	}
223 	fdesc -= 3;
224 	if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
225 		return(-1);
226 	io->i_offset = addr;
227 	io->i_bn = fsbtodb(addr/BSIZE) + io->i_boff;
228 	io->i_cc = 0;
229 	return(0);
230 }
231 
232 getc(fdesc)
233 int	fdesc;
234 {
235 	register struct iob *io;
236 	register char *p;
237 	register  c;
238 	int off;
239 
240 
241 	if (fdesc >= 0 && fdesc <= 2)
242 		return(getchar());
243 	fdesc -= 3;
244 	if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
245 		return(-1);
246 	p = io->i_ma;
247 	if (io->i_cc <= 0) {
248 		io->i_bn = fsbtodb(io->i_offset/(off_t)BSIZE);
249 		if (io->i_flgs&F_FILE)
250 			io->i_bn = fsbtodb(sbmap(io, dbtofsb(io->i_bn))) + io->i_boff;
251 		io->i_ma = io->i_buf;
252 		io->i_cc = BSIZE;
253 		devread(io);
254 		if (io->i_flgs&F_FILE) {
255 			off = io->i_offset % (off_t)BSIZE;
256 			if (io->i_offset+(BSIZE-off) >= io->i_ino.i_size)
257 				io->i_cc = io->i_ino.i_size - io->i_offset + off;
258 			io->i_cc -= off;
259 			if (io->i_cc <= 0)
260 				return(-1);
261 		} else
262 			off = 0;
263 		p = &io->i_buf[off];
264 	}
265 	io->i_cc--;
266 	io->i_offset++;
267 	c = (unsigned)*p++;
268 	io->i_ma = p;
269 	return(c);
270 }
271 /* does this port?
272 getw(fdesc)
273 int	fdesc;
274 {
275 	register w,i;
276 	register char *cp;
277 	int val;
278 
279 	for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
280 		w = getc(fdesc);
281 		if (w < 0) {
282 			if (i == 0)
283 				return(-1);
284 			else
285 				return(val);
286 		}
287 		*cp++ = w;
288 	}
289 	return(val);
290 }
291 */
292 
293 read(fdesc, buf, count)
294 int	fdesc;
295 char	*buf;
296 int	count;
297 {
298 	register i;
299 	register struct iob *file;
300 
301 	if (fdesc >= 0 & fdesc <= 2) {
302 		i = count;
303 		do {
304 			*buf = getchar();
305 		} while (--i && *buf++ != '\n');
306 		return(count - i);
307 	}
308 	fdesc -= 3;
309 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
310 		return(-1);
311 	if ((file->i_flgs&F_READ) == 0)
312 		return(-1);
313 	if ((file->i_flgs&F_FILE) == 0) {
314 		file->i_cc = count;
315 		file->i_ma = buf;
316 		i = devread(file);
317 		file->i_bn += CLSIZE;
318 		return(i);
319 	}
320 	else {
321 		if (file->i_offset+count > file->i_ino.i_size)
322 			count = file->i_ino.i_size - file->i_offset;
323 		if ((i = count) <= 0)
324 			return(0);
325 		do {
326 			*buf++ = getc(fdesc+3);
327 		} while (--i);
328 		return(count);
329 	}
330 }
331 
332 write(fdesc, buf, count)
333 int	fdesc;
334 char	*buf;
335 int	count;
336 {
337 	register i;
338 	register struct iob *file;
339 
340 	if (fdesc >= 0 && fdesc <= 2) {
341 		i = count;
342 		while (i--)
343 			putchar(*buf++);
344 		return(count);
345 	}
346 	fdesc -= 3;
347 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
348 		return(-1);
349 	if ((file->i_flgs&F_WRITE) == 0)
350 		return(-1);
351 	file->i_cc = count;
352 	file->i_ma = buf;
353 	i = devwrite(file);
354 	file->i_bn += CLSIZE;
355 	return(i);
356 }
357 
358 int	openfirst = 1;
359 
360 open(str, how)
361 char *str;
362 int	how;
363 {
364 	register char *cp;
365 	int i;
366 	register struct iob *file;
367 	register struct devsw *dp;
368 	int	fdesc;
369 	long	atol();
370 
371 	if (openfirst) {
372 		for (i = 0; i < NFILES; i++)
373 			iob[i].i_flgs = 0;
374 		openfirst = 0;
375 	}
376 
377 	for (fdesc = 0; fdesc < NFILES; fdesc++)
378 		if (iob[fdesc].i_flgs == 0)
379 			goto gotfile;
380 	_stop("No more file slots");
381 gotfile:
382 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
383 
384 	for (cp = str; *cp && *cp != '('; cp++)
385 			;
386 	if (*cp != '(') {
387 		printf("Bad device\n");
388 		file->i_flgs = 0;
389 		return(-1);
390 	}
391 	*cp++ = '\0';
392 	for (dp = devsw; dp->dv_name; dp++) {
393 		if (match(str, dp->dv_name))
394 			goto gotdev;
395 	}
396 	printf("Unknown device\n");
397 	file->i_flgs = 0;
398 	return(-1);
399 gotdev:
400 	*(cp-1) = '(';
401 	file->i_ino.i_dev = dp-devsw;
402 	file->i_unit = *cp++ - '0';
403 	if (*cp >= '0' && *cp <= '9')
404 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
405 	if (file->i_unit < 0 || file->i_unit > 31) {
406 		printf("Bad unit specifier\n");
407 		file->i_flgs = 0;
408 		return(-1);
409 	}
410 	if (*cp++ != ',') {
411 badoff:
412 		printf("Missing offset specification\n");
413 		file->i_flgs = 0;
414 		return(-1);
415 	}
416 	file->i_boff = atol(cp);
417 	for (;;) {
418 		if (*cp == ')')
419 			break;
420 		if (*cp++)
421 			continue;
422 		goto badoff;
423 	}
424 	devopen(file);
425 	if (*++cp == '\0') {
426 		file->i_flgs |= how+1;
427 		file->i_cc = 0;
428 		file->i_offset = 0;
429 		return(fdesc+3);
430 	}
431 	if ((i = find(cp, file)) == 0) {
432 		file->i_flgs = 0;
433 		return(-1);
434 	}
435 	if (how != 0) {
436 		printf("Can't write files yet.. Sorry\n");
437 		file->i_flgs = 0;
438 		return(-1);
439 	}
440 	openi(i, file);
441 	file->i_offset = 0;
442 	file->i_cc = 0;
443 	file->i_flgs |= F_FILE | (how+1);
444 	return(fdesc+3);
445 }
446 
447 close(fdesc)
448 int	fdesc;
449 {
450 	struct iob *file;
451 
452 	fdesc -= 3;
453 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
454 		return(-1);
455 	if ((file->i_flgs&F_FILE) == 0)
456 		devclose(file);
457 	file->i_flgs = 0;
458 	return(0);
459 }
460 
461 exit()
462 {
463 	_stop("Exit called");
464 }
465 
466 _stop(s)
467 char	*s;
468 {
469 	int i;
470 
471 	for (i = 0; i < NFILES; i++)
472 		if (iob[i].i_flgs != 0)
473 			close(i);
474 	printf("%s\n", s);
475 	_rtt();
476 }
477 
478 trap(ps)
479 int ps;
480 {
481 	printf("Trap %o\n", ps);
482 	for (;;)
483 		;
484 }
485