<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thoughts of an overworked CS student</title>
	<atom:link href="http://www.lukefitzgerald.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lukefitzgerald.co.uk</link>
	<description>Scraps of life + coding problems you can never find that simple solution for</description>
	<lastBuildDate>Tue, 06 Mar 2012 01:22:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Jailbreaking and unlocking an iPhone 3G with a broken power/sleep button</title>
		<link>http://www.lukefitzgerald.co.uk/2012/02/jailbreaking-and-unlocking-an-iphone-3g-with-a-broken-powersleep-button/</link>
		<comments>http://www.lukefitzgerald.co.uk/2012/02/jailbreaking-and-unlocking-an-iphone-3g-with-a-broken-powersleep-button/#comments</comments>
		<pubDate>Sat, 25 Feb 2012 20:06:10 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[dfu]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[jailbreak]]></category>

		<guid isPermaLink="false">http://www.lukefitzgerald.co.uk/?p=119</guid>
		<description><![CDATA[<p>Recently my flatmate was given a hand-me-down iPhone 3G. Unfortunately the phone had two problems meaning she couldn&#8217;t use it:</p> Locked to O2 &#8211; My flatmate has a contract with Vodafone Broken Power/Sleep button <p>To get around this I initially thought it was as simple as jailbreaking the phone, installing Activator to get around the [...]]]></description>
			<content:encoded><![CDATA[<p>Recently my flatmate was given a hand-me-down iPhone 3G. Unfortunately the phone had two problems meaning she couldn&#8217;t use it:</p>
<ul>
<li>Locked to O2 &#8211; My flatmate has a contract with Vodafone</li>
<li>Broken Power/Sleep button</li>
</ul>
<p>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.</p>
<h3>Getting into DFU Mode</h3>
<p>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 &#8220;pwned&#8221; 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.</p>
<p>After googling around for some time I stumbled across <a href="http://ilapstech.blogspot.com/2011/07/downgrade-iphone-3g-with-no-working.html">a blog post</a> which demonstrated how it was possible to get into DFU mode by corrupting the LLB file in a vanilla firmware file.</p>
<p>To do this you&#8217;ll need a Mac or Linux VM (if on Windows).</p>
<ol>
<li>Grab the vanilla 4.2.1 firmware: <a href="http://appldnld.apple.com/iPhone4/061-9853.20101122.Vfgt5/iPhone1,2_4.2.1_8C148_Restore.ipsw">here</a></li>
<li>Unzip the LLB file
<pre>unzip -x iPhone1,2_4.2.1_8C148_Restore.ipsw  */LLB*img3</pre>
</li>
<li>Corrupt some bytes at offset 0&#215;240 (whilst maintaining the file size):
<pre>dd if=/dev/urandom of=Firmware/all_flash/all_flash.n82ap.production/LLB.n82ap.RELEASE.img3 bs=16 count=10 seek=36 conv=notrunc</pre>
</li>
<li>Repack the corrupted file into the ipsw:
<pre>zip -fv iPhone1,2_4.2.1_8C148_Restore.ipsw Firmware/all_flash/all_flash.n82ap.production/LLB.n82ap.RELEASE.img3</pre>
</li>
<li>Use iTunes to flash the corrupted firmware file.</li>
<li>Somewhere through the flashing process, iTunes will throw an error and the iPhone will reboot into DFU mode.</li>
</ol>
<h3>Flashing the custom firmware</h3>
<p>To create the custom firmware ipsw (including the jailbreak), I used redsn0w. However, I found that newer versions didn&#8217;t seem to work properly with the iPhone 3G. In the end I used version 0.9.6rc16 available here: <a href="https://sites.google.com/a/iphone-dev.com/files/home/redsn0w_win_0.9.6rc16.zip?attredirects=0&amp;d=1">Windows</a>, <a href="https://sites.google.com/a/iphone-dev.com/files/home/redsn0w_mac_0.9.6rc16.zip?attredirects=0&amp;d=1">Mac</a>.</p>
<p>The timing and ordering of the next steps is very important and is where I had the most trouble.</p>
<p>After much confusion I found that redsn0w could only put the iPhone into &#8220;Pwned&#8221; 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&#8217;t in &#8220;Pwned&#8221; DFU mode.</p>
<p>Discovering this and working around it proved very time consuming because if you didn&#8217;t successfully enter &#8220;Pwned&#8221; 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!</p>
<p>After achieving &#8220;Pwned&#8221; 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.</p>
<p>Finally I found a process that worked around all of these issues:</p>
<ol>
<li>Wait for the iPhone to run out of battery (There&#8217;s no display on the phone because it&#8217;s in DFU mode so this is a waiting game really)</li>
<li>Click through the redsn0w menus selecting &#8220;Only enter Pwned DFU mode&#8221; until you reach the stage where it walks you through getting into DFU mode</li>
<li>Connect the iPhone</li>
<li>Redsn0w should say it&#8217;s successfully put the phone in &#8220;Pwned&#8221; DFU mode</li>
<li>Leave the iPhone charging from the computer for <strong>at least an hour<br />
</strong>If you don&#8217;t leave it this long, the phone will run out of battery during the flashing process and you&#8217;ll have to start again from the beginning so don&#8217;t get trigger happy!</p>
<p>You may want to make sure your computer doesn&#8217;t go to sleep during the hour or it might stop the charging the phone.</li>
<li>Start iTunes and use Shift/Alt click to select the custom firmware file you made using redsn0w earlier</li>
<li>iTunes should flash the phone without any complaints!</li>
<li>If you encounter error 1600, the phone isn&#8217;t in &#8220;Pwned&#8221; DFU mode and you&#8217;ll need to start again from step 1.<br />
If you encounter errors 9 or 14, you didn&#8217;t leave the phone charging for long enough and you&#8217;ll need to start again from step 1.</li>
</ol>
<h3>Unlocking</h3>
<p>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&#8217;s iPhone was at 05.15.04. This left me with two options:</p>
<ul>
<li>Upgrade to the iPad 6.15.00 baseband (which apparently causes issues with GPS)</li>
<li>Downgrade to the 5.13.04 baseband (only possible if you have bootloader 05.08 / 5.8)</li>
</ul>
<p>Fortunately the bootloader was 05.08 meaning I could downgrade like so:</p>
<ol>
<li>Install &#8220;fuzzyband&#8221; from Cydia</li>
<li>Assuming you&#8217;re on baseband 05.15.04 you&#8217;ll need to add an extra certificate to /Applications/Fuzzyband/ &#8211; You can get it <a href="http://www.lukefitzgerald.co.uk/downgradecert.zip">here</a>. You can copy onto the phone using <a href="http://www.i-funbox.com/">i-FunBox</a> if you&#8217;re using Windows or use SSH.</li>
<li>Run the fuzzyband app and it should let you downgrade the baseband</li>
<li>Once downgraded, add the ultrasn0w repo (repo666.ultrasn0w.com) to Cydia</li>
<li>Install ultrasn0w</li>
</ol>
<p>You&#8217;re done!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2012/02/jailbreaking-and-unlocking-an-iphone-3g-with-a-broken-powersleep-button/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>StatusNet 1.0.0 released</title>
		<link>http://www.lukefitzgerald.co.uk/2011/10/statusnet-1-0-0-released/</link>
		<comments>http://www.lukefitzgerald.co.uk/2011/10/statusnet-1-0-0-released/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 10:41:37 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[irc]]></category>
		<category><![CDATA[msn]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[statusnet]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=111</guid>
		<description><![CDATA[<p>Last summer I produced IRC and MSN interface plugins for StatusNet. Today, StatusNet 1.0.0 has been released and these plugins are now bundled with it!</p> <p>Even got a nice mention on their blog: <a title="http://status.net/2011/09/30/statusnet-1-0-0-its-the-end-of-the-world-as-we-know-it-and-i-feel-fine" href="http://status.net/2011/09/30/statusnet-1-0-0-its-the-end-of-the-world-as-we-know-it-and-i-feel-fine">http://status.net/2011/09/30/statusnet-1-0-0-its-the-end-of-the-world-as-we-know-it-and-i-feel-fine</a></p>]]></description>
			<content:encoded><![CDATA[<p>Last summer I produced IRC and MSN interface plugins for StatusNet. Today, StatusNet 1.0.0 has been released and these plugins are now bundled with it!</p>
<p>Even got a nice mention on their blog: <a title="http://status.net/2011/09/30/statusnet-1-0-0-its-the-end-of-the-world-as-we-know-it-and-i-feel-fine" href="http://status.net/2011/09/30/statusnet-1-0-0-its-the-end-of-the-world-as-we-know-it-and-i-feel-fine">http://status.net/2011/09/30/statusnet-1-0-0-its-the-end-of-the-world-as-we-know-it-and-i-feel-fine</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2011/10/statusnet-1-0-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Encrypting both OS X and Boot Camp</title>
		<link>http://www.lukefitzgerald.co.uk/2011/09/encrypting-both-os-x-and-boot-camp/</link>
		<comments>http://www.lukefitzgerald.co.uk/2011/09/encrypting-both-os-x-and-boot-camp/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 14:12:51 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[bootcamp]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=103</guid>
		<description><![CDATA[<p>Update &#8211; Apparently this is now possible according to Jason Gouger who gave a method in the comments below.</p> <p>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 [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update &#8211; Apparently this is now possible according to <cite>Jason Gouger</cite> who gave a method in the comments below.</strong></p>
<p>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.</p>
<p>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&#8217;s home folder. However, with Lion, FileVault2 now encrypts the entire partition.</p>
<p>9 hours later, my OS X partition was fully encrypted. Here&#8217;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.</p>
<p>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&#8217;s &#8220;Recovery&#8221; partition and then finally the Windows partition. Windows&#8217; built-in Bitlocker encryption also faces the same issue as TrueCrypt requiring the Windows partition to be the first on the drive.</p>
<p>After looking into this issue online, I found a <a href="http://blog.taggesell.de/index.php?/archives/36-TrueCrypt-on-Macbook-Windows-XP.html">tutorial</a> 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.</p>
<p>Another option I considered was Symmantec&#8217;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.</p>
<p>Finally, I found <a href="https://discussions.apple.com/message/15936267#15936267">this post</a> 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&#8217;s bootloader. To boot into Windows, they then had to boot the TrueCrypt bootloader from a USB pendrive.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2011/09/encrypting-both-os-x-and-boot-camp/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>ARM Scatter-loading heap/stack setup</title>
		<link>http://www.lukefitzgerald.co.uk/2011/04/arm-scatter-loading-heapstack-setup/</link>
		<comments>http://www.lukefitzgerald.co.uk/2011/04/arm-scatter-loading-heapstack-setup/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 16:57:43 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[embedded systems]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=96</guid>
		<description><![CDATA[<p>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.</p> <p>I kept getting the error<br /> Execution region ARM_LIB_HEAP spans beyond 32 bit address space (base 0xc8804060, size 3380625504 bytes)</p> <p>Turns out that I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>I kept getting the error<br />
<code>Execution region ARM_LIB_HEAP spans beyond 32 bit address space (base 0xc8804060, size 3380625504 bytes)</code></p>
<p>Turns out that I&#8217;d misunderstood how the <code>EMPTY</code> operator worked. I had:<br />
<code>ARM_LIB_HEAP 0xC8804060 EMPTY 0xC9804060<br />
{<br />
}</code></p>
<p>When in fact the EMPTY operator takes a <strong>size</strong> not an end location! Eventually I realised this and corrected it to</p>
<p><code>ARM_LIB_HEAP 0xC8804060 EMPTY 0x1000000<br />
{<br />
}</code></p>
<p>giving me my desired 16MB heap.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2011/04/arm-scatter-loading-heapstack-setup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EVGA X58 SLI Classified E760 won&#8217;t resume from sleep?</title>
		<link>http://www.lukefitzgerald.co.uk/2011/04/evga-x58-sli-classified-e760-wont-resume-from-sleep/</link>
		<comments>http://www.lukefitzgerald.co.uk/2011/04/evga-x58-sli-classified-e760-wont-resume-from-sleep/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 13:47:22 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[hardware]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=90</guid>
		<description><![CDATA[<p>After installing Windows 7 SP1 (x64) I found that my system would no longer resume from sleep. After having a look through the EVGA forums I found that this is corrected in the latest BIOS update which you can find here:</p> <p><a title="http://www.evga.com/forums/tm.aspx?m=960173" href="http://www.evga.com/forums/tm.aspx?m=960173">http://www.evga.com/forums/tm.aspx?m=960173</a></p>]]></description>
			<content:encoded><![CDATA[<p>After installing Windows 7 SP1 (x64) I found that my system would no longer resume from sleep. After having a look through the EVGA forums I found that this is corrected in the latest BIOS update which you can find here:</p>
<p><a title="http://www.evga.com/forums/tm.aspx?m=960173" href="http://www.evga.com/forums/tm.aspx?m=960173">http://www.evga.com/forums/tm.aspx?m=960173</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2011/04/evga-x58-sli-classified-e760-wont-resume-from-sleep/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ul overflow in Internet Explorer 7</title>
		<link>http://www.lukefitzgerald.co.uk/2011/02/ul-overflow-in-internet-explorer-7/</link>
		<comments>http://www.lukefitzgerald.co.uk/2011/02/ul-overflow-in-internet-explorer-7/#comments</comments>
		<pubDate>Fri, 18 Feb 2011 18:49:31 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[web design]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=86</guid>
		<description><![CDATA[<p>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.</p> <p>It turned out that IE7 seems to have a rendering issue where it doesn&#8217;t show overflow [...]]]></description>
			<content:encoded><![CDATA[<p>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 <code>li</code> element.</p>
<p>It turned out that IE7 seems to have a rendering issue where it doesn&#8217;t show overflow on a <code>ul</code> element.</p>
<p>The fix seems to be to add</p>
<p><code>position: relative</code></p>
<p>to your <code>li</code> elements.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2011/02/ul-overflow-in-internet-explorer-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build bot</title>
		<link>http://www.lukefitzgerald.co.uk/2011/02/build-bot/</link>
		<comments>http://www.lukefitzgerald.co.uk/2011/02/build-bot/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 00:40:35 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[command prompt]]></category>
		<category><![CDATA[games project]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[scheduled tasks]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=46</guid>
		<description><![CDATA[<p>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&#8217;ing into the machines, I was unable to set [...]]]></description>
			<content:encoded><![CDATA[<p>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&#8217;ing into the machines, I was unable to set up building  upon commit.</p>
<p>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.</p>
<p>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 (<a href="http://code.google.com/p/msysgit/">msysgit</a>) we had set up on the machine is basically git compiled using <a href="http://www.mingw.org/">MinGW</a> with a small shell. Unfortunately it seemed that it doesn&#8217;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 &#8220;pie&#8221; and returning you to the bash shell:</p>
<pre class="brush: bash; title: ; notranslate">cmd /C echo pie</pre>
<p>Eventually I found that you could get the desired behaviour with some quoting like so:</p>
<pre class="brush: bash; title: ; notranslate">&quot;cmd&quot; &quot;/C echo pie&quot;</pre>
<p>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 <code>vsvars32.bat</code> script which sets the environment variables for Visual Studio. The script then makes a call to <code>msbuild</code> to compile the solution and exits with the return code from <code>msbuild</code>.</p>
<pre class="brush: bash; title: ; notranslate">@echo off

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

msbuild &quot;%~f1&quot;

exit %ERRORLEVEL%</pre>
<p>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&#8217;s confusing syntax (<code>$_</code>, <code>$?</code> 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 <a href="http://search.cpan.org/dist/Email-Send-Gmail/">Email::Send::Gmail</a> module but it turns out it relies on the IO::Socket::SSL module which can&#8217;t handle timeouts due to IO::Socket::INET not supporting non-blocking sockets on Windows (see <a href="http://cpansearch.perl.org/src/SULLR/IO-Socket-SSL-1.38/README.Win32">http://cpansearch.perl.org/src/SULLR/IO-Socket-SSL-1.38/README.Win32</a>). 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 <code><a href="http://www.muquit.com/muquit/software/mailsend/mailsend.html">mailsend</a></code> which allowed me to easily send emails via a gmail account I set up on my domain.</p>
<pre class="brush: perl; title: ; notranslate">#!/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, &quot;&lt;buildBot.cfg&quot; or die $!;

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

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

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

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

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

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

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

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

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

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

exit 0;</pre>
<p>All done!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2011/02/build-bot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple post-receive hooks for Git</title>
		<link>http://www.lukefitzgerald.co.uk/2011/01/multiple-post-receive-hooks-for-git/</link>
		<comments>http://www.lukefitzgerald.co.uk/2011/01/multiple-post-receive-hooks-for-git/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 19:13:43 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[games project]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[post-receive]]></category>
		<category><![CDATA[trac]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=26</guid>
		<description><![CDATA[<p>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 [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>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.</p>
<p>Initially I just created a single shell script which called both post-receive scripts. Unfortuantely this didn&#8217;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 <a href="http://stackoverflow.com/questions/3448333/multiple-commands-are-not-working-in-git-post-receive" target="_blank">Stack Overflow question</a> with code which copies the input from stdin to a temporary file and then pipes that into both post-receive scripts.</p>
<pre class="brush: bash; title: ; notranslate">#!/bin/sh

FILE=mktemp
cat - &gt; $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</pre>
<p>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&#8217;t actually have permission to write to the trac database. After giving the gitosis user access, my tickets began magically updating <img src='http://www.lukefitzgerald.co.uk/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2011/01/multiple-post-receive-hooks-for-git/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Naïve Bayes and Character encoding in Java</title>
		<link>http://www.lukefitzgerald.co.uk/2010/12/naive-bayes-and-character-encoding-in-java/</link>
		<comments>http://www.lukefitzgerald.co.uk/2010/12/naive-bayes-and-character-encoding-in-java/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 12:30:24 +0000</pubDate>
		<dc:creator>Luke Fitzgerald</dc:creator>
				<category><![CDATA[University]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[machine learning]]></category>

		<guid isPermaLink="false">http://www.inflatablegoldfish.com/?p=7</guid>
		<description><![CDATA[<p>One of my most recent assignments for the <a title="Introduction to Machine Learning" href="http://www.cs.bris.ac.uk/Teaching/Resources/COMS30301/" target="_blank">Introduction to Machine Learning</a> unit has me creating a Naïve Bayes classifier for identifying spam emails. The most recent stage I&#8217;ve implemented is the 10-fold <a title="Cross validation" href="http://en.wikipedia.org/wiki/Cross-validation_%28statistics%29" target="_blank">cross validation</a>.</p> <p>10-fold cross validation involves first randomising the order of your [...]]]></description>
			<content:encoded><![CDATA[<p>One of my most recent assignments for the <a title="Introduction to Machine Learning" href="http://www.cs.bris.ac.uk/Teaching/Resources/COMS30301/" target="_blank">Introduction to Machine Learning</a> unit has me creating a Naïve Bayes classifier for identifying spam emails. The most recent stage I&#8217;ve implemented is the 10-fold <a title="Cross validation" href="http://en.wikipedia.org/wiki/Cross-validation_%28statistics%29" target="_blank">cross validation</a>.</p>
<p>10-fold cross validation involves first randomising the order of your set of training emails, then splitting the emails into 10 even groups (or folds). Next, you train on 9 out of the 10 folds, and test the remaining fold. You do this 10 times so each of the folds is tested by the classifier trained on the other 9 folds. You then take an average of the success rate from the classifications to give the final result.</p>
<p>The puzzling thing was a friend and I were getting different end results. We tracked the cause of this down to us having a different number of words read in for a couple of the emails. After further investigation, it turned out that these emails were using the <a title="Windows-1251" href="http://en.wikipedia.org/wiki/Windows-1251" target="_blank">Windows-1251</a> character set (Cyrillic alphabet).</p>
<p>Yes, that&#8217;s correct, we were expected to classify Russian emails!</p>
<p>The reason we were getting different results is the default character encoding Java uses depends on the operating system. I was using Linux (Ubuntu 10.04) and the other guy was using Windows (7). When reading in from a file in Linux, Java assumes the character encoding of the file to be UTF-8 which unfortunately means that when it tries to read the Windows-1251 encoded file, all the Cyrillic characters become {?} or whatever you call the &#8220;unknown&#8221; character. On the other hand, when on Windows, Java seems to assume the <a title="ISO 8859-1" href="http://en.wikipedia.org/wiki/ISO/IEC_8859-1" target="_blank">ISO 8859-1</a> encoding which will (although incorrectly) read each of the Cyrillic characters as a unique character.</p>
<p>Simply forcing my <code>BufferedReader</code> to use ISO 8859-1 seemed to solve the problem:</p>
<pre class="brush: java; title: ; notranslate">stream = new InputStreamReader(new FileInputStream(file), &quot;ISO8859_1&quot;)
reader = new BufferedReader(stream);</pre>
<p>That&#8217;s all for now, back to work!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lukefitzgerald.co.uk/2010/12/naive-bayes-and-character-encoding-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

