This is broadcast.c in view mode; [Download] [Up]
/*********************************************************** Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ /* Broadcast audio packets over UPD. Standard input should be an audio source, e.g., /dev/audio, or -- at CWI -- a pipeline like "rsh voorn ~guido/tmp/ship2sun". Command line options: -b ipaddr IP address to broadcast to; may be repeated (default broadcast on local net) -p port broadcast to this port number (default 54321) -c port listen to this control port (default 54319) -t time output; use when input is faster than realtime (e.g., read from a file file) */ #ifdef sun #define SUNHACKS /* define this for SunOS */ #endif #define BCASTCTLPORT 54319 #define RADIOCTLPORT 54320 #define RCVPORT 54321 #define SENDPORT 54318 #define BUFFERSIZE 1400 #define CTLPKTSIZE 100 #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <sys/time.h> #ifdef SUNHACKS #include <sys/sockio.h> /* For SIOCGIF* */ #include <net/if.h> /* For struct if* */ #endif #ifdef REMHDR #include <multimedia/libaudio.h> #include <multimedia/audio_filehdr.h> #endif #ifdef NeXT #include <sound/sound.h> #endif extern int optind; extern char * optarg; char *progname; char infostring[100]; struct timeval zerotime; struct timeval tstart; int pdebug = 0; #define NBCADDR 10 /* Max number of broadcast addresses */ int nbcaddr = 0; /* Number of broadcast address options */ struct sockaddr_in bcaddr[NBCADDR]; /* Broadcast addresses */ #ifdef NeXT char *cuserid( char *sp) { static char buf[10]; char *ssp; if( ( ssp = (char *)getlogin()) == NULL && sp != NULL) { *sp = '\0'; return ssp; /* ?? */ } if( sp == NULL) sp = buf; if( ssp == NULL) *sp = '\0'; else strncpy( sp, ssp, 10); return sp; } #endif main(argc, argv) int argc; char **argv; { int port = RCVPORT; char *broadcastaddr = NULL; char buf[BUFFERSIZE]; int on = 1; int i; int s, ctls; int c; int timing = 0; fd_set inputav; struct sockaddr_in locsin; struct sockaddr_in ctlsin; int ctlsinsize; int ctlport = BCASTCTLPORT; progname = argv[0]; /* Always change these two macros together! */ #define OPTIONS "b:p:c:dt" #define USAGE "usage: %s [-d] [-t] [-p port] [-c ctlport] [-b broadcastaddr] ...\n" while ((c = getopt(argc, argv, OPTIONS)) != EOF) { switch (c) { case '?': fprintf(stderr, USAGE, progname); exit(2); case 'b': if (nbcaddr >= NBCADDR) { fprintf(stderr, "%s: too many -b options (max %d)\n", progname, NBCADDR); exit(2); } if (setipaddr(optarg, &bcaddr[nbcaddr]) < 0) { fprintf(stderr, "%s: bad broadcast address '%s'\n", progname, broadcastaddr); exit(2); } nbcaddr++; break; case 'p': port = atoi(optarg); break; case 't': timing = 1; break; case 'd': pdebug = 1; break; case 'c': ctlport = atoi(optarg); break; } } s = opensock("data", (char *)NULL, SENDPORT, (char *)NULL, 0, 1); if (nbcaddr == 0) { configure(s, &bcaddr[0]); nbcaddr = 1; } for (i = 0; i < nbcaddr; i++) { bcaddr[i].sin_port = htons(port); bcaddr[i].sin_family = AF_INET; } sprintf(infostring, "radio:S:%s:%d", cuserid(0), port); ctls = opensock("control", (char *)NULL, ctlport, (char *)NULL, 0, 0); if(timing) { #ifdef REMHDR Audio_hdr hp; (void) audio_read_filehdr(0, &hp, NULL, NULL); #endif #ifdef NeXT SNDSoundStruct s; (void) fread((void *)&s, sizeof(SNDSoundStruct), 1, stdin); #endif gettimeofday(&tstart, 0); } for (;;) { int n = fread(buf, 1, BUFFERSIZE, stdin); if (n <= 0) { if (n < 0) perror("fread"); break; } for (i = 0; i < nbcaddr; i++) { if(timing) { waiting(8000, BUFFERSIZE); } if (sendto(s, buf, n, 0, &bcaddr[i], sizeof bcaddr[i]) != n) { perror("sendto"); break; } } if (pdebug) { if(pdebug == 8) { fprintf(stderr,"8 packets sent\n"); pdebug = 1; } else pdebug++; } if (ctls >= 0) { FD_ZERO(&inputav); FD_SET(ctls, &inputav); if (select(ctls+1, &inputav, 0, 0, &zerotime) == 1) { ctlsinsize = sizeof(ctlsin); n = recvfrom(ctls, buf, BUFFERSIZE, 0, &ctlsin, &ctlsinsize); if (n < 0) { perror("recvfrom"); exit(1); } if (n >= 7 && strncmp(buf, "radio:s", 7) == 0) { sendto(ctls, infostring, strlen(infostring), 0, &ctlsin, ctlsinsize); } else { fprintf(stderr, "%s: Funny ctl message\n", progname); } } } } exit(0); } configure(s, addr_ret) int s; struct sockaddr_in *addr_ret; { #ifdef SUNHACKS char buf[BUFSIZ]; struct ifconf ifc; struct ifreq ifreq; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { perror("ioctl SIOCGIFCONF"); exit(1); } ifreq = *ifc.ifc_req; if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { perror("ioctl SIOCGIFBRDADDR"); exit(1); } * (struct sockaddr *) addr_ret = ifreq.ifr_broadaddr; #else addr_ret->sin_addr.s_addr = INADDR_BROADCAST; #endif } /* * routine to sleep between consecutive packets */ waiting(rate, data) int rate; int data; { static int bytes = 0; /* packets already sent */ struct timeval tnow; int tsleep; bytes += data; gettimeofday(&tnow, 0); tsleep = ((double) bytes/(double) rate) * 1000000 - ((tnow.tv_sec - tstart.tv_sec) * 1000000 + tnow.tv_usec - tstart.tv_usec); if (tsleep > 0) { struct timeval t; t.tv_sec = tsleep / 1000000; t.tv_usec = tsleep % 1000000; (void) select(0, NULL, NULL, NULL, &t); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.