OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [telnet/] [tn3270.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.