1*6068Smckusic /* sys.c 4.5 82/03/07 */ 2327Sbill 3*6068Smckusic #include "../h/param.h" 4*6068Smckusic #include "../h/inode.h" 5*6068Smckusic #include "../h/fs.h" 6*6068Smckusic #include "../h/ndir.h" 7327Sbill #include "saio.h" 8327Sbill 9327Sbill ino_t dlook(); 10327Sbill 11*6068Smckusic struct dirstuff { 12*6068Smckusic int loc; 13*6068Smckusic struct iob *io; 14*6068Smckusic }; 15*6068Smckusic 16327Sbill static 17327Sbill openi(n,io) 18*6068Smckusic register struct iob *io; 19327Sbill { 20327Sbill register struct dinode *dp; 21327Sbill 22327Sbill io->i_offset = 0; 23*6068Smckusic io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 24*6068Smckusic io->i_cc = io->i_fs.fs_bsize; 25327Sbill io->i_ma = io->i_buf; 26327Sbill devread(io); 27327Sbill dp = (struct dinode *)io->i_buf; 28*6068Smckusic io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic; 29327Sbill } 30327Sbill 31327Sbill static 32327Sbill find(path, file) 33*6068Smckusic register char *path; 34*6068Smckusic struct iob *file; 35327Sbill { 36327Sbill register char *q; 37327Sbill char c; 38327Sbill int n; 39327Sbill 40327Sbill if (path==NULL || *path=='\0') { 41327Sbill printf("null path\n"); 42327Sbill return(0); 43327Sbill } 44327Sbill 45327Sbill openi((ino_t) ROOTINO, file); 46327Sbill while (*path) { 47327Sbill while (*path == '/') 48327Sbill path++; 49327Sbill q = path; 50327Sbill while(*q != '/' && *q != '\0') 51327Sbill q++; 52327Sbill c = *q; 53327Sbill *q = '\0'; 54327Sbill 55327Sbill if ((n=dlook(path, file))!=0) { 56327Sbill if (c=='\0') 57327Sbill break; 58327Sbill openi(n, file); 59327Sbill *q = c; 60327Sbill path = q; 61327Sbill continue; 62327Sbill } else { 63327Sbill printf("%s not found\n",path); 64327Sbill return(0); 65327Sbill } 66327Sbill } 67327Sbill return(n); 68327Sbill } 69327Sbill 70327Sbill static daddr_t 71327Sbill sbmap(io, bn) 72*6068Smckusic register struct iob *io; 73*6068Smckusic daddr_t bn; 74327Sbill { 75327Sbill register struct inode *ip; 76*6068Smckusic int i, j, sh; 77327Sbill daddr_t nb, *bap; 78327Sbill 79327Sbill ip = &io->i_ino; 80*6068Smckusic if (bn < 0) { 81327Sbill printf("bn negative\n"); 82327Sbill return((daddr_t)0); 83327Sbill } 84327Sbill 85327Sbill /* 86*6068Smckusic * blocks 0..NDADDR are direct blocks 87327Sbill */ 88*6068Smckusic if(bn < NDADDR) { 89*6068Smckusic nb = ip->i_db[bn]; 90327Sbill return(nb); 91327Sbill } 92327Sbill 93327Sbill /* 94*6068Smckusic * addresses NIADDR have single and double indirect blocks. 95*6068Smckusic * the first step is to determine how many levels of indirection. 96327Sbill */ 97*6068Smckusic sh = 1; 98*6068Smckusic bn -= NDADDR; 99*6068Smckusic for (j = NIADDR; j > 0; j--) { 100*6068Smckusic sh *= NINDIR(&io->i_fs); 101*6068Smckusic if (bn < sh) 102327Sbill break; 103*6068Smckusic bn -= sh; 104327Sbill } 105*6068Smckusic if (j == 0) { 106*6068Smckusic printf("bn ovf %D\n", bn); 107*6068Smckusic return ((daddr_t)0); 108327Sbill } 109327Sbill 110327Sbill /* 111*6068Smckusic * fetch the first indirect block address from the inode 112327Sbill */ 113*6068Smckusic nb = ip->i_ib[NIADDR - j]; 114*6068Smckusic if (nb == 0) { 115327Sbill printf("bn void %D\n",bn); 116327Sbill return((daddr_t)0); 117327Sbill } 118327Sbill 119327Sbill /* 120327Sbill * fetch through the indirect blocks 121327Sbill */ 122*6068Smckusic for (; j <= NIADDR; j++) { 123327Sbill if (blknos[j] != nb) { 124*6068Smckusic io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 125327Sbill io->i_ma = b[j]; 126*6068Smckusic io->i_cc = io->i_fs.fs_bsize; 127327Sbill devread(io); 128327Sbill blknos[j] = nb; 129327Sbill } 130327Sbill bap = (daddr_t *)b[j]; 131*6068Smckusic sh /= NINDIR(&io->i_fs); 132*6068Smckusic i = (bn / sh) % NINDIR(&io->i_fs); 133327Sbill nb = bap[i]; 134327Sbill if(nb == 0) { 135327Sbill printf("bn void %D\n",bn); 136327Sbill return((daddr_t)0); 137327Sbill } 138327Sbill } 139327Sbill return(nb); 140327Sbill } 141327Sbill 142327Sbill static ino_t 143327Sbill dlook(s, io) 144*6068Smckusic char *s; 145*6068Smckusic register struct iob *io; 146327Sbill { 147327Sbill register struct direct *dp; 148327Sbill register struct inode *ip; 149*6068Smckusic struct dirstuff dirp; 150*6068Smckusic int len; 151327Sbill 152*6068Smckusic if (s == NULL || *s == '\0') 153327Sbill return(0); 154327Sbill ip = &io->i_ino; 155*6068Smckusic if ((ip->i_mode&IFMT) != IFDIR) { 156327Sbill printf("not a directory\n"); 157327Sbill return(0); 158327Sbill } 159*6068Smckusic if (ip->i_size == 0) { 160327Sbill printf("zero length directory\n"); 161327Sbill return(0); 162327Sbill } 163*6068Smckusic len = strlen(s); 164*6068Smckusic dirp.loc = 0; 165*6068Smckusic dirp.io = io; 166*6068Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 167*6068Smckusic if(dp->d_ino == 0) 168*6068Smckusic continue; 169*6068Smckusic if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 170327Sbill return(dp->d_ino); 171327Sbill } 172327Sbill return(0); 173327Sbill } 174327Sbill 175*6068Smckusic /* 176*6068Smckusic * get next entry in a directory. 177*6068Smckusic */ 178*6068Smckusic struct direct * 179*6068Smckusic readdir(dirp) 180*6068Smckusic register struct dirstuff *dirp; 181327Sbill { 182*6068Smckusic register struct direct *dp; 183*6068Smckusic register struct iob *io; 184*6068Smckusic daddr_t lbn, d; 185*6068Smckusic int off; 186327Sbill 187*6068Smckusic io = dirp->io; 188*6068Smckusic for(;;) { 189*6068Smckusic if (dirp->loc >= io->i_ino.i_size) 190*6068Smckusic return NULL; 191*6068Smckusic off = blkoff(&io->i_fs, dirp->loc); 192*6068Smckusic if (off == 0) { 193*6068Smckusic lbn = lblkno(&io->i_fs, dirp->loc); 194*6068Smckusic d = sbmap(io, lbn); 195*6068Smckusic if(d == 0) 196*6068Smckusic return NULL; 197*6068Smckusic io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 198*6068Smckusic io->i_ma = io->i_buf; 199*6068Smckusic io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); 200*6068Smckusic devread(io); 201*6068Smckusic } 202*6068Smckusic dp = (struct direct *)(io->i_buf + off); 203*6068Smckusic dirp->loc += dp->d_reclen; 204*6068Smckusic if (dp->d_ino == 0) 205*6068Smckusic continue; 206*6068Smckusic return (dp); 207327Sbill } 208327Sbill } 209327Sbill 210327Sbill lseek(fdesc, addr, ptr) 211*6068Smckusic int fdesc; 212*6068Smckusic off_t addr; 213*6068Smckusic int ptr; 214327Sbill { 215327Sbill register struct iob *io; 216327Sbill 217327Sbill if (ptr != 0) { 218327Sbill printf("Seek not from beginning of file\n"); 219327Sbill return(-1); 220327Sbill } 221327Sbill fdesc -= 3; 222*6068Smckusic if (fdesc < 0 || fdesc >= NFILES || 223*6068Smckusic ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) 224327Sbill return(-1); 225327Sbill io->i_offset = addr; 226*6068Smckusic io->i_bn = addr / DEV_BSIZE; 227327Sbill io->i_cc = 0; 228327Sbill return(0); 229327Sbill } 230327Sbill 231327Sbill getc(fdesc) 232*6068Smckusic int fdesc; 233327Sbill { 234327Sbill register struct iob *io; 235*6068Smckusic register struct fs *fs; 236327Sbill register char *p; 237*6068Smckusic int c, lbn, off, size, diff; 238327Sbill 239327Sbill 240327Sbill if (fdesc >= 0 && fdesc <= 2) 241327Sbill return(getchar()); 242327Sbill fdesc -= 3; 243*6068Smckusic if (fdesc < 0 || fdesc >= NFILES || 244*6068Smckusic ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 245327Sbill return(-1); 246327Sbill p = io->i_ma; 247327Sbill if (io->i_cc <= 0) { 248*6068Smckusic if ((io->i_flgs & F_FILE) != 0) { 249*6068Smckusic diff = io->i_ino.i_size - io->i_offset; 250*6068Smckusic if (diff <= 0) 251*6068Smckusic return (-1); 252*6068Smckusic fs = &io->i_fs; 253*6068Smckusic lbn = lblkno(fs, io->i_offset); 254*6068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 255*6068Smckusic off = blkoff(fs, io->i_offset); 256*6068Smckusic size = blksize(fs, &io->i_ino, lbn); 257*6068Smckusic } else { 258*6068Smckusic io->i_bn = io->i_offset / DEV_BSIZE; 259*6068Smckusic off = 0; 260*6068Smckusic size = DEV_BSIZE; 261*6068Smckusic } 262327Sbill io->i_ma = io->i_buf; 263*6068Smckusic io->i_cc = size; 264327Sbill devread(io); 265*6068Smckusic if ((io->i_flgs & F_FILE) != 0) { 266*6068Smckusic if (io->i_offset - off + size >= io->i_ino.i_size) 267*6068Smckusic io->i_cc = diff + off; 268327Sbill io->i_cc -= off; 269*6068Smckusic } 270327Sbill p = &io->i_buf[off]; 271327Sbill } 272327Sbill io->i_cc--; 273327Sbill io->i_offset++; 274327Sbill c = (unsigned)*p++; 275327Sbill io->i_ma = p; 276327Sbill return(c); 277327Sbill } 278*6068Smckusic 279327Sbill /* does this port? 280327Sbill getw(fdesc) 281*6068Smckusic int fdesc; 282327Sbill { 283327Sbill register w,i; 284327Sbill register char *cp; 285327Sbill int val; 286327Sbill 287327Sbill for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) { 288327Sbill w = getc(fdesc); 289327Sbill if (w < 0) { 290327Sbill if (i == 0) 291327Sbill return(-1); 292327Sbill else 293327Sbill return(val); 294327Sbill } 295327Sbill *cp++ = w; 296327Sbill } 297327Sbill return(val); 298327Sbill } 299327Sbill */ 300327Sbill 301327Sbill read(fdesc, buf, count) 302*6068Smckusic int fdesc; 303*6068Smckusic char *buf; 304*6068Smckusic int count; 305327Sbill { 306327Sbill register i; 307327Sbill register struct iob *file; 308327Sbill 309327Sbill if (fdesc >= 0 & fdesc <= 2) { 310327Sbill i = count; 311327Sbill do { 312327Sbill *buf = getchar(); 313327Sbill } while (--i && *buf++ != '\n'); 314327Sbill return(count - i); 315327Sbill } 316327Sbill fdesc -= 3; 317*6068Smckusic if (fdesc < 0 || fdesc >= NFILES || 318*6068Smckusic ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 319327Sbill return(-1); 320327Sbill if ((file->i_flgs&F_READ) == 0) 321327Sbill return(-1); 322*6068Smckusic if ((file->i_flgs & F_FILE) == 0) { 323327Sbill file->i_cc = count; 324327Sbill file->i_ma = buf; 325327Sbill i = devread(file); 326*6068Smckusic file->i_bn += (count / DEV_BSIZE); 327327Sbill return(i); 328*6068Smckusic } else { 329327Sbill if (file->i_offset+count > file->i_ino.i_size) 330327Sbill count = file->i_ino.i_size - file->i_offset; 331327Sbill if ((i = count) <= 0) 332327Sbill return(0); 333327Sbill do { 334327Sbill *buf++ = getc(fdesc+3); 335327Sbill } while (--i); 336327Sbill return(count); 337327Sbill } 338327Sbill } 339327Sbill 340327Sbill write(fdesc, buf, count) 341*6068Smckusic int fdesc; 342*6068Smckusic char *buf; 343*6068Smckusic int count; 344327Sbill { 345327Sbill register i; 346327Sbill register struct iob *file; 347327Sbill 348327Sbill if (fdesc >= 0 && fdesc <= 2) { 349327Sbill i = count; 350327Sbill while (i--) 351327Sbill putchar(*buf++); 352327Sbill return(count); 353327Sbill } 354327Sbill fdesc -= 3; 355*6068Smckusic if (fdesc < 0 || fdesc >= NFILES || 356*6068Smckusic ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 357327Sbill return(-1); 358327Sbill if ((file->i_flgs&F_WRITE) == 0) 359327Sbill return(-1); 360327Sbill file->i_cc = count; 361327Sbill file->i_ma = buf; 362327Sbill i = devwrite(file); 363*6068Smckusic file->i_bn += (count / DEV_BSIZE); 364327Sbill return(i); 365327Sbill } 366327Sbill 3673349Swnj int openfirst = 1; 3683349Swnj 369327Sbill open(str, how) 370*6068Smckusic char *str; 371*6068Smckusic int how; 372327Sbill { 373327Sbill register char *cp; 374327Sbill int i; 375327Sbill register struct iob *file; 376327Sbill register struct devsw *dp; 377327Sbill int fdesc; 378327Sbill long atol(); 379327Sbill 3803349Swnj if (openfirst) { 381327Sbill for (i = 0; i < NFILES; i++) 382327Sbill iob[i].i_flgs = 0; 3833349Swnj openfirst = 0; 384327Sbill } 385327Sbill 386327Sbill for (fdesc = 0; fdesc < NFILES; fdesc++) 387327Sbill if (iob[fdesc].i_flgs == 0) 388327Sbill goto gotfile; 389327Sbill _stop("No more file slots"); 390327Sbill gotfile: 391327Sbill (file = &iob[fdesc])->i_flgs |= F_ALLOC; 392327Sbill 393327Sbill for (cp = str; *cp && *cp != '('; cp++) 394327Sbill ; 395327Sbill if (*cp != '(') { 396327Sbill printf("Bad device\n"); 397327Sbill file->i_flgs = 0; 398327Sbill return(-1); 399327Sbill } 400327Sbill *cp++ = '\0'; 401327Sbill for (dp = devsw; dp->dv_name; dp++) { 402*6068Smckusic if (!strcmp(str, dp->dv_name)) 403327Sbill goto gotdev; 404327Sbill } 405327Sbill printf("Unknown device\n"); 406327Sbill file->i_flgs = 0; 407327Sbill return(-1); 408327Sbill gotdev: 409327Sbill *(cp-1) = '('; 410327Sbill file->i_ino.i_dev = dp-devsw; 411327Sbill file->i_unit = *cp++ - '0'; 4123274Swnj if (*cp >= '0' && *cp <= '9') 4133274Swnj file->i_unit = file->i_unit * 10 + *cp++ - '0'; 4143274Swnj if (file->i_unit < 0 || file->i_unit > 31) { 415327Sbill printf("Bad unit specifier\n"); 416327Sbill file->i_flgs = 0; 417327Sbill return(-1); 418327Sbill } 419327Sbill if (*cp++ != ',') { 420327Sbill badoff: 421327Sbill printf("Missing offset specification\n"); 422327Sbill file->i_flgs = 0; 423327Sbill return(-1); 424327Sbill } 425327Sbill file->i_boff = atol(cp); 426327Sbill for (;;) { 427327Sbill if (*cp == ')') 428327Sbill break; 429327Sbill if (*cp++) 430327Sbill continue; 431327Sbill goto badoff; 432327Sbill } 433327Sbill devopen(file); 434327Sbill if (*++cp == '\0') { 435327Sbill file->i_flgs |= how+1; 436327Sbill file->i_cc = 0; 437327Sbill file->i_offset = 0; 438327Sbill return(fdesc+3); 439327Sbill } 440*6068Smckusic file->i_ma = (char *)(&file->i_fs); 441*6068Smckusic file->i_cc = SBSIZE; 442*6068Smckusic file->i_bn = SBLOCK; 443*6068Smckusic file->i_offset = 0; 444*6068Smckusic devread(file); 445327Sbill if ((i = find(cp, file)) == 0) { 446327Sbill file->i_flgs = 0; 447327Sbill return(-1); 448327Sbill } 449327Sbill if (how != 0) { 450327Sbill printf("Can't write files yet.. Sorry\n"); 451327Sbill file->i_flgs = 0; 452327Sbill return(-1); 453327Sbill } 454327Sbill openi(i, file); 455327Sbill file->i_offset = 0; 456327Sbill file->i_cc = 0; 457327Sbill file->i_flgs |= F_FILE | (how+1); 458327Sbill return(fdesc+3); 459327Sbill } 460327Sbill 461327Sbill close(fdesc) 462*6068Smckusic int fdesc; 463327Sbill { 464327Sbill struct iob *file; 465327Sbill 466327Sbill fdesc -= 3; 467*6068Smckusic if (fdesc < 0 || fdesc >= NFILES || 468*6068Smckusic ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) 469327Sbill return(-1); 470327Sbill if ((file->i_flgs&F_FILE) == 0) 471327Sbill devclose(file); 472327Sbill file->i_flgs = 0; 473327Sbill return(0); 474327Sbill } 475327Sbill 476327Sbill exit() 477327Sbill { 478327Sbill _stop("Exit called"); 479327Sbill } 480327Sbill 481327Sbill _stop(s) 482*6068Smckusic char *s; 483327Sbill { 4842391Stoy int i; 4852391Stoy 4862391Stoy for (i = 0; i < NFILES; i++) 4872391Stoy if (iob[i].i_flgs != 0) 4882391Stoy close(i); 489327Sbill printf("%s\n", s); 490327Sbill _rtt(); 491327Sbill } 492327Sbill 493327Sbill trap(ps) 494*6068Smckusic int ps; 495327Sbill { 496327Sbill printf("Trap %o\n", ps); 497327Sbill for (;;) 498327Sbill ; 499327Sbill } 500