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