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