-/*
- * Copyright (c) 1984, 1985, 1986 by the Regents of the
- * University of California and by Gregory Glenn Minshall.
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
- * Permission to use, copy, modify, and distribute these
- * programs and their documentation for any purpose and
- * without fee is hereby granted, provided that this
- * copyright and permission appear on all copies and
- * supporting documentation, the name of the Regents of
- * the University of California not be used in advertising
- * or publicity pertaining to distribution of the programs
- * without specific prior permission, and notice be given in
- * supporting documentation that copying and distribution is
- * by permission of the Regents of the University of California
- * and by Gregory Glenn Minshall. Neither the Regents of the
- * University of California nor Gregory Glenn Minshall make
- * representations about the suitability of this software
- * for any purpose. It is provided "as is" without
- * express or implied warranty.
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#ifndef lint
-static char sccsid[] = "@(#)outbound.c 3.1 10/29/86";
-#endif /* lint */
-
+static char sccsid[] = "@(#)termout.c 4.3 (Berkeley) 4/26/91";
+#endif /* not lint */
#if defined(unix)
#include <signal.h>
#endif
#include <stdio.h>
#include <curses.h>
+#if defined(ultrix)
+/* Some version of this OS has a bad definition for nonl() */
+#undef nl
+#undef nonl
+
+#define nl() (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))
+#define nonl() (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))
+#endif /* defined(ultrix) */
-#include "../general.h"
+#include "../general/general.h"
#include "terminal.h"
-#include "../telnet.ext"
+#include "../api/disp_asc.h"
#include "../ctlr/hostctlr.h"
-#include "../ctlr/inbound.ext"
+#include "../ctlr/externs.h"
+#include "../ctlr/declare.h"
#include "../ctlr/oia.h"
-#include "../ctlr/options.ext"
-#include "../ctlr/outbound.ext"
#include "../ctlr/screen.h"
+#include "../ctlr/scrnctlr.h"
-#include "../keyboard/map3270.ext"
+#include "../general/globals.h"
-#include "../system/globals.h"
-
-extern void EmptyTerminal();
+#include "../telextrn.h"
#define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \
- terminalCursorAddress:UnLocked? CursorAddress: HighestScreen())
+ CursorAddress:UnLocked? CursorAddress: HighestScreen())
static int terminalCursorAddress; /* where the cursor is on term */
static int screenInitd; /* the screen has been initialized */
static int screenStopped; /* the screen has been stopped */
-#if defined(SLOWSCREEN)
static int max_changes_before_poll; /* how many characters before looking */
/* at terminal and net again */
-#endif /* defined(SLOWSCREEN) */
static int needToRing; /* need to ring terinal bell */
static char *bellSequence = "\07"; /* bell sequence (may be replaced by
int bellwinup = 0; /* Are we up with it or not */
#if defined(unix)
-static char *KS, *KE;
+static char *myKS, *myKE;
#endif /* defined(unix) */
-#if defined(SLOWSCREEN)
static int inHighlightMode = 0;
ScreenImage Terminal[MAXSCREENSIZE];
-#endif /* defined(SLOWSCREEN) */
/* Variables for transparent mode */
#if defined(unix)
static int savefd[2]; /* for storing fds during transcom */
extern int tin, tout; /* file descriptors */
#endif /* defined(unix) */
-
-
-#include "disp_asc.out"
-
\f
/*
init_screen()
{
bellwinup = 0;
-#if defined(SLOWSCREEN)
inHighlightMode = 0;
ClearArray(Terminal);
-#endif /* defined(SLOWSCREEN) */
}
/* OurExitString - designed to keep us from going through infinite recursion */
static void
-OurExitString(file, string, value)
-FILE *file;
+OurExitString(string, value)
char *string;
int value;
{
if (!recursion) {
recursion = 1;
- ExitString(file, string, value);
+ ExitString(string, value);
}
}
DoARefresh()
{
if (ERR == refresh()) {
- OurExitString(stderr, "ERR from refresh\n", 1);
+ OurExitString("ERR from refresh\n", 1);
}
}
sprintf(foo, "ERR from %s at %d (%d, %d)\n",
from, where, ScreenLine(where), ScreenLineOffset(where));
- OurExitString(stderr, foo, 1);
+ OurExitString(foo, 1);
/* NOTREACHED */
}
\f
-#if defined(SLOWSCREEN)
/* What is the screen address of the attribute byte for the terminal */
static int
return(LowestScreen()); /* unformatted screen... */
}
-#endif /* defined(SLOWSCREEN) */
\f
/*
* There are two algorithms for updating the screen.
*/
-#if defined(SLOWSCREEN)
#if defined(NOT43)
static int
#else /* defined(NOT43) */
#endif /* defined(NOT43) */
SlowScreen()
{
+ register int is, shouldbe, isattr, shouldattr;
register int pointer;
- register int c;
- register int fieldattr;
+ register int fieldattr, termattr;
register int columnsleft;
-# define SetHighlightMode(p) { \
- if (!IsStartField(p) && IsHighlightedAttr(fieldattr)) { \
+#define NORMAL 0
+#define HIGHLIGHT 1 /* Mask bits */
+#define NONDISPLAY 4 /* Mask bits */
+#define UNDETERMINED 8 /* Mask bits */
+
+#define DoAttributes(x) \
+ switch (x&ATTR_DSPD_MASK) { \
+ case ATTR_DSPD_NONDISPLAY: \
+ x = NONDISPLAY; \
+ break; \
+ case ATTR_DSPD_HIGH: \
+ x = HIGHLIGHT; \
+ break; \
+ default: \
+ x = 0; \
+ break; \
+ }
+
+# define SetHighlightMode(x) \
+ { \
+ if ((x)&HIGHLIGHT) { \
if (!inHighlightMode) { \
- inHighlightMode = 1; \
+ inHighlightMode = HIGHLIGHT; \
standout(); \
} \
} else { \
}
# define DoCharacterAt(c,p) { \
- SetTerminal(p, c); \
if (p != HighestScreen()) { \
- c = TerminalCharacterAttr(disp_asc[c&0xff], p, \
- fieldattr); \
+ c = disp_asc[c&0xff]; \
if (terminalCursorAddress != p) { \
if (ERR == mvaddch(ScreenLine(p), \
ScreenLineOffset(p), c)) {\
* decide when the output has caught up.
*/
- if (Highest == HighestScreen()) {
+ if (Highest >= HighestScreen()) { /* Could be > if screen shrunk... */
Highest = ScreenDec(Highest); /* else, while loop will never end */
}
if (Lowest < LowestScreen()) {
pointer += (bunequal(Host+pointer, Terminal+pointer,
(Highest-pointer+1)*sizeof Host[0])/sizeof Host[0]);
- /* how many characters to change until the end of the
+ /*
+ * How many characters to change until the end of the
* current line
*/
columnsleft = NumberColumns - ScreenLineOffset(pointer);
move(ScreenLine(pointer), ScreenLineOffset(pointer));
/* what is the field attribute of the current position */
- fieldattr = FieldAttributes(WhereAttrByte(pointer));
+ if (FormattedScreen()) {
+ fieldattr = FieldAttributes(pointer);
+ DoAttributes(fieldattr);
+ } else {
+ fieldattr = NORMAL;
+ }
+ if (TerminalFormattedScreen()) {
+ termattr = TermAttributes(pointer);
+ DoAttributes(termattr);
+ } else {
+ termattr = NORMAL;
+ }
- if ((IsStartField(pointer) != TermIsStartField(pointer)) ||
- (IsStartField(pointer) &&
- fieldattr != TermAttributes(pointer))) {
+ SetHighlightMode(fieldattr);
+ /*
+ * The following will terminate at least when we get back
+ * to the original 'pointer' location (since we force
+ * things to be equal).
+ */
+ for (;;) {
+ if (IsStartField(pointer)) {
+ shouldbe = DISP_BLANK;
+ shouldattr = 0;
+ fieldattr = GetHost(pointer);
+ DoAttributes(fieldattr);
+ } else {
+ if (fieldattr&NONDISPLAY) {
+ shouldbe = DISP_BLANK;
+ } else {
+ shouldbe = GetHost(pointer);
+ }
+ shouldattr = fieldattr;
+ }
+ if (TermIsStartField(pointer)) {
+ is = DISP_BLANK;
+ isattr = 0;
+ termattr = UNDETERMINED; /* Need to find out AFTER update */
+ } else {
+ if (termattr&NONDISPLAY) {
+ is = DISP_BLANK;
+ } else {
+ is = GetTerminal(pointer);
+ }
+ isattr = termattr;
+ }
+ if ((shouldbe == is) && (shouldattr == isattr)
+ && (GetHost(pointer) == GetTerminal(pointer))
+ && (GetHost(ScreenInc(pointer))
+ == GetTerminal(ScreenInc(pointer)))) {
+ break;
+ }
- int oldterm;
+ if (shouldattr^inHighlightMode) {
+ SetHighlightMode(shouldattr);
+ }
- oldterm = TermAttributes(pointer);
+ DoCharacterAt(shouldbe, pointer);
if (IsStartField(pointer)) {
- TermNewField(pointer, fieldattr);
- SetTerminal(pointer, 0);
+ TermNewField(pointer, FieldAttributes(pointer));
+ termattr = GetTerminal(pointer);
+ DoAttributes(termattr);
} else {
- TermDeleteField(pointer);
- }
- /* We always do the first character in a divergent
- * field, since otherwise the start of a field in
- * the Host structure may leave a highlighted blank
- * on the screen, and the start of a field in the
- * Terminal structure may leave a non-highlighted
- * something in the middle of a highlighted field
- * on the screen.
+ SetTerminal(pointer, GetHost(pointer));
+ /*
+ * If this USED to be a start field location,
+ * recompute the terminal attributes.
*/
- SetHighlightMode(pointer);
- c = GetHost(pointer);
- DoCharacterAt(c,pointer); /* MACRO */
-
- if (NotVisuallyCompatibleAttributes
- (pointer, fieldattr, oldterm)) {
- int j;
-
- j = pointer;
-
- pointer = ScreenInc(pointer);
- if (!(--columnsleft)) {
- DoARefresh();
- EmptyTerminal();
- move(ScreenLine(pointer), 0);
- columnsleft = NumberColumns;
- }
- SetHighlightMode(pointer); /* Turn on highlighting */
- while (!IsStartField(pointer) &&
- !TermIsStartField(pointer)) {
- c = GetHost(pointer);
- DoCharacterAt(c,pointer); /* MACRO */
- pointer = ScreenInc(pointer);
- if (!(--columnsleft)) {
- DoARefresh();
- EmptyTerminal();
- move(ScreenLine(pointer), 0);
- columnsleft = NumberColumns;
- /* We don't look at HaveInput here, since
- * if we leave this loop before the end of
- * the 3270 field, we could have pointer
- * higher than Highest. This would cause
- * us to end the highest "while" loop,
- * but we may, in fact, need to go around the
- * screen once again.
- */
- }
- /* The loop needs to be protected
- * from the situation where there had been only
- * one field on the Terminal, and none on the Host.
- * In this case, we have just deleted our last
- * field. Hence, the break.
- */
- if (j == pointer) {
- break;
+ if (termattr == UNDETERMINED) {
+ termattr = WhereTermAttrByte(pointer);
+ if ((termattr != 0) || TermIsStartField(0)) {
+ termattr = GetTerminal(termattr);
+ DoAttributes(termattr);
+ } else { /* Unformatted screen */
+ termattr = NORMAL;
}
}
- if (IsStartField(pointer) && !TermIsStartField(pointer)) {
- /* Remember what the terminal looked like */
- TermNewField(pointer, oldterm);
+ }
+ pointer = ScreenInc(pointer);
+ if (!(--columnsleft)) {
+ DoARefresh();
+ EmptyTerminal();
+ if (HaveInput) { /* if input came in, take it */
+ int c, j;
+
+ /*
+ * We need to start a new terminal field
+ * at this location iff the terminal attributes
+ * of this location are not what we have had
+ * them as (ie: we've overwritten the terminal
+ * start field, a the previous field had different
+ * display characteristics).
+ */
+
+ isattr = TermAttributes(pointer);
+ DoAttributes(isattr);
+ if ((!TermIsStartField(pointer)) &&
+ (isattr != termattr)) {
/*
- * The danger here is that the current position may
- * be the start of a Host field. If so, and the
- * field is highlighted, and our terminal was
- * highlighted, then we will leave a highlighted
- * blank at this position.
+ * Since we are going to leave a new field
+ * at this terminal position, we
+ * need to make sure that we get an actual
+ * non-highlighted blank on the screen.
*/
- SetHighlightMode(pointer);
- c = GetHost(pointer);
- DoCharacterAt(c,pointer);
- }
- /* We could be in the situation of needing to exit.
- * This could happen if the current field wrapped around
- * the end of the screen.
- */
- if (j > pointer) {
- break;
- }
- } else {
- c = GetHost(pointer);
- /* We always do the first character in a divergent
- * field, since otherwise the start of a field in
- * the Host structure may leave a highlighted blank
- * on the screen, and the start of a field in the
- * Terminal structure may leave a non-highlighted
- * something in the middle of a highlighted field
- * on the screen.
- */
- SetHighlightMode(pointer);
- DoCharacterAt(c,pointer);
- }
- } else {
- SetHighlightMode(pointer);
- /*
- * The following will terminate at least when we get back
- * to the original 'pointer' location (since we force
- * things to be equal).
- */
- while (((c = GetHost(pointer)) != GetTerminal(pointer)) &&
- !IsStartField(pointer) && !TermIsStartField(pointer)) {
- DoCharacterAt(c, pointer);
- pointer = ScreenInc(pointer);
- if (!(--columnsleft)) {
- DoARefresh();
- EmptyTerminal();
- if (HaveInput) { /* if input came in, take it */
- break;
+ if ((is != DISP_BLANK) || (termattr&HIGHLIGHT)) {
+ SetHighlightMode(0); /* Turn off highlight */
+ c = ScreenInc(pointer);
+ j = DISP_BLANK;
+ DoCharacterAt(j, c);
+ }
+ if (termattr&HIGHLIGHT) {
+ termattr = ATTR_DSPD_HIGH;
+ } else if (termattr&NONDISPLAY) {
+ termattr = ATTR_DSPD_NONDISPLAY;
+ } else {
+ termattr = 0;
+ }
+ TermNewField(pointer, termattr);
}
- move(ScreenLine(pointer), 0);
- columnsleft = NumberColumns;
+ break;
}
+ move(ScreenLine(pointer), 0);
+ columnsleft = NumberColumns;
}
- }
- }
+ } /* end of for (;;) */
+ } /* end of while (...) */
}
DoARefresh();
Lowest = pointer;
EmptyTerminal(); /* move data along */
return;
}
-#endif /* defined(SLOWSCREEN) */
\f
#if defined(NOT43)
static int
FastScreen(); /* Recurse */
return;
} else if (fieldattr) { /* Should we display? */
- addch(disp_asc[p->data]); /* Display translated data */
+ /* Display translated data */
+ addch((char)disp_asc[GetTerminalPointer(p)]);
} else {
addch(' '); /* Display a blank */
}
if (IsStartFieldPointer(p)) { /* New field? */
if (tmp != tmpbuf) {
*tmp++ = 0; /* close out */
- addstr(tmpbuf);
+ addstr((char *)tmpbuf);
tmp = tmpbuf;
- tmpend = tmpbuf + NumberColumns - ScreenLineOffset(p-Host);
+ tmpend = tmpbuf+NumberColumns-ScreenLineOffset(p-Host)-1;
}
+ standend();
+ addch(' ');
fieldattr = FieldAttributesPointer(p); /* Get attributes */
DoAttribute(fieldattr); /* Set standout, non-display */
- *tmp++ = ' ';
} else {
if (fieldattr) { /* Should we display? */
/* Display translated data */
- *tmp++ = disp_asc[p->data];
+ *tmp++ = disp_asc[GetTerminalPointer(p)];
} else {
*tmp++ = ' ';
}
int i = p-Host; /* Be sure the "p++" happened first! */
*tmp++ = 0;
- addstr(tmpbuf);
+ addstr((char *)tmpbuf);
tmp = tmpbuf;
move(ScreenLine(i), 0);
tmpend = tmpbuf + NumberColumns;
}
if (tmp != tmpbuf) {
*tmp++ = 0;
- addstr(tmpbuf);
+ addstr((char *)tmpbuf);
tmp = tmpbuf;
}
}
#endif /* defined(NOT43) */
(*TryToSend)() = FastScreen;
\f
+/*ARGSUSED*/
void
ScreenOIA(oia)
OIA *oia;
static int speeds[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800,
2400, 4800, 9600 };
#endif
+ extern void InitMapping();
InitMapping(); /* Go do mapping file (MAP3270) first */
if (!screenInitd) { /* not initialized */
extern char *tgetstr();
#endif /* defined(unix) */
-#if defined(SLOWSCREEN)
+ if (initscr() == ERR) { /* Initialize curses to get line size */
+ ExitString("InitTerminal: Error initializing curses", 1);
+ /*NOTREACHED*/
+ }
+ MaxNumberLines = LINES;
+ MaxNumberColumns = COLS;
ClearArray(Terminal);
-#endif /* defined(SLOWSCREEN) */
terminalCursorAddress = SetBufferAddress(0,0);
#if defined(unix)
signal(SIGHUP, abort);
#endif
TryToSend = FastScreen;
-#if defined(unix) && defined(SLOWSCREEN)
+#if defined(unix)
ioctl(1, TIOCGETP, (char *) &ourttyb);
if ((ourttyb.sg_ospeed < 0) || (ourttyb.sg_ospeed > B9600)) {
max_changes_before_poll = 1920;
TryToSend = SlowScreen;
HaveInput = 1; /* get signals going */
}
-#endif /* defined(unix) && defined(SLOWSCREEN) */
+#endif /* defined(unix) */
setcommandmode();
/*
* By now, initscr() (in curses) has been called (from telnet.c),
* be nice, but it messes us up.
*/
signal(SIGTSTP, SIG_DFL);
- if ((KS = tgetstr("ks", &lotsofspace)) != 0) {
- KS = strsave(KS);
- StringToTerminal(KS);
+ if ((myKS = tgetstr("ks", &lotsofspace)) != 0) {
+ myKS = strsave(myKS);
+ StringToTerminal(myKS);
}
- if ((KE = tgetstr("ke", &lotsofspace)) != 0) {
- KE = strsave(KE);
+ if ((myKE = tgetstr("ke", &lotsofspace)) != 0) {
+ myKE = strsave(myKE);
}
if (tgetstr("md", &lotsofspace) && tgetstr("me", &lotsofspace)) {
SO = strsave(tgetstr("md", &lotsofspace));
screenInitd = 1;
screenStopped = 0; /* Not stopped */
}
- Initialized = 1;
}
if (screenInitd && !screenStopped) {
move(NumberLines-1, 1);
standend();
-#if defined(SLOWSCREEN)
inHighlightMode = 0;
-#endif /* defined(SLOWSCREEN) */
DoARefresh();
setcommandmode();
endwin();
setconnmode();
#if defined(unix)
- if (KE) {
- StringToTerminal(KE);
+ if (myKE) {
+ StringToTerminal(myKE);
}
#endif /* defined(unix) */
if (doNewLine) {
{
if (screenInitd) {
#if defined(unix)
- if (KS) {
- StringToTerminal(KS);
+ if (myKS) {
+ StringToTerminal(myKS);
}
#endif /* defined(unix) */
RefreshScreen();
void
LocalClearScreen()
{
+ extern void Clear3270();
+
outputPurge(); /* flush all data to terminal */
clear(); /* clear in curses */
-#if defined(SLOWSCREEN)
ClearArray(Terminal);
-#endif /* defined(SLOWSCREEN) */
Clear3270();
Lowest = HighestScreen()+1; /* everything in sync... */
Highest = LowestScreen()+1;
delwin(bellwin);
bellwin = 0;
bellwinup = 0;
- Lowest = MIN(Lowest, LINES/2);
- Highest = MAX(Highest, (LINES/2)+3);
-#if defined(SLOWSCREEN)
- memset(Terminal+LINES/2, 0, (sizeof Terminal[0])*(3*COLS));
-#endif /* defined(SLOWSCREEN) */
touchwin(stdscr);
DoARefresh();
}
len = COLS-2;
}
if ((bellwin = newwin(3, len+2, LINES/2, 0)) == NULL) {
- OurExitString(stderr, "Error from newwin in RingBell", 1);
+ OurExitString("Error from newwin in RingBell", 1);
}
werase(bellwin);
wstandout(bellwin);
box(bellwin, '|', '-');
if (wmove(bellwin, 1, 1) == ERR) {
- OurExitString(stderr, "Error from wmove in RingBell", 1);
+ OurExitString("Error from wmove in RingBell", 1);
}
while (len--) {
if (waddch(bellwin, *s++) == ERR) {
- OurExitString(stderr, "Error from waddch in RingBell", 1);
+ OurExitString("Error from waddch in RingBell", 1);
}
}
wstandend(bellwin);
if (wrefresh(bellwin) == ERR) {
- OurExitString(stderr, "Error from wrefresh in RingBell", 1);
+ OurExitString("Error from wrefresh in RingBell", 1);
}
bellwinup = 1;
}
DoTerminalOutput()
{
/* called just before a select to conserve IO to terminal */
- if (!Initialized) {
+ if (!(screenInitd||screenStopped)) {
return 1; /* No output if not initialized */
}
if ((Lowest <= Highest) || needToRing ||
}
void
-TransOut(buffer, count)
+TransOut(buffer, count, kind, control)
unsigned char *buffer;
int count;
+int kind; /* 0 or 5 */
+int control; /* To see if we are done */
{
#if defined(unix)
extern char *transcom;
- int inpipefd[2], outpipefd[2], savemode;
+ int inpipefd[2], outpipefd[2];
void aborttc();
#endif /* defined(unix) */
setcommandmode();
tin = inpipefd[0];
tout = outpipefd[1];
- (void) signal(SIGCHLD, aborttc);
+ (void) signal(SIGCHLD, (int (*)())aborttc);
setconnmode();
tcflag = 1;
break;
}
}
#endif /* defined(unix) */
- (void) DataToTerminal(buffer, count);
+ (void) DataToTerminal((char *)buffer, count);
+ if (control && (kind == 0)) { /* Send in AID byte */
+ SendToIBM();
+ } else {
+ extern void TransInput();
+
+ TransInput(1, kind); /* Go get some data */
+ }
}
static void
aborttc()
{
- int savemode;
-
setcommandmode();
(void) close(tin);
(void) close(tout);