Sending arbitrary keys through xtightvnc

Although it's not particularly clear, a neat feature of xtightvnc is the ability to modify the pop-up menu that appears when you press F8 to send arbitrary keystrokes.

The trick is overriding some of the X11 resources of the file. If you have a look in /etc/X11/app-defaults/Vncviewer (make sure you have a recent package) you can see the default keybindings for the popup menu, which are a good template. Assuming you want to keep them all, you can add your own buttons by starting at button 9 and re-defining the total button count in your ~/.Xresources:

xtightvncviewer*popupButtonCount: 11

xtightvncviewer*popup*button9.label: Alt-F1
xtightvncviewer*popup*button9.translations: #override\n\
                                            <Btn1Down>,<Btn1Up>: \
                                            SendRFBEvent(keydown,Alt_L) \
                                            SendRFBEvent(keydown,F1) \
                                            SendRFBEvent(keyup, F1) \
                                            SendRFBEvent(keyup, Alt_L)

xtightvncviewer*popup*button10.label: Alt-F2
xtightvncviewer*popup*button10.translations: #override\n\
                                            <Btn1Down>,<Btn1Up>: \
                                            SendRFBEvent(keydown,Alt_L) \
                                            SendRFBEvent(keydown,F2) \
                                            SendRFBEvent(keyup, F2) \
                                            SendRFBEvent(keyup, Alt_L)

xtightvncviewer*popup*button11.label: Alt-F12
xtightvncviewer*popup*button11.translations: #override\n\
                                            <Btn1Down>,<Btn1Up>: \
                                            SendRFBEvent(keydown,Alt_L) \
                                            SendRFBEvent(keydown,F12) \

Make sure you merge this with xrdb -merge ~/.Xresources if you don't want to bother logging out and in. This way I can easily send Alt-F1, etc. through to the other side; useful for things like switching virtual terminals in VMware workstation running remotely. I imagine if you were insane you could do all sorts of other tricks too!

Forwarding VNC via ssh, or finding the PID of a running ssh

I found a few people asking how to automate scripts using ssh with the -f option but not many solutions. Th -f option makes the ssh process fork into the background once started, but since it doesn't give you it's PID it becomes hard to kill it once the script ends.

The solution is to setup a control channel with -M. This allows you to communicate to the ssh process and close it down when your process finishes. For example, here is how I open a VNC connection to my desktop at work, which involves going through a corporate ssh firewall box.

ssh -M -S /tmp/vncssh-firewall.ctl -L 2022:desktop.internal.company.com:22 -f -N username@firewall.company.com
ssh -M -S /tmp/vncssh-localhost.ctl -N -p 2022 -L 5901:localhost:5901 -f -N username@localhost
xtightvncviewer -encodings tight localhost:1
ssh -S /tmp/vncssh-firewall.ctl -O exit localhost
ssh -S /tmp/vncssh-localhost.ctl -O exit firewall.company.com

A cool laptop

Or, a modern guide to CPU frequency scaling with Linux. Having setup my laptop long ago, I had a strange hybrid of daemons running all trying to scale the frequency of my laptop periodically based on a myriad of different situations. Having decided to fix this, it appears the simplest approach is, as usual, the best.

The way of the future appears to be to let the kernel do all the work with the ondemand govener. The cpufrequtils Debian package will arrange this for you on boot and by default should just work, although you can of course tweak parameters like minimum speed to decrease to and so forth. You can use the cpufreq-set utility to fiddle with settings, or just go into /sys/devices/system/cpu/cpuN/cpufreq/ to tweak them by hand. The many available daemons (cpufreqd, powernowd, etc.) appear to be largely redundant and are probably best removed.

This dropped the temperature of my laptop about 10 degrees C and, apart from a much cooler lap, is so far imperceptible.

The stamp idiom with make

Sometimes you need direct make to progress through various phases which may not have a particular file target associated with them. For example the first step might be to extract a compressed tarball of data and run a script over it in preparation for compiling that data into something else. Equally you might need to patch some files or maybe download some data. The general idiom to accomplish this sort of thing is the stamp file.

The general principle is to make a phony target that depends on a file called target-stamp. The target-stamp target can then do what it needs to do and simply create a dummy file via touch. This file indicates to make that the phase is complete, and targets that depend on this phase being complete can now depend on the stamp file. A small example follows

all: final

.PHONY: prepare clean

final: prepare
        # run build process

prepare: prepare-phase1-stamp prepare-phase2-stamp

prepare-phase1-stamp:
        # untar data or something
        touch $@

prepare-phase2-stamp: prepare-phase1-stamp
        # run a script or do something else
        touch $@

