Installing Splint on Mac OSX

Splint is a really useful utility to check your source code, but it doesn’t seem to be installed by default on MacOS X. It is not too difficult to download the source and install except for the minor issue that it doesn’t build. The good news is it doesn’t take much to fix the build problem. Here are the instructions.

  1. Download the source from http://www.splint.org/downloads/splint-3.1.2.src.tgz
  2. Open the .tgz file by double clicking.
  3. Open a terminal window and cd to the splint-3.1.2 folder
  4. Configure by using sudo ./configure and enter your password
  5. Open the osd.c file using nano src/osd.c
  6. Scroll down to around line 500 and change the line __pid_t pid = getpid (); to pid_t pid = getpid (); then save the file (control-x).
  7. Type sudo make install to install splint

You should now be able to use splint (eg splint foo.c) and have a look at how many little issues are in your code :) It will fail a few of the tests, but it appears to still work.

Edit Sept 2017. This is a pretty old post. My advice is use brew to install splint.

Removing large numbers of duplicate emails from Mac OSX Mail

I was faced with the problem of having duplicate emails in some of my very large folders in Mail (some of my mail boxes have over 80,000 messages). There are applescripts for finding and removing duplicate messages, but they are very slow (~100 messages a minute) and so are not really viable on very large mail boxes – at this rate it would take more than 5 days to process one of my large email folders.

One simple solution is to archive the mailbox and then use formail to strip out the duplicate messages, then importing the cleaned mbox back into Mail. This approach retains all the meta information like flags and attachments and is actually quite fast. The basic procedure is:

1. Rebuild the mail box. This is probably a good idea anyway.
2. Archive the mail box. This will save a copy of your mailbox in standard mbox format which then formail can process.
3. Open a terminal window and cd to the folder containing the new mbox archive.
4 . Run the following formail command. This will create a copy of the mbox (mbox_new) with the duplicate messages removed. This will take around 5 minutes to process 80,000 messages.
formail -D 100000000 idcache < mbox -s > mbox_new
5. Open Mail and Import Mailboxes. Select the mbox_new mbox. Once it finishes importing you will now have a new folder under Import with all the non-duplicate messages. It is a good idea to rebuild the folder before moving it back to where you want.
6. Delete the archive.

This approach is much,much faster and has the advantage of working on a copy of your email data so if anything goes wrong you won’t mess up your current mailboxes.

Root privilege scripts from Apache

If you have a script that needs to access functions that can only be run as root (e.g. chmod, chgrp, mkdir, etc) you will find that you can’t call these directly since the Apache user is not root (at least it should not be root). There is no perfect solution around this as all solutions involve some security risk, but the least bad seems to be to use sudoer to grant root privileges to the script and then lock down the script so nobody other than root can modify the script.

First chmod the script so that anyone can execute it, but nobody other than root can modify it (I am assuming here that you are logged in as root, otherwise sudo).

chmod 111 /home/path_to_script

Next modify sudoer using visudo. It is a good idea to use visudo so that any change you make are updated without having to restart sudo.

# visudo

Add the following line after the root entry in sudoer

apache_user ALL = NOPASSWD: /home/path_to_script

Change the apache_user to whatever your apache user is (e.g. nobody) and then add the path to your script. You might want to add your favorite editor (mine is nano) to your export in .bashrc. You should now be able to call your script from apache without problem.

Update. Make sure that you have commented out the Defaults requiretty line in visudo or else the script won’t be run by Apache. This problem wasted a couple of hours of my time since the script would run fine from the bash shell of the apache user, but not when called by apache. I finally took a look at the log file (yes I should have done this first) and there was the problem sudo: sorry, you must have a tty to run sudo!

Mac OS X compatible external web camera

I use my macbook with an Apple 23 inch monitor at work and so I can’t use the inbuilt iSight camera. Since Apple stopped selling the external iSight camera there is not much choice for Apple compatible web cams since most of the web cameras on the market don’t come with Mac OS X drivers.

One surprisingly option is the xbox360 web cam. This external usb camera works without any drivers and just plugs straight in and works. I managed to pick up a brand new one on eBay for A$35. The quality is pretty good and it sits without any problems on top of my monitor. Nice work microsoft.

Adding iso repository under XenServer 5.5

If you want to install an OS from a local repository under XenServer 5.5 then you need to do the following. The documentation on how to do this in the xenserver manual is incomplete.

first ssh into the xenserver
mkdir -p /var/opt/xen/iso_import
Copy your ISO images to the /var/opt/xen/iso_import directory using scp.
Create a repository with this command:
xe sr-create name-label=ISOs type=iso device-config:location=/var/opt/xen/iso_import device-config:legacy_mode=true content-type=iso
You then need to attach the ISO library with this command (nicely not mentioned in the citrix documentation)
xe-mount-iso-sr /var/opt/xen/iso_import

You should then be able to create a VM using the .iso

Apple Bootcamp 2.1 and Windows XP SP3

There is a problem with Bootcamp 2.1 in that you can’t install the Apple drivers under Windows XP SP3. I recently bought a new MacBook Pro and installed Windows XP SP3 from an image and then tried to update the XP hardware drivers using bootcamp 2.1. This didn’t work an instead gave a nice cryptic error 2762. It seems it is not possible to install the drivers manually either as windows can’t install the drivers for the wireless network, iSight camera, and trackpad.

The solution is to install XP from a SP2 image (luckily I had kept one), then install the drivers, and then upgrade to SP3. I hope this saves someone a bit of time.

Update. This has apparently been fixed in snow leopard. I guess another reason to update.

How to get total folder / directory size with Linux

If you want to know how much disk space is being used by a directory (including all the sub-directories) then you can use the following command. It will output a single number in human readable form (eg 8.2G). I have found this very useful for finding where all my disk space has gone.

du -h | grep -v '/' | awk '{print $1}'

X11 ssh-forwarding of a gnome-session to Mac OS X 10.5

If you want to X11 ssh-forward a gnome-session on a remote linux server to MacOS X Leopard there seems to be some bug in the 10.5 X11 that causes the gnome desktop to take over the whole screen and you can’t access the session. The solution is to open the gnome-session using Xnest instead. This opens the session in a small X11 window (1024×768 in the example below).

Xnest -geometry 1024x768 :1&amp; DISPLAY=:1 ssh -X &lt;HOST&gt; gnome-session

Random PHP string

I needed to generate a random string in php that did not repeat. This little snippet will generate a random non-repeating 32 character string.

// Generate random 32 character string
$string = md5(time());

IE 6 javascript onchange() problem

I really hate IE6, but as it is still so common it is important to support it. I recently ran into a problem with the javascript onchange function. I was using onchange to update a text box on the page when the check box was selected. I was using “…onchange(this.checked)…” This worked fine for everything except IE6. It turns out that IE doesn’t fire the onchange state until the checkbox loses focus and so my update was not occurring.

The simple way around for this problem was to change onchange() to onclick(). The function now works in all browsers.