Syncing contacts with Google in Mountain Lion

I just installed Mountain Lion on my MacBook but I couldn’t work out how to set up synchronisation of the contacts stored on my Google account as this seemed to be left out of the Google synchronisation options:

Google syncing seems to be missing contacts
Google syncing seems to be missing contacts

I tried adding an exchange account in the same way you achieve push email and contact synchronisation from Google on the iPhone, but there didn’t seem to be an option to enable SSL so this didn’t work (fix this Apple!).

Trying to add the Google Exchange Server but there's no SSL option
Trying to add the Google Exchange Server but there’s no SSL option!

Finally I opened up the Contacts application and went to the account settings and there (somewhat randomly in my opinion), under the “On My Mac” account, is an option to sync with Google.

Google contacts sync at last
Google contacts sync at last

Seems Apple don’t really want you syncing your contacts with Google.

Subsonic and a Raspberry Pi

Subsonic is great, it automatically transcodes audio and (HD) video files on the fly and either streams them using a Flash player or serves up the raw stream for playback in an independent video player. I recently got a Raspberry Pi and immediately loaded it up with Sam Nazarko’s Raspbmc, a linux distro specially designed to run XBMC perfectly on the Raspberry Pi. With XBMC running, I modified t0mm0’s subsonic audio plugin to provide more appropriate bitrate options for video (you can find this here). With this done, I was able to stream films from my Subsonic server to my Raspberry Pi! If you’re struggling to get this setup working (I did) it’s important to note that it only works with the latest Beta version of Subsonic (4.7.beta2 at the time of writing), as HEAD requests were broken before.

By default Subsonic transcodes video using ffmpeg. Unfortunately this means that subtitles aren’t carried through, so if you’re watching a foreign language film you’re left rather clueless. After some investigation I found that it was possible to encode subtitles into the video during the transcoding process by using mencoder, however, setting up mencoder is a bit challenging. I found a script which was supposed to be an easy way to set this up but after further examination I found that a lot of the mencoder arguments had changed since the script was written and that it did not support subtitles stored in mkv files.

After much fiddling I eventually found the new arguments needed for mencoder and added support for subtitles in mkv files. The updated script can be found here. As with the other script, the steps to install it are:

  1. Install mencoder (apt-get install mencoder)
  2. Copy the script to /var/subsonic/transcode/
  3. Create a symlink to mencoder in the same directory (ln -s /usr/bin/mencoder /var/subsonic/transcode/mencoder)
  4. Create the folder /var/subsonic/pipes
  5. Set up a transcoding setting in Subsonic with the “Step 1″ setting as
    mencoder_hook.pl %o %s %bk %w %h

The script uses the “superfast” x264 preset to support the largest range of hardware but I found my server was fine using the “fast” preset giving better video quality.

Update: This method of adding subtitles only works when streaming to XBMC because there is currently a bug in mencoder causing output files muxed using libavformat to be corrupt and only readable by mplayer. XBMC uses mplayer so is able to play the files, but the Subsonic flash player does not, hence the black video.

Jailbreaking and unlocking an iPhone 3G with a broken power/sleep button

Recently my flatmate was given a hand-me-down iPhone 3G. Unfortunately the phone had two problems meaning she couldn’t use it:

  • Locked to O2 – My flatmate has a contract with Vodafone
  • Broken Power/Sleep button

To get around this I initially thought it was as simple as jailbreaking the phone, installing Activator to get around the broken sleep button, and then using ultrasn0w to unlock.

Getting into DFU Mode

It then dawned on me that because the iPhone was at firmware 4.2.1, it could only be jailbroken using a custom firmware flashed through “pwned” DFU mode. Normally to access DFU mode you perform a specially timed series of button presses using the menu and sleep button. This was obviously not possible due to the broken sleep button.

After googling around for some time I stumbled across a blog post which demonstrated how it was possible to get into DFU mode by corrupting the LLB file in a vanilla firmware file.

To do this you’ll need a Mac or Linux VM (if on Windows).

  1. Grab the vanilla 4.2.1 firmware: here
  2. Unzip the LLB file
    unzip -x iPhone1,2_4.2.1_8C148_Restore.ipsw  */LLB*img3
  3. Corrupt some bytes at offset 0x240 (whilst maintaining the file size):
    dd if=/dev/urandom of=Firmware/all_flash/all_flash.n82ap.production/LLB.n82ap.RELEASE.img3 bs=16 count=10 seek=36 conv=notrunc
  4. Repack the corrupted file into the ipsw:
    zip -fv iPhone1,2_4.2.1_8C148_Restore.ipsw Firmware/all_flash/all_flash.n82ap.production/LLB.n82ap.RELEASE.img3
  5. Use iTunes to flash the corrupted firmware file.
  6. Somewhere through the flashing process, iTunes will throw an error and the iPhone will reboot into DFU mode.

