|
|
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(®s, ®s); ! 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(®s, ®s); ! 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) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.