1 /* $NetBSD: tn3270.c,v 1.21 2003/08/07 11:16:12 agc Exp $ */
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)tn3270.c 8.2 (Berkeley) 5/30/95";
37 __RCSID("$NetBSD: tn3270.c,v 1.21 2003/08/07 11:16:12 agc Exp $");
41 #include <sys/types.h>
43 #include <arpa/telnet.h>
54 #include "../ctlr/screen.h"
55 #include "../ctlr/declare.h"
57 #include "../ascii/state.h"
59 #include "../general/globals.h"
61 #include "../sys_curses/telextrn.h"
64 HaveInput
, /* There is input available to scan */
65 cursesdata
, /* Do we dump curses data? */
66 sigiocount
; /* Number of times we got a SIGIO */
69 char *transcom
= 0; /* transparent mode command (default: none) */
71 char Ibuf
[8*BUFSIZ
], *Ifrontp
, *Ibackp
;
73 static char sb_terminal
[] = { IAC
, SB
,
74 TELOPT_TTYPE
, TELQUAL_IS
,
75 'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
77 #define SBTERMMODEL 13
80 Sent3270TerminalType
; /* Have we said we are a 3270? */
82 #endif /* defined(TN3270) */
91 Sent3270TerminalType
= 0;
92 Ifrontp
= Ibackp
= Ibuf
;
93 init_ctlr(); /* Initialize some things */
98 #endif /* defined(TN3270) */
104 * DataToNetwork - queue up some data to go to network. If "done" is set,
105 * then when last byte is queued, we add on an IAC EOR sequence (so,
106 * don't call us with "done" until you want that done...)
108 * We actually do send all the data to the network buffer, since our
109 * only client needs for us to do that.
113 DataToNetwork(char *buffer
, /* where the data is */
114 int count
, /* how much to send */
115 int done
) /* is this the last of a logical block */
123 /* If not enough room for EORs, IACs, etc., wait */
125 struct pollfd set
[1];
128 set
[0].events
= POLLOUT
;
130 while (NETROOM() < 6) {
131 (void) poll(set
, 1, INFTIM
);
135 c
= ring_empty_count(&netoring
);
141 if (((unsigned char)*buffer
) == IAC
) {
148 ring_supply_data(&netoring
, buffer
-c
, c
);
160 netflush(); /* try to move along as quickly as ... */
162 return(origCount
- count
);
167 inputAvailable(int signo
)
181 * The following routines are places where the various tn3270
182 * routines make calls into telnet.c.
186 * DataToTerminal - queue up some data to go to terminal.
188 * Note: there are people who call us and depend on our processing
189 * *all* the data at one time (thus the poll).
194 char *buffer
, /* where the data is */
195 int count
) /* how much to send */
203 if (TTYROOM() == 0) {
204 struct pollfd set
[1];
207 set
[0].events
= POLLOUT
;
209 while (TTYROOM() == 0) {
210 (void) poll(set
, 1, INFTIM
);
218 ring_supply_data(&ttyoring
, buffer
, c
);
227 * Push3270 - Try to send data along the 3270 output (to screen) direction.
233 int save
= ring_full_count(&netiring
);
236 if (Ifrontp
+save
> Ibuf
+sizeof Ibuf
) {
237 if (Ibackp
!= Ibuf
) {
238 memmove(Ibuf
, Ibackp
, Ifrontp
-Ibackp
);
239 Ifrontp
-= (Ibackp
-Ibuf
);
243 if (Ifrontp
+save
< Ibuf
+sizeof Ibuf
) {
247 return save
!= ring_full_count(&netiring
);
252 * Finish3270 - get the last dregs of 3270 data out to the terminal
259 while (Push3270() || !DoTerminalOutput()) {
266 /* StringToTerminal - output a null terminated string to the terminal */
269 StringToTerminal(char *s
)
275 (void) DataToTerminal(s
, count
); /* we know it always goes... */
280 /* _putchar - output a single character to the terminal. This name is so that
281 * curses(3x) can call us to send out data.
292 (void) DataToTerminal(&c
, 1);
303 if (Sent3270TerminalType
&& my_want_state_is_will(TELOPT_BINARY
)
304 && my_want_state_is_do(TELOPT_BINARY
) && !donebinarytoggle
) {
307 Init3270(); /* Initialize 3270 functions */
308 /* initialize terminal key mapping */
309 InitTerminal(); /* Start terminal going */
316 Stop3270(); /* Tell 3270 we aren't here anymore */
325 * Send a response to a terminal type negotiation.
327 * Return '0' if no more responses to send; '1' if a response sent.
334 * Try to send a 3270 type terminal name. Decide which one based
335 * on the format of our screen, and (in the future) color
338 InitTerminal(); /* Sets MaxNumberColumns, MaxNumberLines */
339 if ((MaxNumberLines
>= 24) && (MaxNumberColumns
>= 80)) {
340 Sent3270TerminalType
= 1;
341 if ((MaxNumberLines
>= 27) && (MaxNumberColumns
>= 132)) {
343 MaxNumberColumns
= 132;
344 sb_terminal
[SBTERMMODEL
] = '5';
345 } else if (MaxNumberLines
>= 43) {
347 MaxNumberColumns
= 80;
348 sb_terminal
[SBTERMMODEL
] = '4';
349 } else if (MaxNumberLines
>= 32) {
351 MaxNumberColumns
= 80;
352 sb_terminal
[SBTERMMODEL
] = '3';
355 MaxNumberColumns
= 80;
356 sb_terminal
[SBTERMMODEL
] = '2';
358 NumberLines
= 24; /* before we start out... */
360 ScreenSize
= NumberLines
*NumberColumns
;
361 if ((MaxNumberLines
*MaxNumberColumns
) > MAXSCREENSIZE
) {
362 ExitString("Programming error: MAXSCREENSIZE too small.\n",
366 printsub('>', sb_terminal
+2, sizeof sb_terminal
-2);
367 ring_supply_data(&netoring
, sb_terminal
, sizeof sb_terminal
);
375 settranscom(int argc
, char *argv
[])
379 if (argc
== 1 && transcom
) {
386 (void) strlcpy(tline
, argv
[1], sizeof(tline
));
387 for (i
= 2; i
< argc
; ++i
) {
388 (void) strlcat(tline
, " ", sizeof(tline
));
389 (void) strlcat(tline
, argv
[i
], sizeof(tline
));
394 #endif /* defined(TN3270) */