Flashing the custom firmware

To create the custom firmware ipsw (including the jailbreak), I used redsn0w. However, I found that newer versions didn’t seem to work properly with the iPhone 3G. In the end I used version 0.9.6rc16 available here: Windows, Mac.

The timing and ordering of the next steps is very important and is where I had the most trouble.

After much confusion I found that redsn0w could only put the iPhone into “Pwned” DFU mode the first time it was connected to the computer after entering DFU mode. Later attempts would result in the tool claiming success but when attempting to flash the custom firmware, iTunes would give a 1600 error meaning that the phone wasn’t in “Pwned” DFU mode.

Discovering this and working around it proved very time consuming because if you didn’t successfully enter “Pwned” DFU mode on the first connection after entering DFU mode, the broken power button prevented you from resetting the phone! This meant that each time I failed, I had to wait for the phone to run out of battery before I could try again!

After achieving “Pwned” DFU mode on the phone I kept experiencing errors 9 and 14 when attempting to flash the custom firmware using iTunes. This turned out to be a side-effect of waiting for the battery to run out to reset the phone! It seemed that despite being connected via USB, the phone did not draw enough power to last through the flashing process causing it to fail.

Finally I found a process that worked around all of these issues:

  1. Wait for the iPhone to run out of battery (There’s no display on the phone because it’s in DFU mode so this is a waiting game really)
  2. Click through the redsn0w menus selecting “Only enter Pwned DFU mode” until you reach the stage where it walks you through getting into DFU mode
  3. Connect the iPhone
  4. Redsn0w should say it’s successfully put the phone in “Pwned” DFU mode
  5. Leave the iPhone charging from the computer for at least an hour
    If you don’t leave it this long, the phone will run out of battery during the flashing process and you’ll have to start again from the beginning so don’t get trigger happy!You may want to make sure your computer doesn’t go to sleep during the hour or it might stop the charging the phone.
  6. Start iTunes and use Shift/Alt click to select the custom firmware file you made using redsn0w earlier
  7. iTunes should flash the phone without any complaints!
  8. If you encounter error 1600, the phone isn’t in “Pwned” DFU mode and you’ll need to start again from step 1.
    If you encounter errors 9 or 14, you didn’t leave the phone charging for long enough and you’ll need to start again from step 1.

Unlocking

Ultrasn0w only works with iPhone 3G basebands 4.26.08, 5.11.07, 5.12.01, 5.13.04, and 6.15.00. Unfortunately my friend’s iPhone was at 05.15.04. This left me with two options:

  • Upgrade to the iPad 6.15.00 baseband (which apparently causes issues with GPS)
  • Downgrade to the 5.13.04 baseband (only possible if you have bootloader 05.08 / 5.8)

Fortunately the bootloader was 05.08 meaning I could downgrade like so:

  1. Install “fuzzyband” from Cydia
  2. Assuming you’re on baseband 05.15.04 you’ll need to add an extra certificate to /Applications/Fuzzyband/ – You can get it here. You can copy onto the phone using i-FunBox if you’re using Windows or use SSH.
  3. Run the fuzzyband app and it should let you downgrade the baseband
  4. Once downgraded, add the ultrasn0w repo (repo666.ultrasn0w.com) to Cydia
  5. Install ultrasn0w

You’re done!

Encrypting both OS X and Boot Camp

Update – Apparently this is now possible according to Jason Gouger who gave a method in the comments below.

Recently I decided that walking around with my documents and work unencrypted on my Macbook Pro was possibly a bad idea. If it was stolen, the thieves would have access to everything simply by connecting the hard drive to another machine. To alleviate these concerns, I started to look at the disk encryption options available to me.

On the Macbook I obviously run Mac OS X which I recently upgraded to Lion. With Lion comes an upgrade to the built-in encryption offered by the OS. Previously, FileVault, the built-in encryption system, only offered encryption of the user’s home folder. However, with Lion, FileVault2 now encrypts the entire partition.

