X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/de3003f6a71e7439acbf01fcc84c7f8ca9a807df..850b267cd970be4ca45706a472cbea48de6ad738:/usr/src/usr.bin/tn3270/telnet.c diff --git a/usr/src/usr.bin/tn3270/telnet.c b/usr/src/usr.bin/tn3270/telnet.c index 33bb503d17..b116356972 100644 --- a/usr/src/usr.bin/tn3270/telnet.c +++ b/usr/src/usr.bin/tn3270/telnet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1984, 1985, 1986 by the Regents of the + * Copyright (c) 1984-1987 by the Regents of the * University of California and by Gregory Glenn Minshall. * * Permission to use, copy, modify, and distribute these @@ -21,12 +21,12 @@ #ifndef lint static char copyright[] = -"@(#) Copyright (c) 1984, 1985, 1986 Regents of the University of California.\n\ +"@(#) Copyright (c) 1984-1987 Regents of the University of California.\n\ All rights reserved.\n"; #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)telnet.c 3.1 10/29/86"; +static char sccsid[] = "@(#)telnet.c 6.6 (Berkeley) %G%"; #endif /* not lint */ /* @@ -79,6 +79,11 @@ void setcommandmode(), command(); /* forward declarations */ #endif /* !defined(TN3270) */ #include + +#if defined(pyr) +#define fd_set fdset_t +#endif /* defined(pyr) */ + #include #include @@ -211,7 +216,8 @@ static int ISend, /* trying to send network data in */ debug = 0, crmod, - netdata, + netdata, /* Print out network data flow */ + crlf, /* Should '\r' be mapped to (or )? */ noasynch = 0, /* User specified "-noasynch" on command line */ askedSGA = 0, /* We have talked about suppress go ahead */ telnetport = 1; @@ -231,7 +237,8 @@ static int autoflush = 0, /* flush output when interrupting? */ autosynch, /* send interrupt characters with SYNCH? */ localchars, /* we recognize interrupt/quit */ - donelclchars, /* the user has set "localchars" */ + donelclchars, /* the user has set "localchars" */ + donebinarytoggle, /* the user has put us in binary */ dontlecho, /* do we suppress local echoing right now? */ globalmode; @@ -614,6 +621,9 @@ int fd; #include #include #include +#include +#include +#include #if !defined(SO_OOBINLINE) #define SO_OOBINLINE @@ -629,6 +639,8 @@ static char termLiteralNextChar, termQuitChar; +static char + savedInState, savedOutState; /* * MSDOS doesn't have anyway of deciding whether a full-edited line @@ -829,6 +841,9 @@ void CtrlCInterrupt() { if (!MODE_COMMAND_LINE(globalmode)) { + char far *Bios_Break = (char far *) (((long)0x40<<16)|0x71); + + *Bios_Break = 0; ctrlCCount++; /* XXX */ signal(SIGINT, CtrlCInterrupt); } else { @@ -836,6 +851,38 @@ CtrlCInterrupt() exit(1); } } + +int +dosbinary(fd, onoff) +int fd; +int onoff; +{ + union REGS regs; + int oldstate; + + /* Get old stuff */ + regs.h.ah = 0x44; + regs.h.al = 0; + regs.x.bx = fd; + intdos(®s, ®s); + oldstate = regs.h.dl&(1<<5); /* Save state */ + + /* Set correct bits in new mode */ + regs.h.dh = 0; + if (onoff) { + regs.h.dl |= 1<<5; + } else { + regs.h.dl &= ~(1<<5); + } + + /* Set in new mode */ + regs.h.ah = 0x44; + regs.h.al = 1; + regs.x.bx = fd; + intdos(®s, ®s); + + return oldstate; +} /* * The MSDOS routines, called from elsewhere. @@ -869,8 +916,66 @@ static void TerminalNewMode(f) /* MSDOS */ register int f; { + union REGS inregs; + struct SREGS segregs; + static old_1b_offset = 0, old_1b_segment = 0; + globalmode = f; - signal(SIGINT, CtrlCInterrupt); + if (MODE_COMMAND_LINE(f)) { + signal(SIGINT, SIG_DFL); + if (old_1b_segment|old_1b_offset) { + inregs.h.ah = 0x25; + inregs.h.al = 0x1b; + inregs.x.dx = old_1b_offset; + segregs.ds = old_1b_segment; + intdosx(&inregs, &inregs, &segregs); + old_1b_segment = old_1b_offset = 0; + } + if (setmode(fileno(stdout), O_TEXT) == -1) { + ExitPerror("setmode (text)", 1); + } + (void) dosbinary(fileno(stdout), 0); + if (setmode(fileno(stdin), O_TEXT) == -1) { + ExitPerror("setmode (text)", 1); + } + (void) dosbinary(fileno(stdin), 0); + } else { + signal(SIGINT, CtrlCInterrupt); + if ((old_1b_segment|old_1b_offset) == 0) { + extern void iret_subr(); + void (far *foo_subr)() = iret_subr; + + inregs.h.ah = 0x35; + inregs.h.al = 0x1b; + intdosx(&inregs, &inregs, &segregs); + old_1b_segment = segregs.es; + old_1b_offset = inregs.x.bx; + inregs.h.ah = 0x25; + inregs.h.al = 0x1b; + inregs.x.dx = FP_OFF(foo_subr); + segregs.ds = FP_SEG(foo_subr); + intdosx(&inregs, &inregs, &segregs); + } + if (MODE_LOCAL_CHARS(f)) { + if (setmode(fileno(stdout), O_TEXT) == -1) { + ExitPerror("setmode (text)", 1); + } + (void) dosbinary(fileno(stdout), 0); + if (setmode(fileno(stdin), O_TEXT) == -1) { + ExitPerror("setmode (text)", 1); + } + (void) dosbinary(fileno(stdin), 0); + } else { + if (setmode(fileno(stdout), O_BINARY) == -1) { + ExitPerror("setmode (binary)", 1); + } + (void) dosbinary(fileno(stdout), 1); + if (setmode(fileno(stdin), O_BINARY) == -1) { + ExitPerror("setmode (binary)", 1); + } + (void) dosbinary(fileno(stdin), 1); + } + } } @@ -900,6 +1005,8 @@ int count; static void TerminalSaveState() /* MSDOS */ { + savedInState = dosbinary(fileno(stdin), 0); + savedOutState = dosbinary(fileno(stdout), 0); } int @@ -912,6 +1019,8 @@ TerminalSpecialChars(c) /* MSDOS */ static void TerminalRestoreState() /* MSDOS */ { + (void) dosbinary(fileno(stdin), savedInState); + (void) dosbinary(fileno(stdout), savedOutState); } @@ -980,7 +1089,7 @@ tninit() sbp = sibuf; tbp = tibuf; - connected = net = scc = tcc = In3270 = ISend = 0; + connected = net = scc = tcc = In3270 = ISend = donebinarytoggle = 0; telnetport = 0; #if defined(unix) HaveInput = 0; @@ -1059,6 +1168,9 @@ char **(*next)(); /* routine to return next entry in table */ register char **c, **found; register int nmatches, longest; + if (name == 0) { + return 0; + } longest = 0; nmatches = 0; found = 0; @@ -1887,7 +1999,7 @@ static void SetIn3270() { if (Sent3270TerminalType && myopts[TELOPT_BINARY] - && hisopts[TELOPT_BINARY]) { + && hisopts[TELOPT_BINARY] && !donebinarytoggle) { if (!In3270) { In3270 = 1; Init3270(); /* Initialize 3270 functions */ @@ -1962,7 +2074,7 @@ telrcv() * \n; since we must turn off CRMOD to get proper * input, the mapping is done here (sigh). */ - if (c == '\r') { + if ((c == '\r') && !hisopts[TELOPT_BINARY]) { if (scc > 0) { c = *sbp&0xff; if (c == 0) { @@ -2421,9 +2533,15 @@ int block; /* should we block in the select ? */ if (TTYBYTES()) { FD_SET(tout, &obits); } +#if defined(TN3270) if ((tcc == 0) && NETROOM() && (shell_active == 0)) { FD_SET(tin, &ibits); } +#else /* defined(TN3270) */ + if ((tcc == 0) && NETROOM()) { + FD_SET(tin, &ibits); + } +#endif /* defined(TN3270) */ #endif /* !defined(MSDOS) */ # if !defined(TN3270) if (TTYROOM()) { @@ -2646,29 +2764,39 @@ int block; /* should we block in the select ? */ break; } } - switch (c) { - case '\n': - /* - * If we are in CRMOD mode (\r ==> \n) - * on our local machine, then probably - * a newline (unix) is CRLF (TELNET). - */ - if (MODE_LOCAL_CHARS(globalmode)) { - NETADD('\r'); + if (!myopts[TELOPT_BINARY]) { + switch (c) { + case '\n': + /* + * If we are in CRMOD mode (\r ==> \n) + * on our local machine, then probably + * a newline (unix) is CRLF (TELNET). + */ + if (MODE_LOCAL_CHARS(globalmode)) { + NETADD('\r'); + } + NETADD('\n'); + flushline = 1; + break; + case '\r': + if (!crlf) { + NET2ADD('\r', '\0'); + } else { + NET2ADD('\r', '\n'); + } + flushline = 1; + break; + case IAC: + NET2ADD(IAC, IAC); + break; + default: + NETADD(c); + break; } - NETADD('\n'); - flushline = 1; - break; - case '\r': - NET2ADD('\r', '\0'); - flushline = 1; - break; - case IAC: + } else if (c == IAC) { NET2ADD(IAC, IAC); - break; - default: + } else { NETADD(c); - break; } } # if defined(TN3270) @@ -2676,7 +2804,7 @@ int block; /* should we block in the select ? */ } # endif /* defined(TN3270) */ - if ((!MODE_LINE(globalmode) || flushline) && + if ((!MODE_LINE(globalmode) || flushline || myopts[TELOPT_BINARY]) && FD_ISSET(net, &obits) && (NETBYTES() > 0)) { FD_CLR(net, &obits); returnValue = netflush(); @@ -2762,7 +2890,7 @@ telnet() for (;;) { int schedValue; - while (!In3270) { + while (!In3270 && !shell_active) { if (Scheduler(SCHED_BLOCK) == -1) { setcommandmode(); return; @@ -2782,25 +2910,10 @@ telnet() schedValue = 1; } else { if (shell_active) { -#if defined(MSDOS) - static int haventstopped = 1; - - setcommandmode(); - if (haventstopped) { - StopScreen(1); - haventstopped = 0; - } -#endif /* defined(MSDOS) */ if (shell_continue() == 0) { ConnectScreen(); -#if defined(MSDOS) - haventstopped = 1; -#endif /* defined(MSDOS) */ } -#if defined(MSDOS) - setconnmode(); -#endif /* defined(MSDOS) */ - } else { + } else if (In3270) { schedValue = DoTerminalOutput(); } } @@ -3010,6 +3123,46 @@ togdebug() } +static int +togcrlf() +{ + if (crlf) { + printf("Will send carriage returns as telnet .\n"); + } else { + printf("Will send carriage returns as telnet .\n"); + } + return 1; +} + + +static int +togbinary() +{ + donebinarytoggle = 1; + + if (myopts[TELOPT_BINARY] == 0) { /* Go into binary mode */ + NET2ADD(IAC, DO); + NETADD(TELOPT_BINARY); + printoption("", + togcrlf, + 1, + &crlf, + 0 }, { "crmod", "toggle mapping of received carriage returns", 0, @@ -3138,8 +3303,10 @@ char *argv[]; } else { if (c->variable) { *c->variable = !*c->variable; /* invert it */ - printf("%s %s.\n", *c->variable? "Will" : "Won't", + if (c->actionexplanation) { + printf("%s %s.\n", *c->variable? "Will" : "Won't", c->actionexplanation); + } } if (c->handler) { retval &= (*c->handler)(c); @@ -3565,7 +3732,7 @@ tn(argc, argv) argc = margc; argv = margv; } - if (argc > 3) { + if ((argc < 2) || (argc > 3)) { printf("usage: %s host-name [port]\n", argv[0]); return 0; } @@ -3812,9 +3979,13 @@ command(top) longjmp(toplevel, 1); /*NOTREACHED*/ } +#if defined(TN3270) if (shell_active == 0) { setconnmode(); } +#else /* defined(TN3270) */ + setconnmode(); +#endif /* defined(TN3270) */ } } @@ -3883,7 +4054,7 @@ main(argc, argv) } else { #if defined(TN3270) && defined(unix) if (!strcmp(argv[1], "-t")) { - if ((argc > 1) && (argv[1][0] != '-')) { /* get file name */ + if ((argc > 1) && (argv[2][0] != '-')) { /* get file name */ transcom = tline; (void) strcpy(transcom, argv[1]); argv++;