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