How to get Ctrl+Arrow working for programs running in tmux?

The key combination of Ctrl+arrow key is often used for skipping forward or backward whole words. This can be used in the bash command line, Emacs and many other programs. However, when I am using tmux, this will not work. You can fix this, by adding the following to your ~/.tmux.conf:

set-window-option -g xterm-keys on
This was explained in a nice superuser Q&A.
You can interactively try out tmux commands by hitting C-b : — this will enter the command mode. You can use tab to complete commands.

How to make the mpdas run as a daemon

The other day I installed the mpdas, which is the audio scrobbler for the music player daemon. Since there’s no debian package for the Raspberry Pi, I compiled mpdas from scratch and installed it. Now I don’t want to run it manually each time the Raspberry Pi boots up. So I found a nice template for writing your own debian-style init-script. I changed it a little and also installed the daemon tool, to turn the interactive mpdas program into a daemon. Just run apt-get install daemon to install it. Then put the following file under /etc/init.d/mpdas and run update-rc.d mpdas defaults. Then mpdas will be run automatically upon boot. Oh, one more thing: put your mpdas configuration under /usr/local/etc/mpdasrc or adjust the DAEMONOPTS in the init script accordingly.


#!/bin/bash
### BEGIN INIT INFO
# Provides: mpdas
# Required-Start: $remote_fs $syslog $mpd
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: true
# Short-Description: Audio Scrobbler for mpd
# Description: Starts the Audio Scrobbler for the mpd music player daemon.
### END INIT INFO

DAEMON_PATH="/usr/bin/"

DAEMON=daemon
DAEMONOPTS="-u pi -r -X /usr/local/bin/mpdas"

NAME=mpdas
DESC="The mpdas audio scrobbler for mpd"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

case "$1" in
start)
printf "%-50s" "Starting $NAME..."
cd $DAEMON_PATH
PID=`$DAEMON $DAEMONOPTS > /dev/null 2>&1 & echo $!`
#echo "Saving PID" $PID " to " $PIDFILE
if [ -z $PID ]; then
printf "%sn" "Fail"
else
echo $PID > $PIDFILE
printf "%sn" "Ok"
fi
;;
status)
printf "%-50s" "Checking $NAME..."
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
printf "%sn" "Process dead but pidfile exists"
else
echo "Running"
fi
else
printf "%sn" "Service not running"
fi
;;
stop)
printf "%-50s" "Stopping $NAME"
PID=`cat $PIDFILE`
cd $DAEMON_PATH
if [ -f $PIDFILE ]; then
kill -HUP $PID
printf "%sn" "Ok"
rm -f $PIDFILE
else
printf "%sn" "pidfile not found"
fi
;;

restart)
$0 stop
$0 start
;;

*)
echo "Usage: $0 {status|start|stop|restart}"
exit 1
esac

How to turn the Raspberry Pi into a music server

I have set up my Raspberry Pi as a music and file server. My requirements were:

  • Big local storage (HD), shared over WiFi
  • Local music playing capability, remotely controllable
  • AirPlay speaker capability
The means by which I fulfilled the requirements were:
  • Platinum 1TB MyDrive and Edimax EW-7711UTn USB wireless adapter
  • mpd Music Player Daemon
  • shairport AirPort emulator
For the first part, I bought a WiFi adapter, the Edimax EW-7711UTn. This one works out of the box with Raspbian, using WPA encryption (Note: I switched to a RTL8188 based dongle by now). It identifies itself with lsusb as:
Bus 001 Device 004: ID 7392:7711 Edimax Technology Co., Ltd EW-7711UTn nLite Wireless Adapter [Ralink RT2870]
This can be easily configured using the wpa_gui tool that comes with the default Raspbian installation. Settings will be saved and restored upon reboot.
Second, I installed samba, samba-common and samba-common-bin for sharing my USB drive. The latter one is a Platinum MyDrive, which is attached to a powered Belkin 7-port USB hub, so that I only need two power supplies. One for the Raspberry Py, and one for the Hub and its attached devices. The MyDrive has been formatted with NTFS, so as to be easily mountable under Linux, OS X and Windows. I mount it using the standard /etc/fstab mechanism. Just added one line to the file:
/dev/sda1       /media/MyDrive  ntfs-3g defaults          0       0
The /etc/samba/smb.conf gets in its first iteration only one additional share, a write-for-all public share, as a big file dump: 
[BigDump]
    comment = Free for all
    read only = no
    path = /media/MyDrive/FreeForAll
    guest ok = yes
Note that literally everybody in your LAN can access this and write to it! You may want to fine tune this…
Now to the mpd. It is easily installed by doing apt-get install mpd. When configuring it via /etc/mpd.conf make sure to change the following lines:
music_directory         “/media/MyDrive/Music/”
password                “MyVeryOwnPassword@read,add,control,admin”
bind_to_address         “any”

