|
|
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 "../machine/mtpr.h" ! 8: #include "saio.h" ! 9: ! 10: ino_t dlook(); ! 11: ! 12: struct dirstuff { ! 13: int loc; ! 14: struct iob *io; ! 15: }; ! 16: ! 17: static ! 18: openi(n, io) ! 19: register struct iob *io; ! 20: { ! 21: register struct dinode *dp; ! 22: int cc; ! 23: ! 24: io->i_offset = 0; ! 25: io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; ! 26: io->i_cc = io->i_fs.fs_bsize; ! 27: io->i_ma = io->i_buf; ! 28: cc = devread(io); ! 29: dp = (struct dinode *)io->i_buf; ! 30: io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic; ! 31: return (cc); ! 32: } ! 33: ! 34: static ! 35: find(path, file) ! 36: register char *path; ! 37: struct iob *file; ! 38: { ! 39: register char *q; ! 40: char c; ! 41: int n; ! 42: ! 43: if (path==NULL || *path=='\0') { ! 44: printf("null path\n"); ! 45: return (0); ! 46: } ! 47: ! 48: if (openi((ino_t) ROOTINO, file) < 0) { ! 49: printf("can't read root inode\n"); ! 50: return (0); ! 51: } ! 52: while (*path) { ! 53: while (*path == '/') ! 54: path++; ! 55: q = path; ! 56: while(*q != '/' && *q != '\0') ! 57: q++; ! 58: c = *q; ! 59: *q = '\0'; ! 60: ! 61: if ((n = dlook(path, file)) != 0) { ! 62: if (c == '\0') ! 63: break; ! 64: if (openi(n, file) < 0) ! 65: return (0); ! 66: *q = c; ! 67: path = q; ! 68: continue; ! 69: } else { ! 70: printf("%s not found\n", path); ! 71: return (0); ! 72: } ! 73: } ! 74: return (n); ! 75: } ! 76: ! 77: static daddr_t ! 78: sbmap(io, bn) ! 79: register struct iob *io; ! 80: daddr_t bn; ! 81: { ! 82: register struct inode *ip; ! 83: int i, j, sh; ! 84: daddr_t nb, *bap; ! 85: ! 86: ip = &io->i_ino; ! 87: if (bn < 0) { ! 88: printf("bn negative\n"); ! 89: return ((daddr_t)0); ! 90: } ! 91: ! 92: /* ! 93: * blocks 0..NDADDR are direct blocks ! 94: */ ! 95: if(bn < NDADDR) { ! 96: nb = ip->i_db[bn]; ! 97: return (nb); ! 98: } ! 99: ! 100: /* ! 101: * addresses NIADDR have single and double indirect blocks. ! 102: * the first step is to determine how many levels of indirection. ! 103: */ ! 104: sh = 1; ! 105: bn -= NDADDR; ! 106: for (j = NIADDR; j > 0; j--) { ! 107: sh *= NINDIR(&io->i_fs); ! 108: if (bn < sh) ! 109: break; ! 110: bn -= sh; ! 111: } ! 112: if (j == 0) { ! 113: printf("bn ovf %D\n", bn); ! 114: return ((daddr_t)0); ! 115: } ! 116: ! 117: /* ! 118: * fetch the first indirect block address from the inode ! 119: */ ! 120: nb = ip->i_ib[NIADDR - j]; ! 121: if (nb == 0) { ! 122: printf("bn void %D\n",bn); ! 123: return ((daddr_t)0); ! 124: } ! 125: ! 126: /* ! 127: * fetch through the indirect blocks ! 128: */ ! 129: for (; j <= NIADDR; j++) { ! 130: if (blknos[j] != nb) { ! 131: io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; ! 132: io->i_ma = b[j]; ! 133: io->i_cc = io->i_fs.fs_bsize; ! 134: if (devread(io) != io->i_fs.fs_bsize) { ! 135: if (io->i_error) ! 136: errno = io->i_error; ! 137: printf("bn %D: read error\n", io->i_bn); ! 138: return ((daddr_t)0); ! 139: } ! 140: blknos[j] = nb; ! 141: } ! 142: bap = (daddr_t *)b[j]; ! 143: sh /= NINDIR(&io->i_fs); ! 144: i = (bn / sh) % NINDIR(&io->i_fs); ! 145: nb = bap[i]; ! 146: if(nb == 0) { ! 147: printf("bn void %D\n",bn); ! 148: return ((daddr_t)0); ! 149: } ! 150: } ! 151: return (nb); ! 152: } ! 153: ! 154: static ino_t ! 155: dlook(s, io) ! 156: char *s; ! 157: register struct iob *io; ! 158: { ! 159: register struct direct *dp; ! 160: register struct inode *ip; ! 161: struct dirstuff dirp; ! 162: int len; ! 163: ! 164: if (s == NULL || *s == '\0') ! 165: return (0); ! 166: ip = &io->i_ino; ! 167: if ((ip->i_mode&IFMT) != IFDIR) { ! 168: printf("not a directory\n"); ! 169: return (0); ! 170: } ! 171: if (ip->i_size == 0) { ! 172: printf("zero length directory\n"); ! 173: return (0); ! 174: } ! 175: len = strlen(s); ! 176: dirp.loc = 0; ! 177: dirp.io = io; ! 178: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { ! 179: if(dp->d_ino == 0) ! 180: continue; ! 181: if (dp->d_namlen == len && !strcmp(s, dp->d_name)) ! 182: return (dp->d_ino); ! 183: } ! 184: return (0); ! 185: } ! 186: ! 187: /* ! 188: * get next entry in a directory. ! 189: */ ! 190: struct direct * ! 191: readdir(dirp) ! 192: register struct dirstuff *dirp; ! 193: { ! 194: register struct direct *dp; ! 195: register struct iob *io; ! 196: daddr_t lbn, d; ! 197: int off; ! 198: ! 199: io = dirp->io; ! 200: for(;;) { ! 201: if (dirp->loc >= io->i_ino.i_size) ! 202: return (NULL); ! 203: off = blkoff(&io->i_fs, dirp->loc); ! 204: if (off == 0) { ! 205: lbn = lblkno(&io->i_fs, dirp->loc); ! 206: d = sbmap(io, lbn); ! 207: if(d == 0) ! 208: return NULL; ! 209: io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; ! 210: io->i_ma = io->i_buf; ! 211: io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); ! 212: if (devread(io) < 0) { ! 213: errno = io->i_error; ! 214: printf("bn %D: read error\n", io->i_bn); ! 215: return (NULL); ! 216: } ! 217: } ! 218: dp = (struct direct *)(io->i_buf + off); ! 219: dirp->loc += dp->d_reclen; ! 220: if (dp->d_ino == 0) ! 221: continue; ! 222: return (dp); ! 223: } ! 224: } ! 225: ! 226: lseek(fdesc, addr, ptr) ! 227: int fdesc, ptr; ! 228: off_t addr; ! 229: { ! 230: register struct iob *io; ! 231: ! 232: if (ptr != 0) { ! 233: printf("Seek not from beginning of file\n"); ! 234: errno = EOFFSET; ! 235: return (-1); ! 236: } ! 237: fdesc -= 3; ! 238: if (fdesc < 0 || fdesc >= NFILES || ! 239: ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { ! 240: errno = EBADF; ! 241: return (-1); ! 242: } ! 243: io->i_offset = addr; ! 244: io->i_bn = addr / DEV_BSIZE; ! 245: io->i_cc = 0; ! 246: return (0); ! 247: } ! 248: ! 249: getc(fdesc) ! 250: int fdesc; ! 251: { ! 252: register struct iob *io; ! 253: register struct fs *fs; ! 254: register char *p; ! 255: int c, lbn, off, size, diff; ! 256: ! 257: ! 258: if (fdesc >= 0 && fdesc <= 2) ! 259: return (getchar()); ! 260: fdesc -= 3; ! 261: if (fdesc < 0 || fdesc >= NFILES || ! 262: ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { ! 263: errno = EBADF; ! 264: return (-1); ! 265: } ! 266: p = io->i_ma; ! 267: if (io->i_cc <= 0) { ! 268: if ((io->i_flgs & F_FILE) != 0) { ! 269: diff = io->i_ino.i_size - io->i_offset; ! 270: if (diff <= 0) ! 271: return (-1); ! 272: fs = &io->i_fs; ! 273: lbn = lblkno(fs, io->i_offset); ! 274: io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; ! 275: off = blkoff(fs, io->i_offset); ! 276: size = blksize(fs, &io->i_ino, lbn); ! 277: } else { ! 278: io->i_bn = io->i_offset / DEV_BSIZE; ! 279: off = 0; ! 280: size = DEV_BSIZE; ! 281: } ! 282: io->i_ma = io->i_buf; ! 283: io->i_cc = size; ! 284: if (devread(io) < 0) { ! 285: errno = io->i_error; ! 286: return (-1); ! 287: } ! 288: if ((io->i_flgs & F_FILE) != 0) { ! 289: if (io->i_offset - off + size >= io->i_ino.i_size) ! 290: io->i_cc = diff + off; ! 291: io->i_cc -= off; ! 292: } ! 293: p = &io->i_buf[off]; ! 294: } ! 295: io->i_cc--; ! 296: io->i_offset++; ! 297: c = (unsigned)*p++; ! 298: io->i_ma = p; ! 299: return (c); ! 300: } ! 301: ! 302: /* does this port? ! 303: getw(fdesc) ! 304: int fdesc; ! 305: { ! 306: register w,i; ! 307: int val; ! 308: ! 309: for (i = 0, val = 0; 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: val = (val << 8) | (w & 0xff); ! 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 > 63) { ! 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: file->i_flgs |= how+1; ! 475: devopen(file); ! 476: if (*++cp == '\0') { ! 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: file->i_flgs = 0; ! 489: return (-1); ! 490: } ! 491: if ((i = find(cp, file)) == 0) { ! 492: file->i_flgs = 0; ! 493: errno = ESRCH; ! 494: return (-1); ! 495: } ! 496: if (how != 0) { ! 497: printf("Can't write files yet.. Sorry\n"); ! 498: file->i_flgs = 0; ! 499: errno = EIO; ! 500: return (-1); ! 501: } ! 502: if (openi(i, file) < 0) { ! 503: errno = file->i_error; ! 504: file->i_flgs = 0; ! 505: return (-1); ! 506: } ! 507: file->i_offset = 0; ! 508: file->i_cc = 0; ! 509: file->i_flgs |= F_FILE | (how+1); ! 510: return (fdesc+3); ! 511: } ! 512: ! 513: close(fdesc) ! 514: int fdesc; ! 515: { ! 516: struct iob *file; ! 517: ! 518: fdesc -= 3; ! 519: if (fdesc < 0 || fdesc >= NFILES || ! 520: ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { ! 521: errno = EBADF; ! 522: return (-1); ! 523: } ! 524: if ((file->i_flgs&F_FILE) == 0) ! 525: devclose(file); ! 526: file->i_flgs = 0; ! 527: return (0); ! 528: } ! 529: ! 530: ! 531: exit() ! 532: { ! 533: _stop("Exit called"); ! 534: } ! 535: ! 536: _stop(s) ! 537: char *s; ! 538: { ! 539: int i; ! 540: ! 541: for (i = 0; i < NFILES; i++) ! 542: if (iob[i].i_flgs != 0) ! 543: close(i); ! 544: printf("%s\n", s); ! 545: _rtt(); ! 546: } ! 547: ! 548: trap(ps) ! 549: int ps; ! 550: { ! 551: printf("Trap %o\n", ps); ! 552: for (;;) ! 553: ; ! 554: } ! 555: ! 556: uncache (addr) ! 557: char *addr; ! 558: { ! 559: /* Return *(addr-0x4000); DIRTY assumes this address is valid */ ! 560: mtpr (addr, PDCS); ! 561: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.