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*34463Sbostic * @(#)sys.c 7.6 (Berkeley) 05/24/88 723243Smckusick */ 8327Sbill 930768Skarels #include "param.h" 1030768Skarels #include "inode.h" 1130768Skarels #include "fs.h" 1230768Skarels #include "dir.h" 1330768Skarels #include "reboot.h" 14327Sbill #include "saio.h" 15327Sbill 16*34463Sbostic #define isdigit(c) ((c) >= '0' && (c) <= '9') 17*34463Sbostic #define isspace(c) ((c) == ' ' || (c) == '\t') 18*34463Sbostic #define isupper(c) ((c) >= 'A' && (c) <= 'Z') 19*34463Sbostic #define tolower(c) ((c) - 'A' + 'a') 20*34463Sbostic 21327Sbill ino_t dlook(); 22327Sbill 236068Smckusic struct dirstuff { 246068Smckusic int loc; 256068Smckusic struct iob *io; 266068Smckusic }; 276068Smckusic 28*34463Sbostic struct iob iob[NFILES]; 29*34463Sbostic 30327Sbill static 3110022Ssam openi(n, io) 326068Smckusic register struct iob *io; 33327Sbill { 34327Sbill register struct dinode *dp; 3511083Ssam int cc; 36327Sbill 37327Sbill io->i_offset = 0; 386068Smckusic io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 396068Smckusic io->i_cc = io->i_fs.fs_bsize; 40327Sbill io->i_ma = io->i_buf; 4111083Ssam cc = devread(io); 42327Sbill dp = (struct dinode *)io->i_buf; 436068Smckusic io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic; 4411083Ssam return (cc); 45327Sbill } 46327Sbill 47327Sbill static 48327Sbill find(path, file) 496068Smckusic register char *path; 506068Smckusic struct iob *file; 51327Sbill { 52327Sbill register char *q; 53*34463Sbostic char *dir, c; 54327Sbill int n; 55327Sbill 56*34463Sbostic if (path == NULL || *path == '\0') { 57327Sbill printf("null path\n"); 5810022Ssam return (0); 59327Sbill } 60327Sbill 6111083Ssam if (openi((ino_t) ROOTINO, file) < 0) { 6211083Ssam printf("can't read root inode\n"); 6311083Ssam return (0); 6411083Ssam } 6530768Skarels dir = path; 66327Sbill while (*path) { 67327Sbill while (*path == '/') 68327Sbill path++; 69327Sbill q = path; 70327Sbill while(*q != '/' && *q != '\0') 71327Sbill q++; 72327Sbill c = *q; 73327Sbill *q = '\0'; 7425166Skarels if (q == path) path = "." ; /* "/" means "/." */ 75327Sbill 7630768Skarels if ((n = dlook(path, file, dir)) != 0) { 7711083Ssam if (c == '\0') 78327Sbill break; 7911083Ssam if (openi(n, file) < 0) 8011083Ssam return (0); 81327Sbill *q = c; 82327Sbill path = q; 83327Sbill continue; 84327Sbill } else { 8525166Skarels printf("%s: not found\n", path); 8610022Ssam return (0); 87327Sbill } 88327Sbill } 8910022Ssam return (n); 90327Sbill } 91327Sbill 92*34463Sbostic #define NBUFS 4 93*34463Sbostic static char b[NBUFS][MAXBSIZE]; 94*34463Sbostic static daddr_t blknos[NBUFS]; 95*34463Sbostic 96327Sbill static daddr_t 97327Sbill sbmap(io, bn) 986068Smckusic register struct iob *io; 996068Smckusic daddr_t bn; 100327Sbill { 101327Sbill register struct inode *ip; 1026068Smckusic int i, j, sh; 103327Sbill daddr_t nb, *bap; 104327Sbill 105327Sbill ip = &io->i_ino; 1066068Smckusic if (bn < 0) { 107327Sbill printf("bn negative\n"); 10810022Ssam return ((daddr_t)0); 109327Sbill } 110327Sbill 111327Sbill /* 1126068Smckusic * blocks 0..NDADDR are direct blocks 113327Sbill */ 1146068Smckusic if(bn < NDADDR) { 1156068Smckusic nb = ip->i_db[bn]; 11610022Ssam return (nb); 117327Sbill } 118327Sbill 119327Sbill /* 1206068Smckusic * addresses NIADDR have single and double indirect blocks. 1216068Smckusic * the first step is to determine how many levels of indirection. 122327Sbill */ 1236068Smckusic sh = 1; 1246068Smckusic bn -= NDADDR; 1256068Smckusic for (j = NIADDR; j > 0; j--) { 1266068Smckusic sh *= NINDIR(&io->i_fs); 1276068Smckusic if (bn < sh) 128327Sbill break; 1296068Smckusic bn -= sh; 130327Sbill } 1316068Smckusic if (j == 0) { 1326068Smckusic printf("bn ovf %D\n", bn); 1336068Smckusic return ((daddr_t)0); 134327Sbill } 135327Sbill 136327Sbill /* 1376068Smckusic * fetch the first indirect block address from the inode 138327Sbill */ 1396068Smckusic nb = ip->i_ib[NIADDR - j]; 1406068Smckusic if (nb == 0) { 141327Sbill printf("bn void %D\n",bn); 14210022Ssam return ((daddr_t)0); 143327Sbill } 144327Sbill 145327Sbill /* 146327Sbill * fetch through the indirect blocks 147327Sbill */ 1486068Smckusic for (; j <= NIADDR; j++) { 149327Sbill if (blknos[j] != nb) { 1506068Smckusic io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 151327Sbill io->i_ma = b[j]; 1526068Smckusic io->i_cc = io->i_fs.fs_bsize; 15311083Ssam if (devread(io) != io->i_fs.fs_bsize) { 15411083Ssam if (io->i_error) 15511083Ssam errno = io->i_error; 15611083Ssam printf("bn %D: read error\n", io->i_bn); 15711083Ssam return ((daddr_t)0); 15811083Ssam } 159327Sbill blknos[j] = nb; 160327Sbill } 161327Sbill bap = (daddr_t *)b[j]; 1626068Smckusic sh /= NINDIR(&io->i_fs); 1636068Smckusic i = (bn / sh) % NINDIR(&io->i_fs); 164327Sbill nb = bap[i]; 165327Sbill if(nb == 0) { 166327Sbill printf("bn void %D\n",bn); 16710022Ssam return ((daddr_t)0); 168327Sbill } 169327Sbill } 17010022Ssam return (nb); 171327Sbill } 172327Sbill 173327Sbill static ino_t 17430768Skarels dlook(s, io, dir) 1756068Smckusic char *s; 1766068Smckusic register struct iob *io; 17730768Skarels char *dir; 178327Sbill { 179327Sbill register struct direct *dp; 180327Sbill register struct inode *ip; 1816068Smckusic struct dirstuff dirp; 1826068Smckusic int len; 183327Sbill 1846068Smckusic if (s == NULL || *s == '\0') 18510022Ssam return (0); 186327Sbill ip = &io->i_ino; 1876068Smckusic if ((ip->i_mode&IFMT) != IFDIR) { 18830768Skarels printf("%s: not a directory\n", dir); 18910022Ssam return (0); 190327Sbill } 1916068Smckusic if (ip->i_size == 0) { 19230768Skarels printf("%s: zero length directory\n", dir); 19310022Ssam return (0); 194327Sbill } 1956068Smckusic len = strlen(s); 1966068Smckusic dirp.loc = 0; 1976068Smckusic dirp.io = io; 1986068Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 1996068Smckusic if(dp->d_ino == 0) 2006068Smckusic continue; 2016068Smckusic if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 20210022Ssam return (dp->d_ino); 203327Sbill } 20410022Ssam return (0); 205327Sbill } 206327Sbill 2076068Smckusic /* 2086068Smckusic * get next entry in a directory. 2096068Smckusic */ 2106068Smckusic struct direct * 2116068Smckusic readdir(dirp) 2126068Smckusic register struct dirstuff *dirp; 213327Sbill { 2146068Smckusic register struct direct *dp; 2156068Smckusic register struct iob *io; 2166068Smckusic daddr_t lbn, d; 2176068Smckusic int off; 218327Sbill 2196068Smckusic io = dirp->io; 2206068Smckusic for(;;) { 2216068Smckusic if (dirp->loc >= io->i_ino.i_size) 22211083Ssam return (NULL); 2236068Smckusic off = blkoff(&io->i_fs, dirp->loc); 2246068Smckusic if (off == 0) { 2256068Smckusic lbn = lblkno(&io->i_fs, dirp->loc); 2266068Smckusic d = sbmap(io, lbn); 2276068Smckusic if(d == 0) 228*34463Sbostic return (NULL); 2296068Smckusic io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 2306068Smckusic io->i_ma = io->i_buf; 2316068Smckusic io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); 23211083Ssam if (devread(io) < 0) { 23311083Ssam errno = io->i_error; 23425166Skarels printf("bn %D: directory read error\n", 23525166Skarels io->i_bn); 23611083Ssam return (NULL); 23711083Ssam } 2386068Smckusic } 2396068Smckusic dp = (struct direct *)(io->i_buf + off); 2406068Smckusic dirp->loc += dp->d_reclen; 2416068Smckusic if (dp->d_ino == 0) 2426068Smckusic continue; 2436068Smckusic return (dp); 244327Sbill } 245327Sbill } 246327Sbill 247327Sbill lseek(fdesc, addr, ptr) 24810022Ssam int fdesc, ptr; 24910022Ssam off_t addr; 250327Sbill { 251327Sbill register struct iob *io; 252327Sbill 253*34463Sbostic #ifndef SMALL 254*34463Sbostic if (ptr != L_SET) { 255327Sbill printf("Seek not from beginning of file\n"); 25610022Ssam errno = EOFFSET; 25710022Ssam return (-1); 258327Sbill } 259*34463Sbostic #endif 260327Sbill fdesc -= 3; 2616068Smckusic if (fdesc < 0 || fdesc >= NFILES || 26210022Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 26310022Ssam errno = EBADF; 26410022Ssam return (-1); 26510022Ssam } 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 281327Sbill if (fdesc >= 0 && fdesc <= 2) 28210022Ssam return (getchar()); 283327Sbill fdesc -= 3; 2846068Smckusic if (fdesc < 0 || fdesc >= NFILES || 28510022Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 28610022Ssam errno = EBADF; 28710022Ssam return (-1); 28810022Ssam } 289327Sbill p = io->i_ma; 290327Sbill if (io->i_cc <= 0) { 2916068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2926068Smckusic diff = io->i_ino.i_size - io->i_offset; 2936068Smckusic if (diff <= 0) 2946068Smckusic return (-1); 2956068Smckusic fs = &io->i_fs; 2966068Smckusic lbn = lblkno(fs, io->i_offset); 2976068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 2986068Smckusic off = blkoff(fs, io->i_offset); 2996068Smckusic size = blksize(fs, &io->i_ino, lbn); 3006068Smckusic } else { 3016068Smckusic io->i_bn = io->i_offset / DEV_BSIZE; 3026068Smckusic off = 0; 3036068Smckusic size = DEV_BSIZE; 3046068Smckusic } 305327Sbill io->i_ma = io->i_buf; 3066068Smckusic io->i_cc = size; 30711083Ssam if (devread(io) < 0) { 30811083Ssam errno = io->i_error; 30911083Ssam return (-1); 31011083Ssam } 3116068Smckusic if ((io->i_flgs & F_FILE) != 0) { 3126068Smckusic if (io->i_offset - off + size >= io->i_ino.i_size) 3136068Smckusic io->i_cc = diff + off; 314327Sbill io->i_cc -= off; 3156068Smckusic } 316327Sbill p = &io->i_buf[off]; 317327Sbill } 318327Sbill io->i_cc--; 319327Sbill io->i_offset++; 320327Sbill c = (unsigned)*p++; 321327Sbill io->i_ma = p; 32210022Ssam return (c); 323327Sbill } 3246068Smckusic 32510022Ssam int errno; 326327Sbill 327327Sbill read(fdesc, buf, count) 32810022Ssam int fdesc, count; 32910022Ssam char *buf; 330327Sbill { 33125166Skarels register i, size; 332327Sbill register struct iob *file; 33325166Skarels register struct fs *fs; 33425166Skarels int lbn, off; 335327Sbill 33610022Ssam errno = 0; 337327Sbill if (fdesc >= 0 & fdesc <= 2) { 338327Sbill i = count; 339327Sbill do { 340327Sbill *buf = getchar(); 341327Sbill } while (--i && *buf++ != '\n'); 34210022Ssam return (count - i); 343327Sbill } 344327Sbill fdesc -= 3; 3456068Smckusic if (fdesc < 0 || fdesc >= NFILES || 34610022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 34710022Ssam errno = EBADF; 34810022Ssam return (-1); 34910022Ssam } 35010022Ssam if ((file->i_flgs&F_READ) == 0) { 35110022Ssam errno = EBADF; 35210022Ssam return (-1); 35310022Ssam } 354*34463Sbostic #ifndef SMALL 3556068Smckusic if ((file->i_flgs & F_FILE) == 0) { 356327Sbill file->i_cc = count; 357327Sbill file->i_ma = buf; 3587446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 359327Sbill i = devread(file); 36010022Ssam if (i < 0) 36110022Ssam errno = file->i_error; 36230547Skarels else 36330547Skarels file->i_offset += i; 36410022Ssam return (i); 365327Sbill } 366*34463Sbostic #endif 36725166Skarels if (file->i_offset+count > file->i_ino.i_size) 36825166Skarels count = file->i_ino.i_size - file->i_offset; 36925166Skarels if ((i = count) <= 0) 37025166Skarels return (0); 37125166Skarels /* 37225166Skarels * While reading full blocks, do I/O into user buffer. 37325166Skarels * Anything else uses getc(). 37425166Skarels */ 37525166Skarels fs = &file->i_fs; 37625166Skarels while (i) { 37725166Skarels off = blkoff(fs, file->i_offset); 37825166Skarels lbn = lblkno(fs, file->i_offset); 37925166Skarels size = blksize(fs, &file->i_ino, lbn); 38025166Skarels if (off == 0 && size <= i) { 38125166Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 38225166Skarels file->i_boff; 38325166Skarels file->i_cc = size; 38425166Skarels file->i_ma = buf; 38525166Skarels if (devread(file) < 0) { 38625166Skarels errno = file->i_error; 38725166Skarels return (-1); 38825166Skarels } 38925166Skarels file->i_offset += size; 39025166Skarels file->i_cc = 0; 39125166Skarels buf += size; 39225166Skarels i -= size; 39325166Skarels } else { 39425166Skarels size -= off; 39525166Skarels if (size > i) 39625166Skarels size = i; 39725166Skarels i -= size; 39825166Skarels do { 39925166Skarels *buf++ = getc(fdesc+3); 40025166Skarels } while (--size); 40125166Skarels } 40225166Skarels } 40325166Skarels return (count); 404327Sbill } 405327Sbill 406*34463Sbostic #ifndef SMALL 407327Sbill write(fdesc, buf, count) 40810022Ssam int fdesc, count; 40910022Ssam char *buf; 410327Sbill { 411327Sbill register i; 412327Sbill register struct iob *file; 413327Sbill 41410022Ssam errno = 0; 415327Sbill if (fdesc >= 0 && fdesc <= 2) { 416327Sbill i = count; 417327Sbill while (i--) 418327Sbill putchar(*buf++); 41910022Ssam return (count); 420327Sbill } 421327Sbill fdesc -= 3; 4226068Smckusic if (fdesc < 0 || fdesc >= NFILES || 42310022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 42410022Ssam errno = EBADF; 42510022Ssam return (-1); 42610022Ssam } 42710022Ssam if ((file->i_flgs&F_WRITE) == 0) { 42810022Ssam errno = EBADF; 42910022Ssam return (-1); 43010022Ssam } 431327Sbill file->i_cc = count; 432327Sbill file->i_ma = buf; 4337446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 434327Sbill i = devwrite(file); 4357446Sroot file->i_offset += count; 43610022Ssam if (i < 0) 43710022Ssam errno = file->i_error; 43810022Ssam return (i); 439327Sbill } 440*34463Sbostic #endif 441327Sbill 4423349Swnj int openfirst = 1; 443*34463Sbostic u_int opendev; /* last device opened */ 444*34463Sbostic extern u_int bootdev; 4453349Swnj 446327Sbill open(str, how) 4476068Smckusic char *str; 44810022Ssam int how; 449327Sbill { 450*34463Sbostic register char *t; 451*34463Sbostic register int cnt; 452327Sbill register struct iob *file; 453*34463Sbostic int fdesc, args[8], *argp; 454327Sbill 4553349Swnj if (openfirst) { 456*34463Sbostic for (cnt = 0; cnt < NFILES; cnt++) 457*34463Sbostic iob[cnt].i_flgs = 0; 4583349Swnj openfirst = 0; 459327Sbill } 460327Sbill 461*34463Sbostic for (fdesc = 0;; fdesc++) { 462*34463Sbostic if (fdesc == NFILES) 463*34463Sbostic _stop("No more file slots"); 464*34463Sbostic if (iob[fdesc].i_flgs == 0) { 465*34463Sbostic file = &iob[fdesc]; 466*34463Sbostic file->i_flgs |= F_ALLOC; 467*34463Sbostic file->i_adapt = file->i_ctlr = file->i_unit = 468*34463Sbostic file->i_part = 0; 469*34463Sbostic break; 470*34463Sbostic } 471*34463Sbostic } 472327Sbill 473*34463Sbostic for (cnt = 0; cnt < sizeof(args)/sizeof(args[0]); args[cnt++] = 0); 474*34463Sbostic #ifndef SMALL 475*34463Sbostic for (t = str; *t && *t != '/' && *t != ':' && *t != '('; ++t) 476*34463Sbostic if (isupper(*t)) 477*34463Sbostic *t = tolower(*t); 478*34463Sbostic switch(*t) { 479*34463Sbostic case '(': /* type(adapt, ctlr, drive, partition)file */ 480*34463Sbostic if ((file->i_ino.i_dev = getdev(str, t - str)) == -1) 48130547Skarels goto bad; 482*34463Sbostic for (argp = args + 4, cnt = 0; *t != ')'; ++cnt) { 483*34463Sbostic for (++t; isspace(*t); ++t); 484*34463Sbostic if (*t == ')') 485*34463Sbostic break; 486*34463Sbostic if (!isdigit(*t)) 48730547Skarels goto badspec; 488*34463Sbostic *argp++ = atoi(t); 489*34463Sbostic for (++t; isdigit(*t); ++t); 490*34463Sbostic if (*t != ',' && *t != ')' || cnt == 4) 491*34463Sbostic goto badspec; 49230547Skarels } 493*34463Sbostic for (++t; isspace(*t); ++t); 494*34463Sbostic argp -= 4; 495*34463Sbostic file->i_adapt = *argp++; 496*34463Sbostic file->i_ctlr = *argp++; 497*34463Sbostic file->i_unit = *argp++; 498*34463Sbostic file->i_part = *argp; 499*34463Sbostic break; 500*34463Sbostic case ':': /* [A-Za-z]*[0-9]*[A-Za-z]:file */ 501*34463Sbostic for (t = str; *t != ':' && !isdigit(*t); ++t); 502*34463Sbostic if ((file->i_ino.i_dev = getdev(str, t - str)) == -1) 50330547Skarels goto bad; 504*34463Sbostic if ((file->i_unit = getunit(t)) == -1) 50530547Skarels goto bad; 506*34463Sbostic for (; isdigit(*t); ++t); 507*34463Sbostic if (*t >= 'a' && *t <= 'h') 508*34463Sbostic file->i_part = *t++ - 'a'; 509*34463Sbostic if (*t != ':') { 51025166Skarels errno = EOFFSET; 51130547Skarels goto badspec; 51225166Skarels } 513*34463Sbostic for (++t; isspace(*t); ++t); 514*34463Sbostic break; 515*34463Sbostic case '/': 516*34463Sbostic default: /* default bootstrap unit and device */ 517*34463Sbostic #else 518*34463Sbostic { 519*34463Sbostic #endif /* SMALL */ 520*34463Sbostic file->i_ino.i_dev = B_TYPE(bootdev); 521*34463Sbostic file->i_adapt = B_ADAPTOR(bootdev); 522*34463Sbostic file->i_ctlr = B_CONTROLLER(bootdev); 523*34463Sbostic file->i_unit = B_UNIT(bootdev); 524*34463Sbostic file->i_part = B_PARTITION(bootdev); 525*34463Sbostic t = str; 52625166Skarels } 527*34463Sbostic 528*34463Sbostic opendev = MAKEBOOTDEV(file->i_ino.i_dev, file->i_adapt, file->i_ctlr, 529*34463Sbostic file->i_unit, file->i_part); 530*34463Sbostic 53130547Skarels if (errno = devopen(file)) 53230547Skarels goto bad; 533*34463Sbostic 534*34463Sbostic if (*t == '\0') { 535*34463Sbostic file->i_flgs |= how + 1; 53625166Skarels file->i_cc = 0; 53725166Skarels file->i_offset = 0; 53825166Skarels return (fdesc+3); 53925166Skarels } 540*34463Sbostic #ifndef SMALL 541*34463Sbostic else if (how != 0) { 542*34463Sbostic printf("Can't write files yet.. Sorry\n"); 543*34463Sbostic errno = EIO; 544*34463Sbostic goto bad; 545*34463Sbostic } 54633408Skarels #endif 5476068Smckusic file->i_ma = (char *)(&file->i_fs); 5486068Smckusic file->i_cc = SBSIZE; 54930768Skarels file->i_bn = SBOFF / DEV_BSIZE + file->i_boff; 5506068Smckusic file->i_offset = 0; 55111083Ssam if (devread(file) < 0) { 55211083Ssam errno = file->i_error; 55311083Ssam printf("super block read error\n"); 55430547Skarels goto bad; 55511083Ssam } 556*34463Sbostic if ((cnt = find(t, file)) == 0) { 55710022Ssam errno = ESRCH; 55830547Skarels goto bad; 559327Sbill } 560*34463Sbostic if (openi(cnt, file) < 0) { 56111083Ssam errno = file->i_error; 56230547Skarels goto bad; 56311083Ssam } 564327Sbill file->i_offset = 0; 565327Sbill file->i_cc = 0; 566327Sbill file->i_flgs |= F_FILE | (how+1); 56710022Ssam return (fdesc+3); 56830547Skarels 56933408Skarels #ifndef SMALL 57030547Skarels badspec: 571*34463Sbostic printf("malformed device specification\nusage: device(adaptor, controller, drive, partition)file\n"); 57233408Skarels #endif 57330547Skarels bad: 57430547Skarels file->i_flgs = 0; 57530547Skarels return (-1); 576327Sbill } 577327Sbill 57830924Skarels #ifndef SMALL 57930547Skarels static 58030547Skarels getdev(str, len) 58133408Skarels register char *str; 58230547Skarels int len; 58330547Skarels { 58430547Skarels register struct devsw *dp; 58533408Skarels register int i; 586*34463Sbostic char savedch = str[len]; 58730547Skarels 588*34463Sbostic str[len] = '\0'; 58933408Skarels for (dp = devsw, i = 0; i < ndevs; dp++, i++) 59033408Skarels if (dp->dv_name && strcmp(str, dp->dv_name) == 0) { 591*34463Sbostic str[len] = savedch; 59233408Skarels return (i); 59333408Skarels } 59433408Skarels printf("Unknown device\nKnown devices are:\n"); 59533408Skarels for (dp = devsw, i = 0; i < ndevs; dp++, i++) 59633408Skarels if (dp->dv_name) 59733408Skarels printf(" %s", dp->dv_name); 598*34463Sbostic printf("\n"); 59930547Skarels errno = ENXIO; 60030547Skarels return (-1); 60130547Skarels } 60230547Skarels 60330547Skarels static 60430547Skarels getunit(cp) 60530547Skarels register char *cp; 60630547Skarels { 607*34463Sbostic int unit; 60830547Skarels 609*34463Sbostic unit = atoi(cp); 610*34463Sbostic if ((u_int)unit > 255) { 61130547Skarels printf("minor device number out of range (0-255)\n"); 61230547Skarels errno = EUNIT; 613*34463Sbostic return (-1); 61430547Skarels } 615*34463Sbostic return (unit); 61630547Skarels } 617*34463Sbostic #endif /* SMALL */ 61830547Skarels 619327Sbill close(fdesc) 62010022Ssam int fdesc; 621327Sbill { 622327Sbill struct iob *file; 623327Sbill 624327Sbill fdesc -= 3; 6256068Smckusic if (fdesc < 0 || fdesc >= NFILES || 62610022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 62710022Ssam errno = EBADF; 62810022Ssam return (-1); 62910022Ssam } 630327Sbill if ((file->i_flgs&F_FILE) == 0) 631327Sbill devclose(file); 632327Sbill file->i_flgs = 0; 63310022Ssam return (0); 634327Sbill } 635327Sbill 636*34463Sbostic #ifndef SMALL 63710022Ssam ioctl(fdesc, cmd, arg) 63810022Ssam int fdesc, cmd; 63910022Ssam char *arg; 64010022Ssam { 64110022Ssam register struct iob *file; 64210022Ssam int error = 0; 64310022Ssam 64410331Shelge fdesc -= 3; 64510022Ssam if (fdesc < 0 || fdesc >= NFILES || 64610022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 64710022Ssam errno = EBADF; 64810022Ssam return (-1); 64910022Ssam } 65010022Ssam switch (cmd) { 65110022Ssam 65210022Ssam case SAIOHDR: 65310022Ssam file->i_flgs |= F_HDR; 65410022Ssam break; 65510022Ssam 65610022Ssam case SAIOCHECK: 65710022Ssam file->i_flgs |= F_CHECK; 65810022Ssam break; 65910022Ssam 66010022Ssam case SAIOHCHECK: 66110022Ssam file->i_flgs |= F_HCHECK; 66210022Ssam break; 66310022Ssam 66410331Shelge case SAIONOBAD: 66510331Shelge file->i_flgs |= F_NBSF; 66610331Shelge break; 66710331Shelge 66810331Shelge case SAIODOBAD: 66910331Shelge file->i_flgs &= ~F_NBSF; 67010331Shelge break; 67110331Shelge 67210022Ssam default: 67310022Ssam error = devioctl(file, cmd, arg); 67410022Ssam break; 67510022Ssam } 67610022Ssam if (error < 0) 67710022Ssam errno = file->i_error; 67810022Ssam return (error); 67910022Ssam } 680*34463Sbostic #endif /* SMALL */ 68110022Ssam 682327Sbill exit() 683327Sbill { 684327Sbill _stop("Exit called"); 685327Sbill } 686327Sbill 687327Sbill _stop(s) 68810022Ssam char *s; 689327Sbill { 6902391Stoy int i; 6912391Stoy 6922391Stoy for (i = 0; i < NFILES; i++) 6932391Stoy if (iob[i].i_flgs != 0) 6942391Stoy close(i); 695327Sbill printf("%s\n", s); 696327Sbill _rtt(); 697327Sbill } 698