javier arturo rodríguez

Archive for the 'General' Category

WordPress 2.0.3 inside

Wednesday, July 26th, 2006

WordPressLast Sunday I upgraded WordPress to 2.0.3, and I have to confess that I am very impressed. After a couple of disastrous dry runs in a spare server, I backed up everything and decided to go for it on the production system — half expecting it to crash somehow. However the upgrade went smoothly, and almost every plugin just kept working exactly as before, with the sole exception of WPG2. Since the website recommends to upgrade to Gallery2 2.1.x and to the new WPG2 2.0 plugin, I did just that and got the embedded gallery working again in no time.
Kudos to both WordPress and Gallery2 teams. You have created nice pieces of software, and are setting a high standard for commercial and Open Source blogging and photo gallery software.

Kudos, and thanks.

Add swap space to Linux

Wednesday, July 19th, 2006

This is an old sysadmin trick, but a good one all the same.
Suppose that you finished installing a brand-new Debian GNU/Linux server, and for whatever reason you forgot to set aside some space for a swap partition. Or you correctly got some swap space at installation time but now you desperately need some more. Well, despair not. It’s a little known fact that you can have swap space in a file on top of the filesystem instead of using a dedicated block device.
This simple recipe will give you 2Gb of swap space. Here we go:

# mkdir /var/swap
# chown root.root /var/swap
# chmod 700 /var/swap
# dd if=/dev/zero of=/var/swap/01.swp bs=1024 count=2M
# chown root.root /var/swap/01.swp
# chmod 600 /var/swap
# mkswap /var/swap/01.swp

Now add this newly created swap space to your /etc/fstab:

/var/swap/01.swp none swap sw 0 0

Teoretically, you won’t get the same performance as using a dedicated block device, and if the file actually gets fragmented it might drop rigt to the floor, so if you try this at all do it as soon as possible after installation. So if what you’re trying to do is to *increase* your available swap space instead, you may add a priority option to give preference to the block-device swap space:

/dev/hda1 none swap sw,pri=1 0 0
/var/swap/01.swp none swap sw,pri=2 0 0

And just this time activate the swapspace with addswap (The initscripts will do it on every boot thereafter):

# swapon -av

That’s all there is to it. I particularily like how newer BOFH generations look at this with some skepticism at first, and with endless amazement later.

reiserfs and dd_rescue for data recovery

Sunday, July 16th, 2006

Last thursday the hard disk drive on a development machine died big time. First it started to behave erratically and dmesg showed that it has having trouble with some bad blocks. It did not survive a reboot: ReiserFS woud not mount it on boot, and reiserfsck running from an Accelerated Knoppix CD refused to bring it back to life. At first glance, the disk was beyond repair.
Of course, upon closer inspection, it turned out that the warranty expired exactly two months ago. Normally -after swearing my heart off- I would just replace the disk and make myself a nice paperweight or some other modern art piece -I’ve been looking forward to make one of those nice HDD clocks- but in the guts of that particular HDD were some uncomitted changes that I just wasn’t on the mood of rewriting. Besides, even though most of the data was expendable, the configuration hadn’t been backed up in quite a while (Yes, there is a pattern here).
So here’s the recipe I usually apply in these situations using Kurt Garloff’s dd_rescue. First get a brand-new HDD of approximately the same capacity and place both disks in a working Linux box (Depending on your necessities, booting from Knoppix might do). Let’s call the old, dying HDD /dev/hdg, and the spankin’ new disk will be /dev/hde. For the sake of simplicity, let’s assume that /dev/hdg was partitioned in /dev/hdg1 for swap and /dev/hdg2 for data.
First we’ll copy the entire data partition from /dev/hdg2 to /dev/hde2:

# dd_rescue /dev/hdg2 /dev/hde2

This will take a long, long time. dd_rescue starts with a reasonable block size, but whenever it encounters and error it retries a few times with a smaller block size before skipping the defective blocks and moving along. This is useful because it will copy all data in every readable block, instead of giving up at the first error like dd does. In my case, this took more than a day for a 248GB partition.
Once the data is in a new disk you can try to mount it directly, although it is a good idea to run reiserfsck first to make sure that the files you’ll copy are usable.

# reiserfsck /dev/hde2

Now here you might run into a small obstacle. Ideally I would buy the exact same model as the old drive for recovery purposes, because that guarantees that an exact bit-for-bit copy will work in most cases, partition maps and all. However in this case I bought a different brand, which resulted in a slightly smaller drive and a completely different geometry. When this happens, reiserfsck will complain about the different partition size, and suggests that you rebuild the superblock:

