tn3270.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:10k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1988, 1990, 1993                                            */
  2. /* The Regents of the University of California.  All rights reserved.        */
  3. /*                                                                           */
  4. /* Redistribution and use in source and binary forms, with or without        */
  5. /* modification, are permitted provided that the following conditions        */
  6. /* are met:                                                                  */
  7. /* 1. Redistributions of source code must retain the above copyright         */
  8. /* notice, this list of conditions and the following disclaimer.             */
  9. /* 2. Redistributions in binary form must reproduce the above copyright      */
  10. /* notice, this list of conditions and the following disclaimer in the       */
  11. /* documentation and/or other materials provided with the distribution.      */
  12. /* 3. All advertising materials mentioning features or use of this           */
  13. /* software must display the following acknowledgement:                      */
  14. /*   This product includes software developed by the University of           */
  15. /*   California, Berkeley and its contributors.                              */
  16. /* 4. Neither the name of the University nor the names of its contributors   */
  17. /* may be used to endorse or promote products derived from this software     */
  18. /* without specific prior written permission.                                */
  19. /*                                                                           */
  20. /* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND   */
  21. /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE     */
  22. /* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        */
  23. /* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE */
  24. /* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR       */
  25. /* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF      */
  26. /* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  */
  27. /* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN   */
  28. /* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)   */
  29. /* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF    */
  30. /* THE POSSIBILITY OF SUCH DAMAGE.                                           */
  31. #ifdef SHOW_SCCSIDS
  32. static char sccsid[] = "@(#)tn3270.c 8.2 (Berkeley) 5/30/95";
  33. #endif
  34. #include <sys/types.h>
  35. #include <arpa/telnet.h>
  36. #include "general.h"
  37. #include "defines.h"
  38. #include "ring.h"
  39. #include "externs.h"
  40. #include "fdset.h"
  41. #ifdef TN3270
  42. #include "../ctlr/screen.h"
  43. #include "../general/globals.h"
  44. #include "../sys_curses/telextrn.h"
  45. #include "../ctlr/externs.h"
  46. int HaveInput;     /* There is input available to scan              */
  47. int cursesdata;      /* Do we dump curses data?                       */
  48. int sigiocount;     /* Number of times we got a SIGIO                */
  49. char tline[200];
  50. char *transcom = 0;     /* transparent mode command (default: none)      */
  51. char Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;
  52. static char sb_terminal[] = { IAC, SB, TELOPT_TTYPE, TELQUAL_IS, 'I', 'B', 'M',
  53.       '-', '3', '2', '7', '8', '-', '2', IAC, SE };
  54. #define SBTERMMODEL 13
  55. static int Sent3270TerminalType; /* Have we said we are a 3270?              */
  56. #endif
  57. void init_3270() {
  58. #ifdef TN3270
  59.     HaveInput = 0;
  60.     sigiocount = 0;
  61.     Sent3270TerminalType = 0;
  62.     Ifrontp = Ibackp = Ibuf;
  63.     init_ctlr(); /* Initialize some things */
  64.     init_keyboard();
  65.     init_screen();
  66.     init_system();
  67. #endif /* defined(TN3270) */
  68. }
  69. #ifdef TN3270
  70. /* DataToNetwork - queue up some data to go to network.  If "done" is set,   */
  71. /* then when last byte is queued, we add on an IAC EOR sequence (so, don't   */
  72. /* call us with "done" until you want that done...)                          */
  73. /*                                                                           */
  74. /* We actually do send all the data to the network buffer, since our only    */
  75. /* client needs for us to do that.                                           */
  76. int DataToNetwork(register char *buffer, register int count, int done) {
  77.     register int loop, c;
  78.     int origCount;
  79.     origCount = count;
  80.     while (count) {
  81. /* If not enough room for EORs, IACs, etc., wait */
  82. if (NETROOM() < 6) {
  83.     fd_set o;
  84.     FD_ZERO(&o);
  85.     netflush();
  86.     while (NETROOM() < 6) {
  87. FD_SET(net, &o);
  88. (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
  89. (struct timeval *) 0);
  90. netflush();
  91.     }
  92. }
  93. c = ring_empty_count(&netoring);
  94. if (c > count) {
  95.     c = count;
  96. }
  97. loop = c;
  98. while (loop) {
  99.     if (((unsigned char)*buffer) == IAC) {
  100. break;
  101.     }
  102.     buffer++;
  103.     loop--;
  104. }
  105. if ((c = c-loop)) {
  106.     ring_supply_data(&netoring, buffer-c, c);
  107.     count -= c;
  108. }
  109. if (loop) {
  110.     NET2ADD(IAC, IAC);
  111.     count--;
  112.     buffer++;
  113. }
  114.     }
  115.     if (done) {
  116. NET2ADD(IAC, EOR);
  117. netflush(); /* try to move along as quickly as ... */
  118.     }
  119.     return(origCount - count);
  120. }
  121. void inputAvailable(int signo) {
  122.     HaveInput = 1;
  123.     sigiocount++;
  124. }
  125. void outputPurge() {
  126.     (void)ttyflush(1);
  127. }
  128. /* The following routines are places where the various tn3270 routines make  */
  129. /* calls into telnet.c.                                                      */
  130. /* DataToTerminal - queue up some data to go to terminal.                    */
  131. /*                                                                           */
  132. /* Note: there are people who call us and depend on our processing *all* the */
  133. /* data at one time (thus the select).                                       */
  134. int DataToTerminal(register char *buffer, register int count) {
  135.     register int c;
  136.     int origCount;
  137.     origCount = count;
  138.     while (count) {
  139. if (TTYROOM() == 0) {
  140.     fd_set o;
  141.     FD_ZERO(&o);
  142.     (void) ttyflush(0);
  143.     while (TTYROOM() == 0) {
  144. FD_SET(tout, &o);
  145. (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
  146. (struct timeval *) 0);
  147. (void) ttyflush(0);
  148.     }
  149. }
  150. c = TTYROOM();
  151. if (c > count) {
  152.     c = count;
  153. }
  154. ring_supply_data(&ttyoring, buffer, c);
  155. count -= c;
  156. buffer += c;
  157.     }
  158.     return(origCount);
  159. }
  160. /* Push3270 - Try to send data along the 3270 output (to screen)             */
  161. /* direction.                                                                */
  162. int Push3270() {
  163.     int save = ring_full_count(&netiring);
  164.     if (save) {
  165. if (Ifrontp+save > Ibuf+sizeof Ibuf) {
  166.     if (Ibackp != Ibuf) {
  167. memmove(Ibuf, Ibackp, Ifrontp-Ibackp);
  168. Ifrontp -= (Ibackp-Ibuf);
  169. Ibackp = Ibuf;
  170.     }
  171. }
  172. if (Ifrontp+save < Ibuf+sizeof Ibuf) {
  173.     (void)telrcv();
  174. }
  175.     }
  176.     return save != ring_full_count(&netiring);
  177. }
  178. /* Finish3270 - get the last dregs of 3270 data out to the terminal          */
  179. /* before quitting.                                                          */
  180. void Finish3270() {
  181.     while (Push3270() || !DoTerminalOutput()) {
  182. HaveInput = 0;
  183.     }
  184. }
  185. /* StringToTerminal - output a null terminated string to the terminal */
  186. void StringToTerminal(char *s) {
  187.     int count;
  188.     count = strlen(s);
  189.     if (count) {
  190. (void) DataToTerminal(s, count); /* we know it always goes... */
  191.     }
  192. }
  193. #if ((!defined(NOT43)) || defined(PUTCHAR))
  194. /* _putchar - output a single character to the terminal.  This name is so that
  195.  * curses(3x) can call us to send out data.
  196.  */
  197. void _putchar(char c) {
  198. #if defined(sun) && !defined(__svr4__) /* SunOS 4.0 bug */
  199.     c &= 0x7f;
  200. #endif /* defined(sun) */
  201.     if (cursesdata) {
  202. Dump('>', &c, 1);
  203.     }
  204.     if (!TTYROOM()) {
  205. (void) DataToTerminal(&c, 1);
  206.     } else {
  207. TTYADD(c);
  208.     }
  209. }
  210. #endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */
  211. void SetIn3270() {
  212.     if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY)
  213. && my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) {
  214. if (!In3270) {
  215.     In3270 = 1;
  216.     Init3270(); /* Initialize 3270 functions */
  217.          /* initialize terminal key mapping */
  218.     InitTerminal(); /* Start terminal going */
  219.     setconnmode(0);
  220. }
  221.     } else {
  222. if (In3270) {
  223.     StopScreen(1);
  224.     In3270 = 0;
  225.     Stop3270(); /* Tell 3270 we aren't here anymore */
  226.     setconnmode(0);
  227. }
  228.     }
  229. }
  230. /* tn3270_ttype()                                                            */
  231. /*                                                                           */
  232. /* Send a response to a terminal type negotiation.                           */
  233. /* Return '0' if no more responses to send; '1' if a response sent.          */
  234. int tn3270_ttype() {
  235.     /* Try to send a 3270 type terminal name.  Decide which one based on the */
  236.     /* format of our screen, and (in the future) color capaiblities.         */
  237.     InitTerminal(); /* Sets MaxNumberColumns, MaxNumberLines */
  238.     if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
  239. Sent3270TerminalType = 1;
  240. if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
  241.     MaxNumberLines = 27;
  242.     MaxNumberColumns = 132;
  243.     sb_terminal[SBTERMMODEL] = '5';
  244. } else if (MaxNumberLines >= 43) {
  245.     MaxNumberLines = 43;
  246.     MaxNumberColumns = 80;
  247.     sb_terminal[SBTERMMODEL] = '4';
  248. } else if (MaxNumberLines >= 32) {
  249.     MaxNumberLines = 32;
  250.     MaxNumberColumns = 80;
  251.     sb_terminal[SBTERMMODEL] = '3';
  252. } else {
  253.     MaxNumberLines = 24;
  254.     MaxNumberColumns = 80;
  255.     sb_terminal[SBTERMMODEL] = '2';
  256. }
  257. NumberLines = 24; /* before we start out... */
  258. NumberColumns = 80;
  259. ScreenSize = NumberLines*NumberColumns;
  260. if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
  261.     ExitString("Programming error:  MAXSCREENSIZE too small.n",
  262. 1);
  263.     /*NOTREACHED*/
  264. }
  265. printsub('>', sb_terminal+2, sizeof sb_terminal-2);
  266. ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
  267. return 1;
  268.     } else {
  269. return 0;
  270.     }
  271. }
  272. int settranscom(int argc, char *argv[]) {
  273. int i;
  274. if (argc == 1 && transcom) {
  275.    transcom = 0;
  276. }
  277. if (argc == 1) {
  278.    return 1;
  279. }
  280. transcom = tline;
  281. (void) strcpy(transcom, argv[1]);
  282. for (i = 2; i < argc; ++i) {
  283.     (void) strcat(transcom, " ");
  284.     (void) strcat(transcom, argv[i]);
  285. }
  286. return 1;
  287. }
  288. #endif /* defined(TN3270) */