xref: /original-bsd/sys/stand.att/sys.c (revision d25e1985)
1 /*	sys.c	1.1	06/28/80	*/
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 open(str, how)
359 char *str;
360 int	how;
361 {
362 	register char *cp;
363 	int i;
364 	register struct iob *file;
365 	register struct devsw *dp;
366 	int	fdesc;
367 	static first = 1;
368 	long	atol();
369 
370 	if (first) {
371 		for (i = 0; i < NFILES; i++)
372 			iob[i].i_flgs = 0;
373 		first = 0;
374 	}
375 
376 	for (fdesc = 0; fdesc < NFILES; fdesc++)
377 		if (iob[fdesc].i_flgs == 0)
378 			goto gotfile;
379 	_stop("No more file slots");
380 gotfile:
381 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
382 
383 	for (cp = str; *cp && *cp != '('; cp++)
384 			;
385 	if (*cp != '(') {
386 		printf("Bad device\n");
387 		file->i_flgs = 0;
388 		return(-1);
389 	}
390 	*cp++ = '\0';
391 	for (dp = devsw; dp->dv_name; dp++) {
392 		if (match(str, dp->dv_name))
393 			goto gotdev;
394 	}
395 	printf("Unknown device\n");
396 	file->i_flgs = 0;
397 	return(-1);
398 gotdev:
399 	*(cp-1) = '(';
400 	file->i_ino.i_dev = dp-devsw;
401 	file->i_unit = *cp++ - '0';
402 	if (file->i_unit < 0 || file->i_unit > 7) {
403 		printf("Bad unit specifier\n");
404 		file->i_flgs = 0;
405 		return(-1);
406 	}
407 	if (*cp++ != ',') {
408 badoff:
409 		printf("Missing offset specification\n");
410 		file->i_flgs = 0;
411 		return(-1);
412 	}
413 	file->i_boff = atol(cp);
414 	for (;;) {
415 		if (*cp == ')')
416 			break;
417 		if (*cp++)
418 			continue;
419 		goto badoff;
420 	}
421 	devopen(file);
422 	if (*++cp == '\0') {
423 		file->i_flgs |= how+1;
424 		file->i_cc = 0;
425 		file->i_offset = 0;
426 		return(fdesc+3);
427 	}
428 	if ((i = find(cp, file)) == 0) {
429 		file->i_flgs = 0;
430 		return(-1);
431 	}
432 	if (how != 0) {
433 		printf("Can't write files yet.. Sorry\n");
434 		file->i_flgs = 0;
435 		return(-1);
436 	}
437 	openi(i, file);
438 	file->i_offset = 0;
439 	file->i_cc = 0;
440 	file->i_flgs |= F_FILE | (how+1);
441 	return(fdesc+3);
442 }
443 
444 close(fdesc)
445 int	fdesc;
446 {
447 	struct iob *file;
448 
449 	fdesc -= 3;
450 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
451 		return(-1);
452 	if ((file->i_flgs&F_FILE) == 0)
453 		devclose(file);
454 	file->i_flgs = 0;
455 	return(0);
456 }
457 
458 exit()
459 {
460 	_stop("Exit called");
461 }
462 
463 _stop(s)
464 char	*s;
465 {
466 	printf("%s\n", s);
467 	_rtt();
468 }
469 
470 trap(ps)
471 int ps;
472 {
473 	printf("Trap %o\n", ps);
474 	for (;;)
475 		;
476 }
477