# reiserfsck –rebuild-sb /dev/hde2

Now you can do a normal reiserfsck.
When you’re done just mount the new partition and copy your data to a safe place:

# mount /dev/hde2 /mnt/tmp
# rsync -a –progress /mnt/tmp/etc /backup/dir/
# rsync -a –progress /mnt/tmp/home/arturo /another/backup/dir/

After this you can reformat the new drive for normal usage. Mine is being debbootstrapped as I write this.
This little recipe has saved quite some data and a few disks, including most of mcleod’s late Xbox hard disk. As usual your mileage may vary, but with a litle luck you just might get some of your files back.
Now about that crappy Maxtor HDD… I might just go for the wind chimes instead.

Amplifying ignorance through technological empowerment

Thursday, July 6th, 2006

There are numerous reports around the Internet about a supposed fraud. People that has never heard about the Drunkard’s Walk is firing up Excel or SPSS to plot variables and doing correlations, and while some of them actually ask for interpretation from someone else (an expert, preferrably), all of them are quick to state that the election is rigged, even when they lack either the knowledge or the experience to realize that they are wrong. Most arguments are critically flawed, the methodology is just wrong or anything resembling actual math is completely absent.
Some people are amazed when they apply a curve-fitting algorithm to some data and then -OMG!- it actually fits (What the fuck where they expecting?). Some other people find linear correlations in time series that represent percentages. A lot of people -a whole lot- are amazed that the lines in the PREP never crossed and believe that it is impossible. A couple of so-called experts were on the radio today discussing “mathematical irregularities” without providing real -scientific- arguments. AMLO himself has spoken about “mathematical impossibilities”. His cynicism -and the irony of the phrase- is mindboggling.
I have seen this same problem before in another context, and you might be familiar with it too: Someone learns to program using Visual Basic by drawing buttons and filling up code. He’s a programmer, right? Now he fires up VB.NET, learns to draw “web forms” and fills out some more code. Now he’s also a web programmer!
The same thing happens in other circles. For instance, we all know that anyone that can fill up a form in Blogger or LiveJournal is a journalist. Now we can prove that this very same phenomena -technological empowerment amplifying ignorance instead of supressing it- seems to work out with statistical programs -even with spreadsheets .
Hypothesis: If you give them SPSS, everyone is a statistician.

Mexican elections 20060704 @ 1600hrs

Thursday, July 6th, 2006

The PREP does not determine the actual winner, but a preliminary result within a certain error magin. The “Preliminar” part in “Preliminar Electoral Results Program” is conveniently ignored by many. Since the election numbers are too close to call, and given the error margin (that may account for human error, among other things), the IFE decided to go for a full vote before pronouncing a winner.
The data that the PREP reports is NOT random. The time series does not reflect the measurement of a social variable (e.g. number of births) but a sucessive approximation to a final state (the number of votes for each candidate).
There may be validations in place to detect typing errors (e.g. 129 instead of 124, 272 instead of 212) using the sums in the voting documents but the IFE may not be willing to discard the results of internally inconsistent voting documents (e.g. a bad sum).
The rules are clear, signed by every political party and written somewhere, but the great majority of the people does not know what they are.
As usual, the problem is either education, simple ignorance or disinformation.

Mexican elections 20060703 @ 01:00hrs

Sunday, July 2nd, 2006

Yesterday at 11pm IFE asked for prudence and -mostly- for silence. Once again, *both* PAN and PRD ignored the authority and jumped the gun to declare themselves the winner. The PAN cited hard -if somewhat uncertain- numbers. The PRD called to defend the vote, and that they will respect the results if the are real and the process was clean, which to me sounds like a poorly veiled threat. PRI -irrelevant as it may seem- is still in sweet denial and define themselves as “Mexico’s most important force for stability”, setting the table to negotiate with whomever comes out on top.
Myself, I will go to bed without the certainity of either a bright or a bleak future for me, my family, my business and my country, even if these elections demonstrate beyond doubt that those discrete black-or-white realities don’t apply to Mexico anymore. Uncertainity is definitely a lot worse.
I guess Paco Calderón says it best.
Now I just hope the rest of the world behaves with more responsibility than the candidates and that the market doesn’t punish us too much.
Please?

