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