<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>Michael Maclean - Articles</title>
		<description>A software developer mainly interested in Linux, PHP, Python and the Web, based in Scotland.</description>
		<link>http://mgdm.net</link>
		
			
			<item>
				<title>zsh with Antigen</title>
				<description>&lt;p&gt;I&amp;#8217;ve been using &lt;a href='http://www.zsh.org'&gt;zsh&lt;/a&gt; for a while, with &lt;a href='https://github.com/robbyrussell/oh-my-zsh'&gt;oh-my-zsh&lt;/a&gt; to add a pile of new features to it. Oh-my-zsh is great, and has a lot of useful things in it, but I found it a bit of a pain to keep my fork of it in sync with the main repository and another fork that I&amp;#8217;d stolen things from. The fact that it was one giant repository with everything in there didn&amp;#8217;t seem quite right to me. Then, I came across &lt;a href='https://github.com/zsh-users/antigen'&gt;zsh-antigen&lt;/a&gt;, which promises to be to zsh what &lt;a href='https://github.com/tpope/vim-pathogen'&gt;Pathogen&lt;/a&gt; is to Vim. That sounded good to me, so I gave it a try.&lt;/p&gt;

&lt;p&gt;The main difference is that instead of having one repository with all the plugins, it lets you load plugins from pretty much any Git repository. It includes a special case for the oh-my-zsh repository, so you can load plugins and themes from there by default. I&amp;#8217;d recommend reading the &lt;a href='https://github.com/zsh-users/antigen'&gt;README in the Antigen repository&lt;/a&gt; to get the full story, but I&amp;#8217;ll give a quick overview of how I&amp;#8217;ve got mine set up here.&lt;/p&gt;

&lt;p&gt;First off, I created my own Git repository, and added the Antigen repository as a submodule. I&amp;#8217;ve called mine &lt;code&gt;.zsh-antigen&lt;/code&gt;, and it lives in my home directory.&lt;/p&gt;
&lt;script src='https://gist.github.com/mgdm/cf14dc0aad25e468411f.js'&gt;
&lt;/script&gt;
&lt;p&gt;Next I created my &lt;code&gt;zshrc&lt;/code&gt; file, at &lt;code&gt;~/.zsh-antigen/zshrc&lt;/code&gt;. I symlink it into my home directory to &lt;code&gt;~/.zshrc&lt;/code&gt;.&lt;/p&gt;
&lt;script src='https://gist.github.com/mgdm/5608243.js'&gt;
&lt;/script&gt;
&lt;p&gt;On lines 1 and 2, I set up a variable to refer to the antigen directory, and then load the antigen script itself.&lt;/p&gt;

&lt;p&gt;On line 4, we tell antigen to use oh-my-zsh by default. That way, we can load plugins from there with the &lt;code&gt;antigen-bundle&lt;/code&gt; command. I use a few, the vagrant and git plugins on all my machines, and I detect Mac OS X and load the osx plugin if I&amp;#8217;m on a Mac.&lt;/p&gt;

&lt;p&gt;I use a couple of bundles that don&amp;#8217;t belong to oh-my-zsh, too &amp;#8211; these are the &lt;code&gt;zsh-syntax-highlighting&lt;/code&gt; bundle from zsh-users, which adds nice syntax highlighting to the command line, and the &lt;code&gt;zsh-history-substring-search&lt;/code&gt; bundle that provides history search when you type part of a command and press the up cursor key. As you can see, if they&amp;#8217;re hosted on Github, it&amp;#8217;s as easy as specifying the repos in a &amp;#8220;username/repo-name&amp;#8221; format.&lt;/p&gt;