Mexican elections 2006 @ 21:00hrs

Sunday, July 2nd, 2006

So far, both the PAN and the PRD claim to have won by a wide margin, while the PRI has happily dismissed all exit polls and hinted to victory for themselves in a long, boring speech.
Meanwhile, the whole country is on the edge of their seats.

Mexican elections 2006 @ 20:00hrs

Sunday, July 2nd, 2006

The exit polls of at least three different bureaus point to a tie between Felipe Calderón and López Obrador. In fact, the difference in the poll is inferior to the error margin of every poll.
This just can’t be good.

md5pass

Sunday, July 2nd, 2006

This snippet is a simple wrapper around Digest::MD5’s md5_base64() builds unsalted MD5 digests encoded in base64, very useful for LDAP management and LDIF file processing.

#!/usr/bin/perl
++$|;

use Digest::MD5 qw(md5_base64);

if(!defined($pass=shift)) {
        print “> “;
        $pass=<STDIN>;
        chomp $pass;
}
print encrypted($pass).\n;

sub encrypted {
        my($passwd) = @_;
        return ‘{md5}’.md5_base64($passwd).‘==’;
}

(Source code)

Use it as such:

$ bin/md5pass
> password
{md5}X03MO1qnZdYdgyfeuILPmQ==

Sunday Bloody Sunday

Saturday, July 1st, 2006

Bush's Sunday Bloody Sunday coverTake a look at this unusual cover of U2’s Sunday Bloody Sunday by none other than George W. Bush himself, skillfully put together by The party party.
Even though the subtext is not exactly amusing -no, the irony of putting precisely this song in the mouth of Bush is not lost on me- the remix is great and it does make a point about using media mashups for political commentary. Mexican politics would be an endless source for this kind of creative and meaningful videos. Is anyone up for it?
YouTube video.
Via O’Reilly Radar / PinkDome.

Some lovely ASCII Art

Wednesday, June 28th, 2006

Andrew Savige’s Bottles of Beer have been found by the Python pundits (and by some gutless Perl defectors ;-) ) and are being waved as a textbook executable-line-noise example. There’s people that can’t stand beauty when they see it.
Bottles of Beer
(That code is now an image -see below- but you can always get the original source code).
Yup, it is a Perl program. Yes, it *does* run, with interesting results. There’s even a CPAN module — Acme::EyeDrops — that turns your own Perl programs into purposely unmaintainable yet beautiful works of art that can make the entire Python Party cringe in disgust. You have to admit that there’s certain merit in making grown men cry. Automatically, no less. Go and read how it’s done.
So the Obfuscated Python Contest is incredibly boring. I couldn’t care less.
Via Carlos de la Guardia/Marc Abramowitz/Chris Petrilli.
Update 20060916: Replaced the code with a graphical version because WordPress 2.0 doesn’t play well with the text hightlight plugin.

Griffin radio SHARK + icecast2 on Debian GNU/Linux

Saturday, June 10th, 2006

Griffin radioSHARK I have been meaning to get a Griffin radioSHARK with the intention of getting it running on Linux. Since it has a nice discount over at amazon I ran out of excuses for not buying one, so I finally ordered it.
Once the sweet sweet parcel arrived the radio SHARK sat for a couple of weeks gathering dust while I got a moment to play with it. Trying to get it to run in Windows XP was totally fruitless. The only way I got it to spit any sound at all was while in audio “test” mode. Not really an option, but at least it meant that that the hardware was working fine.
So now it was time to move it over to Linux. The definitive guide for the radioSHARK under linux is at LinuxQuestions.org. They recommend ecasound to transcode the audio input to the sound card in a single computer, but I rather use icecast2 to stream the signal to different computers around the house — even to the office or while I’m on the road. I don’t care much for the time-shifting feature of the Windows/Mac client, and the record function can be replicated with VLC save to disk function or using command-line tools.
The program that controls the radioSHARK lights and change the current station is shark.c, but if you get it from LinuxQuestions.org you’ll have to copy+paste and clean it up a bit, so you might want to use this ready-to-go shark.c instead.
This is the list of packages for Debian GNU/Linux:

linux-image-2.6.15-1-k7 2.6.15-4
linux-source-2.6.15 2.6.15-4
libhid-dev 20060325-2
libhid0 20060325-2
icecast2 2.3.1-3
darkice 0.17-1

