1*41488Smckusick /* 2*41488Smckusick * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 3*41488Smckusick * All rights reserved. 4*41488Smckusick * 5*41488Smckusick * %sccs.include.redist.c% 6*41488Smckusick * 7*41488Smckusick * @(#)sys.c 7.1 (Berkeley) 05/08/90 8*41488Smckusick */ 9*41488Smckusick 10*41488Smckusick #include "saio.h" 11*41488Smckusick #include "ufs/dir.h" 12*41488Smckusick #ifndef SMALL 13*41488Smckusick #include "sys/stat.h" 14*41488Smckusick #endif 15*41488Smckusick 16*41488Smckusick ino_t dlook(); 17*41488Smckusick 18*41488Smckusick struct dirstuff { 19*41488Smckusick int loc; 20*41488Smckusick struct iob *io; 21*41488Smckusick }; 22*41488Smckusick 23*41488Smckusick static 24*41488Smckusick openi(n, io) 25*41488Smckusick register struct iob *io; 26*41488Smckusick { 27*41488Smckusick register struct dinode *dp; 28*41488Smckusick int cc; 29*41488Smckusick 30*41488Smckusick io->i_offset = 0; 31*41488Smckusick io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 32*41488Smckusick io->i_cc = io->i_fs.fs_bsize; 33*41488Smckusick io->i_ma = io->i_buf; 34*41488Smckusick cc = devread(io); 35*41488Smckusick dp = (struct dinode *)io->i_buf; 36*41488Smckusick io->i_ino.i_din = dp[itoo(&io->i_fs, n)]; 37*41488Smckusick return (cc); 38*41488Smckusick } 39*41488Smckusick 40*41488Smckusick static 41*41488Smckusick find(path, file) 42*41488Smckusick register char *path; 43*41488Smckusick struct iob *file; 44*41488Smckusick { 45*41488Smckusick register char *q; 46*41488Smckusick char c; 47*41488Smckusick int n; 48*41488Smckusick 49*41488Smckusick if (path==NULL || *path=='\0') { 50*41488Smckusick printf("null path\n"); 51*41488Smckusick return (0); 52*41488Smckusick } 53*41488Smckusick 54*41488Smckusick if (openi((ino_t) ROOTINO, file) < 0) { 55*41488Smckusick printf("can't read root inode\n"); 56*41488Smckusick return (0); 57*41488Smckusick } 58*41488Smckusick while (*path) { 59*41488Smckusick while (*path == '/') 60*41488Smckusick path++; 61*41488Smckusick q = path; 62*41488Smckusick while(*q != '/' && *q != '\0') 63*41488Smckusick q++; 64*41488Smckusick c = *q; 65*41488Smckusick *q = '\0'; 66*41488Smckusick if (q == path) path = "." ; /* "/" means "/." */ 67*41488Smckusick 68*41488Smckusick if ((n = dlook(path, file)) != 0) { 69*41488Smckusick if (c == '\0') 70*41488Smckusick break; 71*41488Smckusick if (openi(n, file) < 0) 72*41488Smckusick return (0); 73*41488Smckusick *q = c; 74*41488Smckusick path = q; 75*41488Smckusick continue; 76*41488Smckusick } else { 77*41488Smckusick printf("%s: not found\n", path); 78*41488Smckusick return (0); 79*41488Smckusick } 80*41488Smckusick } 81*41488Smckusick return (n); 82*41488Smckusick } 83*41488Smckusick 84*41488Smckusick static daddr_t 85*41488Smckusick sbmap(io, bn) 86*41488Smckusick register struct iob *io; 87*41488Smckusick daddr_t bn; 88*41488Smckusick { 89*41488Smckusick register struct inode *ip; 90*41488Smckusick int i, j, sh; 91*41488Smckusick daddr_t nb, *bap; 92*41488Smckusick 93*41488Smckusick ip = &io->i_ino; 94*41488Smckusick if (bn < 0) { 95*41488Smckusick printf("bn negative\n"); 96*41488Smckusick return ((daddr_t)0); 97*41488Smckusick } 98*41488Smckusick 99*41488Smckusick /* 100*41488Smckusick * blocks 0..NDADDR are direct blocks 101*41488Smckusick */ 102*41488Smckusick if(bn < NDADDR) { 103*41488Smckusick nb = ip->i_db[bn]; 104*41488Smckusick return (nb); 105*41488Smckusick } 106*41488Smckusick 107*41488Smckusick /* 108*41488Smckusick * addresses NIADDR have single and double indirect blocks. 109*41488Smckusick * the first step is to determine how many levels of indirection. 110*41488Smckusick */ 111*41488Smckusick sh = 1; 112*41488Smckusick bn -= NDADDR; 113*41488Smckusick for (j = NIADDR; j > 0; j--) { 114*41488Smckusick sh *= NINDIR(&io->i_fs); 115*41488Smckusick if (bn < sh) 116*41488Smckusick break; 117*41488Smckusick bn -= sh; 118*41488Smckusick } 119*41488Smckusick if (j == 0) { 120*41488Smckusick printf("bn ovf %D\n", bn); 121*41488Smckusick return ((daddr_t)0); 122*41488Smckusick } 123*41488Smckusick 124*41488Smckusick /* 125*41488Smckusick * fetch the first indirect block address from the inode 126*41488Smckusick */ 127*41488Smckusick nb = ip->i_ib[NIADDR - j]; 128*41488Smckusick if (nb == 0) { 129*41488Smckusick printf("bn void %D\n",bn); 130*41488Smckusick return ((daddr_t)0); 131*41488Smckusick } 132*41488Smckusick 133*41488Smckusick /* 134*41488Smckusick * fetch through the indirect blocks 135*41488Smckusick */ 136*41488Smckusick for (; j <= NIADDR; j++) { 137*41488Smckusick if (blknos[j] != nb) { 138*41488Smckusick io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 139*41488Smckusick io->i_ma = b[j]; 140*41488Smckusick io->i_cc = io->i_fs.fs_bsize; 141*41488Smckusick if (devread(io) != io->i_fs.fs_bsize) { 142*41488Smckusick if (io->i_error) 143*41488Smckusick errno = io->i_error; 144*41488Smckusick printf("bn %D: read error\n", io->i_bn); 145*41488Smckusick return ((daddr_t)0); 146*41488Smckusick } 147*41488Smckusick blknos[j] = nb; 148*41488Smckusick } 149*41488Smckusick bap = (daddr_t *)b[j]; 150*41488Smckusick sh /= NINDIR(&io->i_fs); 151*41488Smckusick i = (bn / sh) % NINDIR(&io->i_fs); 152*41488Smckusick nb = bap[i]; 153*41488Smckusick if(nb == 0) { 154*41488Smckusick printf("bn void %D\n",bn); 155*41488Smckusick return ((daddr_t)0); 156*41488Smckusick } 157*41488Smckusick } 158*41488Smckusick return (nb); 159*41488Smckusick } 160*41488Smckusick 161*41488Smckusick static ino_t 162*41488Smckusick dlook(s, io) 163*41488Smckusick char *s; 164*41488Smckusick register struct iob *io; 165*41488Smckusick { 166*41488Smckusick register struct direct *dp; 167*41488Smckusick register struct inode *ip; 168*41488Smckusick struct dirstuff dirp; 169*41488Smckusick int len; 170*41488Smckusick 171*41488Smckusick if (s == NULL || *s == '\0') 172*41488Smckusick return (0); 173*41488Smckusick ip = &io->i_ino; 174*41488Smckusick if ((ip->i_mode&IFMT) != IFDIR) { 175*41488Smckusick printf("not a directory\n"); 176*41488Smckusick printf("%s: not a directory\n", s); 177*41488Smckusick return (0); 178*41488Smckusick } 179*41488Smckusick if (ip->i_size == 0) { 180*41488Smckusick printf("%s: zero length directory\n", s); 181*41488Smckusick return (0); 182*41488Smckusick } 183*41488Smckusick len = strlen(s); 184*41488Smckusick dirp.loc = 0; 185*41488Smckusick dirp.io = io; 186*41488Smckusick for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 187*41488Smckusick if(dp->d_ino == 0) 188*41488Smckusick continue; 189*41488Smckusick if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 190*41488Smckusick return (dp->d_ino); 191*41488Smckusick } 192*41488Smckusick return (0); 193*41488Smckusick } 194*41488Smckusick 195*41488Smckusick /* 196*41488Smckusick * get next entry in a directory. 197*41488Smckusick */ 198*41488Smckusick struct direct * 199*41488Smckusick readdir(dirp) 200*41488Smckusick register struct dirstuff *dirp; 201*41488Smckusick { 202*41488Smckusick register struct direct *dp; 203*41488Smckusick register struct iob *io; 204*41488Smckusick daddr_t lbn, d; 205*41488Smckusick int off; 206*41488Smckusick 207*41488Smckusick io = dirp->io; 208*41488Smckusick for(;;) { 209*41488Smckusick if (dirp->loc >= io->i_ino.i_size) 210*41488Smckusick return (NULL); 211*41488Smckusick off = blkoff(&io->i_fs, dirp->loc); 212*41488Smckusick if (off == 0) { 213*41488Smckusick lbn = lblkno(&io->i_fs, dirp->loc); 214*41488Smckusick d = sbmap(io, lbn); 215*41488Smckusick if(d == 0) 216*41488Smckusick return NULL; 217*41488Smckusick io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 218*41488Smckusick io->i_ma = io->i_buf; 219*41488Smckusick io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); 220*41488Smckusick if (devread(io) < 0) { 221*41488Smckusick errno = io->i_error; 222*41488Smckusick printf("bn %D: directory read error\n", 223*41488Smckusick io->i_bn); 224*41488Smckusick return (NULL); 225*41488Smckusick } 226*41488Smckusick } 227*41488Smckusick dp = (struct direct *)(io->i_buf + off); 228*41488Smckusick dirp->loc += dp->d_reclen; 229*41488Smckusick if (dp->d_ino == 0) 230*41488Smckusick continue; 231*41488Smckusick return (dp); 232*41488Smckusick } 233*41488Smckusick } 234*41488Smckusick 235*41488Smckusick lseek(fdesc, addr, ptr) 236*41488Smckusick int fdesc, ptr; 237*41488Smckusick off_t addr; 238*41488Smckusick { 239*41488Smckusick register struct iob *io; 240*41488Smckusick 241*41488Smckusick #ifndef SMALL 242*41488Smckusick if (ptr != 0) { 243*41488Smckusick printf("Seek not from beginning of file\n"); 244*41488Smckusick errno = EOFFSET; 245*41488Smckusick return (-1); 246*41488Smckusick } 247*41488Smckusick #endif SMALL 248*41488Smckusick fdesc -= 3; 249*41488Smckusick if (fdesc < 0 || fdesc >= NFILES || 250*41488Smckusick ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 251*41488Smckusick errno = EBADF; 252*41488Smckusick return (-1); 253*41488Smckusick } 254*41488Smckusick io->i_offset = addr; 255*41488Smckusick io->i_bn = addr / DEV_BSIZE; 256*41488Smckusick io->i_cc = 0; 257*41488Smckusick return (0); 258*41488Smckusick } 259*41488Smckusick 260*41488Smckusick getc(fdesc) 261*41488Smckusick int fdesc; 262*41488Smckusick { 263*41488Smckusick register struct iob *io; 264*41488Smckusick register struct fs *fs; 265*41488Smckusick register char *p; 266*41488Smckusick int c, lbn, off, size, diff; 267*41488Smckusick 268*41488Smckusick 269*41488Smckusick if (fdesc >= 0 && fdesc <= 2) 270*41488Smckusick return (getchar()); 271*41488Smckusick fdesc -= 3; 272*41488Smckusick if (fdesc < 0 || fdesc >= NFILES || 273*41488Smckusick ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 274*41488Smckusick errno = EBADF; 275*41488Smckusick return (-1); 276*41488Smckusick } 277*41488Smckusick p = io->i_ma; 278*41488Smckusick if (io->i_cc <= 0) { 279*41488Smckusick if ((io->i_flgs & F_FILE) != 0) { 280*41488Smckusick diff = io->i_ino.i_size - io->i_offset; 281*41488Smckusick if (diff <= 0) 282*41488Smckusick return (-1); 283*41488Smckusick fs = &io->i_fs; 284*41488Smckusick lbn = lblkno(fs, io->i_offset); 285*41488Smckusick io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 286*41488Smckusick off = blkoff(fs, io->i_offset); 287*41488Smckusick size = blksize(fs, &io->i_ino, lbn); 288*41488Smckusick } else { 289*41488Smckusick io->i_bn = io->i_offset / DEV_BSIZE; 290*41488Smckusick off = 0; 291*41488Smckusick size = DEV_BSIZE; 292*41488Smckusick } 293*41488Smckusick io->i_ma = io->i_buf; 294*41488Smckusick io->i_cc = size; 295*41488Smckusick if (devread(io) < 0) { 296*41488Smckusick errno = io->i_error; 297*41488Smckusick return (-1); 298*41488Smckusick } 299*41488Smckusick if ((io->i_flgs & F_FILE) != 0) { 300*41488Smckusick if (io->i_offset - off + size >= io->i_ino.i_size) 301*41488Smckusick io->i_cc = diff + off; 302*41488Smckusick io->i_cc -= off; 303*41488Smckusick } 304*41488Smckusick p = &io->i_buf[off]; 305*41488Smckusick } 306*41488Smckusick io->i_cc--; 307*41488Smckusick io->i_offset++; 308*41488Smckusick c = (unsigned)*p++; 309*41488Smckusick io->i_ma = p; 310*41488Smckusick return (c); 311*41488Smckusick } 312*41488Smckusick 313*41488Smckusick int errno; 314*41488Smckusick 315*41488Smckusick read(fdesc, buf, count) 316*41488Smckusick int fdesc, count; 317*41488Smckusick char *buf; 318*41488Smckusick { 319*41488Smckusick register i, size; 320*41488Smckusick register struct iob *file; 321*41488Smckusick register struct fs *fs; 322*41488Smckusick int lbn, off; 323*41488Smckusick 324*41488Smckusick errno = 0; 325*41488Smckusick if (fdesc >= 0 & fdesc <= 2) { 326*41488Smckusick i = count; 327*41488Smckusick do { 328*41488Smckusick *buf = getchar(); 329*41488Smckusick } while (--i && *buf++ != '\n'); 330*41488Smckusick return (count - i); 331*41488Smckusick } 332*41488Smckusick fdesc -= 3; 333*41488Smckusick if (fdesc < 0 || fdesc >= NFILES || 334*41488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 335*41488Smckusick errno = EBADF; 336*41488Smckusick return (-1); 337*41488Smckusick } 338*41488Smckusick if ((file->i_flgs&F_READ) == 0) { 339*41488Smckusick errno = EBADF; 340*41488Smckusick return (-1); 341*41488Smckusick } 342*41488Smckusick #ifndef SMALL 343*41488Smckusick if ((file->i_flgs & F_FILE) == 0) { 344*41488Smckusick file->i_cc = count; 345*41488Smckusick file->i_ma = buf; 346*41488Smckusick file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 347*41488Smckusick i = devread(file); 348*41488Smckusick file->i_offset += count; 349*41488Smckusick if (i < 0) 350*41488Smckusick errno = file->i_error; 351*41488Smckusick return (i); 352*41488Smckusick } 353*41488Smckusick #endif SMALL 354*41488Smckusick if (file->i_offset+count > file->i_ino.i_size) 355*41488Smckusick count = file->i_ino.i_size - file->i_offset; 356*41488Smckusick if ((i = count) <= 0) 357*41488Smckusick return (0); 358*41488Smckusick /* 359*41488Smckusick * While reading full blocks, do I/O into user buffer. 360*41488Smckusick * Anything else uses getc(). 361*41488Smckusick */ 362*41488Smckusick fs = &file->i_fs; 363*41488Smckusick while (i) { 364*41488Smckusick off = blkoff(fs, file->i_offset); 365*41488Smckusick lbn = lblkno(fs, file->i_offset); 366*41488Smckusick size = blksize(fs, &file->i_ino, lbn); 367*41488Smckusick if (off == 0 && size <= i) { 368*41488Smckusick file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 369*41488Smckusick file->i_boff; 370*41488Smckusick file->i_cc = size; 371*41488Smckusick file->i_ma = buf; 372*41488Smckusick if (devread(file) < 0) { 373*41488Smckusick errno = file->i_error; 374*41488Smckusick return (-1); 375*41488Smckusick } 376*41488Smckusick file->i_offset += size; 377*41488Smckusick file->i_cc = 0; 378*41488Smckusick buf += size; 379*41488Smckusick i -= size; 380*41488Smckusick } else { 381*41488Smckusick size -= off; 382*41488Smckusick if (size > i) 383*41488Smckusick size = i; 384*41488Smckusick i -= size; 385*41488Smckusick do { 386*41488Smckusick *buf++ = getc(fdesc+3); 387*41488Smckusick } while (--size); 388*41488Smckusick } 389*41488Smckusick } 390*41488Smckusick return (count); 391*41488Smckusick } 392*41488Smckusick 393*41488Smckusick #ifndef SMALL 394*41488Smckusick write(fdesc, buf, count) 395*41488Smckusick int fdesc, count; 396*41488Smckusick char *buf; 397*41488Smckusick { 398*41488Smckusick register i; 399*41488Smckusick register struct iob *file; 400*41488Smckusick 401*41488Smckusick errno = 0; 402*41488Smckusick if (fdesc >= 0 && fdesc <= 2) { 403*41488Smckusick i = count; 404*41488Smckusick while (i--) 405*41488Smckusick putchar(0, *buf++); 406*41488Smckusick return (count); 407*41488Smckusick } 408*41488Smckusick fdesc -= 3; 409*41488Smckusick if (fdesc < 0 || fdesc >= NFILES || 410*41488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 411*41488Smckusick errno = EBADF; 412*41488Smckusick return (-1); 413*41488Smckusick } 414*41488Smckusick if ((file->i_flgs&F_WRITE) == 0) { 415*41488Smckusick errno = EBADF; 416*41488Smckusick return (-1); 417*41488Smckusick } 418*41488Smckusick file->i_cc = count; 419*41488Smckusick file->i_ma = buf; 420*41488Smckusick file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 421*41488Smckusick i = devwrite(file); 422*41488Smckusick file->i_offset += count; 423*41488Smckusick if (i < 0) 424*41488Smckusick errno = file->i_error; 425*41488Smckusick return (i); 426*41488Smckusick } 427*41488Smckusick #endif SMALL 428*41488Smckusick 429*41488Smckusick int openfirst = 1; 430*41488Smckusick #ifdef notyet 431*41488Smckusick int opendev; /* last device opened; for boot to set bootdev */ 432*41488Smckusick extern int bootdev; 433*41488Smckusick #endif notyet 434*41488Smckusick 435*41488Smckusick open(str, how) 436*41488Smckusick char *str; 437*41488Smckusick int how; 438*41488Smckusick { 439*41488Smckusick register char *cp; 440*41488Smckusick int i; 441*41488Smckusick register struct iob *file; 442*41488Smckusick register struct devsw *dp; 443*41488Smckusick int fdesc; 444*41488Smckusick long atol(); 445*41488Smckusick 446*41488Smckusick if (openfirst) { 447*41488Smckusick for (i = 0; i < NFILES; i++) 448*41488Smckusick iob[i].i_flgs = 0; 449*41488Smckusick openfirst = 0; 450*41488Smckusick } 451*41488Smckusick 452*41488Smckusick for (fdesc = 0; fdesc < NFILES; fdesc++) 453*41488Smckusick if (iob[fdesc].i_flgs == 0) 454*41488Smckusick goto gotfile; 455*41488Smckusick _stop("No more file slots"); 456*41488Smckusick gotfile: 457*41488Smckusick (file = &iob[fdesc])->i_flgs |= F_ALLOC; 458*41488Smckusick 459*41488Smckusick #ifdef notyet 460*41488Smckusick for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++) 461*41488Smckusick ; 462*41488Smckusick if (*cp != ':') { 463*41488Smckusick /* default bootstrap unit and device */ 464*41488Smckusick file->i_ino.i_dev = bootdev; 465*41488Smckusick cp = str; 466*41488Smckusick } else { 467*41488Smckusick # define isdigit(n) ((n>='0') && (n<='9')) 468*41488Smckusick /* 469*41488Smckusick * syntax for possible device name: 470*41488Smckusick * <alpha-string><digit-string><letter>: 471*41488Smckusick */ 472*41488Smckusick for (cp = str; *cp != ':' && !isdigit(*cp); cp++) 473*41488Smckusick ; 474*41488Smckusick for (dp = devsw; dp->dv_name; dp++) { 475*41488Smckusick if (!strncmp(str, dp->dv_name,cp-str)) 476*41488Smckusick goto gotdev; 477*41488Smckusick } 478*41488Smckusick printf("unknown device\n"); 479*41488Smckusick file->i_flgs = 0; 480*41488Smckusick errno = EDEV; 481*41488Smckusick return (-1); 482*41488Smckusick gotdev: 483*41488Smckusick i = 0; 484*41488Smckusick while (*cp >= '0' && *cp <= '9') 485*41488Smckusick i = i * 10 + *cp++ - '0'; 486*41488Smckusick if (i < 0 || i > 255) { 487*41488Smckusick printf("minor device number out of range (0-255)\n"); 488*41488Smckusick file->i_flgs = 0; 489*41488Smckusick errno = EUNIT; 490*41488Smckusick return (-1); 491*41488Smckusick } 492*41488Smckusick if (*cp >= 'a' && *cp <= 'h') { 493*41488Smckusick if (i > 31) { 494*41488Smckusick printf("unit number out of range (0-31)\n"); 495*41488Smckusick file->i_flgs = 0; 496*41488Smckusick errno = EUNIT; 497*41488Smckusick return (-1); 498*41488Smckusick } 499*41488Smckusick i = make_minor(i, *cp++ - 'a'); 500*41488Smckusick } 501*41488Smckusick 502*41488Smckusick if (*cp++ != ':') { 503*41488Smckusick printf("incorrect device specification\n"); 504*41488Smckusick file->i_flgs = 0; 505*41488Smckusick errno = EOFFSET; 506*41488Smckusick return (-1); 507*41488Smckusick } 508*41488Smckusick opendev = file->i_ino.i_dev = makedev(dp-devsw, i); 509*41488Smckusick } 510*41488Smckusick file->i_boff = 0; 511*41488Smckusick devopen(file); 512*41488Smckusick if (cp != str && *cp == '\0') { 513*41488Smckusick file->i_flgs |= how+1; 514*41488Smckusick file->i_cc = 0; 515*41488Smckusick file->i_offset = 0; 516*41488Smckusick return (fdesc+3); 517*41488Smckusick } 518*41488Smckusick #else notyet 519*41488Smckusick for (cp = str; *cp && *cp != '('; cp++) 520*41488Smckusick ; 521*41488Smckusick if (*cp != '(') { 522*41488Smckusick printf("Bad device\n"); 523*41488Smckusick file->i_flgs = 0; 524*41488Smckusick errno = EDEV; 525*41488Smckusick return (-1); 526*41488Smckusick } 527*41488Smckusick *cp = '\0'; 528*41488Smckusick for (dp = devsw; dp->dv_name; dp++) 529*41488Smckusick if (!strcmp(str, dp->dv_name)) 530*41488Smckusick break; 531*41488Smckusick *cp++ = '('; 532*41488Smckusick if (dp->dv_name == NULL) { 533*41488Smckusick printf("Unknown device\n"); 534*41488Smckusick file->i_flgs = 0; 535*41488Smckusick errno = ENXIO; 536*41488Smckusick return (-1); 537*41488Smckusick } 538*41488Smckusick file->i_ino.i_dev = dp-devsw; 539*41488Smckusick file->i_unit = *cp++ - '0'; 540*41488Smckusick if (*cp >= '0' && *cp <= '9') 541*41488Smckusick file->i_unit = file->i_unit * 10 + *cp++ - '0'; 542*41488Smckusick if (file->i_unit < 0 || file->i_unit > 63) { 543*41488Smckusick printf("Bad unit specifier\n"); 544*41488Smckusick file->i_flgs = 0; 545*41488Smckusick errno = EUNIT; 546*41488Smckusick return (-1); 547*41488Smckusick } 548*41488Smckusick if (*cp++ != ',') { 549*41488Smckusick badoff: 550*41488Smckusick printf("Missing offset specification\n"); 551*41488Smckusick file->i_flgs = 0; 552*41488Smckusick errno = EOFFSET; 553*41488Smckusick return (-1); 554*41488Smckusick } 555*41488Smckusick file->i_boff = atol(cp); 556*41488Smckusick for (;;) { 557*41488Smckusick if (*cp == ')') 558*41488Smckusick break; 559*41488Smckusick if (*cp++) 560*41488Smckusick continue; 561*41488Smckusick goto badoff; 562*41488Smckusick } 563*41488Smckusick devopen(file); 564*41488Smckusick if (*++cp == '\0') { 565*41488Smckusick file->i_flgs |= how+1; 566*41488Smckusick file->i_cc = 0; 567*41488Smckusick file->i_offset = 0; 568*41488Smckusick return (fdesc+3); 569*41488Smckusick } 570*41488Smckusick #endif notyet 571*41488Smckusick file->i_ma = (char *)(&file->i_fs); 572*41488Smckusick file->i_cc = SBSIZE; 573*41488Smckusick file->i_bn = SBLOCK + file->i_boff; 574*41488Smckusick file->i_offset = 0; 575*41488Smckusick if (devread(file) < 0) { 576*41488Smckusick errno = file->i_error; 577*41488Smckusick printf("super block read error\n"); 578*41488Smckusick return (-1); 579*41488Smckusick } 580*41488Smckusick if ((i = find(cp, file)) == 0) { 581*41488Smckusick file->i_flgs = 0; 582*41488Smckusick errno = ESRCH; 583*41488Smckusick return (-1); 584*41488Smckusick } 585*41488Smckusick #ifndef SMALL 586*41488Smckusick if (how != 0) { 587*41488Smckusick printf("Can't write files yet.. Sorry\n"); 588*41488Smckusick file->i_flgs = 0; 589*41488Smckusick errno = EIO; 590*41488Smckusick return (-1); 591*41488Smckusick } 592*41488Smckusick #endif SMALL 593*41488Smckusick if (openi(i, file) < 0) { 594*41488Smckusick errno = file->i_error; 595*41488Smckusick return (-1); 596*41488Smckusick } 597*41488Smckusick file->i_offset = 0; 598*41488Smckusick file->i_cc = 0; 599*41488Smckusick file->i_flgs |= F_FILE | (how+1); 600*41488Smckusick return (fdesc+3); 601*41488Smckusick } 602*41488Smckusick 603*41488Smckusick close(fdesc) 604*41488Smckusick int fdesc; 605*41488Smckusick { 606*41488Smckusick struct iob *file; 607*41488Smckusick 608*41488Smckusick fdesc -= 3; 609*41488Smckusick if (fdesc < 0 || fdesc >= NFILES || 610*41488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 611*41488Smckusick errno = EBADF; 612*41488Smckusick return (-1); 613*41488Smckusick } 614*41488Smckusick if ((file->i_flgs&F_FILE) == 0) 615*41488Smckusick devclose(file); 616*41488Smckusick file->i_flgs = 0; 617*41488Smckusick return (0); 618*41488Smckusick } 619*41488Smckusick 620*41488Smckusick exit() 621*41488Smckusick { 622*41488Smckusick _stop("Exit called"); 623*41488Smckusick } 624*41488Smckusick 625*41488Smckusick _stop(s) 626*41488Smckusick char *s; 627*41488Smckusick { 628*41488Smckusick static int stopped = 0; 629*41488Smckusick int i; 630*41488Smckusick 631*41488Smckusick if (!stopped) { 632*41488Smckusick stopped++; 633*41488Smckusick for (i = 0; i < NFILES; i++) 634*41488Smckusick if (iob[i].i_flgs != 0) 635*41488Smckusick close(i); 636*41488Smckusick } 637*41488Smckusick printf("%s\n", s); 638*41488Smckusick _rtt(); 639*41488Smckusick } 640*41488Smckusick 641*41488Smckusick #ifndef SMALL 642*41488Smckusick ioctl(fdesc, cmd, arg) 643*41488Smckusick int fdesc, cmd; 644*41488Smckusick char *arg; 645*41488Smckusick { 646*41488Smckusick register struct iob *file; 647*41488Smckusick int error = 0; 648*41488Smckusick 649*41488Smckusick fdesc -= 3; 650*41488Smckusick if (fdesc < 0 || fdesc >= NFILES || 651*41488Smckusick ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 652*41488Smckusick errno = EBADF; 653*41488Smckusick return (-1); 654*41488Smckusick } 655*41488Smckusick switch (cmd) { 656*41488Smckusick 657*41488Smckusick case SAIOHDR: 658*41488Smckusick file->i_flgs |= F_HDR; 659*41488Smckusick break; 660*41488Smckusick 661*41488Smckusick case SAIOCHECK: 662*41488Smckusick file->i_flgs |= F_CHECK; 663*41488Smckusick break; 664*41488Smckusick 665*41488Smckusick case SAIOHCHECK: 666*41488Smckusick file->i_flgs |= F_HCHECK; 667*41488Smckusick break; 668*41488Smckusick 669*41488Smckusick case SAIONOBAD: 670*41488Smckusick file->i_flgs |= F_NBSF; 671*41488Smckusick break; 672*41488Smckusick 673*41488Smckusick case SAIODOBAD: 674*41488Smckusick file->i_flgs &= ~F_NBSF; 675*41488Smckusick break; 676*41488Smckusick 677*41488Smckusick default: 678*41488Smckusick error = devioctl(file, cmd, arg); 679*41488Smckusick break; 680*41488Smckusick } 681*41488Smckusick if (error < 0) 682*41488Smckusick errno = file->i_error; 683*41488Smckusick return (error); 684*41488Smckusick } 685*41488Smckusick 686*41488Smckusick extern char end; 687*41488Smckusick static caddr_t theend = 0; 688*41488Smckusick 689*41488Smckusick caddr_t 690*41488Smckusick brk(addr) 691*41488Smckusick char *addr; 692*41488Smckusick { 693*41488Smckusick char stkloc; 694*41488Smckusick 695*41488Smckusick if (theend == (caddr_t)0) 696*41488Smckusick theend = &end; 697*41488Smckusick if (addr > &stkloc || addr < &end) 698*41488Smckusick return((caddr_t)-1); 699*41488Smckusick if (addr > theend) 700*41488Smckusick bzero(theend, addr-theend); 701*41488Smckusick theend = addr; 702*41488Smckusick return(0); 703*41488Smckusick } 704*41488Smckusick 705*41488Smckusick caddr_t 706*41488Smckusick sbrk(incr) 707*41488Smckusick int incr; 708*41488Smckusick { 709*41488Smckusick caddr_t obrk, brk(); 710*41488Smckusick 711*41488Smckusick if (theend == (caddr_t)0) 712*41488Smckusick theend = &end; 713*41488Smckusick obrk = theend; 714*41488Smckusick if (brk(theend+incr) == (caddr_t)-1) 715*41488Smckusick return((caddr_t)-1); 716*41488Smckusick return(obrk); 717*41488Smckusick } 718*41488Smckusick 719*41488Smckusick getpagesize() 720*41488Smckusick { 721*41488Smckusick return(NBPG); 722*41488Smckusick } 723*41488Smckusick 724*41488Smckusick getdtablesize() 725*41488Smckusick { 726*41488Smckusick return(NFILES); 727*41488Smckusick } 728*41488Smckusick 729*41488Smckusick fstat(fdesc, sb) 730*41488Smckusick struct stat *sb; 731*41488Smckusick { 732*41488Smckusick register struct iob *io; 733*41488Smckusick 734*41488Smckusick fdesc -= 3; 735*41488Smckusick if (fdesc < 0 || fdesc >= NFILES || 736*41488Smckusick ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 737*41488Smckusick errno = EBADF; 738*41488Smckusick return (-1); 739*41488Smckusick } 740*41488Smckusick /* only important stuff */ 741*41488Smckusick sb->st_mode = io->i_ino.i_mode; 742*41488Smckusick sb->st_uid = io->i_ino.i_uid; 743*41488Smckusick sb->st_gid = io->i_ino.i_gid; 744*41488Smckusick sb->st_size = io->i_ino.i_size; 745*41488Smckusick return (0); 746*41488Smckusick } 747*41488Smckusick 748*41488Smckusick stat(str, sb) 749*41488Smckusick { 750*41488Smckusick /* the easy way */ 751*41488Smckusick int f, rv = 0; 752*41488Smckusick 753*41488Smckusick f = open(str, 0); 754*41488Smckusick if (f < 0 || fstat(f, sb) < 0) 755*41488Smckusick rv = -1; 756*41488Smckusick (void) close(f); 757*41488Smckusick return(rv); 758*41488Smckusick } 759*41488Smckusick 760*41488Smckusick #endif SMALL 761