Annotation of 43BSDTahoe/ucb/telnet/Source/sys_dos.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that this notice is preserved and that due credit is given
        !             7:  * to the University of California at Berkeley. The name of the University
        !             8:  * may not be used to endorse or promote products derived from this
        !             9:  * software without specific prior written permission. This software
        !            10:  * is provided ``as is'' without express or implied warranty.
        !            11:  */
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)sys_dos.c  1.3 (Berkeley) 3/8/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: #if    defined(MSDOS)
        !            18: #include <time.h>
        !            19: #include <signal.h>
        !            20: #include <process.h>
        !            21: #include <fcntl.h>
        !            22: #include <io.h>
        !            23: #include <dos.h>
        !            24: #include <ctype.h>
        !            25: 
        !            26: #include "externs.h"
        !            27: #include "defines.h"
        !            28: 
        !            29: #if    !defined(SO_OOBINLINE)
        !            30: #define        SO_OOBINLINE
        !            31: #endif /* !defined(SO_OOBINLINE) */
        !            32: 
        !            33: 
        !            34: 
        !            35: /*
        !            36:  * MSDOS doesn't have anyway of deciding whether a full-edited line
        !            37:  * is ready to be read in, so we need to do character-by-character
        !            38:  * reads, and then do the editing in the program (in the case where
        !            39:  * we are supporting line-by-line mode).
        !            40:  *
        !            41:  * The following routines, which are internal to the MSDOS-specific
        !            42:  * code, accomplish this miracle.
        !            43:  */
        !            44: 
        !            45: #define Hex(c) HEX[(c)&0xff]
        !            46: 
        !            47: static survivorSetup = 0;              /* Do we have ^C hooks in? */
        !            48: 
        !            49: static int
        !            50:        lineend = 0,            /* There is a line terminator */
        !            51:        ctrlCCount = 0;
        !            52: 
        !            53: static char    linein[200],            /* Where input line is assembled */
        !            54:                *nextin = linein,       /* Next input character */
        !            55:                *nextout = linein;      /* Next character to be consumed */
        !            56: 
        !            57: static char
        !            58:     savedInState, savedOutState;
        !            59: 
        !            60: #define consumechar() \
        !            61:     if ((++nextout) >= nextin) { \
        !            62:        nextout = nextin = linein; \
        !            63:        lineend = 0; \
        !            64:     }
        !            65: 
        !            66: #define        characteratatime()      (!MODE_LINE(globalmode))        /* one by one */
        !            67: 
        !            68: 
        !            69: /*
        !            70:  * killone()
        !            71:  *
        !            72:  *  Erase the last character on the line.
        !            73:  */
        !            74: 
        !            75: static void
        !            76: killone()
        !            77: {
        !            78:     if (lineend) {
        !            79:        return;                 /* ??? XXX */
        !            80:     }
        !            81:     if (nextin == linein) {
        !            82:        return;                 /* Nothing to do */
        !            83:     }
        !            84:     nextin--;
        !            85:     if (!(isspace(*nextin) || isprint(*nextin))) {
        !            86:        putchar('\b');
        !            87:        putchar(' ');
        !            88:        putchar('\b');
        !            89:     }
        !            90:     putchar('\b');
        !            91:     putchar(' ');
        !            92:     putchar('\b');
        !            93: }
        !            94: 
        !            95: 
        !            96: /*
        !            97:  * setlineend()
        !            98:  *
        !            99:  *  Decide if it's time to send the current line up to the user
        !           100:  * process.
        !           101:  */
        !           102: 
        !           103: static void
        !           104: setlineend()
        !           105: {
        !           106:     if (nextin == nextout) {
        !           107:        return;
        !           108:     }
        !           109:     if (characteratatime()) {
        !           110:        lineend = 1;
        !           111:     } else if (nextin >= (linein+sizeof linein)) {
        !           112:        lineend = 1;
        !           113:     } else {
        !           114:        int c = *(nextin-1);
        !           115:        if ((c == termIntChar)
        !           116:                || (c == termQuitChar)
        !           117:                || (c == termEofChar)) {
        !           118:            lineend = 1;
        !           119:        } else if (c == termFlushChar) {
        !           120:            lineend = 1;
        !           121:        } else if ((c == '\n') || (c == '\r')) {
        !           122:            lineend = 1;
        !           123:        }
        !           124:     }
        !           125:     /* Otherwise, leave it alone (reset by 'consumechar') */
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * OK, what we do here is:
        !           130:  *
        !           131:  *   o  If we are echoing, then
        !           132:  *     o  Look for character erase, line kill characters
        !           133:  *     o  Echo the character (using '^' if a control character)
        !           134:  *   o  Put the character in the input buffer
        !           135:  *   o  Set 'lineend' as necessary
        !           136:  */
        !           137: 
        !           138: static void
        !           139: DoNextChar(c)
        !           140: int    c;                      /* Character to process */
        !           141: {
        !           142:     static char literalnextcharacter = 0;
        !           143: 
        !           144:     if (nextin >= (linein+sizeof linein)) {
        !           145:        putchar('\7');          /* Ring bell */
        !           146:        setlineend();
        !           147:        return;
        !           148:     }
        !           149:     if (MODE_LOCAL_CHARS(globalmode)) {
        !           150:        /* Look for some special character */
        !           151:        if (!literalnextcharacter) {
        !           152:            if (c == termEraseChar) {
        !           153:                killone();
        !           154:                setlineend();
        !           155:                return;
        !           156:            } else if (c == termKillChar) {
        !           157:                while (nextin != linein) {
        !           158:                    killone();
        !           159:                }
        !           160:                setlineend();
        !           161:                return;
        !           162:            } else if (c == termLiteralNextChar) {
        !           163:                literalnextcharacter = 1;
        !           164:                return;
        !           165:            }
        !           166:        }
        !           167: 
        !           168:        if (MODE_LOCAL_ECHO(globalmode)) {
        !           169:            if ((literalnextcharacter == 0) && ((c == '\r') || (c == '\n'))) {
        !           170:                putchar('\r');
        !           171:                putchar('\n');
        !           172:                c = '\n';
        !           173:            } else if (!isprint(c) && !isspace(c)) {
        !           174:                putchar('^');
        !           175:                putchar(c^0x40);
        !           176:            } else {
        !           177:                putchar(c);
        !           178:            }
        !           179:        }
        !           180:        literalnextcharacter = 0;
        !           181:     }
        !           182:     *nextin++ = c;
        !           183:     setlineend();
        !           184: }
        !           185: 
        !           186: static int
        !           187: inputExists()
        !           188: {
        !           189:     int input;
        !           190:     static state = 0;
        !           191: 
        !           192:     while (ctrlCCount) {
        !           193:        DoNextChar(0x03);
        !           194:        ctrlCCount--;
        !           195:     }
        !           196:     if (lineend) {
        !           197:        return 1;
        !           198:     }
        !           199: #if    1       /* For BIOS variety of calls */
        !           200:     if (kbhit() == 0) {
        !           201:        return lineend;
        !           202:     }
        !           203:     input = getch();                   /* MSC - get console character */
        !           204:     if ((input&0xff) == 0) {
        !           205:        DoNextChar(0x01);               /* ^A */
        !           206:     } else {
        !           207:        DoNextChar(input&0xff);
        !           208:     }
        !           209: #else  /* 0 */
        !           210:     if ((input = dirconio()) == -1) {
        !           211:        return lineend;
        !           212:     }
        !           213:     if ((input&0xff) == 0) {
        !           214:        if ((input&0xff00) == 0x0300) {         /* Null */
        !           215:            DoNextChar(0);
        !           216:        } else {
        !           217:            DoNextChar(0x01);
        !           218:            if (input&0x8000) {
        !           219:                DoNextChar(0x01);
        !           220:                DoNextChar((input>>8)&0x7f);
        !           221:            } else {
        !           222:                DoNextChar((input>>8)&0xff);
        !           223:            }
        !           224:        }
        !           225:     } else {
        !           226:        DoNextChar(input&0xff);
        !           227:     }
        !           228: #endif /* 0 */
        !           229:     return lineend;
        !           230: }
        !           231: 
        !           232: 
        !           233: void
        !           234: CtrlCInterrupt()
        !           235: {
        !           236:     if (!MODE_COMMAND_LINE(globalmode)) {
        !           237:        char far *Bios_Break = (char far *) (((long)0x40<<16)|0x71);
        !           238: 
        !           239:        ctrlCCount++;           /* XXX */
        !           240:        signal(SIGINT, CtrlCInterrupt);
        !           241:     } else {
        !           242:        closeallsockets();
        !           243:        exit(1);
        !           244:     }
        !           245: }
        !           246: 
        !           247: int
        !           248: dosbinary(fd, onoff)
        !           249: int    fd;
        !           250: int    onoff;
        !           251: {
        !           252:     union REGS regs;
        !           253:     int oldstate;
        !           254: 
        !           255:     /* Get old stuff */
        !           256:     regs.h.ah = 0x44;
        !           257:     regs.h.al = 0;
        !           258:     regs.x.bx = fd;
        !           259:     intdos(&regs, &regs);
        !           260:     oldstate = regs.h.dl&(1<<5);               /* Save state */
        !           261: 
        !           262:     /* Set correct bits in new mode */
        !           263:     regs.h.dh = 0;
        !           264:     if (onoff) {
        !           265:        regs.h.dl |= 1<<5;
        !           266:     } else {
        !           267:        regs.h.dl &= ~(1<<5);
        !           268:     }
        !           269: 
        !           270:     /* Set in new mode */
        !           271:     regs.h.ah = 0x44;
        !           272:     regs.h.al = 1;
        !           273:     regs.x.bx = fd;
        !           274:     intdos(&regs, &regs);
        !           275: 
        !           276:     return oldstate;
        !           277: }
        !           278: 
        !           279: /*
        !           280:  * The MSDOS routines, called from elsewhere.
        !           281:  */
        !           282: 
        !           283: 
        !           284: int
        !           285: TerminalAutoFlush()                            /* MSDOS */
        !           286: {
        !           287:     return 1;
        !           288: }
        !           289: 
        !           290: int
        !           291: TerminalCanRead()
        !           292: {
        !           293:     return inputExists();
        !           294: }
        !           295: 
        !           296: 
        !           297: /*
        !           298:  * Flush output to the terminal
        !           299:  */
        !           300:  
        !           301: void
        !           302: TerminalFlushOutput()                          /* MSDOS */
        !           303: {
        !           304: }
        !           305: 
        !           306: 
        !           307: void
        !           308: TerminalNewMode(fd_in, fd_out, f)              /* MSDOS */
        !           309: int    fd_in, fd_out;                  /* File descriptors */
        !           310: register int f;
        !           311: {
        !           312:     union REGS inregs;
        !           313:     struct SREGS segregs;
        !           314:     static old_1b_offset = 0, old_1b_segment = 0;
        !           315: 
        !           316:     globalmode = f;
        !           317:     if (MODE_COMMAND_LINE(f)) {
        !           318:        signal(SIGINT, SIG_DFL);
        !           319:        if (old_1b_segment|old_1b_offset) {
        !           320:            inregs.h.ah = 0x25;
        !           321:            inregs.h.al = 0x1b;
        !           322:            inregs.x.dx = old_1b_offset;
        !           323:            segregs.ds = old_1b_segment;
        !           324:            intdosx(&inregs, &inregs, &segregs);
        !           325:            old_1b_segment = old_1b_offset = 0;
        !           326:        }
        !           327:        if (setmode(fd_out, O_TEXT) == -1) {
        !           328:            ExitPerror("setmode (text)", 1);
        !           329:        }
        !           330:        (void) dosbinary(fileno(stdout), 0);
        !           331:        if (setmode(fd_out, O_TEXT) == -1) {
        !           332:            ExitPerror("setmode (text)", 1);
        !           333:        }
        !           334:        (void) dosbinary(fileno(stdin), 0);
        !           335:     } else {
        !           336:        signal(SIGINT, CtrlCInterrupt);
        !           337:        if ((old_1b_segment|old_1b_offset) == 0) {
        !           338:            extern void iret_subr();
        !           339:            void (far *foo_subr)() = iret_subr;
        !           340: 
        !           341:            inregs.h.ah = 0x35;
        !           342:            inregs.h.al = 0x1b;
        !           343:            intdosx(&inregs, &inregs, &segregs);
        !           344:            old_1b_segment = segregs.es;
        !           345:            old_1b_offset = inregs.x.bx;
        !           346:            inregs.h.ah = 0x25;
        !           347:            inregs.h.al = 0x1b;
        !           348:            inregs.x.dx = FP_OFF(foo_subr);
        !           349:            segregs.ds = FP_SEG(foo_subr);
        !           350:            intdosx(&inregs, &inregs, &segregs);
        !           351:        }
        !           352:        if (MODE_LOCAL_CHARS(f)) {
        !           353:            if (setmode(fd_out, O_TEXT) == -1) {
        !           354:                ExitPerror("setmode (text)", 1);
        !           355:            }
        !           356:            (void) dosbinary(fileno(stdout), 0);
        !           357:            if (setmode(fd_in, O_TEXT) == -1) {
        !           358:                ExitPerror("setmode (text)", 1);
        !           359:            }
        !           360:            (void) dosbinary(fileno(stdin), 0);
        !           361:        } else {
        !           362:            if (setmode(fd_out, O_BINARY) == -1) {
        !           363:                ExitPerror("setmode (binary)", 1);
        !           364:            }
        !           365:            (void) dosbinary(fileno(stdout), 1);
        !           366:            if (setmode(fd_in, O_BINARY) == -1) {
        !           367:                ExitPerror("setmode (binary)", 1);
        !           368:            }
        !           369:            (void) dosbinary(fileno(stdin), 1);
        !           370:        }
        !           371:     }
        !           372: }
        !           373: 
        !           374: int
        !           375: TerminalRead(fd, buffer, count)
        !           376: int    fd;
        !           377: char   *buffer;
        !           378: int    count;
        !           379: {
        !           380:     int done = 0;
        !           381: 
        !           382:     for (;;) {
        !           383:        while (inputExists() && (done < count)) {
        !           384:            *buffer++ = *nextout;
        !           385:            consumechar();
        !           386:            done++;
        !           387:        }
        !           388:        if (done) {
        !           389:            return(done);
        !           390:        } else {
        !           391:            return 0;
        !           392:        }
        !           393:     }
        !           394: }
        !           395: 
        !           396: 
        !           397: void
        !           398: TerminalSaveState()                            /* MSDOS */
        !           399: {
        !           400:     termEofChar = '\4';
        !           401:     termEraseChar = '\10';
        !           402:     termFlushChar = '\17';
        !           403:     termIntChar = '\3';
        !           404:     termKillChar = '\25';
        !           405:     termLiteralNextChar = '\26';
        !           406:     termQuitChar = '\0';;
        !           407: 
        !           408:     savedInState = dosbinary(fileno(stdin), 0);
        !           409:     savedOutState = dosbinary(fileno(stdout), 0);
        !           410: }
        !           411: 
        !           412: int
        !           413: TerminalSpecialChars(c)                        /* MSDOS */
        !           414: {
        !           415:     return 1;
        !           416: }
        !           417: 
        !           418: 
        !           419: void
        !           420: TerminalRestoreState()                         /* MSDOS */
        !           421: {
        !           422:     (void) dosbinary(fileno(stdin), savedInState);
        !           423:     (void) dosbinary(fileno(stdout), savedOutState);
        !           424: }
        !           425: 
        !           426: 
        !           427: int
        !           428: TerminalWrite(fd, buffer, count)               /* MSDOS */
        !           429: int    fd;
        !           430: char   *buffer;
        !           431: int    count;
        !           432: {
        !           433:     return fwrite(buffer, sizeof (char), count, stdout);       /* XXX */
        !           434: }
        !           435: 
        !           436: 
        !           437: int
        !           438: NetClose(fd)
        !           439: {
        !           440:     return closesocket(fd);
        !           441: }
        !           442: 
        !           443: void
        !           444: NetNonblockingIO(fd, onoff)                            /* MSDOS */
        !           445: int
        !           446:        fd,
        !           447:        onoff;
        !           448: {
        !           449:     if (SetSockOpt(fd, SOL_SOCKET, SO_NONBLOCKING, onoff)) {
        !           450:        perror("setsockop (SO_NONBLOCKING) ");
        !           451:        ExitString(stderr, "exiting\n", 1);
        !           452:     }
        !           453: }
        !           454: 
        !           455: void
        !           456: NetSigIO(fd)                           /* MSDOS */
        !           457: int fd;
        !           458: {
        !           459: }
        !           460: 
        !           461: void
        !           462: NetSetPgrp(fd)                         /* MSDOS */
        !           463: int fd;
        !           464: {
        !           465: }
        !           466: 
        !           467: 
        !           468: #endif /* defined(MSDOS) */

unix.superglobalmegacorp.com

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