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