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