1*2391Stoy /* sys.c 4.2 02/09/81 */ 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 358327Sbill open(str, how) 359327Sbill char *str; 360327Sbill int how; 361327Sbill { 362327Sbill register char *cp; 363327Sbill int i; 364327Sbill register struct iob *file; 365327Sbill register struct devsw *dp; 366327Sbill int fdesc; 367327Sbill static first = 1; 368327Sbill long atol(); 369327Sbill 370327Sbill if (first) { 371327Sbill for (i = 0; i < NFILES; i++) 372327Sbill iob[i].i_flgs = 0; 373327Sbill first = 0; 374327Sbill } 375327Sbill 376327Sbill for (fdesc = 0; fdesc < NFILES; fdesc++) 377327Sbill if (iob[fdesc].i_flgs == 0) 378327Sbill goto gotfile; 379327Sbill _stop("No more file slots"); 380327Sbill gotfile: 381327Sbill (file = &iob[fdesc])->i_flgs |= F_ALLOC; 382327Sbill 383327Sbill for (cp = str; *cp && *cp != '('; cp++) 384327Sbill ; 385327Sbill if (*cp != '(') { 386327Sbill printf("Bad device\n"); 387327Sbill file->i_flgs = 0; 388327Sbill return(-1); 389327Sbill } 390327Sbill *cp++ = '\0'; 391327Sbill for (dp = devsw; dp->dv_name; dp++) { 392327Sbill if (match(str, dp->dv_name)) 393327Sbill goto gotdev; 394327Sbill } 395327Sbill printf("Unknown device\n"); 396327Sbill file->i_flgs = 0; 397327Sbill return(-1); 398327Sbill gotdev: 399327Sbill *(cp-1) = '('; 400327Sbill file->i_ino.i_dev = dp-devsw; 401327Sbill file->i_unit = *cp++ - '0'; 402327Sbill if (file->i_unit < 0 || file->i_unit > 7) { 403327Sbill printf("Bad unit specifier\n"); 404327Sbill file->i_flgs = 0; 405327Sbill return(-1); 406327Sbill } 407327Sbill if (*cp++ != ',') { 408327Sbill badoff: 409327Sbill printf("Missing offset specification\n"); 410327Sbill file->i_flgs = 0; 411327Sbill return(-1); 412327Sbill } 413327Sbill file->i_boff = atol(cp); 414327Sbill for (;;) { 415327Sbill if (*cp == ')') 416327Sbill break; 417327Sbill if (*cp++) 418327Sbill continue; 419327Sbill goto badoff; 420327Sbill } 421327Sbill devopen(file); 422327Sbill if (*++cp == '\0') { 423327Sbill file->i_flgs |= how+1; 424327Sbill file->i_cc = 0; 425327Sbill file->i_offset = 0; 426327Sbill return(fdesc+3); 427327Sbill } 428327Sbill if ((i = find(cp, file)) == 0) { 429327Sbill file->i_flgs = 0; 430327Sbill return(-1); 431327Sbill } 432327Sbill if (how != 0) { 433327Sbill printf("Can't write files yet.. Sorry\n"); 434327Sbill file->i_flgs = 0; 435327Sbill return(-1); 436327Sbill } 437327Sbill openi(i, file); 438327Sbill file->i_offset = 0; 439327Sbill file->i_cc = 0; 440327Sbill file->i_flgs |= F_FILE | (how+1); 441327Sbill return(fdesc+3); 442327Sbill } 443327Sbill 444327Sbill close(fdesc) 445327Sbill int fdesc; 446327Sbill { 447327Sbill struct iob *file; 448327Sbill 449327Sbill fdesc -= 3; 450327Sbill if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 451327Sbill return(-1); 452327Sbill if ((file->i_flgs&F_FILE) == 0) 453327Sbill devclose(file); 454327Sbill file->i_flgs = 0; 455327Sbill return(0); 456327Sbill } 457327Sbill 458327Sbill exit() 459327Sbill { 460327Sbill _stop("Exit called"); 461327Sbill } 462327Sbill 463327Sbill _stop(s) 464327Sbill char *s; 465327Sbill { 466*2391Stoy int i; 467*2391Stoy 468*2391Stoy for (i = 0; i < NFILES; i++) 469*2391Stoy if (iob[i].i_flgs != 0) 470*2391Stoy close(i); 471327Sbill printf("%s\n", s); 472327Sbill _rtt(); 473327Sbill } 474327Sbill 475327Sbill trap(ps) 476327Sbill int ps; 477327Sbill { 478327Sbill printf("Trap %o\n", ps); 479327Sbill for (;;) 480327Sbill ; 481327Sbill } 482