home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- Path: sparky!kent
- From: Guido van Rossum <guido@cwi.nl>
- Subject: v32i027: radio2.0 - Broadcast FM/AM over Local Area Network, Patch01
- Message-ID: <1992Sep10.141840.16231@sparky.imd.sterling.com>
- Followup-To: comp.sources.d
- X-Md4-Signature: 96c8204ea252af922347fbab0d001977
- Sender: kent@sparky.imd.sterling.com (Kent Landfield)
- Organization: Sterling Software
- Date: Thu, 10 Sep 1992 14:18:40 GMT
- Approved: kent@sparky.imd.sterling.com
- Lines: 826
-
- Submitted-by: Guido van Rossum <guido@cwi.nl>
- Posting-number: Volume 32, Issue 27
- Archive-name: radio2.0/patch01
- Patch-To: radio2.0: Volume30, Issue 85-86
- Environment: Sun, SGI, NeXT
-
- Here is the first patch to radio 2.0.
-
- The original was posted to alt.sources, and to comp.sources.misc. It
- is also available by anonymous ftp from ftp.cwi.nl [192.16.184.180],
- directory pub, files radio2.0.tar.Z (main distribution) and tuner1.3.shar
- (Motif tuner program).
-
- Changes in 2.0 patchlevel 1
- ---------------------------
-
- - On the sun and sgi, radio tries to open a connection to the X server
- (specified by the $DISPLAY environment variable) and every now and
- then makes a small request to exercise the connection. This ensures
- that if the user logs out, radio will quit. If no connection to the X
- server can be made, these checks are not made and a warning is printed
- that reminds the user to kill radio when logging out.
-
- - The usage message is more informative.
-
- - The new option '-t' (tee) sends output to both stdout and the audio
- device. Thanks to Scott Hazen Mueller for suggesting this.
-
- - The experimental option '-m mcastgrp' (for SGI only) specifies a
- multicast group. By multicasting instead of broadcasting, you can
- reduce the load on hosts that aren't listening (see the man page).
-
- Here are the patches -- happy listening!
-
- diff -rcN ../orig/MANIFEST ./MANIFEST
- *** ../orig/MANIFEST Thu Sep 10 08:55:29 1992
- --- ./MANIFEST Thu Sep 10 08:57:14 1992
- ***************
- *** 16,20 ****
- --- 16,21 ----
- recordulaw.c 1
- sndulaw.c 1
- socklib.c 1
- + stations.pl 0
- stations.py 1
- ttytuner.py 2
- diff -rcN ../orig/Makefile ./Makefile
- *** ../orig/Makefile Thu Sep 10 08:55:30 1992
- --- ./Makefile Thu Sep 10 08:57:14 1992
- ***************
- *** 33,46 ****
- # Platform-specific entries
-
- sun4.0: # For SunOS 4.x
- ! make all
-
- sun4.1: # For SunOS 4.1 with audio library (/usr/demo/SOUND)
- ! make all LIBS=/usr/demo/SOUND/libaudio.a \
- CFLAGS='-DREMHDR -I/usr/demo/SOUND'
-
- sgi: # For SGI IRIX 4.0
- ! make all recordulaw playulaw LIBS=-laudio
-
- next: # NeXT 2.1
- make all sndulaw
- --- 33,46 ----
- # Platform-specific entries
-
- sun4.0: # For SunOS 4.x
- ! make all LIBS=-lX11
-
- sun4.1: # For SunOS 4.1 with audio library (/usr/demo/SOUND)
- ! make all LIBS='-lX11 /usr/demo/SOUND/libaudio.a' \
- CFLAGS='-DREMHDR -I/usr/demo/SOUND'
-
- sgi: # For SGI IRIX 4.0
- ! make all recordulaw playulaw LIBS='-lX11 -laudio'
-
- next: # NeXT 2.1
- make all sndulaw
- diff -rcN ../orig/README ./README
- *** ../orig/README Thu Sep 10 08:55:31 1992
- --- ./README Thu Sep 10 08:57:15 1992
- ***************
- *** 1,7 ****
- Welcome to the wonderful world of Local Area Network radio!
- ===========================================================
-
- ! This is Radio version 2.0, patchlevel 0.
-
- If you have a local area network full of workstations with audio
- capabilities and at least one FM/AM radio or other audio source, you
- --- 1,7 ----
- Welcome to the wonderful world of Local Area Network radio!
- ===========================================================
-
- ! This is Radio version 2.0, patchlevel 1.
-
- If you have a local area network full of workstations with audio
- capabilities and at least one FM/AM radio or other audio source, you
- ***************
- *** 48,53 ****
- --- 48,73 ----
- This software is copyrighted. See the notice at the end of this file.
-
-
- + Changes in 2.0 patchlevel 1
- + ---------------------------
- +
- + On the sun and sgi, radio tries to open a connection to the X server
- + (specified by the $DISPLAY environment variable) and every now and
- + then makes a small request to exercise the connection. This ensures
- + that if the user logs out, radio will quit. If no connection to the X
- + server can be made, these checks are not made and a warning is printed
- + that reminds the user to kill radio when logging out.
- +
- + The usage message is more informative.
- +
- + The new option '-t' (tee) sends output to both stdout and the audio
- + device. Thanks to Scott Hazen Mueller for suggesting this.
- +
- + The experimental option '-m mcastgrp' (for SGI only) specifies a
- + multicast group. By multicasting instead of broadcasting, you can
- + reduce the load on hosts that aren't listening (see the man page).
- +
- +
- Changes since version 1.0 patchlevel 4
- --------------------------------------
-
- ***************
- *** 217,222 ****
- --- 237,250 ----
- the users on each host where it finds a listener. You must then be
- able to log in to that host remotely (with rlogin or rsh) without
- typing your password.
- +
- + There is also one Perl program, just to show that you don't need to be
- + entirely helpless if you don't have Python nor Motif:
- +
- + The Perl program "stations.pl" listens for and prints essential
- + information about stations. Extension to the functionality if
- + "stations.py" is left as an exercise to the reader.
- +
-
- Author
- ------
- diff -rcN ../orig/patchlevel.h ./patchlevel.h
- *** ../orig/patchlevel.h Thu Sep 10 08:55:36 1992
- --- ./patchlevel.h Thu Sep 10 08:57:15 1992
- ***************
- *** 1,1 ****
- ! #define PATCHLEVEL 0
- --- 1,1 ----
- ! #define PATCHLEVEL 1
- diff -rcN ../orig/playulaw.c ./playulaw.c
- *** ../orig/playulaw.c Thu Sep 10 08:55:36 1992
- --- ./playulaw.c Thu Sep 10 08:57:15 1992
- ***************
- *** 114,124 ****
- signal(SIGINT, cleanup_handler);
- signal(SIGTERM, cleanup_handler);
-
- - /* Set the output sampling rate to 8000 Hz */
- - pvbuf[0] = AL_OUTPUT_RATE;
- - pvbuf[1] = AL_RATE_8000;
- - ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2L);
- -
- /* Configure and open an SGI audio port */
- config = ALnewconfig();
- ALsetchannels(config, AL_MONO);
- --- 114,119 ----
- ***************
- *** 129,134 ****
- --- 124,135 ----
- perror("ALopenport");
- exit(1);
- }
- +
- + /* Set the output sampling rate to 8000 Hz */
- + /* Do this after ALopenport so we needn't undo it if that fails */
- + pvbuf[0] = AL_OUTPUT_RATE;
- + pvbuf[1] = AL_RATE_8000;
- + ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2L);
- #else
- /* Write to /dev/audio */
- if ((ofd = open("/dev/audio", O_WRONLY | O_NDELAY)) < 0) {
- diff -rcN ../orig/radio.c ./radio.c
- *** ../orig/radio.c Thu Sep 10 08:55:49 1992
- --- ./radio.c Thu Sep 10 08:57:15 1992
- ***************
- *** 41,46 ****
- --- 41,48 ----
- -n noninterruptable -- by default radio will be interruptable
- by other sound outputting programs, hoping they do not
- take too long. This option turns off that feature.
- + -t tee mode: send output to stdout as well as to audio h/w
- + -m mcastgrp multicast group (SGI only)
- */
-
- #define BCASTCTLPORT 54319
- ***************
- *** 53,61 ****
- --- 55,66 ----
-
- #ifdef sgi
- #define USE_AL
- + #define CHECK_X_SERVER
- + #define HAVE_MCAST
- #endif
- #ifdef sun
- #define USE_SUN
- + #define CHECK_X_SERVER
- #endif
- #ifdef NeXT
- #define USE_NX
- ***************
- *** 72,77 ****
- --- 77,86 ----
- #include <sys/time.h>
- #include <netinet/in.h>
-
- + #ifdef HAVE_MCAST
- + #include <arpa/inet.h>
- + #endif
- +
- #ifdef USE_AL
- #include <audio.h>
- #include "libst.h"
- ***************
- *** 96,101 ****
- --- 105,111 ----
-
- int interruptable = 1;
- int actlfd = -1;
- + int afd = -1;
-
- void sigpoll_handler();
- #endif /* USE_SUN */
- ***************
- *** 106,111 ****
- --- 116,126 ----
- SNDSoundStruct *snd[NUM_BUFFER];
- #endif /* USE_NX */
-
- + #ifdef CHECK_X_SERVER
- + #include <X11/Xlib.h>
- + Display *xdisplay = 0;
- + #endif
- +
- /* getopt() interface */
- extern int optind;
- extern char * optarg;
- ***************
- *** 114,123 ****
- --- 129,142 ----
- int pausing = 0; /* Flag set when pausing */
- int ofd = -1; /* Output file descriptor */
- int volume = -1; /* -v parameter */
- + int pdebug = 0; /* -p parameter */
- + char *mcastgrp = 0; /* -m parameter */
-
- /* Forward functions */
- void open_speaker();
- void close_speaker();
- + void checkalive();
- + void setmcast();
-
- main(argc, argv)
- int argc;
- ***************
- *** 131,142 ****
- int fromlen;
- int c;
- int filter = 0;
- int nfds;
- fd_set inputset;
- int n;
- - int pdebug = 0;
- char *localname = (char *) NULL;
- char *remotename = (char *) NULL;
- #ifdef USE_AL
- short obuf[BUFFERSIZE];
- int i;
- --- 150,163 ----
- int fromlen;
- int c;
- int filter = 0;
- + int tee = 0;
- int nfds;
- fd_set inputset;
- int n;
- char *localname = (char *) NULL;
- char *remotename = (char *) NULL;
- + struct timeval timeout;
- + int packetcount;
- #ifdef USE_AL
- short obuf[BUFFERSIZE];
- int i;
- ***************
- *** 145,153 ****
- int akt_buf;
- #endif
-
- ! /* Always change these two macros together! */
- ! #define OPTIONS "c:dfl:np:r:sv:"
- ! #define USAGE "usage: %s [-c ctlport] [-d] [-f] [-l localhost] [-n] [-p port]\n\t[-r remotehost] [-s] [-v volume(0-100)]\n"
-
- while ((c = getopt(argc, argv, OPTIONS)) != EOF) {
- switch (c) {
- --- 166,189 ----
- int akt_buf;
- #endif
-
- ! /* Always change these two macros and the following switch together! */
- ! #define OPTIONS "c:dfl:m:np:r:stv:"
- ! #define USAGE "usage: %s [options]\n\
- ! User options:\n\
- ! -p port : port to listen to (default 54321; 1..99 ==> 54321..54419)\n\
- ! -v volume : volume setting (1-100; default unchanged)\n\
- ! Expert options:\n\
- ! -f : filter mode (write data to stdout)\n\
- ! -t : tee mode (write data to stdout as well as to audio device)\n\
- ! -n : not interruptable by other sources (Sun only)\n\
- ! -c ctlport : control port for tuner programs (default 54320)\n\
- ! -s : secure mode: no control port (disallow tuner programs)\n\
- ! Guru options:\n\
- ! -l localhost : listen to packets to this host only\n\
- ! -r remothost : receive packets from that host only\n\
- ! -m mcastgrp : multicast group (SGI only)\n\
- ! -d : debugging mode (writes messages to stderr)\n\
- ! "
-
- while ((c = getopt(argc, argv, OPTIONS)) != EOF) {
- switch (c) {
- ***************
- *** 171,186 ****
- case 'd':
- pdebug = 1;
- break;
- ! #ifdef USE_SUN
- case 'n':
- interruptable = 0;
- break;
- - #endif /* USE_SUN */
- case 's':
- ctlport = -1;
- break;
- case 'f':
- filter = 1;
- break;
- case 'v':
- volume = atoi(optarg);
- --- 207,236 ----
- case 'd':
- pdebug = 1;
- break;
- ! case 'm':
- ! #ifdef HAVE_MCAST
- ! mcastgrp = optarg;
- ! #else
- ! fprintf(stderr, "(-m not supported here)\n");
- ! #endif
- ! break;
- case 'n':
- + #ifdef USE_SUN
- interruptable = 0;
- + #else
- + fprintf(stderr, "(-n not supported here)\n");
- + #endif
- break;
- case 's':
- ctlport = -1;
- break;
- case 'f':
- filter = 1;
- + tee = 0;
- + break;
- + case 't':
- + tee = 1;
- + filter = 0;
- break;
- case 'v':
- volume = atoi(optarg);
- ***************
- *** 188,198 ****
- }
- }
-
- ! if (filter) {
- ofd = fileno(stdout);
- ! }
- ! else {
- open_speaker();
- }
-
- if (ctlport >= 0)
- --- 238,261 ----
- }
- }
-
- ! /* Meaning of the 'tee' and 'filter' flags:
- ! At most one of these can be on.
- ! if tee is on: write stdout and "/dev/audio";
- ! if filter is on: write stdout only;
- ! if both are off: write "/dev/audio" only;
- ! where "/dev/audio" stands for whatever audio hardware we have. */
- !
- ! if (filter || tee)
- ofd = fileno(stdout);
- ! if (!filter) {
- open_speaker();
- + #ifdef CHECK_X_SERVER
- + xdisplay = XOpenDisplay((char *)NULL);
- + if (xdisplay == NULL) {
- + fprintf(stderr,
- + "radio: warning: no X server -- you must kill radio when you log out!\n");
- + }
- + #endif
- }
-
- if (ctlport >= 0)
- ***************
- *** 202,219 ****
- ctls = -1;
-
- s = opensock("data", localname, receiveport, remotename, SENDPORT, 0);
-
- for (;;) {
- /*
- ** Wait until one of the sockets becomes ready
- */
- ! nfds = (s > ctls ? s : ctls) + 1;
- ! FD_ZERO(&inputset);
- ! FD_SET(s, &inputset);
- ! if (ctls >= 0)
- ! FD_SET(ctls, &inputset);
- ! while (select(nfds, &inputset, 0, 0, 0) < 1) {
- ! if(errno != EINTR) {
- perror("select");
- exit(1);
- }
- --- 265,294 ----
- ctls = -1;
-
- s = opensock("data", localname, receiveport, remotename, SENDPORT, 0);
- + if (mcastgrp)
- + setmcast(s, mcastgrp);
- +
- + packetcount = 0;
-
- for (;;) {
- /*
- ** Wait until one of the sockets becomes ready
- */
- ! for (;;) {
- ! nfds = (s > ctls ? s : ctls) + 1;
- ! FD_ZERO(&inputset);
- ! FD_SET(s, &inputset);
- ! if (ctls >= 0)
- ! FD_SET(ctls, &inputset);
- ! timeout.tv_sec = 30;
- ! timeout.tv_usec = 0;
- ! n = select(nfds, &inputset, 0, 0, &timeout);
- ! if (n > 0)
- ! break;
- ! if (n == 0) {
- ! checkalive();
- ! }
- ! else if (errno != EINTR) {
- perror("select");
- exit(1);
- }
- ***************
- *** 241,247 ****
- else
- pdebug++;
- }
- ! if ( n <= CTLPKTSIZE ) {
- /*
- ** It looks like a control packet. Check it.
- */
- --- 316,322 ----
- else
- pdebug++;
- }
- ! if (n <= CTLPKTSIZE) {
- /*
- ** It looks like a control packet. Check it.
- */
- ***************
- *** 278,283 ****
- --- 353,360 ----
- s = opensock("new data", localname,
- receiveport, remotename,
- SENDPORT, 0);
- + if (mcastgrp)
- + setmcast(s, mcastgrp);
- break;
- case 'i': /* Info */
- sprintf(buf, "radio:I:%d:%d",
- ***************
- *** 320,326 ****
- obuf[i] = st_ulaw_to_linear(buf[i]);
- ALwritesamps(aport, obuf, (long)n);
- }
- - else
- #endif /* USE_AL */
- #ifdef USE_NX
- if (!filter) {
- --- 397,402 ----
- ***************
- *** 337,349 ****
- akt_buf+1, 5, 0, 0, 0);
- akt_buf = (akt_buf + 1) % NUM_BUFFER;
- }
- ! else
- ! #endif/* USE_NX */
- ! if (write(ofd, buf, n) != n) {
- ! perror("write");
- ! break;
- }
- }
- }
-
- exit(0);
- --- 413,438 ----
- akt_buf+1, 5, 0, 0, 0);
- akt_buf = (akt_buf + 1) % NUM_BUFFER;
- }
- ! #endif /* USE_NX */
- ! #ifdef USE_SUN
- ! if (!filter) {
- ! if (write(afd, buf, n) != n) {
- ! perror("write afd");
- ! break;
- ! }
- ! }
- ! #endif /* USE_SUN */
- ! if (filter || tee) {
- ! if (write(ofd, buf, n) != n) {
- ! perror("write ofd");
- ! break;
- ! }
- }
- }
- + if (++packetcount > (30*8000 / BUFFERSIZE)) {
- + checkalive();
- + packetcount = 0;
- + }
- }
-
- exit(0);
- ***************
- *** 416,422 ****
- audio_info_t info;
-
- /* Write to AUDIO_IODEV */
- ! if ((ofd = open(AUDIO_IODEV, O_WRONLY)) < 0) {
- perror(AUDIO_IODEV);
- exit(1);
- }
- --- 505,511 ----
- audio_info_t info;
-
- /* Write to AUDIO_IODEV */
- ! if ((afd = open(AUDIO_IODEV, O_WRONLY)) < 0) {
- perror(AUDIO_IODEV);
- exit(1);
- }
- ***************
- *** 425,431 ****
- if (volume >= 0) {
- AUDIO_INITINFO(&info);
- info.play.gain = (AUDIO_MAX_GAIN * volume) / 100;
- ! if (ioctl(ofd, AUDIO_SETINFO, &info))
- perror("volume setting");
- }
-
- --- 514,520 ----
- if (volume >= 0) {
- AUDIO_INITINFO(&info);
- info.play.gain = (AUDIO_MAX_GAIN * volume) / 100;
- ! if (ioctl(afd, AUDIO_SETINFO, &info))
- perror("volume setting");
- }
-
- ***************
- *** 449,458 ****
-
- void close_speaker()
- {
- ! (void) ioctl(ofd, I_FLUSH, FLUSHW);
- ! close(ofd);
- close(actlfd);
- ! ofd = actlfd = -1;
- }
-
- void sigpoll_handler()
- --- 538,547 ----
-
- void close_speaker()
- {
- ! (void) ioctl(afd, I_FLUSH, FLUSHW);
- ! close(afd);
- close(actlfd);
- ! afd = actlfd = -1;
- }
-
- void sigpoll_handler()
- ***************
- *** 463,472 ****
- perror("AUDIO_GETINFO");
- }
- else if (ap.play.waiting) {
- ! (void) ioctl(ofd, I_FLUSH, FLUSHW);
- ! close(ofd);
- /* The open() call blocks until we can use the device again */
- ! if ((ofd = open(AUDIO_IODEV, O_WRONLY)) < 0) {
- perror(AUDIO_IODEV);
- exit(1);
- }
- --- 552,561 ----
- perror("AUDIO_GETINFO");
- }
- else if (ap.play.waiting) {
- ! (void) ioctl(afd, I_FLUSH, FLUSHW);
- ! close(afd);
- /* The open() call blocks until we can use the device again */
- ! if ((afd = open(AUDIO_IODEV, O_WRONLY)) < 0) {
- perror(AUDIO_IODEV);
- exit(1);
- }
- ***************
- *** 488,494 ****
- int err;
-
- /* Alloc NUM_BUFFER Sounds */
- ! for( akt_buf = NUM_BUFFER; akt_buf > 0; akt_buf--) {
- if (err = SNDAlloc(&snd[akt_buf-1], BUFFERSIZE,
- SND_FORMAT_MULAW_8,
- SND_RATE_CODEC, 1, 4)) {
- --- 577,583 ----
- int err;
-
- /* Alloc NUM_BUFFER Sounds */
- ! for (akt_buf = NUM_BUFFER; akt_buf > 0; akt_buf--) {
- if (err = SNDAlloc(&snd[akt_buf-1], BUFFERSIZE,
- SND_FORMAT_MULAW_8,
- SND_RATE_CODEC, 1, 4)) {
- ***************
- *** 505,507 ****
- --- 594,644 ----
- }
-
- #endif /* USE_NX */
- +
- +
- + void checkalive()
- + {
- + #ifdef CHECK_X_SERVER
- + if (xdisplay) {
- + Window focus;
- + int revert_to;
- + if (pdebug)
- + fprintf(stderr, "polling X server...\n");
- + /* Do a simple X request that needs a server round trip...
- + The error handler will kill us when the server is dead,
- + so that radio dies when the user logs out. */
- + XGetInputFocus(xdisplay, &focus, &revert_to);
- + if (pdebug)
- + fprintf(stderr, "X server OK\n");
- + }
- + else if (pdebug)
- + fprintf(stderr, "checkalive() is a no-op\n");
- + #endif /* CHECK_X_SERVER */
- + }
- +
- + void setmcast(s, group)
- + int s;
- + char *group;
- + {
- + #ifdef HAVE_MCAST
- + struct in_addr grpaddr;
- + struct in_addr ifaddr;
- + struct ip_mreq mreq;
- +
- + grpaddr.s_addr = inet_addr(group);
- + if (!IN_MULTICAST(grpaddr.s_addr)) {
- + fprintf(stderr, "Bad multicast group: %s\n", group);
- + exit(1);
- + }
- +
- + ifaddr.s_addr = htonl(INADDR_ANY);
- +
- + mreq.imr_multiaddr = grpaddr;
- + mreq.imr_interface = ifaddr;
- + if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- + &mreq, sizeof(mreq)) < 0) {
- + perror("setsockopt mreq");
- + exit(1);
- + }
- + #endif
- + }
- diff -rcN ../orig/radio.man ./radio.man
- *** ../orig/radio.man Thu Sep 10 08:55:37 1992
- --- ./radio.man Thu Sep 10 08:57:16 1992
- ***************
- *** 14,22 ****
- .B \-l
- .I addr
- ] [
- ! .B \-n
- ]
- ! [
- .B \-p
- .I port
- ] [
- --- 14,25 ----
- .B \-l
- .I addr
- ] [
- ! .B \-m
- ! .I mcastgrp
- ]
- ! [
- ! .B \-n
- ! ] [
- .B \-p
- .I port
- ] [
- ***************
- *** 25,30 ****
- --- 28,35 ----
- ] [
- .B \-s
- ] [
- + .B \-t
- + ] [
- .B \-v
- .I volume
- ]
- ***************
- *** 73,78 ****
- --- 78,94 ----
- .I addr
- (useful for forwarding stations).
- .TP 10
- + .BI "\-m " mcastgrp
- + Multicast group (SGI only).
- + This only makes sense if the same multicast group is passed to the
- + .B \-b
- + option of
- + .IR broadcast (1).
- + Using multicasting instead of broadcasting reduces the load on
- + machines that aren't listening.
- + Unfortunately, the choice of multicast groups is a black art.
- + In any case you probably need a multicast group per station.
- + .TP 10
- .B \-n
- Noninterruptable mode (Sun Sparc only).
- By default,
- ***************
- *** 99,104 ****
- --- 115,124 ----
- can override the port specified with \fB\-p\fP by sending a control
- message to the control port of your radio program.
- .TP 10
- + .B \-t
- + Tee mode: write the U-LAW audio data to stdout as well as
- + sending it to the audio hardware.
- + .TP 10
- .BI "\-v " volume
- Set the initial volume, on a scale from 0 to 100. (SGI and Sun Sparc only.)
- By default, the volume is left unchanged.
- ***************
- *** 107,113 ****
- .SH AUTHOR
- Guido van Rossum
- .SH VERSION
- ! This manual page documents radio version 2.0, patchlevel 0.
- .SH SEE ALSO
- broadcast(1)
- .SH COPYRIGHT
- --- 127,133 ----
- .SH AUTHOR
- Guido van Rossum
- .SH VERSION
- ! This manual page documents radio version 2.0, patchlevel 1.
- .SH SEE ALSO
- broadcast(1)
- .SH COPYRIGHT
- diff -rcN ../orig/stations.pl ./stations.pl
- *** ../orig/stations.pl Wed Dec 31 18:00:00 1969
- --- ./stations.pl Thu Sep 10 08:57:45 1992
- ***************
- *** 0 ****
- --- 1,28 ----
- + #!/usr/bin/perl
- + ##
- + ## Find radio stations
- + ##
- + ## (A small subset of the functionality of stations.py for now)
- + ##
- + ## Written by; Jeff Beadles jeff@onion.rain.com
- + ##
- + # this emulates #! processing on machines that don't support it.
- + eval "exec /usr/bin/perl -S $0 $*"
- + if $running_under_some_shell_and_not_perl;
- +
- + require 'sys/socket.ph';
- +
- + ($name, $aliases, $proto) = getprotobyname('udp');
- +
- + $this = pack('S n a4 x8' , &AF_INET, 54317, "\0\0\0\0");
- +
- + socket(S, &AF_INET, &SOCK_DGRAM, $proto) || die "socket: $!";
- + bind(S, $this) || die "bind: $!";
- +
- + while (1) {
- + recv(S, $buf, 1024, 0) || die "recv: $!\n";
- + chop($buf);
- + ($t_radio,$t_s,$t_name,$t_port,$t_xmit,$t_log,$t_age) = split(/:/,$buf,7);
- + print "Bogus message '$buf'\n" if ($t_radio ne "radio");
- + print "Receiving station '$t_name' on port $t_port\n";
- + }
- exit 0 # Just in case...
-