subversion vs git
The following gem from the Subversion manual somehow manages to explain in only one sentence why svn sucks.
A Subversion filesystem has its data spread throughout files in the repository, in a fashion generally understood by (and of interest to) only the Subversion developers themselves.
With git one can learn and understand the underlying object storage. While “svn” devs just tell you “gaaaaaa! you dont need to know that, go away!”
Sshuttle: Poor man’s VPN with python and ssh
Sshuttle by apenwarr. It really works, I’m amazed :)
./sshuttle -r username@sshserver 192.168.0.0/16 -vv
That’s it! Now your local machine can access the remote network as if you were right there! And if your “client” machine is a router, everyone on your local network can make connections to your remote network.
Getting RT3370 USB Wifi adapter to work in Linux

They look like this one on the picture, nice and small. Available form Ebay. USB id is 0x148F,0×3370. It is not really supported by any of the drivers included with the latest kernel (2.6.34) and the official Ralink drivers available from their site do not support it either. This specific device id is not even in the source, and I did not manage to get it fully working after adding the id either.
Thankfully there are Windows drivers for this chipset and there is also ndiswrapper which allows Windows network drivers to be used in other operating systems, like Linux.
Sadly the windows drivers are distributed as one single Installshield .exe installer. I have no Windows machines in my home and none of the tools I had available (cabextract, etc) could not deal with this file. Finally managed to get the drivers (2780.sys and 2780.inf for WinXP) out of the installer with a help of a friend, who had a Windows machine.
First attempt to load this driver with ndiswrapper ended with the following error message in syslog:
ndiswrapper (import:242): unknown symbol: ntoskrnl.exe:'MmGetSystemRoutineAddress'
Then, I thankfully found this piece of information from Dirk Schwendemann, which I will reproduce here:
the ralink driver 1.4.0.0 (09/25/2008) for a rt2870 usb stick complains about a missing symbol MmGetSystemRoutineAddress.
I’ve just added an empty stub:
wstdcall void* WIN_FUNC(MmGetSystemRoutineAddress,1)
(struct unicode_string *name)
{
struct ansi_string ansi;
if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) {
WARNING("MmGetSystemRoutineAddress: %s", ansi.buf);
RtlFreeAnsiString(&ansi);
}return 0;
}
So I got the latest ndiswrapper (1.56), doublechecked the source, did not find this stub, added it to ntoskrnl.c somewhere after the other Mm* stubs, recompiled ndiswrapper, installed it and lo and behold .. my USB stick is now working.
Thanks Dirk ;)
ssh-copy-id replacement
OsX does not have ssh-copy-id. The following is a nice replacement for that:
cat ~/.ssh/id_dsa.pub | ssh user@otherserver "cat - >> ~/.ssh/authorized_keys"
More PHP type juggling, #2
I found the following gem over at Stackoverflow.com today. Given the following code, what do you think the result is?
<?php
var_dump("01a4" == "001a4");
var_dump("01e4" == "001e4");
The correct answer is:
bool(false)
bool(true)
Why?
PHP doesn’t like strings. It’s looking for any excuse it can find to treat your values as numbers. Change the hexadecimal characters in those strings slightly and suddenly PHP decides that these aren’t strings any more, they are numbers in scientific notation (PHP doesn’t care that you used quotes) and they are equivalent because leading zeros are ignored for numbers. To reinforce this point you will find that PHP also evaluates “01e4″ == “10000″ as true because these are numbers with equivalent values.
Building PEAR packages
Lets suppose you are learning to build PEAR packages (Pirum is a very nice PEAR channel server btw). You managed to create and publish the initial version of the package and it even installed just fine after you ‘pear install’-ed it.
Then you fixed a bug in the source, increased the version number in package.xml, built and published the next version. The new version is listed at the Pirum generated page.
- But ‘pear upgrade channel/Package’ does not ugprade to newest version.
- Forcing upgrade with -f does not help either.
- Uninstalling and reinstalling the package still gets the previous version.
- channel-update does not help.
- After uninstalling the package, removing the source from Pirum, regenerating the index and trying to reinstall you get a nice error stating that this version does not exist at the server.
I was really puzzled by all that. Then I discovered the reason – by looking at pear configuration.
$ pear config-get cache_ttl
3600
Channel contents are cached for that many seconds (3600 = 1 hour). The solution is to either reduce this number, or – preferrably – nuke the cache by
$ pear cache-clear
After this your package will upgrade just fine ;)
Its very logical to cache this information of course to avoid killing package servers and I feel really stupid for not figuring it out earlier.
About thinking ..
Most people prefer not to think. Thinking is hard, and they would get it wrong anyway. Instead, they cheat – they pick someone famous who agrees with their preconceptions and say “look, this guy says X, he’s more famous than you, so there”. That, for them, is enough.
Soap, lather, rinse, repeat
I have had to deal with Soap lately. Mostly it works, except when it doesn’t. In my case I found out that its not exactly straightforward to make a Nusoap client talk to a PHP5 Soap server. Of course, it also depends on the WSDL. Probably. Maybe. In any case I was in a world of pain, which I do really not want to describe in more detail.
But then I found this article, and it made my day :) S stands for Simple. I have been suspecting this, but now its proven. Sigh.
Let me sum up. The definition of SOAP is in constant flux, SOAP is anything but simple, and it is no longer meant for accessing objects-even though that’s what all the tools still do.
Python API for TargetApi.com
Have you ever used DailyPerfect? Try it, its quite nice. Now the guys who built it have released their API for public use, it is called Target Api and is available at www.targetapi.com, there you can read about it and sign up for API key.
Once you have the API key, one the options to actually play with it is through Python, using a little library I wrote and made available at GitHub.
http://github.com/antiveeranna/py-targetapi
Go, read the source, checkout, fork, improve, play, contribute your improvements, whatever rocks your boat :)
Getting started with Unit testing your PHP Code
Giorgio Sironi compiled a really nice e-book explaining practical PHP testing with PHPUnit. You can download the book from his site.