1: #ifndef lint
   2: static char sccsid[] = "@(#)unixtraps.c	4.3 84/05/05";
   3: #endif
   4: 
   5: /* From Lou Salkind: compat/RCS/unixtraps.c,v 1.2 84/01/31 13:34:34 */
   6: 
   7: /*
   8:  * Function to execute version 6 and version 7 UNIX system calls from
   9:  * compatability mode on UNIX-32V.
  10:  *	Art Wetzel	August 1979
  11:  */
  12: 
  13: #include <stdio.h>
  14: #include <signal.h>
  15: #include <sys/types.h>
  16: #include <sys/stat.h>
  17: #include <sys/ioctl.h>
  18: #include <sys/time.h>
  19: #include <sys/dir.h>
  20: #ifdef V6UNIX
  21: #ifdef TRACE
  22: #define RTSNAME "/../../../../usr/local/v6trc"
  23: #else
  24: #define RTSNAME "/../../../../usr/local/v6run"
  25: #endif
  26: #include "unix6sys.h"
  27: #ifdef TRACE
  28: #include "unix6sysn.h"
  29: #endif
  30: #endif
  31: #ifdef V7UNIX
  32: #ifdef TRACE
  33: #define RTSNAME "/../../../../usr/local/v7trc"
  34: #else
  35: #define RTSNAME "/../../../../usr/local/v7run"
  36: #endif
  37: #include "unix7sys.h"
  38: #ifdef TRACE
  39: #include "unix7sysn.h"
  40: #endif
  41: #endif
  42: #include "defs.h"
  43: #define CARRY   1
  44: #define MAXSARGS    100
  45: #ifdef V6UNIX
  46: #define ARGVLEN 512
  47: #define ENVLEN  0
  48: #endif
  49: #ifdef V7UNIX
  50: #define ARGVLEN 5120
  51: #define ENVLEN  1000
  52: #endif
  53: char    argvs[ARGVLEN+ENVLEN];
  54: int args[MAXSARGS];
  55: 
  56: /* 32v type stat structure */
  57: extern struct   stat    stat32v;
  58: 
  59: /* place for times data so we can reverse the longs */
  60: struct timebuf {
  61:     long    t1;
  62:     long    t2;
  63:     long    t3;
  64:     long    t4;
  65: } timebuf;
  66: 
  67: /* place for pipe file descriptors */
  68: int pipes[2];
  69: 
  70: /* wait status */
  71: int wstatus;
  72: 
  73: #ifdef  V6UNIX
  74: /* version 6 style stat structure */
  75: struct v6nod {
  76:     dev_t   majmin;
  77:     ino_t   inumber;
  78:     unsigned short  flags;
  79:     unsigned char   nlinks;
  80:     unsigned char   uid;
  81:     unsigned char   gid;
  82:     unsigned char   size0;
  83:     unsigned short  size1;
  84:     unsigned short  addr[8];
  85:     long    actime;
  86:     long    modtime;
  87: } *v6stat;
  88: #endif
  89: 
  90: #ifdef  V7UNIX
  91: /* version 7 style stat structure */
  92: struct  v7stat {
  93:     dev_t   v7st_dev;
  94:     u_short v7st_ino;
  95:     u_short v7st_mode;
  96:     short   v7st_nlink;
  97:     short   v7st_uid;
  98:     short   v7st_gid;
  99:     dev_t   v7st_rdev;
 100:     int v7st_size;
 101:     int v7st_atime;
 102:     int v7st_mtime;
 103:     int v7st_ctime;
 104: } statv7;
 105: 
 106: struct timeb {
 107:     time_t  time;
 108:     u_short millitm;
 109:     short   timezone;
 110:     short   dstflag;
 111: } timeb;
 112: #endif
 113: 
 114: #define NFILES  20
 115: #define ODSIZE  16
 116: 
 117: off_t   olseek();
 118: 
 119: struct odirect {
 120:     u_short od_ino;
 121:     char    od_name[14];
 122: };
 123: 
 124: struct fdflags {
 125:     DIR *fd_dirp;
 126:     struct odirect  fd_od;
 127:     off_t   fd_offset;
 128: } fdflags[NFILES];
 129: 
 130: /* do the trap stuff for the trap with code */
 131: dotrap(code)
 132:     int code;
 133: {
 134:     register unsigned short *argp, *savp, *savep;
 135:     register int i, j, indirflg;
 136:     register char *avp, *oavp;
 137:     extern sigcatch();
 138:     extern errno;
 139:     extern int sigtrapped;
 140:     DIR *dp;
 141: 
 142:     sigtrapped = 0;
 143:     /* clear out condition codes of psl */
 144:     psl &= ~017;
 145:     /* special case of indirect sys call */
 146:     if (code == 0) {
 147:         /* remember this was indirect */
 148:         indirflg = 1;
 149:         /* point to args */
 150:         argp = (unsigned short *)*(pc++);
 151:         /* code for indirect sys call */
 152:         code = *argp++;
 153:         /* is it legit */
 154:         if (code>>8 != TRAPS) {
 155:             fprintf(stderr,"Bad indirect sys call at 0x%x\n",pc-2);
 156:             pc++;
 157:             /* set carry flag */
 158:             psl |= CARRY;
 159:             regs[0] = -1;
 160:             return(-1);
 161:         }
 162:         code &= 0377;
 163:     } else {
 164:         /* remember this was not indirect */
 165:         indirflg = 0;
 166:         /* point to args */
 167:         argp = pc;
 168:     }
 169:     /* check if code too high or bad sys code */
 170:     if (code >= NSYSTRAPS || sysargs[code][0] == ILLSYS) {
 171:         fprintf(stderr,"Unimplimented trap %d at 0x%x\n",code,argp);
 172:         /* set carry bit */
 173:         psl |= CARRY;
 174:         regs[0] = -1;
 175:         return(-1);
 176:     }
 177:     /* copy args to known locations */
 178:     i=0;
 179:     for (j=0; j<sysargs[code][0]; j++)
 180:         args[i++] = regs[j];
 181:     for (j=0; j<(sysargs[code][1]); j++)
 182:         args[i++] = *argp++;
 183: #ifdef TRACE
 184:     fprintf(stderr,"pid %d ",getpid());
 185:     if (indirflg)
 186:         fprintf(stderr,"indirect ");
 187:     fprintf(stderr, "%s (%d) from 0%o with %d args",
 188:         sysnames[code], code, pc-1, i);
 189:     for (j=0; j<i; j++)
 190:         fprintf(stderr," 0%o",args[j]);
 191:     if (code==OPEN || code==STAT || code==CREAT || code==EXEC ||
 192:         code==UNLNK || code==LINK || code==CHDIR || code==MKNOD)
 193:         fprintf(stderr," (%s)",args[0]);
 194: #ifdef V7UNIX
 195:     if (code==EXECE)
 196:         fprintf(stderr," (%s)",args[0]);
 197: #endif
 198:     if (code==LINK)
 199:         fprintf(stderr," (%s)",args[1]);
 200: #endif
 201:     /* go do whatever sys call it is */
 202:     switch (code) {
 203:     case FORK:
 204:         /* indirect forks return pids on both sides - must do here */
 205:         /* this is possibly a bug in 32V */
 206:         i = fork();
 207:         break;
 208: 
 209:     case WAIT:
 210:         i = wait(&wstatus);
 211:         args[0] = i;
 212:         args[1] = wstatus;
 213:         break;
 214: 
 215:     case EXEC:
 216: #ifdef V7UNIX
 217:     case EXECE:
 218: #endif
 219:         /*
 220: 		 *  have to do a lot of junk here to fix up an argv
 221: 		 *  for execute since (1) the pdp-11 argv consists of 16
 222: 		 *  bit pointers and (2) the argv itself is in the
 223: 		 *  pdp-11 program space where it would get clobbered
 224: 		 *  when a new program is read in and before its
 225: 		 *  argv is set up.
 226: 		 */
 227:         avp = &argvs[0];
 228:         savp = (unsigned short *)args[1];
 229: #ifdef  V6UNIX
 230:         for (i=1; args[i] = *savp++; i++)
 231:             if (args[i] == 0177777)
 232:                 break;
 233: #ifdef  TRACE
 234:             else
 235:                 fprintf(stderr,"argv[%d]%s ",i-1,args[i]);
 236: #endif
 237: #endif
 238: #ifdef  V7UNIX
 239:         savep = (unsigned short *)args[2];
 240:         for (i=1; args[i] = *savp++; i++)
 241: #ifdef  TRACE
 242:             fprintf(stderr,"argv[%d]%s ",i-1,args[i]);
 243: #else
 244:             ;
 245: #endif
 246: #endif
 247:         if (stat(args[0], &stat32v)) {
 248:             /* return error here if file does not exist */
 249: #ifdef  TRACE
 250:             fprintf(stderr," does not exist\n");
 251: #endif
 252:             i = -1;
 253:             break;
 254:         }
 255:         /* must have execute permission */
 256:         if (stat32v.st_mode & (S_IEXEC>>6))
 257:             goto experm;
 258:         if (stat32v.st_mode & (S_IEXEC>>3)) {
 259:             if (stat32v.st_gid == getegid())
 260:                 goto experm;
 261:             if (geteuid() == 0)
 262:                 goto experm;
 263:         }
 264:         if (stat32v.st_mode & S_IEXEC) {
 265:             if (stat32v.st_uid == geteuid())
 266:                 goto experm;
 267:             if (geteuid() == 0)
 268:                 goto experm;
 269:         }
 270:         /* return failure if no exec permision allowed */
 271:         i = -1;
 272: experm:
 273:         /* can't exec a directory */
 274:         if ((stat32v.st_mode&S_IFMT) == S_IFDIR)
 275:             i = -1;
 276:         if (i == -1)
 277:             break;
 278:         args[i] = 0;
 279:         for (j=1; j<i; j++) {
 280:             oavp = (char *)args[j];
 281:             args[j] = (int)avp;
 282:             while (*avp++ = *oavp++)
 283:                 ;
 284:         }
 285: #ifdef V7UNIX
 286:         if (code == EXECE) {
 287:             for (j = ++i; args[j] = *savep++; j++)
 288:                 ;
 289:             for (j = i; oavp = (char *)args[j]; j++) {
 290:                 args[j] = (int)avp;
 291:                 while (*avp++ = *oavp++)
 292:                     ;
 293:             }
 294:         }
 295: #endif
 296:         /* SETUID and SETGID files must be started with a fresh RTS */
 297:         if (stat32v.st_mode & S_ISGID || stat32v.st_mode & S_ISUID) {
 298:             /* should add a check here for good magic # in header */
 299:             args[1] = args[0];
 300:             args[0] = (int)RTSNAME;
 301: #ifdef TRACE
 302:             fprintf(stderr," SETUID-GID");
 303: #endif
 304:             if (args[i])
 305:                 i = execve(args[0], &args[0], &args[i]);
 306:             else
 307:                 i = execv(args[0], &args[0]);
 308:             fprintf(stderr,"can't exec %s\n",RTSNAME);
 309:             break;
 310:         }
 311:         i = execute(args[0], &args[1], &args[i]);
 312:         /* shouldn't get here if exec works */
 313:         break;
 314: 
 315:     case SEEK:
 316: #ifdef  V6UNIX
 317:         /* fix up negative offsets */
 318:         if (args[2] != 0 && args[2] != 3)
 319:             if (args[1] >= 32768)
 320:                 args[1] -= 65536;
 321:         if (args[2] <= 2)
 322:             i = olseek(args[0], args[1], args[2]);
 323:         else
 324:             i = olseek(args[0], args[1]*512, args[2]-3);
 325:         if (i != -1)
 326:             i = 0;
 327: #endif
 328: #ifdef  V7UNIX
 329:         i = olseek(args[0], (args[1]<<16)|(args[2]&0177777), args[3]);
 330: #endif
 331:         break;
 332: 
 333:     case MKNOD:
 334:         if ((args[1] & S_IFMT) == S_IFDIR)
 335:             i = mkdir(args[0], args[1] & 0777);
 336:         else {
 337: #ifdef  V6UNIX
 338:             /*
 339: 			 * version 6 uses allocated bit which
 340: 			 * means regular file here
 341: 			 */
 342:             if (args[1] & S_IFBLK)
 343:                 args[1] &= ~S_IFREG;
 344: #endif
 345:             i = mknod(args[0], args[1], args[2]);
 346:         }
 347:         break;
 348: 
 349:     case PIPE:
 350:         i = pipe(pipes);
 351:         args[0] = pipes[0];
 352:         args[1] = pipes[1];
 353:         break;
 354: 
 355: #ifdef  V6UNIX
 356:     case TELL:
 357:         i = lseek(args[0], 0L, 1);
 358:         break;
 359: 
 360:     case STTY:
 361:         i = stty(args[0], args[1]);
 362:         break;
 363: 
 364:     case GTTY:
 365:         i = gtty(args[0], args[1]);
 366:         break;
 367: #endif
 368: 
 369:     /* HAVE TO FAKE THE SIZE OF DIRECTORIES */
 370: 
 371:     case STAT:
 372:         i = stat(args[0], &stat32v);
 373:         goto allstat;
 374: 
 375:     case FSTAT:
 376:         /* do the syscall to a local stat buffer */
 377:         i = fstat(args[0], &stat32v);
 378: 
 379:     allstat:
 380:         /* reverse the longs */
 381:         stat32v.st_size = longrev(stat32v.st_size);
 382:         stat32v.st_atime = longrev(stat32v.st_atime);
 383:         stat32v.st_mtime = longrev(stat32v.st_mtime);
 384:         stat32v.st_ctime = longrev(stat32v.st_ctime);
 385: #ifdef V7UNIX
 386:         statv7.v7st_dev = stat32v.st_dev;
 387:         statv7.v7st_ino = stat32v.st_ino;
 388:         statv7.v7st_mode = stat32v.st_mode;
 389:         statv7.v7st_nlink = stat32v.st_nlink;
 390:         statv7.v7st_uid = stat32v.st_uid;
 391:         statv7.v7st_gid = stat32v.st_gid;
 392:         statv7.v7st_rdev = stat32v.st_rdev;
 393:         statv7.v7st_size = stat32v.st_size;
 394:         statv7.v7st_atime = stat32v.st_atime;
 395:         statv7.v7st_mtime = stat32v.st_mtime;
 396:         statv7.v7st_ctime = stat32v.st_ctime;
 397:         /* copy out otherwise unchanged stat buffer */
 398:         /* in two pieces with st_size as the breaking point */
 399:         /* note that st_rdev is a short but due to alingnmemt */
 400:         /* problems the rest of the structure is out of sync */
 401:         j = (int)((char *)(&statv7.v7st_size) -
 402:             (char *)(&statv7.v7st_dev));
 403:         bcopy(&statv7, args[1], j);
 404:         bcopy(&statv7.v7st_size, args[1]+j-2, sizeof(struct v7stat)-j);
 405: #endif
 406: #ifdef  V6UNIX
 407:         /* point to user area as v6stat structure */
 408:         v6stat = (struct v6nod *)args[1];
 409:         /* copy out piece by piece */
 410:         v6stat->majmin = stat32v.st_dev;
 411:         v6stat->inumber = stat32v.st_ino;
 412:         v6stat->flags = stat32v.st_mode;
 413:         v6stat->nlinks = (unsigned char)stat32v.st_nlink;
 414:         v6stat->uid = (unsigned char)stat32v.st_uid;
 415:         v6stat->gid = (unsigned char)stat32v.st_gid;
 416:         /* note size already reversed */
 417:         v6stat->size0 = (unsigned char)(stat32v.st_size & 0377);
 418:         v6stat->size1 = (unsigned short)(stat32v.st_size>>16);
 419:         v6stat->actime = stat32v.st_atime;
 420:         v6stat->modtime = stat32v.st_mtime;
 421:         /* patch up flags */
 422:         /* for now just set 100000 bit if not a plain file */
 423:         if (v6stat->flags & 060000)
 424:             v6stat->flags |= 0100000;
 425: #endif
 426:         break;
 427: 
 428:     case TIMES:
 429:         i = times(&timebuf);
 430:         timebuf.t2 = longrev(timebuf.t2) + timebuf.t1;
 431:         timebuf.t3 = longrev(timebuf.t3);
 432:         timebuf.t4 = longrev(timebuf.t4);
 433:         bcopy(&timebuf.t2,args[0],sizeof(struct timebuf)-sizeof(long));
 434:         break;
 435: 
 436: #ifdef  V6UNIX
 437:     case SLEEP:
 438:         /* do a sleep function - what about pwb which has alarm? */
 439:         sleep(args[0]);
 440:         break;
 441: #endif
 442: 
 443:     case GETUID:
 444:         args[0] = getuid();
 445:         args[1] = geteuid();
 446: #ifdef V6UNIX
 447:         i = args[1]<<8 | (args[0] & 0377);
 448: #endif
 449:         break;
 450: 
 451:     case GETGID:
 452:         args[0] = getgid();
 453:         args[1] = getegid();
 454: #ifdef V6UNIX
 455:         i = args[1]<<8 | (args[0] & 0377);
 456: #endif
 457:         break;
 458: 
 459:         /* uids and gids are 8 bits in version 6 */
 460:     case SETUID:
 461:     case SETGID:
 462: #ifdef V6UNIX
 463:         args[0] &= 0377;
 464: #endif
 465:         if (code == SETUID)
 466:             i = setuid(args[0]);
 467:         else
 468:             i = setgid(args[0]);
 469:         break;
 470: 
 471:     case SIG:
 472:         /* if it is a good signal code */
 473:         if (args[0] <= NSIG) {
 474:             /* get the current signal value */
 475:             i = sigvals[args[0]];
 476:             /* reset the signal to the new value */
 477:             sigvals[args[0]] = args[1];
 478:             /* actually do signal except don't reset SIGILL */
 479:             if (args[0] != SIGILL) {
 480:                 if (args[1] == (int)SIG_DFL ||
 481:                     args[1] & (int)SIG_IGN) {
 482:                     if ((int)signal(args[0],args[1]) == -1)
 483:                         i = -1;
 484:                 } else {
 485:                     if ((int)signal(args[0],sigcatch) == -1)
 486:                         i = -1;
 487:                 }
 488:             }
 489:         } else
 490:             i = -1;
 491:         break;
 492: 
 493:     case BRK:
 494:         /* brk is successful unless we run over the stack */
 495:         /* NB: this assumes register usage which need not be used */
 496:         i = 0;
 497:         if (args[0] >= regs[6])
 498:             i = -1;
 499:         break;
 500: 
 501:     /*
 502: 	 * the next bunch are to cope with sys calls removed from 4.2
 503: 	 */
 504:     case TIME:
 505:         i = time(0);
 506:         break;
 507: 
 508:     case STIME: {
 509:         struct timeval tv;
 510: 
 511:         tv.tv_usec = 0;
 512:         tv.tv_sec = (args[0] & 0xffff) | ((args[1] & 0xffff) << 16);
 513:         i = settimeofday(&tv);
 514:         break;
 515:     }
 516: 
 517:     case NICE:
 518:         i = nice(args[0]);
 519:         break;
 520: 
 521: #ifdef V7UNIX
 522:     case ALARM:
 523:         i = alarm(args[0]);
 524:         break;
 525: 
 526:     case PAUSE:
 527:         i = pause();
 528:         break;
 529: 
 530:     case UTIME:
 531:         i = utime(args[0], args[1]);
 532:         break;
 533: 
 534:     case FTIME:
 535:         i = ftime(&timeb);
 536:         timeb.time = longrev(timeb.time);
 537:         bcopy(&timeb, args[0], sizeof timeb - 2);
 538:         break;
 539: 
 540:     case IOCTL:
 541:         args[1] = mapioctl(args[1]);
 542:         if (args[1] == 0)
 543:             i = -1;
 544:         else
 545:             i = ioctl(args[0], args[1], args[2]);
 546:         break;
 547: #endif
 548: 
 549: #ifdef  V6UNIX
 550:     case PWBSYS:
 551:         /* ignore pwbsys for now */
 552:         switch (args[2]) {
 553:         case UNAME:
 554: #ifdef  TRACE
 555:             fprintf(stderr,"UNAME with %d %d\n",args[0],args[1]);
 556: #endif
 557:             strcpy(args[0],"pwbname");
 558:             i = 0;
 559:             break;
 560: 
 561:         case UDATA:
 562: #ifdef  TRACE
 563:             fprintf(stderr,"UDATA with %d %d\n",args[0],args[1]);
 564: #endif
 565:             i = 0;
 566:             break;
 567: 
 568:         case USTAT:
 569: fprintf(stderr,"USTAT with %d %d\n",args[0],args[1]);
 570:             i = 0;
 571:             break;
 572: 
 573:         case UTIME:
 574: fprintf(stderr,"UTIME with %d %d\n",args[0],args[1]);
 575:             i = 0;
 576:             break;
 577:         default:
 578: fprintf(stderr,"bad PWBSYS %d\n",args[3]);
 579:             i = -1;
 580:             break;
 581:         }
 582:         break;
 583: #endif
 584: 
 585:     default:
 586:         /*
 587: 		 *	Many sys calls are easily done here since most
 588: 		 *	system call codes are the same on version 6 and 7 UNIX
 589: 		 *	as they are here.
 590: 		 */
 591:         i = syscall(code,args[0],args[1],args[2],args[3],args[4]);
 592: #ifdef V6UNIX
 593:         /* allow read write access to created files for (IDIS v6 mod) */
 594:         if (code==CREAT) {
 595:             /* get actual file mode after create */
 596:             fstat(i, &stat32v);
 597:             close(i);
 598:             /* ensure read/write access to owner */
 599:             chmod(args[0], 0644);
 600:             i = open(args[0], 2);
 601:             /* change mode back the way it was */
 602:             chmod(args[0], stat32v.st_mode);
 603:         }
 604: #endif
 605:         break;
 606:     case OPEN:
 607:         /*
 608: 		 * check if we are opening a directory
 609: 		 */
 610:         if (stat(args[0], &stat32v) >= 0  &&
 611:             ((stat32v.st_mode & S_IFMT) == S_IFDIR) &&
 612:             ((dp = opendir(args[0])) != NULL)) {
 613: #ifdef DTRACE
 614:             fprintf(stderr,"open directory fd %d\n", i);
 615: #endif
 616:             i = dp->dd_fd;
 617:             fdflags[i].fd_dirp = dp;
 618:             fdflags[i].fd_offset = 0;
 619:         } else
 620:             i = open(args[0], args[1]);
 621:         break;
 622:     case CLOSE:
 623:         i = close(args[0]);
 624:         if (i >= 0 && fdflags[args[0]].fd_dirp) {
 625:             closedir(fdflags[args[0]].fd_dirp);
 626:             fdflags[args[0]].fd_dirp = 0;
 627:         }
 628:         break;
 629:     case READ:
 630:         if ((unsigned)args[0] < NFILES && fdflags[args[0]].fd_dirp)
 631:             i = oread(args[0], args[1], args[2]);
 632:         else
 633:             i = read(args[0], args[1], args[2]);
 634:         break;
 635:     }
 636: #ifdef TRACE
 637:     fprintf(stderr," sys val -> 0%o\n",i);
 638: #endif
 639:     /* set carry bit if sys error */
 640:     if (i == -1)
 641:         psl |= CARRY;
 642:     /* if not an indirect sys call, adjust the pc */
 643:     if (!indirflg && !sigtrapped)
 644:         pc = argp;
 645:     /* do alternate return on one side of fork */
 646:     if (code == FORK && i != 0)
 647:         pc++;
 648:     /* do the various return value formats */
 649:     switch (sysargs[code][2]) {
 650:     case NORMRET:
 651:         /* normal case only one return value in r0 */
 652:         regs[0] = i;
 653:         break;
 654:     case LONGRET:
 655:         /* return a long in r0 - r1 as in time */
 656:         regs[1] = i;
 657:         regs[0] = i >> 16;
 658:         break;
 659:     case TWORET:
 660:         /* return two ints in r0 - r1 as in pipe */
 661:         if (i == -1)
 662:             regs[0] = i;
 663:         else {
 664:             regs[1] = args[1];
 665:             regs[0] = args[0];
 666:         }
 667:         break;
 668:     }
 669:     if (i== -1)
 670:         regs[0] = errno;
 671: }
 672: 
 673: long
 674: longrev(l)
 675:     long l;
 676: {
 677:     /* function to reverse the halves of a long */
 678:     union {
 679:         long    lng;
 680:         short   s[2];
 681:     } u;
 682:     register short t;
 683:     u.lng = l;
 684:     t = u.s[0];
 685:     u.s[0] = u.s[1];
 686:     u.s[1] = t;
 687:     return(u.lng);
 688: }
 689: 
 690: /*
 691:  * Note: these tables are sorted by
 692:  * ioctl "code" (in ascending order).
 693:  */
 694: int fctls[] = { FIOCLEX, FIONCLEX, FIOASYNC, FIONBIO, FIONREAD, 0 };
 695: int tctls[] = {
 696:     TIOCGETD, TIOCSETD, TIOCHPCL, TIOCMODG, TIOCMODS,
 697:     TIOCGETP, TIOCSETP, TIOCSETN, TIOCEXCL, TIOCNXCL,
 698:     TIOCFLUSH,TIOCSETC, TIOCGETC, TIOCREMOTE,TIOCMGET,
 699:     TIOCMBIC, TIOCMBIS, TIOCMSET, TIOCSTART,TIOCSTOP,
 700:     TIOCPKT,  TIOCNOTTY,TIOCSTI,  TIOCOUTQ, TIOCGLTC,
 701:     TIOCSLTC, TIOCSPGRP,TIOCGPGRP,TIOCCDTR, TIOCSDTR,
 702:     TIOCCBRK, TIOCSBRK, TIOCLGET, TIOCLSET, TIOCLBIC,
 703:     TIOCLBIS, 0
 704: };
 705: 
 706: /*
 707:  * Map an old style ioctl command to new.
 708:  */
 709: mapioctl(cmd)
 710:     int cmd;
 711: {
 712:     register int *map, c;
 713: 
 714:     switch ((cmd >> 8) & 0xff) {
 715: 
 716:     case 'f':
 717:         map = fctls;
 718:         break;
 719: 
 720:     case 't':
 721:         map = tctls;
 722:         break;
 723: 
 724:     default:
 725:         return (0);
 726:     }
 727:     while ((c = *map) && (c&0xff) < (cmd&0xff))
 728:         map++;
 729:     if (c && (c&0xff) == (cmd&0xff))
 730:         return (c);
 731:     return (0);
 732: }
 733: 
 734: /*
 735:  * emulate a read of n bytes on an old style directory
 736:  */
 737: oread(fd, buf, count)
 738: int fd, count;
 739: char *buf;
 740: {
 741:     struct fdflags *fp;
 742:     struct direct *dp;
 743:     DIR *dirp;
 744:     struct odirect *odp;
 745:     register int nleft = count;
 746:     int dir_off;
 747:     int i;
 748: 
 749:     fp = &fdflags[fd];
 750:     dirp = fp->fd_dirp;
 751:     odp = &fp->fd_od;
 752:     if (dirp == NULL)
 753:         return(-1);
 754:     dir_off = fp->fd_offset % ODSIZE;
 755:     if (dir_off) {
 756:         i = ODSIZE - dir_off;
 757:         if (nleft < i)
 758:             i = nleft;
 759:         bcopy((caddr_t)odp + dir_off, buf, i);
 760:         fp->fd_offset += i;
 761:         if (i == nleft)
 762:             return(i);
 763:         buf += i;
 764:         nleft -= i;
 765:     }
 766:     while (nleft >= ODSIZE) {
 767:         if ((dp = readdir(dirp)) == NULL)
 768:             return(count - nleft);
 769:         odp->od_ino = dp->d_ino;
 770:         strncpy(odp->od_name, dp->d_name, 14);
 771:         bcopy((caddr_t)odp, buf, ODSIZE);
 772:         fp->fd_offset += ODSIZE;
 773:         buf += ODSIZE;
 774:         nleft -= ODSIZE;
 775:     }
 776:     if (nleft > 0) {
 777:         if ((dp = readdir(dirp)) == NULL)
 778:             return(count - nleft);
 779:         odp->od_ino = dp->d_ino;
 780:         strncpy(odp->od_name, dp->d_name, 14);
 781:         bcopy((caddr_t)odp, buf, nleft);
 782:         fp->fd_offset += nleft;
 783:         /* nleft = 0; */
 784:     }
 785:     return(count);
 786: }
 787: 
 788: /*
 789:  * emulate the lseek system call
 790:  */
 791: off_t
 792: olseek(fd, n, whence)
 793: int fd, whence;
 794: off_t n;
 795: {
 796:     struct fdflags *fp;
 797:     char buf[512];
 798:     off_t newpos;
 799:     int i, j;
 800: 
 801:     if ((unsigned)fd >= NFILES)
 802:         return(-1);
 803:     fp = &fdflags[fd];
 804:     /*
 805: 	 * the system can handle everything
 806: 	 * except directory files
 807: 	 */
 808:     if (fp->fd_dirp == NULL)
 809:         return(lseek(fd, n, whence));
 810:     switch (whence) {
 811:     case 0:
 812:         newpos = n;
 813:         break;
 814:     case 1:
 815:         newpos = fp->fd_offset + n;
 816:         break;
 817:     case 2:     /* not yet implemented */
 818:     default:
 819:         return(-1);
 820:     }
 821:     if (newpos < 0)
 822:         return(-1);
 823:     if (newpos < fp->fd_offset) {
 824:         rewinddir(fdflags[fd].fd_dirp);
 825:         fp->fd_offset = 0;
 826:     }
 827:     i = newpos - fp->fd_offset;
 828:     while (i > 0) {
 829:         j = i < 512 ? i : 512;
 830:         if (oread(fd, buf, j) != j)
 831:             break;
 832:         i -= j;
 833:     }
 834:     return(fp->fd_offset);
 835: }

