Annotation of 41BSD/games/compat/unixtraps.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.