1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)sys.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "../h/param.h"
  10: #include "../h/inode.h"
  11: #include "../h/fs.h"
  12: #include "../h/dir.h"
  13: #include "saio.h"
  14: 
  15: ino_t   dlook();
  16: 
  17: struct dirstuff {
  18:     int loc;
  19:     struct iob *io;
  20: };
  21: 
  22: static
  23: openi(n, io)
  24:     register struct iob *io;
  25: {
  26:     register struct dinode *dp;
  27:     int cc;
  28: 
  29:     io->i_offset = 0;
  30:     io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
  31:     io->i_cc = io->i_fs.fs_bsize;
  32:     io->i_ma = io->i_buf;
  33:     cc = devread(io);
  34:     dp = (struct dinode *)io->i_buf;
  35:     io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
  36:     return (cc);
  37: }
  38: 
  39: static
  40: find(path, file)
  41:     register char *path;
  42:     struct iob *file;
  43: {
  44:     register char *q;
  45:     char c;
  46:     int n;
  47: 
  48:     if (path==NULL || *path=='\0') {
  49:         printf("null path\n");
  50:         return (0);
  51:     }
  52: 
  53:     if (openi((ino_t) ROOTINO, file) < 0) {
  54:         printf("can't read root inode\n");
  55:         return (0);
  56:     }
  57:     while (*path) {
  58:         while (*path == '/')
  59:             path++;
  60:         q = path;
  61:         while(*q != '/' && *q != '\0')
  62:             q++;
  63:         c = *q;
  64:         *q = '\0';
  65:         if (q == path) path = "." ; /* "/" means "/." */
  66: 
  67:         if ((n = dlook(path, file)) != 0) {
  68:             if (c == '\0')
  69:                 break;
  70:             if (openi(n, file) < 0)
  71:                 return (0);
  72:             *q = c;
  73:             path = q;
  74:             continue;
  75:         } else {
  76:             printf("%s: not found\n", path);
  77:             return (0);
  78:         }
  79:     }
  80:     return (n);
  81: }
  82: 
  83: static daddr_t
  84: sbmap(io, bn)
  85:     register struct iob *io;
  86:     daddr_t bn;
  87: {
  88:     register struct inode *ip;
  89:     int i, j, sh;
  90:     daddr_t nb, *bap;
  91: 
  92:     ip = &io->i_ino;
  93:     if (bn < 0) {
  94:         printf("bn negative\n");
  95:         return ((daddr_t)0);
  96:     }
  97: 
  98:     /*
  99: 	 * blocks 0..NDADDR are direct blocks
 100: 	 */
 101:     if(bn < NDADDR) {
 102:         nb = ip->i_db[bn];
 103:         return (nb);
 104:     }
 105: 
 106:     /*
 107: 	 * addresses NIADDR have single and double indirect blocks.
 108: 	 * the first step is to determine how many levels of indirection.
 109: 	 */
 110:     sh = 1;
 111:     bn -= NDADDR;
 112:     for (j = NIADDR; j > 0; j--) {
 113:         sh *= NINDIR(&io->i_fs);
 114:         if (bn < sh)
 115:             break;
 116:         bn -= sh;
 117:     }
 118:     if (j == 0) {
 119:         printf("bn ovf %D\n", bn);
 120:         return ((daddr_t)0);
 121:     }
 122: 
 123:     /*
 124: 	 * fetch the first indirect block address from the inode
 125: 	 */
 126:     nb = ip->i_ib[NIADDR - j];
 127:     if (nb == 0) {
 128:         printf("bn void %D\n",bn);
 129:         return ((daddr_t)0);
 130:     }
 131: 
 132:     /*
 133: 	 * fetch through the indirect blocks
 134: 	 */
 135:     for (; j <= NIADDR; j++) {
 136:         if (blknos[j] != nb) {
 137:             io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
 138:             io->i_ma = b[j];
 139:             io->i_cc = io->i_fs.fs_bsize;
 140:             if (devread(io) != io->i_fs.fs_bsize) {
 141:                 if (io->i_error)
 142:                     errno = io->i_error;
 143:                 printf("bn %D: read error\n", io->i_bn);
 144:                 return ((daddr_t)0);
 145:             }
 146:             blknos[j] = nb;
 147:         }
 148:         bap = (daddr_t *)b[j];
 149:         sh /= NINDIR(&io->i_fs);
 150:         i = (bn / sh) % NINDIR(&io->i_fs);
 151:         nb = bap[i];
 152:         if(nb == 0) {
 153:             printf("bn void %D\n",bn);
 154:             return ((daddr_t)0);
 155:         }
 156:     }
 157:     return (nb);
 158: }
 159: 
 160: static ino_t
 161: dlook(s, io)
 162:     char *s;
 163:     register struct iob *io;
 164: {
 165:     register struct direct *dp;
 166:     register struct inode *ip;
 167:     struct dirstuff dirp;
 168:     int len;
 169: 
 170:     if (s == NULL || *s == '\0')
 171:         return (0);
 172:     ip = &io->i_ino;
 173:     if ((ip->i_mode&IFMT) != IFDIR) {
 174:         printf("not a directory\n");
 175:         printf("%s: not a directory\n", s);
 176:         return (0);
 177:     }
 178:     if (ip->i_size == 0) {
 179:         printf("%s: zero length directory\n", s);
 180:         return (0);
 181:     }
 182:     len = strlen(s);
 183:     dirp.loc = 0;
 184:     dirp.io = io;
 185:     for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
 186:         if(dp->d_ino == 0)
 187:             continue;
 188:         if (dp->d_namlen == len && !strcmp(s, dp->d_name))
 189:             return (dp->d_ino);
 190:     }
 191:     return (0);
 192: }
 193: 
 194: /*
 195:  * get next entry in a directory.
 196:  */
 197: struct direct *
 198: readdir(dirp)
 199:     register struct dirstuff *dirp;
 200: {
 201:     register struct direct *dp;
 202:     register struct iob *io;
 203:     daddr_t lbn, d;
 204:     int off;
 205: 
 206:     io = dirp->io;
 207:     for(;;) {
 208:         if (dirp->loc >= io->i_ino.i_size)
 209:             return (NULL);
 210:         off = blkoff(&io->i_fs, dirp->loc);
 211:         if (off == 0) {
 212:             lbn = lblkno(&io->i_fs, dirp->loc);
 213:             d = sbmap(io, lbn);
 214:             if(d == 0)
 215:                 return NULL;
 216:             io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
 217:             io->i_ma = io->i_buf;
 218:             io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
 219:             if (devread(io) < 0) {
 220:                 errno = io->i_error;
 221:                 printf("bn %D: directory read error\n",
 222:                     io->i_bn);
 223:                 return (NULL);
 224:             }
 225:         }
 226:         dp = (struct direct *)(io->i_buf + off);
 227:         dirp->loc += dp->d_reclen;
 228:         if (dp->d_ino == 0)
 229:             continue;
 230:         return (dp);
 231:     }
 232: }
 233: 
 234: lseek(fdesc, addr, ptr)
 235:     int fdesc, ptr;
 236:     off_t addr;
 237: {
 238:     register struct iob *io;
 239: 
 240: #ifndef SMALL
 241:     if (ptr != 0) {
 242:         printf("Seek not from beginning of file\n");
 243:         errno = EOFFSET;
 244:         return (-1);
 245:     }
 246: #endif SMALL
 247:     fdesc -= 3;
 248:     if (fdesc < 0 || fdesc >= NFILES ||
 249:         ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
 250:         errno = EBADF;
 251:         return (-1);
 252:     }
 253:     io->i_offset = addr;
 254:     io->i_bn = addr / DEV_BSIZE;
 255:     io->i_cc = 0;
 256:     return (0);
 257: }
 258: 
 259: getc(fdesc)
 260:     int fdesc;
 261: {
 262:     register struct iob *io;
 263:     register struct fs *fs;
 264:     register char *p;
 265:     int c, lbn, off, size, diff;
 266: 
 267: 
 268:     if (fdesc >= 0 && fdesc <= 2)
 269:         return (getchar());
 270:     fdesc -= 3;
 271:     if (fdesc < 0 || fdesc >= NFILES ||
 272:         ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
 273:         errno = EBADF;
 274:         return (-1);
 275:     }
 276:     p = io->i_ma;
 277:     if (io->i_cc <= 0) {
 278:         if ((io->i_flgs & F_FILE) != 0) {
 279:             diff = io->i_ino.i_size - io->i_offset;
 280:             if (diff <= 0)
 281:                 return (-1);
 282:             fs = &io->i_fs;
 283:             lbn = lblkno(fs, io->i_offset);
 284:             io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
 285:             off = blkoff(fs, io->i_offset);
 286:             size = blksize(fs, &io->i_ino, lbn);
 287:         } else {
 288:             io->i_bn = io->i_offset / DEV_BSIZE;
 289:             off = 0;
 290:             size = DEV_BSIZE;
 291:         }
 292:         io->i_ma = io->i_buf;
 293:         io->i_cc = size;
 294:         if (devread(io) < 0) {
 295:             errno = io->i_error;
 296:             return (-1);
 297:         }
 298:         if ((io->i_flgs & F_FILE) != 0) {
 299:             if (io->i_offset - off + size >= io->i_ino.i_size)
 300:                 io->i_cc = diff + off;
 301:             io->i_cc -= off;
 302:         }
 303:         p = &io->i_buf[off];
 304:     }
 305:     io->i_cc--;
 306:     io->i_offset++;
 307:     c = (unsigned)*p++;
 308:     io->i_ma = p;
 309:     return (c);
 310: }
 311: 
 312: int errno;
 313: 
 314: read(fdesc, buf, count)
 315:     int fdesc, count;
 316:     char *buf;
 317: {
 318:     register i, size;
 319:     register struct iob *file;
 320:     register struct fs *fs;
 321:     int lbn, off;
 322: 
 323:     errno = 0;
 324:     if (fdesc >= 0 & fdesc <= 2) {
 325:         i = count;
 326:         do {
 327:             *buf = getchar();
 328:         } while (--i && *buf++ != '\n');
 329:         return (count - i);
 330:     }
 331:     fdesc -= 3;
 332:     if (fdesc < 0 || fdesc >= NFILES ||
 333:         ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
 334:         errno = EBADF;
 335:         return (-1);
 336:     }
 337:     if ((file->i_flgs&F_READ) == 0) {
 338:         errno = EBADF;
 339:         return (-1);
 340:     }
 341: #ifndef SMALL
 342:     if ((file->i_flgs & F_FILE) == 0) {
 343:         file->i_cc = count;
 344:         file->i_ma = buf;
 345:         file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
 346:         i = devread(file);
 347:         file->i_offset += count;
 348:         if (i < 0)
 349:             errno = file->i_error;
 350:         return (i);
 351:     }
 352: #endif SMALL
 353:     if (file->i_offset+count > file->i_ino.i_size)
 354:         count = file->i_ino.i_size - file->i_offset;
 355:     if ((i = count) <= 0)
 356:         return (0);
 357:     /*
 358: 	 * While reading full blocks, do I/O into user buffer.
 359: 	 * Anything else uses getc().
 360: 	 */
 361:     fs = &file->i_fs;
 362:     while (i) {
 363:         off = blkoff(fs, file->i_offset);
 364:         lbn = lblkno(fs, file->i_offset);
 365:         size = blksize(fs, &file->i_ino, lbn);
 366:         if (off == 0 && size <= i) {
 367:             file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
 368:                 file->i_boff;
 369:             file->i_cc = size;
 370:             file->i_ma = buf;
 371:             if (devread(file) < 0) {
 372:                 errno = file->i_error;
 373:                 return (-1);
 374:             }
 375:             file->i_offset += size;
 376:             file->i_cc = 0;
 377:             buf += size;
 378:             i -= size;
 379:         } else {
 380:             size -= off;
 381:             if (size > i)
 382:                 size = i;
 383:             i -= size;
 384:             do {
 385:                 *buf++ = getc(fdesc+3);
 386:             } while (--size);
 387:         }
 388:     }
 389:     return (count);
 390: }
 391: 
 392: #ifndef SMALL
 393: write(fdesc, buf, count)
 394:     int fdesc, count;
 395:     char *buf;
 396: {
 397:     register i;
 398:     register struct iob *file;
 399: 
 400:     errno = 0;
 401:     if (fdesc >= 0 && fdesc <= 2) {
 402:         i = count;
 403:         while (i--)
 404:             putchar(*buf++);
 405:         return (count);
 406:     }
 407:     fdesc -= 3;
 408:     if (fdesc < 0 || fdesc >= NFILES ||
 409:         ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
 410:         errno = EBADF;
 411:         return (-1);
 412:     }
 413:     if ((file->i_flgs&F_WRITE) == 0) {
 414:         errno = EBADF;
 415:         return (-1);
 416:     }
 417:     file->i_cc = count;
 418:     file->i_ma = buf;
 419:     file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
 420:     i = devwrite(file);
 421:     file->i_offset += count;
 422:     if (i < 0)
 423:         errno = file->i_error;
 424:     return (i);
 425: }
 426: #endif SMALL
 427: 
 428: int openfirst = 1;
 429: #ifdef notyet
 430: int opendev;    /* last device opened; for boot to set bootdev */
 431: extern  int bootdev;
 432: #endif notyet
 433: 
 434: open(str, how)
 435:     char *str;
 436:     int how;
 437: {
 438:     register char *cp;
 439:     int i;
 440:     register struct iob *file;
 441:     register struct devsw *dp;
 442:     int fdesc;
 443:     long atol();
 444: 
 445:     if (openfirst) {
 446:         for (i = 0; i < NFILES; i++)
 447:             iob[i].i_flgs = 0;
 448:         openfirst = 0;
 449:     }
 450: 
 451:     for (fdesc = 0; fdesc < NFILES; fdesc++)
 452:         if (iob[fdesc].i_flgs == 0)
 453:             goto gotfile;
 454:     _stop("No more file slots");
 455: gotfile:
 456:     (file = &iob[fdesc])->i_flgs |= F_ALLOC;
 457: 
 458: #ifdef notyet
 459:     for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++)
 460:             ;
 461:     if (*cp != ':') {
 462:         /* default bootstrap unit and device */
 463:         file->i_ino.i_dev = bootdev;
 464:         cp = str;
 465:     } else {
 466: # define isdigit(n) ((n>='0') && (n<='9'))
 467:         /*
 468: 	 	 * syntax for possible device name:
 469: 	 	 *	<alpha-string><digit-string><letter>:
 470: 	 	 */
 471:         for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
 472:             ;
 473:         for (dp = devsw; dp->dv_name; dp++) {
 474:             if (!strncmp(str, dp->dv_name,cp-str))
 475:                 goto gotdev;
 476:         }
 477:         printf("unknown device\n");
 478:         file->i_flgs = 0;
 479:         errno = EDEV;
 480:         return (-1);
 481:     gotdev:
 482:         i = 0;
 483:         while (*cp >= '0' && *cp <= '9')
 484:             i = i * 10 + *cp++ - '0';
 485:         if (i < 0 || i > 255) {
 486:             printf("minor device number out of range (0-255)\n");
 487:             file->i_flgs = 0;
 488:             errno = EUNIT;
 489:             return (-1);
 490:         }
 491:         if (*cp >= 'a' && *cp <= 'h') {
 492:             if (i > 31) {
 493:                 printf("unit number out of range (0-31)\n");
 494:                 file->i_flgs = 0;
 495:                 errno = EUNIT;
 496:                 return (-1);
 497:             }
 498:             i = make_minor(i, *cp++ - 'a');
 499:         }
 500: 
 501:         if (*cp++ != ':') {
 502:             printf("incorrect device specification\n");
 503:             file->i_flgs = 0;
 504:             errno = EOFFSET;
 505:             return (-1);
 506:         }
 507:         opendev = file->i_ino.i_dev = makedev(dp-devsw, i);
 508:     }
 509:     file->i_boff = 0;
 510:     devopen(file);
 511:     if (cp != str && *cp == '\0') {
 512:         file->i_flgs |= how+1;
 513:         file->i_cc = 0;
 514:         file->i_offset = 0;
 515:         return (fdesc+3);
 516:     }
 517: #else notyet
 518:     for (cp = str; *cp && *cp != '('; cp++)
 519:             ;
 520:     if (*cp != '(') {
 521:         printf("Bad device\n");
 522:         file->i_flgs = 0;
 523:         errno = EDEV;
 524:         return (-1);
 525:     }
 526:     *cp++ = '\0';
 527:     for (dp = devsw; dp->dv_name; dp++) {
 528:         if (!strcmp(str, dp->dv_name))
 529:             goto gotdev;
 530:     }
 531:     printf("Unknown device\n");
 532:     file->i_flgs = 0;
 533:     errno = ENXIO;
 534:     return (-1);
 535: gotdev:
 536:     *(cp-1) = '(';
 537:     file->i_ino.i_dev = dp-devsw;
 538:     file->i_unit = *cp++ - '0';
 539:     if (*cp >= '0' && *cp <= '9')
 540:         file->i_unit = file->i_unit * 10 + *cp++ - '0';
 541:     if (file->i_unit < 0 || file->i_unit > 63) {
 542:         printf("Bad unit specifier\n");
 543:         file->i_flgs = 0;
 544:         errno = EUNIT;
 545:         return (-1);
 546:     }
 547:     if (*cp++ != ',') {
 548: badoff:
 549:         printf("Missing offset specification\n");
 550:         file->i_flgs = 0;
 551:         errno = EOFFSET;
 552:         return (-1);
 553:     }
 554:     file->i_boff = atol(cp);
 555:     for (;;) {
 556:         if (*cp == ')')
 557:             break;
 558:         if (*cp++)
 559:             continue;
 560:         goto badoff;
 561:     }
 562:     devopen(file);
 563:     if (*++cp == '\0') {
 564:         file->i_flgs |= how+1;
 565:         file->i_cc = 0;
 566:         file->i_offset = 0;
 567:         return (fdesc+3);
 568:     }
 569: #endif notyet
 570:     file->i_ma = (char *)(&file->i_fs);
 571:     file->i_cc = SBSIZE;
 572:     file->i_bn = SBLOCK + file->i_boff;
 573:     file->i_offset = 0;
 574:     if (devread(file) < 0) {
 575:         errno = file->i_error;
 576:         printf("super block read error\n");
 577:         return (-1);
 578:     }
 579:     if ((i = find(cp, file)) == 0) {
 580:         file->i_flgs = 0;
 581:         errno = ESRCH;
 582:         return (-1);
 583:     }
 584: #ifndef SMALL
 585:     if (how != 0) {
 586:         printf("Can't write files yet.. Sorry\n");
 587:         file->i_flgs = 0;
 588:         errno = EIO;
 589:         return (-1);
 590:     }
 591: #endif SMALL
 592:     if (openi(i, file) < 0) {
 593:         errno = file->i_error;
 594:         return (-1);
 595:     }
 596:     file->i_offset = 0;
 597:     file->i_cc = 0;
 598:     file->i_flgs |= F_FILE | (how+1);
 599:     return (fdesc+3);
 600: }
 601: 
 602: close(fdesc)
 603:     int fdesc;
 604: {
 605:     struct iob *file;
 606: 
 607:     fdesc -= 3;
 608:     if (fdesc < 0 || fdesc >= NFILES ||
 609:         ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
 610:         errno = EBADF;
 611:         return (-1);
 612:     }
 613:     if ((file->i_flgs&F_FILE) == 0)
 614:         devclose(file);
 615:     file->i_flgs = 0;
 616:     return (0);
 617: }
 618: 
 619: #ifndef SMALL
 620: ioctl(fdesc, cmd, arg)
 621:     int fdesc, cmd;
 622:     char *arg;
 623: {
 624:     register struct iob *file;
 625:     int error = 0;
 626: 
 627:     fdesc -= 3;
 628:     if (fdesc < 0 || fdesc >= NFILES ||
 629:         ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
 630:         errno = EBADF;
 631:         return (-1);
 632:     }
 633:     switch (cmd) {
 634: 
 635:     case SAIOHDR:
 636:         file->i_flgs |= F_HDR;
 637:         break;
 638: 
 639:     case SAIOCHECK:
 640:         file->i_flgs |= F_CHECK;
 641:         break;
 642: 
 643:     case SAIOHCHECK:
 644:         file->i_flgs |= F_HCHECK;
 645:         break;
 646: 
 647:     case SAIONOBAD:
 648:         file->i_flgs |= F_NBSF;
 649:         break;
 650: 
 651:     case SAIODOBAD:
 652:         file->i_flgs &= ~F_NBSF;
 653:         break;
 654: 
 655:     default:
 656:         error = devioctl(file, cmd, arg);
 657:         break;
 658:     }
 659:     if (error < 0)
 660:         errno = file->i_error;
 661:     return (error);
 662: }
 663: #endif SMALL
 664: 
 665: exit()
 666: {
 667:     _stop("Exit called");
 668: }
 669: 
 670: _stop(s)
 671:     char *s;
 672: {
 673:     int i;
 674: 
 675:     for (i = 0; i < NFILES; i++)
 676:         if (iob[i].i_flgs != 0)
 677:             close(i);
 678:     printf("%s\n", s);
 679:     _rtt();
 680: }

Defined functions

dlook defined in line 160; used 2 times
find defined in line 39; used 1 times
ioctl defined in line 620; used 15 times
openi defined in line 22; used 3 times
readdir defined in line 197; used 3 times
sbmap defined in line 83; used 3 times

Defined variables

errno defined in line 312; used 60 times
opendev defined in line 430; used 1 times
openfirst defined in line 428; used 2 times

Defined struct's

dirstuff defined in line 17; used 4 times

Defined macros

isdigit defined in line 466; used 1 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1995
Valid CSS Valid XHTML 1.0 Strict