<?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>Spice World!</title>
	<atom:link href="http://www.cyberspice.org.uk/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cyberspice.org.uk/blog</link>
	<description>The life and times of a jet setting software engineer!</description>
	<lastBuildDate>Fri, 02 Dec 2011 14:52:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>My BBC Micro and Me</title>
		<link>http://www.cyberspice.org.uk/blog/2011/12/02/my-bbc-micro-and-me/</link>
		<comments>http://www.cyberspice.org.uk/blog/2011/12/02/my-bbc-micro-and-me/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 14:39:42 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Women In Technology]]></category>
		<category><![CDATA[BBC Micro]]></category>
		<category><![CDATA[BBC Microcomputer]]></category>
		<category><![CDATA[Beeb]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=492</guid>
		<description><![CDATA[The BBC Microcomputer is 30 years old. The BBC News web site had an article about it but from the article you would think that only males benefited from it. Well it wasn&#8217;t just the boys who had fun with them! (Photo &#169; Anachrocomputer) The first computer in the house was my father&#8217;s. It was [...]]]></description>
			<content:encoded><![CDATA[<p>The BBC Microcomputer is 30 years old. The BBC News web site had an article about it but from the article you would think that only males benefited from it. Well it wasn&#8217;t just the boys who had fun with them!  (Photo &copy; <a href="http://www.flickr.com/photos/anachrocomputer/">Anachrocomputer</a>)<span id="more-492"></span><a href="http://www.flickr.com/photos/anachrocomputer/4440207275/" title="View 'Maker Faire 2010: BBC Micro with Ethernet' on Flickr.com"><img border="0" style="float:right; margin:10px;" height="160" src="http://farm5.staticflickr.com/4024/4440207275_1b732860b6_m.jpg" alt="Maker Faire 2010: BBC Micro with Ethernet &copy;Anachrocomputer" width="240" title="Maker Faire 2010: BBC Micro with Ethernet &copy;Anachrocomputer"/></a></p>
<p>The first computer in the house was my father&#8217;s. It was a TRS-80 Model 1. He had bought it to learn computing and because he realised computers were the future. I used it a lot learning to program in the BASIC language and then in Z80 assembly language (the language of the<br />
microprocessor that ran the computer).</p>
<p>I was also interested in electronics (thanks to my Uncle who taught it in schools) and around the same time I saw an advertisement for the<br />
Acorn Atom in an electronics magazine and I wanted one. I started saving but the BBC Microcomputer (&#8220;The Beeb&#8221;) came out before I could afford one. My Parents offered to help buy a Beeb by way of multiple combined Birthday and Christmas presents and the deal I would not use it until after my &#8216;O&#8217; levels which I mainly complied with. I remember the excitement of going in to the store to purchase my Beeb.</p>
<p>I learnt to program that machine from top to bottom. I had the reference manuals and the data sheets for all the chips. I loved how you got the full circuit diagram with the Advanced User Guide (it was a print of the one hand drawn by Acorn). I learnt BBC BASIC and 6502 assembly language. I learnt how to add to the operating system and how to do clever things by directly programming the chips in the machine. It taught me a lot about programming, such as interrupts, concurrency, race conditions, dead and live locks, and so on. Programming did become my first love and superseded electronics but I wouldn&#8217;t be the programmer I am today with out it!</p>
<p>I didn&#8217;t just program. I did play games with my favourites being Chuckie Egg and Elite! Elite was a complete time sink. No game following sucked me in as much as Elite did until World of Warcraft!</p>
<p>I didn&#8217;t completely give up on electronics and would develope small projects to connect to my Beeb. In the mid 80s I was studying for a Physics degree and naturally I used my Beeb. My final year project was based around the automation of an experiment. I designed hardware to drive the equipment, sensors and hardware to read data, and wrote software to drive it all from a Beeb.</p>
<p>In 1989 I got an Acorn A3000. It was the successor to the Beeb and also used in schools. It had the Acorn designed ARM processor (now used in nearly everything from a mobile phone to the iPad, set top boxes and televisions), what seemed like copious amounts of memory, loads of colours and a built in disk drive. It had BBC BASIC so I was at home and also taught me to program ARM assembly language (which I still use today). So the Beeb was basically retired.</p>
<p>I moved on to other machines, developing for Linux, higher degrees and becoming a research assistant but I never lost my love of my Beeb though and I still own mine almost 30 years after I bought it. I also still make projects for it. The most recent being an ethernet interface so that I can connect it to the internet.</p>
<p>I am now an embedded software consultant and I work for a company that was formed by employees of the company that bought Acorn Computers when it finally ended in 1999. My most recent project was optimising Linux on a device with an ARM processor. And my entire career is down to me and my Parents buying that Beeb 30 years ago!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2011/12/02/my-bbc-micro-and-me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The BBC Model B Microcomputer keyboard &#8211; How it works</title>
		<link>http://www.cyberspice.org.uk/blog/2011/04/27/the-bbc-model-b-microcomputer-keyboard-how-it-works/</link>
		<comments>http://www.cyberspice.org.uk/blog/2011/04/27/the-bbc-model-b-microcomputer-keyboard-how-it-works/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 19:06:14 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[BBC Micro PC]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=485</guid>
		<description><![CDATA[As part of my BBC Micro PC project (more about this later) I need to turn the keyboard in a BBC Micro in to a USB hid device. I could just rip the insides out of a PC USB keyboard and solder wires on to the back off all the key switches but that seems [...]]]></description>
			<content:encoded><![CDATA[<p>As part of my BBC Micro PC project (more about this later) I need to turn the keyboard in a BBC Micro in to a USB hid device. I could just rip the insides out of a PC USB keyboard and solder wires on to the back off all the key switches but that seems somewhat messy. So I decided to design a micro-controller circuit to read the keyboard and to appear as a standard USB HID device. The neatest solution is to have the micro-controller drivng the keyboard circuitry the same was as the BBC Micro main board does. This post explains how the keyboard circuit works.<span id="more-485"></span>The BBC Model B keyboard circuit board is more than just a grid of key-switches. It comprises some circuitry to reduce the number of connections between it and the main circuit board to 8 lines and to generate interrupts on key presses. Its a very neat design. Below is the keyboard circuit diagram taken from the BBC Model B service manual. The diagram also includes a bit of circuitry for the speech ROM expansion which I will ignore.</p>
<p><a href="http://www.flickr.com/photos/39013214@N03/5660684665" title="View 'BBC Model B Keyboard Circuit' on Flickr.com"><img border="0" style="display:block; margin-left:auto; margin-right:auto;" height="337" src="http://farm6.static.flickr.com/5188/5660684665_b5af5c664b.jpg" alt="BBC Model B Keyboard Circuit" width="500" title="BBC Model B Keyboard Circuit"/></a><br />
<center><br />
<table border="1" cellpadding="2" cellspacing="0">
<tr>
<th>IC1</th>
<td>74xx161/163</td>
<td>Synchronous 4 bit binary counter</td>
</tr>
<tr>
<th>IC2</th>
<td>74xx45</td>
<td>BCD to decimal decoder</td>
</tr>
<tr>
<th>IC3</th>
<td>74xx251</td>
<td>3 state 1 of 8 line data selector</td>
</tr>
<tr>
<th>IC4</th>
<td>74xx30</td>
<td>Octal NAND gate</td>
</tr>
</table>
<p></center></p>
<p>At the core is the traditional key matrix. It is a grid of rows and columns with momentary push switches that connect a row to a column when pressed. All of the rows are tied high by resistors to the 5v supply rail. The rows are inputs to an octal NAND gate (IC4), which, in this case is better thought of as an OR gate with inverting inputs. I.e. but default the output of the NAND gate is low but if one of the rows is pulled low the NAND output goes high. The rows are also inputs in to the line data selector (IC2).</p>
<p>The synchronous 4 bit binary counter (IC1) is driven by the BBC Micro&#8217;s 1MHz clock and when the KB EN is high is in free running mode. The 4 bit outputs (outputs QA-QD) are decoded by the BCD to decimal decoder (IC3) such that the decoder&#8217;s outputs go low in turn. The outputs of the decoder form the columns of the grid. I.e. column 0 is low on the first clock pulse, column 1 on the second and so on. If a key is pressed the row the key is on will go low when the column goes low.  This in turn makes the output of the NAND gate go high indicating a key is pressed. The output of the NAND gate is used to generate an interrupt in the BBC Micro&#8217;s CPU.</p>
<p>So normally the keyboard is being scanned by the hardware without any software influence.  This is a good thing as it takes a lot of loading off of the BBC Micro&#8217;s CPU.  When the key press interrupt is triggered the key scanning software takes over. As I said normally the 4 bit binary counter (IC1) is free running however if the LOAD pin (pin 9) is taken low the 4 bit input value (inputs A-D) are latched through to the outputs (QA-QD) and hence control the columns provided by the decoder (IC3). IC1&#8242;s load pin is connected to KB EN.</p>
<p>The S line of the data line selector (IC2) is the select line and is also connected to KB EN. The output of IC2 is 3 state meaning it either reflects the appropriate data input line when select is low or is high impedance. The data input lines are the row lines of the keyboard matrix. The input line is chosen using the three bit &#8216;address&#8217; value on A-C. The row state is output via pin W. </p>
<p>So the keyboard is normally hardware scanning. If the user presses a key, the interrupt is triggered. The CPU enables the keyboard by setting KB EN low and then manually scans the key board by setting the columns in turn via IC1 and checking the state of the rows in turn via IC2.  Once the scan is complete KB EN is set high and the hardware scanning continues.</p>
<p>There are three keys on the keyboard which are exceptions. The two SHIFT and CTRL keys are on a row that does not trigger an interrupt. This means that shift is only scanned manually or when another key is pressed.  The BREAK key (labled RST) is completely separate from the matrix and triggers the CPU&#8217;s reset line. On boot the CPU scans the keyboard manually to see if any of the modifiers are held down to do a cold reset or mount the disk for example.</p>
<p>The BBC Micro keyboard can be easily interfaced with say an ATMEL ATMega328 (like in an Arduino).  The micro-controller can drive a pin directly from one of the timers generating a square wave output to scan the keyboard. The interrupt can be connected to one of interrupt inputs and the rest connected to general purpose IO pins set as outputs or inputs as appropriate.  Dick Streefland&#8217;s <a href="http://www.xs4all.nl/%7Edicks/avr/usbtiny/">USBtiny</a> code provides the functionality to support the USB protocol in software utilising three IO pins on the micro-controller and a few discrete components. All that is required by me is to write the keyboard scanning code and provide the missing bits of the HID device profile.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2011/04/27/the-bbc-model-b-microcomputer-keyboard-how-it-works/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Upgrading your UK T-Mobile Google G1 (HTC Dream) to Android 2.x</title>
		<link>http://www.cyberspice.org.uk/blog/2010/10/22/upgrading-your-uk-t-mobile-google-g1-htc-dream-to-android-2-x/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/10/22/upgrading-your-uk-t-mobile-google-g1-htc-dream-to-android-2-x/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 15:33:22 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Google G1]]></category>
		<category><![CDATA[HTC Dream]]></category>
		<category><![CDATA[T-Mobile]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=480</guid>
		<description><![CDATA[I&#8217;m currently developing a new project. Its a bluetooth enabled bracelet. I wanted to write an iPhone app to control it. However, much as I like my iPhone 4, Apple&#8217;s policy about locking the thing down sucks. So I then looked at writing an Android application for my G1. The problem with that is that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently developing a new project.  Its a bluetooth enabled bracelet.  I wanted to write an iPhone app to control it.  However, much as I like my iPhone 4, Apple&#8217;s policy about locking the thing down sucks.  So I then looked at writing an Android application for my G1.  The problem with that is that bluetooth support only arrived in Android 2.0 and T-Mobile/HTC ceased upgrades at 1.6 on the G1.  Since my G1 is two years old and out of contract I decided to be brave and upgrade it to Android 2.2.  Note the G1 is called the HTC Dream in many markets.</p>
<p><span id="more-480"></span><br />
<h2>Overview</h2>
<p>In order to install kind of new operating system I needed to have root access on the device.  This meant I had to <em>root</em> it.  Since Android 1.6 (Release R10) on the G1 doesn&#8217;t have any useful exploits I had to downgrade the OS to Release R7 first.  Once it is downgraded it you can use the rooting exploit in R7 to get root access and install a recovery image that will allow the installation of an updated radio software and the new operating system.</p>
<h2>Preliminaries</h2>
<p>Firstly read all of this blog post and all of the pages linked to from this blog post.  There is at least one point in this process where you can &#8220;brick your phone&#8221;.  I.e. you can put it in a state where by a regular user cannot make it usable.</p>
<p>Secondly you will be wiping your phone and replacing the software on it.  Back anything up you want to keep.  This includes purchased applications, data, contacts, whatever.</p>
<p>Make sure the phone is fully charged.  You don&#8217;t want it running out of power mid-flash!</p>
<p><span style="text-color: #ff0000;"><strong>Finally I provide no warranty express or implied.  You are doing this to your phone.  If it goes wrong its your fault!  You have been warned!</strong></span></p>
<h2>Downgrading and rooting</h2>
<p>Downgrading, rooting the phone, and installing a recovery image is described in the link below.  However since there are specific requirements for upgrading to Android 2.X I&#8217;ll explain each stage here.</p>
<p><a href="http://forum.xda-developers.com/showthread.php?t=442480">http://forum.xda-developers.com/showthread.php?t=442480</a></p>
<h3>Downgrading</h3>
<p>Before you do anything take note of the radio version string in the boot-loader.  Its the fourth line down.  You get the boot-loader screen up by holding down the camera button when powering on the phone.  With the original loader you should have multi-coloured bars with yellow text in the top left hand corner.  On my phone the radio version string read <em>&#8220;RADIO-2.22.19.26I&#8221;</em>.  Write down the string and store it somewhere safe.  You&#8217;ll need it later.</p>
<p>Now download the appropriate older image for your phone.  The links to the image downloads are on the page above however here&#8217;s the link for <a href="http://koushikdutta.blurryfox.com/G1/DREAMIMG-RC7.zip">RC7</a> for those with UK phones.  Download the image, unzip it, and save the <em>DREAMIMG.nbh</em> file in the root of your SD card.  While you&#8217;re at it also download <a href="http://www.androidspin.com/downloads.php?dir=amon_ra/RECOVERY/&#038;file=recovery-RA-dream-v1.5.2.img">recovery-RA-dream-v1.5.2.img</a> which is a recovery image and will be used later.  Save this in the root of your SD card also.</p>
<p>Turn off your phone, insert the SD card, and turn it back on again holding down the camera key as before.  It should now re-flash your phone.  There should be a progress bar.  When its all complete you can restart your phone normally (without the camera key held down).  This will result in some old school Android graphics and you wondering how anyone ever coped with that software.  Once the phone has booted find the phone details in settings and check the software build version number.  It should appear as something like <em>TC5-RC7 112931</em>.</p>
<p><center><br />
<table>
<tr>
<td><a href="http://www.flickr.com/photos/39013214@N03/5075135008" title="View 'Initial bootloader' on Flickr.com"><img height="240" alt="Initial bootloader" border="0" style="display: inline;" src="http://farm5.static.flickr.com/4113/5075135008_1492d33db5_m.jpg" width="162"/></a></td>
<td><a href="http://www.flickr.com/photos/39013214@N03/5074536617" title="View 'Installing an image from SD card' on Flickr.com"><img height="240" alt="Installing an image from SD card" border="0" style="display: inline;" src="http://farm5.static.flickr.com/4012/5074536617_0f606f44e1_m.jpg" width="172"/></a></td>
<td><a href="http://www.flickr.com/photos/39013214@N03/5075135512" title="View 'Software information screen' on Flickr.com"><img height="240" alt="Software information screen" border="0" style="display: inline;" src="http://farm5.static.flickr.com/4111/5075135512_f439d0d7e8_m.jpg" width="168"/></a></td>
</tr>
</table>
<p></center></p>
<h3>Rooting the phone</h3>
<p>Now you have exploitable image installed it is time to root the phone.  This can be done using a back door.  Go to the home screen then type&#8230;</p>
<pre>
&lt;return&gt;
&lt;return&gt;
telnetd
&lt;return&gt;
</pre>
<p>&#8230;on the slide out keyboard.  This will look like a search in contacts for the name of <em>telnetd</em>.  In fact <em>telnetd</em> is the telnet daemon which allows you to connect to shell on the phone via telnet.  So now you need a telnet client.  Use the Android Market to download a telnet client.  Once installed you should be able to telnet to <em>localhost</em> and get a telnet prompt.</p>
<p>If all is well you have shell access as root (a &#8216;#&#8217; prompt).  Yay!</p>
<h3>Installing a recovery image</h3>
<p>Now we are going to install the recovery image we downloaded earlier. This will also give us permanent root access.  In the shell type&#8230;</p>
<pre>
mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system
cd sdcard
flash_image recovery recovery-RA-dream-v1.5.2.img
cat recovery-RA-dream-v1.5.2.img > /system/recovery.img
</pre>
<p>For those who are interested the lines do the following:</p>
<ol>
<li>Remounts the flash memory in read/write mode.  This allows you to save to the flash in the phone.</li>
<li>Navigate to the sdcard (which is mounted at /sdcard)</li>
<li>Flashes the recovery-RA-dream-v1.5.2.img image file in to the special recovery partition in the flash.</li>
<li>Copies the recovery-RA-dream-v1.5.2.img as /system/recovery.img (The Android busybox doesn&#8217;t have the copy command but cat with a pipe works just as well!).</li>
</ol>
<p>Once you&#8217;ve done this and have a prompt again you can reboot the phone.  This time if you hold down the home and power buttons when you power on the phone it will boot in to the recovery image.  You can use the short cuts or the track ball to select a menu item.</p>
<p>Now we are ready to install the new software.</p>
<p><a href="http://www.flickr.com/photos/39013214@N03/5074537061" title="View 'Custom recovery image menu' on Flickr.com"><img height="240" style="display:block; margin-left:auto; margin-right:auto;" alt="Custom recovery image menu" border="0" src="http://farm5.static.flickr.com/4071/5074537061_048eed984f_m.jpg" width="166"/></a></p>
<h2>New radio software and DangerSPL</h2>
<p>Now we have to repartition the flash to give enough room for the new platform.  This is the scary bit.  As I said before&#8230;</p>
<p><span style="text-color: #ff0000;"><strong>Finally I provide no warranty express or implied.  You are doing this to your phone.  If it goes wrong its your fault!  You have been warned!</strong></span></p>
<p>Read this page thoroughly <a href="http://wiki.cyanogenmod.com/index.php?title=Dream:DangerSPL">http://wiki.cyanogenmod.com/index.php?title=Dream:DangerSPL</a>.  If you&#8217;ve gotten this far you fulfil the prerequisites to install Danger/SPL.  You now need to download the appropriate radio image, place it in the root of your SD card and flash it.  Remember that number we noted down from the boot-loader screen at the start (<em>&#8220;RADIO-2.22.19.26I&#8221;</em> or similar).  You will need it now.</p>
<p>Boot in to recovery by holding down the home and power buttons. Select <em>&#8220;Flash zip from sdcard&#8221;</em>.  Select <em>update.zip</em> (if that&#8217;s the name of the file) from the file menu.  The image should be flashed and will then reboot the phone.  Reboot the phone again.</p>
<p>Take out the SD card and boot back in to the boot loader.  It should now appear as below.</p>
<p><a href="http://www.flickr.com/photos/39013214@N03/5074537429" title="View 'Updated Google G1 bootloader' on Flickr.com"><img height="240" style="display:block; margin-left:auto; margin-right:auto;" alt="Updated Google G1 bootloader" border="0" src="http://farm5.static.flickr.com/4043/5074537429_0bebc5256a_m.jpg" width="179"/></a></p>
<h2>Upgrading to FROYO and installing Google Apps</h2>
<p>All the hard work is now done.  You have a rooted phone with a nice recovery menu which allows you to flash anything that will fit.</p>
<p>To install the latest Android read this link: <a href="http://wiki.cyanogenmod.com/index.php?title=Dream:Installing_CyanogenMod_5%2B">http://wiki.cyanogenmod.com/index.php?title=Dream:Installing_CyanogenMod_5%2B</a>.</p>
<p>Clear out your SD card and download <a href="http://wiki.cyanogenmod.com/index.php?title=Latest_Version#DreamCM6">Froyo for the G1/Dream</a> and the <a href="http://wiki.cyanogenmod.com/index.php?title=Latest_Version#Google_Apps">Google <strong>Tiny</strong> Apps</a> (The G1 is a bit short on flash space so wont fit the all singing all dancing versions of the Google apps).  Boot in to recovery as before (home and power buttons) and again select <em>&#8220;Flash zip from sdcard&#8221;</em>.  Flash first Froyo and then the apps.</p>
<p>Finally reboot your phone.  You should now have Android 2.2 installed!</p>
<p><center><br />
<table>
<tr>
<td><a href="http://www.flickr.com/photos/39013214@N03/5074537651" title="View 'Cyanogen's Froyo (Android 2.2) booting' on Flickr.com"><img height="240" alt="Cyanogen's Froyo (Android 2.2) booting" border="0" style="display: inline;" src="http://farm5.static.flickr.com/4068/5074537651_fd8dc6e0e7_m.jpg" width="179"/></a></td>
<td><a href="http://www.flickr.com/photos/39013214@N03/5075136748" title="View 'Cyanogen's Froyo (Android 2.2) home screen.' on Flickr.com"><img height="240" alt="Cyanogen's Froyo (Android 2.2) home screen." border="0" style="display: inline;" src="http://farm5.static.flickr.com/4089/5075136748_9bb89e6b2c_m.jpg" width="179"/></a></td>
</tr>
</table>
<p></center></p>
<h2>Issues</h2>
<p>The only issue I had was an exception from the keyboard software the first time I used Froyo.  This can be solved using the <em>&#8220;Wipe&#8221;</em> menu in the recovery image.  I wiped data, cache and delvik cache (The latter generated an error I ignored) and then re-installed Froyo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/10/22/upgrading-your-uk-t-mobile-google-g1-htc-dream-to-android-2-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing http://projects.cyberspice.org.uk/</title>
		<link>http://www.cyberspice.org.uk/blog/2010/09/29/announcing-httpprojects-cyberspice-org-uk/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/09/29/announcing-httpprojects-cyberspice-org-uk/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 14:03:23 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Acorn]]></category>
		<category><![CDATA[BBC Micro]]></category>
		<category><![CDATA[BBC Microcomputer]]></category>
		<category><![CDATA[Beebthernet]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=478</guid>
		<description><![CDATA[I am pleased to say that I have finally gotten around to starting to publish details of the hardware projects I have been working on. I have created a new site http://projects.cyberspice.org.uk/ which contains all the details of these projects. Over the next few days I will be updating it with the details of Beebthernet, [...]]]></description>
			<content:encoded><![CDATA[<p>I am pleased to say that I have finally gotten around to starting to publish details of the hardware projects I have been working on.  </p>
<p>I have created a new site <a href="http://projects.cyberspice.org.uk/">http://projects.cyberspice.org.uk/</a> which contains all the details of these projects.  Over the next few days I will be updating it with the details of Beebthernet, my programmable earrings and so on.  Each of the projects will be described in detail and links to software and schematic downloads provided.</p>
<p>The first documented project is my ethernet for a BBC Microcomputer project known as <a href="http://projects.cyberspice.org.uk/beebthernet/">Beebthernet</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/09/29/announcing-httpprojects-cyberspice-org-uk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enumerating note data in Flickr using PHP</title>
		<link>http://www.cyberspice.org.uk/blog/2010/09/24/enumerating-note-data-in-flickr-using-php/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/09/24/enumerating-note-data-in-flickr-using-php/#comments</comments>
		<pubDate>Fri, 24 Sep 2010 12:44:38 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Flickr]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=466</guid>
		<description><![CDATA[Flickr provides a comprehensive API to access its data. It also has a very neat notes facility that allows you to add notes to a region of an image which pop-up when you mouse over the relevant area. Flickr provides API calls to add, edit and delete notes but not to enumerate notes associated with [...]]]></description>
			<content:encoded><![CDATA[<p>Flickr provides a comprehensive API to access its data.  It also has a very neat notes facility that allows you to add notes to a region of an image which pop-up when you mouse over the relevant area.  Flickr provides API calls to add, edit and delete notes but not to enumerate notes associated with an image.  To do that you have to do a little more work.</p>
<p><span id="more-466"></span></p>
<p>Flickr provides the following APIs to access notes:</p>
<ul>
<li><a href="http://www.flickr.com/services/api/flickr.photos.notes.add.html">flickr.photos.notes.add</a></li>
<li><a href="http://www.flickr.com/services/api/flickr.photos.notes.edit.html">flickr.photos.notes.edit</a></li>
<li><a href="http://www.flickr.com/services/api/flickr.photos.notes.delete.html">flickr.photos.notes.delete</a></li>
</ul>
<p>The first API takes the photo id, coordinates (appropriate for a 500 pixel wide image) and text of the note to add.  The second takes the note id, new coordinates and text to update the note with.  The third takes the note id of the note to delete.  As you can see there&#8217;s no way, using the API, of getting the ids of notes already associated with an image.  The API only allows you to edit and delete notes that you have created using the API.</p>
<p>However all is not completely lost.  Flickr outputs very nice HTML with HTML elements having sensible class names and so on.  The layout of a Flickr image page is basically as follows:</p>
<p><center></p>
<table>
<tr style="border: 1px solid white; margin: 5px; spacing: 5px; text-align: center;">
<td style="border: 1px solid white; margin: 5px; spacing: 5px;">
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
<p>
id=&#8221;notes&#8221;</p>
<p>
</div>
<p>id=&#8221;photo&#8221;
</p></div>
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;meta&#8221;
</div>
<div style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;comments&#8221;
</div>
<p>id=&#8221;primary-column&#8221;
</td>
<td style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;sidebar&#8221;
</td>
<td style="border: 1px solid white; margin: 5px; spacing: 5px;">
id=&#8221;shortcuts&#8221;
</td>
</tr>
</table>
<p></center></p>
<p>All of the elements are <strong>&lt;div;&gt;</strong> elements except for &#8220;notes&#8221; which is an un-ordered list.  Each of the notes themselves is a list item.  Below is a typical note list item.  As you can see it looks some what complicated.  This is because it includes the code needed to render the border of the note&#8217;s active area together with re-size corners.  However we can ignore most of it.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;li class=&quot;box note note-byowner note-highlight&quot; data-note-user_id=&quot;38990160&quot; data-note-id=&quot;72157624923250854&quot; style=&quot;left: 253px; top: 56px; width: 94px; height: 120px; z-index: 2; &quot; id=&quot;yui_3_1_0_1_1285322792456209&quot;&gt;
&lt;span class=&quot;box-stroke box-stroke-outer&quot; id=&quot;yui_3_1_0_1_1285322792456803&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;box-stroke box-stroke-inner&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;box-stroke box-stroke-main&quot; id=&quot;yui_3_1_0_1_1285322792456784&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;note-content&quot; id=&quot;yui_3_1_0_1_1285322792456788&quot;&gt;
&lt;span class=&quot;note-text&quot; id=&quot;yui_3_1_0_1_1285322792456792&quot;&gt;
&lt;span class=&quot;note-wrap&quot; id=&quot;yui_3_1_0_1_1285322792456832&quot;&gt;WIZ810MJ ethernet module.&lt;/span&gt;
&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-nw&quot;&gt;&lt;span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-ne&quot;&gt;
&lt;span&gt;
&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-se&quot;&gt;&lt;span&gt;
&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;resize resize-sw&quot;&gt;
&lt;span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;</pre></div></div>

<p>The only elements of interest is the list item itself and the plain text it contains.  The list item includes meta data which is useful to us.  The <em>data-note-id</em> value is the note id value to use in the Flickr API, the <em>style</em> provides the coordinates and size of the note&#8217;s active area, and the plain text is the actual note description.  This makes it reasonably easy to extract using &#8220;screen scraping&#8221;.</p>
<p>The Simple HTML DOM parser is a couple of PHP objects that parses HTML and allows you to access the DOM in a way similar to JQuery.  It uses the MIT licence and is freely available from <a href="http://sourceforge.net/projects/simplehtmldom/files/">SourceForge</a>.  Using this parser we can extract the notes information from the Flickr web page for the image.</p>
<p>The URL for an image page on flickr is:</p>
<pre>
http://www.flickr.com/photos/&lt;user id&gt;/&lt;photo id&gt;/
</pre>
<p>The following example code displays the note information for notes related to an image in my Flickr stream.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Using the SimpleHTMLDOM parser.</span>
<span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'simple_html_dom.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create a new parser</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> simple_html_dom<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Parse the web page for the image we want the notes for</span>
<span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load_file</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.flickr.com/photos/39013214@N03/4976074521/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Flickr keeps all the notes in a &lt;ul&gt; with a class id of 'notes'</span>
<span style="color: #000088;">$notes</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$html</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#notes'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Each note is a list item</span>
<span style="color: #000088;">$note_items</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$notes</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'li'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Iterate through the notes</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$note_items</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Get the id</span>
	<span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data-note-id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Get the coordinates</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'style'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$style_item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;:&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$style_item</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'left'</span>  <span style="color: #339933;">:</span> <span style="color: #000088;">$left</span>   <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'top'</span>   <span style="color: #339933;">:</span> <span style="color: #000088;">$top</span>    <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'width'</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$width</span>  <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'height'</span><span style="color: #339933;">:</span> <span style="color: #000088;">$height</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Get the text</span>
	<span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Output info</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Id: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$id</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Coords:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Left  : &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$left</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Top   : &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$top</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Width : &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$width</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;  Height: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$height</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Text: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$text</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As you can see Simple HTML DOM parser makes things simple.  The page for the image is loaded and parsed.  Then the first element with the id of &#8220;notes&#8221; is found (there should be only one).  Then an array of the list item elements to the &#8220;notes&#8221; element is obtained and iterated over.  The <em>data-note-id</em> item is the note id; the <em>style</em> is parsed to extract the coordinates and size of the active area; and the plain text, i.e. the note text, is copied.</p>
<p>The output from the example code is as follows:</p>
<pre>
kring:simplehtmldom melanie$ php test.php
Id: 72157624923250854
Coords:
  Left  : 253px
  Top   : 56px
  Width : 94px
  Height: 120px
Text: WIZ810MJ ethernet module.

Id: 72157624798614851
Coords:
  Left  : 254px
  Top   : 177px
  Width : 95px
  Height: 77px
Text: Adapter to allow it to be plugged in to breadboard (the WIZ810MJ has 2mm pitch connectors)

Id: 72157624923256462
Coords:
  Left  : 205px
  Top   : 204px
  Width : 49px
  Height: 67px
Text: 3.3V regulation.

Id: 72157624798617733
Coords:
  Left  : 354px
  Top   : 233px
  Width : 91px
  Height: 72px
Text: From BBC micro 8 bit &quot;User&quot; parallel port.

Id: 72157624923259400
Coords:
  Left  : 103px
  Top   : 299px
  Width : 242px
  Height: 64px
Text: Boarduino to provide 5V power.
</pre>
<p>Using this information you can update the note using the Flickr API or display the image complete with notes on your own page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/09/24/enumerating-note-data-in-flickr-using-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using multiple private keys with SSH</title>
		<link>http://www.cyberspice.org.uk/blog/2010/07/23/using-multiple-public-keys-with-ssh/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/07/23/using-multiple-public-keys-with-ssh/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 10:13:39 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=459</guid>
		<description><![CDATA[A couple of days ago I posted on how to set up a subversion server with ssh access. In that post, in the section about creating your private ssh key I said that if you already had an id_rsa or id_dsa file in your ~/.ssh directory not to go any further because the generation of [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of days ago I posted on how to set up a subversion server with ssh access.  In that post, in the section about creating your private ssh key I said that if you already had an <em>id_rsa</em> or <em>id_dsa</em> file in your ~/.ssh directory not to go any further because the generation of a new private key file could over write it.  This post explains how to cope with multiple private keys.</p>
<p>ssh uses <em>~/.ssh/identity</em> as the default filename for the private key when using version 1 of the ssh protocol and it uses <em>~/.ssh/id_rsa</em> and <em>~/.ssh/id_dsa</em> as the default filenames for the RSA and DSA private keys when using version 2 of the ssh protocol.  However there are several ways of changing this behaviour.</p>
<h2>Command line</h2>
<p>ssh allows you to provide a different identity/id file using the -i option on the ssh command line as follows:</p>
<pre>
$ ssh -i /path/to/id_rsa user@some.domain.org
</pre>
<p>Where <em>id_rsa</em> can be substituted with <em>id_dsa</em> or <em>identity</em>.</p>
<p>This is the simplest method.  And when used in conjunction with a subversion client you can create a [tunnel] in the subversion configuration file like so:</p>
<pre>
[general]
ssh = ssh -i /path/to/identity_file
</pre>
<p>If you want to support different identity/id files create a new [tunnel] &#8216;alias&#8217; for each identity file.  You can also use the -p option if you want to specify a different port at the same time.</p>
<h2>Config file &#8211; first method</h2>
<p>Another method is to use the ssh config file.  The global file is found in <em>/etc/ssh/config</em> however you can also provide config files on a per user basic in <em>~/.ssh</em>.  In the config file you can restrict declarations using the <strong>Host</strong> declaration.  Per the man page:</p>
<pre>
Host
   Restricts the following declarations (up to the next Host
   keyword) to be only for those hosts that match one of the
   patterns given after the keyword.  If more than one pattern
   is provided, they should be separated by whitespace.  A
   single `*' as a pattern can be used to provide global defaults
   for all hosts.  The host is the hostname argument given on
   the command line (i.e. the name is not converted to a
   canonicalized host name before matching).
</pre>
<p>The declaration <strong>IdentityFile</strong> allows you to specify the private key file that ssh should use.  By using <strong>Host</strong> and <strong>IdentityFile</strong> you can let ssh pick the identity/id file itself based upon the host name.  The following example will pick <em>~/.ssh/id_dsa</em> for any host other than <strong>my.specific.host.org</strong> and <strong>my.other.host.com</strong>.  In those cases the specified private key files are used.</p>
<pre>
# General settings
IdentityFile ~/.ssh/id_rsa
IdentifyFile ~/.ssh/id_dsa
IdentityFile ~/.ssh/identity

Host my.specific.host.org
IdentityFile ~/.ssh/my_specific_key_file

Host my.other.host.com
IdentityFile ~/.ssh/my_other_key_file
</pre>
<p>Note how the config file allows you to specify more than one file at once.  When you do ssh will try each of the files in turn or as appropriate.</p>
<h2>Config file &#8211; second method</h2>
<p>The problem with the above method is that you have to keep adding new entries to the config file for new hosts.  <strong>IdentityFile</strong> is actually very powerful and allows you to have wild cards in the path specification.  The full man page definition says:</p>
<pre>
IdentityFile
   Specifies a file from which the user's RSA or DSA
   authentication identity is read.  The default is ~/.ssh/identity
   for protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa
   for protocol version 2. Additionally, any identities
   represented by the authentication agent will be used for
   authentication.

   The file name may use the tilde syntax to refer to a user's
   home directory or one of the following escape characters:
   `%d' (local user's home directory), `%u' (local user name),
    `%l' (local host name), `%h' (remote host name) or `%r'
   (remote user name).

   It is possible to have multiple identity files specified in
   configuration files; all these identities will be tried in
   sequence.
</pre>
<p>So I have set up my config file as below.  It basically tries ~/.ssh/idents/hostname/username/id_* first, then ~/.ssh/idents/hostname/id_*, then the defaults before giving up.</p>
<pre>
# SSH config file

IdentityFile ~/.ssh/idents/%h/%u/id_rsa
IdentityFile ~/.ssh/idents/%h/%u/id_dsa
IdentityFile ~/.ssh/idents/%h/id_rsa
IdentityFile ~/.ssh/idents/%h/id_dsa
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_dsa
</pre>
<p>This allows me to support a new server/key file combination just by putting the key file in the appropriate place in the <em>~/.ssh</em> without having to edit config files.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/07/23/using-multiple-public-keys-with-ssh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up a subversion plus ssh server</title>
		<link>http://www.cyberspice.org.uk/blog/2010/07/20/setting-up-a-subversion-plus-ssh-server/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/07/20/setting-up-a-subversion-plus-ssh-server/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 14:46:47 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=453</guid>
		<description><![CDATA[As someone who is a strong advocate of source control at work I&#8217;m actually quite bad at following what I preach. So this lunch time I decided to finally get around to setting up a Subversion server on my Linux server. Installation I am currently running Ubuntu 9.10 so installed subversion as follows: $ sudo [...]]]></description>
			<content:encoded><![CDATA[<p>As someone who is a strong advocate of source control at work I&#8217;m actually quite bad at following what I preach.  So this lunch time I decided to finally get around to setting up a Subversion server on my Linux server.  </p>
<h2>Installation</h2>
<p>I am currently running Ubuntu 9.10 so installed subversion as follows:</p>
<pre>
$ sudo apt-get install subversion
</pre>
<p>If you don&#8217;t have ssh installed (why not?) install it similarly.</p>
<h2>Users and groups</h2>
<p>Once you have subversion and ssh installed you can set up the SVN server.  Firstly you need to create a suitable users group, an admin user and a repository.</p>
<p>Create the group like so:</p>
<pre>
$ sudo groupadd -g 127 svnusers
</pre>
<p>The group id (127 above) needs to be unique so unless you know a free group id value check to see the last id used in  the groups file as follows:</p>
<pre>
$ tail /etc/group
</pre>
<p>Then create an SVN admin user using useradd as below:</p>
<pre>
$ sudo useradd -c "SVN Admin" -u 2000 -g 127 -d /home/svnadmin -m -s /bin/bash svnadmin
</pre>
<p>Again the user id (2000 above) needs to be unique.  This time look at /etc/passwd to find out the last id used.  The group id (127 above) should be the same value as the group you created.  The rest of the options tell <em>useradd</em> to  create a home directory and to set the default shell to be bash.</p>
<p>Set the password for the SVN admin user like so:</p>
<pre>
$ sudo passwd svnadmin
</pre>
<p>Finally add any other users to the <strong>svnusers</strong> group by editing /etc/group and adding the additional users in a comma separated list on the end.  For example:</p>
<pre>
svnusers:x:127:svnadmin,melanie
</pre>
<h2>Server setup</h2>
<p>Now its time to create a repository.  Firstly create the directory where all the repositories will be stored.  I put mine in /var since my /var is on separate partition (to protect from disk full issues).  However you can put them where you want.  So create the directory and set the permissions as below:</p>
<pre>
$ mkdir -p /path/to/subversion/repositories
$ chown -R root.svnusers /path/to/subversion/repositories
$ chmod -R 770 /path/to/subversion/repositories
</pre>
<p>When using ssh, <em>svnserve</em> is used as the SVN server.  <em>svnserve</em> requires the full path to repository to be provided by the client to access the repository.  You may not want to expose your file system that much so you can write a small script to modify the behaviour.  Use <em>which</em> to find out where <em>svnserve</em> is and rename it.</p>
<pre>
$ which svnserve
/usr/bin/svnserve
$ sudo mv /usr/bin/svnserve /usr/bin/svnserve.bin
</pre>
<p>Then using your favourite editor create the script below and save it under the old <em>svnserve</em> name.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>svnserve.bin <span style="color: #660033;">-r</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>subversion<span style="color: #000000; font-weight: bold;">/</span>repositories <span style="color: #ff0000;">&quot;$@&quot;</span></pre></div></div>

<p>Finally set the execute permissions.</p>
<pre>
$ sudo chmod 755 /usr/bin/svnserve
</pre>
<h2>Creating a project</h2>
<p>Now its time to create a project.  Change to the <strong>svnadmin</strong> user and enter the password.</p>
<pre>
$ su - svnadmin
password:
</pre>
<p>Now create a project and turn off other access so that only members of the <strong>svnusers</strong> group and the admin user can access it.</p>
<pre>
$ svnadmin create /path/to/subversion/repositories/my_first_project
$ chmod -R o-rwx /path/to/subversion/repositories/my_first_project
</pre>
<p>Finally you need to configure the project&#8217;s access permissions by editing </p>
<pre>
/path/to/subversion/repositories/my_first_project/conf/svnserve.conf
</pre>
<p>In the <strong>[general]</strong> section uncomment or add:</p>
<pre>
anon-access = none
auth-access = write
</pre>
<p>Now save the file.  </p>
<h2>Testing</h2>
<p>Now you should be able to access the svn repository from anywhere provided the user is in the <strong>svnusers</strong> group.  Test as follows from a client.</p>
<pre>
$ svn list svn+ssh://user@some.domain.org/my_first_project
</pre>
<p>You will be asked for the ssh password for the machine running subversion.  And that&#8217;s it.  You should be able to use your project.  You can add new projects using the <strong>svnadmin</strong> user.</p>
<h2>Further tweaks</h2>
<p>There a couple of additional things you may want to do.  Firstly my subversion server is behind a firewall.  The machine it is on is accessed using ssh on a different port to the default.  Secondly keep being asked for the ssh password can become quite a pain.  Using public key authentication does make things somewhat easier.</p>
<h2>Using an alternative ssh port</h2>
<p>Annoyingly SVN does not understand the &#8216;username@domain:port&#8217; syntax.  It doesn&#8217;t know what to do with the port.  However you can use svn&#8217;s configuration files to create a custom &#8216;protocol&#8217;.  This allows you to add support for an alternative port through the configuration file.</p>
<p>You client user should have a file </p>
<pre>
~/.subversion/config
</pre>
<p>If not, create it.  In it there should be a <strong>[tunnels]</strong> section.  To that you can add a new &#8216;protocol&#8217;.  I created <strong>sshhome</strong> as follows:</p>
<pre>
[general]
sshhome = ssh -q -p 1234
</pre>
<p>The -q option prevents the &#8220;Killed by signal 15&#8243; message that you see with some versions of subversion.  You can then use <strong>sshhome</strong> instead of <strong>ssh</strong> as the protocol and it will use the specified port.  E.g.</p>
<pre>
$ svn list svn+sshhome://user@some.domain.org/my_first_project
</pre>
<h2>Public key authentication</h2>
<p>Finally to save having to enter your password all the time you can create a public key and install it on the server.  On the client change to the ~/.ssh directory.  Now if there&#8217;s already a file in it called <em>id_dsa</em> or <em>id_rsa</em> STOP.  I&#8217;m not sure how to support multiple keys yet and create a new key will over write these files.  If all is well create a set of keys as below.  Do not use an empty passphrase.  It&#8217;s also good security not to use your password as the passphrase.</p>
<pre>
$ ssh-keygen -t dsa -C "username@some.domain.org"
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/username/.ssh/id_dsa.
Your public key has been saved in /Users/username/.ssh/id_dsa.pub.
The key fingerprint is:
</pre>
<p>Now you need to put the public key on to the server.  Copy the file in to your home directory on the SVN server.  You can use <em>scp</em> for that.</p>
<pre>
$ scp id_dsa.pub username@some.domain.org:/path/to/home/directory/.ssh
</pre>
<p>Then log in to the SVN server and change to the ~/.ssh directory.  In that directory add the public key to the file of authorized keys and set the permissions.  Then delete the public key file.  See below:</p>
<pre>
$ cat id_dsa.pub  >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
$ rm id_dsa.pub
</pre>
<p>And that should be it.  Try listing your project directory again.  This time for the first time it will ask you for your password but then it will only ask for the password infrequently.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/07/20/setting-up-a-subversion-plus-ssh-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DPC 2010</title>
		<link>http://www.cyberspice.org.uk/blog/2010/07/15/dpc-2010/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/07/15/dpc-2010/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 21:17:08 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[dpc10]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=451</guid>
		<description><![CDATA[A couple of weeks ago I went to the Dutch PHP Conference 2010 and I had an amazing time. The event was held in Amsterdam at the RAI centre. The primary sponsor was iBuildings and the entire event was organised by the totally awesome Lornajane. When DPC 2010 announced the call for papers I submitted [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I went to the Dutch PHP Conference 2010 and I had an amazing time.  The event was held in Amsterdam at the RAI centre.  The primary sponsor was <a href="http://www.ibuildings.nl/">iBuildings</a> and the entire event was organised by the totally awesome <a href="http://www.lornajane.net/">Lornajane</a>.</p>
<p>When DPC 2010 announced the call for papers I submitted both a proposal for a tutorial on PHP extensions and one for a talk on web services.  Both were excepted.  I had proposed both half day and full day versions of the tutorial the organisers chose the full day version.  This turned out to be a lot of work.  Basically I would be talking for 6 hours in four 90 minute slots.<br />
<span id="more-451"></span><br />
The web services talk was to be trailed at the PHP NW group in May.  Unfortunately being stuck in the US due to the Icelandic Volcano and its dust cloud didn&#8217;t give me much time to prepare for it.  However by the time of the group meeting I had a basic talk.  This meant I could devote the rest of the time up to DPC preparing the tutorial.</p>
<p>Since it is still early in my speaking career I don&#8217;t yet have the experience to accurately judge how long a talk will take.  I had never done a tutorial before so I had no experience to base it on.  In the end I came up with a plan where I had some &#8216;optional&#8217; sections which I could add on the end if I ran short.  It was scary to see how much content I required and took me several weeks to prepare in odd evenings.  In the end it came in at over 100 slides together with four example extensions.</p>
<p>I flew to Amsterdam courtesy of KLM&#8217;s direct flight from Leeds Bradford Airport to Schipol.  Since the hotel was right by Amsterdam Centraal train station it was a simple train ride from the airport and a short walk.  After meeting other attendees and speakers in the hotel foyer I headed up to my room to finish preparation for the Friday.  It turned out that I wasn&#8217;t by the station, my room was in a building <strong>over</strong> the station.  It straddled two platforms and a set of tracks.</p>
<p>The following morning I got up early and Lornajane helped me, and others, get to the conference venue.  I was extremely nervous.  This wasn&#8217;t helped by finding out that many of iBuilding&#8217;s own staff would be in my Extensions tutorial.  In the end the day went very quickly.  As usual when I&#8217;m nervous I spoke to quickly.  Luckily I could answer all questions and also had a chance to talk about some side projects.  I finished early so I turned the last session in to a workshop to any who wanted to try their hand at writing an extension.  I was very pleased at how well it had been received.</p>
<p>That evening a whole bunch of us were going to an Indonesian fusion restaurant.  Unfortunately due to our guide getting a little lost and my impractical shoes I arrived tired with sore feet.  The food was great but I wanted to get back to the hotel and sleep.  As I was still nervous about the talk the following day I didn&#8217;t sleep well.  I also had the dilemma of either being too warm or it being too noisy with the trains.</p>
<p>The following morning I woke very tired.  I met with some friends and fellow conference people at breakfast and we all headed off for the first of the two days of conference talks.  It was an awesome Friday keynote from <a href="http://www.two-sdg.demon.co.uk/curbralan/kevlin.html">Kevlin Henney</a>.  I had seen him speak before an PHP NW 2009 and he did not disappoint.  Following talks were equally impressive.  My slot was on after afternoon tea which is always hard work and by then I was tired out.  It was not a great talk.  Although fine for the PHP NW group meeting it was a little basic for an international conference.  I will know for next time.</p>
<p>That evening was the Speakers dinner which was thoroughly enjoyable.  I got to talk to Kevlin and others and since by then I had given all my content I could have a bit of a drink and not worry about having to make it the following morning although since the Saturday keynote was being given by <a href="http://shiflett.org/">Chris Shiflett</a> who I had also seen before and thoroughly enjoyed I was too late to bed so that I could be there on time to see him. </p>
<p>Sunday provided another day of great speakers and talks.  Thoroughly enjoyable.  Then the conference wound down.  Those of us who were staying the Saturday night headed off for pancakes.  Marcus and I got completely lost in Amsterdam due to confusing instructions from Ivo (it was the <em>wrong</em> social he was talking about) and eventually turned up about an hour later than everyone else.  However the pancakes were well worth it.  It was followed by some more drinking and then bed.</p>
<p>Since Lornajane and I live in the same city we were on the same KLM flight back from Amsterdam so we became travel partners.  Sunday was spent mostly hanging out in Amsterdam followed by an unstressed journey to the airport, a couple of beers waiting for our flight, and an uneventful flight home.</p>
<p>DPC 2010 was really good fun.  I learnt a lot, both from the talks and giving the tutorial and the talk.  I met many good friends and made lots of new ones.  Too many to have a check list here.  I&#8217;m now looking forward to my &#8216;home&#8217; conference, PHP NW 2010 in October.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/07/15/dpc-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DPC2010 &#8211; &#8220;PHP Extensions Tutorial&#8221; and &#8220;Web Services For Consumer Devices&#8221;</title>
		<link>http://www.cyberspice.org.uk/blog/2010/06/12/dpc2010-php-extensions-tutorial-and-web-services-for-consumer-devices/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/06/12/dpc2010-php-extensions-tutorial-and-web-services-for-consumer-devices/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 10:20:42 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[dpc10]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=447</guid>
		<description><![CDATA[I am still at the Dutch PHP Conference and very enjoyable it is too. I have now given my two talks. The first was an all day session on writing PHP extensions in C. The second was a regular 45 minute session on Web Services For Consumer Devices. PHP Extensions This tutorial covered writing PHP [...]]]></description>
			<content:encoded><![CDATA[<p>I am still at the Dutch PHP Conference and very enjoyable it is too.  I have now given my two talks.  The first was an all day session on writing PHP extensions in C.  The second was a regular 45 minute session on Web Services For Consumer Devices.</p>
<h2>PHP Extensions</h2>
<p>This tutorial covered writing PHP extensions from the very beginning right through to writing objects and classes in C.  I think this went well.  Its a lot for beginners to cover so naturally some people got lost towards the end but I have had some good feedback.  Links to the slides and examples are below.</p>
<div style="margin-left: auto;margin-right: auto">
<table>
<tr>
<td><strong>Slides</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/PHPExtensions-Final-20100612.pdf">PHPExtensions-Final-20100612.pdf</a></td>
</tr>
<tr>
<td><strong>Example &#8211; Hello World</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/ExtensionTutorial/hello_world-20100612.tgz">hello_world-20100612.tgz</a></td>
</tr>
<tr>
<td><strong>Example &#8211; Hello World (Extended)</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/ExtensionTutorial/hello_world-20100612.tgz">hello_world_extended-20100612.tgz</a></td>
</tr>
<tr>
<td><strong>Example &#8211; Memory Stream</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/ExtensionTutorial/http://www.cyberspice.org.uk/downloads/ExtensionTutorial/memory_stream-20100612.tgz">memory_stream-20100612.tgz</a></td>
</tr>
<tr>
<td><strong>Framegrab (PECL)</strong></td>
<td><a href="http://pecl.php.net/package/framegrab">http://pecl.php.net/package/framegrab</a></td>
</tr>
</table>
</div>
<h2>Web Services For Consumer Devices</h2>
<p>This talk covered what to consider when writing a service to be used by an application on a consumer devices.  I agree with the commenters who felt it was a little light.  Yes it needs revision before it gets reused.</p>
<p><a href="http://www.cyberspice.org.uk/downloads/ WebServicesForConsumerDevices-20100612.pdf">WebServicesForConsumerDevices-20100612.pdf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/06/12/dpc2010-php-extensions-tutorial-and-web-services-for-consumer-devices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CELF Embedded Linux Conference 2010</title>
		<link>http://www.cyberspice.org.uk/blog/2010/04/22/celf-embedded-linux-conference-2010/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/04/22/celf-embedded-linux-conference-2010/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 04:05:30 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Talks]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=443</guid>
		<description><![CDATA[I will write a proper report of the CELF Embedded Linux Conference 2010 soon however I have uploaded the slides to my talk, &#8220;Case Study &#8211; Embedded Linux in a Digital Television STB&#8221;, for download here.]]></description>
			<content:encoded><![CDATA[<p>I will write a proper report of the <a href="http://www.embeddedlinuxconference.com/elc_2010/">CELF Embedded Linux Conference 2010</a> soon however I have uploaded the slides to my talk, &#8220;Case Study &#8211; Embedded Linux in a Digital Television STB&#8221;, for download <a href="http://www.cyberspice.org.uk/downloads/SetTopBoxCaseStudy.pdf">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/04/22/celf-embedded-linux-conference-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