Change the directory and password to your liking. Then restart the service or reboot you device. You can control the mpd using a magnitude of clients. For example Theremin for OS X or Mpod for iOS.
Finally, I would like to be able to use the RasPi as an AirPlay target for my Mac and my iOS devices. This can be done via shairport. There are already a lot of good howtos for shairport on the Raspberry Pi. So I refer you to one of those. Two things come to my mind, though:
  1. The Net::SDP library, required by shairport, is not available on Raspbian by default. It is best to clone the github mirror, and go by its installation instructions. Installation via CPAN fails, plus CPAN needs huge amounts of RAM.
  2. The configuration needs to be tweaked a bit. The /etc/init.d/shairport script should be tuned to a sensible name for your RasPi. 
This way, you will be able to see the RasPi in your AirPlay speakers list and it will be happily churning along.

Quoting a set of parameters for program arguments using sed

I have a script which launches another program. That program takes some command line arguments, which in turn can have parameters. Those parameters may include “;”, which has a special meaning in the Bash. To quote these, you can use the following sed command:

$ echo "foo --bar=1 --baz=2" | sed -e 's/(--[^[:space:]]*=)([^[:space:]]*)/1"2"/g'
foo --bar="1" --baz="2"

Setting the sender of git post-receive hooks

There is a nice stackoverflow posting about how to set the sender of git post-receive hooks. I used this, slightly augmented:

#!/bin/sh

# Use the name and email address of the author of the last commit.
USER_EMAIL=$(git log -1 --format=format:%ae HEAD)
USER_NAME=$(git log -1 --format=format:%an HEAD)
. $(dirname $0)/post-receive-email

I then also changed the default post-receive-email script, to look like this in the send_mail() function:

send_mail()
{
if [ -n "$envelopesender" ]; then
/usr/sbin/sendmail -t -f "$envelopesender"
else
/usr/sbin/sendmail -t -F "$USER_NAME" -f "$USER_EMAIL"
fi
}
This will let the emails come from the last user in the git log. This is only a hack, and might break or not make sense under certain circumstances, but is good enough for most of my needs.

Migrating from GMX IMAP to MobileMe IMAP

I am currently migrating my >4GiB of mail data from GMX to MobileMe. I have been using offlineimap regularly to backup my mail data. So first step was to update the backup. Now the next step is to run imapsync, which can migrate whole IMAP accounts. The full command I am using for this is:

imapsync –sep1 ‘/’ –prefix1 ”  –ssl1 –ssl2 –authmech1 PLAIN –authmech2 PLAIN –host1 imap.gmx.net –user1 “yourname@gmx.de” –host2 mail.me.com –user2 “yourname@me.com”

I will report back once the sync has finished, this might take a while.

Update: Yup, it worked. My mail is now hosted on MobileMe. More disk space. What is missing at MobileMe is that it does not support automatically expiring mail folders. I.e. for mailing lists, I sort the mails into subfolders for each list. The lists are often high volume traffic, and not very important. So I’d like the mails to expire after, say, 30 days. With GMX this was not a problem, but MobileMe does not yet have such a feature. However, I found a nice tool called imapfilter. It allows you to do all kinds of stuff, besides other things it allows you to filter mails according to date and to delete them. This is what I will do. I’ll write another post, when I found out how to do that exactly.

Redefining quit-char in Emacs 23

The quit command C-g is pretty much standard in Emacs. It runs the interactive function keyboard-quit and also serves as the default quit-char. It aborts basically every running function, also it allows you to cancel operations in the minibuffer. The Emacs documentation describes current-input-mode, set-input-mode and set-quit-char for getting and setting the quit-char value. Also, global-set-key allows you to rebind keyboard-quit to another character. However, this does not work very well. The quit-char is not settable for non-tty Emacs versions, e.g. on OS X using Cocoa Emacs you get this:

So, basically nothing changes. On a tty it looks more promising:

After rebinding the keyboard quit as well, using (global-set-key (kbd “C-q”) ‘keyboard-quit), not much happens either. It seems the minibuffer assumes C-g to be the choice of the day. Running find-file with C-x C-f or interactively via M-x find-file, and then hitting C-q does nothing except printing “Quit”. Hitting C-g however quits the minibuffer. This seems to be documented in Bug #1218 of Emacs.

Arrow keys broken for console applications in OS X 10.6.3

I was just trying to configure some project using the curses based ccmake tool. I noticed that I cannot do that, since the arrow keys on my keyboard stopped responding when running ccmake. Turns out, Apple broke curses in OS X 10.6.3. Workaround is to copy the ncurses dylib from a 10.6.2 system, which I don’t have at hand right now. Funny enough, the keys are also broken when using xterm instead of the standard terminal, so there is definitely something very broken in ncurses right now.

Setting PATH and other variables on OS X

Since OS X is a UNIX like many others, I usually put my environment variable settings like PATH in ~/.profile. However, for Cocoa based apps, that are not run from a terminal, this will not help. Luckily, there is a documented procedure for setting environment variables for Cocoa applications. In short, you just have to edit a plist. If it already exists on your system, just type the following in a terminal:

open ~/.MacOSX/environment.plist
If the file does not yet exist, just run the Property List Editor (e.g. via spotlight), and create that folder and that file.