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