1 
2 /* $Id: endp.c,v 1.27 2002/05/15 02:05:36 bsd Exp $ */
3 
4 /*
5  * Copyright 2000, 2001, 2002 Brian S. Dean <bsd@bsdhome.com>
6  * All Rights Reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY BRIAN S. DEAN ``AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL BRIAN S. DEAN BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
28  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29  * DAMAGE.
30  *
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <errno.h>
39 #include <netinet/in.h>
40 #include <netdb.h>
41 #include <ctype.h>
42 #include <fcntl.h>
43 #include <assert.h>
44 #include <sys/types.h>
45 #include <sys/sysctl.h>
46 #include <termios.h>
47 #include <unistd.h>
48 
49 #include "comserv.h"
50 #include "cmd.h"
51 #include "endp.h"
52 #include "log.h"
53 #include "pty.h"
54 
55 
56 char * endp_versionid = "$Id: endp.c,v 1.27 2002/05/15 02:05:36 bsd Exp $";
57 
58 
59 ENDPOINT ** endpoint     = NULL;
60 int         max_endpoint = 0;
61 
62 
endp_init(void)63 int endp_init(void)
64 {
65   int maxfiles;
66   int i;
67 
68   maxfiles = FD_SETSIZE;
69 
70   endpoint = (ENDPOINT **)malloc(sizeof(ENDPOINT *)*maxfiles);
71   if (endpoint == NULL) {
72     msgout("endp_init(): can't alloc %d bytes of memory for endpoint array\n",
73            sizeof(ENDPOINT)*maxfiles);
74     return -2;
75   }
76 
77   max_endpoint = maxfiles;
78 
79   for (i=0; i<max_endpoint; i++) {
80     endpoint[i] = NULL;
81   }
82 
83   return maxfiles;
84 }
85 
86 
init_endp(ENDPOINT * e)87 void init_endp(ENDPOINT * e)
88 {
89   memset(e, 0, sizeof(*e));
90   e->state  = ST_START;
91   e->fd     = -1;
92   e->bufcnt = 0;
93   e->bufptr = e->buf;
94 
95   return;
96 }
97 
98 
99 
new_endp(void)100 ENDPOINT * new_endp(void)
101 {
102   ENDPOINT * e;
103   static int ne = 0;
104 
105   ne++;
106 
107   e = (ENDPOINT *)malloc(sizeof(ENDPOINT));
108   if (e == NULL) {
109     msgout("out of memory allocating the endpoint no. %d\n", ne);
110     exit(1);
111   }
112 
113   init_endp(e);
114 
115   return e;
116 }
117 
118 
119 
endp_attr(ENDPOINT * e)120 int endp_attr(ENDPOINT * e)
121 {
122   int rc;
123   struct termios termios;
124   int err;
125 
126   if (!isatty(e->fd))
127     return 0;
128 
129   /*
130    * initialize terminal modes
131    */
132   rc = tcgetattr(e->fd, &termios);
133   if (rc < 0) {
134     err = errno;
135     msgout("tcgetattr() failed, %s",
136            strerror(err));
137     return -err;
138   }
139 
140   termios.c_iflag = 0;
141   termios.c_oflag = 0;
142   termios.c_cflag &= ~ (PARENB | CSIZE | CSTOPB);
143   termios.c_cflag |=   (CS8 | HUPCL | CREAD | CLOCAL);
144   termios.c_lflag = 0;
145 
146   termios.c_cc[VEOF] = _POSIX_VDISABLE;
147 #if 1
148   termios.c_cc[VEOL] = _POSIX_VDISABLE;
149 #endif
150   termios.c_cc[VEOL2] = _POSIX_VDISABLE;
151   termios.c_cc[VERASE] = _POSIX_VDISABLE;
152   termios.c_cc[VWERASE] = _POSIX_VDISABLE;
153   termios.c_cc[VKILL] = _POSIX_VDISABLE;
154   termios.c_cc[VREPRINT] = _POSIX_VDISABLE;
155   termios.c_cc[VINTR] = _POSIX_VDISABLE;
156   termios.c_cc[VQUIT] = _POSIX_VDISABLE;
157   termios.c_cc[VSUSP] = _POSIX_VDISABLE;
158   termios.c_cc[VDSUSP] = _POSIX_VDISABLE;
159   termios.c_cc[VSTART] = _POSIX_VDISABLE;
160   termios.c_cc[VSTOP] = _POSIX_VDISABLE;
161   termios.c_cc[VLNEXT] = _POSIX_VDISABLE;
162   termios.c_cc[VDISCARD] = _POSIX_VDISABLE;
163   termios.c_cc[VMIN] = _POSIX_VDISABLE;
164   termios.c_cc[VTIME] = _POSIX_VDISABLE;
165   termios.c_cc[VSTATUS] = _POSIX_VDISABLE;
166 #if 0
167   termios.c_cc[VMIN]  = 1;
168   termios.c_cc[VTIME] = 0;
169 #endif
170 
171   rc = tcsetattr(e->fd, TCSANOW, &termios);
172   if (rc < 0) {
173     err = errno;
174     msgout("tcsetattr() failed, %s",
175            strerror(err) );
176     return -err;
177   }
178 
179   return 0;
180 }
181 
182 
cleanup(ENDPOINT * r,fd_set * masterrd,fd_set * masterwr,int * maxfd)183 void cleanup(ENDPOINT * r, fd_set * masterrd, fd_set * masterwr,
184              int * maxfd)
185 {
186   if (r == NULL)
187     return;
188 
189   if (r->fd > 0) {
190     close (r->fd);
191     if (r->fd == config_fd)
192       config_fd = -1;
193     FD_CLR(r->fd,masterrd);
194     FD_CLR(r->fd,masterwr);
195     if (r->fd == *maxfd) {
196       *maxfd = *maxfd - 1;
197     }
198   }
199 
200   if (r->command != NULL) {
201     if (r->command->buf != NULL) {
202       free(r->command->buf);
203     }
204     free(r->command);
205     r->command = NULL;
206   }
207 
208   if (r->comserv != NULL) {
209     if (r == r->comserv->le) {
210       unlink(r->comserv->localpath);
211       r->comserv->le = NULL;
212     }
213     else if (r == r->comserv->re) {
214       r->comserv->re = NULL;
215     }
216   }
217 
218   bzero(r,sizeof(*r));
219 
220   r->fd     = -1;
221   r->state  = ST_START;
222   r->bufcnt = 0;
223   r->bufptr = r->buf;
224 }
225 
226 
227 
set_blocking(ENDPOINT * e,int blocking,int doretry)228 int set_blocking(ENDPOINT * e, int blocking, int doretry)
229 {
230   int rc;
231   int flags;
232 
233   rc = fcntl(e->fd, F_GETFL);
234   if (rc == -1) {
235     msgout("WARNING: can't get fd %d flags: %s\n", e->fd, strerror(errno));
236     return -1;
237   }
238 
239   flags = rc;
240 
241   if (blocking)
242     flags &= ~O_NONBLOCK;
243   else
244     flags |= O_NONBLOCK;
245 
246   rc = fcntl(e->fd, F_SETFL, flags);
247   if (rc)
248     return -1;
249   else
250     return 0;
251 
252   return 0;
253 }
254 
255 
whichside(int state)256 char * whichside(int state)
257 {
258   switch (state) {
259     case ST_LOCAL    : return "local"; break;
260     case ST_CMDINPUT : return "local"; break;
261     case ST_REMOTE   : return "remote"; break;
262     default          : return "unknown"; break;
263   }
264 }
265 
266 
267 
set_command(ENDPOINT * e)268 int set_command(ENDPOINT * e)
269 {
270   char * bp;
271 
272   bp = (char *) malloc(MAX_RBUF);
273   if (bp == NULL) {
274     msgout("out of memory allocating local mode command buffer\n");
275     return -1;
276   }
277 
278   e->command = new_cmd();
279   e->command->buf = bp;
280   snprintf(e->command->prompt, MAX_PROMPT, "%s> ", progname);
281   e->command->echo = 0;
282   e->command->lastc[1] = '\r';
283   e->command->lastc[0] = '\n';
284 
285   return 0;
286 }
287 
288 
289 
290