So how do you get a full-functioning, live-streaming, all-singing radioSHARK working under Debian?

  1. Plug the radioSHARK in the USB port you’ll get this in dmesg:
    usb 1-2: new full speed USB device using uhci_hcd and address 3
    usbcore: registered new driver hiddev
    input: Griffin Technology, Inc. RadioSHARK as /class/input/input2
    input: USB HID v1.00 Device [Griffin Technology, Inc. RadioSHARK] on usb-0000:00:10.0-2
    usbcore: registered new driver usbhid
    drivers/usb/input/hid-core.c: v2.6:USB HID core driver
  2. Compile shark.c using
    gcc -g -o shark -lhid shark.c

  3. Copy shark to /usr/local/bin
    # cp shark /usr/local/bin

  4. Check that your brand-new shark is working:
    # /usr/local/bin/shark -blue 60

  5. Edit /etc/icecast2/icecast.xml and fill out at least the authentication and hostname sections.
  6. Copy /usr/share/doc/darkice/examples/darkice.cfg to /etc/darkice.cfg and edit to taste. My own configuration goes something like this:
    [general]
    duration = 0
    bufferSecs = 5
    reconnect = yes

    [input]
    device = /dev/dsp
    sampleRate = 22050
    bitsPerSample = 16
    channel = 2

    [icecast2-0]
    bitrateMode = vbr
    format = vorbis
    bitrate = 32
    quality = 0.8
    server = localhost
    port = 8000
    password = icecastPassword
    mountPoint = radio.ogg
    name = Radio MexicoDF
    description = Radio from Mexico, D.F.
    url = http://your.url
    genre = misc
    public = yes

  7. Start up icecast2 running /etc/init.d/icecast2 start and check out that it’s running by opening http://localhost:8000/ . You should get a status screen without any streams.
  8. Start up darkice with /usr/bin/darkice -c /etc/darkice.cfg . When you reload http://localhost:8000/ in your web browser you should get a stream mount point with your newly defined stream. Tune in to the stream URL using XMMS, VLC, WinAmp or your favorite audio player, and you sould hear something, at least some white noise.
  9. To change stations use
    # /usr/local/bin/shark -fm 102.5
    After a few seconds -depending on your audio player buffer size- you should hear the new station.

My next weekend project will be to create a web front-end to shark — perhaps even implement a record-to-disk option.

Miserably Sad

Wednesday, March 29th, 2006

Today the world is a worse place that it was a few hours ago. I got word –and just confirmed– that my mentor, my teacher and overall good man Rosendo Pardo Osuna was run over by some bastard in a car.
They took you away from the Campus you built, but nobody was able to take you away from the place you loved so much. You will always live in the heart of all the people you touched — if anything, we can attest to your loving, caring work.
But I miss you already, Inge.

The Sad iPod Syndrome

Friday, March 24th, 2006

