Annotation of 43BSDReno/old/games.vax/compat/unixtraps.c, revision 1.1

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

unix.superglobalmegacorp.com

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