|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.