root/src/noit_console_telnet.h

Revision c4546c715aee6db46888e7ab0bb87fd2ce5357c6, 10.9 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 7 years ago)

I sure hope this doesn't break other platforms too badly. Solaris support sans the eventer... untested, of course. refs #32.

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 1989, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 2007
5  *      OmnitTI Computer Consulting, Inc.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by the University of
18  *      California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *      @(#)defs.h      8.1 (Berkeley) 6/4/93
36  */
37
38 #ifndef _NOIT_CONSOLE_TELNET_H
39 #define _NOIT_CONSOLE_TELNET_H
40
41 #include "noit_defines.h"
42 #include "utils/noit_hash.h"
43
44 #include <arpa/telnet.h>
45 #include <sys/ioctl.h>
46 #ifdef HAVE_SYS_IOCTL_COMPAT_H
47 #include <sys/ioctl_compat.h>
48 #endif
49 #ifdef HAVE_TERMIOS_H
50 #include <termios.h>
51 #endif
52 #ifdef HAVE_CURSES_H
53 #include <curses.h>
54 #endif
55 #ifdef HAVE_TERMIO_H
56 #include <termio.h>
57 #endif
58 #ifdef HAVE_TERM_H
59 #include <term.h>
60 #endif
61
62 #if !defined(__linux__) && !defined(__sun)
63 /* At least _I_ can't get LINUMODE working on Linux */
64 #define LINEMODE 1
65 #endif
66
67 #ifndef _POSIX_VDISABLE
68 # ifdef VDISABLE
69 #  define _POSIX_VDISABLE VDISABLE
70 # else
71 #  define _POSIX_VDISABLE ((unsigned char)'\377')
72 # endif
73 #endif
74
75 /*
76  * Structures of information for each special character function.
77  */
78
79 typedef struct {
80         unsigned char   flag;           /* the flags for this function */
81         unsigned char   val;            /* the value of the special character */
82 } slcent, *Slcent;
83
84 typedef struct {
85         slcent          defset;         /* the default settings */
86         slcent          current;        /* the current settings */
87         unsigned char   *sptr;          /* a pointer to the char in */
88                                         /* system data structures */
89 } slcfun, *Slcfun;
90
91 #ifndef USE_TERMIO
92 struct termbuf {
93         struct sgttyb sg;
94         struct tchars tc;
95         struct ltchars ltc;
96         int state;
97         int lflags;
98 };
99 # define        cfsetospeed(tp, val)    (tp)->sg.sg_ospeed = (val)
100 # define        cfsetispeed(tp, val)    (tp)->sg.sg_ispeed = (val)
101 # define        cfgetospeed(tp)         (tp)->sg.sg_ospeed
102 # define        cfgetispeed(tp)         (tp)->sg.sg_ispeed
103 #else   /* USE_TERMIO */
104 # ifndef        TCSANOW
105 #  ifdef TCSETS
106 #   define      TCSANOW         TCSETS
107 #   define      TCSADRAIN       TCSETSW
108 #   define      tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
109 #  else
110 #   ifdef TCSETA
111 #    define     TCSANOW         TCSETA
112 #    define     TCSADRAIN       TCSETAW
113 #    define     tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
114 #   else
115 #    define     TCSANOW         TIOCSETA
116 #    define     TCSADRAIN       TIOCSETAW
117 #    define     tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
118 #   endif
119 #  endif
120 #  define       tcsetattr(f, a, t)      ioctl(f, a, t)
121 #  define       cfsetospeed(tp, val)    (tp)->c_cflag &= ~CBAUD; \
122                                         (tp)->c_cflag |= (val)
123 #  define       cfgetospeed(tp)         ((tp)->c_cflag & CBAUD)
124 #  ifdef CIBAUD
125 #   define      cfsetispeed(tp, val)    (tp)->c_cflag &= ~CIBAUD; \
126                                         (tp)->c_cflag |= ((val)<<IBSHIFT)
127 #   define      cfgetispeed(tp)         (((tp)->c_cflag & CIBAUD)>>IBSHIFT)
128 #  else
129 #   define      cfsetispeed(tp, val)    (tp)->c_cflag &= ~CBAUD; \
130                                         (tp)->c_cflag |= (val)
131 #   define      cfgetispeed(tp)         ((tp)->c_cflag & CBAUD)
132 #  endif
133 # endif /* TCSANOW */
134 #endif  /* USE_TERMIO */
135
136 /*
137  * The following are some clocks used to decide how to interpret
138  * the relationship between various variables.
139  */
140
141 struct clocks_t {
142     int
143         system,                 /* what the current time is */
144         echotoggle,             /* last time user entered echo character */
145         modenegotiated,         /* last time operating mode negotiated */
146         didnetreceive,          /* last time we read data from network */
147         ttypesubopt,            /* ttype subopt is received */
148         tspeedsubopt,           /* tspeed subopt is received */
149         environsubopt,          /* environ subopt is received */
150         oenvironsubopt,         /* old environ subopt is received */
151         xdisplocsubopt,         /* xdisploc subopt is received */
152         baseline,               /* time started to do timed action */
153         gotDM;                  /* when did we last see a data mark */
154 };
155
156 typedef struct {
157   noit_hash_table _env;
158   unsigned char *_subbuffer;
159   unsigned char *_subpointer;
160   unsigned char *_subend;
161   unsigned char *_subsave;
162   unsigned char  _pty_buf[1024];
163   int            _pty_fill;
164   slcfun         _slctab[NSLC + 1];
165   char           _options[256];
166   char           _do_dont_resp[256];
167   char           _will_wont_resp[256];
168   int            _SYNCHing;
169   int            _flowmode;
170   int            _restartany;
171   int            __terminit;
172   int            _linemode;
173   int            _uselinemode;
174   int            _alwayslinemode;
175   int            _editmode;
176   int            _useeditmode;
177   unsigned char *_def_slcbuf;
178   int            _def_slclen;
179   int            _slcchange;    /* change to slc is requested */
180   unsigned char *_slcptr;       /* pointer into slc buffer */
181   unsigned char  _slcbuf[NSLC*6];       /* buffer for slc negotiation */
182
183   int            _def_tspeed; /* This one */
184   int            _def_rspeed; /* and this one, need init to -1 */
185 #if     !defined(LINEMODE) || !defined(KLUDGELINEMODE)
186   int            _turn_on_sga;
187 #endif
188 #ifdef TIOCSWINSZ
189   int            _def_row;
190   int            _def_col;
191 #endif
192   char           _terminalname[41];
193   struct clocks_t _clocks;
194 #ifdef USE_TERMIO
195   struct termios _termbuf, _termbuf2;   /* pty control structure */
196 #else
197   struct termbuf _termbuf, _termbuf2;   /* pty control structure */
198 #endif
199 } *noit_console_telnet_closure_t;
200
201
202 /*
203  * We keep track of each side of the option negotiation.
204  */
205
206 #define MY_STATE_WILL           0x01
207 #define MY_WANT_STATE_WILL      0x02
208 #define MY_STATE_DO             0x04
209 #define MY_WANT_STATE_DO        0x08
210
211 /*
212  * Macros to check the current state of things
213  */
214
215 #define my_state_is_do(opt)             (ncct->telnet->_options[opt]&MY_STATE_DO)
216 #define my_state_is_will(opt)           (ncct->telnet->_options[opt]&MY_STATE_WILL)
217 #define my_want_state_is_do(opt)        (ncct->telnet->_options[opt]&MY_WANT_STATE_DO)
218 #define my_want_state_is_will(opt)      (ncct->telnet->_options[opt]&MY_WANT_STATE_WILL)
219
220 #define my_state_is_dont(opt)           (!my_state_is_do(opt))
221 #define my_state_is_wont(opt)           (!my_state_is_will(opt))
222 #define my_want_state_is_dont(opt)      (!my_want_state_is_do(opt))
223 #define my_want_state_is_wont(opt)      (!my_want_state_is_will(opt))
224
225 #define set_my_state_do(opt)            (ncct->telnet->_options[opt] |= MY_STATE_DO)
226 #define set_my_state_will(opt)          (ncct->telnet->_options[opt] |= MY_STATE_WILL)
227 #define set_my_want_state_do(opt)       (ncct->telnet->_options[opt] |= MY_WANT_STATE_DO)
228 #define set_my_want_state_will(opt)     (ncct->telnet->_options[opt] |= MY_WANT_STATE_WILL)
229
230 #define set_my_state_dont(opt)          (ncct->telnet->_options[opt] &= ~MY_STATE_DO)
231 #define set_my_state_wont(opt)          (ncct->telnet->_options[opt] &= ~MY_STATE_WILL)
232 #define set_my_want_state_dont(opt)     (ncct->telnet->_options[opt] &= ~MY_WANT_STATE_DO)
233 #define set_my_want_state_wont(opt)     (ncct->telnet->_options[opt] &= ~MY_WANT_STATE_WILL)
234
235 /*
236  * Tricky code here.  What we want to know is if the MY_STATE_WILL
237  * and MY_WANT_STATE_WILL bits have the same value.  Since the two
238  * bits are adjacent, a little arithmatic will show that by adding
239  * in the lower bit, the upper bit will be set if the two bits were
240  * different, and clear if they were the same.
241  */
242 #define my_will_wont_is_changing(opt) \
243                         ((ncct->telnet->_options[opt]+MY_STATE_WILL) & MY_WANT_STATE_WILL)
244
245 #define my_do_dont_is_changing(opt) \
246                         ((ncct->telnet->_options[opt]+MY_STATE_DO) & MY_WANT_STATE_DO)
247
248 /*
249  * Make everything symmetrical
250  */
251
252 #define HIS_STATE_WILL                  MY_STATE_DO
253 #define HIS_WANT_STATE_WILL             MY_WANT_STATE_DO
254 #define HIS_STATE_DO                    MY_STATE_WILL
255 #define HIS_WANT_STATE_DO               MY_WANT_STATE_WILL
256
257 #define his_state_is_do                 my_state_is_will
258 #define his_state_is_will               my_state_is_do
259 #define his_want_state_is_do            my_want_state_is_will
260 #define his_want_state_is_will          my_want_state_is_do
261
262 #define his_state_is_dont               my_state_is_wont
263 #define his_state_is_wont               my_state_is_dont
264 #define his_want_state_is_dont          my_want_state_is_wont
265 #define his_want_state_is_wont          my_want_state_is_dont
266
267 #define set_his_state_do                set_my_state_will
268 #define set_his_state_will              set_my_state_do
269 #define set_his_want_state_do           set_my_want_state_will
270 #define set_his_want_state_will         set_my_want_state_do
271
272 #define set_his_state_dont              set_my_state_wont
273 #define set_his_state_wont              set_my_state_dont
274 #define set_his_want_state_dont         set_my_want_state_wont
275 #define set_his_want_state_wont         set_my_want_state_dont
276
277 #define his_will_wont_is_changing       my_do_dont_is_changing
278 #define his_do_dont_is_changing         my_will_wont_is_changing
279
280 struct __noit_console_closure;
281 void
282   noit_console_telnet_willoption(struct __noit_console_closure *ncct,
283                                  int option);
284 void
285   noit_console_telnet_wontoption(struct __noit_console_closure *ncct,
286                                  int option);
287 void
288   noit_console_telnet_dooption(struct __noit_console_closure *ncct,
289                                int option);
290 void
291   noit_console_telnet_dontoption(struct __noit_console_closure *ncct,
292                                  int option);
293 void
294   noit_console_telnet_send_do(struct __noit_console_closure *ncct,
295                               int option, int init);
296 void
297   noit_console_telnet_send_dont(struct __noit_console_closure *ncct,
298                                 int option, int init);
299 void
300   noit_console_telnet_send_will(struct __noit_console_closure *ncct,
301                                 int option, int init);
302 void
303   noit_console_telnet_send_wont(struct __noit_console_closure *ncct,
304                                 int option, int init);
305 void
306   noit_console_telnet_doclientstat(struct __noit_console_closure *ncct);
307 void
308   noit_console_telnet_send_status(struct __noit_console_closure *ncct);
309
310 void noit_console_telnet_free(noit_console_telnet_closure_t);
311 noit_console_telnet_closure_t
312   noit_console_telnet_alloc(struct __noit_console_closure *ncct);
313 int
314   noit_console_telnet_telrcv(struct __noit_console_closure *ncct,
315                              const void *buf, int buflen);
316 void ptyflush(struct __noit_console_closure *ncct);
317
318 #endif
Note: See TracBrowser for help on using the browser.