&lt;p&gt;On line 14, I load a bundle which is local to my config. (It just provides some path detection to tell me what app I&amp;#8217;m in when editing files on my work computer. These appear in the right prompt.) You can add as many bundles and as you like, without them having to be part of oh-my-zsh.&lt;/p&gt;

&lt;p&gt;Next, on line 16 I apply a theme. This is a theme in the same format as oh-my-zsh, and just specifies what appears in the left prompt (&lt;code&gt;PS1&lt;/code&gt;, as in Bash and similar shells) and &lt;code&gt;RPS1&lt;/code&gt; (which is right-aligned and doesn&amp;#8217;t normally exist in Bash).&lt;/p&gt;

&lt;p&gt;We then call &lt;code&gt;antigen-apply&lt;/code&gt; last of all, which applies all the previous configuration. When &lt;code&gt;antigen-apply&lt;/code&gt; is called, it will ensure that it has all the bundles and themes that have been requested. If not, it will go off and download them and cache them locally. This means that the first time you load antigen in a new shell, it&amp;#8217;ll wait a few seconds while it goes and grabs the oh-my-zsh code along with any other bundles you&amp;#8217;ve requested.&lt;/p&gt;

&lt;p&gt;Underneath this, I place all my useful environment variables, aliases, and install things like rbenv, the same way as I used to do in Bash. I find this way of working to be quite a bit cleaner than oh-my-zsh - the &lt;code&gt;.zshrc&lt;/code&gt; I ended up with in there had quite a lot going on, along with various &amp;#8216;magic&amp;#8217; things that I wasn&amp;#8217;t keen on. The automatic updating really got on my nerves, even though it&amp;#8217;s supposed to be convenient. Feel free to grab my repo and use it as a starting point if it&amp;#8217;s helpful.&lt;/p&gt;</description>
				<published>2013-05-19 19:30:00 +0100</published>
				<link>http://mgdm.net/weblog/zsh-antigen</link>
			</item>
			
		
			
			<item>
				<title>PHP room at FOSDEM 2013</title>
				<description>&lt;p&gt;I&amp;#8217;ve been intending to go to FOSDEM for a few years now, but so far I&amp;#8217;ve never quite got around to making it. This year, though, &lt;a href='http://lornajane.net'&gt;Lorna&lt;/a&gt; asked me if I was up for helping to run the PHP devroom. I said yes, and so this year I will be there!&lt;/p&gt;

&lt;p&gt;There are calls for papers open for the main track and lightning talks, which you can find on the &lt;a href='http://fosdem.org'&gt;FOSDEM site&lt;/a&gt;. We&amp;#8217;d also like to see submissions for talks in the PHP room&amp;#8211;head on over to the &lt;a href='http://lrnja.net/W1A2Nk'&gt;submission form&lt;/a&gt; to post your talks. This year, we&amp;#8217;re going to try an anonymized process to choose the talks. All we&amp;#8217;ll have to go on will be the talk title, abstract and length; no personally identifiable information will be there. As the form says, we don&amp;#8217;t care who you are, we just want great talks.&lt;/p&gt;

&lt;p&gt;FOSDEM is a huge, community-run event that takes place in Brussels every year. Attendance and participation is completely free to anyone. This does mean that we can&amp;#8217;t cover costs for accommodation or getting to and from Brussels, but we hope that doesn&amp;#8217;t put too many people off. As well as the PHP room, there will be a lot more going on in other tracks and rooms around the event, so there&amp;#8217;ll be plenty of things to see and do elsewhere. Hopefully I&amp;#8217;ll see some of you there.&lt;/p&gt;</description>
				<published>2012-11-19 00:00:00 +0000</published>
				<link>http://mgdm.net/weblog/fosdem-2013</link>
			</item>
			
		
			
			<item>
				<title>Why one-line installers are a bad idea</title>
				<description>&lt;p&gt;There has been a trend in the last while for various bits of useful software to have a one-line shell command recommended as the installation method. The usual form of this is to pipe something like &lt;code&gt;curl&lt;/code&gt; or &lt;code&gt;wget&lt;/code&gt; to some interpreter, be it &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;php&lt;/code&gt;, &lt;code&gt;ruby&lt;/code&gt;, or some such. They look like this (taken from &lt;a href='https://rvm.io/rvm/install/'&gt;RVM&amp;#8217;s installation page&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;curl -L https://get.rvm.io | bash -s stable --ruby&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;RVM is by no means the first bit of software to do this&amp;#8211;I remember at various stages PEAR, Homebrew, and others suggesting the same thing. This command takes the output of &lt;code&gt;curl&lt;/code&gt; and pipes it straight to &lt;code&gt;bash&lt;/code&gt;. I have several issues with this.&lt;/p&gt;

&lt;h2 id='it_gives_you_no_opportunity_to_inspect_the_code_that_you_are_running'&gt;It gives you no opportunity to inspect the code that you are running&lt;/h2&gt;

&lt;p&gt;In this example, you are blindly assuming that the code you get from http://get.rvm.io is actually the RVM installer. There is no verification of any form - if, for example, the host has been compromised, the installer might have been replaced with something as simple as an &lt;code&gt;rm -rf .&lt;/code&gt;, which would blow away anything in the current directory. Or, indeed, it could any other command that you have permission to run as the current user. It might not even be intentionally malicious&amp;#8211;there could just be a bug which has some &lt;a href='http://pcgamingwiki.com/wiki/Half-Life#Severe_System_Crippling_and_Data_Destroying_Uninstall_Bug'&gt;unexpected side-effect&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='there_is_no_way_to_verify_the_source_of_the_code'&gt;There is no way to verify the source of the code&lt;/h2&gt;

&lt;p&gt;It could be argued that because the code is delivered over HTTPS in this case, there is some verification of the identity of the source. This is not enough, as can be demonstrated by the case above, where the source is compromised. With packaging systems such as &lt;code&gt;dpkg&lt;/code&gt; or &lt;code&gt;rpm&lt;/code&gt;, there are cryptographic signatures attached to each package. These sign each release of the package in question, and hence there is a trust layer you can use to help decide if you wish to use the package source. Also, it can then flag up when the source may have been compromised.&lt;/p&gt;

&lt;p&gt;You can, of course, override the signature verification step in a package manager along the lines of &lt;code&gt;dpkg&lt;/code&gt; or &lt;code&gt;rpm&lt;/code&gt; or many others that I have not used; however, at that point, you are making the decision to do so yourself and therefore take responsibility for the results.&lt;/p&gt;

&lt;p&gt;In the case of PHP&amp;#8217;s Composer, which I&amp;#8217;ll come back to, &lt;a href='http://twitter.com/padraicb'&gt;Pádraic Brady&lt;/a&gt; &lt;a href='https://twitter.com/padraicb/status/246305589964181504'&gt;pointed out&lt;/a&gt; that the Composer people are aware of the issue of running arbitrary unsigned code, and a &lt;a href='https://github.com/composer/composer/pull/1092'&gt;pull request has been filed&lt;/a&gt; to fix part of it. Although I agree with many of the changes made, I don&amp;#8217;t believe it does anything to protect the installer itself. (I may be wrong here&amp;#8211;if I have misread, please let me know.)&lt;/p&gt;

&lt;h2 id='it_teaches_bad_habits'&gt;It teaches bad habits&lt;/h2&gt;

&lt;p&gt;The example that prompted this blog post is that of the PHP utility, &lt;a href='http://getcomposer.org'&gt;Composer&lt;/a&gt;. This is a wonderful piece of software for managing library dependencies within PHP projects. However, on their &lt;a href='http://getcomposer.org/download/'&gt;download page&lt;/a&gt;, they have two variants of the one-line installer, the first being along the pattern already discussed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;curl -s https://getcomposer.org/installer | php&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And the second, for &amp;#8220;if you don&amp;#8217;t have &lt;code&gt;curl&lt;/code&gt;&amp;#8221;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;php -r &amp;quot;eval(&amp;#39;?&amp;gt;&amp;#39;.
file_get_contents(&amp;#39;https://getcomposer.org/installer&amp;#39;));&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the former case, you are teaching your users that piping code downloaded from web sites directly to an interpreter is OK; in the latter example, you are teaching people that doing the same with &lt;code&gt;eval&lt;/code&gt; in PHP is also just fine. I, personally, think this is the worst part of all&amp;#8211;while running &lt;code&gt;curl&lt;/code&gt; to get the code is bad, it might also end up suggesting to people that &lt;code&gt;eval&lt;/code&gt; is just fine for this purpose, when even the most rudimentary material on security will say just the opposite. Software written in PHP has a bad enough reputation for careless use of its capability to open, and if you&amp;#8217;re not careful, execute &amp;#8216;files&amp;#8217; across the Web, and advocating this as part of an installation process is really not a good thing.&lt;/p&gt;

&lt;h2 id='in_summary'&gt;In summary&lt;/h2&gt;

&lt;p&gt;Although installers like this are undoubtedly convenient for the user, there is a huge risk as a result. Convenience and security undoubtedly do not go hand in hand; in this case, it would be far better to encourage people to download the installer file, and then perhaps verify it using a checksum such as SHA256&amp;#8211;although, of course, this is also open to compromise, it would be a start. The package could also be signed with GPG or a similar system. This would take the user a few minutes, which undoubtedly gets in the way of using the software in question. However, I believe in this case the loss of convenience is far outweighed by mitigating the security risks involved.&lt;/p&gt;</description>
				<published>2012-09-13 01:30:00 +0100</published>
				<link>http://mgdm.net/weblog/why-one-line-installers-are-bad</link>
			</item>
			
		
			
			<item>
				<title>New Toys</title>
				<description>&lt;p&gt;For someone who hardly ever actually writes anything, I do spend quite a long time messing about with the software that powers my site. I think over the years I&amp;#8217;ve variously used &lt;a href='http://www.wordpress.org'&gt;WordPress&lt;/a&gt;, &lt;a href='http://ez.no'&gt;eZ Publish&lt;/a&gt;, &lt;a href='http://habariproject.org'&gt;Habari&lt;/a&gt;, and probably other things that I&amp;#8217;ve forgotten to run a weblog but never actually use it. Welcome to the latest incarnation, which this time is powered by &lt;a href='https://github.com/mojombo/jekyll'&gt;Jekyll&lt;/a&gt;. I decided that running a database and a server-side language all the time for a site that doesn&amp;#8217;t get much traffic is pointless, and hence Jekyll suits my purposes by generating flat HTML files that require no further processing. It does also mean that I can store the site itself on Github, and write Markdown files in Vim to create posts, which appeals to my geek side.&lt;/p&gt;

&lt;p&gt;This time I built the theme from scratch myself, too, after spending a little too long reading books with names like &lt;em&gt;The Elements of Typographic Style&lt;/em&gt; and &lt;em&gt;Thinking With Type&lt;/em&gt;, as well as innumerable articles on &lt;a href='http://alistapart.com'&gt;A List Apart&lt;/a&gt; and places like that. I like to think that I have the typography of the site working to a reasonable level, and I&amp;#8217;ll probably continue to ham-fistedly play with the rest of it. Just writing this post resulted in me messing with the CSS of the navigation as I wasn&amp;#8217;t quite happy with how it looked.&lt;/p&gt;

&lt;p&gt;In the time since my last post, I have actually done useful things to a couple of the software projects I&amp;#8217;ve been working on. I&amp;#8217;ll aim to try and get some of those written up soon.&lt;/p&gt;</description>
				<published>2012-06-25 23:30:00 +0100</published>
				<link>http://mgdm.net/weblog/new-toys</link>
			</item>
			
		
			
			<item>
				<title>PECL/Cairo 0.3.0 released!</title>
				<description>&lt;p&gt;
As I'm sure you've all been longing to hear, we've finally got around to releasing a new version of &lt;a href=&quot;http://pecl.php.net/package/cairo&quot;&gt;PECL/Cairo&lt;/a&gt;! This version fixes some bugs, and adds support for some new features available since Cairo 1.10 &amp;mdash; notably, support for subsurfaces, which are surfaces that draw onto a part of a larger surface, and for recording surfaces, which record all drawing operations and can then be used as the source for other drawing operations. Also, &lt;a href=&quot;http://www.theskillers.co.uk&quot;&gt;Mark Skilbeck&lt;/a&gt; has added support for Win32 fonts. Also, the FreeType font handling has been improved, and should now give more informative messages when errors occur.
&lt;/p&gt;
&lt;p&gt;
Any questions, comments, bug reports, or contributed code are welcome. Drop us a line on the PECL mailing list, or try #php.pecl on EFNet.
&lt;/p&gt;
</description>
				<published>2011-12-28 20:41:09 +0000</published>
				<link>http://mgdm.net/weblog/peclcairo-030-released</link>
			</item>
			
		
			
			<item>
				<title>FrOSCon 2011</title>
				<description>&lt;p&gt;I&amp;#8217;m very pleased to be able to announce that I&amp;#8217;ll be giving two talks at this year&amp;#8217;s FrOSCon conference in St Augustin near Bonn in Germany, on the 20th and 21st of August. The first is on the &lt;a href='http://froscon.phpugdo.de'&gt;PHP track&lt;/a&gt;, and is an overview of the &lt;a href='http://pecl.php.net/package/cairo'&gt;PECL/Cairo&lt;/a&gt; extension for PHP.&lt;/p&gt;

&lt;p&gt;The second talk is on the main track, and is about &lt;a href='http://programm.froscon.org/2011/events/663.html'&gt;Making Software See&lt;/a&gt;, where I&amp;#8217;ll give an introduction to the &lt;a href='http://www.opencv.org'&gt;OpenCV&lt;/a&gt; image processing library, including some examples in various popular programming languages.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m extremely happy to have been selected both by the main FrOSCon organisers and the PHP track, organised by the &lt;a href='http://phpugdo.de/.html'&gt;PHP Usergroup Dortmund&lt;/a&gt;. I hope to see some of you there!&lt;/p&gt;</description>
				<published>2011-08-04 00:14:32 +0100</published>
				<link>http://mgdm.net/weblog/froscon-2011</link>
			</item>
			
		
			
			<item>
				<title>Pango for PHP PECL channel</title>
				<description>&lt;p&gt;It occurs to me that though I wrote an &lt;a href='http://mgdm.net/weblog/using-pango-for-php-a-taster'&gt;introduction post about Pango for PHP&lt;/a&gt;, I forgot to mention that it&amp;#8217;s actually installable using the PECL installer.&lt;/p&gt;
&lt;pre&gt;
 pecl channel-discover pecl.mgdm.net
 pecl install channel://pecl.mgdm.net/Pango-0.1.0
&lt;/pre&gt;
&lt;p&gt;Assuming you have the required development packages installed, it should go off and install it. You may still need to add the&lt;/p&gt;
&lt;pre&gt;
extension=pango.so
&lt;/pre&gt;
&lt;p&gt;line to your php.ini. Hope this helps someone give it a go! As ever, any feedback is welcome.&lt;/p&gt;</description>
				<published>2011-06-09 23:30:15 +0100</published>
				<link>http://mgdm.net/weblog/pango-for-php-pecl-channel</link>
			</item>
			
		
			
			<item>
				<title>Android: LinearLayouts, WebViews and black screens</title>
				<description>&lt;p&gt;Just making a quick note in case anyone else is searching for the same problem.&lt;/p&gt;

&lt;p&gt;I have an app with an activity which previously was just a WebView, but I wanted to add some other widgets above the WebView as well, so I made an XML layout and wrapped the WebView in a LinearLayout. Upon using this as the content view, my WebView went black. Completely. This resulted in a bit of frantic Googling, whereupon I discovered that it wasn&amp;#8217;t an unusual problem. Most of the solutions revolved around making sure the LinearLayout&amp;#8217;s width and height were both set to fill_parent &amp;#8212; this didn&amp;#8217;t work for me. A little bit of investigation then lead me to discover that I&amp;#8217;d forgotten to set the orientation on the LinearLayout. Once I&amp;#8217;d set that, everything started working fine. A silly problem, but quite often it&amp;#8217;s the silly ones that take the most time to figure out.&lt;/p&gt;</description>
				<published>2011-03-21 21:09:49 +0000</published>
				<link>http://mgdm.net/weblog/android-linearlayouts-webviews-and-black-screens</link>
			</item>
			
		
			
			<item>
				<title>Using Pango for PHP: a taster</title>
				<description>&lt;p&gt;
The &lt;a href=&quot;http://pecl.php.net/package/cairo&quot;&gt;PECL/Cairo&lt;/a&gt; library is pretty good at drawing vector graphics (in our opinion, as the developers, at least!), but one thing it's not able to do by itself is draw text with mildly advanced layout. It has the CairoContext::showText() function, but that doesn't really let you do anything GD can't. That's because the developers of the Cairo library decided to let another more specialised library handle the job of text layout. Much of the time, the library that gets used for this is &lt;a href=&quot;http://pango.org&quot;&gt;Pango&lt;/a&gt;. It has several bindings already for most popular languages on Unix-like platforms. It's quite capable, and able to lay out text while taking care of things such as paragraph alignment, line breaking, bold/italic text, justification, and various other features. In this post, I intend to give a little tour of some of its features.
&lt;/p&gt;&lt;p&gt;
Quite a while ago now, I wrote an extension to wrap Pango for PHP. It's available on its &lt;a href=&quot;https://github.com/mgdm/php-pango&quot;&gt;Github repository&lt;/a&gt;. It's not available on PECL right now, but you can check it out from there and install it using the &lt;a href=&quot;http://php.net/manual/en/install.pecl.phpize.php&quot;&gt;normal method&lt;/a&gt;. (Sorry Windows users, I've not had time to test it out on there, and likely won't any time soon. Patches are welcome, though...). It requires that the Pango headers are installed, and that PECL/Cairo is already installed into PHP.
&lt;/p&gt;&lt;p&gt;
Once installed, you can use it with Cairo. The best way to show it off is probably some example code:
&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Content-Type: image/png&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Make a 300x300px image surface */&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CairoImageSurface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CairoFormat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ARGB32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CairoContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Set the background to white */&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setSourceRGB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;paint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Let&amp;#39;s draw using black &amp;#39;ink&amp;#39; */&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setSourceRGB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Make a Pango layout, set the font, then set the layout size */&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PangoLayout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$desc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PangoFontDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Bitstream Charter 28&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setFontDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$desc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setWidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;250&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PANGO_SCALE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Here, we use Pango markup to make part of the text bold */&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setMarkup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &amp;lt;b&amp;gt;world!&amp;lt;/b&amp;gt; Here is a rather long paragraph which should get wrapped&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Draw the layout on the surface */&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;showLayout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Output the PNG to the browser */&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;writeToPng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;php://output&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
If all goes to plan, you should see a PNG in your browser with the above text.
&lt;/p&gt;&lt;p&gt;
Going through each step, firstly we set up the Cairo surface to draw on, and the context we use to draw with. Once we have done that, we can create a PangoLayout object which lets us draw the text we require. The PangoLayout is passed a context, so it can invoke the drawing methods itself to draw the text. We pass the PangoLayout a PangoFontDescription object, which lets us choose from the fonts already installed on the machine. This means that we don't need to concern ourselves with the paths to actual TrueType font files, or similar - the fonts are resolved by Fontconfig or whatever system is available on your machine.
&lt;/p&gt;&lt;p&gt;
Next, we set the width of the layout. We can also set a height, but I haven't bothered on this occasion. This lets Pango know where to wrap the text - if we don't set this, it won't bother, which may result in text falling off the edge of the image. You may note that the width is multiplied by the PANGO_SCALE - this is because Pango deals in units which are a tiny fraction (1/1024, in fact) of a pixel, in order to handle antialiasing properly. Because we're using a CairoImageSurface, this means that they layout will be 250 pixels wide.
&lt;/p&gt;&lt;p&gt;
Next up, we set the text to be drawn. There are two methods available to do this; PangoLayout::setText() is used when we just want to render text with no formatting instructions. In this case, I've opted for the PangoLayout::setMarkup() method, which lets me use &lt;a href=&quot;http://library.gnome.org/devel/pango/stable/PangoMarkupFormat.html&quot;&gt;Pango's markup language&lt;/a&gt; to make part of the text bold. Many other attributes can be changed using this markup, which has shortcuts that somewhat resemble HTML.
&lt;/p&gt;&lt;p&gt;
Finally, the call to showLayout() renders the layout onto the surface. You can also render just a path, using layoutPath(), which sets the path on the surface so you can then use more advanced effects with Cairo. The layout is drawn using whatever the current source is on the Cairo context, so you can render using flat colours, gradients, other source images, or whatever takes your fancy. Additionally, this means that any transformations you have set on the Cairo context also take effect, allowing you to rotate, scale, shear and otherwise distort the text.
&lt;/p&gt;&lt;p&gt;
It probably looks a little complex just to write some text on an image, but it is rather flexible. This flexibility is handy when you consider that Cairo can render more than just PNG images; PDFs, PostScript and SVG are also easy to create. I hope that this post may inspire someone else to give it a try. Feedback and reports of issues are always welcome.
&lt;/p&gt;
</description>
				<published>2011-02-21 20:42:15 +0000</published>
				<link>http://mgdm.net/weblog/using-pango-for-php-a-taster</link>
			</item>
			
		
			
			<item>
				<title>libsureelec, a driver for Sure Electronics LCD displays</title>
				<description>&lt;img alt=&quot;IMAG0227.jpg&quot; src=&quot;/assets/img/posts/IMAG0227.jpg&quot;&gt;
&lt;p&gt;
A few months ago I got a pair of 4x20 LCD displays from Sure Electronics, via eBay. Though they worked quite happily through LCDproc, I didn't really want to use that (as I intend to use one of them on a &lt;a href=&quot;http://bifferos.bizhat.com/&quot;&gt;Bifferboard&lt;/a&gt;). To that end, I've attempted to write a driver for them. Until recently I didn't have a lot of success, which made me think that the documentation provided with the device was incorrect, until &lt;a href=&quot;http://www.gjcp.net&quot;&gt;Gordon&lt;/a&gt; suggested trying the command set through gtkterm. I did, which made it work, and discovered that it requires the entire line to be sent to the display even if you're only updating part of it. Adjusting my code to handle this, and add some sleep time after sending each command, made it work. &lt;/p&gt;

&lt;p&gt;
I've put the code on &lt;a href=&quot;http://github.com/mgdm/libsureelec&quot;&gt;Github&lt;/a&gt; in case anyone else is interested. It's able to drive my DE-LD023 device quite happily, but I suspect it should work for other 4x20 devices too. Once I add the code to detect the device features it should also work for different sized displays. Any comments or patches are of course welcome.&lt;/p&gt;
</description>
				<published>2011-02-02 18:13:51 +0000</published>
				<link>http://mgdm.net/weblog/libsureelec-a-driver-for-sure-electronics-lcd-displays</link>
			</item>
			
		
			
			<item>
				<title>CMSes: an update</title>
				<description>My previous post was typed in a bit of a hurry (was it that obvious?) and could probably have done with a few more sarcasm tags, though I think I still have a valid, if small, point. It surprised me that these well-maintained projects seem to be content to run with what I would consider to be errors. Though they do run, otherwise nobody would be using them. For what it's worth, SilverStripe and I have made up and it's all going swimmingly at present. Thanks to everyone who commented with recommendations; I'll try and follow some of them up when I get time. 

One comment did ask me to define what I meant when I refer to a &quot;lightweight&quot; CMS -- basically, I was looking for something that will allow me to create a hierarchy of pages that consist roughly of a title and content. Nothing fancy. I don't need multiple content types, complex user management, discussion forums, built-in wikis, etc. It's the sort of thing I could have coded up in a couple of days using any number of frameworks, but I figured there'd be something off the shelf that'd do what I was after.

Another commenter questioned why I cared about coding standards warnings seemingly more than avoiding SQL injection and XSS and CSRF protection -- I don't, those are absolute hard requirements for any application. I'd put avoiding the coding standards warnings somewhere above &quot;nice to have&quot;, but those warnings are indications that something is being done in a way which is either less than ideal (such as using non-static methods in a static context, a la Concrete5), or deprecated (such as using the ereg functions).

My next post shall try and be a little more constructive, as I release some code.</description>
				<published>2011-01-19 21:50:37 +0000</published>
				<link>http://mgdm.net/weblog/cmses-an-update</link>
			</item>
			
		
			
			<item>
				<title>Where are all the decent PHP CMSes?</title>
				<description>I've been recently asked to check out some CMSes for someone, and try to find a recommendation. What I've been finding hasn't really been encouraging. Out of the several CMSes I've tried, they've all failed for various reasons. I admit that I might be looking at this from a slightly different perspective than most - that of admining it and coding against it, rather than as a user - but it's still rather disappointing.

&lt;ul&gt;
&lt;li&gt;Silverstripe is what I used first - but the forms (including the login to the admin) kept failing to render. In the end, I got sick of debugging it and started my hunt.&lt;/li&gt;
&lt;li&gt;Next up was Concrete5, which I heard mentioned recently. There were &lt;strong&gt;one hundred and fifty-five&lt;/strong&gt; strict warnings in the front page of the installer. Bye bye.&lt;/li&gt;
&lt;li&gt;Next, CMS Made Simple. Its installer wanted E_STRICT and E_DEPRECATED removed from error reporting. At this point some folk might have continued; but that was enough for me not to consider it. I didn't have enough confidence in the code that I wanted to continue. It lost more points for the tarball not extracting into a subdirectory, which resulted in my document root being filled with nonsense.&lt;/li&gt;
&lt;li&gt;Joomla!... well, my last experience of it wasn't pleasant - I couldn't work out how the code was structured. It's also overkill for the requirements of this site.&lt;/li&gt;
&lt;li&gt;I would love to go for Habari, but the site isn't a blog, so it doesn't really fit the use case. It's still the top of the list just now, though.&lt;/li&gt;
&lt;li&gt;I could do what everyone else does and run Wordpress - but, again, the site isn't a blog, and I'd rather try something different.&lt;/li&gt;
&lt;/ul&gt;

I didn't consider Drupal or eZ Publish, which again I believed to be massive overkill for what is required of the site. What's going on? This is what PHP is supposed to be good at. Where are the simple, lightweight CMSes with modern code? Notices, strict and deprecation warnings should be considered errors when developing - this doesn't seem to be the case with many of the above projects.

So, that's what I've found. I now don my asbestos suit.</description>
				<published>2011-01-17 21:10:09 +0000</published>
				<link>http://mgdm.net/weblog/where-are-all-the-decent-php-cmses</link>
			</item>
			
		
			
			<item>
				<title>Habari plugins published</title>
				<description>I've just committed two new plugins to the habari-extras Subversion. Firstly, there's the 'share' plugin, which adds the Facebook OpenGraph metadata to pages so that the Like button works, and also adds Facebook and Twitter widgets to the bottom of posts. Secondly, there's a bitly plugin, that pings bit.ly's API when every post is published and generates a short URL. This URL is then stored in the post info, and it provides a template to add it to the head of each page using the &lt;a href=&quot;http://microformats.org/wiki/rel-shortlink&quot;&gt;shortlink&lt;/a&gt; markup. I'd be interested in feedback from anyone more familar with Habari in case there's a better way to do what I'm doing.

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://svn.habariproject.org/habari-extras/plugins/share/&quot;&gt;Share plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://svn.habariproject.org/habari-extras/plugins/bitly/&quot;&gt;Bit.ly plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<published>2011-01-16 22:50:07 +0000</published>
				<link>http://mgdm.net/weblog/habari-plugins-published</link>
			</item>
			
		
			
			<item>
				<title>Recent activity: Habari plugins</title>
				<description>I think I'm just about keeping to this one-post-a-week thing, almost. I've recently been playing with the internals of Habari, writing a couple of plugins. I've found it quite well put together, though I don't seem to ever get the Utils::debug() output to display properly - though this might have been due to the code I was writing running before a redirect. I believe though that I now have got 2 plugins which I'm going to investigate publishing - one which generates the Facebook and Twitter widgets at the bottom of the posts (and the relevant OpenGraph metadata for Facebook in the header), and another which pings bit.ly and generates a short URL for each post as it's published. I'm writing this post in part as a test to see that it works for real :-)

If I get a bit of time over the next few days, I'll finish tidying them up and make them available. If anyone's interested before I do, drop me an email or catch me on Twitter.</description>
				<published>2011-01-15 22:49:13 +0000</published>
				<link>http://mgdm.net/weblog/recent-activity-habari-plugins</link>
			</item>
			
		
			
			<item>
				<title>2011, now with less tumbleweed</title>
				<description>It's my intention this year to at write at least one post on here per week, ideally with some substance to it, rather than just recording what I had for breakfast (that being Twitter's job, after all). I'm not holding my breath about whether I will manage it or not, but I intend to give it a go. I have a draft in the works, which I will hope to get out there some time soon...

In actual news, I have been accepted to talk at &lt;a href=&quot;http://confoo.ca&quot;&gt;ConFoo&lt;/a&gt; in Canada, on the subject &quot;Making PHP See&quot; - which is about image recognition using OpenCV and PHP. I'm really looking forward to the conference, and I'm fortunate to be up alongside some excellent speakers, so it should be great fun.</description>
				<published>2011-01-02 23:41:54 +0000</published>
				<link>http://mgdm.net/weblog/2011-now-with-less-tumbleweed</link>
			</item>
			
		
			
			<item>
				<title>Cairo talk feedback from DPC10</title>
				<description>I noted a couple of comments after my talk on Cairo at &lt;a href=&quot;http://phpconference.nl&quot;&gt;DPC 10&lt;/a&gt; yesterday, so I thought I'd respond to them here to clear up what's going on. It's always good to get some feedback about something I've been working on so I'd like to reply and keep the conversation going if I can.

First off, someone mentioned that the wrapper seems a bit beta and incomplete - and yes, that is true. The 0.2.0 release, which is the latest as I wrote this, is still marked as beta. The aim of me coming and talking about it is to try and get some more people interested in using it, so we can get some more information from real users about what works and what doesn't. I probably didn't help by mentioning that there are some features that we intend to implement that aren't there yet, which I'll list:

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Support for reading and writing images that aren't PNGs&lt;/b&gt; The developers of the core Cairo API are not really interested in handling all the various graphics formats that exist, so they decided to implement one and one only which is useful for getting data in and out. This is the functionality that we use at present. We (the developers of the wrapper) would like to fix that and handle JPEG, GIF, TIFF, and whatever new format is cool this week, but we're not quite sure how to go about that yet. We could recycle the code used by GD or use ImageMagick or GraphicsMagick, but those would introduce dependencies that people might not have available. Once we work out a decent solution here, it will be put in.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Support for hyperlinks in PDFs and SVGs&lt;/b&gt; Again, this is something we'd quite like but it's not supported in the underlying library &lt;b&gt;yet&lt;/b&gt;. There have been rumours about adding an API to do this, but there hasn't been a concensus about what's a good way to go about it. It's something I'd quite like to help fix, so I've been learning how Cairo itself is put together with the intention to add the support.&lt;/li&gt;
&lt;/ul&gt;

The other comments I saw suggested that the API is a bit fiddly, which I can't deny. It's not quite as simple to set up and get running as some of the other libraries in PHP already. This is nearly intentional - we're wrapping the underlying Cairo API as closely as we can, because we don't want to diverge too far from how other languages with Cairo wrappers work, so that developers who may be familiar with those already know roughly what is going on. It's for this reason that, for example, the API uses floating-point values from 0 to 1 to define the intensity of colours, rather than an integer value from 0-255 which most people are probably used to. This is because Cairo is designed not to make any assumptions about the surface you're going to be drawing to - some day we might get 16-bits-per-channel surfaces, and using float values means that we don't need to change the API or the values we're passing in to allow us to write to them. It'll just carry on working as it did before, just with better colour resolution.

However, if anyone has any ideas for how we could make things simpler, then we'd love to hear about it &amp;emdash; drop us a line on the PECL developers mailing list (which you can find on the &lt;a href=&quot;http://pecl.php.net/support.php&quot;&gt;PECL mailing lists&lt;/a&gt; page), or find us on IRC on #php.pecl on EFnet.

There are a couple of things that I have worked on which sit on top of the Cairo extension, which can do some interesting things. If you're still at DPC I'll be demoing a couple of them on the uncon track at 2pm. It's only a 15 minute talk, so it shouldn't be too boring...!</description>
				<published>2010-06-12 09:48:21 +0100</published>
				<link>http://mgdm.net/weblog/cairo-feedback-from-dpc10</link>
			</item>
			
		
			
			<item>
				<title>Ubuntu Accessibility team</title>
				<description>Recently I've become involved in a move to resurrect the Ubuntu Accessibility team, which seemed to have stagnated until quite recently when &lt;a href=&quot;http://pendulumtech.wordpress.com&quot;&gt;Penelope Stowe&lt;/a&gt; got involved and suggested I joined too. She arranged a session at the Ubuntu Developer Summit for the next Ubuntu release, Maverick Meerkat, which seems to have &lt;a href=&quot;http://pendulumtech.wordpress.com/2010/05/31/ubuntu-accessibility-team-goals-for-maverick-meerkat/&quot;&gt;gone quite well&lt;/a&gt;. The main focus for the team right now is getting organised, and to this end we're aiming to create a set of personas, which are representations of hypothetical users with various accessibility requirements which developers and testers can keep in mind when working on the next Ubuntu release. These personas are going to be developed by a survey which will be dispatched to a host of groups who may have accessibility requirements to get an idea of what the main factors that affect their experience with Ubuntu are, so we can get an idea of the main areas to improve. Hopefully then the work which will take place as a result of these can be sent upstream to the original projects. 

My own role in the team isn't quite clear yet, but I intend to help on the development side, if I can, once more work starts in this area. If you would like to help, the team hangs out on &lt;a href=&quot;irc://chat.freenode.net/#ubuntu-accessibility&quot;&gt;#ubuntu-accessibility&lt;/a&gt; on Freenode IRC, and there is a &lt;a href=&quot;http://lists.ubuntu.com/mailman/listinfo/ubuntu-accessibility&quot;&gt;mailing list&lt;/a&gt;. You can also check out the &lt;a href=&quot;https://wiki.ubuntu.com/Accessibility&quot;&gt;wiki page&lt;/a&gt; which we're working on improving. </description>
				<published>2010-06-01 23:05:33 +0100</published>
				<link>http://mgdm.net/weblog/ubuntu-accessibility-team</link>
			</item>
			
		
			
			<item>
				<title>EuroWinPHP contest</title>
				<description>This year I've decided to enter the &lt;a href=&quot;http://www.eurowinphp.com&quot;&gt;EuroWinPHP&lt;/a&gt; contest, as I figured it might be interesting to learn a bit more about how PHP works on Windows. I originally started using it there, back in around 2002, running early versions of Apache 1.3 and PHP 4.1 on Windows 98 and 2000. These days, though, I'm running IIS7 and PHP 5.3.2, and have a bit more knowledge of how the bits fit together, though since I've been running Linux for the last 5 years I'm a little out of touch.

The project I've opted to do is something I've been thinking about for a little while, but not got around to developing until now. It's named GarnetCMS, and the idea is to create a CMS that uses the features of PHP 5.3, such as closures, and based around a signal/slot mechanism. The idea is to initially develop it to use NoSQL datastores, and I intend to create back ends for &lt;a href=&quot;http://www.microsoft.com/windowsazure/&quot;&gt;Microsoft Azure&lt;/a&gt; and &lt;a href=&quot;http://www.mongodb.org&quot;&gt;MongoDB&lt;/a&gt; at first. If I do things correctly, though, adding a traditional RDBMS back end later on should be relatively simple.

Development-wise, I'm trying out Mercurial for version control, and using Bitbucket to store the code - the project will be on there at &lt;a href=&quot;http://bitbucket.org/mgdm/garnet-cms/&quot;&gt;http://bitbucket.org/mgdm/garnet-cms/&lt;/a&gt; once it gets going. I'm intending to try out Komodo Edit, because while I do love GVim on Windows it doesn't quite fit with the &quot;complete change&quot; I'm going for with most other things! &lt;a href=&quot;http://tortoisehg.bitbucket.org/&quot;&gt;TortoiseHg&lt;/a&gt; seems quite nice so far, and I've managed to get IIS up and running, so now all I need to do is get coding. I'm quite looking forward to seeing how it turns out.</description>
				<published>2010-04-10 22:03:14 +0100</published>
				<link>http://mgdm.net/weblog/eurowinphp-contest</link>
			</item>
			
		
			
			<item>
				<title>Handling fonts in PECL/Cairo</title>
				<description>(This is just a quick note to get some information out there for reference, I am adding it to the PHP manual as well!)

Currently, in PECL/Cairo the only way to draw text is the referred to as the &quot;toy&quot; text API, which is a very basic way of handling text compared to the facilities available in the Cairo library itself. However, it's sufficient for most purposes that I've come across so far. In version 0.1.0 of PECL/Cairo, there was only one way to choose what font you wished to use, which was the &lt;a href=&quot;http://www.php.net/manual/en/cairocontext.selectfontface.php&quot;&gt;CairoContext::selectFontFace()&lt;/a&gt; method. You pass a string to this method with the name of the font you want, along with the optional slant and weight parameters. This then invokes your system's font handling to find the font you're after, or an alternative if it's not available, so you need to have the font you want installed into your system's font library.This is occasionally not handy.

In version 0.2.0 FreeType support was added.  It allows you to choose any font file you'd like, as long as PHP's streams API can find it.  Yes, this means 'http://' streams, but I wouldn't recommend it.

&lt;geshi lang=&quot;php&quot;&gt;
&lt;?php
/* Set up the surface, and make the background white */
$s = new CairoImageSurface(CairoFormat::ARGB32, 300, 100);
$c = new CairoContext($s);
$c-&gt;setSourceRgb(1, 1, 1); 
$c-&gt;paint();

/* Draw the text using the Vollkorn font, from 
   http://friedrichalthausen.de/2006/01/01/vollkorn/ */
$c-&gt;setSourceRGB(0, 0, 0);
$c-&gt;moveTo(10, 60);
$f = new CairoFtFontFace(dirname(__FILE__) . &quot;/vollkorn.otf&quot;);
$c-&gt;setFontFace($f);
$c-&gt;setFontSize(50);
$c-&gt;showText(&quot;Hello world&quot;);

/* Send the image to the browser */
header(&quot;Content-type: image/png&quot;);
$s-&gt;writeToPng(&quot;php://output&quot;);
?&gt;
&lt;/geshi&gt;

The output image should hopefully look like this:

&lt;img alt=&quot;Script output&quot; src=&quot;http://mgdm.net/weblog/user/files/cairo-freetype.png&quot;&gt;

(For those who are familiar with the Cairo library, this function maps to the cairo_ft_font_face_create_for_ft_face function in its API.)

There is still some work to be done in this area, notably to support the Windows and Mac OS X font systems, but they'll be coming in a future release, we hope. If anyone would like to help us with that, or any other aspect of it (including documentation!), you can get in touch on the &lt;a href=&quot;http://news.php.net/php.pecl.dev&quot;&gt;PECL dev mailing list&lt;/a&gt;, or if you're on IRC, drop in to #php.pecl on EFnet. All contributions are welcome!
</description>
				<published>2010-03-01 19:06:43 +0000</published>
				<link>http://mgdm.net/weblog/handling-fonts-in-peclcairo</link>
			</item>
			
		
			
			<item>
				<title>Speaking at DPC10</title>
				<description>&lt;img alt=&quot;DPC10 speaker badge&quot; src=&quot;http://mgdm.net/weblog/user/files/dpc09_speaker.jpg&quot;&gt;

I'm happy to say that I'll be speaking at the &lt;a href=&quot;http://phpconference.nl/&quot;&gt;Dutch PHP Conference&lt;/a&gt; in June in Amsterdam, on the subject of the &lt;a href=&quot;http://pecl.php.net/package/cairo&quot;&gt;PECL/Cairo extension&lt;/a&gt; I've been helping out by working on for the past few months. This will be my first appearance as a speaker at a technical conference so I'm a little nervous, but I've no doubt I'll be practicing a bit before it happens. Apologies in advance to anyone I inflict the talk on before the event. </description>
				<published>2010-02-26 10:55:47 +0000</published>
				<link>http://mgdm.net/weblog/speaking-at-dpc10</link>
			</item>
			
		
			
			<item>
				<title>PECL/Cairo 0.2.0 released</title>
				<description>The first beta version of the &lt;a href=&quot;http://pecl.php.net/package/cairo&quot;&gt;PECL/Cairo extension&lt;/a&gt; has just been released. This version includes support for loading arbitrary fonts via Freetype, cloning matrices, and has a rather large set of bug fixes. If you've been using 0.1.0 for anything at all I'd really recommend an upgrade. Windows builds will appear soon over at &lt;a href=&quot;http://perisama.net/cairo/&quot;&gt;perisama.net&lt;/a&gt; for all the major PHP variants courtesy of &lt;a href=&quot;http://www.elizabethmariesmith.com/&quot;&gt;Elizabeth M. Smith&lt;/a&gt;. Many thanks to Mark Skilbeck for helping get this release working on Windows!</description>
				<published>2010-02-03 23:13:56 +0000</published>
				<link>http://mgdm.net/weblog/peclcairo-020-released</link>
			</item>
			
		
			
			<item>
				<title>Cairo article published</title>
				<description>I've got 3 posts or so queued up in my mind to write out, but some of them rather depend on doing other things first, so this will just be a quick note to say I have an article in &lt;a href=&quot;http://www.phparch.com/magazine/index/111&quot;&gt;the most recent php|architect magazine&lt;/a&gt; on the subject of &quot;Vector Graphics with Cairo&quot;. This is a basic introduction to the &lt;a href=&quot;http://pecl.php.net/pecl/cairo&quot;&gt;PECL/Cairo&lt;/a&gt; extension which I've been helping out on for a while now. Thanks to &lt;a href=&quot;http://caseysoftware.com/&quot;&gt;Keith Casey&lt;/a&gt; for his input, to the folks at php|architect for letting me do it, and the long-suffering &lt;a href=&quot;http://www.elizabethmariesmith.com/&quot;&gt;Elizabeth Marie Smith&lt;/a&gt; for putting up with all my stupid questions while working on this and other extensions!

Now, back to my regularly scheduled coding...
</description>
				<published>2010-01-21 20:32:00 +0000</published>
				<link>http://mgdm.net/weblog/cairo-article-published</link>
			</item>
			
		
			
			<item>
				<title>A brief update</title>
				<description>Last weekend I spent a couple of days on the yacht &lt;a href=&quot;http://www.flickr.com/photos/mgdm/3087512670/&quot;&gt;Hebridean&lt;/a&gt; as part of an &lt;a href=&quot;http://www.rya.org.uk/coursestraining/courses/sailcruising/Pages/Dayskipper.aspx&quot;&gt;RYA sail cruising day skipper course&lt;/a&gt;. This was the second half, as we were aboard before last month but had to cancel due to the weather. This time, we combined the course with delivering the yacht to Oban Marina on Kerrera where it will spend the winter. I'm happy to say I passed, so theoretically at least I could be able to charter a yacht for a trip at some stage. I might investigate that for one summer, but I'll want a bit more mileage and experience first. I also noticed that the local college were running a Coastal Skipper theory course, so I'm on that now too.

I'm considering going to &lt;a href=&quot;http://fosdem.org&quot;&gt;FOSDEM&lt;/a&gt; in Belgium in February. I missed &lt;a href=&quot;http://lugradio.org/live/&quot;&gt;LugRadio Live&lt;/a&gt; this year so I'm thinking of it as a sort of substitute. Also considering PHP London, but we'll see.</description>
				<published>2009-11-09 20:28:39 +0000</published>
				<link>http://mgdm.net/weblog/a-brief-update</link>
			</item>
			
		
			
			<item>
				<title>Debug of the year</title>
				<description>I saw &lt;a href=&quot;http://news.bbc.co.uk/1/hi/world/americas/8152278.stm&quot;&gt;this article&lt;/a&gt; on the BBC, where a man who bought a packet of cigarettes from a petrol station in the US ended up being charged $23,148,855,308,184,500 instead. Wow. I was a little curious as to how this could have happened, though the number didn't look familar - I know roughly what 2^32, 2^32 / 2, 2^64, 2^64 / 2 look like, and this didn't appear to be any of those. A swift Google though led me to Stack Overflow, which is a fantastic site. Therein lies &lt;a href=&quot;http://stackoverflow.com/questions/1133581/is-23-148-855-308-184-500-a-magic-number-or-sheer-chance/1133612#1133612&quot;&gt;a quite plausible explanation&lt;/a&gt;:
&lt;blockquote&gt;
&lt;p&gt;Add the cents to the number and you get 2314885530818450000, which in hexadecimal is 2020 2020 2020 1250.&lt;/p&gt;
&lt;p&gt;Do you see the pattern? The first six bytes has been overwritten by spaces (hex 20, dec 32).&lt;/p&gt;
&lt;/blockquote&gt;
Ingenious! I can imagine spending quite a while trying to come up with that...</description>
				<published>2009-07-16 02:04:19 +0100</published>
				<link>http://mgdm.net/weblog/debug-of-the-year</link>
			</item>
			
		
			
			<item>
				<title>PECL/Cairo 0.1.0 released</title>
				<description>The first alpha of the &lt;a href=&quot;http://pecl.php.net/package/cairo&quot;&gt;PECL Cairo&lt;/a&gt; extension I've been helping out with has been released. Please download it, play with it, try and break it, and file bugs if you do! There isn't an official manual yet (for licencing-related reasons which I'm hoping to sort out soon), but I'll update this post when there is one. For now, there is a lot of stuff in the &lt;a href=&quot;http://cvs.php.net/viewvc.cgi/pecl/cairo/examples/&quot;&gt;examples/&lt;/a&gt; directory in the source which can be used as inspiration.</description>
				<published>2009-07-06 15:35:39 +0100</published>
				<link>http://mgdm.net/weblog/peclcairo-010-released</link>
			</item>
			
		
			
			<item>
				<title>What I've been up to</title>
				<description>I finally decided to get around to doing something about my site, so I've made a front page for it which is better than a straight redirect onto the blog. Hopefully it's reasonable.

I've been learning a bit more recently about the internals of PHP, and how to write extensions for it. I've been practicing by doing a bit of work on a &lt;a href=&quot;http://trac.macvicar.net/php-cairo&quot;&gt;Cairo wrapper&lt;/a&gt; that was started in the Google Summer of Code last year and until now has been mainly looked after by &lt;a href=&quot;http://elizabethmariesmith.com/&quot;&gt;Elizabeth Marie Smith&lt;/a&gt;. She's put up with many, many newbie questions from me and so I've learned a lot while doing it. It's now at the stage where it'll run the eZ Components Graph component without too much complaining. It has a dual procedural and object-oriented API, so it should manage to run most things that use the existing cairo_wrapper extension. Thanks to all the regulars on #php.pecl and #php.doc on EFNet, and #php-gtk on Freenode for putting up with me while doing this. I've also written a quick wrapper for &lt;a href=&quot;http://tokyocabinet.sourceforge.net/&quot;&gt;Tokyo Cabinet&lt;/a&gt; for the DBA extension in PHP which with a bit of luck will get committed to PHP6 some time soon.

In other news, I've been occasionally helping in the maintenance of Jubilee and An Sulaire, the two Sgoth Niseach boats I go sailing on occasionally. Hopefully they'll be going back in the water soon and we can get some sailing done. I'm looking forward to it.</description>
				<published>2009-05-15 22:44:45 +0100</published>
				<link>http://mgdm.net/weblog/what-ive-been-up-to</link>
			</item>
			
		
			
			<item>
				<title>PHP 5.3.0RC2</title>
				<description>&lt;a href=&quot;http://www.php.net/archive/2009.php#id2009-05-07-1&quot;&gt;PHP 5.3.0RC2 has been released&lt;/a&gt;, which means that the next version of PHP is just around the corner. It comes right in the middle of the annual &lt;a href=&quot;http://wiki.php.net/qa/testfest&quot;&gt;PHP Testfest&lt;/a&gt;. I rambled on a bit on the &lt;a href=&quot;http://podcast.freenode.net/episodes/free-as-in-node-season-1-episode-3-soapbox&quot;&gt;Freenode podcast&lt;/a&gt; a couple of weeks ago about this - it's an annual project where PHP usergroups and individuals around the world get together to improve the unit testing of PHP. This has benefits for everyone involved - PHP is improved, and more likely to maintain backward compatibility, and the people involved in writing the tests get to contribute in a meaningful way to the project, and hopefully learn something on the way. Several usergroups have events scheduled, and a couple have already taken place to great success. If you're a serious PHP user, and interested in getting involved, it's well worth checking out. 

Even just grabbing the latest PHP release, compiling it on your platform, and running &quot;make test&quot; helps the project. It doesn't take much to do, and you can run it in the background while doing something else. Go for it!</description>
				<published>2009-05-08 22:57:18 +0100</published>
				<link>http://mgdm.net/weblog/php-530rc2</link>
			</item>
			
		
			
			<item>
				<title>My favourite ever dialogue box</title>
				<description>    &lt;p&gt;I saw this on &lt;a href=&quot;http://www.thedailywtf.com&quot;&gt;TheDailyWTF&lt;/a&gt; recently, and decided I had to try it for myself, and it works!&lt;/p&gt;
    
&lt;img alt=&quot;the-best-dialogue-box-ever.png&quot; src=&quot;/weblog/user/files/the-best-dialogue-box-ever.png&quot;&gt;
    
&lt;p&gt;You get it if you go to &quot;Clear History&quot; in the &quot;Go&quot; menu in Nautilus.&lt;/p&gt;
  
</description>
				<published>2008-10-19 19:09:00 +0100</published>
				<link>http://mgdm.net/weblog/my-favourite-ever-dialogue-box</link>
			</item>
			
		
			
			<item>
				<title>Custom functions on the 400D</title>
				<description>    &lt;p&gt;This is a camera-geek post, so if you're not one of those, feel free to skip. I've just been having a bit more of a play with the custom functions available to change how the 400D operates. There are a couple of things that I've found that I can't believe I didn't know about - they look like they'll make things a lot easier. I'm making a note here so that if I lose them, I can find them again.&lt;/p&gt;
    
    &lt;p class=&quot;lineblock&quot;&gt;I now have set:&lt;br&gt;&lt;/br&gt;&lt;/p&gt;
    &lt;p&gt;Now I just need to get out and do some more shooting. Not done very much of late that hasn't been with my N95, which is disappointing.&lt;/p&gt;
    &lt;p&gt;
      &lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
              &lt;p&gt;Setting name&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;Value&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;Effect&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
              &lt;p&gt;CF01 - Set button/cross keys function&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;4: Cross keys - AF Frame select&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;Makes the arrow keys choose the autofocus point when shooting, rather than selecting the picture &quot;style&quot;, which is something I've never used beyond setting it on &quot;neutral&quot;&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
              &lt;p&gt;CF04 - Shutter/AE lock button&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;1: AE Lock/AF&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;This makes the &quot;*&quot; button cause the camera to autofocus, and have pressing the shutter button half way set the exposure (in non-manual modes). This might well drive me nuts, but I like the idea, in theory.&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
              &lt;p&gt;CF05 - AF-assist beam&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;2: Only external flash emits&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;This should stop it flashing like mad when trying to focus in low light, when I'm not using my 430EX. I don't use the on-camera flash that much anyway, so it won't make a lot of difference, but it is an irritating feature when I am using it.&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
              &lt;p&gt;CF09 - Shutter curtain sync&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;1: Second curtain sync&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;This makes the flash fire just before the shutter closes, rather than when the shutter opens. This might not seem to make a lot of sense at first glance, but it means that if I take a photo with a relatively long exposure with the intention of getting some motion blur, the shutter will fire at the end of the exposure, so that the object is &quot;frozen&quot; with the trail behind it, rather than seeming to go ahead of it.&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
              &lt;p&gt;CF11 - LCD display when power ON&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;1: Retain power OFF status&lt;/p&gt;
            &lt;/td&gt;
            &lt;td&gt;
              &lt;p&gt;This stops the display coming on when I switch the camera on. I don't use the display much so I have it turned off most of the time to save battery power.&lt;/p&gt;
            &lt;/td&gt;
          &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
</description>
				<published>2008-09-29 01:05:00 +0100</published>
				<link>http://mgdm.net/weblog/custom-functions-on-the-400d</link>
			</item>
			
		
			
			<item>
				<title>Making timelapses with Linux</title>
				<description>In other news, I've been spending far too much time recently with my camera. One thing I quite like doing is timelapse photography, which my camera (a Canon 400D) can't do by itself, however I did acquire a cheap intervalometer from eBay, which together with my new tripod (a Velbon Sherpa 250, highly recommended) is quite for this kind of work.
    
I can't, however, ever remember the command to create the timelapses. So, here's a note to myself and anyone else who's interested. If you have a folder full of .JPG files, with a sequential numbering scheme like most cameras have by default, you can run this command to create a video file using each JPEG image as a frame:

&lt;pre&gt;mencoder &quot;mf://*.JPG&quot; -mf fps=25 -vf scale -zoom -xy 1024 -ovc lavc -lavcopts vcodec=mpeg4 -o output.avi&lt;/pre&gt;

&lt;p&gt;This will output an MPEG4 file in the file output.avi. It will scale the images so that the video ends up being 1024 pixels wide, and set the height to keep the aspect ratio. It will also run at 25 frames per second. These values can be tweaked, depending on the effect you want.&lt;/p&gt;
&lt;p&gt;I'll update this post once I've figured out a few more things - I'd like to be able to do panning and zooming as well, and I know it's possible, though perhaps a bit fiddly.&lt;/p&gt;
</description>
				<published>2008-07-28 15:18:00 +0100</published>
				<link>http://mgdm.net/weblog/making-timelapses-with-linux</link>
			</item>
			
		
			
			<item>
				<title>Defective Defective by Design</title>
				<description>    &lt;p&gt;A couple of years ago, I think, I became sufficiently motivated by the defectivebydesign.org campaign that I decided to go and join the Free Software Foundation to support them. However, recent events are making me actively reconsider my membership.&lt;/p&gt;
    &lt;p&gt;They've come up with a &lt;a href=&quot;http://defectivebydesign.org/apple-challenge&quot;&gt;campaign&lt;/a&gt; involving people signing up for appointments to Apple's Genius Bar technical support questions, and asking them a series of questions with regard to Apple's stance on DRM. It basically amounts to a denial of service attack on their technical support. I, and many others, believe that they are Doing It Wrong on several levels. I tried to sum my thoughts up in an email to them, to which I haven't yet had a response (not that I particularly expected one):&lt;/p&gt;
    &lt;p&gt;
      &lt;/p&gt;&lt;blockquote&gt;
        &lt;p&gt;I seriously urge you to reconsider this campaign against Apple. I fully believe it is going to bring you far more negative publicity than actual gains. It will result in people who have a need to obtain service from the Apple technicians being inconvenienced, with the likely result that many of them will learn about the FSF for the first time as being a group of irritating timewasters rather than a worthy cause. It will result in the people working in Apple stores, some of whom I know are active members in local Free Software user groups and other communities, becoming utterly disillusioned with the Free Software movement. It will not make Apple as a whole any more kindly disposed to contributing to Free Software. On the whole, I believe this to be a mistake. I say this as a member of the FSF who joined because of the Defective by Design campaign, though I am seriously reconsidering my position on this - I cannot support an organisation who take the attitude that inconveniencing the general public is a valid way forward in the promotion of their views.&lt;/p&gt;
      &lt;/blockquote&gt;
    
    &lt;p&gt;My position is now that if they go ahead with this campaign, I'm going to resign from the FSF. Someone in there seems to have some seriously misguided views about what is and isn't acceptable in terms of getting their message across.&lt;/p&gt;
  </description>
				<published>2008-07-28 15:02:00 +0100</published>
				<link>http://mgdm.net/weblog/defective-defective-by-design</link>
			</item>
			
		
			
			<item>
				<title>Lugradio Live 2008</title>
				<description>    &lt;p&gt;
      &lt;a href=&quot;http://lugradio.org/live/UK2008/&quot;&gt;&lt;/a&gt;
    &lt;/p&gt;
    &lt;p&gt;LugRadio Live 2008 is happening on the 19th and 20th of July at The Lighthouse Media Center, Chubb Buildings, Fryer Street, Wolverhampton. This'll be my first time there, and so I've been very sensible and volunteered for the crew. Should be fun!&lt;/p&gt;
  </description>
				<published>2008-06-04 14:27:00 +0100</published>
				<link>http://mgdm.net/weblog/lugradio-live-2008</link>
			</item>
			
		
			
			<item>
				<title>The Linksys NSLU2, part one</title>
				<description>    &lt;p&gt;I've spent some time recently playing with a couple of Linksys NSLU2s. These are small devices which have 2 USB ports and an Ethernet port, and are intended to be used to share USB drives across a network via CIFS (Windows file sharing). The best feature of them though is that like the early WRT54G routers, it runs Linux by default, and uses Samba to share the files. This means that with a bit of hacking, it's fairly easy to extend it to make it more functional. There are a few projects doing this, the most famous being the Unslung firmware.&lt;/p&gt;
    &lt;p&gt;Another project that has been working on support for the NSLU2 is Debian. As of version 4.0 (Etch), the default Debian installer has had support for them out of the box. More information on this can be found at &lt;a href=&quot;http://cyrius.com/debian/nslu2/&quot;&gt;http://cyrius.com/debian/nslu2/&lt;/a&gt;. I've installed Etch on both my NSLU2s, though I found it quicker and easier to use the manual install method, which just means unpacking a tarball of the base system. This is described at &lt;a href=&quot;http://cyrius.com/debian/nslu2/unpack.html&quot;&gt;http://cyrius.com/debian/nslu2/unpack.html&lt;/a&gt;. The instructions there are far better than I could describe, so I won't bother trying to replicate them.&lt;/p&gt;
    &lt;p&gt;So, what can you do with these things once they're running Debian? Lots of things. Just now I'm going to describe one of the most basic things I use it for, which is for serving DHCP and DNS on my LAN.&lt;/p&gt;
    &lt;p&gt;You can, if you like, run the full ISC BIND and dhcpd servers on your Slug, but there isn't really that much point. They're big, sometimes tricky to configure, and overkill for a small LAN. A decent, light alternative is dnsmasq. It's a small daemon that uses the existing /etc/hosts and other related files to handle serving the network. I run it for a couple of reasons - firstly, my ISP's DNS servers are somewhat less than reliable, so I use dnsmasq to proxy to OpenDNS. Secondly, it allows me to use internal DNS names for my machines. So, for example, rather than having to remember that my router is 192.168.1.1, if I want to go and change something in its configuration, I can just type &quot;portal&quot; into my browser. Similarly, my NSLU2s can be accessed by just typing &quot;ssh kaylee&quot; or &quot;ssh inara&quot;. I've picked a domain name that doesn't exist in the wider Internet to ensure I don't collide with anything real.&lt;/p&gt;
    &lt;h3&gt;Setting it up&lt;/h3&gt;
    &lt;p&gt;dnsmasq doesn't come installed by default, but it's only an apt-get away.&lt;/p&gt;
    
    &lt;pre&gt;apt-get install dnsmasq&lt;/pre&gt;
    &lt;p&gt;After that, there is a configuration file at /etc/dnsmasq.conf which you may want to have a look at. The defaults are mostly sensible. In my setup, I have changed the following options:&lt;/p&gt;
    
    &lt;pre&gt;
# Set the domain name for hosts on this network
domain=internal.lan
# Set the start and end of the DHCP pool, and set the
# default lease time to 24 hours
dhcp-range=192.168.1.100,192.168.1.150,24h

# Set DHCP option 3 (which supplies the default route) 
# to the IP address of your router - otherwise dnsmasq 
# will assume that the gateway is the machine it is running on
dhcp-option 3,192.168.1.1

# Answer DNS queries based on the interface the request was sent
# to - the effect of this means that you will never get 127.0.0.1
# returned when looking up the name of the dnsmasq server. 
localise-queries

&lt;/pre&gt;
    &lt;p&gt;You can also hard-code the MAC addresses of your machines into the dnsmasq.conf file, using the dhcp-host statement, so that each machine will always get the same IP address. This is a neat trick, but personally I don't think that dnsmasq.conf is the right place to do that when there is already an /etc/ethers file that stores this information. So, for now, uncomment the &quot;read-ethers&quot; line in dnsmasq.conf. I'll get back to setting up that file in a moment.&lt;/p&gt;
    &lt;p&gt;Next, you want to set up your resolv.conf file. This will contain the IP addresses of the nameservers you want to use, and which dnsmasq will proxy for. In my case, I'm using OpenDNS, so I've grabbed the DNS servers from &lt;a href=&quot;https://www.opendns.com/start&quot;&gt;https://www.opendns.com/start&lt;/a&gt;. My resolv.conf now looks like:&lt;/p&gt;
    
    &lt;pre&gt;
domain internal.lan
nameserver 208.67.222.222
nameserver 208.67.220.220
&lt;/pre&gt;
    &lt;p&gt;To set up internal hosts on your LAN, you just need to enter them in /etc/hosts, and dnsmasq will read them from there. Beyond the normal entries for localhost and some IPv6 ones, I have things that look like:&lt;/p&gt;
    
    &lt;pre&gt;
192.168.1.1     portal.internal.lan        portal
192.168.1.5     zoidberg.internal.lan      zoidberg
192.168.1.10    inara.internal.lan         inara
192.168.1.11    kaylee.internal.lan        kaylee
&lt;/pre&gt;
    &lt;p&gt;You can add as many of these as you like, making sure that the domain name part of them matches what is in /etc/dnsmasq.conf, otherwise they may not work properly.&lt;/p&gt;
    &lt;p&gt;Finally, back to /etc/ethers. This is a simple mapping between MAC addresses and either IP addresses or names, as long as the names can be resolved by either DNS or (in this case) the /etc/hosts file.&lt;/p&gt;
    
    &lt;pre&gt;
00:12:34:56:78:9A zoidberg.planetexpress.lan
00:BC:DE:F0:12:34 animal.planetexpress.lan
&lt;/pre&gt;
    &lt;p&gt;All the hosts in this file will be issued the same IP address every time they do a DHCP request, provided they also exist in /etc/hosts. Bear in mind that MAC addresses are per interface, not per machine, so if you have a laptop with a wired and a wireless interface I'd advise having two entries, one for each. Last of all, ensure that your router or other device isn't running a DHCP server any more, and run /etc/init.d/dnsmasq restart. The new settings should take effect, and all being well, everything should work.&lt;/p&gt;
    &lt;p&gt;(I have updated this based on feedback from &lt;a href=&quot;http://www.dropshock.com/blog/&quot;&gt;Jason Liquorish&lt;/a&gt;, adding a bit about DHCP option 3 and the localise-queries option, which I forgot earlier. Thanks Jason!)&lt;/p&gt;
  </description>
				<published>2008-04-23 16:26:00 +0100</published>
				<link>http://mgdm.net/weblog/the-linksys-nslu2-part-one</link>
			</item>
			
		
	</channel>
</rss>