9 hours later, my OS X partition was fully encrypted. Here’s where I began to run into issues. As well as Mac OS X, I also use Boot Camp to allow me to boot a native Windows 7 install. FileVault is quite tightly tied to HFS+ so although you can encrypt your OS X partition, your Windows NTFS partition remains unencrypted.

My initial reaction was to think I could just use TrueCrypt to encrypt the Windows parition. However, TrueCrypt expects the Windows partition to be the first on the drive which is not the layout in place after setting up Boot Camp. By default, the EFI partition is first followed by the OS X partition and it’s “Recovery” partition and then finally the Windows partition. Windows’ built-in Bitlocker encryption also faces the same issue as TrueCrypt requiring the Windows partition to be the first on the drive.

After looking into this issue online, I found a tutorial which provided a method for getting Windows installed on first partition on the drive, allowing the use of TrueCrypt. The issue with this method is that it requires using the MBR partition table instead of the newer GPT partition table used by OS X. Without the GPT partition table, OS X will refuse to install on the drive and even after you coerce it by manually writing an image, you then cannot enable FileVault as it requires the GPT partition table.

Another option I considered was Symmantec’s PGP Full Disk Encryption which encrypts both the OS X and Windows partitions, but this is a commercial piece of software and does not even support Lion yet.

Finally, I found this post which says that someone managed to get both their OS X and Windows partitions encrypted by modifying TrueCrypt so that it did not attempt to install it’s bootloader. To boot into Windows, they then had to boot the TrueCrypt bootloader from a USB pendrive.

This all sounded like a massive hack and a lot of trouble. Instead, a compromise could be to have a TrueCrypt encrypted partition after the Windows partition on which sensitive data is placed. The downside to this method is that the partition would have to be unlocked from within Windows. This poses some security concerns and in the end, may actually be providing false security.  A keylogger could catch the password whilst unlocking and then the disk encryption is useless.

ARM Scatter-loading heap/stack setup

Whilst working on my Embedded Systems Advanced OS coursework I ran into an issue whilst trying to define the location/size of my C heap and stack using the scatter-loading description file.

I kept getting the error
Execution region ARM_LIB_HEAP spans beyond 32 bit address space (base 0xc8804060, size 3380625504 bytes)

Turns out that I’d misunderstood how the EMPTY operator worked. I had:
ARM_LIB_HEAP 0xC8804060 EMPTY 0xC9804060
{
}

When in fact the EMPTY operator takes a size not an end location! Eventually I realised this and corrected it to

ARM_LIB_HEAP 0xC8804060 EMPTY 0x1000000
{
}

giving me my desired 16MB heap.

ul overflow in Internet Explorer 7

As most web designers will know, Internet Explorer 7 and older never seem to render anything properly. My most recent gripe has been why IE7 was refusing to show a background image I had defined on an li element.

It turned out that IE7 seems to have a rendering issue where it doesn’t show overflow on a ul element.

The fix seems to be to add

position: relative

to your li elements.

Build bot

Another job for myself as part of the Games Project was to set up automatic building of our master repository branch whenever anyone committed new code. Unfortunately, due to our game being developed for Windows (using Visual Studio) and there being a security restriction stopping us SSH’ing into the machines, I was unable to set up building upon commit.

I eventually decided that the next best thing would be to use Scheduled Tasks to first do a pull from the remote repository, and then if there were any changes, attempt to build the solution. The task was set up so that it would run every 15 minutes and it runs even when none of the group are logged into the machine.

The next step was to write the script that would do the pull from the repository and then call the Visual Studio MSBuild tool. Here was where I ran into a number of issues. The git package (msysgit) we had set up on the machine is basically git compiled using MinGW with a small shell. Unfortunately it seemed that it doesn’t like to launch the command prompt as you would normally. For example, the following code simply leaves you at a command prompt instead of printing “pie” and returning you to the bash shell:

cmd /C echo pie

Eventually I found that you could get the desired behaviour with some quoting like so:

"cmd" "/C echo pie"

Now that I was able to launch the command prompt (and therefore batch scripts), I had to create a batch script which would first call the Visual Studio vsvars32.bat script which sets the environment variables for Visual Studio. The script then makes a call to msbuild to compile the solution and exits with the return code from msbuild.

@echo off

@call "C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"

msbuild "%~f1"

exit %ERRORLEVEL%

