|
|
1.1 ! root 1: # ! 2: /* Function to execute version 6 and version 7 UNIX system calls from ! 3: * compatability mode on UNIX-32V. ! 4: * Art Wetzel August 1979 ! 5: */ ! 6: #include <stdio.h> ! 7: #include <signal.h> ! 8: #include <sys/types.h> ! 9: #include <sys/stat.h> ! 10: #ifdef V6UNIX ! 11: #ifdef TRACE ! 12: #define RTSNAME "/../../../../usr/local/v6trc" ! 13: #else ! 14: #define RTSNAME "/../../../../usr/local/v6run" ! 15: #endif ! 16: #include "unix6sys.h" ! 17: #ifdef TRACE ! 18: #include "unix6sysn.h" ! 19: #endif ! 20: #endif ! 21: #ifdef V7UNIX ! 22: #ifdef TRACE ! 23: #define RTSNAME "/../../../../usr/local/v7trc" ! 24: #else ! 25: #define RTSNAME "/../../../../usr/local/v7run" ! 26: #endif ! 27: #include "unix7sys.h" ! 28: #ifdef TRACE ! 29: #include "unix7sysn.h" ! 30: #endif ! 31: #endif ! 32: #include "defs.h" ! 33: #define CARRY 1 ! 34: #define MAXSARGS 25 ! 35: #ifdef V6UNIX ! 36: #define ARGVLEN 512 ! 37: #define ENVLEN 0 ! 38: #endif ! 39: #ifdef V7UNIX ! 40: #define ARGVLEN 5120 ! 41: #define ENVLEN 1000 ! 42: #endif ! 43: char argvs[ARGVLEN+ENVLEN]; ! 44: int args[MAXSARGS]; ! 45: /* 32v type stat structure */ ! 46: extern struct stat stat32v; ! 47: /* place for times data so we can reverse the longs */ ! 48: struct timebuf { ! 49: long t1; ! 50: long t2; ! 51: long t3; ! 52: long t4; ! 53: } timebuf; ! 54: /* place for pipe file descriptors */ ! 55: int pipes[2]; ! 56: /* wait status */ ! 57: int wstatus; ! 58: #ifdef V6UNIX ! 59: /* version 6 style stat structure */ ! 60: struct v6nod { ! 61: dev_t majmin; ! 62: ino_t inumber; ! 63: unsigned short flags; ! 64: unsigned char nlinks; ! 65: unsigned char uid; ! 66: unsigned char gid; ! 67: unsigned char size0; ! 68: unsigned short size1; ! 69: unsigned short addr[8]; ! 70: long actime; ! 71: long modtime; ! 72: } *v6stat; ! 73: #endif ! 74: /* do the trap stuff for the trap with code */ ! 75: dotrap(code) int code; { ! 76: register unsigned short *argp, *savp, *savep; ! 77: register int i, j, indirflg; ! 78: register char *avp, *oavp; ! 79: extern sigcatch(); ! 80: extern errno; ! 81: /* clear out condition codes of psl */ ! 82: psl &= ~017; ! 83: /* special case of indirect sys call */ ! 84: if(code == 0) { ! 85: /* remember this was indirect */ ! 86: indirflg = 1; ! 87: /* point to args */ ! 88: argp = (unsigned short *)*(pc++); ! 89: /* code for indirect sys call */ ! 90: code = *argp++; ! 91: /* is it legit */ ! 92: if(code>>8 != TRAPS) { ! 93: fprintf(stderr,"Bad indirect sys call at 0x%x\n",pc-2); ! 94: pc++; ! 95: /* set carry flag */ ! 96: psl |= CARRY; ! 97: regs[0] = -1; ! 98: return(-1); ! 99: } ! 100: code &= 0377; ! 101: } ! 102: else { ! 103: /* remember this was not indirect */ ! 104: indirflg = 0; ! 105: /* point to args */ ! 106: argp = pc; ! 107: } ! 108: /* check if code too high or bad sys code */ ! 109: if(code >= NSYSTRAPS || sysargs[code][0] == ILLSYS) { ! 110: fprintf(stderr,"Unimplimented trap %d at 0x%x\n",code,argp); ! 111: /* set carry bit */ ! 112: psl |= CARRY; ! 113: regs[0] = -1; ! 114: return(-1); ! 115: } ! 116: /* copy args to known locations */ ! 117: i=0; ! 118: for(j=0; j<sysargs[code][0]; j++) args[i++] = regs[j]; ! 119: for(j=0; j<(sysargs[code][1]); j++) args[i++] = *argp++; ! 120: #ifdef TRACE ! 121: fprintf(stderr,"pid %d ",getpid()); ! 122: if(indirflg) fprintf(stderr,"indirect "); ! 123: fprintf(stderr,"%s (%d) from 0%o with %d args",sysnames[code],code,pc-1,i); ! 124: for(j=0; j<i; j++) ! 125: fprintf(stderr," 0%o",args[j]); ! 126: if(code==OPEN||code==STAT||code==CREAT||code==EXEC||code==UNLNK||code==LINK||code==CHDIR||code==MKNOD) ! 127: fprintf(stderr," (%s)",args[0]); ! 128: #ifdef V7UNIX ! 129: if(code==EXECE) ! 130: fprintf(stderr," (%s)",args[0]); ! 131: #endif ! 132: if(code==LINK) ! 133: fprintf(stderr," (%s)",args[1]); ! 134: #endif ! 135: /* go do whatever sys call it is */ ! 136: switch(code) { ! 137: case FORK: ! 138: /* indirect forks return pids on both sides - must do here */ ! 139: /* this is possibly a bug in 32V */ ! 140: i = fork(); ! 141: break; ! 142: case WAIT: ! 143: i = wait(&wstatus); ! 144: args[0] = i; ! 145: args[1] = wstatus; ! 146: break; ! 147: case EXEC: ! 148: #ifdef V7UNIX ! 149: case EXECE: ! 150: #endif ! 151: /* ! 152: * have to do a lot of junk here to fix up an argv ! 153: * for execute since (1) the pdp-11 argv consists of 16 ! 154: * bit pointers and (2) the argv itself is in the ! 155: * pdp-11 program space where it would get clobbered ! 156: * when a new program is read in and before its ! 157: * argv is set up. ! 158: */ ! 159: avp = &argvs[0]; ! 160: savp = (unsigned short *)args[1]; ! 161: #ifdef V6UNIX ! 162: for(i=1; args[i] = *savp++; i++) ! 163: if(args[i] == 0177777) break; ! 164: #ifdef TRACE ! 165: else fprintf(stderr,"argv[%d]%s ",i-1,args[i]); ! 166: #endif ! 167: #endif ! 168: #ifdef V7UNIX ! 169: savep = (unsigned short *)args[2]; ! 170: for(i=1; args[i] = *savp++; i++) ! 171: #ifdef TRACE ! 172: fprintf(stderr,"argv[%d]%s ",i-1,args[i]); ! 173: #else ! 174: ; ! 175: #endif ! 176: #endif ! 177: if(stat(args[0], &stat32v)) { ! 178: /* return error here if file does not exist */ ! 179: #ifdef TRACE ! 180: fprintf(stderr," does not exist\n"); ! 181: #endif ! 182: i = -1; ! 183: break; ! 184: } ! 185: /* must have execute permission */ ! 186: if(stat32v.st_mode & (S_IEXEC>>6)) goto experm; ! 187: if(stat32v.st_mode & (S_IEXEC>>3)) { ! 188: if(stat32v.st_gid == getegid()) goto experm; ! 189: if(geteuid() == 0) goto experm; ! 190: } ! 191: if(stat32v.st_mode & S_IEXEC) { ! 192: if(stat32v.st_uid == geteuid()) goto experm; ! 193: if(geteuid() == 0) goto experm; ! 194: } ! 195: /* return failure if no exec permision allowed */ ! 196: i = -1; ! 197: experm: ! 198: /* can't exec a directory */ ! 199: if(stat32v.st_mode & S_IFDIR) ! 200: i = -1; ! 201: if(i == -1) break; ! 202: args[i] = 0; ! 203: for(j=0; j<i; j++) { ! 204: oavp = (char *)args[j]; ! 205: args[j] = (int)avp; ! 206: while(*avp++ = *oavp++) ; ! 207: } ! 208: #ifdef V7UNIX ! 209: if(code == EXECE) { ! 210: for(j = ++i; args[j] = *savep++; j++) ; ! 211: for( ; j>i; j--) { ! 212: oavp = (char *)args[j]; ! 213: args[j] = (int)avp; ! 214: while(*avp++ = *oavp++) ; ! 215: } ! 216: } ! 217: #endif ! 218: /* SETUID and SETGID files must be started with a fresh RTS */ ! 219: if(stat32v.st_mode & S_ISGID || stat32v.st_mode & S_ISUID) { ! 220: /* should add a check here for good magic # in header */ ! 221: args[1] = args[0]; ! 222: args[0] = (int)RTSNAME; ! 223: #ifdef TRACE ! 224: fprintf(stderr," SETUID-GID"); ! 225: #endif ! 226: if(args[i]) ! 227: i = execve(args[0], &args[0], &args[i]); ! 228: else ! 229: i = execv(args[0], &args[0]); ! 230: fprintf(stderr,"can't exec %s\n",RTSNAME); ! 231: break; ! 232: } ! 233: i = execute(args[0], &args[1], &args[i]); ! 234: /* shouldn't get here if exec works */ ! 235: break; ! 236: case SEEK: ! 237: #ifdef V6UNIX ! 238: /* fix up negative offsets */ ! 239: if(args[2] != 0 && args[2] != 3) ! 240: if(args[1] >= 32768) args[1] -= 65536; ! 241: if(args[2] <= 2) ! 242: i = lseek(args[0], args[1], args[2]); ! 243: else ! 244: i = lseek(args[0], args[1]*512, args[2]-3); ! 245: if(i != -1) i = 0; ! 246: #endif ! 247: #ifdef V7UNIX ! 248: i = lseek(args[0], (args[1]<<16)|(args[2]&0177777), args[3]); ! 249: #endif ! 250: break; ! 251: #ifdef V6UNIX ! 252: case MKNOD: ! 253: /* version 6 uses allocated bit which means regular file here */ ! 254: if(args[1] & S_IFBLK) ! 255: args[1] &= ~S_IFREG; ! 256: i = mknod(args[0], args[1], args[2]); ! 257: break; ! 258: #endif ! 259: case PIPE: ! 260: i = pipe(pipes); ! 261: args[0] = pipes[0]; ! 262: args[1] = pipes[1]; ! 263: break; ! 264: #ifdef V6UNIX ! 265: case TELL: ! 266: i = lseek(args[0], 0L, 1); ! 267: break; ! 268: #endif ! 269: case STAT: ! 270: case FSTAT: ! 271: /* do the syscall to a local stat buffer */ ! 272: i = syscall(code, args[0], &stat32v); ! 273: /* reverse the longs */ ! 274: stat32v.st_size = longrev(stat32v.st_size); ! 275: stat32v.st_atime = longrev(stat32v.st_atime); ! 276: stat32v.st_mtime = longrev(stat32v.st_mtime); ! 277: stat32v.st_ctime = longrev(stat32v.st_ctime); ! 278: #ifdef V7UNIX ! 279: /* copy out otherwise unchanged stat buffer */ ! 280: /* in two pieces with st_size as the breaking point */ ! 281: /* note that st_rdev is a short but due to alingnmemt */ ! 282: /* problems the rest of the structure is out of sync */ ! 283: j = (int)((char *)(&stat32v.st_size)-(char *)(&stat32v.st_dev)); ! 284: bcopy(&stat32v, args[1], j); ! 285: bcopy(&stat32v.st_size, args[1]+j-2, sizeof(struct stat)-j); ! 286: #endif ! 287: #ifdef V6UNIX ! 288: /* point to user area as v6stat structure */ ! 289: v6stat = (struct v6nod *)args[1]; ! 290: /* copy out piece by piece */ ! 291: v6stat->majmin = stat32v.st_dev; ! 292: v6stat->inumber = stat32v.st_ino; ! 293: v6stat->flags = stat32v.st_mode; ! 294: v6stat->nlinks = (unsigned char)stat32v.st_nlink; ! 295: v6stat->uid = (unsigned char)stat32v.st_uid; ! 296: v6stat->gid = (unsigned char)stat32v.st_gid; ! 297: /* note size already reversed */ ! 298: v6stat->size0 = (unsigned char)(stat32v.st_size & 0377); ! 299: v6stat->size1 = (unsigned short)(stat32v.st_size>>16); ! 300: v6stat->actime = stat32v.st_atime; ! 301: v6stat->modtime = stat32v.st_mtime; ! 302: /* patch up flags */ ! 303: /* for now just set 100000 bit if not a plain file */ ! 304: if(v6stat->flags & 060000) ! 305: v6stat->flags |= 0100000; ! 306: #endif ! 307: break; ! 308: case TIMES: ! 309: i = times(&timebuf); ! 310: timebuf.t2 = longrev(timebuf.t2) + timebuf.t1; ! 311: timebuf.t3 = longrev(timebuf.t3); ! 312: timebuf.t4 = longrev(timebuf.t4); ! 313: bcopy(&timebuf.t2,args[0],sizeof(struct timebuf)-sizeof(long)); ! 314: break; ! 315: #ifdef V6UNIX ! 316: case SLEEP: ! 317: /* do a sleep function - what about pwb which has alarm? */ ! 318: sleep(args[0]); ! 319: break; ! 320: #endif ! 321: case GETUID: ! 322: args[0] = getuid(); ! 323: args[1] = geteuid(); ! 324: #ifdef V6UNIX ! 325: i = args[1]<<8 | args[0]; ! 326: #endif ! 327: break; ! 328: case GETGID: ! 329: args[0] = getgid(); ! 330: args[1] = getegid(); ! 331: #ifdef V6UNIX ! 332: i = args[1]<<8 | args[0]; ! 333: #endif ! 334: break; ! 335: #ifdef V6UNIX ! 336: case SETUID: ! 337: case SETGID: ! 338: /* uids and gids are 8 bits in version 6 */ ! 339: i = syscall(code,args[0]&0377); ! 340: break; ! 341: #endif ! 342: case SIG: ! 343: /* if it is a good signal code */ ! 344: if(args[0] <= NSIG) { ! 345: /* get the current signal value */ ! 346: i = sigvals[args[0]]; ! 347: /* reset the signal to the new value */ ! 348: sigvals[args[0]] = args[1]; ! 349: /* actually do signal except don't reset SIGILL */ ! 350: if(args[0] != SIGILL) { ! 351: if(args[1] == (int)SIG_DFL || args[1] & (int)SIG_IGN) { ! 352: if((int)signal(args[0],args[1]) == -1) ! 353: i = -1; ! 354: } else { ! 355: if((int)signal(args[0], sigcatch) == -1) ! 356: i = -1; ! 357: } ! 358: } ! 359: } ! 360: else i = -1; ! 361: break; ! 362: case BRK: ! 363: /* brk is successful unless we run over the stack */ ! 364: i = 0; ! 365: if(args[0] >= regs[6]) i = -1; ! 366: break; ! 367: #ifdef V6UNIX ! 368: case PWBSYS: ! 369: /* ignore pwbsys for now */ ! 370: switch(args[2]) { ! 371: case UNAME: ! 372: #ifdef TRACE ! 373: fprintf(stderr,"UNAME with %d %d\n",args[0],args[1]); ! 374: #endif ! 375: strcpy(args[0],"pwbname"); ! 376: i = 0; ! 377: break; ! 378: case UDATA: ! 379: #ifdef TRACE ! 380: fprintf(stderr,"UDATA with %d %d\n",args[0],args[1]); ! 381: #endif ! 382: i = 0; ! 383: break; ! 384: case USTAT: ! 385: fprintf(stderr,"USTAT with %d %d\n",args[0],args[1]); ! 386: i = 0; ! 387: break; ! 388: case UTIME: ! 389: fprintf(stderr,"UTIME with %d %d\n",args[0],args[1]); ! 390: i = 0; ! 391: break; ! 392: default: ! 393: fprintf(stderr,"bad PWBSYS %d\n",args[3]); ! 394: i = -1; ! 395: break; ! 396: } ! 397: break; ! 398: #endif ! 399: default: ! 400: /* ! 401: * Many sys calls are easily done here since most ! 402: * system call codes are the same on version 6 and 7 UNIX ! 403: * as they are here. ! 404: */ ! 405: i = syscall(code,args[0],args[1],args[2],args[3],args[4]); ! 406: #ifdef V6UNIX ! 407: /* allow read write access to created files for(IDIS v6 mod) */ ! 408: if(code==CREAT) { ! 409: /* get actual file mode after create */ ! 410: fstat(i, &stat32v); ! 411: close(i); ! 412: /* ensure read/write access to owner */ ! 413: chmod(args[0], 0644); ! 414: i = open(args[0], 2); ! 415: /* change mode back the way it was */ ! 416: chmod(args[0], stat32v.st_mode); ! 417: } ! 418: #endif ! 419: break; ! 420: } ! 421: #ifdef TRACE ! 422: fprintf(stderr," sys val -> 0%o\n",i); ! 423: #endif ! 424: /* set carry bit if sys error */ ! 425: if(i == -1) ! 426: psl |= CARRY; ! 427: /* if not an indirect sys call, adjust the pc */ ! 428: if(indirflg == 0) ! 429: pc = argp; ! 430: /* do alternate return on one side of fork */ ! 431: if(code == FORK && i != 0) ! 432: pc++; ! 433: /* do the various return value formats */ ! 434: switch(sysargs[code][2]) { ! 435: case NORMRET: ! 436: /* normal case only one return value in r0 */ ! 437: regs[0] = i; ! 438: break; ! 439: case LONGRET: ! 440: /* return a long in r0 - r1 as in time */ ! 441: regs[1] = i; ! 442: regs[0] = i >> 16; ! 443: break; ! 444: case TWORET: ! 445: /* return two ints in r0 - r1 as in pipe */ ! 446: if(i == -1) ! 447: regs[0] = i; ! 448: else { ! 449: regs[1] = args[1]; ! 450: regs[0] = args[0]; ! 451: } ! 452: break; ! 453: } ! 454: if(i== -1) ! 455: regs[0] = errno; ! 456: } ! 457: long longrev(l) long l; { ! 458: /* function to reverse the halves of a long */ ! 459: union { ! 460: long lng; ! 461: short s[2]; ! 462: } u; ! 463: register short t; ! 464: u.lng = l; ! 465: t = u.s[0]; ! 466: u.s[0] = u.s[1]; ! 467: u.s[1] = t; ! 468: return(u.lng); ! 469: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.