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