Defined functions

dotrap defined in line 131; used 1 times
longrev defined in line 673; used 8 times
mapioctl defined in line 709; used 1 times
olseek defined in line 791; used 4 times
oread defined in line 737; used 2 times

Defined variables

args defined in line 54; used 143 times
argvs defined in line 53; used 1 times
fctls defined in line 694; used 1 times
fdflags defined in line 128; used 9 times
pipes defined in line 68; used 3 times
sccsid defined in line 2; never used
statv7 defined in line 104; used 15 times
tctls defined in line 695; used 1 times
timeb defined in line 111; used 5 times
timebuf defined in line 65; used 9 times
v6stat defined in line 87; used 13 times
wstatus defined in line 71; used 2 times

Defined struct's

fdflags defined in line 124; used 4 times
odirect defined in line 119; used 4 times
timeb defined in line 106; never used
timebuf defined in line 60; used 2 times
  • in line 433(2)
v6nod defined in line 75; used 2 times
  • in line 408(2)
v7stat defined in line 92; used 2 times
  • in line 404(2)

Defined macros

ARGVLEN defined in line 50; used 1 times
  • in line 53
CARRY defined in line 43; used 3 times
ENVLEN defined in line 51; used 1 times
  • in line 53
MAXSARGS defined in line 44; used 1 times
  • in line 54
NFILES defined in line 114; used 3 times
ODSIZE defined in line 115; used 7 times
RTSNAME defined in line 35; used 2 times
Last modified: 1984-05-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2039
Valid CSS Valid XHTML 1.0 Strict