123243Smckusick /* 229310Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323243Smckusick * All rights reserved. The Berkeley software License Agreement 423243Smckusick * specifies the terms and conditions for redistribution. 523243Smckusick * 6*48826Swilliam * @(#)sys.c 7.14 (Berkeley) 04/28/91 723243Smckusick */ 8327Sbill 940498Sroot #include "sys/param.h" 1045792Sbostic #include "sys/reboot.h" 1140498Sroot #include "ufs/dir.h" 1245792Sbostic #include "stand/saio.h" /* used from machine/stand dir */ 13327Sbill 1434942Sbostic #define isdigit(c) ((u_int)((c) - '0') <= 9) 1534463Sbostic #define isspace(c) ((c) == ' ' || (c) == '\t') 1634942Sbostic #define isupper(c) ((u_int)((c) - 'A') <= 'Z' - 'A') 1734463Sbostic #define tolower(c) ((c) - 'A' + 'a') 1834463Sbostic 19327Sbill ino_t dlook(); 20327Sbill 216068Smckusic struct dirstuff { 226068Smckusic int loc; 236068Smckusic struct iob *io; 246068Smckusic }; 256068Smckusic 2634463Sbostic struct iob iob[NFILES]; 2734463Sbostic 28327Sbill static 2910022Ssam openi(n, io) 306068Smckusic register struct iob *io; 31327Sbill { 32327Sbill register struct dinode *dp; 3311083Ssam int cc; 34327Sbill 35327Sbill io->i_offset = 0; 366068Smckusic io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 376068Smckusic io->i_cc = io->i_fs.fs_bsize; 38327Sbill io->i_ma = io->i_buf; 3911083Ssam cc = devread(io); 40327Sbill dp = (struct dinode *)io->i_buf; 4140500Smckusick io->i_ino = dp[itoo(&io->i_fs, n)]; 4211083Ssam return (cc); 43327Sbill } 44327Sbill 45327Sbill static 46327Sbill find(path, file) 476068Smckusic register char *path; 486068Smckusic struct iob *file; 49327Sbill { 50327Sbill register char *q; 5134463Sbostic char *dir, c; 52327Sbill int n; 53327Sbill 5434463Sbostic if (path == NULL || *path == '\0') { 55327Sbill printf("null path\n"); 5610022Ssam return (0); 57327Sbill } 58327Sbill 5911083Ssam if (openi((ino_t) ROOTINO, file) < 0) { 6011083Ssam printf("can't read root inode\n"); 6111083Ssam return (0); 6211083Ssam } 6330768Skarels dir = path; 64327Sbill while (*path) { 65327Sbill while (*path == '/') 66327Sbill path++; 67327Sbill q = path; 68327Sbill while(*q != '/' && *q != '\0') 69327Sbill q++; 70327Sbill c = *q; 71327Sbill *q = '\0'; 7225166Skarels if (q == path) path = "." ; /* "/" means "/." */ 73327Sbill 7430768Skarels if ((n = dlook(path, file, dir)) != 0) { 7511083Ssam if (c == '\0') 76327Sbill break; 7711083Ssam if (openi(n, file) < 0) 7811083Ssam return (0); 79327Sbill *q = c; 80327Sbill path = q; 81327Sbill continue; 82327Sbill } else { 8325166Skarels printf("%s: not found\n", path); 8410022Ssam return (0); 85327Sbill } 86327Sbill } 8710022Ssam return (n); 88327Sbill } 89327Sbill 9034463Sbostic #define NBUFS 4 9134463Sbostic static char b[NBUFS][MAXBSIZE]; 9234463Sbostic static daddr_t blknos[NBUFS]; 9334463Sbostic 94327Sbill static daddr_t 95327Sbill sbmap(io, bn) 966068Smckusic register struct iob *io; 976068Smckusic daddr_t bn; 98327Sbill { 9940500Smckusick register struct dinode *ip; 1006068Smckusic int i, j, sh; 101327Sbill daddr_t nb, *bap; 102327Sbill 103327Sbill ip = &io->i_ino; 1046068Smckusic if (bn < 0) { 105327Sbill printf("bn negative\n"); 10610022Ssam return ((daddr_t)0); 107327Sbill } 108327Sbill 109327Sbill /* 1106068Smckusic * blocks 0..NDADDR are direct blocks 111327Sbill */ 1126068Smckusic if(bn < NDADDR) { 11340500Smckusick nb = ip->di_db[bn]; 11410022Ssam return (nb); 115327Sbill } 116327Sbill 117327Sbill /* 1186068Smckusic * addresses NIADDR have single and double indirect blocks. 1196068Smckusic * the first step is to determine how many levels of indirection. 120327Sbill */ 1216068Smckusic sh = 1; 1226068Smckusic bn -= NDADDR; 1236068Smckusic for (j = NIADDR; j > 0; j--) { 1246068Smckusic sh *= NINDIR(&io->i_fs); 1256068Smckusic if (bn < sh) 126327Sbill break; 1276068Smckusic bn -= sh; 128327Sbill } 1296068Smckusic if (j == 0) { 1306068Smckusic printf("bn ovf %D\n", bn); 1316068Smckusic return ((daddr_t)0); 132327Sbill } 133327Sbill 134327Sbill /* 1356068Smckusic * fetch the first indirect block address from the inode 136327Sbill */ 13740500Smckusick nb = ip->di_ib[NIADDR - j]; 1386068Smckusic if (nb == 0) { 139327Sbill printf("bn void %D\n",bn); 14010022Ssam return ((daddr_t)0); 141327Sbill } 142327Sbill 143327Sbill /* 144327Sbill * fetch through the indirect blocks 145327Sbill */ 1466068Smckusic for (; j <= NIADDR; j++) { 147327Sbill if (blknos[j] != nb) { 1486068Smckusic io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 149327Sbill io->i_ma = b[j]; 1506068Smckusic io->i_cc = io->i_fs.fs_bsize; 15111083Ssam if (devread(io) != io->i_fs.fs_bsize) { 15211083Ssam if (io->i_error) 15311083Ssam errno = io->i_error; 15411083Ssam printf("bn %D: read error\n", io->i_bn); 15511083Ssam return ((daddr_t)0); 15611083Ssam } 157327Sbill blknos[j] = nb; 158327Sbill } 159327Sbill bap = (daddr_t *)b[j]; 1606068Smckusic sh /= NINDIR(&io->i_fs); 1616068Smckusic i = (bn / sh) % NINDIR(&io->i_fs); 162327Sbill nb = bap[i]; 163327Sbill if(nb == 0) { 164327Sbill printf("bn void %D\n",bn); 16510022Ssam return ((daddr_t)0); 166327Sbill } 167327Sbill } 16810022Ssam return (nb); 169327Sbill } 170327Sbill 1716068Smckusic /* 1726068Smckusic * get next entry in a directory. 1736068Smckusic */ 1746068Smckusic struct direct * 1756068Smckusic readdir(dirp) 1766068Smckusic register struct dirstuff *dirp; 177327Sbill { 1786068Smckusic register struct direct *dp; 1796068Smckusic register struct iob *io; 1806068Smckusic daddr_t lbn, d; 1816068Smckusic int off; 182327Sbill 1836068Smckusic io = dirp->io; 1846068Smckusic for(;;) { 18540500Smckusick if (dirp->loc >= io->i_ino.di_size) 18611083Ssam return (NULL); 1876068Smckusic off = blkoff(&io->i_fs, dirp->loc); 1886068Smckusic if (off == 0) { 1896068Smckusic lbn = lblkno(&io->i_fs, dirp->loc); 1906068Smckusic d = sbmap(io, lbn); 1916068Smckusic if(d == 0) 19234463Sbostic return (NULL); 1936068Smckusic io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 1946068Smckusic io->i_ma = io->i_buf; 19540500Smckusick io->i_cc = dblksize(&io->i_fs, &io->i_ino, lbn); 19611083Ssam if (devread(io) < 0) { 19711083Ssam errno = io->i_error; 19825166Skarels printf("bn %D: directory read error\n", 19925166Skarels io->i_bn); 20011083Ssam return (NULL); 20111083Ssam } 2026068Smckusic } 2036068Smckusic dp = (struct direct *)(io->i_buf + off); 2046068Smckusic dirp->loc += dp->d_reclen; 2056068Smckusic if (dp->d_ino == 0) 2066068Smckusic continue; 2076068Smckusic return (dp); 208327Sbill } 209327Sbill } 210327Sbill 21140500Smckusick static ino_t 21240500Smckusick dlook(s, io, dir) 21340500Smckusick char *s; 21440500Smckusick register struct iob *io; 21540500Smckusick char *dir; 21640500Smckusick { 21740500Smckusick register struct direct *dp; 21840500Smckusick register struct dinode *ip; 21940500Smckusick struct dirstuff dirp; 22040500Smckusick int len; 22140500Smckusick 22240500Smckusick if (s == NULL || *s == '\0') 22340500Smckusick return (0); 22440500Smckusick ip = &io->i_ino; 22540500Smckusick if ((ip->di_mode&IFMT) != IFDIR) { 22640500Smckusick printf("%s: not a directory\n", dir); 22740500Smckusick return (0); 22840500Smckusick } 22940500Smckusick if (ip->di_size == 0) { 23040500Smckusick printf("%s: zero length directory\n", dir); 23140500Smckusick return (0); 23240500Smckusick } 23340500Smckusick len = strlen(s); 23440500Smckusick dirp.loc = 0; 23540500Smckusick dirp.io = io; 23640500Smckusick for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 23740500Smckusick if(dp->d_ino == 0) 23840500Smckusick continue; 23940500Smckusick if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 24040500Smckusick return (dp->d_ino); 24140500Smckusick } 24240500Smckusick return (0); 24340500Smckusick } 24440500Smckusick 245327Sbill lseek(fdesc, addr, ptr) 24610022Ssam int fdesc, ptr; 24710022Ssam off_t addr; 248327Sbill { 249327Sbill register struct iob *io; 250327Sbill 25134463Sbostic #ifndef SMALL 25234463Sbostic if (ptr != L_SET) { 253327Sbill printf("Seek not from beginning of file\n"); 25410022Ssam errno = EOFFSET; 25510022Ssam return (-1); 256327Sbill } 25734463Sbostic #endif 258327Sbill fdesc -= 3; 259*48826Swilliam #ifndef SMALL 2606068Smckusic if (fdesc < 0 || fdesc >= NFILES || 26110022Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 26210022Ssam errno = EBADF; 26310022Ssam return (-1); 26410022Ssam } 265*48826Swilliam #endif 266327Sbill io->i_offset = addr; 2676068Smckusic io->i_bn = addr / DEV_BSIZE; 268327Sbill io->i_cc = 0; 26910022Ssam return (0); 270327Sbill } 271327Sbill 272327Sbill getc(fdesc) 27310022Ssam int fdesc; 274327Sbill { 275327Sbill register struct iob *io; 2766068Smckusic register struct fs *fs; 277327Sbill register char *p; 2786068Smckusic int c, lbn, off, size, diff; 279327Sbill 280327Sbill 281*48826Swilliam #ifndef SMALL 282327Sbill if (fdesc >= 0 && fdesc <= 2) 28310022Ssam return (getchar()); 284*48826Swilliam #endif 285327Sbill fdesc -= 3; 2866068Smckusic if (fdesc < 0 || fdesc >= NFILES || 28710022Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 28810022Ssam errno = EBADF; 28910022Ssam return (-1); 29010022Ssam } 291327Sbill p = io->i_ma; 292327Sbill if (io->i_cc <= 0) { 2936068Smckusic if ((io->i_flgs & F_FILE) != 0) { 29440500Smckusick diff = io->i_ino.di_size - io->i_offset; 2956068Smckusic if (diff <= 0) 2966068Smckusic return (-1); 2976068Smckusic fs = &io->i_fs; 2986068Smckusic lbn = lblkno(fs, io->i_offset); 2996068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 3006068Smckusic off = blkoff(fs, io->i_offset); 30140500Smckusick size = dblksize(fs, &io->i_ino, lbn); 3026068Smckusic } else { 303*48826Swilliam io->i_bn = io->i_offset / DEV_BSIZE + io->i_boff; 3046068Smckusic off = 0; 3056068Smckusic size = DEV_BSIZE; 3066068Smckusic } 307327Sbill io->i_ma = io->i_buf; 3086068Smckusic io->i_cc = size; 30911083Ssam if (devread(io) < 0) { 31011083Ssam errno = io->i_error; 31111083Ssam return (-1); 31211083Ssam } 3136068Smckusic if ((io->i_flgs & F_FILE) != 0) { 31440500Smckusick if (io->i_offset - off + size >= io->i_ino.di_size) 3156068Smckusic io->i_cc = diff + off; 316327Sbill io->i_cc -= off; 3176068Smckusic } 318327Sbill p = &io->i_buf[off]; 319327Sbill } 320327Sbill io->i_cc--; 321327Sbill io->i_offset++; 322327Sbill c = (unsigned)*p++; 323327Sbill io->i_ma = p; 32410022Ssam return (c); 325327Sbill } 3266068Smckusic 32710022Ssam int errno; 328327Sbill 329327Sbill read(fdesc, buf, count) 33010022Ssam int fdesc, count; 33110022Ssam char *buf; 332327Sbill { 33325166Skarels register i, size; 334327Sbill register struct iob *file; 33525166Skarels register struct fs *fs; 33625166Skarels int lbn, off; 337327Sbill 33810022Ssam errno = 0; 339*48826Swilliam #ifndef SMALL 34045352Sbostic if (fdesc >= 0 && fdesc <= 2) { 341327Sbill i = count; 342327Sbill do { 343327Sbill *buf = getchar(); 344327Sbill } while (--i && *buf++ != '\n'); 34510022Ssam return (count - i); 346327Sbill } 347*48826Swilliam #endif 348327Sbill fdesc -= 3; 3496068Smckusic if (fdesc < 0 || fdesc >= NFILES || 35010022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 35110022Ssam errno = EBADF; 35210022Ssam return (-1); 35310022Ssam } 35410022Ssam if ((file->i_flgs&F_READ) == 0) { 35510022Ssam errno = EBADF; 35610022Ssam return (-1); 35710022Ssam } 35834463Sbostic #ifndef SMALL 3596068Smckusic if ((file->i_flgs & F_FILE) == 0) { 360327Sbill file->i_cc = count; 361327Sbill file->i_ma = buf; 3627446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 363327Sbill i = devread(file); 36410022Ssam if (i < 0) 36510022Ssam errno = file->i_error; 36630547Skarels else 36730547Skarels file->i_offset += i; 36810022Ssam return (i); 369327Sbill } 37034463Sbostic #endif 37140500Smckusick if (file->i_offset+count > file->i_ino.di_size) 37240500Smckusick count = file->i_ino.di_size - file->i_offset; 37325166Skarels if ((i = count) <= 0) 37425166Skarels return (0); 37525166Skarels /* 37625166Skarels * While reading full blocks, do I/O into user buffer. 37725166Skarels * Anything else uses getc(). 37825166Skarels */ 37925166Skarels fs = &file->i_fs; 38025166Skarels while (i) { 38125166Skarels off = blkoff(fs, file->i_offset); 38225166Skarels lbn = lblkno(fs, file->i_offset); 38340500Smckusick size = dblksize(fs, &file->i_ino, lbn); 384*48826Swilliam #ifndef SMALL 38525166Skarels if (off == 0 && size <= i) { 38625166Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 38725166Skarels file->i_boff; 38825166Skarels file->i_cc = size; 38925166Skarels file->i_ma = buf; 39025166Skarels if (devread(file) < 0) { 39125166Skarels errno = file->i_error; 39225166Skarels return (-1); 39325166Skarels } 39425166Skarels file->i_offset += size; 39525166Skarels file->i_cc = 0; 39625166Skarels buf += size; 39725166Skarels i -= size; 39825166Skarels } else { 399*48826Swilliam #endif 40025166Skarels size -= off; 40125166Skarels if (size > i) 40225166Skarels size = i; 40325166Skarels i -= size; 40425166Skarels do { 40525166Skarels *buf++ = getc(fdesc+3); 40625166Skarels } while (--size); 407*48826Swilliam #ifndef SMALL 40825166Skarels } 409*48826Swilliam #endif 41025166Skarels } 41125166Skarels return (count); 412327Sbill } 413327Sbill 41434463Sbostic #ifndef SMALL 415327Sbill write(fdesc, buf, count) 41610022Ssam int fdesc, count; 41710022Ssam char *buf; 418327Sbill { 419327Sbill register i; 420327Sbill register struct iob *file; 421327Sbill 42210022Ssam errno = 0; 423327Sbill if (fdesc >= 0 && fdesc <= 2) { 424327Sbill i = count; 425327Sbill while (i--) 426327Sbill putchar(*buf++); 42710022Ssam return (count); 428327Sbill } 429327Sbill fdesc -= 3; 4306068Smckusic if (fdesc < 0 || fdesc >= NFILES || 43110022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 43210022Ssam errno = EBADF; 43310022Ssam return (-1); 43410022Ssam } 43510022Ssam if ((file->i_flgs&F_WRITE) == 0) { 43610022Ssam errno = EBADF; 43710022Ssam return (-1); 43810022Ssam } 439327Sbill file->i_cc = count; 440327Sbill file->i_ma = buf; 4417446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 442327Sbill i = devwrite(file); 4437446Sroot file->i_offset += count; 44410022Ssam if (i < 0) 44510022Ssam errno = file->i_error; 44610022Ssam return (i); 447327Sbill } 44834463Sbostic #endif 449327Sbill 4503349Swnj int openfirst = 1; 45134463Sbostic u_int opendev; /* last device opened */ 45234463Sbostic extern u_int bootdev; 4533349Swnj 454327Sbill open(str, how) 4556068Smckusic char *str; 45610022Ssam int how; 457327Sbill { 45834463Sbostic register char *t; 45934463Sbostic register int cnt; 460327Sbill register struct iob *file; 46134463Sbostic int fdesc, args[8], *argp; 462327Sbill 4633349Swnj if (openfirst) { 46434463Sbostic for (cnt = 0; cnt < NFILES; cnt++) 46534463Sbostic iob[cnt].i_flgs = 0; 4663349Swnj openfirst = 0; 467327Sbill } 468327Sbill 46934463Sbostic for (fdesc = 0;; fdesc++) { 47034463Sbostic if (fdesc == NFILES) 47134463Sbostic _stop("No more file slots"); 47234463Sbostic if (iob[fdesc].i_flgs == 0) { 47334463Sbostic file = &iob[fdesc]; 47434463Sbostic file->i_flgs |= F_ALLOC; 47534463Sbostic file->i_adapt = file->i_ctlr = file->i_unit = 47634463Sbostic file->i_part = 0; 47734463Sbostic break; 47834463Sbostic } 47934463Sbostic } 480327Sbill 48134463Sbostic for (cnt = 0; cnt < sizeof(args)/sizeof(args[0]); args[cnt++] = 0); 48234463Sbostic #ifndef SMALL 48334463Sbostic for (t = str; *t && *t != '/' && *t != ':' && *t != '('; ++t) 48434463Sbostic if (isupper(*t)) 48534463Sbostic *t = tolower(*t); 48634463Sbostic switch(*t) { 48734463Sbostic case '(': /* type(adapt, ctlr, drive, partition)file */ 48840500Smckusick if ((file->i_dev = getdev(str, t - str)) == -1) 48930547Skarels goto bad; 49034463Sbostic for (argp = args + 4, cnt = 0; *t != ')'; ++cnt) { 49134463Sbostic for (++t; isspace(*t); ++t); 49234463Sbostic if (*t == ')') 49334463Sbostic break; 49434463Sbostic if (!isdigit(*t)) 49530547Skarels goto badspec; 49634463Sbostic *argp++ = atoi(t); 49734463Sbostic for (++t; isdigit(*t); ++t); 49834463Sbostic if (*t != ',' && *t != ')' || cnt == 4) 49934463Sbostic goto badspec; 50030547Skarels } 50134463Sbostic for (++t; isspace(*t); ++t); 50234463Sbostic argp -= 4; 50334463Sbostic file->i_adapt = *argp++; 50434463Sbostic file->i_ctlr = *argp++; 50534463Sbostic file->i_unit = *argp++; 50634463Sbostic file->i_part = *argp; 50734463Sbostic break; 50834463Sbostic case ':': /* [A-Za-z]*[0-9]*[A-Za-z]:file */ 50934463Sbostic for (t = str; *t != ':' && !isdigit(*t); ++t); 51040500Smckusick if ((file->i_dev = getdev(str, t - str)) == -1) 51130547Skarels goto bad; 51234463Sbostic if ((file->i_unit = getunit(t)) == -1) 51330547Skarels goto bad; 51434463Sbostic for (; isdigit(*t); ++t); 51534463Sbostic if (*t >= 'a' && *t <= 'h') 51634463Sbostic file->i_part = *t++ - 'a'; 51734463Sbostic if (*t != ':') { 51825166Skarels errno = EOFFSET; 51930547Skarels goto badspec; 52025166Skarels } 52134463Sbostic for (++t; isspace(*t); ++t); 52234463Sbostic break; 52334463Sbostic case '/': 52434463Sbostic default: /* default bootstrap unit and device */ 52534463Sbostic #else 52634463Sbostic { 52734463Sbostic #endif /* SMALL */ 52840500Smckusick file->i_dev = B_TYPE(bootdev); 52934463Sbostic file->i_adapt = B_ADAPTOR(bootdev); 53034463Sbostic file->i_ctlr = B_CONTROLLER(bootdev); 53134463Sbostic file->i_unit = B_UNIT(bootdev); 53234463Sbostic file->i_part = B_PARTITION(bootdev); 53334463Sbostic t = str; 53425166Skarels } 53534463Sbostic 53640500Smckusick opendev = MAKEBOOTDEV(file->i_dev, file->i_adapt, file->i_ctlr, 53734463Sbostic file->i_unit, file->i_part); 53834463Sbostic 53930547Skarels if (errno = devopen(file)) 54030547Skarels goto bad; 54134463Sbostic 54234463Sbostic if (*t == '\0') { 54334463Sbostic file->i_flgs |= how + 1; 54425166Skarels file->i_cc = 0; 54525166Skarels file->i_offset = 0; 54625166Skarels return (fdesc+3); 54725166Skarels } 54834463Sbostic #ifndef SMALL 54934463Sbostic else if (how != 0) { 55034463Sbostic printf("Can't write files yet.. Sorry\n"); 55134463Sbostic errno = EIO; 55234463Sbostic goto bad; 55334463Sbostic } 55433408Skarels #endif 5556068Smckusic file->i_ma = (char *)(&file->i_fs); 5566068Smckusic file->i_cc = SBSIZE; 55730768Skarels file->i_bn = SBOFF / DEV_BSIZE + file->i_boff; 5586068Smckusic file->i_offset = 0; 55911083Ssam if (devread(file) < 0) { 56011083Ssam errno = file->i_error; 56111083Ssam printf("super block read error\n"); 56230547Skarels goto bad; 56311083Ssam } 56434463Sbostic if ((cnt = find(t, file)) == 0) { 56510022Ssam errno = ESRCH; 56630547Skarels goto bad; 567327Sbill } 56834463Sbostic if (openi(cnt, file) < 0) { 56911083Ssam errno = file->i_error; 57030547Skarels goto bad; 57111083Ssam } 572327Sbill file->i_offset = 0; 573327Sbill file->i_cc = 0; 574327Sbill file->i_flgs |= F_FILE | (how+1); 57510022Ssam return (fdesc+3); 57630547Skarels 57733408Skarels #ifndef SMALL 57830547Skarels badspec: 579*48826Swilliam printf("malformed device specification\nusage: device(adaptor, controller, drive, partition)file -or- <device><unit><partitionletter>:<file>\n"); 58033408Skarels #endif 58130547Skarels bad: 58230547Skarels file->i_flgs = 0; 58330547Skarels return (-1); 584327Sbill } 585327Sbill 58630924Skarels #ifndef SMALL 58730547Skarels static 58830547Skarels getdev(str, len) 58933408Skarels register char *str; 59030547Skarels int len; 59130547Skarels { 59230547Skarels register struct devsw *dp; 59333408Skarels register int i; 59434463Sbostic char savedch = str[len]; 59530547Skarels 59634463Sbostic str[len] = '\0'; 59733408Skarels for (dp = devsw, i = 0; i < ndevs; dp++, i++) 59833408Skarels if (dp->dv_name && strcmp(str, dp->dv_name) == 0) { 59934463Sbostic str[len] = savedch; 60033408Skarels return (i); 60133408Skarels } 60233408Skarels printf("Unknown device\nKnown devices are:\n"); 60333408Skarels for (dp = devsw, i = 0; i < ndevs; dp++, i++) 60433408Skarels if (dp->dv_name) 60533408Skarels printf(" %s", dp->dv_name); 60634463Sbostic printf("\n"); 60730547Skarels errno = ENXIO; 60830547Skarels return (-1); 60930547Skarels } 61030547Skarels 61130547Skarels static 61230547Skarels getunit(cp) 61330547Skarels register char *cp; 61430547Skarels { 61534463Sbostic int unit; 61630547Skarels 61734463Sbostic unit = atoi(cp); 61834463Sbostic if ((u_int)unit > 255) { 61930547Skarels printf("minor device number out of range (0-255)\n"); 62030547Skarels errno = EUNIT; 62134463Sbostic return (-1); 62230547Skarels } 62334463Sbostic return (unit); 62430547Skarels } 62534463Sbostic #endif /* SMALL */ 62630547Skarels 627327Sbill close(fdesc) 62810022Ssam int fdesc; 629327Sbill { 630*48826Swilliam #ifndef SMALL 631327Sbill struct iob *file; 632327Sbill 633327Sbill fdesc -= 3; 6346068Smckusic if (fdesc < 0 || fdesc >= NFILES || 63510022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 63610022Ssam errno = EBADF; 63710022Ssam return (-1); 63810022Ssam } 639327Sbill if ((file->i_flgs&F_FILE) == 0) 640327Sbill devclose(file); 641327Sbill file->i_flgs = 0; 642*48826Swilliam #endif 64310022Ssam return (0); 644327Sbill } 645327Sbill 64634463Sbostic #ifndef SMALL 64710022Ssam ioctl(fdesc, cmd, arg) 64810022Ssam int fdesc, cmd; 64910022Ssam char *arg; 65010022Ssam { 65110022Ssam register struct iob *file; 65210022Ssam int error = 0; 65310022Ssam 65410331Shelge fdesc -= 3; 65510022Ssam if (fdesc < 0 || fdesc >= NFILES || 65610022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 65710022Ssam errno = EBADF; 65810022Ssam return (-1); 65910022Ssam } 66010022Ssam switch (cmd) { 66110022Ssam 66210022Ssam case SAIOHDR: 66310022Ssam file->i_flgs |= F_HDR; 66410022Ssam break; 66510022Ssam 66610022Ssam case SAIOCHECK: 66710022Ssam file->i_flgs |= F_CHECK; 66810022Ssam break; 66910022Ssam 67010022Ssam case SAIOHCHECK: 67110022Ssam file->i_flgs |= F_HCHECK; 67210022Ssam break; 67310022Ssam 67410331Shelge case SAIONOBAD: 67510331Shelge file->i_flgs |= F_NBSF; 67610331Shelge break; 67710331Shelge 67810331Shelge case SAIODOBAD: 67910331Shelge file->i_flgs &= ~F_NBSF; 68010331Shelge break; 68110331Shelge 68210022Ssam default: 68310022Ssam error = devioctl(file, cmd, arg); 68410022Ssam break; 68510022Ssam } 68610022Ssam if (error < 0) 68710022Ssam errno = file->i_error; 68810022Ssam return (error); 68910022Ssam } 69034463Sbostic #endif /* SMALL */ 69110022Ssam 692*48826Swilliam #ifndef i386 693327Sbill exit() 694327Sbill { 695327Sbill _stop("Exit called"); 696327Sbill } 697*48826Swilliam #endif 698327Sbill 699327Sbill _stop(s) 70010022Ssam char *s; 701327Sbill { 7022391Stoy int i; 70341542Smckusick static int stopped = 0; 7042391Stoy 70541542Smckusick if (!stopped) { 70641542Smckusick stopped++; 70741542Smckusick for (i = 0; i < NFILES; i++) 70841542Smckusick if (iob[i].i_flgs != 0) 70941542Smckusick close(i); 71041542Smckusick } 711327Sbill printf("%s\n", s); 712327Sbill _rtt(); 713327Sbill } 714