The \"Sad iPod\" iconA couple of months ago my (formerly) trusty iPod anounced its impending death and I didn’t listen. Sure, it hung up a couple of times, but it had done that before. When I tried to connect it to a PC to feed it the latest podcasts the PC hung up, but Windows machines do that, too. A lot. Later I copied an ISO image to the laptop under Linux, and it took an unusually long time, but I was tired and didn’t even think of taking a look to dmesg. When I whipped out the iPod to listen to some music during an 11-hour flight only to find out that the battery was dead –even tough I had charged it overnight– I didn’t gave much importance to the issue. I just forgot to toggle the hold switch, I rationalized. So when it definitely locked up with a whirring noise and the clicks that usually announce the death of a hard disk, it came to me as a surprise. I felt a cold sweat down my back as an exclamation point appeared on the screen, inviting me to visit the Apple support website.
*Then* I remembered that I don’t have a backup of my iPod.
Of course, my iPod has a copy of my entire music collection. Heck, the iPod *is* my entire music collection, since it has every track of every CD I have ever bought, including many that have been lost or stolen. On top of that, it has more that 5GB of podcasts, a few ISOs, an essential software collection and an encrypted volume with a backup of critical information. The data files didn’t worry me as much as the music, because most of them were just backup files, but recreating that volume was going to be bothersome at best.
Now about the music… I have spent countless hours tagging, classifying and pasting artwork and lyrics to my music. That really hurt.
The iPod got worse really fast. After following the instructions on the Apple website a couple of times to get it into disk mode just to be ignored by the PC in turn, the folder icon was replaced by the dreaded Sad iPod icon. That’s it for the iPod, i tought. I should have bought that 60GB iPod with the color screen when I had the opportunity, instead of waiting for an 80GB model that never materialized.
When I followed the instructions on Apple.com I saw that Apple is more than willing to replace my out-of-warranty 4G iPod –engraving and all– after I dutifully paid US$250. Or I could shell out a few more bucks for a newer model, and forego all the accessories I have bought over the last three years, which have cost a small fortune and none of which will work with a video iPod. Smart move, Steve.
So let’s move on to the other option: perhaps I can replace just the hard drive. *Mmmh…* They go for some USD$100 for a 20GB one, and about USD$130 for the 40GB I need. That’s about half the tribute to Apple for a replacement. So I started looking for other people’s experiences replacing a broken iPod HD, and came across a post detailing William Mitchell’s own encounter with the Sad iPod icon, a reference to Josh Highland’s experience replacing an iPod HD and a cryptic reference to “dropping the iPod” near the end. Josh’s instructions are pretty straightforward, but when I read the comments to his post I found out that apparently many people have had success reviving their iPod by smacking it. Now in my experience one thing is dropping and Apple ][ a few inches to settle the RAM ICs into their sockets, but smacking an iPod to “realign” the HD head is something entirely different. I’m a trained Electronics Engineer. I am a member of the ACM. I *know* that this is not the way things work. But since the HD was dead anyway I decieded to give it a try.
I read the instructions again. No, there was no mention of any blood sacrifice or any other form of dark magic that could compromise my soul any further. I toggled the hold switch exactly ten times. I took the iPod with my left hand, and slapped the right side firmly. I turned the iPod on, and lo and behold: the whirring noise was gone, the clicks wheren’t there, and the iPod worked. My belief system was shaken to its core.
Now I can attest to the miracle.
I connected the iPod to a PC immediately and it was recognized. I spent a couple of hours looking for a program that could backup a selection of the songs in the iPod — podUtil is nice but won’t work in advanced mode unless you register, and in basic mode a nag screen pops up every 50 songs or so. ephPod is still broken, and YamiPod is great but Smart Playlists don’t work. Everyone else want to set you back at least US$19 for the privilege of backing up /your/ music from /your/ iPod to /your/ computer — a feature that iTunes should have in the first place. What the heck. I just plugged it into a Linux box and rsync’ed the entire partition –including the entire iPod_Control– to the storage server. It complained with I/O errors in a couple of files, which were promptly dd’ed with zeroes just in case the HD controller is able to reallocate those bad sectors. I entered the diagnostics mode and ran a HDD scan which the iPod passed with flying colors. And it is still working and merrily pumping out music as I write this.
The lessons I learned: Smacking stuff to make it work applies to high-tech gear as well, unbelievable as it may seem. Apple needs to provide an easy, intutive way to back up your music or move it between your iPods without resorting to third-party utilities. Throwing out backwards compatibility for consumer electronics is a smart financial move for Apple and its licensees, but it doesn’t make any sense for the consumers themselves. And finally the iPod is no walkman — you still have to back it up periodically. I should have known better.
So it looks that the iPod is fully functional again. I just *know* that the HD will fail again –probably for good this time– so I ordered a replacement HD anyway. But now I have my music and my tags securely backed up, so I won’t care as much when the iPod breaks again during the next worktour.
Update: In an amazing display of synchronicity, I just read Fate’s latest post on this same topic. I swear I had not seen it before, nor discussed this specific remedy with him (Actually, I still owe him a cup of coffee)… Perhaps there are no coincidences after all?

gammu

Thursday, March 16th, 2006

Gammu -the GNU All Mobile Management Utilities formerly known as MyGnokki2- is a full-featured cellphone manager for *nix and Win32. Its makefile knows about .debs and .rpms, it is incredibly easy to configure and -unlike Gnokii- it supports the Nokia 3200 (RH-31) right out of the box through an inexpensive DKU-5 cable.
Right now I’m using this simple /etc/gammurc under Debian GNU/Linux with kernel 2.6.12:

[gammu]
port = /dev/ttyUSB0
model = 3200a
connection = dku5fbus
synchronizetime = yes
#logfile = gammulog
#logformat = textall
use_locking = yes
gammuloc = locfile
startinfo = yes
gammucoding = utf8
rsslevel = teststable
usephonedb = yes

# gammu --identify duly reports

Manufacturer : Nokia
Model : 3200a (RH-31)
Firmware : 5.29 I (22-10-04)
Hardware : 1620
IMEI : 356656xxxxxxxxx
Original IMEI : 356656/xx/xxxxxx/x
Manufactured : 06/2005
Product code : xxxxxxx
Simlock data : xxxxxx
Old simlock : TELCEL GSM (xxx xx)
UEM : xxxx

Métro

Sunday, February 26th, 2006

Metro(*ack!* Wordpress ate my post!)

Demo for Luhn algorithm in PHP

Friday, February 24th, 2006

If you have a number that adheres to the Luhn algorithm for validation, you may check it easily with this short PHP snippet.

<?php
function luhn($str) {
        $odd = !strlen($str)%2;
        $sum = 0;
        for($i=0;$i<strlen($str);++$i) {
            $n=0+$str[$i];
            $odd=!$odd;
            if($odd) {
                $sum+=$n;
            } else {
                $x=2*$n;
                $sum+=$x>9?$x-9:$x;
            }
        }
        return(($sum%10)==0);
}
$num = $_GET[‘number’];
?>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
<html>
<head>
<title>Online Luhn algorithm test</title>
<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1″>
</head>
<body>
<?php if($num) { ?>
<?php   if(luhn($num)) { ?>
<div style=“background:#ddffdd;border:1px solid #004400;”>
<?=htmlspecialchars($num)?> is valid
</div>
<?php   } else { ?>
<div style=“background:#ffdddd;border:1px solid #880000;”>
<?=htmlspecialchars($num)?> is NOT valid
</div>
<?php   } ?>
<?php } ?>
<form action=“luhn.php” method=“GET”>
<div>
Number: <input type=“text” name=“number” value=“<?=urlencode($num)?>” size=“40″/>
<input type=“button” name=“btSend” value=“Check”/>
</div>
</form>
</body>

(Download)
You may test this script at http://javier.rodriguez.org.mx/code/luhn-test.php.
Please consider that this is a demo, so please do not use this to check credit card numbers unless you send me an expiry date. CCV2 has taken over as the preferred method for credit card number validation anyway.

The best blonde joke ever

Thursday, February 16th, 2006

It might be based on a silly stereotype, but this is the best blonde joke ever.

Find out LDAP client IPs

Monday, January 23rd, 2006

ips.pl is a simple perl filter that processes SunONE Directory Server 5.2 access logs to find out the IP addresses that queries are coming from. It’s very useful to evaluate the impact for migrating LDAP infrastructures. Most comments and variable names are in spanish but the code should be clear enough to any SODS sysadmin. Or drop me a line if you absolutely need an all-english version.

#!/usr/bin/perl
# ips.pl $Revision: 1.1 $
# Analiza archivos access de Sun ONE Directory Server 5.2 para generar
# reporte de IPs de clientes y servidores
# Copyright (C) 2005 Javier Arturo Rodriguez
use strict;
my($acceso);
my $filename = shift @ARGV;
die(“Usage:\t$0 <filename>\n\tbunzip2 -c <filename.bz2> | $0 -\n) unless $file
name;
open(FILE,“<$filename”);
while(<FILE>) {
        chomp;
        if($_=~m,^\[(.*?)\].*?connection from ([\d\.]+) to ([\d\.]+),) {
                $acceso->{$3}->{$2}->{TS}=$1;
                ++$acceso->{$3}->{$2}->{CNT};
        }
}
close(FILE);
foreach my $dst (sort keys %{$acceso||{}}) {
        print “Acceden a traves de $dst\n;
        foreach my $src (
                reverse sort { $acceso->{$dst}->{$a}->{CNT} <=> $acceso->{$dst}
->{$b}->{CNT} }
                keys %{$acceso->{$dst}||{}}
        ) {
                printf(“  %-15s (last seen on %s; %d hit%s)\n,
                        $src,
                        $acceso->{$dst}->{$src}->{TS},
                        $acceso->{$dst}->{$src}->{CNT},
                        $acceso->{$dst}->{$src}->{CNT}==1?:’s’,
                );
        }
}

(Download)

Anansi Stories

Monday, January 23rd, 2006

Motivated by Neil Gaiman’s Anansi Boys, I’ve started reading the Jamaica Anansi Stories by Martha Warren Bechwith. Go give’em a whirl!

23 queries. 0.281s  $Revision: 1.6 $
Use Any Browser! Valid XHTML 1.0   Powered by WordPress Powered by Apache Web Server Hacker Emblem