summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/u_pdreceive.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/u_pdreceive.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/u_pdreceive.c326
1 files changed, 0 insertions, 326 deletions
diff --git a/apps/plugins/pdbox/PDa/src/u_pdreceive.c b/apps/plugins/pdbox/PDa/src/u_pdreceive.c
deleted file mode 100644
index 51e60f7d5f..0000000000
--- a/apps/plugins/pdbox/PDa/src/u_pdreceive.c
+++ /dev/null
@@ -1,326 +0,0 @@
1/* Copyright (c) 2000 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */
4
5/* the "pdreceive" command. This is a standalone program that receives messages
6from Pd via the netsend/netreceive ("FUDI") protocol, and copies them to
7standard output. */
8
9#include <sys/types.h>
10#include <string.h>
11#include <stdio.h>
12#include <errno.h>
13#include <stdlib.h>
14#ifdef UNIX
15#include <sys/time.h>
16#include <unistd.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <netdb.h>
20#define SOCKET_ERROR -1
21#else
22#include <winsock.h>
23#endif
24
25typedef struct _fdpoll
26{
27 int fdp_fd;
28 char *fdp_inbuf;
29 int fdp_inhead;
30 int fdp_intail;
31 int fdp_udp;
32} t_fdpoll;
33
34static int nfdpoll;
35static t_fdpoll *fdpoll;
36static int maxfd;
37static int sockfd;
38static int protocol;
39
40static void sockerror(char *s);
41static void x_closesocket(int fd);
42static void dopoll(void);
43#define BUFSIZE 4096
44
45int main(int argc, char **argv)
46{
47 int portno;
48 struct sockaddr_in server;
49 int nretry = 10;
50#ifdef MSW
51 short version = MAKEWORD(2, 0);
52 WSADATA nobby;
53#endif
54 if (argc < 2 || sscanf(argv[1], "%d", &portno) < 1 || portno <= 0)
55 goto usage;
56 if (argc >= 3)
57 {
58 if (!strcmp(argv[2], "tcp"))
59 protocol = SOCK_STREAM;
60 else if (!strcmp(argv[2], "udp"))
61 protocol = SOCK_DGRAM;
62 else goto usage;
63 }
64 else protocol = SOCK_STREAM;
65#ifdef MSW
66 if (WSAStartup(version, &nobby)) sockerror("WSAstartup");
67#endif
68 sockfd = socket(AF_INET, protocol, 0);
69 if (sockfd < 0)
70 {
71 sockerror("socket()");
72 exit(1);
73 }
74 maxfd = sockfd + 1;
75 server.sin_family = AF_INET;
76 server.sin_addr.s_addr = INADDR_ANY;
77
78#ifdef IRIX
79 /* this seems to work only in IRIX but is unnecessary in
80 Linux. Not sure what MSW needs in place of this. */
81 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
82 post("setsockopt failed\n");
83#endif
84
85 /* assign client port number */
86 server.sin_port = htons((unsigned short)portno);
87
88 /* name the socket */
89 if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
90 {
91 sockerror("bind");
92 x_closesocket(sockfd);
93 return (0);
94 }
95 if (protocol == SOCK_STREAM)
96 {
97 if (listen(sockfd, 5) < 0)
98 {
99 sockerror("listen");
100 x_closesocket(sockfd);
101 exit(1);
102 }
103 }
104 /* now loop forever selecting on sockets */
105 while (1)
106 dopoll();
107
108usage:
109 fprintf(stderr, "usage: pdreceive <portnumber> [udp|tcp]\n");
110 fprintf(stderr, "(default is tcp)\n");
111 exit(1);
112}
113
114static void addport(int fd)
115{
116 int nfd = nfdpoll;
117 t_fdpoll *fp;
118 fdpoll = (t_fdpoll *)realloc(fdpoll,
119 (nfdpoll+1) * sizeof(t_fdpoll));
120 fp = fdpoll + nfdpoll;
121 fp->fdp_fd = fd;
122 nfdpoll++;
123 if (fd >= maxfd) maxfd = fd + 1;
124 fp->fdp_inhead = fp->fdp_intail = 0;
125 if (!(fp->fdp_inbuf = malloc(BUFSIZE)))
126 {
127 fprintf(stderr, "out of memory");
128 exit(1);
129 }
130 printf("number_connected %d;\n", nfdpoll);
131}
132
133static void rmport(t_fdpoll *x)
134{
135 int nfd = nfdpoll;
136 int i, size = nfdpoll * sizeof(t_fdpoll);
137 t_fdpoll *fp;
138 for (i = nfdpoll, fp = fdpoll; i--; fp++)
139 {
140 if (fp == x)
141 {
142 x_closesocket(fp->fdp_fd);
143 free(fp->fdp_inbuf);
144 while (i--)
145 {
146 fp[0] = fp[1];
147 fp++;
148 }
149 fdpoll = (t_fdpoll *)realloc(fdpoll,
150 (nfdpoll-1) * sizeof(t_fdpoll));
151 nfdpoll--;
152 printf("number_connected %d;\n", nfdpoll);
153 return;
154 }
155 }
156 fprintf(stderr, "warning: item removed from poll list but not found");
157}
158
159static void doconnect(void)
160{
161 int fd = accept(sockfd, 0, 0);
162 if (fd < 0)
163 perror("accept");
164 else addport(fd);
165}
166
167static void udpread(void)
168{
169 char buf[BUFSIZE];
170 int ret = recv(sockfd, buf, BUFSIZE, 0);
171 if (ret < 0)
172 {
173 sockerror("recv (udp)");
174 x_closesocket(sockfd);
175 exit(1);
176 }
177 else if (ret > 0)
178 {
179#ifdef UNIX
180 if (write(1, buf, ret) < ret)
181 {
182 perror("write");
183 exit(1);
184 }
185#else
186 int j;
187 for (j = 0; j < ret; j++)
188 putchar(buf[j]);
189#endif
190 }
191}
192
193static int tcpmakeoutput(t_fdpoll *x)
194{
195 char messbuf[BUFSIZE+1], *bp = messbuf;
196 int indx;
197 int inhead = x->fdp_inhead;
198 int intail = x->fdp_intail;
199 char *inbuf = x->fdp_inbuf;
200 if (intail == inhead)
201 return (0);
202 for (indx = intail; indx != inhead; indx = (indx+1)&(BUFSIZE-1))
203 {
204 /* search for a semicolon. */
205 char c = *bp++ = inbuf[indx];
206 if (c == ';')
207 {
208 intail = (indx+1)&(BUFSIZE-1);
209 if (inbuf[intail] == '\n')
210 intail = (intail+1)&(BUFSIZE-1);
211 *bp++ = '\n';
212#ifdef UNIX
213 write(1, messbuf, bp - messbuf);
214#else
215 {
216 int j;
217 for (j = 0; j < bp - messbuf; j++)
218 putchar(messbuf[j]);
219 }
220#endif
221 x->fdp_inhead = inhead;
222 x->fdp_intail = intail;
223 return (1);
224 }
225 }
226 return (0);
227}
228
229static void tcpread(t_fdpoll *x)
230{
231 int readto =
232 (x->fdp_inhead >= x->fdp_intail ? BUFSIZE : x->fdp_intail-1);
233 int ret;
234
235 /* the input buffer might be full. If so, drop the whole thing */
236 if (readto == x->fdp_inhead)
237 {
238 fprintf(stderr, "pd: dropped message from gui\n");
239 x->fdp_inhead = x->fdp_intail = 0;
240 readto = BUFSIZE;
241 }
242 else
243 {
244 ret = recv(x->fdp_fd, x->fdp_inbuf + x->fdp_inhead,
245 readto - x->fdp_inhead, 0);
246 if (ret < 0)
247 {
248 sockerror("recv (tcp)");
249 rmport(x);
250 }
251 else if (ret == 0)
252 rmport(x);
253 else
254 {
255 x->fdp_inhead += ret;
256 if (x->fdp_inhead >= BUFSIZE)
257 x->fdp_inhead = 0;
258 while (tcpmakeoutput(x))
259 ;
260 }
261 }
262}
263
264static void dopoll(void)
265{
266 int i;
267 t_fdpoll *fp;
268 fd_set readset, writeset, exceptset;
269 FD_ZERO(&writeset);
270 FD_ZERO(&readset);
271 FD_ZERO(&exceptset);
272
273 FD_SET(sockfd, &readset);
274 if (protocol == SOCK_STREAM)
275 {
276 for (fp = fdpoll, i = nfdpoll; i--; fp++)
277 FD_SET(fp->fdp_fd, &readset);
278 }
279 if (select(maxfd+1, &readset, &writeset, &exceptset, 0) < 0)
280 {
281 perror("select");
282 exit(1);
283 }
284 if (protocol == SOCK_STREAM)
285 {
286 for (i = 0; i < nfdpoll; i++)
287 if (FD_ISSET(fdpoll[i].fdp_fd, &readset))
288 tcpread(&fdpoll[i]);
289 if (FD_ISSET(sockfd, &readset))
290 doconnect();
291 }
292 else
293 {
294 if (FD_ISSET(sockfd, &readset))
295 udpread();
296 }
297}
298
299
300static void sockerror(char *s)
301{
302#ifdef MSW
303 int err = WSAGetLastError();
304 if (err == 10054) return;
305 else if (err == 10044)
306 {
307 fprintf(stderr,
308 "Warning: you might not have TCP/IP \"networking\" turned on\n");
309 }
310#endif
311#ifdef UNIX
312 int err = errno;
313#endif
314 fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err);
315}
316
317static void x_closesocket(int fd)
318{
319#ifdef UNIX
320 close(fd);
321#endif
322#ifdef MSW
323 closesocket(fd);
324#endif
325}
326