clean:
        rm -f *-stamp

One place you may notice extensive use of this is the -stamp files in the /debian directory of packages built with CDBS.

exim4 with ssmtp on Debian

Update: You need to be careful if you are updating to the latest Debian Exim (~4.67), since the Debian config file format has changed slightly. I'm pretty sure this whole thing could be easier, so I have filed #430057. Instructions below updated slightly.

Sending secure mail seems to have two possible implementations; firstly you can connect over an insecure channel and issue a command (STARTTLS) which tells the SMTP server to start a secure channel. The other option is where you use a secure channel to start with. Usually this happens with an SSL (TLS) connection on port 465 which you then probably have to authenticate over.

Exim doesn't support this second model, seemingly by design. Which is a little annoying if that's all your ISP offers! You may like this on your laptop, since by authenticating you should be able to send email from anywhere through the ISP mail server.

What you need is a wrapper that provides the SSL connection between your computer and the ISP. Then you have to fool exim into using it, and direct it to send passwords unencrypted (though the underlying channel is safely encrypted).

Firstly, install stunnel; I found stunnel4 didn't work that well. Then create a script to start it and make a tunnel to your ISP. Put the following a file /etc/init.d/ssmtp-tunnel (change to your ISP's secure email server) and then run update-rc.d ssmtp-tunnel defaults (and start it with /etc/init.d/ssmtp-tunnel start).

#! /bin/sh -e

case "$1" in
  start)
    echo -n "Starting ssmtp tunnel "
    start-stop-daemon --start --quiet --exec /usr/sbin/stunnel -- -c -d ssmtp -r securemail.internode.on.net:ssmtp
    echo "stunnel."
    ;;
  stop)
    echo -n "Stopping ssmtp tunnel "
    start-stop-daemon --stop --quiet --oknodo --retry 2 --exec /usr/sbin/stunnel
    echo "stunnel."
    ;;
  restart)
    $0 stop
    sleep 1
    $0 start
    ;;
  *)
    echo "Usage: /etc/init.d/ssmtp-tunnel {start|stop|restart|reload|force-reload}"
    exit 1
esac

exit 0

If you telnet localhost 465 and see a normal SMTP connection, which is running over SSL, you have things working correctly.

Now you need to configure exim to use this to firstly authenticate, then send the email onto the smarthost.

Make sure you're using the big config file option with dpkg-reconfigure exim4-config. When it asks you what the smarthost should be, tell it localhost.

  • Firstly create the file /etc/exim4/exim4.conf.localmacros (if it doesn't already exist) and add a line AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS = true. This forces using authentication even though it looks like an unencrypted channel.

  • Then in /etc/exim4/exim4.conf.template, under the smarthost router (i.e. the line that starts smarthost:) add self = send. This allows what exim thinks is a router to an external MTA to actually go back to the localhost.

  • In the same file change the remote_smtp_smarthost (i.e the line that starts remote_smtp_smarthost:) transport to have:

    • hosts_avoid_tls = localhost
    • hosts_require_auth = localhost
    • port = 465

    (all on separate lines).

  • Add a line to /etc/exim4/passwd.client for localhost with your ISP username/password (or just use * if this is the only entry).

Finally, update the config file with update-exim4.conf and restart exim /etc/init.d/exim4 restart. All going well, Exim will now get the mail out wherever you are!

Getting a tick in LaTeX

So you need to show something is good in your LaTeX document, and want a tick (or a cross)? The pifont package gives you access to ZapfDingbats, which has lots of neat characters as shown in the documentation (along with dinglists and other nifty features).

So, after \usepackage{pifont} a quick \newcommand{\tick}{\ding{52}} gives you \tick for all your ticking needs!

The MarvoSym package also has some Winding type things, like laundry instructions (?).

file this under the "easy when you know how but otherwise takes you at least half an hour" category...

xfig and colours

User defined colours in xfig are per file. To get a decent selection of colours, a good way is to have the xfig-libs package installed and import one of the complex example pictures from the library. This way you get all its colours. But be careful; these colours can make it into exported postscript and cause your interpreter to really crawl.

This tip courtesy of Charles Gray, who is currently in the process of obtaining a PhD in xfigology.

How to cancel a pending CVS remove

If you accidently locally do cvs rm on a file and want it back (and you haven't committed, of course), just cvs add it and it will restore the latest version.

The trick is to not copy back the missing file and try to add that, otherwise you'll get an error about how the file should be removed and is still there (or is back again). If you have a later version of file you are trying to resurrect move it back after you do the (re)``add``.