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.c324
1 files changed, 0 insertions, 324 deletions
diff --git a/apps/plugins/pdbox/PDa/src/u_pdreceive.c b/apps/plugins/pdbox/PDa/src/u_pdreceive.c
index 3ec097edcc..51e60f7d5f 100644
--- a/apps/plugins/pdbox/PDa/src/u_pdreceive.c
+++ b/apps/plugins/pdbox/PDa/src/u_pdreceive.c
@@ -323,328 +323,4 @@ static void x_closesocket(int fd)
323 closesocket(fd); 323 closesocket(fd);
324#endif 324#endif
325} 325}
326/* Copyright (c) 2000 Miller Puckette.
327* For information on usage and redistribution, and for a DISCLAIMER OF ALL
328* WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */
329
330/* the "pdreceive" command. This is a standalone program that receives messages
331from Pd via the netsend/netreceive ("FUDI") protocol, and copies them to
332standard output. */
333
334#include <sys/types.h>
335#include <string.h>
336#include <stdio.h>
337#include <errno.h>
338#include <stdlib.h>
339#ifdef UNIX
340#include <sys/time.h>
341#include <unistd.h>
342#include <sys/socket.h>
343#include <netinet/in.h>
344#include <netdb.h>
345#define SOCKET_ERROR -1
346#else
347#include <winsock.h>
348#endif
349
350typedef struct _fdpoll
351{
352 int fdp_fd;
353 char *fdp_inbuf;
354 int fdp_inhead;
355 int fdp_intail;
356 int fdp_udp;
357} t_fdpoll;
358
359static int nfdpoll;
360static t_fdpoll *fdpoll;
361static int maxfd;
362static int sockfd;
363static int protocol;
364
365static void sockerror(char *s);
366static void x_closesocket(int fd);
367static void dopoll(void);
368#define BUFSIZE 4096
369
370int main(int argc, char **argv)
371{
372 int portno;
373 struct sockaddr_in server;
374 int nretry = 10;
375#ifdef MSW
376 short version = MAKEWORD(2, 0);
377 WSADATA nobby;
378#endif
379 if (argc < 2 || sscanf(argv[1], "%d", &portno) < 1 || portno <= 0)
380 goto usage;
381 if (argc >= 3)
382 {
383 if (!strcmp(argv[2], "tcp"))
384 protocol = SOCK_STREAM;
385 else if (!strcmp(argv[2], "udp"))
386 protocol = SOCK_DGRAM;
387 else goto usage;
388 }
389 else protocol = SOCK_STREAM;
390#ifdef MSW
391 if (WSAStartup(version, &nobby)) sockerror("WSAstartup");
392#endif
393 sockfd = socket(AF_INET, protocol, 0);
394 if (sockfd < 0)
395 {
396 sockerror("socket()");
397 exit(1);
398 }
399 maxfd = sockfd + 1;
400 server.sin_family = AF_INET;
401 server.sin_addr.s_addr = INADDR_ANY;
402
403#ifdef IRIX
404 /* this seems to work only in IRIX but is unnecessary in
405 Linux. Not sure what MSW needs in place of this. */
406 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
407 post("setsockopt failed\n");
408#endif
409
410 /* assign client port number */
411 server.sin_port = htons((unsigned short)portno);
412
413 /* name the socket */
414 if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
415 {
416 sockerror("bind");
417 x_closesocket(sockfd);
418 return (0);
419 }
420 if (protocol == SOCK_STREAM)
421 {
422 if (listen(sockfd, 5) < 0)
423 {
424 sockerror("listen");
425 x_closesocket(sockfd);
426 exit(1);
427 }
428 }
429 /* now loop forever selecting on sockets */
430 while (1)
431 dopoll();
432
433usage:
434 fprintf(stderr, "usage: pdreceive <portnumber> [udp|tcp]\n");
435 fprintf(stderr, "(default is tcp)\n");
436 exit(1);
437}
438
439static void addport(int fd)
440{
441 int nfd = nfdpoll;
442 t_fdpoll *fp;
443 fdpoll = (t_fdpoll *)realloc(fdpoll,
444 (nfdpoll+1) * sizeof(t_fdpoll));
445 fp = fdpoll + nfdpoll;
446 fp->fdp_fd = fd;
447 nfdpoll++;
448 if (fd >= maxfd) maxfd = fd + 1;
449 fp->fdp_inhead = fp->fdp_intail = 0;
450 if (!(fp->fdp_inbuf = malloc(BUFSIZE)))
451 {
452 fprintf(stderr, "out of memory");
453 exit(1);
454 }
455 printf("number_connected %d;\n", nfdpoll);
456}
457
458static void rmport(t_fdpoll *x)
459{
460 int nfd = nfdpoll;
461 int i, size = nfdpoll * sizeof(t_fdpoll);
462 t_fdpoll *fp;
463 for (i = nfdpoll, fp = fdpoll; i--; fp++)
464 {
465 if (fp == x)
466 {
467 x_closesocket(fp->fdp_fd);
468 free(fp->fdp_inbuf);
469 while (i--)
470 {
471 fp[0] = fp[1];
472 fp++;
473 }
474 fdpoll = (t_fdpoll *)realloc(fdpoll,
475 (nfdpoll-1) * sizeof(t_fdpoll));
476 nfdpoll--;
477 printf("number_connected %d;\n", nfdpoll);
478 return;
479 }
480 }
481 fprintf(stderr, "warning: item removed from poll list but not found");
482}
483
484static void doconnect(void)
485{
486 int fd = accept(sockfd, 0, 0);
487 if (fd < 0)
488 perror("accept");
489 else addport(fd);
490}
491
492static void udpread(void)
493{
494 char buf[BUFSIZE];
495 int ret = recv(sockfd, buf, BUFSIZE, 0);
496 if (ret < 0)
497 {
498 sockerror("recv (udp)");
499 x_closesocket(sockfd);
500 exit(1);
501 }
502 else if (ret > 0)
503 {
504#ifdef UNIX
505 if (write(1, buf, ret) < ret)
506 {
507 perror("write");
508 exit(1);
509 }
510#else
511 int j;
512 for (j = 0; j < ret; j++)
513 putchar(buf[j]);
514#endif
515 }
516}
517
518static int tcpmakeoutput(t_fdpoll *x)
519{
520 char messbuf[BUFSIZE+1], *bp = messbuf;
521 int indx;
522 int inhead = x->fdp_inhead;
523 int intail = x->fdp_intail;
524 char *inbuf = x->fdp_inbuf;
525 if (intail == inhead)
526 return (0);
527 for (indx = intail; indx != inhead; indx = (indx+1)&(BUFSIZE-1))
528 {
529 /* search for a semicolon. */
530 char c = *bp++ = inbuf[indx];
531 if (c == ';')
532 {
533 intail = (indx+1)&(BUFSIZE-1);
534 if (inbuf[intail] == '\n')
535 intail = (intail+1)&(BUFSIZE-1);
536 *bp++ = '\n';
537#ifdef UNIX
538 write(1, messbuf, bp - messbuf);
539#else
540 {
541 int j;
542 for (j = 0; j < bp - messbuf; j++)
543 putchar(messbuf[j]);
544 }
545#endif
546 x->fdp_inhead = inhead;
547 x->fdp_intail = intail;
548 return (1);
549 }
550 }
551 return (0);
552}
553
554static void tcpread(t_fdpoll *x)
555{
556 int readto =
557 (x->fdp_inhead >= x->fdp_intail ? BUFSIZE : x->fdp_intail-1);
558 int ret;
559
560 /* the input buffer might be full. If so, drop the whole thing */
561 if (readto == x->fdp_inhead)
562 {
563 fprintf(stderr, "pd: dropped message from gui\n");
564 x->fdp_inhead = x->fdp_intail = 0;
565 readto = BUFSIZE;
566 }
567 else
568 {
569 ret = recv(x->fdp_fd, x->fdp_inbuf + x->fdp_inhead,
570 readto - x->fdp_inhead, 0);
571 if (ret < 0)
572 {
573 sockerror("recv (tcp)");
574 rmport(x);
575 }
576 else if (ret == 0)
577 rmport(x);
578 else
579 {
580 x->fdp_inhead += ret;
581 if (x->fdp_inhead >= BUFSIZE)
582 x->fdp_inhead = 0;
583 while (tcpmakeoutput(x))
584 ;
585 }
586 }
587}
588 326
589static void dopoll(void)
590{
591 int i;
592 t_fdpoll *fp;
593 fd_set readset, writeset, exceptset;
594 FD_ZERO(&writeset);
595 FD_ZERO(&readset);
596 FD_ZERO(&exceptset);
597
598 FD_SET(sockfd, &readset);
599 if (protocol == SOCK_STREAM)
600 {
601 for (fp = fdpoll, i = nfdpoll; i--; fp++)
602 FD_SET(fp->fdp_fd, &readset);
603 }
604 if (select(maxfd+1, &readset, &writeset, &exceptset, 0) < 0)
605 {
606 perror("select");
607 exit(1);
608 }
609 if (protocol == SOCK_STREAM)
610 {
611 for (i = 0; i < nfdpoll; i++)
612 if (FD_ISSET(fdpoll[i].fdp_fd, &readset))
613 tcpread(&fdpoll[i]);
614 if (FD_ISSET(sockfd, &readset))
615 doconnect();
616 }
617 else
618 {
619 if (FD_ISSET(sockfd, &readset))
620 udpread();
621 }
622}
623
624
625static void sockerror(char *s)
626{
627#ifdef MSW
628 int err = WSAGetLastError();
629 if (err == 10054) return;
630 else if (err == 10044)
631 {
632 fprintf(stderr,
633 "Warning: you might not have TCP/IP \"networking\" turned on\n");
634 }
635#endif
636#ifdef UNIX
637 int err = errno;
638#endif
639 fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err);
640}
641
642static void x_closesocket(int fd)
643{
644#ifdef UNIX
645 close(fd);
646#endif
647#ifdef MSW
648 closesocket(fd);
649#endif
650}