Annotation of 43BSD/games/compat/unixtraps.c, revision 1.1

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

unix.superglobalmegacorp.com

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