<?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>shapeshifter.se &#187; General</title>
	<atom:link href="http://www.shapeshifter.se/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.shapeshifter.se</link>
	<description>Mostly miscellaneous technical mumbo-jumbo.</description>
	<lastBuildDate>Mon, 11 Jul 2011 14:19:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Pre-compressed JavaScript files</title>
		<link>http://www.shapeshifter.se/2009/11/08/pre-compressed-javascript-files/</link>
		<comments>http://www.shapeshifter.se/2009/11/08/pre-compressed-javascript-files/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 11:54:54 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[thttpd]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=671</guid>
		<description><![CDATA[You can save bandwidth by pre-compressing your JavaScript files with gzip without relying on dynamic compression such as mod_deflate.  To to this properly and having it working across all browsers you&#8217;ll need to modify your webserver to return the correct mime type and encoding for the file.
Most browsers are quite liberal in what they accept, [...]]]></description>
			<content:encoded><![CDATA[<p>You can save bandwidth by pre-compressing your JavaScript files with gzip without relying on dynamic compression such as mod_deflate.  To to this properly and having it working across all browsers you&#8217;ll need to modify your webserver to return the correct mime type and encoding for the file.</p>
<p>Most browsers are quite liberal in what they accept, except for Safari/Konqueror. For some reason it doesn&#8217;t like it if a JavaScript file ends in .gz, it ignores the content-encoding and attempts to read the compressed data as JavaScript. The key to make it work is to create a new extension, for example .jgz and set the Content-Encoding for this extension to gzip AND to set the mime type of .js to text/javascript, not text/plain or application/x-javascript.</p>
<p>To recap, call the file script.js.jgz and make sure your webserver delivers it with the following options</p>
<blockquote><pre>
Content-Encoding: gzip
Content-Type: text/javascript</pre>
</blockquote>
<p>Just include the file as usual</p>
<blockquote><pre>
&lt;script type="text/javascript" src="script.js.jgz"&gt;&lt;/script&gt;
</pre>
</blockquote>
<p>This has been tested with the following browsers</p>
<ul>
<li>Firefox 3.0/3.5</li>
<li>Opera 10</li>
<li>Internet Explorer 7</li>
<li>Konqueror (webkit based, behaves like Safari)</li>
<li>Google Chrome 3</li>
<li>Epiphany</li>
</ul>
<h3>Apache</h3>
<p>Put the following in a .htaccess file</p>
<blockquote><pre>
AddType text/javascript .js
AddEncoding gzip .jsz</pre>
</blockquote>
<h3>thttpd</h3>
<p>Add jsz gzip to mime_encodings.txt and change the type for js in mime_types.txt to js text/javascript.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/11/08/pre-compressed-javascript-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VirtualBox hacking</title>
		<link>http://www.shapeshifter.se/2009/08/21/virtualbox-hacking/</link>
		<comments>http://www.shapeshifter.se/2009/08/21/virtualbox-hacking/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 14:55:04 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=661</guid>
		<description><![CDATA[VirtualBox (host mode) was quite recently ported to FreeBSD, some bits are still missing particular network support. So I spent the last couple of days hacking on it and how have a working implementation that supports bridged adapters.
Update 10 Sep: The patches have been committed upstreams. 
Update 9 Sep: working vboxnetadp and patchset sent upstreams.
Update: [...]]]></description>
			<content:encoded><![CDATA[<p>VirtualBox (host mode) was quite recently ported to FreeBSD, some bits are still missing particular network support. So I spent the last couple of days hacking on it and how have a working implementation that supports bridged adapters.</p>
<p>Update 10 Sep: <a href="http://www.virtualbox.org/changeset/22875">The patches have been committed upstreams. </a><br />
Update 9 Sep: working vboxnetadp and patchset sent upstreams.<br />
Update: Re-written to use netgraph, now works on FreeBSD 7 and 8</p>
<p>Patches can be found at</p>
<p><a href="http://www.shapeshifter.se/pub/patches/virtualbox/vbox-freebsd-netif-20090908.patch">http://www.shapeshifter.se/pub/patches/virtualbox/vbox-freebsd-netif-20090908.patch</a><br />
<a href="http://www.shapeshifter.se/pub/patches/virtualbox/vbox-freebsd-vboxnetadp-20090908.patch">http://www.shapeshifter.se/pub/patches/virtualbox/vbox-freebsd-vboxnetadp-20090908.patch</a><br />
<a href="http://www.shapeshifter.se/pub/patches/virtualbox/vbox-freebsd-vboxnetflt-20090908.patch">http://www.shapeshifter.se/pub/patches/virtualbox/vbox-freebsd-vboxnetflt-20090908.patch</a><br />
<a href="http://www.shapeshifter.se/pub/patches/virtualbox/Config.kmk-20090908.patch">http://www.shapeshifter.se/pub/patches/virtualbox/Config.kmk-20090908.patch</a><br />
<a href="http://www.shapeshifter.se/pub/patches/virtualbox/src-VBox-HostDrivers-Makefile.kmk-20090908.patch">http://www.shapeshifter.se/pub/patches/virtualbox/src-VBox-HostDrivers-Makefile.kmk-20090908.patch</a></p>
<p>Additional patches to test with the <strong>3.0.51.r22226</strong> version in FreeBSD ports.</p>
<p><a href="http://www.shapeshifter.se/pub/patches/virtualbox/Config.kmk-r22226-20090908.patch">http://www.shapeshifter.se/pub/patches/virtualbox/Config.kmk-r22226-20090908.patch</a><br />
<a href="http://www.shapeshifter.se/pub/patches/virtualbox/virtualbox-port-20090907.patch">http://www.shapeshifter.se/pub/patches/virtualbox/virtualbox-port-20090907.patch</a><br />
<a href="http://www.shapeshifter.se/pub/patches/virtualbox/ConsoleImpl2.cpp.patch">http://www.shapeshifter.se/pub/patches/virtualbox/ConsoleImpl2.cpp.patch</a></p>
<p>Re-install VirtualBox through ports using the following commands</p>
<blockquote>
<pre>
Apply/compile with
cd /usr/ports/emulators/virtualbox
make clean patch
mkdir work/virtualbox-3.0.51r22226/src/VBox/HostDrivers/VBoxNetFlt/freebsd
mkdir work/virtualbox-3.0.51r22226/src/VBox/HostDrivers/VBoxNetAdp/freebsd
patch < virtualbox-port-20090907.patch
patch -d work/virtualbox-3.0.51r22226/Config.kmk-r22226-20090908.patch
patch -d work/virtualbox-3.0.51r22226/ConsoleImpl2.cpp.patch
patch -d work/virtualbox-3.0.51r22226/src-VBox-HostDrivers-Makefile.kmk-20090908.patch
patch -d work/virtualbox-3.0.51r22226/vbox-freebsd-netif-20090908.patch
patch -d work/virtualbox-3.0.51r22226/vbox-freebsd-vboxnetadp-20090908.patch
patch -d work/virtualbox-3.0.51r22226/vbox-freebsd-vboxnetflt-20090908.patch
make install
</pre>
</blockquote>
<p>In VirtualBox network settings, under "Bridged Adapter" you should now see your available network interfaces. Select the one connected to your network and boot your virtual machine.  It should now be connected to your local network as any other machine.</p>
<p>Host only adapter mode can be used to create a virtual network with multiple guests, it creates a special vboxnetX adapter on the host. You'll have to do normal routing between this interface to get outside connectivity.</p>
<p>In addition to vboxdrv.ko you'll have to load vboxnetflt.ko and vboxnetadp.ko too.</p>
<blockquote>
<pre>
kldload /boot/modules/vboxnetflt.ko
kldload /boot/modules/vboxnetadp.ko
</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/08/21/virtualbox-hacking/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>1-wire meets IPv6</title>
		<link>http://www.shapeshifter.se/2009/07/10/1-wire-meets-ipv6/</link>
		<comments>http://www.shapeshifter.se/2009/07/10/1-wire-meets-ipv6/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 12:25:19 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[1-wire]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[Ethernet]]></category>
		<category><![CDATA[IPv6]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=548</guid>
		<description><![CDATA[A project I&#8217;ve been hacking on for a while is a self-contained 1-wire to IPv6 bridge based on an Atmel AVR ATmega644 and the ENC28J60 Ethernet controller from Microchip.
1-wire: is a serial bus from Dallas Semiconductor/Maxim that only requires 1 data line, there are a number of cheap sensors and other devices for this bus. [...]]]></description>
			<content:encoded><![CDATA[<p>A project I&#8217;ve been hacking on for a while is a self-contained <a href="http://www.maxim-ic.com/products/1-wire/">1-wire</a> to IPv6 bridge based on an <a href="http://www.atmel.com/dyn/products/product_card.asp?PN=ATmega644P%20Automotive">Atmel AVR ATmega644</a> and the <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en022889">ENC28J60</a> Ethernet controller from Microchip.</p>
<p><strong>1-wire</strong>: is a serial bus from Dallas Semiconductor/Maxim that only requires 1 data line, there are a number of cheap sensors and other devices for this bus. The strength of this bus is not its speed but that it supports large ranges (up to 300 meters).<br />
Also, each 1-wire device has a permanent <em>unique</em> 64-bit serial number.</p>
<p><strong>IPv6</strong>: Insanely large address space. It&#8217;s common to use a 64-bit netmask for site networks so that <a href="http://en.wikipedia.org/wiki/EUI-64">EUI-64</a> based addresses can be used for auto configuration. This leaves 64-bit for the node address &#8211; do you see where this is going now&#8230; <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Yes..I&#8217;ve built a device that assigned each 1-wire device it&#8217;s connected to its own IPv6 address. Why? you ask, mostly because I can.</p>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --></p>
<h3>Hardware</h3>
<p>As mentioned above, the device is based on an AVR ATmega644. It has 64KB of flash memory for program code and 4KB of RAM. It&#8217;s running on its built-in oscillator at 8MHz. The ENC28J60 Ethernet chip is connected to the AVR using SPI. The rest of the hardware is mostly for power distribution and management.</p>
<p>The PCB was manufactured by <a href="http://www.batchpcb.com/">BatchPCB</a>, cheap service but a bit slow turn-around time.</p>
<p><a href="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00658.JPG"><img class="aligncenter size-medium wp-image-608" title="Populated PCB" src="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00658-300x225.jpg" alt="Populated PCB" width="300" height="225" /></a></p>
<p>Unfortunately I  screwed up the SPI connection but I managed to fix that with some green wires (or black wires in this case). You&#8217;ll note them in the picture above.<br />
I also intended to run the AVR at 5V and the ethernet chip at 3.3V. This is what the quad AND-gate in the upper right<br />
corner was for, but since I screwed up the SPI routing it&#8217;s disconnected and the whole circuit is running at 3.3V.<br />
The ENC28J60 can only run at 3.3V, the AVR has a range from 2.8-5V and 1-wire should be ran at 5V but works at 3.3V. Hence the need for TTL voltage translation.</p>
<p>As for the 1-wire devices I had implemented a bus master in software that generated the require waveforms. It worked great up to about 10-15 meters. Any cable length greater than that refused to work.<br />
This was a bit unexpected and without an oscilloscope it was more or less impossible to figure out where and how the signals got mangled. So I simply got a <a href="http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2923">DS2480</a> 1-wire line driver that generates the required signals in hardware with more precise timing.</p>
<div id="attachment_595" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00725.JPG"><img class="size-medium wp-image-595" title="DSC00725" src="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00725-300x189.jpg" alt="Add-on board with a 1-wire master" width="300" height="189" /></a><p class="wp-caption-text">Add-on board with a 1-wire master</p></div>
<p>This required an add-on board and because I didn&#8217;t want to wait for a new PCB I used a 2.54mm prototype board. With the DS2480 only available in SOIC8 packages it required some &#8220;creative&#8221; soldering <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
The DS2480 required 5V, thus It had to get its own power supply and also required level translation on the UART line between this device and the AVR. I choose an approach using MOSFETs and a few resistors for this (the TO92 packages in the picture above). This turned out to work really good and I think I&#8217;m going to use this for the SPI level translation in the next revision of the board.<br />
The wire leaving the board on the left side leads to the 1-wire sensor devices.</p>
<p>The add-on board is extremely ugly. But hey, it works.</p>
<p>Future improvements for the next revision</p>
<ul>
<li>Use of external crystal at 16MHz instead of internal 8MHz clock.</li>
<li>Use MOSFETs for 3.3-5 V translation. Need to test it at 16MHz before manufacturing a PCB though.</li>
<li>Obviously fix all PCB errors <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>All SMD parts (resistors and voltage regulators) to shrink PCB size even more.</li>
<li>Better power distribution. I was a bit too conservative with the decoupling capacitors resulting in some weird power problems (fixable with some caps)</li>
<li>Create a real add-on board</li>
</ul>
<p>I&#8217;ll publish the PCB CAD files when the next revision is complete.</p>
<h3>Software</h3>
<p>The only small IPv6 stack I know of is the uIPv6 stack in the <a href="http://www.sics.se/contiki/">Contiki operating system</a> created by Adam Dunkel et al. This is unfortunately only available together with Contiki and not as a stand alone package as the originally uIP (IPv4) stack.</p>
<p>Contiki is a great operating system, but when you only have 4KB of RAM it becomes a bit heavy weight. So I broke out the uIPv6 stack from Contiki and made it run stand alone and ported in to AVR. I also ported the web server application from Contiki and made it run on AVR. As I wanted to use multiple IPv6 addresses I also had to add support for IP aliases to the uIPv6 stack.</p>
<p>Since the uIPv6 was integrated with Contiki it used the Contiki process model which it self is based on &#8220;proto-threads&#8221; (another thing invented by Adam Dunkel). I felt that this didn&#8217;t fit so I turned all processes into a polling mode instead. So one has to call a set of polling functions from the main application loop or from timers.</p>
<p>The other major parts of the code are drivers for ENC28J60, DS2480 and DS1820.</p>
<h5>Software</h5>
<dl>
<dt>1-wire devices</dt>
<dd>30 second polling interval with auto-discovery of new devices.<br />
Each device is assigned its own IPv6 address, requires a /64 network to be available.</dd>
<dt>Webserver</dt>
<dd>Integrated web server makes it possible to visit each address. An XML file with the latest sensor reading is returned. An &#8220;age timestamp&#8221; is also provided which makes it possible to determine how old the reading is. </dd>
</dl>
<p>Currently, with 5 1-wire devices connected it uses about 3KB of RAM.</p>
<ul>
<li><a href="http://svn.h3q.net/work/avr/ethernode/src">Source code</a></li>
<li><a href="http://www.shapeshifter.se/code/uipv6/">uIPv6 port</a></li>
</ul>
<h3>In-action</h3>
<p>I only have temperature sensors connected at the moment. If you happen to have an IPv6 capable connection you can access the sensors through a web browser.</p>
<p><a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:2894:eaf6:100:0c7]">2001:16d8:ffe5:002:2894:eaf6:100:0c7</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:28c1:b4f6:100:035]">2001:16d8:ffe5:002:28c1:b4f6:100:035</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:2809:aef6:100:0ca]">2001:16d8:ffe5:002:2809:aef6:100:0ca</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:28c5:a5f6:100:058]">2001:16d8:ffe5:002:28c5:a5f6:100:058</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:2813:caf6:100:050]">2001:16d8:ffe5:002:2813:caf6:100:050</a></p>
<p style="text-align: center;">(If you don&#8217;t have IPv6 you should get it, or you can view graphs based on the sensor values at <a rel="nofollow" href="http://www.lindberg.tl">lindberg.tl</a> instead).</p>
<table style="text-align: center;" border="0" cellspacing="2">
<tbody>
<tr>
<td><a href="/wp-content/uploads/2009/07/DSC00664.JPG"><img title="DSC00664" src="/wp-content/uploads/2009/07/DSC00664-300x225.jpg" alt="DSC00664" width="300" height="225" /></a></td>
<td><a href="/wp-content/uploads/2009/07/DSC00661.JPG"><img title="DSC00661" src="/wp-content/uploads/2009/07/DSC00661-300x225.jpg" alt="DSC00661" width="300" height="225" /></a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/07/10/1-wire-meets-ipv6/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>DIY: Female-Female USB-adapter</title>
		<link>http://www.shapeshifter.se/2009/07/07/diy-female-female-usb-adapter/</link>
		<comments>http://www.shapeshifter.se/2009/07/07/diy-female-female-usb-adapter/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 15:18:57 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[usb]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=553</guid>
		<description><![CDATA[Do you have a bunch of useless USB-to-PS/2 keyboard adapters laying around? Two of them make a great female-female USB adapter &#8211; If you need one that is. Here is how I made one.

Carefully crack the case open using a knife. You can be quite rough at the PS/2 end of the casing as this [...]]]></description>
			<content:encoded><![CDATA[<p>Do you have a bunch of useless USB-to-PS/2 keyboard adapters laying around? Two of them make a great female-female USB adapter &#8211; If you need one that is. Here is how I made one.</p>
<p><a href="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_open.jpg"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_open-300x133.jpg" alt="usb_to_ps2_open" title="usb_to_ps2_open" width="300" height="133" class="alignright size-medium wp-image-561" /></a></p>
<p>Carefully crack the case open using a knife. You can be quite rough at the PS/2 end of the casing as this part will be<br />
removed anyway. Don&#8217;t destroy the USB side of the casing as this part will be reused for our adapter casing later on.</p>
<p>Once opened you should basically have a USB-connector connected to a PS/2 connector covered in hot glue/plastic wrapped in a thin-foil like material (for shielding). Remove the wrapping and cut away the PS/2 connector with a knife.</p>
<p>Now, carefully remove the remaining plastic. Don&#8217;t worry about the soldered wires but  make sure that you don&#8217;t damage the pins on the USB connector. You should end up with something like this.</p>
<p><a href="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_stripped.jpg"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_stripped-300x200.jpg" alt="usb_to_ps2_stripped" title="usb_to_ps2_stripped" width="300" height="200" class="aligncenter size-medium wp-image-567" /></a></p>
<p>Do the same with another USB-PS/2 adapter so that you basically end up with two USB connectors.<br />
Bring out your soldering iron and de-solder the remaining wires from the connectors.</p>
<p><a href="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_two_stripped.jpg"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_two_stripped-300x178.jpg" alt="usb_to_ps2_two_stripped" title="usb_to_ps2_two_stripped" width="300" height="178" class="aligncenter size-medium wp-image-570" /></a></p>
<p>Place the connectors back-to-back and turn one of them 180 degrees so that it becomes &#8220;up-side-down&#8221;. If you don&#8217;t do this you&#8217;ll end up connecting the pins in the wrong way.<br />
To make the pins touch each other you&#8217;ll have to bend them roughly 30-45 degrees. Solder the pins together.</p>
<p><a href="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_soldered.jpg"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_soldered-300x170.jpg" alt="usb_to_ps2_soldered" title="usb_to_ps2_soldered" width="300" height="170" class="aligncenter size-medium wp-image-564" /></a></p>
<p>Cut out a piece of wire and solder it to the casing off each connector. You can use the existing solder points used for the shielding/ground or create a new. Some flux will help a lot here.</p>
<p><a href="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_soldered_gnd_side.jpg"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_ps2_soldered_gnd_side-300x131.jpg" alt="usb_to_ps2_soldered_gnd_side" title="usb_to_ps2_soldered_gnd_side" width="300" height="131" class="aligncenter size-medium wp-image-565" /></a></p>
<p>That&#8217;s it for the connector. Next up is to creating a new casing using the existing casings. Unfortunately I forgot to take pictures of this process.<br />
Take on pair of the two cases, take one of the two pieces and place the USB-USB adapter inside it . Make a mark on the casing approximately in the middle of where the soldered pins meet.<br />
Cut at this point and do the same for the same half of the other case. Just do a rough cut and file the pieces until the adapter fits. Once the bottom fits, do the same for the top part using the bottom pieces as a template.</p>
<p>Place it in the new casing and pour some hot glue over it to make it steady. Glue the top on and it&#8217;s complete.<br />
<a href="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_usb_half_assembled.jpg"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_usb_half_assembled-300x200.jpg" alt="usb_to_usb_half_assembled" title="usb_to_usb_half_assembled" width="300" height="200" class="aligncenter size-medium wp-image-572" /></a></p>
<p>USB-USB female adapter in action.<br />
<a href="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_usb_assembled.jpg"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/06/usb_to_usb_assembled-300x225.jpg" alt="usb_to_usb_assembled" title="usb_to_usb_assembled" width="300" height="225" class="aligncenter size-medium wp-image-571" /></a></p>
<p>Will it be as good as a commercial adapter? probably not. Will it effect data transmission? probably (depending on how good the solder joints are). Cheaper than a commercial adapter? yep (assuming you already have the parts needed and don&#8217;t factor in the labor <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/07/07/diy-female-female-usb-adapter/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>AVR System Timer</title>
		<link>http://www.shapeshifter.se/2009/06/02/avr-system-timer/</link>
		<comments>http://www.shapeshifter.se/2009/06/02/avr-system-timer/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 10:17:41 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[microcontroller]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=546</guid>
		<description><![CDATA[Handy system clock for AVR 8-bit microcontrollers suitable for measuring elapsed time or for use with timers. This provides
a monotonic time since system startup (like the POSIX CLOCK_MONOTONIC).
The system clock is based around a 32kHz clock crystal and one of the 8-bit timers provided by the AVR, it is possible to use the CPU frequency [...]]]></description>
			<content:encoded><![CDATA[<p>Handy system clock for AVR 8-bit microcontrollers suitable for measuring elapsed time or for use with timers. This provides<br />
a monotonic time since system startup (like the POSIX CLOCK_MONOTONIC).</p>
<p>The system clock is based around a 32kHz clock crystal and one of the 8-bit timers provided by the AVR, it is possible to use the CPU frequency as a timer base as  long as it&#8217;s a nice, dividable, frequency.<br />
To be able to provide a stable 1 Hz clock but still have sub-second precision we divide 1 second into an arbitrary number of<br />
system ticks. To minimize CPU usage the tick counter should be increased at each interrupt, this means that the number of<br />
ticks per second we we choose determines our interrupt frequency and timer resolution.<br />
How to choose number of ticks? It all depends on your required resolution, if you only want a 1 second resolution a tick and a second becomes equal.</p>
<p>The AVR timer is a 8-bit register that simply counts at the rate of its clock source. The clock source can be either the CPU<br />
clock or an external oscillator, the clock source is also subject to a prescaler to further decrease the frequency.<br />
The timer then generates an interrupt on overflow and/or when it hits a pre-configured value.<br />
Since its a 8-bit timer, we have a maximum of 256 cycles before an interrupt is generated, a smaller interval can be achieved by using the comparator match to generate an interrupt at a specific value.</p>
<p>This example is creating a 1/32 second resolution timer (32 ticks per second) using an external 32768 Hz watch crystal.<br />
<em>comp</em> is the comparator value, to avoid re-arming it with different values it should be limited to 128 or 256, otherwise it has to be changed at each interrupt.</p>
<img src='http://s.wordpress.com/latex.php?latex=F_%7Btimer%7D%20%3D%2032768&#038;bg=FAFAFA&#038;fg=000000&#038;s=1' alt='F_{timer} = 32768' title='F_{timer} = 32768' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=ticks%20%3D%2032&#038;bg=FAFAFA&#038;fg=000000&#038;s=1' alt='ticks = 32' title='ticks = 32' class='latex' />
<p>The following to equations can be used to calculate either <em>comp</em> or the <em>prescale</em> value.<br />
<em>prescale</em> is limited by the target device, but common values are powers of 2 (8,32,64,128,256,1024).</p>
<p style="text-align: center;"><img src='http://s.wordpress.com/latex.php?latex=comp%20%3D%20%5Cfrac%7B%5Cfrac%7BF_%7Btimer%7D%7D%7Bprescale%7D%7D%7Bticks%7D&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='comp = \frac{\frac{F_{timer}}{prescale}}{ticks}' title='comp = \frac{\frac{F_{timer}}{prescale}}{ticks}' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=prescale%20%3D%20%5Cfrac%7BF_%7Btimer%7D%7D%7Bcomp%20%5Ctimes%20ticks%7D&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='prescale = \frac{F_{timer}}{comp \times ticks}' title='prescale = \frac{F_{timer}}{comp \times ticks}' class='latex' /></p>
<p>Using 128 as the <em>comp</em> value and inserting the other values into equation 2 yields the following prescaler</p>
<p style="text-align: center;">
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B32768%7D%7B128%20%5Ctimes%2032%7D%20%3D%208&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='\frac{32768}{128 \times 32} = 8' title='\frac{32768}{128 \times 32} = 8' class='latex' />
</p>
<p>So, a prescaler of 8 gives us two interrupts per 256 cycles, one at 128 and one at 256 (overflow). Using 256 as <em>comp</em> would yield a perscaler of 4 but the target device I used didn&#8217;t have a TS/4 prescaler.</p>
<p>Complete source code for a 1/32 (or 31.25ms) second resolution timer for the ATmegaxx4 using Timer 2 and a 32kHz watch crystal connected to the pins TOSC1 and TOSC2.<br />
Requires <a href="http://www.nongnu.org/avr-libc/">AVR libc</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;avr/io.h&gt;</span>
<span style="color: #339933;">#include &lt;avr/interrupt.h&gt;</span>
&nbsp;
<span style="color: #993333;">typedef</span> uint32_t clock_time_t<span style="color: #339933;">;</span>
<span style="color: #993333;">static</span> clock_time_t global_system_ticks <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* ISR for the timer overflow */</span>
ISR<span style="color: #009900;">&#40;</span>TIMER2_OVF_vect<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    global_system_ticks<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* ISR for the comparator */</span>
ISR<span style="color: #009900;">&#40;</span>TIMER2_COMPA_vect<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    global_system_ticks<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Return number of elapsed ticks */</span>
clock_time_t clock_time<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>global_system_ticks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Return number of elapsed seconds */</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> clock_seconds<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    uint32_t tmp<span style="color: #339933;">;</span>
&nbsp;
    TIMSK2 <span style="color: #339933;">&amp;=</span> ~<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    tmp <span style="color: #339933;">=</span> global_system_ticks <span style="color: #339933;">/</span> <span style="color: #0000dd;">32</span><span style="color: #339933;">;</span>
    TIMSK2 <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>tmp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> clock_init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Enable external oscillator (32 kHz crystal) connected to TOSC{1,2} */</span>
    ASSR <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> AS2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Reset timer */</span>
    TCNT2 <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Set TS/8 prescaler, results in a 4096Hz clock */</span>
    TCCR2B <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> CS21<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Compare at half counter value */</span>
    OCR2A <span style="color: #339933;">=</span> <span style="color: #0000dd;">128</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/*
     * Enable overflow and compare interrupt.
     * Triggers each 1/32 secs
     */</span>
    TIMSK2 <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/06/02/avr-system-timer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MoreThanAll MagJack Eagle PCB footprint</title>
		<link>http://www.shapeshifter.se/2009/05/28/morethanall-magjack-eagle-pcb-footprint/</link>
		<comments>http://www.shapeshifter.se/2009/05/28/morethanall-magjack-eagle-pcb-footprint/#comments</comments>
		<pubDate>Thu, 28 May 2009 16:02:51 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Eagle]]></category>
		<category><![CDATA[footprint]]></category>
		<category><![CDATA[MagJack]]></category>
		<category><![CDATA[PCB]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=507</guid>
		<description><![CDATA[
Creating PCB footprints is usually quite easy as most components come in standard packages.
Footprints for &#8216;magjacks&#8217; (RJ45 with built-in Ethernet transformer) are another thing as different manufactures tend to at least put the LED pins at different positions.
Here is an Eagle PCB footprint I created for the MagJack (MJF13T36L-KF06B3GY-0808) from MoreThanAll sold by Sparkfun.
This one [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.shapeshifter.se/wp-content/uploads/2009/05/magjack.jpg" alt="magjack" title="magjack" width="100" height="107" class="alignleft size-full wp-image-511" /><br />
Creating PCB footprints is usually quite easy as most components come in standard packages.<br />
Footprints for &#8216;magjacks&#8217; (RJ45 with built-in Ethernet transformer) are another thing as different manufactures tend to at least put the LED pins at different positions.</p>
<p>Here is an Eagle PCB footprint I created for the <a href="http://www.morethanall.com/products/index/btype_id/9/type_id/106/id/1217">MagJack</a> (MJF13T36L-KF06B3GY-0808) from MoreThanAll sold by <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=8534">Sparkfun</a>.</p>
<p>This one has been <strong>proven</strong> in production and it works, however you should double- (and triple-) check pin-outs and footprint of your device before sending a PCB for manufacturing using this part. Use at your own risk.</p>
<div id="attachment_505" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.shapeshifter.se/wp-content/uploads/2009/05/magjack_schematic.png"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/05/magjack_schematic-300x300.png" alt="Magjack schematic" title="magjack_schematic" width="300" height="300" class="size-medium wp-image-505" /></a><p class="wp-caption-text">Magjack schematic</p></div>
<div id="attachment_506" class="wp-caption aligncenter" style="width: 235px"><a href="http://www.shapeshifter.se/wp-content/uploads/2009/05/magjack_footprint.png"><img src="http://www.shapeshifter.se/wp-content/uploads/2009/05/magjack_footprint.png" alt="Magjack footprint" title="magjack_footprint" width="225" height="283" class="size-full wp-image-506" /></a><p class="wp-caption-text">Magjack footprint</p></div>
<h3>Download</h3>
<p><a href='http://www.shapeshifter.se/wp-content/uploads/2009/05/morethanall_magjack.lbr'>morethanall_magjack.lbr</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/05/28/morethanall-magjack-eagle-pcb-footprint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Obscuring SMTP auth headers &#8211; with IPv6</title>
		<link>http://www.shapeshifter.se/2008/12/10/obscuring-smtp-auth-headers-with-ipv6/</link>
		<comments>http://www.shapeshifter.se/2008/12/10/obscuring-smtp-auth-headers-with-ipv6/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 16:01:19 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[postfix]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=410</guid>
		<description><![CDATA[
The FreeBSD Diary and Riseup labs describe a way to anonymize the first &#8220;received from&#8221; header with usually contain the IP-address of the computer the mail was sent from.  This information is removed by taking advantage of the &#8220;Authenticated sender&#8221; and the header_checks directive in Postfix.
The &#8220;Authenticated sender&#8221; is added when a user has been [...]]]></description>
			<content:encoded><![CDATA[<p><!-- WSA: rules for context 'adsense-post-top' did not apply --><br />
The <a href="http://www.freebsddiary.org/smtp-headers-rewrite-auth.php">FreeBSD Diary</a> and <a href="http://riseuplabs.org/privacy/postfix/">Riseup labs</a> describe a way to anonymize the first &#8220;received from&#8221; header with usually contain the IP-address of the computer the mail was sent from.  This information is removed by taking advantage of the &#8220;Authenticated sender&#8221; and the header_checks directive in Postfix.</p>
<p>The &#8220;Authenticated sender&#8221; is added when a user has been authenticated by the MTA through SASL and the directive smtpd_sasl_authenticated_header have been set to yes.  The header_checks directive takes a file containing a regular expression which rewrites the header data and removes sensitive information.</p>
<p>This all works well &#8211; with IPv4. The regular expression posted on the pages mentioned above does not take IPv6 addresses into account, I modified it slightly to accept both IPv4 and IPv6 addresses.</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #339933;">/^</span>Received<span style="color: #339933;">:</span> from <span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span> \<span style="color: #009900;">&#40;</span>\<span style="color: #009900;">&#91;</span><span style="color: #339933;">?</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">-.</span>_<span style="color: #009900;">&#91;</span><span style="color: #339933;">:</span>alnum<span style="color: #339933;">:</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span>\<span style="color: #009900;">&#93;</span><span style="color: #339933;">?</span> \<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>\<span style="color: #339933;">.</span>0<span style="color: #339933;">-</span><span style="color: #cc66cc;">9</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">7</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">15</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">|</span>IPv6<span style="color: #009900;">&#91;</span>\<span style="color: #339933;">:</span>a<span style="color: #339933;">-</span>fA<span style="color: #339933;">-</span>F0<span style="color: #339933;">-</span><span style="color: #cc66cc;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #009900;">&#41;</span>\<span style="color: #009900;">&#93;</span>\<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span>
\<span style="color: #009900;">&#40;</span>Authenticated sender<span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">^</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #009900;">&#41;</span>\<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>by mx1\<span style="color: #339933;">.</span>example\<span style="color: #339933;">.</span>com<span style="color: #009900;">&#41;</span> \<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">^</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #009900;">&#41;</span>\<span style="color: #009900;">&#41;</span> with <span style="color: #009900;">&#40;</span>E<span style="color: #339933;">?</span>SMTPS<span style="color: #339933;">?</span>A<span style="color: #339933;">?</span><span style="color: #009900;">&#41;</span> id
 <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>A<span style="color: #339933;">-</span>F<span style="color: #009900;">&#91;</span><span style="color: #339933;">:</span>digit<span style="color: #339933;">:</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span> REPLACE Received<span style="color: #339933;">:</span> from smtp<span style="color: #339933;">-</span>auth<span style="color: #339933;">.</span>example<span style="color: #339933;">.</span>com <span style="color: #009900;">&#40;</span>smtp<span style="color: #339933;">-</span>auth<span style="color: #339933;">.</span>example<span style="color: #339933;">.</span>com
 <span style="color: #009900;">&#91;</span>127<span style="color: #339933;">.</span>0<span style="color: #339933;">.</span>0<span style="color: #339933;">.</span>1<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span>Authenticated sender<span style="color: #339933;">:</span> hidden<span style="color: #009900;">&#41;</span><span style="color: #0000ff;">$5</span><span style="color: #0000ff;">$6</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$7</span><span style="color: #009900;">&#41;</span> with <span style="color: #0000ff;">$8</span> id <span style="color: #0000ff;">$9</span> <span style="color: #0000ff;">$10</span></pre></div></div>

<p>Note that this should be one single line.</p>
<p>Put this in a file, for example /usr/local/etc/postfix/obscure_smtp_auth and add the following to your Postfix configuration (assuming you have SASL working).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">header_checks <span style="color: #339933;">=</span> pcre<span style="color: #339933;">:/</span>usr<span style="color: #339933;">/</span>local<span style="color: #339933;">/</span>etc<span style="color: #339933;">/</span>postfix<span style="color: #339933;">/</span>obscure_smtp_auth
smtpd_sasl_authenticated_header <span style="color: #339933;">=</span> yes</pre></div></div>

<p>The first header will now be rewritten, for both IPv4 and IPv6 clients and will look something like this.</p>
<pre>
Received: from smtp-auth.example.com (smtp-auth.example.com [127.0.0.1]) 127.0.0.1 (Authenticated sender: hidden)
	by mx1.example.com (Postfix) with ESMTPSA id 3677033C6F
	for &#038;lthostmaster@example.se&gt;; Wed, 10 Dec 2008 16:31:51 +0100 (CET)
</pre>
<p>instead of</p>
<pre>
Received: from [IPv6:2001:xxxx:xxxx:xxxx:xxxx:xxxx:fedd:7914] (unknown [IPv6:2001:xxxx:xxxx:xxxx:xxxx:xxxx::fedd:7914])
	(Authenticated sender: someuser@example.com)
	by mx1.example.com (Postfix) with ESMTPSA id 3677033C6F
	for  &#038;lthostmaster@example.se&gt;;  Wed, 10 Dec 2008 16:31:51 +0100 (CET)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/12/10/obscuring-smtp-auth-headers-with-ipv6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UUID generator for PHP</title>
		<link>http://www.shapeshifter.se/2008/09/29/uuid-generator-for-php/</link>
		<comments>http://www.shapeshifter.se/2008/09/29/uuid-generator-for-php/#comments</comments>
		<pubDate>Mon, 29 Sep 2008 18:48:44 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[UUID]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=352</guid>
		<description><![CDATA[UUID (Universally Unique Identifier) is standard (part of ISO/IEC 11578:1996) to create &#8220;universally unique&#8221; identifiers to identify objects within a system or across system boundaries. The identifiers are 128-bit in length (that&#8217;s 16 bytes) and while there really is no way to guarantee global uniqueness the probability of colissions are very small both thanks to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Uuid">UUID</a> (Universally Unique Identifier) is standard (part of ISO/IEC 11578:1996) to create &#8220;universally unique&#8221; identifiers to identify objects within a system or across system boundaries. The identifiers are 128-bit in length (that&#8217;s 16 bytes) and while there really is no way to guarantee global uniqueness the probability of colissions are very small both thanks to the number of bits and the way the identifiers are created.</p>
<p>The UUID generation algorithms are specified in <a href="http://tools.ietf.org/html/rfc4122">RFC4122</a> and I&#8217;ve created a static PHP class that implements version 1 which is time based UUID, version 4 which is truly psuedo random UUID and version 3 and 5 which are named based UUID, using either MD5 (version 3) or SHA-1 (version 5).<br />
<span id="more-352"></span><br />
I know there is a PECL package around the original uuidlib but this class have no external dependencies. The full source is available at the bottom of the page.</p>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --></p>
<p>The class has the following public functions, their return value depends on the format argument.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$mixed</span> generate<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fmt</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">FMT_BYTE</span><span style="color: #339933;">,</span> <span style="color: #000088;">$node</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ns</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000088;">$mixed</span> convert<span style="color: #009900;">&#40;</span><span style="color: #000088;">$uuid</span><span style="color: #339933;">,</span> <span style="color: #000088;">$from</span><span style="color: #339933;">,</span> <span style="color: #000088;">$to</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>UUID version constants where each constant represents a specific UUID version</p>
<blockquote>
<pre>UUID_TIME, UUID_NAME_MD5, UUID_RANDOM, UUID_NAME_SHA1</pre>
</blockquote>
<p>UUID format constants</p>
<ul>
<li><em>FMT_BYTE</em> is the default and returns a array of bytes that represents the 128-bit UUID.</li>
<li><em>FMT_FIELD</em> returns a associative array with individual fields as the format specified in RFC4122.</li>
<li><em>FMT_STRING</em> returns the familiar ASCII representation of a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx).</li>
<li><em>FMT_BINARY</em> returns a raw 128-bit binary representation of the UUID.</li>
</ul>
<p>The <em>convert</em> method can be used to convert between these representations.</p>
<h3>UUID version 1 example</h3>
<p>xxxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx<br />
Version 1 UUIDs are timed based with the node constant. The name space argument is ignored and is not used in the generation. The node identifier (&#8221;abcdef&#8221; in this case) should identify the node or object, only 6 bytes (or characters) are used from the node id.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class.uuid.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_TIME</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;abcdef&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$str</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Example output, the last part is the node id and will remain constant (as long as the node id is the same), the first part will change according to time while the middle part is pseudo random.</p>
<blockquote>
<pre>1b55e723-578b-4e34-d5cf-616263646566</pre>
</blockquote>
<p>The class does not fully implement version 1 as described in the RFC. The clock sequence is generated from a psuedo random generator each time a new UUID is generated and not written and read from a stable storage as described in the RFC.</p>
<h3>UUID version 4 example</h3>
<p>xxxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx<br />
Version 4 is a fully pseudo random where all fields are randomly generated.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class.uuid.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_RANDOM</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$str</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Kind of useless example output <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote>
<pre>d8988842-43d5-42b3-9049-af4bbc694dbe</pre>
</blockquote>
<h3>UUID version 3/5 example</h3>
<p>xxxxxxxxx-xxxx-3/5xxx-xxxx-xxxxxxxxxxxx<br />
The main difference is that a node id is unique within a name space and a UUID generated from the same node id and name space is always the same. The generation algorithm is the same for both version 3 and 5 with the only difference being the hash method used (MD5 versus SHA1).<br />
This is the example from the RFC.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'class.uuid.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * 6ba7b810-9dad-11d1-80b4-00c04fd430c8 is the DNS name space
 */</span>
<span style="color: #000088;">$md5</span> <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_NAME_MD5</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">&quot;www.widgets.com&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'6ba7b810-9dad-11d1-80b4-00c04fd430c8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$sha1</span>  <span style="color: #339933;">=</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span>UUID<span style="color: #339933;">::</span><span style="color: #004000;">UUID_NAME_SHA1</span><span style="color: #339933;">,</span> UUID<span style="color: #339933;">::</span><span style="color: #004000;">FMT_STRING</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">&quot;www.widgets.com&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'6ba7b810-9dad-11d1-80b4-00c04fd430c8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;MD5: <span style="color: #006699; font-weight: bold;">$md5</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;SHA1: <span style="color: #006699; font-weight: bold;">$sha1</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Example output</p>
<blockquote>
<pre>MD5: e902893a-9d22-3c7e-a7b8-d6e313b71d9f
SHA1: 13726f09-44a9-5eeb-8910-3525a23fb23b</pre>
</blockquote>
<h3>Final notes</h3>
<p>This class have been tested with PHP 5.2.x on both little and big endian machines. While there could be bugs in the algorithm implementation at least they are consistent across platforms <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Get from github</h3>
<ul>
<li><a href="https://github.com/fredriklindberg/class.uuid.php">class.uuid.php</a></li>
</ul>
<h3>Links</h3>
<ul>
<li><a href="http://tools.ietf.org/html/rfc4122">RFC4122</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/09/29/uuid-generator-for-php/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>ShareIt! &#8211; Social Media Bookmark Bar</title>
		<link>http://www.shapeshifter.se/2008/08/05/shareit-social-media-bookmark-bar/</link>
		<comments>http://www.shapeshifter.se/2008/08/05/shareit-social-media-bookmark-bar/#comments</comments>
		<pubDate>Tue, 05 Aug 2008 09:31:45 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[bookmark]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[share]]></category>
		<category><![CDATA[social media]]></category>
		<category><![CDATA[web 2.0]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=176</guid>
		<description><![CDATA[
Want a &#8220;web 2.0&#8243; styled bookmark bar for your blog that automatically creates submission links (bookmark and share) to social media sites? if you answered yes, then continue reading.
I previously used the service from addthis but never really liked it so I created my own, you&#8217;re free to use it if you like. It&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p><!-- WSA: rules for context 'adsense-post-square' did not apply --><br />
Want a &#8220;web 2.0&#8243; styled bookmark bar for your blog that automatically creates submission links (bookmark and share) to social media sites? if you answered yes, then continue reading.</p>
<p>I previously used the service from addthis but never really liked it so I created my own, you&#8217;re free to use it if you like. It&#8217;s a simple script that is quite easy (guess it depends on who you ask&#8230;) to use and that generates bookmark/share buttons for popular services such as delicious, digg, facebook, twitter and more.</p>
<p><strong>Supports Delicious, Digg, StumbleUpon, Twitter, Technorati Favorites, Google Bookmarks, Facebook, Reddit, Diigo, Blogmarks, Blinklist and Magnolia</strong></p>
<p>This is a sample of how the bookmark bar could look, it&#8217;s possible to re-arrange and remove individual services if wanted. The icons are courtesy of <a href="http://fasticon.com/freeware/index.php/web-2-icons/">http://fasticon.com/freeware/index.php/web-2-icons/</a></p>
<p style="text-align: center;"><a href="http://www.shapeshifter.se/wp-content/uploads/2008/08/bookmarks.png"><img class="size-full wp-image-178 aligncenter" title="bookmarks" src="http://www.shapeshifter.se/wp-content/uploads/2008/08/bookmarks.png" alt="" width="290" height="26" /></a></p>
<p>Follow this guide to get your own bookmark bar, you need some knowledge of how to edit HTML.<br />
<span id="more-176"></span></p>
<h3>Step 1</h3>
<ul>
<li>Download <a href="/pub/shareit/shareit.js">shareit.js</a></em></li>
<li>Download the icon pack from <a href="http://fasticon.com/freeware/index.php/web-2-icons/">here</a> or <a href="/pub/shareit/Web2Icons_PNG.zip">here</a></li>
</ul>
<h3>Step 2</h3>
<p>Extract the folder <em>Icons</em> from Web2Icons_PNG.zip, copy the <em>Icons</em> directory and the <em>shareit.js</em> file to your webhost.</p>
<h3>Step 3</h3>
<p>Integrate a piece of JavaScript code where you would like the bookmark bar to appear, the script will automatically get the current page title and page link and use that as the base for the submission.</p>
<p>There are three variables that affect the look.</p>
<ul>
<li><em>share_show</em> &#8211; Selects which services to display</li>
<li><em>share_icon_path</em> &#8211; Absolute path to icon directory</li>
<li><em>share_domain</em> &#8211; Optional, if you want your domain to be replaced with something else.</li>
</ul>
<p>Make sure to adjust the path to the Icons and shareit.js so that they point to the correct position on your webhost.</p>
<p>This will give you a bookmark bar like the one above.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #003366; font-weight: bold;">var</span> share_show <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'delicious'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'digg'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'stumbleupon'</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">'twitter'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'technorati'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'google'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'facebook'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'reddit'</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">'diigo'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'blogmarks'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'blinklist'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'magnolia'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> share_icon_path <span style="color: #339933;">=</span> <span style="color: #3366CC;">'/Icons/'</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&lt;script type=&quot;text/javascript&quot; src=&quot;/shareit.js&quot;&gt;&lt;/script&gt;</pre></div></div>

<p>You can tweak <em>share_show</em> to select and order which services you would like to display, for example to only display FaceBook, Digg, Delicious and Twitter set it like this</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #003366; font-weight: bold;">var</span> share_show <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'facebook'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'digg'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'delicious'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'twitter'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> share_icon_path <span style="color: #339933;">=</span> <span style="color: #3366CC;">'/Icons/'</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&lt;script type=&quot;text/javascript&quot; src=&quot;/shareit.js&quot;&gt;&lt;/script&gt;</pre></div></div>

<p>If you have an IDN domain you need to use the <em>share_domain</em> setting, set it to your puny-encoded domain. Like this</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #003366; font-weight: bold;">var</span> share_show <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'delicious'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'digg'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'stumbleupon'</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">'twitter'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'technorati'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'google'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'facebook'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'reddit'</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">'diigo'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'blogmarks'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'blinklist'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'magnolia'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> share_icon_path <span style="color: #339933;">=</span> <span style="color: #3366CC;">'/Icons/'</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> share_domain <span style="color: #339933;">=</span> <span style="color: #3366CC;">'www.xn--bcher-kva.ch'</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&lt;script type=&quot;text/javascript&quot; src=&quot;/shareit.js&quot;&gt;&lt;/script&gt;</pre></div></div>

<p>There you have, you should now have your very own bookmark bar!</p>
<p>If you use this on your blog/website consider putting a link back to here, thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/08/05/shareit-social-media-bookmark-bar/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Asynchronous background execution with PHP</title>
		<link>http://www.shapeshifter.se/2008/08/04/asynchronous-background-execution-with-php/</link>
		<comments>http://www.shapeshifter.se/2008/08/04/asynchronous-background-execution-with-php/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 08:23:12 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=189</guid>
		<description><![CDATA[If you ever worked with threads and particular work queues you know how convenient they can be.
Have some demanding work that needs to be done but no time to do it yourself? No problem, just put it on the work queue and continue with whatever we were doing, some other thread will come along and [...]]]></description>
			<content:encoded><![CDATA[<p>If you ever worked with threads and particular work queues you know how convenient they can be.<br />
Have some demanding work that needs to be done but no time to do it yourself? No problem, just put it on the work queue and continue with whatever we were doing, some other thread will come along and do the dirty work for you.</p>
<p>Consider the following scenario. Actions and inputs from a web page triggers something that might take a (very) long time to execute and if executed during the browser session which besides annoying the user who has to wait for a page to load, might cause a time out and interrupt the processing. How do we solve this?</p>
<p><span id="more-189"></span></p>
<p>I&#8217;ll use the term <em>job</em> to indicate some work that needs to be execution, in practice this is an isolated PHP function which takes an unspecified time to execute.</p>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --></p>
<p>Some possible solutions</p>
<ul>
<li>Store job information somewhere (like a SQL database) have a separate script, PHP or in some other language, running on the host, either continuously or from <a href="http://en.wikipedia.org/wiki/Cron">crontab</a>. The obvious flaw is that it requires additional administrative maintenance to keep the script running and if executed from crontab, will cause an additional delay before the job is executed.</li>
<li>Use <a href="http://www.php.net/manual/en/function.pcntl-fork.php">pcntl_fork</a> from inside the (web page) PHP script and execute the job function in the child, problem is that this will fork an entire Apache (or whatever web server you&#8217;re using) processes which can cause all sorts of problems.</li>
<li>Some other solution I didn&#8217;t think about? <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>My solution ended up being a mix of the two above. It consists of three major parts and, a bit simplified, works like this</p>
<ol>
<li>Job information is stored in a SQL database.</li>
<li>An external CLI-based <em>worker</em> PHP-script is launched from inside the web page script using <a href="http://www.php.net/manual/en/function.proc-open.php">proc_open</a>.</li>
<li>The worker script, which is running in an isolated PHP process calls pcntl_fork to create a duplicate of itself. The parent returns directly to the web page script.</li>
<li>The child process of the worker script now runs free of any webserver process and can now retrieve job information from the SQL database. When all jobs are executed it kills itself.</li>
</ol>
<p>Here is a nice block diagram that shows the interaction of the components</p>
<p style="text-align: center;">
<a href="http://www.shapeshifter.se/wp-content/uploads/2008/08/bgphp.png"><img src="http://www.shapeshifter.se/wp-content/uploads/2008/08/bgphp-300x173.png" alt="Block layout of PHP background execution" title="bgphp" width="300" height="173" class="size-medium wp-image-205" style="float: none;" /></a>
</p>
<p>And viola, we have asynchronous background execution of (almost) arbitrary PHP functions. There are a few problems left to solve, we&#8217;ll tackle those further down.</p>
<p><strong>Requirements</strong></p>
<ul>
<li>PHP 5 built with CLI support</li>
<li>The PHP module pcntl</li>
<li>The classes <em>SQLConnector</em> and <em>Prefs</em> published in earlier posts.</li>
</ul>
<h3>SQL database</h3>
<p>First, we&#8217;ll need some database support. I&#8217;ve used MySQL, but any database should work fine. One simple table is required, it&#8217;s called <em>jobs</em> and looks like this</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+---------------------+------+-----+---------+----------------+</span>
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">FIELD</span> <span style="color: #66cc66;">|</span> Type                <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #66cc66;">|</span> Extra          <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+---------------------+------+-----+---------+----------------+</span>
<span style="color: #66cc66;">|</span> jid   <span style="color: #66cc66;">|</span> bigint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span> PRI <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">DATA</span>  <span style="color: #66cc66;">|</span> text                <span style="color: #66cc66;">|</span> YES  <span style="color: #66cc66;">|</span>     <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span>                <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------+---------------------+------+-----+---------+----------------+</span></pre></div></div>

<p>The column <em>jid</em> is an arbitrary job id and the column <em>data</em> contains job information (more on what exactly job information is will be covered further down). You can create this table with the following SQL command</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> jobs <span style="color: #66cc66;">&#40;</span>jid bigint <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
    <span style="color: #993333; font-weight: bold;">DATA</span> text<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>jid<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>PHP implementation</h3>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --><br />
The implementation consists of three files, we&#8217;ll focus on the class <em>jobs</em> first. This leads us into what exactly the <em>data</em> column should contain. Since the <em>job</em> (PHP function) will execute in a new context the worker must be able to bring in PHP files so that required functions and classes can be resolved. So, in addition to the actual job function and an opaque argument we also need to store a list of PHP files to include at execution time.</p>
<p>The complete data structure stored in the <em>data</em> column looks like this.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #666666; font-style: italic;">/* Version identifier of job structure */</span>
    <span style="color: #0000ff;">'version'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">/* Array of PHP files to include at execution time */</span>
    <span style="color: #0000ff;">'include'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">/* Name of actual job function */</span>
    <span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">/* Opaque argument passed to callback function */</span>
    <span style="color: #0000ff;">'args'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>A dedicated class calls <em>jobs</em> manages jobs and allows enqueuing and dequeuing of jobs. For clarity, only the function prototypes are shown here, the full source code can be found at the bottom of the pafe.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> jobs <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_con</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">/* SQL Connector */</span>
    <span style="color: #000000; font-weight: bold;">const</span> jobversion <span style="color: #339933;">=</span> <span style="color: #0000ff;">'1'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">/* Job structure version */</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$m_data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'version'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">jobversion</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'include'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'callback'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'args'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Enqueue a job for execution
     *  cb - Name of PHP function to execute
     *  args - Arguments to pass to 'cb'
     *  incs - Array of PHP files to include before execution
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> enqueue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$cb</span><span style="color: #339933;">,</span> <span style="color: #000088;">$args</span><span style="color: #339933;">,</span> <span style="color: #000088;">$incs</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Return the job identifier (integer) of
     * next available job or -1 if no new jobs are
     * available.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> nextJob<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;">/*
     * Dequeue job with id 'jid' for execution,
     * if no such job is available null is returned.
     *
     * An array with the following keys are returned
     *  (jid, include, callback, args)
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> dequeue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$jid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Attempt to launch worker process if not already running
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> startWorker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The callback function &#8216;cb&#8217; will be called like this, <em>cb(args)</em>, before this call all files listed in the array <em>incs</em> will be included using <em>require_once</em>.<br />
The functions <em>enqueue</em>, <em>dequeue</em> and <em>nextJob</em> are nothing special, they simply do normal SQL manipulation (inserts and removes job from the table). However the routine <em>startWorker</em> might deserve some attention (it&#8217;s called internally from <em>enqueue</em>)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/* Should be set to the path of the CLI PHP binary */</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;PHP_PATH&quot;</span><span style="color: #339933;">,</span>      <span style="color: #0000ff;">&quot;/usr/local/bin/php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> startWorker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">/*
     * Attempt to read the preference
     * 'worker_pid' to check if the worker is
     * already running.
     */</span>
    <span style="color: #000088;">$prefs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">m_con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'jobs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">worker_pid</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">!=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Get our working directory */</span>
    <span style="color: #000088;">$cwd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">getcwd</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;">/*
     * Construct a command such as the following
     *  /usr/local/bin/php /working/path/worker.php
     */</span>
    <span style="color: #000088;">$cmd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">escapeshellcmd</span><span style="color: #009900;">&#40;</span>PHP_PATH <span style="color: #339933;">.</span><span style="color: #0000ff;">&quot; <span style="color: #006699; font-weight: bold;">$cwd</span>/worker.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$desc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</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;">/* Execute the command and wait for it to finish */</span>
    <span style="color: #000088;">$proc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">proc_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cmd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$desc</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pipes</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">proc_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$proc</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <em>startWorker</em> function is executed in the context of a web page (from inside the Apache PHP module for example) and as you can see it doesn&#8217;t call <em>pcntl_fork</em> directly. Technically it still forks, otherwise it wouldn&#8217;t be able to execute another process. But we let the PHP module deal with that mess.</p>
<p>This leads us to worker.php<br />
File: <strong>worker.php</strong>
</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'prefs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mysql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;PHP_PATH&quot;</span><span style="color: #339933;">,</span>      <span style="color: #0000ff;">&quot;/usr/local/bin/php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$argv</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Don't call me from a browser&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Fork our self and let the parent return directly to startWorker
 */</span>
<span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;could not fork&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">/*
     * This is the parent process. Record the child pid so that we
     * don't launch more processes than wanted.
     */</span>
    <span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$prefs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'jobs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">worker_pid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$pid</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">/*
     * Exit the script, it runs in a separate
     * PHP process NOT inside Apache
     */</span>
    <span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span>
<span style="color: #000088;">$jobs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> jobs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$cwd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">getcwd</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$cwd</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;can't get working directory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Loop over all available jobs
 */</span>
<span style="color: #000088;">$pjid</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$jid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$jobs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nextJob</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$jid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #339933;">||</span> <span style="color: #000088;">$jid</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$pjid</span><span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/*
     * Execute each job in a clean environment
     */</span>
    <span style="color: #000088;">$cmd</span> <span style="color: #339933;">=</span> <span style="color: #990000;">escapeshellcmd</span><span style="color: #009900;">&#40;</span>PHP_PATH <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; <span style="color: #006699; font-weight: bold;">$cwd</span>/job_execute.php <span style="color: #006699; font-weight: bold;">$jid</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$desc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$proc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">proc_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cmd</span><span style="color: #339933;">,</span> <span style="color: #000088;">$desc</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pipes</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">proc_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$proc</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$pjid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$jid</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Tell the world that we aren't executing any more */</span>
<span style="color: #000088;">$prefs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Prefs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'jobs'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$prefs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">worker_pid</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first thing that happens is that <em>worker.php</em> forks itself and lets the parent return directly to the caller, which in this case is <em>startWorker</em>. This allows <em>startWorker</em> and thus <em>enqueue</em> to finish and the calling PHP script can resume with what ever it was doing (creating a web page etc).</p>
<p>Also note that <em>worker.php</em> doesn&#8217;t execute the job functions directly, instead it hands the jid number to a second script called <em>job_execute.php</em>. There is a good reason for this, since we must include PHP files (with <em>require_once</em>) to be able to execute the job function the namespace of the worker would be contaminated quite fast and with that comes the risk of name collisions. By letting each job execute in a totally clean environment they can include only the files needed for their execution and thus avoid any name collisions.
</p>
<p>
<em>job_execute.php</em> takes a job id (<em>jid</em>) as argument, dequeues the job, includes all required files, calls the job function and then terminates.
</p>
<p>File: <strong>job_execute.php</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mysql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$argv</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Don't call me from a browser&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Job missing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$jid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$jobs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> jobs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$job</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$jobs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dequeue</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$jid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Job dequeue failed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Include required files
 */</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'include'</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$inc</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$inc</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Execute the job handler */</span>
<span style="color: #000088;">$cb</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'callback'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$cb</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'args'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Okay, that should be all. Are you still with me? <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Using it</h3>
<p>
After all this&#8230;how do one use this then? First of all we need one or more job functions that we would like to be background executed. The prototype for such a function looks like this</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> myBgFunc<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #339933;">...</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Where <em>args</em> can be anything you like (as long as PHP allows it). Put the function inside a file and include (preferably with <em>require_once</em>) any other files that you might need. For example like this, not the best example, but anyway.</p>
<p>File: <strong>myfunc.php</strong></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>
<span style="color: #666666; font-style: italic;">/* $args is an integer in this case */</span>
<span style="color: #000000; font-weight: bold;">function</span> test1<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$args</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #000088;">$j</span> <span style="color: #339933;">*=</span> <span style="color:#800080;">1.00001</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">/* Report result somewhere */</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Now, from your run-of-the-mill PHP script, create a <em>jobs</em> object and enqueue the function <em>test1</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'db_mysql.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.inc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MySQLConnector<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'localhost'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'pwd'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$jobs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> jobs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">/* Remember, &quot;function&quot;, &quot;argument&quot;, &quot;files needed&quot; */</span>
<span style="color: #000088;">$jobs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enqueue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;test1&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">1000</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'myfunc.php'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Job enqueued&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Even if <em>test1</em> takes ages to execute, the enqeue function will execute in a fraction of a second and report back directly to the web browser. You can enqueue any number of functions, they will be executed on a first-come first-serve basis.</p>
<h3>Improvements</h3>
<p>I&#8217;ve tested this a bit and it seems to work, however I haven&#8217;t put it through some real situation test yet. With some additional locking it should be possible to run multiple instances of <em>worker.php</em> to take advantage of SMP systems.</p>
<p>
There is no built-in mechanism to know when a job has finished. The job function will need to report its results to a SQL database for example. If browser feedback is needed an AJAX solution could poll the database for the execution status.</p>
<h3>Files</h3>
<p>
Files with complete source code
</p>
<ul>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/jobs.phps'>jobs.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/worker.phps'>worker.php</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/job_execute.phps'>job_execute.php</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/prefs.phps'>prefs.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/db_iface.phps'>db_iface.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/db_mysql.phps'>db_mysql.inc</a></li>
<li><a href='http://www.shapeshifter.se/wp-content/uploads/2008/08/static.phps'>static.inc</a></li>
</ul>
<p>If you found this useful consider putting a link back to this article from your own blog/website, thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2008/08/04/asynchronous-background-execution-with-php/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

