1*3349Swnj /* sys.c 4.4 81/03/22 */ 2327Sbill 3327Sbill #include <sys/param.h> 4327Sbill #include <sys/ino.h> 5327Sbill #include <sys/inode.h> 6327Sbill #include <sys/filsys.h> 7327Sbill #include <sys/dir.h> 8327Sbill #include "saio.h" 9327Sbill 10327Sbill ino_t dlook(); 11327Sbill 12327Sbill static 13327Sbill openi(n,io) 14327Sbill register struct iob *io; 15327Sbill { 16327Sbill register struct dinode *dp; 17327Sbill 18327Sbill io->i_offset = 0; 19327Sbill io->i_bn = fsbtodb(itod(n)) + io->i_boff; 20327Sbill io->i_cc = BSIZE; 21327Sbill io->i_ma = io->i_buf; 22327Sbill devread(io); 23327Sbill 24327Sbill dp = (struct dinode *)io->i_buf; 25327Sbill dp = &dp[itoo(n)]; 26327Sbill io->i_ino.i_number = n; 27327Sbill io->i_ino.i_mode = dp->di_mode; 28327Sbill io->i_ino.i_size = dp->di_size; 29327Sbill l3tol((char *)io->i_ino.i_un.i_addr, (char *)dp->di_addr, NADDR); 30327Sbill } 31327Sbill 32327Sbill static 33327Sbill find(path, file) 34327Sbill register char *path; 35327Sbill struct iob *file; 36327Sbill { 37327Sbill register char *q; 38327Sbill char c; 39327Sbill int n; 40327Sbill 41327Sbill if (path==NULL || *path=='\0') { 42327Sbill printf("null path\n"); 43327Sbill return(0); 44327Sbill } 45327Sbill 46327Sbill openi((ino_t) ROOTINO, file); 47327Sbill while (*path) { 48327Sbill while (*path == '/') 49327Sbill path++; 50327Sbill q = path; 51327Sbill while(*q != '/' && *q != '\0') 52327Sbill q++; 53327Sbill c = *q; 54327Sbill *q = '\0'; 55327Sbill 56327Sbill if ((n=dlook(path, file))!=0) { 57327Sbill if (c=='\0') 58327Sbill break; 59327Sbill openi(n, file); 60327Sbill *q = c; 61327Sbill path = q; 62327Sbill continue; 63327Sbill } else { 64327Sbill printf("%s not found\n",path); 65327Sbill return(0); 66327Sbill } 67327Sbill } 68327Sbill return(n); 69327Sbill } 70327Sbill 71327Sbill static daddr_t 72327Sbill sbmap(io, bn) 73327Sbill register struct iob *io; 74327Sbill daddr_t bn; 75327Sbill { 76327Sbill register i; 77327Sbill register struct inode *ip; 78327Sbill int j, sh; 79327Sbill daddr_t nb, *bap; 80327Sbill int ibn = bn; 81327Sbill 82327Sbill ip = &io->i_ino; 83327Sbill if(bn < 0) { 84327Sbill printf("bn negative\n"); 85327Sbill return((daddr_t)0); 86327Sbill } 87327Sbill 88327Sbill /* 89327Sbill * blocks 0..NADDR-4 are direct blocks 90327Sbill */ 91327Sbill if(bn < NADDR-3) { 92327Sbill i = bn; 93327Sbill nb = ip->i_un.i_addr[i]; 94327Sbill return(nb); 95327Sbill } 96327Sbill 97327Sbill /* 98327Sbill * addresses NADDR-3, NADDR-2, and NADDR-1 99327Sbill * have single, double, triple indirect blocks. 100327Sbill * the first step is to determine 101327Sbill * how many levels of indirection. 102327Sbill */ 103327Sbill sh = 0; 104327Sbill nb = 1; 105327Sbill bn -= NADDR-3; 106327Sbill for(j=3; j>0; j--) { 107327Sbill sh += NSHIFT; 108327Sbill nb <<= NSHIFT; 109327Sbill if(bn < nb) 110327Sbill break; 111327Sbill bn -= nb; 112327Sbill } 113327Sbill if(j == 0) { 114327Sbill printf("bn ovf %D\n",bn); 115327Sbill return((daddr_t)0); 116327Sbill } 117327Sbill 118327Sbill /* 119327Sbill * fetch the address from the inode 120327Sbill */ 121327Sbill nb = ip->i_un.i_addr[NADDR-j]; 122327Sbill if(nb == 0) { 123327Sbill printf("bn void %D\n",bn); 124327Sbill return((daddr_t)0); 125327Sbill } 126327Sbill 127327Sbill /* 128327Sbill * fetch through the indirect blocks 129327Sbill */ 130327Sbill for(; j<=3; j++) { 131327Sbill if (blknos[j] != nb) { 132327Sbill io->i_bn = fsbtodb(nb) + io->i_boff; 133327Sbill io->i_ma = b[j]; 134327Sbill io->i_cc = BSIZE; 135327Sbill devread(io); 136327Sbill bap = (daddr_t *)b[j]; 137327Sbill blknos[j] = nb; 138327Sbill } 139327Sbill bap = (daddr_t *)b[j]; 140327Sbill sh -= NSHIFT; 141327Sbill i = (bn>>sh) & NMASK; 142327Sbill nb = bap[i]; 143327Sbill if(nb == 0) { 144327Sbill printf("bn void %D\n",bn); 145327Sbill return((daddr_t)0); 146327Sbill } 147327Sbill } 148327Sbill return(nb); 149327Sbill } 150327Sbill 151327Sbill static ino_t 152327Sbill dlook(s, io) 153327Sbill char *s; 154327Sbill register struct iob *io; 155327Sbill { 156327Sbill register struct direct *dp; 157327Sbill register struct inode *ip; 158327Sbill daddr_t bn; 159327Sbill int n,dc; 160327Sbill 161327Sbill if (s==NULL || *s=='\0') 162327Sbill return(0); 163327Sbill ip = &io->i_ino; 164327Sbill if ((ip->i_mode&IFMT)!=IFDIR) { 165327Sbill printf("not a directory\n"); 166327Sbill return(0); 167327Sbill } 168327Sbill 169327Sbill n = ip->i_size/sizeof(struct direct); 170327Sbill 171327Sbill if (n==0) { 172327Sbill printf("zero length directory\n"); 173327Sbill return(0); 174327Sbill } 175327Sbill 176327Sbill dc = BSIZE; 177327Sbill bn = (daddr_t)0; 178327Sbill while(n--) { 179327Sbill if (++dc >= BSIZE/sizeof(struct direct)) { 180327Sbill io->i_bn = fsbtodb(sbmap(io, bn++)) + io->i_boff; 181327Sbill io->i_ma = io->i_buf; 182327Sbill io->i_cc = BSIZE; 183327Sbill devread(io); 184327Sbill dp = (struct direct *)io->i_buf; 185327Sbill dc = 0; 186327Sbill } 187327Sbill 188327Sbill if (match(s, dp->d_name)) 189327Sbill return(dp->d_ino); 190327Sbill dp++; 191327Sbill } 192327Sbill return(0); 193327Sbill } 194327Sbill 195327Sbill static 196327Sbill match(s1,s2) 197327Sbill register char *s1,*s2; 198327Sbill { 199327Sbill register cc; 200327Sbill 201327Sbill cc = DIRSIZ; 202327Sbill while (cc--) { 203327Sbill if (*s1 != *s2) 204327Sbill return(0); 205327Sbill if (*s1++ && *s2++) 206327Sbill continue; else 207327Sbill return(1); 208327Sbill } 209327Sbill return(1); 210327Sbill } 211327Sbill 212327Sbill lseek(fdesc, addr, ptr) 213327Sbill int fdesc; 214327Sbill off_t addr; 215327Sbill int ptr; 216327Sbill { 217327Sbill register struct iob *io; 218327Sbill 219327Sbill if (ptr != 0) { 220327Sbill printf("Seek not from beginning of file\n"); 221327Sbill return(-1); 222327Sbill } 223327Sbill fdesc -= 3; 224327Sbill if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 225327Sbill return(-1); 226327Sbill io->i_offset = addr; 227327Sbill io->i_bn = fsbtodb(addr/BSIZE) + io->i_boff; 228327Sbill io->i_cc = 0; 229327Sbill return(0); 230327Sbill } 231327Sbill 232327Sbill getc(fdesc) 233327Sbill int fdesc; 234327Sbill { 235327Sbill register struct iob *io; 236327Sbill register char *p; 237327Sbill register c; 238327Sbill int off; 239327Sbill 240327Sbill 241327Sbill if (fdesc >= 0 && fdesc <= 2) 242327Sbill return(getchar()); 243327Sbill fdesc -= 3; 244327Sbill if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 245327Sbill return(-1); 246327Sbill p = io->i_ma; 247327Sbill if (io->i_cc <= 0) { 248327Sbill io->i_bn = fsbtodb(io->i_offset/(off_t)BSIZE); 249327Sbill if (io->i_flgs&F_FILE) 250327Sbill io->i_bn = fsbtodb(sbmap(io, dbtofsb(io->i_bn))) + io->i_boff; 251327Sbill io->i_ma = io->i_buf; 252327Sbill io->i_cc = BSIZE; 253327Sbill devread(io); 254327Sbill if (io->i_flgs&F_FILE) { 255327Sbill off = io->i_offset % (off_t)BSIZE; 256327Sbill if (io->i_offset+(BSIZE-off) >= io->i_ino.i_size) 257327Sbill io->i_cc = io->i_ino.i_size - io->i_offset + off; 258327Sbill io->i_cc -= off; 259327Sbill if (io->i_cc <= 0) 260327Sbill return(-1); 261327Sbill } else 262327Sbill off = 0; 263327Sbill p = &io->i_buf[off]; 264327Sbill } 265327Sbill io->i_cc--; 266327Sbill io->i_offset++; 267327Sbill c = (unsigned)*p++; 268327Sbill io->i_ma = p; 269327Sbill return(c); 270327Sbill } 271327Sbill /* does this port? 272327Sbill getw(fdesc) 273327Sbill int fdesc; 274327Sbill { 275327Sbill register w,i; 276327Sbill register char *cp; 277327Sbill int val; 278327Sbill 279327Sbill for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) { 280327Sbill w = getc(fdesc); 281327Sbill if (w < 0) { 282327Sbill if (i == 0) 283327Sbill return(-1); 284327Sbill else 285327Sbill return(val); 286327Sbill } 287327Sbill *cp++ = w; 288327Sbill } 289327Sbill return(val); 290327Sbill } 291327Sbill */ 292327Sbill 293327Sbill read(fdesc, buf, count) 294327Sbill int fdesc; 295327Sbill char *buf; 296327Sbill int count; 297327Sbill { 298327Sbill register i; 299327Sbill register struct iob *file; 300327Sbill 301327Sbill if (fdesc >= 0 & fdesc <= 2) { 302327Sbill i = count; 303327Sbill do { 304327Sbill *buf = getchar(); 305327Sbill } while (--i && *buf++ != '\n'); 306327Sbill return(count - i); 307327Sbill } 308327Sbill fdesc -= 3; 309327Sbill if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 310327Sbill return(-1); 311327Sbill if ((file->i_flgs&F_READ) == 0) 312327Sbill return(-1); 313327Sbill if ((file->i_flgs&F_FILE) == 0) { 314327Sbill file->i_cc = count; 315327Sbill file->i_ma = buf; 316327Sbill i = devread(file); 317327Sbill file->i_bn += CLSIZE; 318327Sbill return(i); 319327Sbill } 320327Sbill else { 321327Sbill if (file->i_offset+count > file->i_ino.i_size) 322327Sbill count = file->i_ino.i_size - file->i_offset; 323327Sbill if ((i = count) <= 0) 324327Sbill return(0); 325327Sbill do { 326327Sbill *buf++ = getc(fdesc+3); 327327Sbill } while (--i); 328327Sbill return(count); 329327Sbill } 330327Sbill } 331327Sbill 332327Sbill write(fdesc, buf, count) 333327Sbill int fdesc; 334327Sbill char *buf; 335327Sbill int count; 336327Sbill { 337327Sbill register i; 338327Sbill register struct iob *file; 339327Sbill 340327Sbill if (fdesc >= 0 && fdesc <= 2) { 341327Sbill i = count; 342327Sbill while (i--) 343327Sbill putchar(*buf++); 344327Sbill return(count); 345327Sbill } 346327Sbill fdesc -= 3; 347327Sbill if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 348327Sbill return(-1); 349327Sbill if ((file->i_flgs&F_WRITE) == 0) 350327Sbill return(-1); 351327Sbill file->i_cc = count; 352327Sbill file->i_ma = buf; 353327Sbill i = devwrite(file); 354327Sbill file->i_bn += CLSIZE; 355327Sbill return(i); 356327Sbill } 357327Sbill 358*3349Swnj int openfirst = 1; 359*3349Swnj 360327Sbill open(str, how) 361327Sbill char *str; 362327Sbill int how; 363327Sbill { 364327Sbill register char *cp; 365327Sbill int i; 366327Sbill register struct iob *file; 367327Sbill register struct devsw *dp; 368327Sbill int fdesc; 369327Sbill long atol(); 370327Sbill 371*3349Swnj if (openfirst) { 372327Sbill for (i = 0; i < NFILES; i++) 373327Sbill iob[i].i_flgs = 0; 374*3349Swnj openfirst = 0; 375327Sbill } 376327Sbill 377327Sbill for (fdesc = 0; fdesc < NFILES; fdesc++) 378327Sbill if (iob[fdesc].i_flgs == 0) 379327Sbill goto gotfile; 380327Sbill _stop("No more file slots"); 381327Sbill gotfile: 382327Sbill (file = &iob[fdesc])->i_flgs |= F_ALLOC; 383327Sbill 384327Sbill for (cp = str; *cp && *cp != '('; cp++) 385327Sbill ; 386327Sbill if (*cp != '(') { 387327Sbill printf("Bad device\n"); 388327Sbill file->i_flgs = 0; 389327Sbill return(-1); 390327Sbill } 391327Sbill *cp++ = '\0'; 392327Sbill for (dp = devsw; dp->dv_name; dp++) { 393327Sbill if (match(str, dp->dv_name)) 394327Sbill goto gotdev; 395327Sbill } 396327Sbill printf("Unknown device\n"); 397327Sbill file->i_flgs = 0; 398327Sbill return(-1); 399327Sbill gotdev: 400327Sbill *(cp-1) = '('; 401327Sbill file->i_ino.i_dev = dp-devsw; 402327Sbill file->i_unit = *cp++ - '0'; 4033274Swnj if (*cp >= '0' && *cp <= '9') 4043274Swnj file->i_unit = file->i_unit * 10 + *cp++ - '0'; 4053274Swnj if (file->i_unit < 0 || file->i_unit > 31) { 406327Sbill printf("Bad unit specifier\n"); 407327Sbill file->i_flgs = 0; 408327Sbill return(-1); 409327Sbill } 410327Sbill if (*cp++ != ',') { 411327Sbill badoff: 412327Sbill printf("Missing offset specification\n"); 413327Sbill file->i_flgs = 0; 414327Sbill return(-1); 415327Sbill } 416327Sbill file->i_boff = atol(cp); 417327Sbill for (;;) { 418327Sbill if (*cp == ')') 419327Sbill break; 420327Sbill if (*cp++) 421327Sbill continue; 422327Sbill goto badoff; 423327Sbill } 424327Sbill devopen(file); 425327Sbill if (*++cp == '\0') { 426327Sbill file->i_flgs |= how+1; 427327Sbill file->i_cc = 0; 428327Sbill file->i_offset = 0; 429327Sbill return(fdesc+3); 430327Sbill } 431327Sbill if ((i = find(cp, file)) == 0) { 432327Sbill file->i_flgs = 0; 433327Sbill return(-1); 434327Sbill } 435327Sbill if (how != 0) { 436327Sbill printf("Can't write files yet.. Sorry\n"); 437327Sbill file->i_flgs = 0; 438327Sbill return(-1); 439327Sbill } 440327Sbill openi(i, file); 441327Sbill file->i_offset = 0; 442327Sbill file->i_cc = 0; 443327Sbill file->i_flgs |= F_FILE | (how+1); 444327Sbill return(fdesc+3); 445327Sbill } 446327Sbill 447327Sbill close(fdesc) 448327Sbill int fdesc; 449327Sbill { 450327Sbill struct iob *file; 451327Sbill 452327Sbill fdesc -= 3; 453327Sbill if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 454327Sbill return(-1); 455327Sbill if ((file->i_flgs&F_FILE) == 0) 456327Sbill devclose(file); 457327Sbill file->i_flgs = 0; 458327Sbill return(0); 459327Sbill } 460327Sbill 461327Sbill exit() 462327Sbill { 463327Sbill _stop("Exit called"); 464327Sbill } 465327Sbill 466327Sbill _stop(s) 467327Sbill char *s; 468327Sbill { 4692391Stoy int i; 4702391Stoy 4712391Stoy for (i = 0; i < NFILES; i++) 4722391Stoy if (iob[i].i_flgs != 0) 4732391Stoy close(i); 474327Sbill printf("%s\n", s); 475327Sbill _rtt(); 476327Sbill } 477327Sbill 478327Sbill trap(ps) 479327Sbill int ps; 480327Sbill { 481327Sbill printf("Trap %o\n", ps); 482327Sbill for (;;) 483327Sbill ; 484327Sbill } 485