xref: /csrg-svn/sys/stand.att/sys.c (revision 10022)
1*10022Ssam /*	sys.c	4.8	82/12/30	*/
2327Sbill 
36068Smckusic #include "../h/param.h"
46068Smckusic #include "../h/inode.h"
56068Smckusic #include "../h/fs.h"
67446Sroot #include "../h/dir.h"
7327Sbill #include "saio.h"
8327Sbill 
9327Sbill ino_t	dlook();
10327Sbill 
116068Smckusic struct dirstuff {
126068Smckusic 	int loc;
136068Smckusic 	struct iob *io;
146068Smckusic };
156068Smckusic 
16327Sbill static
17*10022Ssam openi(n, io)
186068Smckusic 	register struct iob *io;
19327Sbill {
20327Sbill 	register struct dinode *dp;
21327Sbill 
22327Sbill 	io->i_offset = 0;
236068Smckusic 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
246068Smckusic 	io->i_cc = io->i_fs.fs_bsize;
25327Sbill 	io->i_ma = io->i_buf;
26327Sbill 	devread(io);
27327Sbill 	dp = (struct dinode *)io->i_buf;
286068Smckusic 	io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
29327Sbill }
30327Sbill 
31327Sbill static
32327Sbill find(path, file)
336068Smckusic 	register char *path;
346068Smckusic 	struct iob *file;
35327Sbill {
36327Sbill 	register char *q;
37327Sbill 	char c;
38327Sbill 	int n;
39327Sbill 
40327Sbill 	if (path==NULL || *path=='\0') {
41327Sbill 		printf("null path\n");
42*10022Ssam 		return (0);
43327Sbill 	}
44327Sbill 
45327Sbill 	openi((ino_t) ROOTINO, file);
46327Sbill 	while (*path) {
47327Sbill 		while (*path == '/')
48327Sbill 			path++;
49327Sbill 		q = path;
50327Sbill 		while(*q != '/' && *q != '\0')
51327Sbill 			q++;
52327Sbill 		c = *q;
53327Sbill 		*q = '\0';
54327Sbill 
55327Sbill 		if ((n=dlook(path, file))!=0) {
56327Sbill 			if (c=='\0')
57327Sbill 				break;
58327Sbill 			openi(n, file);
59327Sbill 			*q = c;
60327Sbill 			path = q;
61327Sbill 			continue;
62327Sbill 		} else {
63327Sbill 			printf("%s not found\n",path);
64*10022Ssam 			return (0);
65327Sbill 		}
66327Sbill 	}
67*10022Ssam 	return (n);
68327Sbill }
69327Sbill 
70327Sbill static daddr_t
71327Sbill sbmap(io, bn)
726068Smckusic 	register struct iob *io;
736068Smckusic 	daddr_t bn;
74327Sbill {
75327Sbill 	register struct inode *ip;
766068Smckusic 	int i, j, sh;
77327Sbill 	daddr_t nb, *bap;
78327Sbill 
79327Sbill 	ip = &io->i_ino;
806068Smckusic 	if (bn < 0) {
81327Sbill 		printf("bn negative\n");
82*10022Ssam 		return ((daddr_t)0);
83327Sbill 	}
84327Sbill 
85327Sbill 	/*
866068Smckusic 	 * blocks 0..NDADDR are direct blocks
87327Sbill 	 */
886068Smckusic 	if(bn < NDADDR) {
896068Smckusic 		nb = ip->i_db[bn];
90*10022Ssam 		return (nb);
91327Sbill 	}
92327Sbill 
93327Sbill 	/*
946068Smckusic 	 * addresses NIADDR have single and double indirect blocks.
956068Smckusic 	 * the first step is to determine how many levels of indirection.
96327Sbill 	 */
976068Smckusic 	sh = 1;
986068Smckusic 	bn -= NDADDR;
996068Smckusic 	for (j = NIADDR; j > 0; j--) {
1006068Smckusic 		sh *= NINDIR(&io->i_fs);
1016068Smckusic 		if (bn < sh)
102327Sbill 			break;
1036068Smckusic 		bn -= sh;
104327Sbill 	}
1056068Smckusic 	if (j == 0) {
1066068Smckusic 		printf("bn ovf %D\n", bn);
1076068Smckusic 		return ((daddr_t)0);
108327Sbill 	}
109327Sbill 
110327Sbill 	/*
1116068Smckusic 	 * fetch the first indirect block address from the inode
112327Sbill 	 */
1136068Smckusic 	nb = ip->i_ib[NIADDR - j];
1146068Smckusic 	if (nb == 0) {
115327Sbill 		printf("bn void %D\n",bn);
116*10022Ssam 		return ((daddr_t)0);
117327Sbill 	}
118327Sbill 
119327Sbill 	/*
120327Sbill 	 * fetch through the indirect blocks
121327Sbill 	 */
1226068Smckusic 	for (; j <= NIADDR; j++) {
123327Sbill 		if (blknos[j] != nb) {
1246068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
125327Sbill 			io->i_ma = b[j];
1266068Smckusic 			io->i_cc = io->i_fs.fs_bsize;
127327Sbill 			devread(io);
128327Sbill 			blknos[j] = nb;
129327Sbill 		}
130327Sbill 		bap = (daddr_t *)b[j];
1316068Smckusic 		sh /= NINDIR(&io->i_fs);
1326068Smckusic 		i = (bn / sh) % NINDIR(&io->i_fs);
133327Sbill 		nb = bap[i];
134327Sbill 		if(nb == 0) {
135327Sbill 			printf("bn void %D\n",bn);
136*10022Ssam 			return ((daddr_t)0);
137327Sbill 		}
138327Sbill 	}
139*10022Ssam 	return (nb);
140327Sbill }
141327Sbill 
142327Sbill static ino_t
143327Sbill dlook(s, io)
1446068Smckusic 	char *s;
1456068Smckusic 	register struct iob *io;
146327Sbill {
147327Sbill 	register struct direct *dp;
148327Sbill 	register struct inode *ip;
1496068Smckusic 	struct dirstuff dirp;
1506068Smckusic 	int len;
151327Sbill 
1526068Smckusic 	if (s == NULL || *s == '\0')
153*10022Ssam 		return (0);
154327Sbill 	ip = &io->i_ino;
1556068Smckusic 	if ((ip->i_mode&IFMT) != IFDIR) {
156327Sbill 		printf("not a directory\n");
157*10022Ssam 		return (0);
158327Sbill 	}
1596068Smckusic 	if (ip->i_size == 0) {
160327Sbill 		printf("zero length directory\n");
161*10022Ssam 		return (0);
162327Sbill 	}
1636068Smckusic 	len = strlen(s);
1646068Smckusic 	dirp.loc = 0;
1656068Smckusic 	dirp.io = io;
1666068Smckusic 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
1676068Smckusic 		if(dp->d_ino == 0)
1686068Smckusic 			continue;
1696068Smckusic 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
170*10022Ssam 			return (dp->d_ino);
171327Sbill 	}
172*10022Ssam 	return (0);
173327Sbill }
174327Sbill 
1756068Smckusic /*
1766068Smckusic  * get next entry in a directory.
1776068Smckusic  */
1786068Smckusic struct direct *
1796068Smckusic readdir(dirp)
1806068Smckusic 	register struct dirstuff *dirp;
181327Sbill {
1826068Smckusic 	register struct direct *dp;
1836068Smckusic 	register struct iob *io;
1846068Smckusic 	daddr_t lbn, d;
1856068Smckusic 	int off;
186327Sbill 
1876068Smckusic 	io = dirp->io;
1886068Smckusic 	for(;;) {
1896068Smckusic 		if (dirp->loc >= io->i_ino.i_size)
1906068Smckusic 			return NULL;
1916068Smckusic 		off = blkoff(&io->i_fs, dirp->loc);
1926068Smckusic 		if (off == 0) {
1936068Smckusic 			lbn = lblkno(&io->i_fs, dirp->loc);
1946068Smckusic 			d = sbmap(io, lbn);
1956068Smckusic 			if(d == 0)
1966068Smckusic 				return NULL;
1976068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
1986068Smckusic 			io->i_ma = io->i_buf;
1996068Smckusic 			io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
2006068Smckusic 			devread(io);
2016068Smckusic 		}
2026068Smckusic 		dp = (struct direct *)(io->i_buf + off);
2036068Smckusic 		dirp->loc += dp->d_reclen;
2046068Smckusic 		if (dp->d_ino == 0)
2056068Smckusic 			continue;
2066068Smckusic 		return (dp);
207327Sbill 	}
208327Sbill }
209327Sbill 
210327Sbill lseek(fdesc, addr, ptr)
211*10022Ssam 	int fdesc, ptr;
212*10022Ssam 	off_t addr;
213327Sbill {
214327Sbill 	register struct iob *io;
215327Sbill 
216327Sbill 	if (ptr != 0) {
217327Sbill 		printf("Seek not from beginning of file\n");
218*10022Ssam 		errno = EOFFSET;
219*10022Ssam 		return (-1);
220327Sbill 	}
221327Sbill 	fdesc -= 3;
2226068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
223*10022Ssam 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
224*10022Ssam 		errno = EBADF;
225*10022Ssam 		return (-1);
226*10022Ssam 	}
227327Sbill 	io->i_offset = addr;
2286068Smckusic 	io->i_bn = addr / DEV_BSIZE;
229327Sbill 	io->i_cc = 0;
230*10022Ssam 	return (0);
231327Sbill }
232327Sbill 
233327Sbill getc(fdesc)
234*10022Ssam 	int fdesc;
235327Sbill {
236327Sbill 	register struct iob *io;
2376068Smckusic 	register struct fs *fs;
238327Sbill 	register char *p;
2396068Smckusic 	int c, lbn, off, size, diff;
240327Sbill 
241327Sbill 
242327Sbill 	if (fdesc >= 0 && fdesc <= 2)
243*10022Ssam 		return (getchar());
244327Sbill 	fdesc -= 3;
2456068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
246*10022Ssam 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
247*10022Ssam 		errno = EBADF;
248*10022Ssam 		return (-1);
249*10022Ssam 	}
250327Sbill 	p = io->i_ma;
251327Sbill 	if (io->i_cc <= 0) {
2526068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
2536068Smckusic 			diff = io->i_ino.i_size - io->i_offset;
2546068Smckusic 			if (diff <= 0)
2556068Smckusic 				return (-1);
2566068Smckusic 			fs = &io->i_fs;
2576068Smckusic 			lbn = lblkno(fs, io->i_offset);
2586068Smckusic 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
2596068Smckusic 			off = blkoff(fs, io->i_offset);
2606068Smckusic 			size = blksize(fs, &io->i_ino, lbn);
2616068Smckusic 		} else {
2626068Smckusic 			io->i_bn = io->i_offset / DEV_BSIZE;
2636068Smckusic 			off = 0;
2646068Smckusic 			size = DEV_BSIZE;
2656068Smckusic 		}
266327Sbill 		io->i_ma = io->i_buf;
2676068Smckusic 		io->i_cc = size;
268327Sbill 		devread(io);
2696068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
2706068Smckusic 			if (io->i_offset - off + size >= io->i_ino.i_size)
2716068Smckusic 				io->i_cc = diff + off;
272327Sbill 			io->i_cc -= off;
2736068Smckusic 		}
274327Sbill 		p = &io->i_buf[off];
275327Sbill 	}
276327Sbill 	io->i_cc--;
277327Sbill 	io->i_offset++;
278327Sbill 	c = (unsigned)*p++;
279327Sbill 	io->i_ma = p;
280*10022Ssam 	return (c);
281327Sbill }
2826068Smckusic 
283327Sbill /* does this port?
284327Sbill getw(fdesc)
285*10022Ssam 	int fdesc;
286327Sbill {
287327Sbill 	register w,i;
288327Sbill 	register char *cp;
289327Sbill 	int val;
290327Sbill 
291327Sbill 	for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
292327Sbill 		w = getc(fdesc);
293327Sbill 		if (w < 0) {
294327Sbill 			if (i == 0)
295*10022Ssam 				return (-1);
296327Sbill 			else
297*10022Ssam 				return (val);
298327Sbill 		}
299327Sbill 		*cp++ = w;
300327Sbill 	}
301*10022Ssam 	return (val);
302327Sbill }
303327Sbill */
304*10022Ssam int	errno;
305327Sbill 
306327Sbill read(fdesc, buf, count)
307*10022Ssam 	int fdesc, count;
308*10022Ssam 	char *buf;
309327Sbill {
310327Sbill 	register i;
311327Sbill 	register struct iob *file;
312327Sbill 
313*10022Ssam 	errno = 0;
314327Sbill 	if (fdesc >= 0 & fdesc <= 2) {
315327Sbill 		i = count;
316327Sbill 		do {
317327Sbill 			*buf = getchar();
318327Sbill 		} while (--i && *buf++ != '\n');
319*10022Ssam 		return (count - i);
320327Sbill 	}
321327Sbill 	fdesc -= 3;
3226068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
323*10022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
324*10022Ssam 		errno = EBADF;
325*10022Ssam 		return (-1);
326*10022Ssam 	}
327*10022Ssam 	if ((file->i_flgs&F_READ) == 0) {
328*10022Ssam 		errno = EBADF;
329*10022Ssam 		return (-1);
330*10022Ssam 	}
3316068Smckusic 	if ((file->i_flgs & F_FILE) == 0) {
332327Sbill 		file->i_cc = count;
333327Sbill 		file->i_ma = buf;
3347446Sroot 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
335327Sbill 		i = devread(file);
3367446Sroot 		file->i_offset += count;
337*10022Ssam 		if (i < 0)
338*10022Ssam 			errno = file->i_error;
339*10022Ssam 		return (i);
3406068Smckusic 	} else {
341327Sbill 		if (file->i_offset+count > file->i_ino.i_size)
342327Sbill 			count = file->i_ino.i_size - file->i_offset;
343327Sbill 		if ((i = count) <= 0)
344*10022Ssam 			return (0);
345327Sbill 		do {
346327Sbill 			*buf++ = getc(fdesc+3);
347327Sbill 		} while (--i);
348*10022Ssam 		return (count);
349327Sbill 	}
350327Sbill }
351327Sbill 
352327Sbill write(fdesc, buf, count)
353*10022Ssam 	int fdesc, count;
354*10022Ssam 	char *buf;
355327Sbill {
356327Sbill 	register i;
357327Sbill 	register struct iob *file;
358327Sbill 
359*10022Ssam 	errno = 0;
360327Sbill 	if (fdesc >= 0 && fdesc <= 2) {
361327Sbill 		i = count;
362327Sbill 		while (i--)
363327Sbill 			putchar(*buf++);
364*10022Ssam 		return (count);
365327Sbill 	}
366327Sbill 	fdesc -= 3;
3676068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
368*10022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
369*10022Ssam 		errno = EBADF;
370*10022Ssam 		return (-1);
371*10022Ssam 	}
372*10022Ssam 	if ((file->i_flgs&F_WRITE) == 0) {
373*10022Ssam 		errno = EBADF;
374*10022Ssam 		return (-1);
375*10022Ssam 	}
376327Sbill 	file->i_cc = count;
377327Sbill 	file->i_ma = buf;
3787446Sroot 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
379327Sbill 	i = devwrite(file);
3807446Sroot 	file->i_offset += count;
381*10022Ssam 	if (i < 0)
382*10022Ssam 		errno = file->i_error;
383*10022Ssam 	return (i);
384327Sbill }
385327Sbill 
3863349Swnj int	openfirst = 1;
3873349Swnj 
388327Sbill open(str, how)
3896068Smckusic 	char *str;
390*10022Ssam 	int how;
391327Sbill {
392327Sbill 	register char *cp;
393327Sbill 	int i;
394327Sbill 	register struct iob *file;
395327Sbill 	register struct devsw *dp;
396*10022Ssam 	int fdesc;
397*10022Ssam 	long atol();
398327Sbill 
3993349Swnj 	if (openfirst) {
400327Sbill 		for (i = 0; i < NFILES; i++)
401327Sbill 			iob[i].i_flgs = 0;
4023349Swnj 		openfirst = 0;
403327Sbill 	}
404327Sbill 
405327Sbill 	for (fdesc = 0; fdesc < NFILES; fdesc++)
406327Sbill 		if (iob[fdesc].i_flgs == 0)
407327Sbill 			goto gotfile;
408327Sbill 	_stop("No more file slots");
409327Sbill gotfile:
410327Sbill 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
411327Sbill 
412327Sbill 	for (cp = str; *cp && *cp != '('; cp++)
413327Sbill 			;
414327Sbill 	if (*cp != '(') {
415327Sbill 		printf("Bad device\n");
416327Sbill 		file->i_flgs = 0;
417*10022Ssam 		errno = EDEV;
418*10022Ssam 		return (-1);
419327Sbill 	}
420327Sbill 	*cp++ = '\0';
421327Sbill 	for (dp = devsw; dp->dv_name; dp++) {
4226068Smckusic 		if (!strcmp(str, dp->dv_name))
423327Sbill 			goto gotdev;
424327Sbill 	}
425327Sbill 	printf("Unknown device\n");
426327Sbill 	file->i_flgs = 0;
427*10022Ssam 	errno = ENXIO;
428*10022Ssam 	return (-1);
429327Sbill gotdev:
430327Sbill 	*(cp-1) = '(';
431327Sbill 	file->i_ino.i_dev = dp-devsw;
432327Sbill 	file->i_unit = *cp++ - '0';
4333274Swnj 	if (*cp >= '0' && *cp <= '9')
4343274Swnj 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
4353274Swnj 	if (file->i_unit < 0 || file->i_unit > 31) {
436327Sbill 		printf("Bad unit specifier\n");
437327Sbill 		file->i_flgs = 0;
438*10022Ssam 		errno = EUNIT;
439*10022Ssam 		return (-1);
440327Sbill 	}
441327Sbill 	if (*cp++ != ',') {
442327Sbill badoff:
443327Sbill 		printf("Missing offset specification\n");
444327Sbill 		file->i_flgs = 0;
445*10022Ssam 		errno = EOFFSET;
446*10022Ssam 		return (-1);
447327Sbill 	}
448327Sbill 	file->i_boff = atol(cp);
449327Sbill 	for (;;) {
450327Sbill 		if (*cp == ')')
451327Sbill 			break;
452327Sbill 		if (*cp++)
453327Sbill 			continue;
454327Sbill 		goto badoff;
455327Sbill 	}
456327Sbill 	devopen(file);
457327Sbill 	if (*++cp == '\0') {
458327Sbill 		file->i_flgs |= how+1;
459327Sbill 		file->i_cc = 0;
460327Sbill 		file->i_offset = 0;
461*10022Ssam 		return (fdesc+3);
462327Sbill 	}
4636068Smckusic 	file->i_ma = (char *)(&file->i_fs);
4646068Smckusic 	file->i_cc = SBSIZE;
4657446Sroot 	file->i_bn = SBLOCK + file->i_boff;
4666068Smckusic 	file->i_offset = 0;
4676068Smckusic 	devread(file);
468327Sbill 	if ((i = find(cp, file)) == 0) {
469327Sbill 		file->i_flgs = 0;
470*10022Ssam 		errno = ESRCH;
471*10022Ssam 		return (-1);
472327Sbill 	}
473327Sbill 	if (how != 0) {
474327Sbill 		printf("Can't write files yet.. Sorry\n");
475327Sbill 		file->i_flgs = 0;
476*10022Ssam 		errno = EIO;
477*10022Ssam 		return (-1);
478327Sbill 	}
479327Sbill 	openi(i, file);
480327Sbill 	file->i_offset = 0;
481327Sbill 	file->i_cc = 0;
482327Sbill 	file->i_flgs |= F_FILE | (how+1);
483*10022Ssam 	return (fdesc+3);
484327Sbill }
485327Sbill 
486327Sbill close(fdesc)
487*10022Ssam 	int fdesc;
488327Sbill {
489327Sbill 	struct iob *file;
490327Sbill 
491327Sbill 	fdesc -= 3;
4926068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
493*10022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
494*10022Ssam 		errno = EBADF;
495*10022Ssam 		return (-1);
496*10022Ssam 	}
497327Sbill 	if ((file->i_flgs&F_FILE) == 0)
498327Sbill 		devclose(file);
499327Sbill 	file->i_flgs = 0;
500*10022Ssam 	return (0);
501327Sbill }
502327Sbill 
503*10022Ssam ioctl(fdesc, cmd, arg)
504*10022Ssam 	int fdesc, cmd;
505*10022Ssam 	char *arg;
506*10022Ssam {
507*10022Ssam 	register struct iob *file;
508*10022Ssam 	int error = 0;
509*10022Ssam 
510*10022Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
511*10022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
512*10022Ssam 		errno = EBADF;
513*10022Ssam 		return (-1);
514*10022Ssam 	}
515*10022Ssam 	switch (cmd) {
516*10022Ssam 
517*10022Ssam 	case SAIOHDR:
518*10022Ssam 		file->i_flgs |= F_HDR;
519*10022Ssam 		break;
520*10022Ssam 
521*10022Ssam 	case SAIOCHECK:
522*10022Ssam 		file->i_flgs |= F_CHECK;
523*10022Ssam 		break;
524*10022Ssam 
525*10022Ssam 	case SAIOHCHECK:
526*10022Ssam 		file->i_flgs |= F_HCHECK;
527*10022Ssam 		break;
528*10022Ssam 
529*10022Ssam 	default:
530*10022Ssam 		error = devioctl(file, cmd, arg);
531*10022Ssam 		break;
532*10022Ssam 	}
533*10022Ssam 	if (error < 0)
534*10022Ssam 		errno = file->i_error;
535*10022Ssam 	return (error);
536*10022Ssam }
537*10022Ssam 
538327Sbill exit()
539327Sbill {
540327Sbill 	_stop("Exit called");
541327Sbill }
542327Sbill 
543327Sbill _stop(s)
544*10022Ssam 	char *s;
545327Sbill {
5462391Stoy 	int i;
5472391Stoy 
5482391Stoy 	for (i = 0; i < NFILES; i++)
5492391Stoy 		if (iob[i].i_flgs != 0)
5502391Stoy 			close(i);
551327Sbill 	printf("%s\n", s);
552327Sbill 	_rtt();
553327Sbill }
554327Sbill 
555327Sbill trap(ps)
5566068Smckusic 	int ps;
557327Sbill {
558327Sbill 	printf("Trap %o\n", ps);
559327Sbill 	for (;;)
560327Sbill 		;
561327Sbill }
562