RSS | technovelty home | page of ian | ianw@ieee.org
A recent post reminded me of a problem I once had; determine the glibc version and its support for various things.
There's actually a little known but useful confstr call defined for just this sort of thing. Here's a minimal example:
#include <stdio.h>
#include <unistd.h>
#include <alloca.h>
#include <string.h>
int main (void)
{
size_t n = confstr (_CS_GNU_LIBC_VERSION, NULL, 0);
if (n > 0)
{
char *buf = alloca (n);
confstr (_CS_GNU_LIBC_VERSION, buf, n);
printf("%s\n", buf);
}
return 0;
}
man confstr has all the details. If you don't need it in your program, you can also just run /lib/libc/so.6 and it will print out it's version info, e.g.
$ /lib/libc.so.6 GNU C Library stable release version 2.7, by Roland McGrath et al. Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled by GNU CC version 4.3.1 20080523 (prerelease). Compiled on a Linux >>2.6.24.4<< system on 2008-06-02. Available extensions: crypt add-on version 2.1 by Michael Glad and others GNU Libidn by Simon Josefsson Native POSIX Threads Library by Ulrich Drepper et al BIND-8.2.3-T5B For bug reporting instructions, please see: <http://www.gnu.org/software/libc/bugs.html>.
There's also another glibc trick that often comes in useful; the LD_DEBUG environment variable. Start with help and you can get more details from there.
$ LD_DEBUG=help ls Valid options for the LD_DEBUG environment variable are: libs display library search paths reloc display relocation processing files display progress for input file symbols display symbol table processing bindings display information about symbol binding versions display version dependencies all all previous options combined statistics display relocation statistics unused determined unused DSOs help display this help message and exit To direct the debugging output into a file instead of standard output a filename can be specified using the LD_DEBUG_OUTPUT environment variable.
posted at: Fri, 08 Aug 2008 13:51 | in /linux/tips | permalink | add comment (0 others)
I recently picked up the Netgear WG311 V3 very cheap from Office Depot.
The card seems to work fine with ndiswrapper; there are other guides on getting it working.
The first problem was the reception was, in a word, rubbish. After putting the box back in it's usual home the house wireless was lucky to get a 7/100 signal rating. I found a work-around while the cheap external antenna I ordered is arriving; shield the antenna with foil. This increased signal to between 30-40/100, a considerable boost making it actually useful.
The second problem was coming to terms with wpa_supplicant, of which the details often become very confusing very quickly. Here's the Debian 2-second guide for a simple, standard WPA network I was looking for:
iface wlan0 inet dhcp
# Useful with ifup -v
# wpa-debug-level 3
wpa-conf /etc/wpa_supplicant.conf
network={
ssid="your_ssid"
psk="your_password"
key_mgmt=WPA-PSK
proto=WPA
}
posted at: Sun, 06 Jul 2008 20:48 | in /linux/tips | permalink | add comment (0 others)
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!
posted at: Thu, 22 May 2008 16:29 | in /linux/tips | permalink | add comment (0 others)
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
posted at: Tue, 04 Mar 2008 21:51 | in /linux/tips | permalink | add comment (0 others)
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.
posted at: Tue, 29 Jan 2008 16:30 | in /linux/tips | permalink | add comment (0 others)
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.
posted at: Thu, 27 Sep 2007 11:46 | in /linux/tips | permalink | add comment (2 others)
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.
/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./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.remote_smtp_smarthost
(i.e the line that starts remote_smtp_smarthost:)
transport to have:
hosts_avoid_tls = localhosthosts_require_auth = localhostport = 465/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!
posted at: Fri, 22 Jun 2007 12:50 | in /linux/tips | permalink | add comment (10 others)
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...
posted at: Wed, 19 Jul 2006 14:16 | in /linux/tips | permalink | add comment (1 others)
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.
posted at: Thu, 30 Mar 2006 23:16 | in /linux/tips | permalink | add comment (1 others)
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.
posted at: Tue, 17 Jan 2006 17:01 | in /linux/tips | permalink | add comment (0 others)
Here's how I setup my wireless on Debian.
Firstly, create a script in /usr/local/bin called
wireless-mapping or something similar. Make sure the
dialog package is installed.
#!/bin/bash
if [ -f /etc/default/wireless ] ; then
. /etc/default/wireless
else
echo Please setup /etc/default/wireless
fi
for profile in $WIRELESS_PROFILES
do
LOCATION_NAME=$profile\_NAME
LOCATION_DESCR=$profile\_DESCR
DIALOG_ARGS="$DIALOG_ARGS \"${!LOCATION_NAME}\" \"${!LOCATION_DESCR}\""
done
LOCATION=`eval dialog --stdout --menu \"Select your wireless location\" 10 50 5 $DIALOG_ARGS`
echo eth2-$LOCATION
Then create a file /etc/default/wireless where you put
descriptions of your wireless networks. Put each of your networks in
WIRELESS_PROFILES and then setup a name and a
description, like below.
#WIRELESS OPTIONS WIRELESS_PROFILES="home keg nicta" home_NAME="home" home_DESCR="At home" keg_NAME="keg" keg_DESCR="keg private" nicta_NAME="nicta" nicta_DESCR="nicta (hack)"
Finally, you need to make the mapping in
/etc/network/interfaces for each network. It should look
something like this.
mapping eth2
script /usr/local/bin/wireless-mapping
iface eth2-keg inet dhcp
wireless-essid keg
wireless-key [key]
iface eth2-home inet dhcp
wireless-essid wienand
wireless-key [key]
iface eth2-nicta inet dhcp
wireless-essid nicta_wireless
Notice how the mapping for your ethernet card is the script, and
then you have a bunch of interfaces defined as
interface-name, where name is the name you chose in the
/etc/defaults/wireless script.
All going well, next time you ifup eth2 you should see
something like this
posted at: Sat, 24 Dec 2005 15:25 | in /linux/tips | permalink | add comment (0 others)
More from the "things you'd learn if you read the manual"
department, although the manual as currently written is a little
esoteric on this feature of hexdump.
$ hexdump -e ' [iterations]/[byte_count] "[format string]" '
As you might guess, this means apply format string to
groups of byte_count bytes, iterations times.
Format string is like printf.
You can of course chain multiple formats together, or put them in a file. So say you needed to clag some binary data into a C array, a-la firmware for loading into a driver. You could use
$ hexdump -v -e '6/4 "0x%08x, "' -e '"\n"' ./dump
to get something that fits in 80 columns and is almost ready to go.
posted at: Tue, 13 Dec 2005 15:46 | in /linux/tips | permalink | add comment (1 others)
If your laptop hard disk is so slow it sometimes seems like it
would be faster to write the ones and zeros with a pencil on paper, a
large apt-get update can take hours.
I have found most of the time is actually spent in
/sbin/ldconfig. ldconfig is extremely disk
intensive and a real bottle neck, and really only needs to be run once
once you've finished, rather than every time a library is installed.
Replacing ldconfig with a stub makes update times much
more tolerable.
#!/bin/bash exit 0
I think there has been some talk of apt being smart
enough to only do it once for you, but current versions don't seem to
implement this. When you're finished restore the old (real) binary
and run it to update your shared library cache.
posted at: Mon, 10 Oct 2005 16:43 | in /linux/tips | permalink | add comment (0 others)
I might be a bit slow, but I finally figured out how to get a decent font (i.e. not anti-aliased) for gnome-terminal on Debian.
xfonts-100dpi is installeddpkg-reconfigure fontconfig and answer
yes to the question about bitmapped fonts.Desktop->Preferences->Fonts
the ability to select the Fixed font.gnome-terminals. The font may look a
little weird before you do that.Update: it appears I'm not the only one who doesn't like the fuzzy fonts in my terminal.
Davyd Madeley suggested that rather than enabling bitmapped fonts
you can just enable a single font with fontconfig. He
gives this
example (place it in /etc/fonts/conf.d).
He suggested
There was an issue of it choosing extra wide fonts sometimes. You can fix this by copying the version of Fixed you want (eg. 7x13.pcf.gz) into your ~/.fonts directory.
James Ballantine suggested copying the font as well, although for some reason his Firefox started to choose bitmapped fonts after following the above steps.
I can't really understand why, as it appears that bitmapped fonts are enabled by default on Debian; at least in my fontconfig package we have in the post-install script
case "$enable_bitmaps" in
"true")
#
# Bitmap fonts will be enabled by default, so there's no need
# to use this configuration file. However, the file remains useful if
# you want to force bitmaps to be considered even when some application
# disables them.
#
# ln -s $CONFDIR/$yes_bitmaps $CONFDIR/$bitmaps_prio$yes_bitmaps
;;
*)
ln -s $CONFDIR/$no_bitmaps $CONFDIR/$bitmaps_prio$no_bitmaps
;;
esac
So the dpkg question is at least badly worded, but I haven't yet
decided if this is a bug. Probably the only thing I did was install
the xfonts-100dpi package which gave me the bitmapped
fonts.
Any other feedback is appreciated.
posted at: Thu, 15 Sep 2005 13:07 | in /linux/tips | permalink | add comment (2 others)
After looking at some shell scripts today it seems the very handy
pushd and popd aren't used enough in the
wild.
If you're just popping into a new directory for a moment to do
something, then want to return to the directory you came from, use
pushd newdir; it will push the current directory to the
top of the directory stack (actually the DIRSTACK
environment variable) and cd you there.
When you're done, use popd to go back to where you
came from. Obviously you can keep pushing onto the stack and nest
your directory changes deeper. Never again shall you need to manually
remember $PWD!
ianw@lime:~$ pushd /tmp /tmp ~ ianw@lime:/tmp$ echo do something in /tmp do something in /tmp ianw@lime:/tmp$ popd ~ ianw@lime:~$
posted at: Wed, 07 Sep 2005 15:37 | in /linux/tips | permalink | add comment (0 others)

This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.