tools/llvm: Do not build with symbols
[minix3.git] / external / bsd / nvi / dist / ipc / ip_trans.c
blob2da831325e8a2d788a544d39592b921af0b7ff57
1 /* $NetBSD: ip_trans.c,v 1.3 2013/11/27 17:53:00 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 #ifndef lint
12 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 ";
13 #endif /* not lint */
15 #include <sys/types.h>
16 #include <sys/queue.h>
17 #ifdef HAVE_SYS_SELECT_H
18 #include <sys/select.h>
19 #endif
21 #include <bitstring.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <netinet/in.h>
27 #ifdef __STDC__
28 #include <stdarg.h>
29 #else
30 #include <varargs.h>
31 #endif
33 #include "../common/common.h"
34 #include "ip.h"
35 #include "ipc_def.h"
37 static char ibuf[2048]; /* Input buffer. */
38 static size_t ibuf_len; /* Length of current input. */
40 extern IPFUNLIST const ipfuns[];
43 * vi_input --
44 * Read from the vi message queue.
46 * PUBLIC: int vi_input __P((IPVIWIN *, int));
48 int
49 vi_input(IPVIWIN *ipviwin, int fd)
51 ssize_t nr;
53 /* Read waiting vi messages and translate to X calls. */
54 switch (nr = read(fd, ibuf + ibuf_len, sizeof(ibuf) - ibuf_len)) {
55 case 0:
56 return (0);
57 case -1:
58 return (-1);
59 default:
60 break;
62 ibuf_len += nr;
64 /* Parse to data end or partial message. */
65 (void)vi_translate(ipviwin, ibuf, &ibuf_len, NULL);
67 return (ibuf_len > 0);
71 * vi_wsend --
72 * Construct and send an IP buffer, and wait for an answer.
74 * PUBLIC: int vi_wsend __P((IPVIWIN*, char *, IP_BUF *));
76 int
77 vi_wsend(IPVIWIN *ipviwin, char *fmt, IP_BUF *ipbp)
79 fd_set rdfd;
80 ssize_t nr;
82 if (vi_send(ipviwin->ofd, fmt, ipbp))
83 return (1);
85 FD_ZERO(&rdfd);
86 ipbp->code = CODE_OOB;
88 for (;;) {
89 FD_SET(ipviwin->ifd, &rdfd);
90 if (select(ipviwin->ifd + 1, &rdfd, NULL, NULL, NULL) != 0)
91 return (-1);
93 /* Read waiting vi messages and translate to X calls. */
94 switch (nr =
95 read(ipviwin->ifd, ibuf + ibuf_len, sizeof(ibuf) - ibuf_len)) {
96 case 0:
97 return (0);
98 case -1:
99 return (-1);
100 default:
101 break;
103 ibuf_len += nr;
105 /* Parse to data end or partial message. */
106 (void)vi_translate(ipviwin, ibuf, &ibuf_len, ipbp);
108 if (ipbp->code != CODE_OOB)
109 break;
111 return (0);
115 * vi_translate --
116 * Translate vi messages into function calls.
118 * PUBLIC: int vi_translate __P((IPVIWIN *, char *, size_t *, IP_BUF *));
121 vi_translate(IPVIWIN *ipviwin, char *bp, size_t *lenp, IP_BUF *ipbp)
123 IP_BUF ipb;
124 size_t len, needlen;
125 u_int32_t *vp;
126 const char *fmt;
127 char *p, *s_bp;
128 const char **vsp;
129 IPFunc fun;
131 memset(&ipb, 0, sizeof(ipb));
132 for (s_bp = bp, len = *lenp; len > 0;) {
133 fmt = ipfuns[(ipb.code = bp[0])-1].format;
135 p = bp + IPO_CODE_LEN;
136 needlen = IPO_CODE_LEN;
137 for (; *fmt != '\0'; ++fmt)
138 switch (*fmt) {
139 case '1': /* Value #1. */
140 vp = &ipb.val1;
141 goto value;
142 case '2': /* Value #2. */
143 vp = &ipb.val2;
144 goto value;
145 case '3': /* Value #3. */
146 vp = &ipb.val3;
147 value: needlen += IPO_INT_LEN;
148 if (len < needlen)
149 goto partial;
150 memcpy(vp, p, IPO_INT_LEN);
151 *vp = ntohl(*vp);
152 p += IPO_INT_LEN;
153 break;
154 case 'a': /* String #1. */
155 vp = &ipb.len1;
156 vsp = &ipb.str1;
157 goto string;
158 case 'b': /* String #2. */
159 vp = &ipb.len2;
160 vsp = &ipb.str2;
161 string: needlen += IPO_INT_LEN;
162 if (len < needlen)
163 goto partial;
164 memcpy(vp, p, IPO_INT_LEN);
165 *vp = ntohl(*vp);
166 p += IPO_INT_LEN;
167 needlen += *vp;
168 if (len < needlen)
169 goto partial;
170 *vsp = p;
171 p += *vp;
172 break;
174 bp += needlen;
175 len -= needlen;
178 * XXX
179 * Protocol error!?!?
181 if (ipb.code >= SI_EVENT_SUP) {
182 len = 0;
183 break;
187 * If we're waiting for a reply and we got it, return it, and
188 * leave any unprocessed data in the buffer. If we got a reply
189 * and we're not waiting for one, discard it -- callers wait
190 * for responses.
192 if (ipb.code == SI_REPLY) {
193 if (ipbp == NULL)
194 continue;
195 *ipbp = ipb;
196 break;
199 /* Call the underlying routine. */
200 fun = *(IPFunc *)
201 (((char *)ipviwin->si_ops)+ipfuns[ipb.code - 1].offset);
202 if (fun != NULL &&
203 ipfuns[ipb.code - 1].unmarshall(ipviwin, &ipb, fun))
204 break;
206 partial:
207 if ((*lenp = len) != 0)
208 memmove(s_bp, bp, len);
209 return (0);