Annotation of 43BSDTahoe/ucb/telnet/Source/sys_dos.c, revision 1.1.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.