Fri, 25 Nov 2005

10 Free Burritos From Chipotle

I eat at Chipotle probably twice a week. A couple days ago, I dropped my business card in the fishbowl next to the register. Today, I got a call from Shabby at Chipotle, telling me that I had won 10 free burritos. Unfortunately, it's 10 free burritos to be ordered for a single lunch, to feed an office of people.

I work from home. I don't think I even know 10 people who live in Northridge. Anybody want to join me for lunch next week?

business | Permanent Link

Sun, 20 Nov 2005

Using udev and autofs Under Debian with an iPod and Camera

Last week, I set up udev on my desktop machine. udev is the Linux 2.6 way of dynamically managing the /dev directory. It populates /dev only with devices that actually exist, and adds and removes entries as devices are plugged in or removed from the system. In addition, it allows the entries in /dev to be named consistently.

Consistent naming of /dev entries solves a big problem with using USB devices under Linux. Many USB devices use the usb-storage module, appearing as SCSI devices. The problem is that the name the kernel gives to the devices depends on the order in which they are plugged into the system.

For example, I might plug my iPod Shuffle into my computer, and the kernel would name it /dev/sdd. Then I plug in my camera, and the kernel would call it sde. But if I had plugged them in in the opposite order, their names would have been reversed. This makes it difficult to mount them without first checking dmesg to find out what the device has been named.

udev solves this problem by allowing me to tell it what to name a device when it is detected. udev uses information from sysfs to determine which device is plugged in. I have configured udev to name a device whose vendor attribute is "Apple" /dev/ipod and a device whose vendor is "Pentax" /dev/camera. The Debian udev packages put the udev rules in /etc/udev/rules.d. So I created /etc/udev/rules.d/50-custom.rules which contains:
BUS=="scsi", SYSFS{vendor}=="Pentax", NAME{all_partitions}="camera", GROUP="plugdev"
BUS=="scsi", SYSFS{vendor}=="Apple", NAME{all_partitions}="ipod", GROUP="plugdev"

The NAME{all_partitions} part tells udev to create device entries for all of the block device's partitions, so it will create /dev/ipod[1-15] and /dev/camera[1-15], allowing me to mount the FAT partitions on each. See Daniel Drake's guide to writing udev rules for more information on configuring udev.

Now that my iPod and camera are consistently named, I'd like to be able to access them from within gtkpod and digikam, the applications I use to manage the files on them, respectively, without having to manually mount them. While gtkpod has an option to mount the iPod, digikam does not. I have my camera set up in digikam as a generic USB mass storage device, for which you just need to configure a directory to browse.

Following the debian-administration.org tutorial, I set up autofs to automatically mount the usb devices when they are accessed, and unmount them when they're no longer being used. So after installing the autofs package, I added the following line to /etc/auto.master:
/var/autofs/removable /etc/auto.removable --timeout=2

And in /etc/auto.removable, I put:
ipod -fstype=vfat,rw,gid=46,umask=002 :/dev/ipod1
camera -fstype=vfat,rw,gid=46,umask=002 :/dev/camera1


Then I made /media/ipod a symlink to /var/autofs/removable/ipod and /media/camera a symlink to /var/autofs/removable/camera. When I access /media/camera, automount automatically mounts /dev/camera1 as /var/autofs/removable/camera if it has been created by udev. After it hasn't been accessed for two seconds, it will be unmounted (which might take a little while if there are buffers which haven't been flushed out to the drive).

Update (8/12/06): I fixed the rules to use the proper equality test, == rather than =, which newer versions of udev require. Thanks to Andrew Schulman for pointing this out.

tech | Permanent Link

PayFlow Pro PHP Extension on Debian

This is how I built a php4-pfpro package for Debian. Tested with 4.3.10-2.
# apt-get build-dep php4
# apt-get source php4
Follow this part of the instructions from the PHP Documentation

You will require the appropriate SDK for your platform, which may be downloaded from within the manager interface once you have registered. Once you have downloaded the SDK you should copy the files from the lib directory of the distribution. Copy the header file pfpro.h to /usr/local/include and the library file libpfpro.so to /usr/local/lib.

Edit debian/control. Add the following:

Package: php4-pfpro
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${php:Depends}, php4-common (= ${Source-Version})
Description: Verisign's Payflow Pro module for php4
 This package provides a module for Verisign's Payflow Pro for PHP scripts.
 .
 PHP4 is an HTML-embedded scripting language. Much of its syntax is borrowed
 from C, Java and Perl with a couple of unique PHP-specific features thrown
 in. The goal of the language is to allow web developers to write
 dynamically generated pages quickly.

Add the following line to debian/modulelist:
pfpro PayFlowPro
Add the following line to the CFLAGS in the configure-apache-stamp rule in debian/rules:
--with-pfpro=shared,/usr/local \
If you're building apache2 modules, add it to the configure-apache2-stamp rule too, but I haven't tested that. I also had problems building the caudium packages so I removed all of the caudium related stuff from debian/rules.
Here's the full patch.
# ./debian/rules binary

Update 11/06/06: I've updated the Sarge package to 4.3.10-18.
Update 05/05/07: I've updated the Sarge package to 4.3.10-20.

tech | Permanent Link

Thu, 17 Nov 2005

What The Hell Is Wrong With Google Analytics?