Now that I could build solutions from the bash shell, all that was left was to write a perl script (msysgit includes perl) which would handle the calls to git. For the most part this was reasonably easy despite perl’s confusing syntax ($_, $? etc), but I ran into a hitch when I got to the part where I wanted to send the email. Initially I tried to use the CPAN Email::Send::Gmail module but it turns out it relies on the IO::Socket::SSL module which can’t handle timeouts due to IO::Socket::INET not supporting non-blocking sockets on Windows (see http://cpansearch.perl.org/src/SULLR/IO-Socket-SSL-1.38/README.Win32). It also turns out that although msysgit includes perl, it barely includes any modules so I was going to have to add tonnes of dependencies. Instead, I found mailsend which allowed me to easily send emails via a gmail account I set up on my domain.

#!/usr/bin/perl

use strict;
use warnings;

sub trim{
   my $string = shift;
   $string =~ s/^\s+|\s+$//g;
   return $string;
}

# Check we're on the master branch
`git checkout -q master`;

my $gitOutput = qx(git pull);

open FILE, "<buildBot.cfg" or die $!;

if ($gitOutput eq "Already up-to-date.\n")
{
    print "\nNo new commits, exiting\n";
}
else
{
    print "\nNew commits, commencing automated build\n\n";

    # Here we'll actually do the build attempts
    my @failures = ();
    my $output;
    my @temp;
    while (<FILE>)
    {
        # Only examine non-comments
        if (substr($_, 0, 1) ne "#" && $_ ne "")
        {
            print "Now building $_\n";

            $output = `"cmd" "/C buildSolution.bat ../$_"`;

            for (my $i = 0; $i < 5; $i++) {
                $output =~ s/.*?\n//;
            }

            if (($? >>=8) != 0)
            {
                @temp = ($_, $output);
                push(@failures, [@temp]);
            }
        }
    }

    if (@failures > 0)
    {
        # Get the current revision from git
        my $revision = trim(`git log --no-merges --format="%H" -1`);
        my $author = trim(`git log --no-merges --format="%aN" -1`);
        my $commitMessage = trim(`git log --format="%s" --no-merges -1`);
        my $subject = "[BloodBrothers Build Bot Alert] Automated building failed at revision $revision";
        my $message = "Automated building failed for revision $revision\n\nThis was probably caused by a commit by $author with log message:\n\"$commitMessage\"\n\nThe following solutions failed to build:\n";

        # Build string representing failures for email
        foreach my $solution (@failures)
        {
            $message .= @$solution[0] . "\n";
        }

        $message .= "\nLogs for failed solutions:\n";

        foreach my $solution (@failures)
        {
            $message .= "------------------------------------------------------------\n" . @$solution[0] . "\n------------------------------------------------------------\n";
            $message .= @$solution[1] . "\n";
        }

        # Call mailsend (eating it's output)
        open(PIPE, "| mailsend -t \"to\@somewhere.com\" -f \"buildbot\@somewhere.com\" -smtp smtp.gmail.com -port 587 -sub \"$subject\" -from \"buildbot\@somewhere.com\" +cc +bc -starttls -auth -user \"buildbot\@somewhere.com\" -pass \"password\"");
        print PIPE $message;
        close(PIPE);
    }
}

exit 0;

All done!

Multiple post-receive hooks for Git

For the University games project unit this year, my group are using Git for version control and trac for project management and bug tracking. It was decided that all members of the group should be emailed upon any commits to the repository. This was easy enough to implement, only requiring the renaming of a sample post-receive script and configuration of a few variables.

The tricky part was when I needed to set up a second post-receive script which allowed people to put tags in their commit messages to update trac tickets. The problem was that it would seem that there is not any built-in support for multiple post-receive scripts so you need to implement it yourself.

Initially I just created a single shell script which called both post-receive scripts. Unfortuantely this didn’t seem to work. So why!? It turned out that the input to the scripts is piped in on stdin and that the email script was just eating up the whole lot leaving nothing for the trac script to use! To get around this, I found a Stack Overflow question with code which copies the input from stdin to a temporary file and then pipes that into both post-receive scripts.

#!/bin/sh

FILE=mktemp
cat - > $FILE

cat $FILE | /srv/gitosis/repos/bloodbrothers.git/hooks/post-receive-email
cat $FILE | /srv/gitosis/repos/bloodbrothers.git/hooks/post-receive-trac

rm $FILE

Following this, bizarrely, tickets were still not being updated. Eventually I found the problem was that I had the incorrect permissions set on my trac directory. This meant that when my trac post-receive script tried to call trac-admin, it didn’t actually have permission to write to the trac database. After giving the gitosis user access, my tickets began magically updating 😀