Index: remctl/Makefile
===================================================================
--- remctl/Makefile	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/Makefile	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,7 @@
+all:
+
+install:
+	mkdir -p $(DESTDIR)/usr/lib/gutenbach/remctl/
+	mkdir -p $(DESTDIR)/etc/remctl/conf.d/
+	install -m 755 lib/gutenbach/* $(DESTDIR)/usr/lib/gutenbach/remctl/
+	install -m 755 lib/remctl/* $(DESTDIR)/etc/remctl/conf.d/
Index: remctl/cd
===================================================================
--- remctl/cd	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,3 +1,0 @@
-cd cddb     /usr/lib/gutenbach/remctl/cd-cddb     ANYUSER
-cd cddb-get /usr/lib/gutenbach/remctl/cd-cddb-get ANYUSER
-cd play     /usr/lib/gutenbach/remctl/cd-play     ANYUSER
Index: remctl/cd-cddb
===================================================================
--- remctl/cd-cddb	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,20 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-die () {
-    echo "$@";
-    exit 1;
-}
-
-CACHE=$(cd-cddb-get) || die "Unable to fetch CDDB information."
-
-. "$CACHE"
-
-echo "Artist: $DARTIST";
-echo "Album: $DALBUM";
-echo "Tracks: $TRACKS";
-
-for i in $(seq 1 $TRACKS); do
-    echo -n "Track $i: "
-    eval 'echo $TRACK'$i
-done
Index: remctl/cd-cddb-get
===================================================================
--- remctl/cd-cddb-get	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
-MYUSER="gutenbach"
-MYHOST=`hostname`".mit.edu"
-
-DISCID=$(cd-discid /dev/cdrom 2>/dev/null) || exit 1
-
-set -- $DISCID
-
-ID="$1"
-TRACKS="$2"
-
-mkdir -p /var/cache/gutenbach
-
-CACHEFILE="/var/cache/gutenbach/$ID"
-
-if [ ! -e "$CACHEFILE" ]; then
-
-    CD=$(cddb-tool query "$CDDBURL" 3 "$MYUSER" "$MYHOST" $DISCID) \
-	|| exit 2;
-
-    file=$(tempfile)
-
-    cddb-tool read "$CDDBURL" 3 "$MYUSER" "$MYHOST" \
-	$(echo "$CD" | head -1 | awk '{print $2 " " $3}') > "$file"  \
-	|| exit 3;
-
-    echo "TRACKS=$TRACKS"   >  "$CACHEFILE"
-    cddb-tool parse "$file" >> "$CACHEFILE"
-
-    rm "$file"
-fi
-
-echo "$CACHEFILE"
-exit 0;
Index: remctl/cd-play
===================================================================
--- remctl/cd-play	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-CDDB=
-
-CACHE=$(cd-cddb-get)
-
-printername=$(/usr/lib/gutenbach/gutenbach-get-config queue)
-
-if [ "$?" = 0 ]; then
-    CDDB=1
-fi
-
-. "$CACHE"
-
-play_one () {
-    T=$1
-    if [ -n "$CDDB" ]; then
-	DESC=" - "$(eval 'echo $TRACK'$T)
-    fi
-
-    echo "cdda://$(($T - 1))" | mit-lpr -P"$queue"@localhost -J "Track $T$DESC";
-    echo "Queued Track $T$DESC";
-}
-
-TOPLAY="$2"
-
-if [ -z "$TOPLAY" -o "$TOPLAY" = "all" ]; then
-    for i in $(seq 1 "$TRACKS"); do
-	play_one $i
-    done
-else
-    shift;
-    for i in "$@"; do
-	play_one $i
-    done
-fi
Index: remctl/lib/gutenbach/cd-cddb
===================================================================
--- remctl/lib/gutenbach/cd-cddb	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/cd-cddb	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,20 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+die () {
+    echo "$@";
+    exit 1;
+}
+
+CACHE=$(cd-cddb-get) || die "Unable to fetch CDDB information."
+
+. "$CACHE"
+
+echo "Artist: $DARTIST";
+echo "Album: $DALBUM";
+echo "Tracks: $TRACKS";
+
+for i in $(seq 1 $TRACKS); do
+    echo -n "Track $i: "
+    eval 'echo $TRACK'$i
+done
Index: remctl/lib/gutenbach/cd-cddb-get
===================================================================
--- remctl/lib/gutenbach/cd-cddb-get	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/cd-cddb-get	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,37 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
+MYUSER="gutenbach"
+MYHOST=`hostname`".mit.edu"
+
+DISCID=$(cd-discid /dev/cdrom 2>/dev/null) || exit 1
+
+set -- $DISCID
+
+ID="$1"
+TRACKS="$2"
+
+mkdir -p /var/cache/gutenbach
+
+CACHEFILE="/var/cache/gutenbach/$ID"
+
+if [ ! -e "$CACHEFILE" ]; then
+
+    CD=$(cddb-tool query "$CDDBURL" 3 "$MYUSER" "$MYHOST" $DISCID) \
+	|| exit 2;
+
+    file=$(tempfile)
+
+    cddb-tool read "$CDDBURL" 3 "$MYUSER" "$MYHOST" \
+	$(echo "$CD" | head -1 | awk '{print $2 " " $3}') > "$file"  \
+	|| exit 3;
+
+    echo "TRACKS=$TRACKS"   >  "$CACHEFILE"
+    cddb-tool parse "$file" >> "$CACHEFILE"
+
+    rm "$file"
+fi
+
+echo "$CACHEFILE"
+exit 0;
Index: remctl/lib/gutenbach/cd-play
===================================================================
--- remctl/lib/gutenbach/cd-play	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/cd-play	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,37 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+CDDB=
+
+CACHE=$(cd-cddb-get)
+
+printername=$(/usr/lib/gutenbach/gutenbach-get-config queue)
+
+if [ "$?" = 0 ]; then
+    CDDB=1
+fi
+
+. "$CACHE"
+
+play_one () {
+    T=$1
+    if [ -n "$CDDB" ]; then
+	DESC=" - "$(eval 'echo $TRACK'$T)
+    fi
+
+    echo "cdda://$(($T - 1))" | mit-lpr -P"$queue"@localhost -J "Track $T$DESC";
+    echo "Queued Track $T$DESC";
+}
+
+TOPLAY="$2"
+
+if [ -z "$TOPLAY" -o "$TOPLAY" = "all" ]; then
+    for i in $(seq 1 "$TRACKS"); do
+	play_one $i
+    done
+else
+    shift;
+    for i in "$@"; do
+	play_one $i
+    done
+fi
Index: remctl/lib/gutenbach/status-clear
===================================================================
--- remctl/lib/gutenbach/status-clear	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/status-clear	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,3 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+> /var/run/gutenbach/status
Index: remctl/lib/gutenbach/status-get
===================================================================
--- remctl/lib/gutenbach/status-get	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/status-get	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,3 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+cat /var/run/gutenbach/status
Index: remctl/lib/gutenbach/voldaemon.c
===================================================================
--- remctl/lib/gutenbach/voldaemon.c	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/voldaemon.c	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,319 @@
+/*
+ * $Id: voldaemon.c,v 1.1 2008-09-27 08:49:10 root Exp $
+ * $Source: /tmp/tmp.UFBNno9997/RCS/voldaemon.c,v $
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <assert.h>
+#include <netinet/in.h>
+
+
+#define LISTEN_PORT 8930
+#define MULTI_PORT 8931
+#define MULTI_ADDR "224.0.1.20"
+
+/* Block queries from off this subnet net 18.*/
+#define OUR_SUBNET      187
+
+typedef struct volmessage{
+  char A;
+  char request;
+  char value;
+  unsigned char ip_3;
+  unsigned char ip_2;
+  unsigned char ip_1;
+  unsigned char ip_0;
+  char ZE;
+} volmessage;
+
+#define MESSAGE_SIZE (sizeof(volmessage))
+
+/* The client makes requests using the following packets.  Responses
+   to queries and status reports from the server follow the same
+   pattern
+
+  Request/Response
+
+  'AVxiiiiZ'     Volume
+  'AMxiiiiZ'     Mute
+  'AQQiiiiZ'     Query 
+
+  Response Only
+  'AVeiiiiE'     Volume Set Error 
+  'AMeiiiiE'     Mute Set Error 
+  'AEeiiiiE'     Unknown error 
+
+   e=1  Permission denied (invalid IP)
+   e=2  Invalid request (Bad Packet)
+   
+*/
+
+void message(char *m){
+  write(STDERR_FILENO,m,strlen(m));
+}
+
+void abortm(char *m){
+  message(m);
+  message("Errno = ");
+  message(strerror(errno));
+  message("\n");
+  exit(1);
+}
+
+struct in_addr multiaddr={0};
+
+int multicast(volmessage *m){
+  static int sockfd=-1;
+  static struct sockaddr_in dest;
+  int destlen=sizeof(dest);
+
+  if(sockfd==-1)
+    if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
+      abortm("Could not open multicast socket\n");
+
+  if(multiaddr.s_addr==0)
+    multiaddr.s_addr = inet_addr(MULTI_ADDR);
+      /*inet_aton(MULTI_ADDR,&multiaddr);*/
+
+  memset(&dest,0,sizeof(dest));
+  dest.sin_family=AF_INET;
+  dest.sin_addr.s_addr=multiaddr.s_addr;
+  dest.sin_port=htons(MULTI_PORT);
+
+  if(sendto(sockfd,m,MESSAGE_SIZE,0,(struct sockaddr *)&dest,destlen)<0){
+    message("Multicast send error\n");
+    return(1);
+  }
+  return(0);
+}
+
+int sockfd=-1,volfd;
+static struct sockaddr_in me,you;
+static int youlen=sizeof(you);
+struct in_addr multiaddr;
+
+int opensock(){
+  if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
+    abortm("Could not open listen socket\n");
+
+  memset(&me,0,sizeof(me));
+  me.sin_family=AF_INET;
+  me.sin_addr.s_addr=htonl(INADDR_ANY);
+  me.sin_port=htons(LISTEN_PORT);
+
+  if(bind(sockfd,(struct sockaddr *)&me,sizeof(me))<0)
+    abortm("Could not bind to listen port\n");
+
+  listen(sockfd,5);
+  return(sockfd);
+}
+
+/*  -1 blocks
+    0  nonblocking
+    +n timeout 
+*/
+
+int
+fetch (int usec, volmessage *m) {
+  fd_set fdset;
+  int retval;
+  struct timeval tv;
+  if(sockfd==-1)
+    opensock();
+
+  FD_ZERO(&fdset);
+  FD_SET(sockfd, &fdset);
+
+  tv.tv_sec = 0;
+  tv.tv_usec = usec;
+  retval = select(sockfd+1,
+		  &fdset, NULL, NULL,
+		  ((usec == -1) ? NULL : &tv));
+  if (retval == 1) {
+    /* Select got us a single descriptor to play with, as we
+     * expected. Pull a message from it. */
+    int youlen = sizeof(you);
+    retval = recvfrom(sockfd,
+		      m, MESSAGE_SIZE,
+		      0,
+		      (struct sockaddr *)&you, &youlen);
+    if(retval < MESSAGE_SIZE || m->A != 'A' || m->ZE != 'Z') {
+      message("Packet receive error\n");
+      return(0);
+    } else {
+      return(1);
+    }
+  } else {
+    if (retval == 0) {
+      /* This means the timeout finished. */
+    } else if (retval == -1) {
+      fprintf(stderr, "Select error. errno = %d (%s).\n",
+	      errno, strerror(errno));
+    } else {
+      fprintf(stderr, "Select returned unexpected value %d.\n", retval);
+    }
+    /* Whatever error we get, we just return 0. */
+    return(0);
+  }
+}
+
+
+int
+reply (volmessage *m) {
+  int retval;
+  assert(sockfd != -1);
+  
+  retval = sendto(sockfd,
+		  m, MESSAGE_SIZE,
+		  0,
+		  (struct sockaddr *)&you, youlen);
+  if(retval < 0){
+    message("Reply error\n");
+    return(1);
+  }
+  return(0);
+}
+  
+int vol_iterate(int newval){
+  static int val=0;
+  char command[100];
+  
+
+  if (val==newval)
+    return(0);
+
+  if (val<newval) {
+    val+=8;
+    if(val>newval)
+      val=newval;
+  } else {
+    val-=8;
+    if(val<newval)
+      val=newval;
+  }
+  sprintf(command,"/usr/bin/aumix -v %d",val);
+  fprintf(stderr,"Setting volume to %d\n",val);
+  system(command);
+  return(1);
+}
+
+int main(){
+  unsigned char volume=32,mute=0,ip_3=0,ip_2=0,ip_1=0,ip_0=0;
+  int messagestatus=1,volstatus=1;
+  volmessage m;
+
+  system("/usr/bin/aumix -v 0");
+  system("/usr/bin/aumix -i 100");
+  system("/usr/bin/aumix -l 100");
+
+  message("\nSIPB volume daemon running\n");
+
+  /* We want to process messages quickly, then get to the business of
+     controlling ther hardware when no messages are in the queue. 
+     The select on the message fetch also does our timing for volume
+     iteration */
+
+  while(1){
+    if(messagestatus==1)
+      /* Messages likely pending.  Process quickly */
+      messagestatus=fetch(0,&m);
+    else
+      if(volstatus==1){
+	/* No messages, but volume to be updated */
+	messagestatus=fetch(50,&m);
+	if(messagestatus==0)volstatus=vol_iterate(mute?0:volume);
+      }else{
+	/* Steady state.  Wait (almost) forever until a message */
+	m.ip_0=ip_0;
+	m.ip_1=ip_1;
+	m.ip_2=ip_2;
+	m.ip_3=ip_3;
+	m.A='A';
+	m.request='V';
+	m.value=volume;
+	m.ZE='Z';
+    	multicast(&m);
+	m.A='A';
+	m.request='M';
+	m.value=mute;
+	m.ZE='Z';
+    	multicast(&m);
+	messagestatus=fetch(400000,&m);
+      }
+
+    if(messagestatus){
+      int error=0;
+      m.ip_3=(ntohl(you.sin_addr.s_addr)>>24)&0xff;
+      m.ip_2=(ntohl(you.sin_addr.s_addr)>>16)&0xff;
+      m.ip_1=(ntohl(you.sin_addr.s_addr)>>8)&0xff;
+      m.ip_0=ntohl(you.sin_addr.s_addr)&0xff;
+
+      if(m.ip_3!=18 || m.ip_2!=OUR_SUBNET){
+	error=1;
+      }
+
+      switch(m.request){
+      case 'V':
+	if(error){
+	  m.value=error;
+	  m.ZE='E';
+	  reply(&m);
+	  message("Request from off subnet rejected\n");
+	}else{
+	  ip_0=m.ip_0;
+	  ip_1=m.ip_1;
+	  ip_2=m.ip_2;
+	  ip_3=m.ip_3;
+	  volume=m.value;
+	  reply(&m);
+	  multicast(&m);
+	  volstatus=1;
+	}
+	break;
+      case 'M':
+	if(error){
+	  m.value=error;
+	  m.ZE='E';
+	  reply(&m);	  
+	  message("Request from off subnet rejected\n");
+	}else{
+	  ip_0=m.ip_0;
+	  ip_1=m.ip_1;
+	  ip_2=m.ip_2;
+	  ip_3=m.ip_3;
+	  mute=(m.value?1:0);
+	  m.value=mute;
+	  reply(&m);
+	  multicast(&m);
+	  volstatus=1;
+	}
+	break;
+      case 'Q':
+	m.ip_0=ip_0;
+	m.ip_1=ip_1;
+	m.ip_2=ip_2;
+	m.ip_3=ip_3;
+	m.request='V';
+	m.value=volume;
+	reply(&m);
+	m.request='M';
+	m.value=mute;
+	reply(&m);
+	break;
+      default:
+	reply((volmessage *)"AE20000E");
+	break;
+      }
+    }
+  }
+}
Index: remctl/lib/gutenbach/volume-down
===================================================================
--- remctl/lib/gutenbach/volume-down	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-down	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,3 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+volume-set . $(( $(volume-get .) - 1 ))
Index: remctl/lib/gutenbach/volume-get
===================================================================
--- remctl/lib/gutenbach/volume-get	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-get	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,8 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
+channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
+
+amixer get $mixer | grep "$channel" \
+ | perl -lne 'print $1 if (/: Playback ([0-9]+)/)'
Index: remctl/lib/gutenbach/volume-help
===================================================================
--- remctl/lib/gutenbach/volume-help	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-help	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,15 @@
+#!/bin/bash
+PATH="$(dirname $0):$PATH"
+cat <<EOF
+Usage: remctl zsr.mit.edu <command> <subcommand> [..args..]
+Commands:
+  volume up        - increment volume
+  volume down      - decrement volume
+  volume get       - get volume
+  volume set [vol] - set volume, in range 0..31
+  volume mute      - zero volume
+  volume help,
+   help <anything> - print this help
+
+'v', 'u', 'd' abbreviate 'volume', 'up', 'down' respectively.
+EOF
Index: remctl/lib/gutenbach/volume-is-muted
===================================================================
--- remctl/lib/gutenbach/volume-is-muted	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-is-muted	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,17 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
+channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
+
+volstat=$(amixer get $mixer | grep "$channel" \
+ | perl -lne 'print $1 if (/: Playback .*\[(on|off)\]$/)'
+)
+
+case "$volstat" in 
+    on)  result=unmuted;;
+    off) result=muted;;
+    *)   result=unknown;;
+esac
+
+echo $result
Index: remctl/lib/gutenbach/volume-mute
===================================================================
--- remctl/lib/gutenbach/volume-mute	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-mute	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,10 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
+channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
+
+amixer set $mixer toggle > /dev/null
+volume-is-muted
+
+volume-zephyr
Index: remctl/lib/gutenbach/volume-set
===================================================================
--- remctl/lib/gutenbach/volume-set	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-set	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,10 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
+channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
+
+amixer set $mixer "$2" | grep "$channel" \
+ | perl -lne 'print $1 if (/: Playback ([0-9]+)/)'
+
+volume-zephyr
Index: remctl/lib/gutenbach/volume-show
===================================================================
--- remctl/lib/gutenbach/volume-show	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-show	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,7 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+
+mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
+channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
+
+amixer get $mixer
Index: remctl/lib/gutenbach/volume-up
===================================================================
--- remctl/lib/gutenbach/volume-up	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-up	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,3 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+volume-set . $(( $(volume-get .) + 1 ))
Index: remctl/lib/gutenbach/volume-zephyr
===================================================================
--- remctl/lib/gutenbach/volume-zephyr	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/gutenbach/volume-zephyr	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,28 @@
+#!/bin/sh
+PATH="$(dirname $0):$PATH"
+class=$(/usr/lib/gutenbach/gutenbach-get-config zephyr-class)
+host=$(/usr/lib/gutenbach/gutenbach-get-config host)
+queue=$(/usr/lib/gutenbach/gutenbach-get-config queue)
+instance="$queue-volume@$host"
+
+mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
+channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
+
+echo "Class: $class" >> /tmp/gutenbach-remctl.log
+echo "Host: $host" >> /tmp/gutenbach-remctl.log
+echo "Queue: $queue" >> /tmp/gutenbach-remctl.log
+echo "Instance: $instance" >> /tmp/gutenbach-remctl.log
+echo "Mixer: $mixer" >> /tmp/gutenbach-remctl.log
+echo "Channel: $channel" >> /tmp/gutenbach-remctl.log
+
+muted=$(volume-is-muted)
+mute_str=" [$muted]"
+if [ "$muted" = "unmuted" ]; then
+    mute_str=""
+fi
+
+start-stop-daemon --stop --oknodo --pidfile /usr/lib/gutenbach/gutenbach-zephyr >/dev/null 2>&1
+start-stop-daemon --start --pidfile /usr/lib/gutenbach/gutenbach-zephyr --make-pidfile --background --exec /bin/sh -- -c "sleep 10 && zwrite -c $class -i $instance -d -n -m 'volume changed to $(volume-get)$mute_str' > /dev/null" >/dev/null 2>&1
+
+echo "sleep 10 && zwrite -c $class -i $instance -d -n -m 'volume changed to $(volume-get)$mute_str' > /dev/null" >> /tmp/gutenbach-remctl.log
+echo "" >> /tmp/gutenbach-remctl.log
Index: remctl/lib/remctl/cd
===================================================================
--- remctl/lib/remctl/cd	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/remctl/cd	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,3 @@
+cd cddb     /usr/lib/gutenbach/remctl/cd-cddb     ANYUSER
+cd cddb-get /usr/lib/gutenbach/remctl/cd-cddb-get ANYUSER
+cd play     /usr/lib/gutenbach/remctl/cd-play     ANYUSER
Index: remctl/lib/remctl/status
===================================================================
--- remctl/lib/remctl/status	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/remctl/status	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,2 @@
+status get   /usr/lib/gutenbach/remctl/status-get   ANYUSER
+status clear /usr/lib/gutenbach/remctl/status-clear ANYUSER
Index: remctl/lib/remctl/volume
===================================================================
--- remctl/lib/remctl/volume	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
+++ remctl/lib/remctl/volume	(revision 9c0279ee584d72ca543f631999621c6c1afac43e)
@@ -0,0 +1,25 @@
+volume set  /usr/lib/gutenbach/remctl/volume-set	 ANYUSER 
+volume get  /usr/lib/gutenbach/remctl/volume-get    ANYUSER
+volume show /usr/lib/gutenbach/remctl/volume-show   ANYUSER
+volume mute /usr/lib/gutenbach/remctl/volume-mute   ANYUSER 
+volume up   /usr/lib/gutenbach/remctl/volume-up     ANYUSER 
+volume down /usr/lib/gutenbach/remctl/volume-down   ANYUSER 
+volume is-muted /usr/lib/gutenbach/remctl/volume-is-muted   ANYUSER 
+
+v set  /usr/lib/gutenbach/remctl/volume-set    ANYUSER 
+v get  /usr/lib/gutenbach/remctl/volume-get    ANYUSER
+v show /usr/lib/gutenbach/remctl/volume-show   ANYUSER
+v mute /usr/lib/gutenbach/remctl/volume-mute   ANYUSER 
+v up   /usr/lib/gutenbach/remctl/volume-up     ANYUSER 
+v down /usr/lib/gutenbach/remctl/volume-down   ANYUSER 
+v is-muted /usr/lib/gutenbach/remctl/volume-is-muted   ANYUSER 
+
+v u /usr/lib/gutenbach/remctl/volume-up   ANYUSER
+v d /usr/lib/gutenbach/remctl/volume-down ANYUSER
+
+volume u /usr/lib/gutenbach/remctl/volume-up   ANYUSER
+volume d /usr/lib/gutenbach/remctl/volume-down ANYUSER
+
+volume help /usr/lib/gutenbach/remctl/volume-help ANYUSER
+v      help /usr/lib/gutenbach/remctl/volume-help ANYUSER
+help   ALL  /usr/lib/gutenbach/remctl/volume-help ANYUSER
Index: remctl/status
===================================================================
--- remctl/status	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,2 +1,0 @@
-status get   /usr/lib/gutenbach/remctl/status-get   ANYUSER
-status clear /usr/lib/gutenbach/remctl/status-clear ANYUSER
Index: remctl/status-clear
===================================================================
--- remctl/status-clear	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-> /var/run/gutenbach/status
Index: remctl/status-get
===================================================================
--- remctl/status-get	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-cat /var/run/gutenbach/status
Index: remctl/voldaemon.c
===================================================================
--- remctl/voldaemon.c	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,319 +1,0 @@
-/*
- * $Id: voldaemon.c,v 1.1 2008-09-27 08:49:10 root Exp $
- * $Source: /tmp/tmp.UFBNno9997/RCS/voldaemon.c,v $
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <assert.h>
-#include <netinet/in.h>
-
-
-#define LISTEN_PORT 8930
-#define MULTI_PORT 8931
-#define MULTI_ADDR "224.0.1.20"
-
-/* Block queries from off this subnet net 18.*/
-#define OUR_SUBNET      187
-
-typedef struct volmessage{
-  char A;
-  char request;
-  char value;
-  unsigned char ip_3;
-  unsigned char ip_2;
-  unsigned char ip_1;
-  unsigned char ip_0;
-  char ZE;
-} volmessage;
-
-#define MESSAGE_SIZE (sizeof(volmessage))
-
-/* The client makes requests using the following packets.  Responses
-   to queries and status reports from the server follow the same
-   pattern
-
-  Request/Response
-
-  'AVxiiiiZ'     Volume
-  'AMxiiiiZ'     Mute
-  'AQQiiiiZ'     Query 
-
-  Response Only
-  'AVeiiiiE'     Volume Set Error 
-  'AMeiiiiE'     Mute Set Error 
-  'AEeiiiiE'     Unknown error 
-
-   e=1  Permission denied (invalid IP)
-   e=2  Invalid request (Bad Packet)
-   
-*/
-
-void message(char *m){
-  write(STDERR_FILENO,m,strlen(m));
-}
-
-void abortm(char *m){
-  message(m);
-  message("Errno = ");
-  message(strerror(errno));
-  message("\n");
-  exit(1);
-}
-
-struct in_addr multiaddr={0};
-
-int multicast(volmessage *m){
-  static int sockfd=-1;
-  static struct sockaddr_in dest;
-  int destlen=sizeof(dest);
-
-  if(sockfd==-1)
-    if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
-      abortm("Could not open multicast socket\n");
-
-  if(multiaddr.s_addr==0)
-    multiaddr.s_addr = inet_addr(MULTI_ADDR);
-      /*inet_aton(MULTI_ADDR,&multiaddr);*/
-
-  memset(&dest,0,sizeof(dest));
-  dest.sin_family=AF_INET;
-  dest.sin_addr.s_addr=multiaddr.s_addr;
-  dest.sin_port=htons(MULTI_PORT);
-
-  if(sendto(sockfd,m,MESSAGE_SIZE,0,(struct sockaddr *)&dest,destlen)<0){
-    message("Multicast send error\n");
-    return(1);
-  }
-  return(0);
-}
-
-int sockfd=-1,volfd;
-static struct sockaddr_in me,you;
-static int youlen=sizeof(you);
-struct in_addr multiaddr;
-
-int opensock(){
-  if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
-    abortm("Could not open listen socket\n");
-
-  memset(&me,0,sizeof(me));
-  me.sin_family=AF_INET;
-  me.sin_addr.s_addr=htonl(INADDR_ANY);
-  me.sin_port=htons(LISTEN_PORT);
-
-  if(bind(sockfd,(struct sockaddr *)&me,sizeof(me))<0)
-    abortm("Could not bind to listen port\n");
-
-  listen(sockfd,5);
-  return(sockfd);
-}
-
-/*  -1 blocks
-    0  nonblocking
-    +n timeout 
-*/
-
-int
-fetch (int usec, volmessage *m) {
-  fd_set fdset;
-  int retval;
-  struct timeval tv;
-  if(sockfd==-1)
-    opensock();
-
-  FD_ZERO(&fdset);
-  FD_SET(sockfd, &fdset);
-
-  tv.tv_sec = 0;
-  tv.tv_usec = usec;
-  retval = select(sockfd+1,
-		  &fdset, NULL, NULL,
-		  ((usec == -1) ? NULL : &tv));
-  if (retval == 1) {
-    /* Select got us a single descriptor to play with, as we
-     * expected. Pull a message from it. */
-    int youlen = sizeof(you);
-    retval = recvfrom(sockfd,
-		      m, MESSAGE_SIZE,
-		      0,
-		      (struct sockaddr *)&you, &youlen);
-    if(retval < MESSAGE_SIZE || m->A != 'A' || m->ZE != 'Z') {
-      message("Packet receive error\n");
-      return(0);
-    } else {
-      return(1);
-    }
-  } else {
-    if (retval == 0) {
-      /* This means the timeout finished. */
-    } else if (retval == -1) {
-      fprintf(stderr, "Select error. errno = %d (%s).\n",
-	      errno, strerror(errno));
-    } else {
-      fprintf(stderr, "Select returned unexpected value %d.\n", retval);
-    }
-    /* Whatever error we get, we just return 0. */
-    return(0);
-  }
-}
-
-
-int
-reply (volmessage *m) {
-  int retval;
-  assert(sockfd != -1);
-  
-  retval = sendto(sockfd,
-		  m, MESSAGE_SIZE,
-		  0,
-		  (struct sockaddr *)&you, youlen);
-  if(retval < 0){
-    message("Reply error\n");
-    return(1);
-  }
-  return(0);
-}
-  
-int vol_iterate(int newval){
-  static int val=0;
-  char command[100];
-  
-
-  if (val==newval)
-    return(0);
-
-  if (val<newval) {
-    val+=8;
-    if(val>newval)
-      val=newval;
-  } else {
-    val-=8;
-    if(val<newval)
-      val=newval;
-  }
-  sprintf(command,"/usr/bin/aumix -v %d",val);
-  fprintf(stderr,"Setting volume to %d\n",val);
-  system(command);
-  return(1);
-}
-
-int main(){
-  unsigned char volume=32,mute=0,ip_3=0,ip_2=0,ip_1=0,ip_0=0;
-  int messagestatus=1,volstatus=1;
-  volmessage m;
-
-  system("/usr/bin/aumix -v 0");
-  system("/usr/bin/aumix -i 100");
-  system("/usr/bin/aumix -l 100");
-
-  message("\nSIPB volume daemon running\n");
-
-  /* We want to process messages quickly, then get to the business of
-     controlling ther hardware when no messages are in the queue. 
-     The select on the message fetch also does our timing for volume
-     iteration */
-
-  while(1){
-    if(messagestatus==1)
-      /* Messages likely pending.  Process quickly */
-      messagestatus=fetch(0,&m);
-    else
-      if(volstatus==1){
-	/* No messages, but volume to be updated */
-	messagestatus=fetch(50,&m);
-	if(messagestatus==0)volstatus=vol_iterate(mute?0:volume);
-      }else{
-	/* Steady state.  Wait (almost) forever until a message */
-	m.ip_0=ip_0;
-	m.ip_1=ip_1;
-	m.ip_2=ip_2;
-	m.ip_3=ip_3;
-	m.A='A';
-	m.request='V';
-	m.value=volume;
-	m.ZE='Z';
-    	multicast(&m);
-	m.A='A';
-	m.request='M';
-	m.value=mute;
-	m.ZE='Z';
-    	multicast(&m);
-	messagestatus=fetch(400000,&m);
-      }
-
-    if(messagestatus){
-      int error=0;
-      m.ip_3=(ntohl(you.sin_addr.s_addr)>>24)&0xff;
-      m.ip_2=(ntohl(you.sin_addr.s_addr)>>16)&0xff;
-      m.ip_1=(ntohl(you.sin_addr.s_addr)>>8)&0xff;
-      m.ip_0=ntohl(you.sin_addr.s_addr)&0xff;
-
-      if(m.ip_3!=18 || m.ip_2!=OUR_SUBNET){
-	error=1;
-      }
-
-      switch(m.request){
-      case 'V':
-	if(error){
-	  m.value=error;
-	  m.ZE='E';
-	  reply(&m);
-	  message("Request from off subnet rejected\n");
-	}else{
-	  ip_0=m.ip_0;
-	  ip_1=m.ip_1;
-	  ip_2=m.ip_2;
-	  ip_3=m.ip_3;
-	  volume=m.value;
-	  reply(&m);
-	  multicast(&m);
-	  volstatus=1;
-	}
-	break;
-      case 'M':
-	if(error){
-	  m.value=error;
-	  m.ZE='E';
-	  reply(&m);	  
-	  message("Request from off subnet rejected\n");
-	}else{
-	  ip_0=m.ip_0;
-	  ip_1=m.ip_1;
-	  ip_2=m.ip_2;
-	  ip_3=m.ip_3;
-	  mute=(m.value?1:0);
-	  m.value=mute;
-	  reply(&m);
-	  multicast(&m);
-	  volstatus=1;
-	}
-	break;
-      case 'Q':
-	m.ip_0=ip_0;
-	m.ip_1=ip_1;
-	m.ip_2=ip_2;
-	m.ip_3=ip_3;
-	m.request='V';
-	m.value=volume;
-	reply(&m);
-	m.request='M';
-	m.value=mute;
-	reply(&m);
-	break;
-      default:
-	reply((volmessage *)"AE20000E");
-	break;
-      }
-    }
-  }
-}
Index: remctl/volume
===================================================================
--- remctl/volume	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,25 +1,0 @@
-volume set  /usr/lib/gutenbach/remctl/volume-set	 ANYUSER 
-volume get  /usr/lib/gutenbach/remctl/volume-get    ANYUSER
-volume show /usr/lib/gutenbach/remctl/volume-show   ANYUSER
-volume mute /usr/lib/gutenbach/remctl/volume-mute   ANYUSER 
-volume up   /usr/lib/gutenbach/remctl/volume-up     ANYUSER 
-volume down /usr/lib/gutenbach/remctl/volume-down   ANYUSER 
-volume is-muted /usr/lib/gutenbach/remctl/volume-is-muted   ANYUSER 
-
-v set  /usr/lib/gutenbach/remctl/volume-set    ANYUSER 
-v get  /usr/lib/gutenbach/remctl/volume-get    ANYUSER
-v show /usr/lib/gutenbach/remctl/volume-show   ANYUSER
-v mute /usr/lib/gutenbach/remctl/volume-mute   ANYUSER 
-v up   /usr/lib/gutenbach/remctl/volume-up     ANYUSER 
-v down /usr/lib/gutenbach/remctl/volume-down   ANYUSER 
-v is-muted /usr/lib/gutenbach/remctl/volume-is-muted   ANYUSER 
-
-v u /usr/lib/gutenbach/remctl/volume-up   ANYUSER
-v d /usr/lib/gutenbach/remctl/volume-down ANYUSER
-
-volume u /usr/lib/gutenbach/remctl/volume-up   ANYUSER
-volume d /usr/lib/gutenbach/remctl/volume-down ANYUSER
-
-volume help /usr/lib/gutenbach/remctl/volume-help ANYUSER
-v      help /usr/lib/gutenbach/remctl/volume-help ANYUSER
-help   ALL  /usr/lib/gutenbach/remctl/volume-help ANYUSER
Index: remctl/volume-down
===================================================================
--- remctl/volume-down	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-volume-set . $(( $(volume-get .) - 1 ))
Index: remctl/volume-get
===================================================================
--- remctl/volume-get	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
-channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
-
-amixer get $mixer | grep "$channel" \
- | perl -lne 'print $1 if (/: Playback ([0-9]+)/)'
Index: remctl/volume-help
===================================================================
--- remctl/volume-help	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,15 +1,0 @@
-#!/bin/bash
-PATH="$(dirname $0):$PATH"
-cat <<EOF
-Usage: remctl zsr.mit.edu <command> <subcommand> [..args..]
-Commands:
-  volume up        - increment volume
-  volume down      - decrement volume
-  volume get       - get volume
-  volume set [vol] - set volume, in range 0..31
-  volume mute      - zero volume
-  volume help,
-   help <anything> - print this help
-
-'v', 'u', 'd' abbreviate 'volume', 'up', 'down' respectively.
-EOF
Index: remctl/volume-is-muted
===================================================================
--- remctl/volume-is-muted	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,17 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
-channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
-
-volstat=$(amixer get $mixer | grep "$channel" \
- | perl -lne 'print $1 if (/: Playback .*\[(on|off)\]$/)'
-)
-
-case "$volstat" in 
-    on)  result=unmuted;;
-    off) result=muted;;
-    *)   result=unknown;;
-esac
-
-echo $result
Index: remctl/volume-mute
===================================================================
--- remctl/volume-mute	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,10 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
-channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
-
-amixer set $mixer toggle > /dev/null
-volume-is-muted
-
-volume-zephyr
Index: remctl/volume-set
===================================================================
--- remctl/volume-set	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,10 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
-channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
-
-amixer set $mixer "$2" | grep "$channel" \
- | perl -lne 'print $1 if (/: Playback ([0-9]+)/)'
-
-volume-zephyr
Index: remctl/volume-show
===================================================================
--- remctl/volume-show	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,7 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-
-mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
-channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
-
-amixer get $mixer
Index: remctl/volume-up
===================================================================
--- remctl/volume-up	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-volume-set . $(( $(volume-get .) + 1 ))
Index: remctl/volume-zephyr
===================================================================
--- remctl/volume-zephyr	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ 	(revision )
@@ -1,28 +1,0 @@
-#!/bin/sh
-PATH="$(dirname $0):$PATH"
-class=$(/usr/lib/gutenbach/gutenbach-get-config zephyr-class)
-host=$(/usr/lib/gutenbach/gutenbach-get-config host)
-queue=$(/usr/lib/gutenbach/gutenbach-get-config queue)
-instance="$queue-volume@$host"
-
-mixer=$(/usr/lib/gutenbach/gutenbach-get-config mixer)
-channel=$(/usr/lib/gutenbach/gutenbach-get-config channel)
-
-echo "Class: $class" >> /tmp/gutenbach-remctl.log
-echo "Host: $host" >> /tmp/gutenbach-remctl.log
-echo "Queue: $queue" >> /tmp/gutenbach-remctl.log
-echo "Instance: $instance" >> /tmp/gutenbach-remctl.log
-echo "Mixer: $mixer" >> /tmp/gutenbach-remctl.log
-echo "Channel: $channel" >> /tmp/gutenbach-remctl.log
-
-muted=$(volume-is-muted)
-mute_str=" [$muted]"
-if [ "$muted" = "unmuted" ]; then
-    mute_str=""
-fi
-
-start-stop-daemon --stop --oknodo --pidfile /usr/lib/gutenbach/gutenbach-zephyr >/dev/null 2>&1
-start-stop-daemon --start --pidfile /usr/lib/gutenbach/gutenbach-zephyr --make-pidfile --background --exec /bin/sh -- -c "sleep 10 && zwrite -c $class -i $instance -d -n -m 'volume changed to $(volume-get)$mute_str' > /dev/null" >/dev/null 2>&1
-
-echo "sleep 10 && zwrite -c $class -i $instance -d -n -m 'volume changed to $(volume-get)$mute_str' > /dev/null" >> /tmp/gutenbach-remctl.log
-echo "" >> /tmp/gutenbach-remctl.log