Google Analytics, their new hosted web stats application based on Urchin, seems to be completely broken. Every time I log in, I get the following message.

Analytics has been successfully installed and data is being gathered now. Your first reports will be ready within twelve hours.

The problem is that I added the Google javascript to my site three days ago. I want my pretty graphs, damn it.

tech | Permanent Link

Make Pretty Charts with PHP/SWF Charts

PHP/SWF Charts is a PHP script and flash file that can build great looking charts. The flash part does all the work. The PHP script just generates the HTML tags to embed the flash file. It can generate a number of different types of charts including line, column, and pie charts.

We're using it at Postica to generate charts for our customers showing statistics on the number of spam and malware blocked, for example.

tech | Permanent Link

How To Send Mail Safely Using PHP

There are a growing number of spammers exploiting PHP scripts to send spam. Such scripts are often simple "Contact Us" forms which use PHP's mail() function. When using the mail() function, it is important to validate any input coming from the user before passing it to the mail() function.

For example, consider the following simple script.

<?php
$to        = 'info@example.com';
$subject   = 'Contact Us Submission';
$sender    = $_POST['sender'];
$message   = $_POST['message'];

$mailMessage = "The following message was received from $sender.\n\n$message";  
mail($to, $subject, $mailMessage, "From: $sender");

?>

Such a script looks fairly innocuous. The problem is that sender variable sent from the client is not sanitized. By manipulating the value sent in the sender variable, a malicous spammer could cause this script to send messages to anyone.

Here's an example of how such an attack might be carried out.

curl -d sender="spammer@example.com%0D%0ABcc: victim@example.com" \
-d message="Get a mortgage!" http://www.example.com/contact.php


Now, in addition to being sent to info@example.com, the message will also be sent to victim@example.com.

The solution to this problem is to either not set extra headers when using mail(), or to sanitize all data being sent in these headers. A simple example would be to strip out all whitespace from the sender's address.

$sender = preg_replace('~\s~', '', $_POST['sender']);

A more sophisticated approach might be to use PEAR's Mail_RFC822::parseAddressList() to validate the address.

tech » mail | Permanent Link

restartd, a Process Monitor-and-Restart Daemon

Restartd is a daemon for checking your running and not
running processes. It reads the /proc directory in every n
secs and does a POSIX regexp on the process names. You can
execute a script/program if the process is not or it is running.

In general, I don't like automated systems that restart processes. If a process dies unexpectedly, there is a problem that needs to be addressed by a human. Automatically restarting processes that randomly die makes it too easy to ignore the underlying problem.

In the case of clamd, the ClamAV daemon, I have acquiesced because I cannot figure out why it dies randomly every month or two, and have installed restartd. The best thing about restartd is it's simplicity. It reads /proc/*/cmdline every n seconds and compares each command with the list of processes defined in it's config file. I have it configured to monitor clamd, spamd, and our in-house Exim log-to-database utility, exidblog, and to call the appropriate init script to restart a process if it's not running.

The current version of restartd in Debian Sarge (and Sid), 0.1.a-3, is a bit buggy in that it will fail to restart services if it is started from an interactive session once the session is closed. Based on suggestions and code by Glen Turner, I've patched restartd to redirect stdin/stdout/stderr to /dev/null, change the working directory to /, and disassociate from the controlling terminal. I've made the patched Debian package available for download.

tech | Permanent Link

Sun, 13 Nov 2005

Coffee Bean Inconsistency

Hey Sunny, I was hanging out at one of your stores today, the one at Devonshire and Reseda in Northridge. You really need to get your franchisees to get their shops in order. While overall, you guys make good coffee, much too often, I get a terrible one. It's quite a crapshoot to get a coffee at one of your stores. There's simply no consistency in the coffees made at The Coffee Bean. While on a good day, your lattes are quite delicious, I'd estimate that about 10% of the time, I get a terrible coffee. Part of problem seems to be under-trained staff. Different baristas in the same store often make coffees differently. The first iced latte that I sent back today was clearly disproportioned, lacking the nice milky tone; it looked like coffee-water. Nonetheless, I drank some of the bitter swill and added some more milk. Alas, it still tasted quite bad. I had the latte remade, and while the second looked right, it still tasted poorly. Hoping that perhaps someone spilled some dish water into the ice maker, I had it replaced with a hot latte. Unfortunately, the hot one was not much better. I did burn my tongue a bit on it which helped keep my taste buds from revolting. I suggest that you visit the shops and make sure that they're cleaning out the espresso machines regularly. Or perhaps they are using low-grade coffee beans in order to widen the narrow profit margins on $3 cups of coffee. Please let me know what your research turns up and when it's safe to return to Coffee Bean stores. Thanks, Christian

business | Permanent Link

Reunion Recap

My high school reunion last night was a bit disappointing. There were a handful of old classmates that I remember, but most of good friends from yesteryear didn't show up.

There were a number of law enforcement officers and teachers in attendance. There were also a surprising number of people still living in Rosamond.

I did get contact info for a bunch of people, so I'll try to get in touch with some of the people who didn't show up. That means you: Lee, Ian, Malia, Elsie, Josh, Chris. (I hope nobody else is insulted by my poor memory.)

misc | Permanent Link

The state is that great fiction by which everyone tries to live at the expense of everyone else. - Frederic Bastiat