1*49117Sbostic /*- 2*49117Sbostic * Copyright (c) 1982, 1988 The Regents of the University of California. 3*49117Sbostic * All rights reserved. 423243Smckusick * 5*49117Sbostic * %sccs.include.proprietary.c% 6*49117Sbostic * 7*49117Sbostic * @(#)sys.c 7.15 (Berkeley) 05/04/91 823243Smckusick */ 9327Sbill 10*49117Sbostic #include <sys/param.h> 11*49117Sbostic #include <sys/reboot.h> 12*49117Sbostic #include <ufs/dir.h> 13*49117Sbostic #include <stand/saio.h> /* used from machine/stand dir */ 14327Sbill 15327Sbill ino_t dlook(); 16327Sbill 176068Smckusic struct dirstuff { 186068Smckusic int loc; 196068Smckusic struct iob *io; 206068Smckusic }; 216068Smckusic 22*49117Sbostic struct iob iob[SOPEN_MAX]; 2334463Sbostic 24327Sbill static 2510022Ssam openi(n, io) 266068Smckusic register struct iob *io; 27327Sbill { 28327Sbill register struct dinode *dp; 2911083Ssam int cc; 30327Sbill 31327Sbill io->i_offset = 0; 326068Smckusic io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 336068Smckusic io->i_cc = io->i_fs.fs_bsize; 34327Sbill io->i_ma = io->i_buf; 3511083Ssam cc = devread(io); 36327Sbill dp = (struct dinode *)io->i_buf; 3740500Smckusick io->i_ino = dp[itoo(&io->i_fs, n)]; 3811083Ssam return (cc); 39327Sbill } 40327Sbill 41327Sbill static 42327Sbill find(path, file) 436068Smckusic register char *path; 446068Smckusic struct iob *file; 45327Sbill { 46327Sbill register char *q; 4734463Sbostic char *dir, c; 48327Sbill int n; 49327Sbill 5034463Sbostic if (path == NULL || *path == '\0') { 51327Sbill printf("null path\n"); 5210022Ssam return (0); 53327Sbill } 54327Sbill 5511083Ssam if (openi((ino_t) ROOTINO, file) < 0) { 5611083Ssam printf("can't read root inode\n"); 5711083Ssam return (0); 5811083Ssam } 5930768Skarels dir = path; 60327Sbill while (*path) { 61327Sbill while (*path == '/') 62327Sbill path++; 63327Sbill q = path; 64327Sbill while(*q != '/' && *q != '\0') 65327Sbill q++; 66327Sbill c = *q; 67327Sbill *q = '\0'; 6825166Skarels if (q == path) path = "." ; /* "/" means "/." */ 69327Sbill 7030768Skarels if ((n = dlook(path, file, dir)) != 0) { 7111083Ssam if (c == '\0') 72327Sbill break; 7311083Ssam if (openi(n, file) < 0) 7411083Ssam return (0); 75327Sbill *q = c; 76327Sbill path = q; 77327Sbill continue; 78327Sbill } else { 7925166Skarels printf("%s: not found\n", path); 8010022Ssam return (0); 81327Sbill } 82327Sbill } 8310022Ssam return (n); 84327Sbill } 85327Sbill 8634463Sbostic #define NBUFS 4 8734463Sbostic static char b[NBUFS][MAXBSIZE]; 8834463Sbostic static daddr_t blknos[NBUFS]; 8934463Sbostic 90327Sbill static daddr_t 91327Sbill sbmap(io, bn) 926068Smckusic register struct iob *io; 936068Smckusic daddr_t bn; 94327Sbill { 9540500Smckusick register struct dinode *ip; 966068Smckusic int i, j, sh; 97327Sbill daddr_t nb, *bap; 98327Sbill 99327Sbill ip = &io->i_ino; 1006068Smckusic if (bn < 0) { 101327Sbill printf("bn negative\n"); 10210022Ssam return ((daddr_t)0); 103327Sbill } 104327Sbill 105*49117Sbostic /* The first NDADDR blocks are direct blocks. */ 1066068Smckusic if(bn < NDADDR) { 10740500Smckusick nb = ip->di_db[bn]; 10810022Ssam return (nb); 109327Sbill } 110327Sbill 111*49117Sbostic /* Determine the number of levels of indirection. */ 1126068Smckusic sh = 1; 1136068Smckusic bn -= NDADDR; 1146068Smckusic for (j = NIADDR; j > 0; j--) { 1156068Smckusic sh *= NINDIR(&io->i_fs); 1166068Smckusic if (bn < sh) 117327Sbill break; 1186068Smckusic bn -= sh; 119327Sbill } 1206068Smckusic if (j == 0) { 1216068Smckusic printf("bn ovf %D\n", bn); 1226068Smckusic return ((daddr_t)0); 123327Sbill } 124327Sbill 125*49117Sbostic /* Get the first indirect block address. */ 12640500Smckusick nb = ip->di_ib[NIADDR - j]; 1276068Smckusic if (nb == 0) { 128327Sbill printf("bn void %D\n",bn); 12910022Ssam return ((daddr_t)0); 130327Sbill } 131327Sbill 132*49117Sbostic /* Get the indirect blocks. */ 1336068Smckusic for (; j <= NIADDR; j++) { 134327Sbill if (blknos[j] != nb) { 1356068Smckusic io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 136327Sbill io->i_ma = b[j]; 1376068Smckusic io->i_cc = io->i_fs.fs_bsize; 13811083Ssam if (devread(io) != io->i_fs.fs_bsize) { 13911083Ssam if (io->i_error) 14011083Ssam errno = io->i_error; 14111083Ssam printf("bn %D: read error\n", io->i_bn); 14211083Ssam return ((daddr_t)0); 14311083Ssam } 144327Sbill blknos[j] = nb; 145327Sbill } 146327Sbill bap = (daddr_t *)b[j]; 1476068Smckusic sh /= NINDIR(&io->i_fs); 1486068Smckusic i = (bn / sh) % NINDIR(&io->i_fs); 149327Sbill nb = bap[i]; 150327Sbill if(nb == 0) { 151327Sbill printf("bn void %D\n",bn); 15210022Ssam return ((daddr_t)0); 153327Sbill } 154327Sbill } 15510022Ssam return (nb); 156327Sbill } 157327Sbill 1586068Smckusic struct direct * 1596068Smckusic readdir(dirp) 1606068Smckusic register struct dirstuff *dirp; 161327Sbill { 1626068Smckusic register struct direct *dp; 1636068Smckusic register struct iob *io; 1646068Smckusic daddr_t lbn, d; 1656068Smckusic int off; 166327Sbill 1676068Smckusic io = dirp->io; 1686068Smckusic for(;;) { 16940500Smckusick if (dirp->loc >= io->i_ino.di_size) 17011083Ssam return (NULL); 1716068Smckusic off = blkoff(&io->i_fs, dirp->loc); 1726068Smckusic if (off == 0) { 1736068Smckusic lbn = lblkno(&io->i_fs, dirp->loc); 1746068Smckusic d = sbmap(io, lbn); 1756068Smckusic if(d == 0) 17634463Sbostic return (NULL); 1776068Smckusic io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 1786068Smckusic io->i_ma = io->i_buf; 17940500Smckusick io->i_cc = dblksize(&io->i_fs, &io->i_ino, lbn); 18011083Ssam if (devread(io) < 0) { 18111083Ssam errno = io->i_error; 18225166Skarels printf("bn %D: directory read error\n", 18325166Skarels io->i_bn); 18411083Ssam return (NULL); 18511083Ssam } 1866068Smckusic } 1876068Smckusic dp = (struct direct *)(io->i_buf + off); 1886068Smckusic dirp->loc += dp->d_reclen; 1896068Smckusic if (dp->d_ino == 0) 1906068Smckusic continue; 1916068Smckusic return (dp); 192327Sbill } 193327Sbill } 194327Sbill 19540500Smckusick static ino_t 19640500Smckusick dlook(s, io, dir) 19740500Smckusick char *s; 19840500Smckusick register struct iob *io; 19940500Smckusick char *dir; 20040500Smckusick { 20140500Smckusick register struct direct *dp; 20240500Smckusick register struct dinode *ip; 20340500Smckusick struct dirstuff dirp; 20440500Smckusick int len; 20540500Smckusick 20640500Smckusick if (s == NULL || *s == '\0') 20740500Smckusick return (0); 20840500Smckusick ip = &io->i_ino; 20940500Smckusick if ((ip->di_mode&IFMT) != IFDIR) { 21040500Smckusick printf("%s: not a directory\n", dir); 21140500Smckusick return (0); 21240500Smckusick } 21340500Smckusick if (ip->di_size == 0) { 21440500Smckusick printf("%s: zero length directory\n", dir); 21540500Smckusick return (0); 21640500Smckusick } 21740500Smckusick len = strlen(s); 21840500Smckusick dirp.loc = 0; 21940500Smckusick dirp.io = io; 22040500Smckusick for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 22140500Smckusick if(dp->d_ino == 0) 22240500Smckusick continue; 22340500Smckusick if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 22440500Smckusick return (dp->d_ino); 22540500Smckusick } 22640500Smckusick return (0); 22740500Smckusick } 22840500Smckusick 229327Sbill lseek(fdesc, addr, ptr) 23010022Ssam int fdesc, ptr; 23110022Ssam off_t addr; 232327Sbill { 233327Sbill register struct iob *io; 234327Sbill 23534463Sbostic #ifndef SMALL 23634463Sbostic if (ptr != L_SET) { 237327Sbill printf("Seek not from beginning of file\n"); 23810022Ssam errno = EOFFSET; 23910022Ssam return (-1); 240327Sbill } 24134463Sbostic #endif 242327Sbill fdesc -= 3; 24348826Swilliam #ifndef SMALL 244*49117Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 24510022Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 24610022Ssam errno = EBADF; 24710022Ssam return (-1); 24810022Ssam } 24948826Swilliam #endif 250327Sbill io->i_offset = addr; 2516068Smckusic io->i_bn = addr / DEV_BSIZE; 252327Sbill io->i_cc = 0; 25310022Ssam return (0); 254327Sbill } 255327Sbill 256327Sbill getc(fdesc) 25710022Ssam int fdesc; 258327Sbill { 259327Sbill register struct iob *io; 2606068Smckusic register struct fs *fs; 261327Sbill register char *p; 2626068Smckusic int c, lbn, off, size, diff; 263327Sbill 264327Sbill 26548826Swilliam #ifndef SMALL 266327Sbill if (fdesc >= 0 && fdesc <= 2) 26710022Ssam return (getchar()); 26848826Swilliam #endif 269327Sbill fdesc -= 3; 270*49117Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 27110022Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 27210022Ssam errno = EBADF; 27310022Ssam return (-1); 27410022Ssam } 275327Sbill p = io->i_ma; 276327Sbill if (io->i_cc <= 0) { 2776068Smckusic if ((io->i_flgs & F_FILE) != 0) { 27840500Smckusick diff = io->i_ino.di_size - io->i_offset; 2796068Smckusic if (diff <= 0) 2806068Smckusic return (-1); 2816068Smckusic fs = &io->i_fs; 2826068Smckusic lbn = lblkno(fs, io->i_offset); 2836068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 2846068Smckusic off = blkoff(fs, io->i_offset); 28540500Smckusick size = dblksize(fs, &io->i_ino, lbn); 2866068Smckusic } else { 28748826Swilliam io->i_bn = io->i_offset / DEV_BSIZE + io->i_boff; 2886068Smckusic off = 0; 2896068Smckusic size = DEV_BSIZE; 2906068Smckusic } 291327Sbill io->i_ma = io->i_buf; 2926068Smckusic io->i_cc = size; 29311083Ssam if (devread(io) < 0) { 29411083Ssam errno = io->i_error; 29511083Ssam return (-1); 29611083Ssam } 2976068Smckusic if ((io->i_flgs & F_FILE) != 0) { 29840500Smckusick if (io->i_offset - off + size >= io->i_ino.di_size) 2996068Smckusic io->i_cc = diff + off; 300327Sbill io->i_cc -= off; 3016068Smckusic } 302327Sbill p = &io->i_buf[off]; 303327Sbill } 304327Sbill io->i_cc--; 305327Sbill io->i_offset++; 306327Sbill c = (unsigned)*p++; 307327Sbill io->i_ma = p; 30810022Ssam return (c); 309327Sbill } 3106068Smckusic 31110022Ssam int errno; 312327Sbill 313327Sbill read(fdesc, buf, count) 31410022Ssam int fdesc, count; 31510022Ssam char *buf; 316327Sbill { 31725166Skarels register i, size; 318327Sbill register struct iob *file; 31925166Skarels register struct fs *fs; 32025166Skarels int lbn, off; 321327Sbill 32210022Ssam errno = 0; 32348826Swilliam #ifndef SMALL 32445352Sbostic if (fdesc >= 0 && fdesc <= 2) { 325327Sbill i = count; 326327Sbill do { 327327Sbill *buf = getchar(); 328327Sbill } while (--i && *buf++ != '\n'); 32910022Ssam return (count - i); 330327Sbill } 33148826Swilliam #endif 332327Sbill fdesc -= 3; 333*49117Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 33410022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 33510022Ssam errno = EBADF; 33610022Ssam return (-1); 33710022Ssam } 33810022Ssam if ((file->i_flgs&F_READ) == 0) { 33910022Ssam errno = EBADF; 34010022Ssam return (-1); 34110022Ssam } 34234463Sbostic #ifndef SMALL 3436068Smckusic if ((file->i_flgs & F_FILE) == 0) { 344327Sbill file->i_cc = count; 345327Sbill file->i_ma = buf; 3467446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 347327Sbill i = devread(file); 34810022Ssam if (i < 0) 34910022Ssam errno = file->i_error; 35030547Skarels else 35130547Skarels file->i_offset += i; 35210022Ssam return (i); 353327Sbill } 35434463Sbostic #endif 35540500Smckusick if (file->i_offset+count > file->i_ino.di_size) 35640500Smckusick count = file->i_ino.di_size - file->i_offset; 35725166Skarels if ((i = count) <= 0) 35825166Skarels return (0); 35925166Skarels /* 36025166Skarels * While reading full blocks, do I/O into user buffer. 36125166Skarels * Anything else uses getc(). 36225166Skarels */ 36325166Skarels fs = &file->i_fs; 36425166Skarels while (i) { 36525166Skarels off = blkoff(fs, file->i_offset); 36625166Skarels lbn = lblkno(fs, file->i_offset); 36740500Smckusick size = dblksize(fs, &file->i_ino, lbn); 36848826Swilliam #ifndef SMALL 36925166Skarels if (off == 0 && size <= i) { 37025166Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 37125166Skarels file->i_boff; 37225166Skarels file->i_cc = size; 37325166Skarels file->i_ma = buf; 37425166Skarels if (devread(file) < 0) { 37525166Skarels errno = file->i_error; 37625166Skarels return (-1); 37725166Skarels } 37825166Skarels file->i_offset += size; 37925166Skarels file->i_cc = 0; 38025166Skarels buf += size; 38125166Skarels i -= size; 38225166Skarels } else { 38348826Swilliam #endif 38425166Skarels size -= off; 38525166Skarels if (size > i) 38625166Skarels size = i; 38725166Skarels i -= size; 38825166Skarels do { 38925166Skarels *buf++ = getc(fdesc+3); 39025166Skarels } while (--size); 39148826Swilliam #ifndef SMALL 39225166Skarels } 39348826Swilliam #endif 39425166Skarels } 39525166Skarels return (count); 396327Sbill } 397327Sbill 39834463Sbostic #ifndef SMALL 399327Sbill write(fdesc, buf, count) 40010022Ssam int fdesc, count; 40110022Ssam char *buf; 402327Sbill { 403327Sbill register i; 404327Sbill register struct iob *file; 405327Sbill 40610022Ssam errno = 0; 407327Sbill if (fdesc >= 0 && fdesc <= 2) { 408327Sbill i = count; 409327Sbill while (i--) 410327Sbill putchar(*buf++); 41110022Ssam return (count); 412327Sbill } 413327Sbill fdesc -= 3; 414*49117Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 41510022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 41610022Ssam errno = EBADF; 41710022Ssam return (-1); 41810022Ssam } 41910022Ssam if ((file->i_flgs&F_WRITE) == 0) { 42010022Ssam errno = EBADF; 42110022Ssam return (-1); 42210022Ssam } 423327Sbill file->i_cc = count; 424327Sbill file->i_ma = buf; 4257446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 426327Sbill i = devwrite(file); 4277446Sroot file->i_offset += count; 42810022Ssam if (i < 0) 42910022Ssam errno = file->i_error; 43010022Ssam return (i); 431327Sbill } 43234463Sbostic #endif 433327Sbill 4343349Swnj int openfirst = 1; 43534463Sbostic u_int opendev; /* last device opened */ 43634463Sbostic extern u_int bootdev; 4373349Swnj 438327Sbill open(str, how) 4396068Smckusic char *str; 44010022Ssam int how; 441327Sbill { 44234463Sbostic register char *t; 44334463Sbostic register int cnt; 444327Sbill register struct iob *file; 44534463Sbostic int fdesc, args[8], *argp; 446327Sbill 4473349Swnj if (openfirst) { 448*49117Sbostic for (cnt = 0; cnt < SOPEN_MAX; cnt++) 44934463Sbostic iob[cnt].i_flgs = 0; 4503349Swnj openfirst = 0; 451327Sbill } 452327Sbill 45334463Sbostic for (fdesc = 0;; fdesc++) { 454*49117Sbostic if (fdesc == SOPEN_MAX) 45534463Sbostic _stop("No more file slots"); 45634463Sbostic if (iob[fdesc].i_flgs == 0) { 45734463Sbostic file = &iob[fdesc]; 45834463Sbostic file->i_flgs |= F_ALLOC; 45934463Sbostic file->i_adapt = file->i_ctlr = file->i_unit = 46034463Sbostic file->i_part = 0; 46134463Sbostic break; 46234463Sbostic } 46334463Sbostic } 464327Sbill 46534463Sbostic for (cnt = 0; cnt < sizeof(args)/sizeof(args[0]); args[cnt++] = 0); 46634463Sbostic #ifndef SMALL 46734463Sbostic for (t = str; *t && *t != '/' && *t != ':' && *t != '('; ++t) 46834463Sbostic if (isupper(*t)) 46934463Sbostic *t = tolower(*t); 47034463Sbostic switch(*t) { 47134463Sbostic case '(': /* type(adapt, ctlr, drive, partition)file */ 47240500Smckusick if ((file->i_dev = getdev(str, t - str)) == -1) 47330547Skarels goto bad; 47434463Sbostic for (argp = args + 4, cnt = 0; *t != ')'; ++cnt) { 47534463Sbostic for (++t; isspace(*t); ++t); 47634463Sbostic if (*t == ')') 47734463Sbostic break; 47834463Sbostic if (!isdigit(*t)) 47930547Skarels goto badspec; 48034463Sbostic *argp++ = atoi(t); 48134463Sbostic for (++t; isdigit(*t); ++t); 48234463Sbostic if (*t != ',' && *t != ')' || cnt == 4) 48334463Sbostic goto badspec; 48430547Skarels } 48534463Sbostic for (++t; isspace(*t); ++t); 48634463Sbostic argp -= 4; 48734463Sbostic file->i_adapt = *argp++; 48834463Sbostic file->i_ctlr = *argp++; 48934463Sbostic file->i_unit = *argp++; 49034463Sbostic file->i_part = *argp; 49134463Sbostic break; 49234463Sbostic case ':': /* [A-Za-z]*[0-9]*[A-Za-z]:file */ 49334463Sbostic for (t = str; *t != ':' && !isdigit(*t); ++t); 49440500Smckusick if ((file->i_dev = getdev(str, t - str)) == -1) 49530547Skarels goto bad; 49634463Sbostic if ((file->i_unit = getunit(t)) == -1) 49730547Skarels goto bad; 49834463Sbostic for (; isdigit(*t); ++t); 49934463Sbostic if (*t >= 'a' && *t <= 'h') 50034463Sbostic file->i_part = *t++ - 'a'; 50134463Sbostic if (*t != ':') { 50225166Skarels errno = EOFFSET; 50330547Skarels goto badspec; 50425166Skarels } 50534463Sbostic for (++t; isspace(*t); ++t); 50634463Sbostic break; 50734463Sbostic case '/': 50834463Sbostic default: /* default bootstrap unit and device */ 50934463Sbostic #else 51034463Sbostic { 51134463Sbostic #endif /* SMALL */ 51240500Smckusick file->i_dev = B_TYPE(bootdev); 51334463Sbostic file->i_adapt = B_ADAPTOR(bootdev); 51434463Sbostic file->i_ctlr = B_CONTROLLER(bootdev); 51534463Sbostic file->i_unit = B_UNIT(bootdev); 51634463Sbostic file->i_part = B_PARTITION(bootdev); 51734463Sbostic t = str; 51825166Skarels } 51934463Sbostic 52040500Smckusick opendev = MAKEBOOTDEV(file->i_dev, file->i_adapt, file->i_ctlr, 52134463Sbostic file->i_unit, file->i_part); 52234463Sbostic 52330547Skarels if (errno = devopen(file)) 52430547Skarels goto bad; 52534463Sbostic 52634463Sbostic if (*t == '\0') { 52734463Sbostic file->i_flgs |= how + 1; 52825166Skarels file->i_cc = 0; 52925166Skarels file->i_offset = 0; 53025166Skarels return (fdesc+3); 53125166Skarels } 53234463Sbostic #ifndef SMALL 53334463Sbostic else if (how != 0) { 53434463Sbostic printf("Can't write files yet.. Sorry\n"); 53534463Sbostic errno = EIO; 53634463Sbostic goto bad; 53734463Sbostic } 53833408Skarels #endif 5396068Smckusic file->i_ma = (char *)(&file->i_fs); 5406068Smckusic file->i_cc = SBSIZE; 54130768Skarels file->i_bn = SBOFF / DEV_BSIZE + file->i_boff; 5426068Smckusic file->i_offset = 0; 54311083Ssam if (devread(file) < 0) { 54411083Ssam errno = file->i_error; 54511083Ssam printf("super block read error\n"); 54630547Skarels goto bad; 54711083Ssam } 54834463Sbostic if ((cnt = find(t, file)) == 0) { 54910022Ssam errno = ESRCH; 55030547Skarels goto bad; 551327Sbill } 55234463Sbostic if (openi(cnt, file) < 0) { 55311083Ssam errno = file->i_error; 55430547Skarels goto bad; 55511083Ssam } 556327Sbill file->i_offset = 0; 557327Sbill file->i_cc = 0; 558327Sbill file->i_flgs |= F_FILE | (how+1); 55910022Ssam return (fdesc+3); 56030547Skarels 56133408Skarels #ifndef SMALL 56230547Skarels badspec: 56348826Swilliam printf("malformed device specification\nusage: device(adaptor, controller, drive, partition)file -or- <device><unit><partitionletter>:<file>\n"); 56433408Skarels #endif 56530547Skarels bad: 56630547Skarels file->i_flgs = 0; 56730547Skarels return (-1); 568327Sbill } 569327Sbill 57030924Skarels #ifndef SMALL 57130547Skarels static 57230547Skarels getdev(str, len) 57333408Skarels register char *str; 57430547Skarels int len; 57530547Skarels { 57630547Skarels register struct devsw *dp; 57733408Skarels register int i; 57834463Sbostic char savedch = str[len]; 57930547Skarels 58034463Sbostic str[len] = '\0'; 58133408Skarels for (dp = devsw, i = 0; i < ndevs; dp++, i++) 58233408Skarels if (dp->dv_name && strcmp(str, dp->dv_name) == 0) { 58334463Sbostic str[len] = savedch; 58433408Skarels return (i); 58533408Skarels } 58633408Skarels printf("Unknown device\nKnown devices are:\n"); 58733408Skarels for (dp = devsw, i = 0; i < ndevs; dp++, i++) 58833408Skarels if (dp->dv_name) 58933408Skarels printf(" %s", dp->dv_name); 59034463Sbostic printf("\n"); 59130547Skarels errno = ENXIO; 59230547Skarels return (-1); 59330547Skarels } 59430547Skarels 59530547Skarels static 59630547Skarels getunit(cp) 59730547Skarels register char *cp; 59830547Skarels { 59934463Sbostic int unit; 60030547Skarels 60134463Sbostic unit = atoi(cp); 60234463Sbostic if ((u_int)unit > 255) { 60330547Skarels printf("minor device number out of range (0-255)\n"); 60430547Skarels errno = EUNIT; 60534463Sbostic return (-1); 60630547Skarels } 60734463Sbostic return (unit); 60830547Skarels } 60934463Sbostic #endif /* SMALL */ 61030547Skarels 611327Sbill close(fdesc) 61210022Ssam int fdesc; 613327Sbill { 61448826Swilliam #ifndef SMALL 615327Sbill struct iob *file; 616327Sbill 617327Sbill fdesc -= 3; 618*49117Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 61910022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 62010022Ssam errno = EBADF; 62110022Ssam return (-1); 62210022Ssam } 623327Sbill if ((file->i_flgs&F_FILE) == 0) 624327Sbill devclose(file); 625327Sbill file->i_flgs = 0; 62648826Swilliam #endif 62710022Ssam return (0); 628327Sbill } 629327Sbill 63034463Sbostic #ifndef SMALL 63110022Ssam ioctl(fdesc, cmd, arg) 63210022Ssam int fdesc, cmd; 63310022Ssam char *arg; 63410022Ssam { 63510022Ssam register struct iob *file; 63610022Ssam int error = 0; 63710022Ssam 63810331Shelge fdesc -= 3; 639*49117Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 64010022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 64110022Ssam errno = EBADF; 64210022Ssam return (-1); 64310022Ssam } 64410022Ssam switch (cmd) { 64510022Ssam 64610022Ssam case SAIOHDR: 64710022Ssam file->i_flgs |= F_HDR; 64810022Ssam break; 64910022Ssam 65010022Ssam case SAIOCHECK: 65110022Ssam file->i_flgs |= F_CHECK; 65210022Ssam break; 65310022Ssam 65410022Ssam case SAIOHCHECK: 65510022Ssam file->i_flgs |= F_HCHECK; 65610022Ssam break; 65710022Ssam 65810331Shelge case SAIONOBAD: 65910331Shelge file->i_flgs |= F_NBSF; 66010331Shelge break; 66110331Shelge 66210331Shelge case SAIODOBAD: 66310331Shelge file->i_flgs &= ~F_NBSF; 66410331Shelge break; 66510331Shelge 66610022Ssam default: 66710022Ssam error = devioctl(file, cmd, arg); 66810022Ssam break; 66910022Ssam } 67010022Ssam if (error < 0) 67110022Ssam errno = file->i_error; 67210022Ssam return (error); 67310022Ssam } 67434463Sbostic #endif /* SMALL */ 67510022Ssam 67648826Swilliam #ifndef i386 677327Sbill exit() 678327Sbill { 679327Sbill _stop("Exit called"); 680327Sbill } 68148826Swilliam #endif 682327Sbill 683327Sbill _stop(s) 68410022Ssam char *s; 685327Sbill { 6862391Stoy int i; 68741542Smckusick static int stopped = 0; 6882391Stoy 68941542Smckusick if (!stopped) { 69041542Smckusick stopped++; 691*49117Sbostic for (i = 0; i < SOPEN_MAX; i++) 69241542Smckusick if (iob[i].i_flgs != 0) 69341542Smckusick close(i); 69441542Smckusick } 695327Sbill printf("%s\n", s); 696327Sbill _rtt(); 697327Sbill } 698