28 May 2006

Recovering Grammer Snob

I just read June Casagrande's _Grammer Snobs Are Great Big Meanies_ (Penguin, 2006). It's a guide to avoiding common grammatical errors and to dealing with people who think they know more about the English language than they actually do.

The book is awesome: very helpful, and very, very funny. It's only about $14 retail, and worth every bit. I borrowed it from the library, but I'm going to buy a copy. (The book has a website at http://www.grammarsnobs.com/.)

Here are a few notes (to myself) that I jotted down while reading the book.

'correct' (perhaps not unanimously):
e-mail
website
preventive (not preventative)
'entitled' for rights/privileges, 'titled' for the name of a book

The _Chicago Manual of Style_ (used for books) recommends using the Oxford comma. The _AP Stylebook_ (used for newspapers [and, arguably, blogs]) recommends omitting the Oxford comma. (The Oxford comma is the second comma in the following sentence: This blog is simultaneously pedagogical, pedantic, and pedestrian.)

Newspapers tend to use _Webster's New World College Dictionary_ (too bad for colleges of the old world), and books tend to use the _Merriam-Webster Collegiate Dictionary_.

A screed is a long discourse. And a cool word.

Use 'which' for nonrestrictve clauses, and 'that' for restrictive clauses:
  1. This blog, which has a silly and misleading title, will be useful and/or interesting to a very small number of readers (on a good day).
  2. The _Best of Blondie_ CD that I bought last night is really bitchin'.
'prurient' means interesting (even lurid). 'purient' (to my dismay) does not appear to be a word at all. (I blame dog food manufacturers.)

24 May 2006

Web 2.0 URLs w/ Apache

(Yes, the term 'Web 2.0' is ridiculously overhyped.)

Let's say you have a Web application which takes two optional GET variables v1 and v2. Let's assume that v1 is always an integer and that v2 is always a character string. We'll also assume that a DirectoryIndex index.php directive has been applied:

http://www.example.com/somedir/index.php?v1=27&v2=hello

And let's say your application has an administrative interface in an 'admin' subdirectory:

http://www.example.com/somedir/admin/admin.php

Try putting the following in your Apache configuration (this assumes that mod_rewrite is enabled):

RewriteEngine on
RewriteBase /somedir
RewriteRule ^admin - [L]
RewriteRule ^(\d+)/([a-z]+)/?$ /somedir/index.php?v1=$1&v2=$2 [L]
RewriteRule ^([a-z]+)/(\d+)/?$ /somedir/index.php?v1=$2&v2=$1 [L]
RewriteRule ^(\d+)/?$ /somedir/index.php?v1=$1 [L]
RewriteRule ^([a-z]+)/?$ /somedir/index.php?v2=$1 [L]

(You could put this in an .htaccess file if your Apache configuration applies an AllowOverride FileInfo directive to this part of your content area.)

You application should now be accessible by any of the following URLs:

http://www.example.com/somedir/hello/27/
http://www.example.com/somedir/27/hello/
http://www.example.com/somedir/hello/
http://www.example.com/somedir/27/
http://www.example.com/somedir/

The first and second URLs should set both variables, the third URL should set v2 only, the fourth should set v1 only, and the fifth should set neither (the fifth URL should still run the application because of the DirectoryIndex index.php directive).

Of course, it doesn't have to be '27' and 'hello'--it can be '42' and 'foobar', or whatever.

And your admin interfaces should still be accessible as before (the dash in the 'admin' RewriteRule means 'no alteration').

In the example I've used PHP as the hypothetical Web application, but the language doesn't matter--this is all Apache magic. But if you want to test this with some PHP code, try this in index.php:


header('Content-type: text/plain');
$v1 = '';
$v2 = '';

if ( isset($_GET['v1']) && $_GET['v1'] ) {
$v1 = $_GET['v1'];
printf("v1 is %s\n", $_GET['v1']);
}
else {
printf("v1 not set\n");
}

if ( isset($_GET['v2']) && $_GET['v2'] ) {
$v2 = $_GET['v2'];
printf("v2 is %s\n", $_GET['v2']);
}
else {
printf("v2 not set\n");
}

_X-Men: The Last Stand_

I got to see a preview screening of the new X-Men movie last night. It was awesome. Overall I think I enjoyed the first two films more. I think they tried to do too much and introduce too many characters in this film. But it was still awesome. I even liked Kelsey Grammer as Beast (I didn't think I would).

Make sure you stay until the bitter end. Sit through the credits, and don't leave the theater until the projector turns off.

04 May 2006

Perl programming in joe

I do a lot of Perl programming, and I use joe (Joe's Own Editor). I've defined a few macros that I found pretty useful when scripting. Just add the following macro definitions to your .joerc file (do a text search in .joerc for 'Macros:', and add the lines there-ish):

:def comment filt,"sed -e \'s/^/#/g\'",rtn,tomarkb,markk,prevpos
:def uncomment filt,"sed -e \'s/^#//g\'",rtn,tomarkb,markk,prevpos
:def perltidy bof,markb,eof,markk,filt,"perltidy",rtn,bof,markk

comment ^K 1
uncomment ^K 2
perltidy ^K 3

The first macro comments out a section of text by putting a '#' at the beginning of each line of the section. To use it, just go the the beginning of the section you want to comment out and do 'Ctrl-K b', move to the end of the section and do 'Ctrl-K k', and then do 'Ctrl-1'. It'll comment out those lines, disengage the block (so that the section of text will no longer be highlighted), and return the cursor to the previous position (probably the end of the section of text).

The second macro does just the opposite by uncommenting a section of text.

(You could probably replace the '#' in the macro definitions with a pair of forward slashes for programming in PHP or JavaScript.)

The third macro applies the 'perltidy' program to the entire file (not just a highlighed section). Of course, you'll need perltidy installed for this to work. It's in the Fedora Core extras, and the project home page is http://perltidy.sourceforge.net/.

14 April 2006

the Golden Ratio and the Fibonacci series (Perl program)

I've been re-reading Dan Brown's The Da Vinci Code lately, and I was intrigued by the Golden Ratio and how it relates to the Fibonacci series. The Fibonacci series is such that each term is the sum of the previous two terms:
1, 1, 2, 3, 5, 8, 13, ...

The ratio of consecutive terms in the Fibonacci series converges on the Golden Ratio, which has a value of approximately 1.618. It also shows up in a geometric analysis of the pentacle. These properties are discussed in mathematical detail on the following Web pages:

the Golden Ratio
pentacle geometry

I wanted to see this from a computational point of view, so I wrote a quick Perl program to compute the Fibonacci numbers and ratios out to around 100 terms. The program prints out deviations from the Golden Ratio, and the output shows a near-zero deviation after less than 40 terms.


#!/usr/bin/perl -w

use strict;
use diagnostics;

my $NUM_ITERATIONS = 100;
my $GOLDEN_RATIO = 0.5 * (1.0 + sqrt(5));

my ($previous_term, $current_term) = (1, 1);
my $iteration_number = 1;
while ( $iteration_number <= $NUM_ITERATIONS ) {
my $new_term = $previous_term + $current_term;
my $ratio = $new_term / $current_term;
my $deviation = abs($GOLDEN_RATIO-$ratio) / $GOLDEN_RATIO;
printf "% 3d: %e\n", $iteration_number, $deviation;
$previous_term = $current_term;
$current_term = $new_term;
$iteration_number++;
}

06 April 2006

seeing 'svn diff' output while editing the commit log in joe

I use subversion and I use the text editor joe (http://sourceforge.net/projects/joe-editor/). I've got the following in my ~/.bashrc file, so that joe is the editor that's launched when I type 'svn commit':


export VISUAL="/usr/bin/joe"


(export SVN_EDITOR="/usr/bin/joe" also works, if you've already got VISUAL set to something else.)

I like being able to look at the output of 'svn diff' while I edit the commit log entry, and I've found two ways of doing this (I'm still figuring out which I like better).

The first way is to redirect 'svn diff' to a file, edit the file (putting the log entry in the file), remove the 'svn diff' output from the file, and then use that file as the log entry when committing:


$ svn diff > ~/commit.txt
$ joe ~/commit.txt
(compose the log entry at the top of the file,
and delete the 'svn diff' output)
$ svn commit --file ~/commit.txt
$ rm ~/commit.txt


The second way is to pull the 'svn diff' output into the editor below the 'This line, and those below, will be ignored' line. Then I just compose the log entry at the top of the file and then quit-and-save. In fact, this can be done with a joe macro. Try adding this to the 'Macros' section of ~/.joerc:


:def svndiff eof,insf,"!svn diff",rtn,bof
svndiff ^K 4


Then, next time you want to commit, just type 'svn commit' and do a '^K 4' in joe. That'll add the 'svn diff' output at the bottom of the file and return the cursor to the top of the file.

The second approach requires fewer keystrokes. The only drawback I've noticed is that if you decide you want to abort the commit and you've already saved your edits, you need to be sure to delete the svn-commit.tmp file before exiting joe, or the commit will proceed with whatever's saved in the svn-commit.tmp file.

28 March 2006

grabbing HTTP headers

Sometimes it's useful to inspect the HTTP response headers from a Webserver (for example, to know if the Webserver is running Apache, IIS, or something else). Most Web browsers have some sort of 'Page Info' feature which will display the response headers. But it's often more convenient to do it from the command line.

The text-only browser lynx has a nice feature for this. Typing the following command will dump the HTTP response headers to the screen without displaying the content of the www.example.com homepage:

lynx -dump -head http://www.example.com/

wget can also do this. wget ordinarily downloads the Web content to a local file without displaying response headers. The following will show the headers and discard the content (-S displays the headers, and -O diverts the output here to /dev/null):

wget -S -O /dev/null http://www.example.com/

The curl utility can do much the same thing (note that this is a lower-case o to specify the output destination, and there a bare hyphen after the -D, indicating that the headers should be written to stdout):

curl -D - -o /dev/null http://www.example.com/

netcat offers a fourth way of getting the headers by allowing you to hurl a custom HTTP request at port 80 on the Webserver:

printf "HEAD / HTTP/1.0\n\n" | nc www.example.com 80

The previous example would only work for HTTP. For HTTPS, you can do a similar trick using the s_client mode for the openssl utility (this example uses an HTTP v1.1 request, which requires a host request header):

printf "HEAD / HTTP/1.1\nhost: www.example.com\n\n" \
| openssl s_client -ign_eof -connect www.example.com:443


The -ign_eof keeps the connection open so that the s_client will see the printf output: this also requires manually closing the connection (Control-C should do it). Additionally, you may get certificate verification errors from openssl. If so, try specifying your system's certificate authority bundle (which contains the public keys of a list of trusted certificate authorities, and which may be in a different location that this example):

printf "HEAD / HTTP/1.1\nhost: www.example.com\n\n" \
| openssl s_client -ign_eof \
-CAfile /etc/pki/tls/certs/ca-bundle.crt \
-connect www.example.com:443

24 March 2006

sorting files by modification date

At times I've found that I need to sort the contents of a directory by modification date. If all the files are in a single directory, 'ls -lt' will do the trick. But it's not so easy if the files are scattered through an arbitrarily complicated directory structure. So I've saved the following shell script in ~/bin/file_epoch.sh (and made it executable w/ 'chmod 700 ~/bin/file_epoch.sh'):


#!/bin/bash
file_name="$1"
mod_time="`/bin/ls --full-time \"${file_name}\" \
| awk '{ print $6,$7; }' | cut -d'.' -f1`"
epoch="`date -d \"${mod_time}\" +%Y%m%d%H%M%S`"
echo "${epoch} ${file_name}"


The script takes a single filename as its argument, and the output is something like this:

20060324152639 /path/to/some/file

Then when I need to sort the files, I just do this:


find /path/to/directory/structure -type f \
-exec ~/bin/file_epoch.sh {} \; | sort -rn


This runs the script on every file in /path/to/directory/structure, and piping the output to 'sort -rn' sorts the files in chronological order (from newest to oldest).

22 March 2006

current year (e.g., for copyright) in TT2 templates

If you are using the Perl Template Toolkit and want the template always to display a copyright notice giving the current year, just include the following in your template:

&copy; [% USE date %][% date.format(date.now, '%Y') %]

It uses the Template::Plugin::Date plugin.

Using GPG as a password wallet

I have too many passwords. In fact, I make many of my less-used passwords by grabbing the first 10 or 12 characters of output from something like this:

dd if=/dev/urandom bs=1k count=1 | md5sum

So I get passwords like '1758dbed4331'--no way I'll remember that.

For a while I tried using a nice text-based password wallet program called the Password Management System (PMS--yes, it's a very unfortunate acronym). I learned about this from a Linux Journal article by Marcel Gagne. I built it from source and used it on FC3 for months.

Then I upgraded to FC4. I rebuilt PMS from source and tried reading the previous PMS data files (two data files in my home directory, as I recall). I kept getting segmentation faults. PMS on FC4 worked OK on new data, but it wouldn't read the old data. Some weird incompatibility in the libraries, I guess. So I had to build PMS on another FC3 box, run it, and copy-and-paste all my passwords out of PMS and into a text file. Lame. Hella lame.

So now I just stick with that text file, but it's encrypted by gpg:

gpg -c passwords.txt

When prompted, I gave it a good password. Now, when I need to look up one of my passwords, I just do this:

cat passwords.txt.gpg | gpg | less

Because the output is in 'less', I can even do text searches (each username/password pair is accompanied by some text describing where the password is used). When I've looked up whatever password I need, I just hit 'q', and I'm done.

trick for hosting large DVD ISOs on Apache

I recently needed to make a large file (a DVD ISO) available from a Webserver running Apache. The ISO was around 3.1GB, and Apache wouldn't serve it (the file wouldn't even show up in the mod_autoindex listing).

So I split up the original file into smaller chunks:

split -b 1073741824 huge_DVD.iso

This created 4 files called xaa, xab, xac, and xad. The first three were 1073741824 bytes each, and xad was around 31MB. I renamed the files (in order) to huge_DVD.chunk1, huge_DVD.chunk2, huge_DVD.chunk3, and huge_DVD.chunk4.

I posted the 'chunks' to the Webserver along with a text file containing the SHA1 checksum of the original file. The original file can be reassembled and its checksum computed in a single read by running the following command (after downloading the chunks):

cat huge_DVD.chunk* | tee huge_DVD.iso | openssl dgst -sha1

17 March 2006

bad blogger, no cookie

I haven't been very good at updating this silly thing, have I?

30 January 2006

Initial post

Blogs seem to be getting pretty popular, so I thought I'd try one.

Here's my first post. It's really dull. Oh, well. It may get better (but probably not).

By the way, I don't much care for wine, I just thought the title was a clever pun (no, in fact, I don't get out much).