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