Remove building with NOCRYPTO option
[minix.git] / external / bsd / nvi / dist / ipc / ip_trans.c
blobaecdfa1aecdad8f72189636e7b2e764f5ce24e4e
1 /* $NetBSD: ip_trans.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
2 /*-
3 * Copyright (c) 1996
4 * Keith Bostic. All rights reserved.
6 * See the LICENSE file for redistribution information.
7 */
9 #include "config.h"
11 #include <sys/cdefs.h>
12 #if 0
13 #ifndef lint
14 static const char sccsid[] = "Id: ip_trans.c,v 8.18 2001/06/25 15:19:25 skimo Exp (Berkeley) Date: 2001/06/25 15:19:25 ";
15 #endif /* not lint */
16 #else
17 __RCSID("$NetBSD: ip_trans.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
18 #endif
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #ifdef HAVE_SYS_SELECT_H
23 #include <sys/select.h>
24 #endif
26 #include <bitstring.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <netinet/in.h>
32 #ifdef __STDC__
33 #include <stdarg.h>
34 #else
35 #include <varargs.h>
36 #endif
38 #include "../common/common.h"
39 #include "ip.h"
40 #include "ipc_def.h"
42 static char ibuf[2048]; /* Input buffer. */
43 static size_t ibuf_len; /* Length of current input. */
45 extern IPFUNLIST const ipfuns[];
48 * vi_input --
49 * Read from the vi message queue.
51 * PUBLIC: int vi_input __P((IPVIWIN *, int));
53 int
54 vi_input(IPVIWIN *ipviwin, int fd)
56 ssize_t nr;
58 /* Read waiting vi messages and translate to X calls. */
59 switch (nr = read(fd, ibuf + ibuf_len, sizeof(ibuf) - ibuf_len)) {
60 case 0:
61 return (0);
62 case -1:
63 return (-1);
64 default:
65 break;
67 ibuf_len += nr;
69 /* Parse to data end or partial message. */
70 (void)vi_translate(ipviwin, ibuf, &ibuf_len, NULL);
72 return (ibuf_len > 0);
76 * vi_wsend --
77 * Construct and send an IP buffer, and wait for an answer.
79 * PUBLIC: int vi_wsend __P((IPVIWIN*, char *, IP_BUF *));
81 int
82 vi_wsend(IPVIWIN *ipviwin, char *fmt, IP_BUF *ipbp)
84 fd_set rdfd;
85 ssize_t nr;
87 if (vi_send(ipviwin->ofd, fmt, ipbp))
88 return (1);
90 FD_ZERO(&rdfd);
91 ipbp->code = CODE_OOB;
93 for (;;) {
94 FD_SET(ipviwin->ifd, &rdfd);
95 if (select(ipviwin->ifd + 1, &rdfd, NULL, NULL, NULL) != 0)
96 return (-1);
98 /* Read waiting vi messages and translate to X calls. */
99 switch (nr =
100 read(ipviwin->ifd, ibuf + ibuf_len, sizeof(ibuf) - ibuf_len)) {
101 case 0:
102 return (0);
103 case -1:
104 return (-1);
105 default:
106 break;
108 ibuf_len += nr;
110 /* Parse to data end or partial message. */
111 (void)vi_translate(ipviwin, ibuf, &ibuf_len, ipbp);
113 if (ipbp->code != CODE_OOB)
114 break;
116 return (0);
120 * vi_translate --
121 * Translate vi messages into function calls.
123 * PUBLIC: int vi_translate __P((IPVIWIN *, char *, size_t *, IP_BUF *));
126 vi_translate(IPVIWIN *ipviwin, char *bp, size_t *lenp, IP_BUF *ipbp)
128 IP_BUF ipb;
129 size_t len, needlen;
130 u_int32_t *vp;
131 const char *fmt;
132 char *p, *s_bp;
133 const char **vsp;
134 IPFunc fun;
136 memset(&ipb, 0, sizeof(ipb));
137 for (s_bp = bp, len = *lenp; len > 0;) {
138 fmt = ipfuns[(ipb.code = bp[0])-1].format;
140 p = bp + IPO_CODE_LEN;
141 needlen = IPO_CODE_LEN;
142 for (; *fmt != '\0'; ++fmt)
143 switch (*fmt) {
144 case '1': /* Value #1. */
145 vp = &ipb.val1;
146 goto value;
147 case '2': /* Value #2. */
148 vp = &ipb.val2;
149 goto value;
150 case '3': /* Value #3. */
151 vp = &ipb.val3;
152 value: needlen += IPO_INT_LEN;
153 if (len < needlen)
154 goto partial;
155 memcpy(vp, p, IPO_INT_LEN);
156 *vp = ntohl(*vp);
157 p += IPO_INT_LEN;
158 break;
159 case 'a': /* String #1. */
160 vp = &ipb.len1;
161 vsp = &ipb.str1;
162 goto string;
163 case 'b': /* String #2. */
164 vp = &ipb.len2;
165 vsp = &ipb.str2;
166 string: needlen += IPO_INT_LEN;
167 if (len < needlen)
168 goto partial;
169 memcpy(vp, p, IPO_INT_LEN);
170 *vp = ntohl(*vp);
171 p += IPO_INT_LEN;
172 needlen += *vp;
173 if (len < needlen)
174 goto partial;
175 *vsp = p;
176 p += *vp;
177 break;
179 bp += needlen;
180 len -= needlen;
183 * XXX
184 * Protocol error!?!?
186 if (ipb.code >= SI_EVENT_SUP) {
187 len = 0;
188 break;
192 * If we're waiting for a reply and we got it, return it, and
193 * leave any unprocessed data in the buffer. If we got a reply
194 * and we're not waiting for one, discard it -- callers wait
195 * for responses.
197 if (ipb.code == SI_REPLY) {
198 if (ipbp == NULL)
199 continue;
200 *ipbp = ipb;
201 break;
204 /* Call the underlying routine. */
205 fun = *(IPFunc *)
206 (((char *)ipviwin->si_ops)+ipfuns[ipb.code - 1].offset);
207 if (fun != NULL &&
208 ipfuns[ipb.code - 1].unmarshall(ipviwin, &ipb, fun))
209 break;
211 partial:
212 if ((*lenp = len) != 0)
213 memmove(s_bp, bp, len);
214 return (0);