xref: /original-bsd/sys/stand.att/sys.c (revision fbed46ce)
1 /*	sys.c	4.5	82/03/07	*/
2 
3 #include "../h/param.h"
4 #include "../h/inode.h"
5 #include "../h/fs.h"
6 #include "../h/ndir.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 		i = devread(file);
326 		file->i_bn += (count / DEV_BSIZE);
327 		return(i);
328 	} else {
329 		if (file->i_offset+count > file->i_ino.i_size)
330 			count = file->i_ino.i_size - file->i_offset;
331 		if ((i = count) <= 0)
332 			return(0);
333 		do {
334 			*buf++ = getc(fdesc+3);
335 		} while (--i);
336 		return(count);
337 	}
338 }
339 
340 write(fdesc, buf, count)
341 	int	fdesc;
342 	char	*buf;
343 	int	count;
344 {
345 	register i;
346 	register struct iob *file;
347 
348 	if (fdesc >= 0 && fdesc <= 2) {
349 		i = count;
350 		while (i--)
351 			putchar(*buf++);
352 		return(count);
353 	}
354 	fdesc -= 3;
355 	if (fdesc < 0 || fdesc >= NFILES ||
356 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
357 		return(-1);
358 	if ((file->i_flgs&F_WRITE) == 0)
359 		return(-1);
360 	file->i_cc = count;
361 	file->i_ma = buf;
362 	i = devwrite(file);
363 	file->i_bn += (count / DEV_BSIZE);
364 	return(i);
365 }
366 
367 int	openfirst = 1;
368 
369 open(str, how)
370 	char *str;
371 	int	how;
372 {
373 	register char *cp;
374 	int i;
375 	register struct iob *file;
376 	register struct devsw *dp;
377 	int	fdesc;
378 	long	atol();
379 
380 	if (openfirst) {
381 		for (i = 0; i < NFILES; i++)
382 			iob[i].i_flgs = 0;
383 		openfirst = 0;
384 	}
385 
386 	for (fdesc = 0; fdesc < NFILES; fdesc++)
387 		if (iob[fdesc].i_flgs == 0)
388 			goto gotfile;
389 	_stop("No more file slots");
390 gotfile:
391 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
392 
393 	for (cp = str; *cp && *cp != '('; cp++)
394 			;
395 	if (*cp != '(') {
396 		printf("Bad device\n");
397 		file->i_flgs = 0;
398 		return(-1);
399 	}
400 	*cp++ = '\0';
401 	for (dp = devsw; dp->dv_name; dp++) {
402 		if (!strcmp(str, dp->dv_name))
403 			goto gotdev;
404 	}
405 	printf("Unknown device\n");
406 	file->i_flgs = 0;
407 	return(-1);
408 gotdev:
409 	*(cp-1) = '(';
410 	file->i_ino.i_dev = dp-devsw;
411 	file->i_unit = *cp++ - '0';
412 	if (*cp >= '0' && *cp <= '9')
413 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
414 	if (file->i_unit < 0 || file->i_unit > 31) {
415 		printf("Bad unit specifier\n");
416 		file->i_flgs = 0;
417 		return(-1);
418 	}
419 	if (*cp++ != ',') {
420 badoff:
421 		printf("Missing offset specification\n");
422 		file->i_flgs = 0;
423 		return(-1);
424 	}
425 	file->i_boff = atol(cp);
426 	for (;;) {
427 		if (*cp == ')')
428 			break;
429 		if (*cp++)
430 			continue;
431 		goto badoff;
432 	}
433 	devopen(file);
434 	if (*++cp == '\0') {
435 		file->i_flgs |= how+1;
436 		file->i_cc = 0;
437 		file->i_offset = 0;
438 		return(fdesc+3);
439 	}
440 	file->i_ma = (char *)(&file->i_fs);
441 	file->i_cc = SBSIZE;
442 	file->i_bn = SBLOCK;
443 	file->i_offset = 0;
444 	devread(file);
445 	if ((i = find(cp, file)) == 0) {
446 		file->i_flgs = 0;
447 		return(-1);
448 	}
449 	if (how != 0) {
450 		printf("Can't write files yet.. Sorry\n");
451 		file->i_flgs = 0;
452 		return(-1);
453 	}
454 	openi(i, file);
455 	file->i_offset = 0;
456 	file->i_cc = 0;
457 	file->i_flgs |= F_FILE | (how+1);
458 	return(fdesc+3);
459 }
460 
461 close(fdesc)
462 	int	fdesc;
463 {
464 	struct iob *file;
465 
466 	fdesc -= 3;
467 	if (fdesc < 0 || fdesc >= NFILES ||
468 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
469 		return(-1);
470 	if ((file->i_flgs&F_FILE) == 0)
471 		devclose(file);
472 	file->i_flgs = 0;
473 	return(0);
474 }
475 
476 exit()
477 {
478 	_stop("Exit called");
479 }
480 
481 _stop(s)
482 	char	*s;
483 {
484 	int i;
485 
486 	for (i = 0; i < NFILES; i++)
487 		if (iob[i].i_flgs != 0)
488 			close(i);
489 	printf("%s\n", s);
490 	_rtt();
491 }
492 
493 trap(ps)
494 	int ps;
495 {
496 	printf("Trap %o\n", ps);
497 	for (;;)
498 		;
499 }
500