1*10331Shelge /* sys.c 4.9 83/01/16 */ 2327Sbill 36068Smckusic #include "../h/param.h" 46068Smckusic #include "../h/inode.h" 56068Smckusic #include "../h/fs.h" 67446Sroot #include "../h/dir.h" 7327Sbill #include "saio.h" 8327Sbill 9327Sbill ino_t dlook(); 10327Sbill 116068Smckusic struct dirstuff { 126068Smckusic int loc; 136068Smckusic struct iob *io; 146068Smckusic }; 156068Smckusic 16327Sbill static 1710022Ssam openi(n, io) 186068Smckusic register struct iob *io; 19327Sbill { 20327Sbill register struct dinode *dp; 21327Sbill 22327Sbill io->i_offset = 0; 236068Smckusic io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 246068Smckusic 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; 286068Smckusic io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic; 29327Sbill } 30327Sbill 31327Sbill static 32327Sbill find(path, file) 336068Smckusic register char *path; 346068Smckusic 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"); 4210022Ssam 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); 6410022Ssam return (0); 65327Sbill } 66327Sbill } 6710022Ssam return (n); 68327Sbill } 69327Sbill 70327Sbill static daddr_t 71327Sbill sbmap(io, bn) 726068Smckusic register struct iob *io; 736068Smckusic daddr_t bn; 74327Sbill { 75327Sbill register struct inode *ip; 766068Smckusic int i, j, sh; 77327Sbill daddr_t nb, *bap; 78327Sbill 79327Sbill ip = &io->i_ino; 806068Smckusic if (bn < 0) { 81327Sbill printf("bn negative\n"); 8210022Ssam return ((daddr_t)0); 83327Sbill } 84327Sbill 85327Sbill /* 866068Smckusic * blocks 0..NDADDR are direct blocks 87327Sbill */ 886068Smckusic if(bn < NDADDR) { 896068Smckusic nb = ip->i_db[bn]; 9010022Ssam return (nb); 91327Sbill } 92327Sbill 93327Sbill /* 946068Smckusic * addresses NIADDR have single and double indirect blocks. 956068Smckusic * the first step is to determine how many levels of indirection. 96327Sbill */ 976068Smckusic sh = 1; 986068Smckusic bn -= NDADDR; 996068Smckusic for (j = NIADDR; j > 0; j--) { 1006068Smckusic sh *= NINDIR(&io->i_fs); 1016068Smckusic if (bn < sh) 102327Sbill break; 1036068Smckusic bn -= sh; 104327Sbill } 1056068Smckusic if (j == 0) { 1066068Smckusic printf("bn ovf %D\n", bn); 1076068Smckusic return ((daddr_t)0); 108327Sbill } 109327Sbill 110327Sbill /* 1116068Smckusic * fetch the first indirect block address from the inode 112327Sbill */ 1136068Smckusic nb = ip->i_ib[NIADDR - j]; 1146068Smckusic if (nb == 0) { 115327Sbill printf("bn void %D\n",bn); 11610022Ssam return ((daddr_t)0); 117327Sbill } 118327Sbill 119327Sbill /* 120327Sbill * fetch through the indirect blocks 121327Sbill */ 1226068Smckusic for (; j <= NIADDR; j++) { 123327Sbill if (blknos[j] != nb) { 1246068Smckusic io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 125327Sbill io->i_ma = b[j]; 1266068Smckusic io->i_cc = io->i_fs.fs_bsize; 127327Sbill devread(io); 128327Sbill blknos[j] = nb; 129327Sbill } 130327Sbill bap = (daddr_t *)b[j]; 1316068Smckusic sh /= NINDIR(&io->i_fs); 1326068Smckusic i = (bn / sh) % NINDIR(&io->i_fs); 133327Sbill nb = bap[i]; 134327Sbill if(nb == 0) { 135327Sbill printf("bn void %D\n",bn); 13610022Ssam return ((daddr_t)0); 137327Sbill } 138327Sbill } 13910022Ssam return (nb); 140327Sbill } 141327Sbill 142327Sbill static ino_t 143327Sbill dlook(s, io) 1446068Smckusic char *s; 1456068Smckusic register struct iob *io; 146327Sbill { 147327Sbill register struct direct *dp; 148327Sbill register struct inode *ip; 1496068Smckusic struct dirstuff dirp; 1506068Smckusic int len; 151327Sbill 1526068Smckusic if (s == NULL || *s == '\0') 15310022Ssam return (0); 154327Sbill ip = &io->i_ino; 1556068Smckusic if ((ip->i_mode&IFMT) != IFDIR) { 156327Sbill printf("not a directory\n"); 15710022Ssam return (0); 158327Sbill } 1596068Smckusic if (ip->i_size == 0) { 160327Sbill printf("zero length directory\n"); 16110022Ssam return (0); 162327Sbill } 1636068Smckusic len = strlen(s); 1646068Smckusic dirp.loc = 0; 1656068Smckusic dirp.io = io; 1666068Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 1676068Smckusic if(dp->d_ino == 0) 1686068Smckusic continue; 1696068Smckusic if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 17010022Ssam return (dp->d_ino); 171327Sbill } 17210022Ssam return (0); 173327Sbill } 174327Sbill 1756068Smckusic /* 1766068Smckusic * get next entry in a directory. 1776068Smckusic */ 1786068Smckusic struct direct * 1796068Smckusic readdir(dirp) 1806068Smckusic register struct dirstuff *dirp; 181327Sbill { 1826068Smckusic register struct direct *dp; 1836068Smckusic register struct iob *io; 1846068Smckusic daddr_t lbn, d; 1856068Smckusic int off; 186327Sbill 1876068Smckusic io = dirp->io; 1886068Smckusic for(;;) { 1896068Smckusic if (dirp->loc >= io->i_ino.i_size) 1906068Smckusic return NULL; 1916068Smckusic off = blkoff(&io->i_fs, dirp->loc); 1926068Smckusic if (off == 0) { 1936068Smckusic lbn = lblkno(&io->i_fs, dirp->loc); 1946068Smckusic d = sbmap(io, lbn); 1956068Smckusic if(d == 0) 1966068Smckusic return NULL; 1976068Smckusic io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 1986068Smckusic io->i_ma = io->i_buf; 1996068Smckusic io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); 2006068Smckusic devread(io); 2016068Smckusic } 2026068Smckusic dp = (struct direct *)(io->i_buf + off); 2036068Smckusic dirp->loc += dp->d_reclen; 2046068Smckusic if (dp->d_ino == 0) 2056068Smckusic continue; 2066068Smckusic return (dp); 207327Sbill } 208327Sbill } 209327Sbill 210327Sbill lseek(fdesc, addr, ptr) 21110022Ssam int fdesc, ptr; 21210022Ssam off_t addr; 213327Sbill { 214327Sbill register struct iob *io; 215327Sbill 216327Sbill if (ptr != 0) { 217327Sbill printf("Seek not from beginning of file\n"); 21810022Ssam errno = EOFFSET; 21910022Ssam return (-1); 220327Sbill } 221327Sbill fdesc -= 3; 2226068Smckusic if (fdesc < 0 || fdesc >= NFILES || 22310022Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 22410022Ssam errno = EBADF; 22510022Ssam return (-1); 22610022Ssam } 227327Sbill io->i_offset = addr; 2286068Smckusic io->i_bn = addr / DEV_BSIZE; 229327Sbill io->i_cc = 0; 23010022Ssam return (0); 231327Sbill } 232327Sbill 233327Sbill getc(fdesc) 23410022Ssam int fdesc; 235327Sbill { 236327Sbill register struct iob *io; 2376068Smckusic register struct fs *fs; 238327Sbill register char *p; 2396068Smckusic int c, lbn, off, size, diff; 240327Sbill 241327Sbill 242327Sbill if (fdesc >= 0 && fdesc <= 2) 24310022Ssam return (getchar()); 244327Sbill fdesc -= 3; 2456068Smckusic if (fdesc < 0 || fdesc >= NFILES || 24610022Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 24710022Ssam errno = EBADF; 24810022Ssam return (-1); 24910022Ssam } 250327Sbill p = io->i_ma; 251327Sbill if (io->i_cc <= 0) { 2526068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2536068Smckusic diff = io->i_ino.i_size - io->i_offset; 2546068Smckusic if (diff <= 0) 2556068Smckusic return (-1); 2566068Smckusic fs = &io->i_fs; 2576068Smckusic lbn = lblkno(fs, io->i_offset); 2586068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 2596068Smckusic off = blkoff(fs, io->i_offset); 2606068Smckusic size = blksize(fs, &io->i_ino, lbn); 2616068Smckusic } else { 2626068Smckusic io->i_bn = io->i_offset / DEV_BSIZE; 2636068Smckusic off = 0; 2646068Smckusic size = DEV_BSIZE; 2656068Smckusic } 266327Sbill io->i_ma = io->i_buf; 2676068Smckusic io->i_cc = size; 268327Sbill devread(io); 2696068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2706068Smckusic if (io->i_offset - off + size >= io->i_ino.i_size) 2716068Smckusic io->i_cc = diff + off; 272327Sbill io->i_cc -= off; 2736068Smckusic } 274327Sbill p = &io->i_buf[off]; 275327Sbill } 276327Sbill io->i_cc--; 277327Sbill io->i_offset++; 278327Sbill c = (unsigned)*p++; 279327Sbill io->i_ma = p; 28010022Ssam return (c); 281327Sbill } 2826068Smckusic 283327Sbill /* does this port? 284327Sbill getw(fdesc) 28510022Ssam int fdesc; 286327Sbill { 287327Sbill register w,i; 288327Sbill register char *cp; 289327Sbill int val; 290327Sbill 291327Sbill for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) { 292327Sbill w = getc(fdesc); 293327Sbill if (w < 0) { 294327Sbill if (i == 0) 29510022Ssam return (-1); 296327Sbill else 29710022Ssam return (val); 298327Sbill } 299327Sbill *cp++ = w; 300327Sbill } 30110022Ssam return (val); 302327Sbill } 303327Sbill */ 30410022Ssam int errno; 305327Sbill 306327Sbill read(fdesc, buf, count) 30710022Ssam int fdesc, count; 30810022Ssam char *buf; 309327Sbill { 310327Sbill register i; 311327Sbill register struct iob *file; 312327Sbill 31310022Ssam errno = 0; 314327Sbill if (fdesc >= 0 & fdesc <= 2) { 315327Sbill i = count; 316327Sbill do { 317327Sbill *buf = getchar(); 318327Sbill } while (--i && *buf++ != '\n'); 31910022Ssam return (count - i); 320327Sbill } 321327Sbill fdesc -= 3; 3226068Smckusic if (fdesc < 0 || fdesc >= NFILES || 32310022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 32410022Ssam errno = EBADF; 32510022Ssam return (-1); 32610022Ssam } 32710022Ssam if ((file->i_flgs&F_READ) == 0) { 32810022Ssam errno = EBADF; 32910022Ssam return (-1); 33010022Ssam } 3316068Smckusic if ((file->i_flgs & F_FILE) == 0) { 332327Sbill file->i_cc = count; 333327Sbill file->i_ma = buf; 3347446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 335327Sbill i = devread(file); 3367446Sroot file->i_offset += count; 33710022Ssam if (i < 0) 33810022Ssam errno = file->i_error; 33910022Ssam return (i); 3406068Smckusic } else { 341327Sbill if (file->i_offset+count > file->i_ino.i_size) 342327Sbill count = file->i_ino.i_size - file->i_offset; 343327Sbill if ((i = count) <= 0) 34410022Ssam return (0); 345327Sbill do { 346327Sbill *buf++ = getc(fdesc+3); 347327Sbill } while (--i); 34810022Ssam return (count); 349327Sbill } 350327Sbill } 351327Sbill 352327Sbill write(fdesc, buf, count) 35310022Ssam int fdesc, count; 35410022Ssam char *buf; 355327Sbill { 356327Sbill register i; 357327Sbill register struct iob *file; 358327Sbill 35910022Ssam errno = 0; 360327Sbill if (fdesc >= 0 && fdesc <= 2) { 361327Sbill i = count; 362327Sbill while (i--) 363327Sbill putchar(*buf++); 36410022Ssam return (count); 365327Sbill } 366327Sbill fdesc -= 3; 3676068Smckusic if (fdesc < 0 || fdesc >= NFILES || 36810022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 36910022Ssam errno = EBADF; 37010022Ssam return (-1); 37110022Ssam } 37210022Ssam if ((file->i_flgs&F_WRITE) == 0) { 37310022Ssam errno = EBADF; 37410022Ssam return (-1); 37510022Ssam } 376327Sbill file->i_cc = count; 377327Sbill file->i_ma = buf; 3787446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 379327Sbill i = devwrite(file); 3807446Sroot file->i_offset += count; 38110022Ssam if (i < 0) 38210022Ssam errno = file->i_error; 38310022Ssam return (i); 384327Sbill } 385327Sbill 3863349Swnj int openfirst = 1; 3873349Swnj 388327Sbill open(str, how) 3896068Smckusic char *str; 39010022Ssam int how; 391327Sbill { 392327Sbill register char *cp; 393327Sbill int i; 394327Sbill register struct iob *file; 395327Sbill register struct devsw *dp; 39610022Ssam int fdesc; 39710022Ssam long atol(); 398327Sbill 3993349Swnj if (openfirst) { 400327Sbill for (i = 0; i < NFILES; i++) 401327Sbill iob[i].i_flgs = 0; 4023349Swnj openfirst = 0; 403327Sbill } 404327Sbill 405327Sbill for (fdesc = 0; fdesc < NFILES; fdesc++) 406327Sbill if (iob[fdesc].i_flgs == 0) 407327Sbill goto gotfile; 408327Sbill _stop("No more file slots"); 409327Sbill gotfile: 410327Sbill (file = &iob[fdesc])->i_flgs |= F_ALLOC; 411327Sbill 412327Sbill for (cp = str; *cp && *cp != '('; cp++) 413327Sbill ; 414327Sbill if (*cp != '(') { 415327Sbill printf("Bad device\n"); 416327Sbill file->i_flgs = 0; 41710022Ssam errno = EDEV; 41810022Ssam return (-1); 419327Sbill } 420327Sbill *cp++ = '\0'; 421327Sbill for (dp = devsw; dp->dv_name; dp++) { 4226068Smckusic if (!strcmp(str, dp->dv_name)) 423327Sbill goto gotdev; 424327Sbill } 425327Sbill printf("Unknown device\n"); 426327Sbill file->i_flgs = 0; 42710022Ssam errno = ENXIO; 42810022Ssam return (-1); 429327Sbill gotdev: 430327Sbill *(cp-1) = '('; 431327Sbill file->i_ino.i_dev = dp-devsw; 432327Sbill file->i_unit = *cp++ - '0'; 4333274Swnj if (*cp >= '0' && *cp <= '9') 4343274Swnj file->i_unit = file->i_unit * 10 + *cp++ - '0'; 4353274Swnj if (file->i_unit < 0 || file->i_unit > 31) { 436327Sbill printf("Bad unit specifier\n"); 437327Sbill file->i_flgs = 0; 43810022Ssam errno = EUNIT; 43910022Ssam return (-1); 440327Sbill } 441327Sbill if (*cp++ != ',') { 442327Sbill badoff: 443327Sbill printf("Missing offset specification\n"); 444327Sbill file->i_flgs = 0; 44510022Ssam errno = EOFFSET; 44610022Ssam return (-1); 447327Sbill } 448327Sbill file->i_boff = atol(cp); 449327Sbill for (;;) { 450327Sbill if (*cp == ')') 451327Sbill break; 452327Sbill if (*cp++) 453327Sbill continue; 454327Sbill goto badoff; 455327Sbill } 456327Sbill devopen(file); 457327Sbill if (*++cp == '\0') { 458327Sbill file->i_flgs |= how+1; 459327Sbill file->i_cc = 0; 460327Sbill file->i_offset = 0; 46110022Ssam return (fdesc+3); 462327Sbill } 4636068Smckusic file->i_ma = (char *)(&file->i_fs); 4646068Smckusic file->i_cc = SBSIZE; 4657446Sroot file->i_bn = SBLOCK + file->i_boff; 4666068Smckusic file->i_offset = 0; 4676068Smckusic devread(file); 468327Sbill if ((i = find(cp, file)) == 0) { 469327Sbill file->i_flgs = 0; 47010022Ssam errno = ESRCH; 47110022Ssam return (-1); 472327Sbill } 473327Sbill if (how != 0) { 474327Sbill printf("Can't write files yet.. Sorry\n"); 475327Sbill file->i_flgs = 0; 47610022Ssam errno = EIO; 47710022Ssam return (-1); 478327Sbill } 479327Sbill openi(i, file); 480327Sbill file->i_offset = 0; 481327Sbill file->i_cc = 0; 482327Sbill file->i_flgs |= F_FILE | (how+1); 48310022Ssam return (fdesc+3); 484327Sbill } 485327Sbill 486327Sbill close(fdesc) 48710022Ssam int fdesc; 488327Sbill { 489327Sbill struct iob *file; 490327Sbill 491327Sbill fdesc -= 3; 4926068Smckusic if (fdesc < 0 || fdesc >= NFILES || 49310022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 49410022Ssam errno = EBADF; 49510022Ssam return (-1); 49610022Ssam } 497327Sbill if ((file->i_flgs&F_FILE) == 0) 498327Sbill devclose(file); 499327Sbill file->i_flgs = 0; 50010022Ssam return (0); 501327Sbill } 502327Sbill 50310022Ssam ioctl(fdesc, cmd, arg) 50410022Ssam int fdesc, cmd; 50510022Ssam char *arg; 50610022Ssam { 50710022Ssam register struct iob *file; 50810022Ssam int error = 0; 50910022Ssam 510*10331Shelge fdesc -= 3; 51110022Ssam if (fdesc < 0 || fdesc >= NFILES || 51210022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 51310022Ssam errno = EBADF; 51410022Ssam return (-1); 51510022Ssam } 51610022Ssam switch (cmd) { 51710022Ssam 51810022Ssam case SAIOHDR: 51910022Ssam file->i_flgs |= F_HDR; 52010022Ssam break; 52110022Ssam 52210022Ssam case SAIOCHECK: 52310022Ssam file->i_flgs |= F_CHECK; 52410022Ssam break; 52510022Ssam 52610022Ssam case SAIOHCHECK: 52710022Ssam file->i_flgs |= F_HCHECK; 52810022Ssam break; 52910022Ssam 530*10331Shelge case SAIONOBAD: 531*10331Shelge file->i_flgs |= F_NBSF; 532*10331Shelge break; 533*10331Shelge 534*10331Shelge case SAIODOBAD: 535*10331Shelge file->i_flgs &= ~F_NBSF; 536*10331Shelge break; 537*10331Shelge 538*10331Shelge case SAIOECCLIM: 539*10331Shelge file->i_flgs |= F_ECCLM; 540*10331Shelge break; 541*10331Shelge 542*10331Shelge case SAIOECCUNL: 543*10331Shelge file->i_flgs &= ~F_ECCLM; 544*10331Shelge break; 545*10331Shelge 54610022Ssam default: 54710022Ssam error = devioctl(file, cmd, arg); 54810022Ssam break; 54910022Ssam } 55010022Ssam if (error < 0) 55110022Ssam errno = file->i_error; 55210022Ssam return (error); 55310022Ssam } 55410022Ssam 555327Sbill exit() 556327Sbill { 557327Sbill _stop("Exit called"); 558327Sbill } 559327Sbill 560327Sbill _stop(s) 56110022Ssam char *s; 562327Sbill { 5632391Stoy int i; 5642391Stoy 5652391Stoy for (i = 0; i < NFILES; i++) 5662391Stoy if (iob[i].i_flgs != 0) 5672391Stoy close(i); 568327Sbill printf("%s\n", s); 569327Sbill _rtt(); 570327Sbill } 571327Sbill 572327Sbill trap(ps) 5736068Smckusic int ps; 574327Sbill { 575327Sbill printf("Trap %o\n", ps); 576327Sbill for (;;) 577327Sbill ; 578327Sbill } 579