141488Smckusick /*
241488Smckusick * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
341488Smckusick * All rights reserved.
441488Smckusick *
541488Smckusick * %sccs.include.redist.c%
641488Smckusick *
7*44826Skarels * @(#)sys.c 7.2 (Berkeley) 07/01/90
841488Smckusick */
941488Smckusick
1041488Smckusick #include "saio.h"
1141488Smckusick #include "ufs/dir.h"
1241488Smckusick #ifndef SMALL
1341488Smckusick #include "sys/stat.h"
1441488Smckusick #endif
1541488Smckusick
1641488Smckusick ino_t dlook();
1741488Smckusick
1841488Smckusick struct dirstuff {
1941488Smckusick int loc;
2041488Smckusick struct iob *io;
2141488Smckusick };
2241488Smckusick
2341488Smckusick static
openi(n,io)2441488Smckusick openi(n, io)
2541488Smckusick register struct iob *io;
2641488Smckusick {
2741488Smckusick register struct dinode *dp;
2841488Smckusick int cc;
2941488Smckusick
3041488Smckusick io->i_offset = 0;
3141488Smckusick io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
3241488Smckusick io->i_cc = io->i_fs.fs_bsize;
3341488Smckusick io->i_ma = io->i_buf;
3441488Smckusick cc = devread(io);
3541488Smckusick dp = (struct dinode *)io->i_buf;
36*44826Skarels io->i_ino = dp[itoo(&io->i_fs, n)];
3741488Smckusick return (cc);
3841488Smckusick }
3941488Smckusick
4041488Smckusick static
find(path,file)4141488Smckusick find(path, file)
4241488Smckusick register char *path;
4341488Smckusick struct iob *file;
4441488Smckusick {
4541488Smckusick register char *q;
4641488Smckusick char c;
4741488Smckusick int n;
4841488Smckusick
4941488Smckusick if (path==NULL || *path=='\0') {
5041488Smckusick printf("null path\n");
5141488Smckusick return (0);
5241488Smckusick }
5341488Smckusick
5441488Smckusick if (openi((ino_t) ROOTINO, file) < 0) {
5541488Smckusick printf("can't read root inode\n");
5641488Smckusick return (0);
5741488Smckusick }
5841488Smckusick while (*path) {
5941488Smckusick while (*path == '/')
6041488Smckusick path++;
6141488Smckusick q = path;
6241488Smckusick while(*q != '/' && *q != '\0')
6341488Smckusick q++;
6441488Smckusick c = *q;
6541488Smckusick *q = '\0';
6641488Smckusick if (q == path) path = "." ; /* "/" means "/." */
6741488Smckusick
6841488Smckusick if ((n = dlook(path, file)) != 0) {
6941488Smckusick if (c == '\0')
7041488Smckusick break;
7141488Smckusick if (openi(n, file) < 0)
7241488Smckusick return (0);
7341488Smckusick *q = c;
7441488Smckusick path = q;
7541488Smckusick continue;
7641488Smckusick } else {
7741488Smckusick printf("%s: not found\n", path);
7841488Smckusick return (0);
7941488Smckusick }
8041488Smckusick }
8141488Smckusick return (n);
8241488Smckusick }
8341488Smckusick
8441488Smckusick static daddr_t
sbmap(io,bn)8541488Smckusick sbmap(io, bn)
8641488Smckusick register struct iob *io;
8741488Smckusick daddr_t bn;
8841488Smckusick {
89*44826Skarels register struct dinode *ip;
9041488Smckusick int i, j, sh;
9141488Smckusick daddr_t nb, *bap;
9241488Smckusick
9341488Smckusick ip = &io->i_ino;
9441488Smckusick if (bn < 0) {
9541488Smckusick printf("bn negative\n");
9641488Smckusick return ((daddr_t)0);
9741488Smckusick }
9841488Smckusick
9941488Smckusick /*
10041488Smckusick * blocks 0..NDADDR are direct blocks
10141488Smckusick */
10241488Smckusick if(bn < NDADDR) {
103*44826Skarels nb = ip->di_db[bn];
10441488Smckusick return (nb);
10541488Smckusick }
10641488Smckusick
10741488Smckusick /*
10841488Smckusick * addresses NIADDR have single and double indirect blocks.
10941488Smckusick * the first step is to determine how many levels of indirection.
11041488Smckusick */
11141488Smckusick sh = 1;
11241488Smckusick bn -= NDADDR;
11341488Smckusick for (j = NIADDR; j > 0; j--) {
11441488Smckusick sh *= NINDIR(&io->i_fs);
11541488Smckusick if (bn < sh)
11641488Smckusick break;
11741488Smckusick bn -= sh;
11841488Smckusick }
11941488Smckusick if (j == 0) {
12041488Smckusick printf("bn ovf %D\n", bn);
12141488Smckusick return ((daddr_t)0);
12241488Smckusick }
12341488Smckusick
12441488Smckusick /*
12541488Smckusick * fetch the first indirect block address from the inode
12641488Smckusick */
127*44826Skarels nb = ip->di_ib[NIADDR - j];
12841488Smckusick if (nb == 0) {
12941488Smckusick printf("bn void %D\n",bn);
13041488Smckusick return ((daddr_t)0);
13141488Smckusick }
13241488Smckusick
13341488Smckusick /*
13441488Smckusick * fetch through the indirect blocks
13541488Smckusick */
13641488Smckusick for (; j <= NIADDR; j++) {
13741488Smckusick if (blknos[j] != nb) {
13841488Smckusick io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
13941488Smckusick io->i_ma = b[j];
14041488Smckusick io->i_cc = io->i_fs.fs_bsize;
14141488Smckusick if (devread(io) != io->i_fs.fs_bsize) {
14241488Smckusick if (io->i_error)
14341488Smckusick errno = io->i_error;
14441488Smckusick printf("bn %D: read error\n", io->i_bn);
14541488Smckusick return ((daddr_t)0);
14641488Smckusick }
14741488Smckusick blknos[j] = nb;
14841488Smckusick }
14941488Smckusick bap = (daddr_t *)b[j];
15041488Smckusick sh /= NINDIR(&io->i_fs);
15141488Smckusick i = (bn / sh) % NINDIR(&io->i_fs);
15241488Smckusick nb = bap[i];
15341488Smckusick if(nb == 0) {
15441488Smckusick printf("bn void %D\n",bn);
15541488Smckusick return ((daddr_t)0);
15641488Smckusick }
15741488Smckusick }
15841488Smckusick return (nb);
15941488Smckusick }
16041488Smckusick
16141488Smckusick static ino_t
dlook(s,io)16241488Smckusick dlook(s, io)
16341488Smckusick char *s;
16441488Smckusick register struct iob *io;
16541488Smckusick {
16641488Smckusick register struct direct *dp;
167*44826Skarels struct direct *readdir();
168*44826Skarels register struct dinode *ip;
16941488Smckusick struct dirstuff dirp;
17041488Smckusick int len;
17141488Smckusick
17241488Smckusick if (s == NULL || *s == '\0')
17341488Smckusick return (0);
17441488Smckusick ip = &io->i_ino;
175*44826Skarels if ((ip->di_mode&IFMT) != IFDIR) {
17641488Smckusick printf("not a directory\n");
17741488Smckusick printf("%s: not a directory\n", s);
17841488Smckusick return (0);
17941488Smckusick }
180*44826Skarels if (ip->di_size == 0) {
18141488Smckusick printf("%s: zero length directory\n", s);
18241488Smckusick return (0);
18341488Smckusick }
18441488Smckusick len = strlen(s);
18541488Smckusick dirp.loc = 0;
18641488Smckusick dirp.io = io;
18741488Smckusick for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
18841488Smckusick if(dp->d_ino == 0)
18941488Smckusick continue;
19041488Smckusick if (dp->d_namlen == len && !strcmp(s, dp->d_name))
19141488Smckusick return (dp->d_ino);
19241488Smckusick }
19341488Smckusick return (0);
19441488Smckusick }
19541488Smckusick
19641488Smckusick /*
19741488Smckusick * get next entry in a directory.
19841488Smckusick */
19941488Smckusick struct direct *
readdir(dirp)20041488Smckusick readdir(dirp)
20141488Smckusick register struct dirstuff *dirp;
20241488Smckusick {
20341488Smckusick register struct direct *dp;
20441488Smckusick register struct iob *io;
20541488Smckusick daddr_t lbn, d;
20641488Smckusick int off;
20741488Smckusick
20841488Smckusick io = dirp->io;
20941488Smckusick for(;;) {
210*44826Skarels if (dirp->loc >= io->i_ino.di_size)
21141488Smckusick return (NULL);
21241488Smckusick off = blkoff(&io->i_fs, dirp->loc);
21341488Smckusick if (off == 0) {
21441488Smckusick lbn = lblkno(&io->i_fs, dirp->loc);
21541488Smckusick d = sbmap(io, lbn);
21641488Smckusick if(d == 0)
21741488Smckusick return NULL;
21841488Smckusick io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
21941488Smckusick io->i_ma = io->i_buf;
220*44826Skarels io->i_cc = dblksize(&io->i_fs, &io->i_ino, lbn);
22141488Smckusick if (devread(io) < 0) {
22241488Smckusick errno = io->i_error;
22341488Smckusick printf("bn %D: directory read error\n",
22441488Smckusick io->i_bn);
22541488Smckusick return (NULL);
22641488Smckusick }
22741488Smckusick }
22841488Smckusick dp = (struct direct *)(io->i_buf + off);
22941488Smckusick dirp->loc += dp->d_reclen;
23041488Smckusick if (dp->d_ino == 0)
23141488Smckusick continue;
23241488Smckusick return (dp);
23341488Smckusick }
23441488Smckusick }
23541488Smckusick
lseek(fdesc,addr,ptr)23641488Smckusick lseek(fdesc, addr, ptr)
23741488Smckusick int fdesc, ptr;
23841488Smckusick off_t addr;
23941488Smckusick {
24041488Smckusick register struct iob *io;
24141488Smckusick
24241488Smckusick #ifndef SMALL
24341488Smckusick if (ptr != 0) {
24441488Smckusick printf("Seek not from beginning of file\n");
24541488Smckusick errno = EOFFSET;
24641488Smckusick return (-1);
24741488Smckusick }
24841488Smckusick #endif SMALL
24941488Smckusick fdesc -= 3;
25041488Smckusick if (fdesc < 0 || fdesc >= NFILES ||
25141488Smckusick ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
25241488Smckusick errno = EBADF;
25341488Smckusick return (-1);
25441488Smckusick }
25541488Smckusick io->i_offset = addr;
25641488Smckusick io->i_bn = addr / DEV_BSIZE;
25741488Smckusick io->i_cc = 0;
25841488Smckusick return (0);
25941488Smckusick }
26041488Smckusick
getc(fdesc)26141488Smckusick getc(fdesc)
26241488Smckusick int fdesc;
26341488Smckusick {
26441488Smckusick register struct iob *io;
26541488Smckusick register struct fs *fs;
26641488Smckusick register char *p;
26741488Smckusick int c, lbn, off, size, diff;
26841488Smckusick
26941488Smckusick
27041488Smckusick if (fdesc >= 0 && fdesc <= 2)
27141488Smckusick return (getchar());
27241488Smckusick fdesc -= 3;
27341488Smckusick if (fdesc < 0 || fdesc >= NFILES ||
27441488Smckusick ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
27541488Smckusick errno = EBADF;
27641488Smckusick return (-1);
27741488Smckusick }
27841488Smckusick p = io->i_ma;
27941488Smckusick if (io->i_cc <= 0) {
28041488Smckusick if ((io->i_flgs & F_FILE) != 0) {
281*44826Skarels diff = io->i_ino.di_size - io->i_offset;
28241488Smckusick if (diff <= 0)
28341488Smckusick return (-1);
28441488Smckusick fs = &io->i_fs;
28541488Smckusick lbn = lblkno(fs, io->i_offset);
28641488Smckusick io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
28741488Smckusick off = blkoff(fs, io->i_offset);
288*44826Skarels size = dblksize(fs, &io->i_ino, lbn);
28941488Smckusick } else {
29041488Smckusick io->i_bn = io->i_offset / DEV_BSIZE;
29141488Smckusick off = 0;
29241488Smckusick size = DEV_BSIZE;
29341488Smckusick }
29441488Smckusick io->i_ma = io->i_buf;
29541488Smckusick io->i_cc = size;
29641488Smckusick if (devread(io) < 0) {
29741488Smckusick errno = io->i_error;
29841488Smckusick return (-1);
29941488Smckusick }
30041488Smckusick if ((io->i_flgs & F_FILE) != 0) {
301*44826Skarels if (io->i_offset - off + size >= io->i_ino.di_size)
30241488Smckusick io->i_cc = diff + off;
30341488Smckusick io->i_cc -= off;
30441488Smckusick }
30541488Smckusick p = &io->i_buf[off];
30641488Smckusick }
30741488Smckusick io->i_cc--;
30841488Smckusick io->i_offset++;
30941488Smckusick c = (unsigned)*p++;
31041488Smckusick io->i_ma = p;
31141488Smckusick return (c);
31241488Smckusick }
31341488Smckusick
31441488Smckusick int errno;
31541488Smckusick
read(fdesc,buf,count)31641488Smckusick read(fdesc, buf, count)
31741488Smckusick int fdesc, count;
31841488Smckusick char *buf;
31941488Smckusick {
32041488Smckusick register i, size;
32141488Smckusick register struct iob *file;
32241488Smckusick register struct fs *fs;
32341488Smckusick int lbn, off;
32441488Smckusick
32541488Smckusick errno = 0;
32641488Smckusick if (fdesc >= 0 & fdesc <= 2) {
32741488Smckusick i = count;
32841488Smckusick do {
32941488Smckusick *buf = getchar();
33041488Smckusick } while (--i && *buf++ != '\n');
33141488Smckusick return (count - i);
33241488Smckusick }
33341488Smckusick fdesc -= 3;
33441488Smckusick if (fdesc < 0 || fdesc >= NFILES ||
33541488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
33641488Smckusick errno = EBADF;
33741488Smckusick return (-1);
33841488Smckusick }
33941488Smckusick if ((file->i_flgs&F_READ) == 0) {
34041488Smckusick errno = EBADF;
34141488Smckusick return (-1);
34241488Smckusick }
34341488Smckusick #ifndef SMALL
34441488Smckusick if ((file->i_flgs & F_FILE) == 0) {
34541488Smckusick file->i_cc = count;
34641488Smckusick file->i_ma = buf;
34741488Smckusick file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
34841488Smckusick i = devread(file);
34941488Smckusick file->i_offset += count;
35041488Smckusick if (i < 0)
35141488Smckusick errno = file->i_error;
35241488Smckusick return (i);
35341488Smckusick }
35441488Smckusick #endif SMALL
355*44826Skarels if (file->i_offset+count > file->i_ino.di_size)
356*44826Skarels count = file->i_ino.di_size - file->i_offset;
35741488Smckusick if ((i = count) <= 0)
35841488Smckusick return (0);
35941488Smckusick /*
36041488Smckusick * While reading full blocks, do I/O into user buffer.
36141488Smckusick * Anything else uses getc().
36241488Smckusick */
36341488Smckusick fs = &file->i_fs;
36441488Smckusick while (i) {
36541488Smckusick off = blkoff(fs, file->i_offset);
36641488Smckusick lbn = lblkno(fs, file->i_offset);
367*44826Skarels size = dblksize(fs, &file->i_ino, lbn);
36841488Smckusick if (off == 0 && size <= i) {
36941488Smckusick file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
37041488Smckusick file->i_boff;
37141488Smckusick file->i_cc = size;
37241488Smckusick file->i_ma = buf;
37341488Smckusick if (devread(file) < 0) {
37441488Smckusick errno = file->i_error;
37541488Smckusick return (-1);
37641488Smckusick }
37741488Smckusick file->i_offset += size;
37841488Smckusick file->i_cc = 0;
37941488Smckusick buf += size;
38041488Smckusick i -= size;
38141488Smckusick } else {
38241488Smckusick size -= off;
38341488Smckusick if (size > i)
38441488Smckusick size = i;
38541488Smckusick i -= size;
38641488Smckusick do {
38741488Smckusick *buf++ = getc(fdesc+3);
38841488Smckusick } while (--size);
38941488Smckusick }
39041488Smckusick }
39141488Smckusick return (count);
39241488Smckusick }
39341488Smckusick
39441488Smckusick #ifndef SMALL
write(fdesc,buf,count)39541488Smckusick write(fdesc, buf, count)
39641488Smckusick int fdesc, count;
39741488Smckusick char *buf;
39841488Smckusick {
39941488Smckusick register i;
40041488Smckusick register struct iob *file;
40141488Smckusick
40241488Smckusick errno = 0;
40341488Smckusick if (fdesc >= 0 && fdesc <= 2) {
40441488Smckusick i = count;
40541488Smckusick while (i--)
40641488Smckusick putchar(0, *buf++);
40741488Smckusick return (count);
40841488Smckusick }
40941488Smckusick fdesc -= 3;
41041488Smckusick if (fdesc < 0 || fdesc >= NFILES ||
41141488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
41241488Smckusick errno = EBADF;
41341488Smckusick return (-1);
41441488Smckusick }
41541488Smckusick if ((file->i_flgs&F_WRITE) == 0) {
41641488Smckusick errno = EBADF;
41741488Smckusick return (-1);
41841488Smckusick }
41941488Smckusick file->i_cc = count;
42041488Smckusick file->i_ma = buf;
42141488Smckusick file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
42241488Smckusick i = devwrite(file);
42341488Smckusick file->i_offset += count;
42441488Smckusick if (i < 0)
42541488Smckusick errno = file->i_error;
42641488Smckusick return (i);
42741488Smckusick }
42841488Smckusick #endif SMALL
42941488Smckusick
43041488Smckusick int openfirst = 1;
43141488Smckusick #ifdef notyet
43241488Smckusick int opendev; /* last device opened; for boot to set bootdev */
43341488Smckusick extern int bootdev;
43441488Smckusick #endif notyet
43541488Smckusick
open(str,how)43641488Smckusick open(str, how)
43741488Smckusick char *str;
43841488Smckusick int how;
43941488Smckusick {
44041488Smckusick register char *cp;
44141488Smckusick int i;
44241488Smckusick register struct iob *file;
44341488Smckusick register struct devsw *dp;
44441488Smckusick int fdesc;
44541488Smckusick long atol();
44641488Smckusick
44741488Smckusick if (openfirst) {
44841488Smckusick for (i = 0; i < NFILES; i++)
44941488Smckusick iob[i].i_flgs = 0;
45041488Smckusick openfirst = 0;
45141488Smckusick }
45241488Smckusick
45341488Smckusick for (fdesc = 0; fdesc < NFILES; fdesc++)
45441488Smckusick if (iob[fdesc].i_flgs == 0)
45541488Smckusick goto gotfile;
45641488Smckusick _stop("No more file slots");
45741488Smckusick gotfile:
45841488Smckusick (file = &iob[fdesc])->i_flgs |= F_ALLOC;
45941488Smckusick
46041488Smckusick #ifdef notyet
46141488Smckusick for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++)
46241488Smckusick ;
46341488Smckusick if (*cp != ':') {
46441488Smckusick /* default bootstrap unit and device */
465*44826Skarels file->i_dev = bootdev;
46641488Smckusick cp = str;
46741488Smckusick } else {
46841488Smckusick # define isdigit(n) ((n>='0') && (n<='9'))
46941488Smckusick /*
47041488Smckusick * syntax for possible device name:
47141488Smckusick * <alpha-string><digit-string><letter>:
47241488Smckusick */
47341488Smckusick for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
47441488Smckusick ;
47541488Smckusick for (dp = devsw; dp->dv_name; dp++) {
47641488Smckusick if (!strncmp(str, dp->dv_name,cp-str))
47741488Smckusick goto gotdev;
47841488Smckusick }
47941488Smckusick printf("unknown device\n");
48041488Smckusick file->i_flgs = 0;
48141488Smckusick errno = EDEV;
48241488Smckusick return (-1);
48341488Smckusick gotdev:
48441488Smckusick i = 0;
48541488Smckusick while (*cp >= '0' && *cp <= '9')
48641488Smckusick i = i * 10 + *cp++ - '0';
48741488Smckusick if (i < 0 || i > 255) {
48841488Smckusick printf("minor device number out of range (0-255)\n");
48941488Smckusick file->i_flgs = 0;
49041488Smckusick errno = EUNIT;
49141488Smckusick return (-1);
49241488Smckusick }
49341488Smckusick if (*cp >= 'a' && *cp <= 'h') {
49441488Smckusick if (i > 31) {
49541488Smckusick printf("unit number out of range (0-31)\n");
49641488Smckusick file->i_flgs = 0;
49741488Smckusick errno = EUNIT;
49841488Smckusick return (-1);
49941488Smckusick }
50041488Smckusick i = make_minor(i, *cp++ - 'a');
50141488Smckusick }
50241488Smckusick
50341488Smckusick if (*cp++ != ':') {
50441488Smckusick printf("incorrect device specification\n");
50541488Smckusick file->i_flgs = 0;
50641488Smckusick errno = EOFFSET;
50741488Smckusick return (-1);
50841488Smckusick }
509*44826Skarels opendev = file->i_dev = makedev(dp-devsw, i);
51041488Smckusick }
51141488Smckusick file->i_boff = 0;
51241488Smckusick devopen(file);
51341488Smckusick if (cp != str && *cp == '\0') {
51441488Smckusick file->i_flgs |= how+1;
51541488Smckusick file->i_cc = 0;
51641488Smckusick file->i_offset = 0;
51741488Smckusick return (fdesc+3);
51841488Smckusick }
51941488Smckusick #else notyet
52041488Smckusick for (cp = str; *cp && *cp != '('; cp++)
52141488Smckusick ;
52241488Smckusick if (*cp != '(') {
52341488Smckusick printf("Bad device\n");
52441488Smckusick file->i_flgs = 0;
52541488Smckusick errno = EDEV;
52641488Smckusick return (-1);
52741488Smckusick }
52841488Smckusick *cp = '\0';
52941488Smckusick for (dp = devsw; dp->dv_name; dp++)
53041488Smckusick if (!strcmp(str, dp->dv_name))
53141488Smckusick break;
53241488Smckusick *cp++ = '(';
53341488Smckusick if (dp->dv_name == NULL) {
53441488Smckusick printf("Unknown device\n");
53541488Smckusick file->i_flgs = 0;
53641488Smckusick errno = ENXIO;
53741488Smckusick return (-1);
53841488Smckusick }
539*44826Skarels file->i_dev = dp-devsw;
54041488Smckusick file->i_unit = *cp++ - '0';
54141488Smckusick if (*cp >= '0' && *cp <= '9')
54241488Smckusick file->i_unit = file->i_unit * 10 + *cp++ - '0';
54341488Smckusick if (file->i_unit < 0 || file->i_unit > 63) {
54441488Smckusick printf("Bad unit specifier\n");
54541488Smckusick file->i_flgs = 0;
54641488Smckusick errno = EUNIT;
54741488Smckusick return (-1);
54841488Smckusick }
54941488Smckusick if (*cp++ != ',') {
55041488Smckusick badoff:
55141488Smckusick printf("Missing offset specification\n");
55241488Smckusick file->i_flgs = 0;
55341488Smckusick errno = EOFFSET;
55441488Smckusick return (-1);
55541488Smckusick }
55641488Smckusick file->i_boff = atol(cp);
55741488Smckusick for (;;) {
55841488Smckusick if (*cp == ')')
55941488Smckusick break;
56041488Smckusick if (*cp++)
56141488Smckusick continue;
56241488Smckusick goto badoff;
56341488Smckusick }
56441488Smckusick devopen(file);
56541488Smckusick if (*++cp == '\0') {
56641488Smckusick file->i_flgs |= how+1;
56741488Smckusick file->i_cc = 0;
56841488Smckusick file->i_offset = 0;
56941488Smckusick return (fdesc+3);
57041488Smckusick }
57141488Smckusick #endif notyet
57241488Smckusick file->i_ma = (char *)(&file->i_fs);
57341488Smckusick file->i_cc = SBSIZE;
57441488Smckusick file->i_bn = SBLOCK + file->i_boff;
57541488Smckusick file->i_offset = 0;
57641488Smckusick if (devread(file) < 0) {
57741488Smckusick errno = file->i_error;
57841488Smckusick printf("super block read error\n");
57941488Smckusick return (-1);
58041488Smckusick }
58141488Smckusick if ((i = find(cp, file)) == 0) {
58241488Smckusick file->i_flgs = 0;
58341488Smckusick errno = ESRCH;
58441488Smckusick return (-1);
58541488Smckusick }
58641488Smckusick #ifndef SMALL
58741488Smckusick if (how != 0) {
58841488Smckusick printf("Can't write files yet.. Sorry\n");
58941488Smckusick file->i_flgs = 0;
59041488Smckusick errno = EIO;
59141488Smckusick return (-1);
59241488Smckusick }
59341488Smckusick #endif SMALL
59441488Smckusick if (openi(i, file) < 0) {
59541488Smckusick errno = file->i_error;
59641488Smckusick return (-1);
59741488Smckusick }
59841488Smckusick file->i_offset = 0;
59941488Smckusick file->i_cc = 0;
60041488Smckusick file->i_flgs |= F_FILE | (how+1);
60141488Smckusick return (fdesc+3);
60241488Smckusick }
60341488Smckusick
close(fdesc)60441488Smckusick close(fdesc)
60541488Smckusick int fdesc;
60641488Smckusick {
60741488Smckusick struct iob *file;
60841488Smckusick
60941488Smckusick fdesc -= 3;
61041488Smckusick if (fdesc < 0 || fdesc >= NFILES ||
61141488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
61241488Smckusick errno = EBADF;
61341488Smckusick return (-1);
61441488Smckusick }
61541488Smckusick if ((file->i_flgs&F_FILE) == 0)
61641488Smckusick devclose(file);
61741488Smckusick file->i_flgs = 0;
61841488Smckusick return (0);
61941488Smckusick }
62041488Smckusick
exit()62141488Smckusick exit()
62241488Smckusick {
62341488Smckusick _stop("Exit called");
62441488Smckusick }
62541488Smckusick
_stop(s)62641488Smckusick _stop(s)
62741488Smckusick char *s;
62841488Smckusick {
62941488Smckusick static int stopped = 0;
63041488Smckusick int i;
63141488Smckusick
63241488Smckusick if (!stopped) {
63341488Smckusick stopped++;
63441488Smckusick for (i = 0; i < NFILES; i++)
63541488Smckusick if (iob[i].i_flgs != 0)
63641488Smckusick close(i);
63741488Smckusick }
63841488Smckusick printf("%s\n", s);
63941488Smckusick _rtt();
64041488Smckusick }
64141488Smckusick
64241488Smckusick #ifndef SMALL
ioctl(fdesc,cmd,arg)64341488Smckusick ioctl(fdesc, cmd, arg)
64441488Smckusick int fdesc, cmd;
64541488Smckusick char *arg;
64641488Smckusick {
64741488Smckusick register struct iob *file;
64841488Smckusick int error = 0;
64941488Smckusick
65041488Smckusick fdesc -= 3;
65141488Smckusick if (fdesc < 0 || fdesc >= NFILES ||
65241488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
65341488Smckusick errno = EBADF;
65441488Smckusick return (-1);
65541488Smckusick }
65641488Smckusick switch (cmd) {
65741488Smckusick
65841488Smckusick case SAIOHDR:
65941488Smckusick file->i_flgs |= F_HDR;
66041488Smckusick break;
66141488Smckusick
66241488Smckusick case SAIOCHECK:
66341488Smckusick file->i_flgs |= F_CHECK;
66441488Smckusick break;
66541488Smckusick
66641488Smckusick case SAIOHCHECK:
66741488Smckusick file->i_flgs |= F_HCHECK;
66841488Smckusick break;
66941488Smckusick
67041488Smckusick case SAIONOBAD:
67141488Smckusick file->i_flgs |= F_NBSF;
67241488Smckusick break;
67341488Smckusick
67441488Smckusick case SAIODOBAD:
67541488Smckusick file->i_flgs &= ~F_NBSF;
67641488Smckusick break;
67741488Smckusick
67841488Smckusick default:
67941488Smckusick error = devioctl(file, cmd, arg);
68041488Smckusick break;
68141488Smckusick }
68241488Smckusick if (error < 0)
68341488Smckusick errno = file->i_error;
68441488Smckusick return (error);
68541488Smckusick }
68641488Smckusick
68741488Smckusick extern char end;
68841488Smckusick static caddr_t theend = 0;
68941488Smckusick
69041488Smckusick caddr_t
brk(addr)69141488Smckusick brk(addr)
69241488Smckusick char *addr;
69341488Smckusick {
69441488Smckusick char stkloc;
69541488Smckusick
69641488Smckusick if (theend == (caddr_t)0)
69741488Smckusick theend = &end;
69841488Smckusick if (addr > &stkloc || addr < &end)
69941488Smckusick return((caddr_t)-1);
70041488Smckusick if (addr > theend)
70141488Smckusick bzero(theend, addr-theend);
70241488Smckusick theend = addr;
70341488Smckusick return(0);
70441488Smckusick }
70541488Smckusick
70641488Smckusick caddr_t
sbrk(incr)70741488Smckusick sbrk(incr)
70841488Smckusick int incr;
70941488Smckusick {
71041488Smckusick caddr_t obrk, brk();
71141488Smckusick
71241488Smckusick if (theend == (caddr_t)0)
71341488Smckusick theend = &end;
71441488Smckusick obrk = theend;
71541488Smckusick if (brk(theend+incr) == (caddr_t)-1)
71641488Smckusick return((caddr_t)-1);
71741488Smckusick return(obrk);
71841488Smckusick }
71941488Smckusick
getpagesize()72041488Smckusick getpagesize()
72141488Smckusick {
72241488Smckusick return(NBPG);
72341488Smckusick }
72441488Smckusick
getdtablesize()72541488Smckusick getdtablesize()
72641488Smckusick {
72741488Smckusick return(NFILES);
72841488Smckusick }
72941488Smckusick
73041488Smckusick fstat(fdesc, sb)
73141488Smckusick struct stat *sb;
73241488Smckusick {
73341488Smckusick register struct iob *io;
73441488Smckusick
73541488Smckusick fdesc -= 3;
73641488Smckusick if (fdesc < 0 || fdesc >= NFILES ||
73741488Smckusick ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
73841488Smckusick errno = EBADF;
73941488Smckusick return (-1);
74041488Smckusick }
74141488Smckusick /* only important stuff */
742*44826Skarels sb->st_mode = io->i_ino.di_mode;
743*44826Skarels sb->st_uid = io->i_ino.di_uid;
744*44826Skarels sb->st_gid = io->i_ino.di_gid;
745*44826Skarels sb->st_size = io->i_ino.di_size;
74641488Smckusick return (0);
74741488Smckusick }
74841488Smckusick
stat(str,sb)74941488Smckusick stat(str, sb)
75041488Smckusick {
75141488Smckusick /* the easy way */
75241488Smckusick int f, rv = 0;
75341488Smckusick
75441488Smckusick f = open(str, 0);
75541488Smckusick if (f < 0 || fstat(f, sb) < 0)
75641488Smckusick rv = -1;
75741488Smckusick (void) close(f);
75841488Smckusick return(rv);
75941488Smckusick }
76041488Smckusick
76141488Smckusick #endif SMALL
762