Getting the settings right for the Drupal GeSHi Filter module

I wanted to find a way to do syntax highlighting of code snippets on my Drupal blog. I came across the GeSHi Filter module, which lets Drupal sites take advantage of the apparently well-regarded GeSHi Generic Syntax Highlighter library that’s meant for just this purpose.

However, I ran into some roadblocks implementing it on my site. Here’s the short story of what I settled on after some trial and error.

My existing code snippets are in <code> blocks, and the initial GeSHi Filter settings applied badly to them. I made the decision to only use GeSHi on <blockcode> blocks, since I wasn’t using that tag yet and it wouldn’t conflict with the snippets already posted.

I most commonly write Bash/Zsh, Python, and AppleScript snippets on my blog. However, the Bash code I was using as part of my trial and error simply wasn’t highlighting; it was coming through as the default (and boring) plain text — but was at least boxed off from the rest of the blog post.

I thought that GeSHi wasn't correctly discovering that the code was written in UNIX shell syntax. I couldn’t find a way to specify the language for that blockcode tag, until I did some searching on the ’net. To change my blockquotes to choose a certain language — at least for the purposes of this Drupal module, if not for GeSHI in general — I needed to add the “lang=lang” style to the tag. For Bash, I could use “lang=bash,” for Python, “lang=python,” and for AppleScript, “lang=applescript.” That made sense.

However, my code was still not being syntax highlighted. I discovered that the Drupal module came with an initial set of languages enabled. The others were all turned off, but that could be changed in the module settings. Without turning them on, even properly-tagged <blockcode> sections did not get the benefit of syntax highlighting.

I changed the GeSHi Filter options to enable some of the languages that were initially disabled, and then disabled the ones I didn’t anticipate using. This allowed me to add Bash and AppleScript syntax highlighting support, as both had been turned off by default. After that, I saw the results I’d hoped for: a syntax-highlighted code snippet.

It took some work, but now that it’s done, I should be all set.

Check for SSL certificate expiration of Radmind client certificates

You can find out if an SSL certificate has expired with the command below. I’ve found it useful to be able to check for expired certificates in my use of Radmind, where you can uniquely identify clients to the server with them.

$ openssl x509 -in /path/to/cert.pem -noout -checkend 0

I mention this command primarily because I reviewed the the OpenSSL x509 man page (“man x509”) that comes with Mac OS X Leopard, and it didn’t show the “checkend” option for the command. That was odd, because that option was just what I needed.

I did, however, find it documented in the usage statement-style help for the command:

$ openssl x509 --help

In that usage statement, the “checkend” option is described (with little punctuation) as a way to “check whether the cert expires in the next arg seconds [sic] exit 1 if so, 0 if not.” So, using zero seconds shows you if the certificate has already expired, while an integer greater than zero will show if it will expire in the future. No matter how many seconds you check against, you must examine the results from the exit code (the “$?” shell variable) to see if the certificate is or has expired.

I find this is tremendously useful knowledge when dealing with certificates in Radmind, where an expired certificate can mean the failure of a client to connect to the Radmind server. It could be beneficial in other circumstances, of course — but I don't have those circumstances.

Taking this further, you could check for certificate expiration on a Radmind server — if your certificates are stored in the Radmind special directory for each hostname of a managed client. (Substitute one of your own managed clients’ hostnames for “hostname” in the path below.)

$ openssl x509 -in /var/radmind/special/hostname/private/var/radmind/cert/cert.pem -noout -checkend 0

Since you can do it for one client certificate, you could also loop through all of the certificates on a Radmind server. In this example, I’ll continue to use the path of /var/radmind even though, on Mac OS X, I’d generally prefer to specify the full /private/var/radmind; your Radmind server may not be on Mac OS X even if your clients are. Also, you may need to modify the “depth” parameter on your search to accommodate the paths on your server. Finally, I’ll change the “checkend” parameter to 604800, for seven days (60*60*24*7=604800). That produces something along the lines of:

for CERT in `find /var/radmind/special -name cert.pem -print -type f -depth 6`;
do
    openssl x509 -in "/private/var/radmind/$CERT" -noout -checkend 604800
         RESULT=$?
    case "$RESULT" in
     0)
          echo "$CERT: okay"
          ;;
     *)
          echo "$CERT: expiring"
          ;;
esac
done

Change the last line to “done | grep expiring” if you only want to see the expiring certificates.

It’s great to get just the CN of the certificate in these circumstances, since it’s likely you’ll want to act on just those that need attention. One way to do this relatively cleanly is to use OpenSSL x509’s “subject” and “nameopt” options, and then parse the output. Below, I’ll use awk for that. (Again, substitute one of your own managed clients’ hostnames for “hostname” in the path below.)

$ openssl x509 -in /private/var/radmind/special/hostname/private/var/radmind/cert/cert.pem -noout -subject -nameopt sep_multiline | awk '/CN/ {split($1,elements,"=") ; print elements[2] ;}'

Beyond checking for expiration on the server, it may be valuable to do so in your Radmind client scripts, especially if you favor SSL connections. If you find an expired certificate, you can take some remedial action right away that might allow the client to communicate with the server.

I thought about this a while, and the easiest way I came up with — after having already developed more complex logic — was to simply rename or remove the expired certificate from its normal path. Then, allow the client to connect with another authorization level where the client certificate is unnecessary. (Use of a client certificate implies Ramind’s “-w2” authorization level, while a lesser level would mean you’re performing hostname/DNS rather than certificate verification.) This would probably mean you have multiple Radmind server processes running, each on its own port, to accept such incoming requests on the server.

New York Times on The Worst Is Yet To Come: Anonymous Banker Weighs In On The Coming Credit Card Debacle

The New York Times’ Executive Suite Blog says that The Worst Is Yet To Come: Anonymous Banker Weighs In On The Coming Credit Card Debacle.

I’ve been pondering this very topic for a while, and wonder what’s in store for all of us in the spring.

[Via Daring Fireball.]

An Epic Introduction to PyObjC and Cocoa

Irrational Exuberance has An Epic Introduction to PyObjC and Cocoa. Skimming over it, it really does seem to start at the ground level — and that’s what I need. I have high hopes it will help me figure out PyObjC.

[Via PyObjC Development mailing list.]

List changed files in a Mercurial repository with a custom output style

While trying to troubleshoot what I’d done to mess up the Mercurial repositories managing my Drupal installations last weekend, I really would have liked a way to see what files had changes in specific revisions. Each revision to a Mercurial repository affects some files, of course, but it seems awfully hard to figure what files changed in that check-in.

I have since found a way to do that by customizing the output of Mercurial. To customize output, you can create templates on the command line (with --template) or for more powerful reformatting, create an output style file.

I struggled for a while to figure out how to use style files, and eventually came up with something that works for me so far.

Since I’ve installed Mercurial from Lee Cantey’s standard binary package for Mac OS X Leopard, I created the file “map-cmdline.changedfiles” at the “/Library/Python/2.5/site-packages/mercurial/templates” path. (Where you put the file may vary depending on where Mercurial is installed, and I’m sorry but I don’t know where it gets installed on other systems.) The contents of “map-cmdline.changedfiles” are below, along with my possibly inept description of what each line is doing:

# Get all of the files in the selected revision
# and stringify them, whatever that means
# but do not 'tabindent' or wrap them to 68/76 columns
# Without first setting changeset to the list of files
# you won't get output from subsequent lines
changeset = '{files|stringify}'
# List modified files, one per line
# preceded by M to mimic `hg status`
file = 'M {file}\n'
last_file = 'M {file}\n'
# List added files, one per line
# preceded by A to mimic `hg status`
file_add = 'A {file_add}\n'
last_file_add = 'A {file_add}\n'
# List deleted files, one per line
# preceded by ! to mimic `hg status`
file_del = '! {file_del}\n'
last_file_del = '! {file_del}\n'

I don’t know why the “map-cmdline.” portion of the filename is there, but as long as I have it, I can call the style file from the command line with what follows the period. So, I can call the style with “--style changedfiles” — and that tiny bit of voodoo seems reasonable enough to me. (The other styles in the directory above, many of which end in “.tmpl” extensions, seem related to the Mercurial Web server, hgweb. I tried, but I couldn’t use their names at the command line, with or without their extensions. Plus, their contents looked HTML-ish.)

With the “map-cmdline.changedfiles” style file saved in that location, I can call Mercurial’s “log” command:

$ hg log --style changedfiles -r tip

… which gives me a list of the files changed in the “tip” (or latest revision) of the repository. I could substitute in any revision identifier for “tip.”

I haven’t actually seen the “file_add” and “file_del” keywords in action; every time I’ve used this style file in the manner described, I’ve only seen files marked as “M” — even if I’m looking at a revision where new files were first checked into the repo. I’m confused by that, but I’m not going to let it sour my day at this point.

There might have been an easier way to do this but I didn’t find one last weekend. It took me some time to figure even this bit out, and I hope writing this post saves someone new to Mercurial from future frustration.

Launch Services database manipulation with lsregister

While you could clear the various LaunchServices databases by deleting files, I prefer to use a more targeted command line tool when possible. My assumption is that the command line tool is canonical and will therefore produce more reliable results.

In Mac OS X Tiger, you could clear the LaunchServices database using the following “lsregister” command:

$ /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/
Versions/Current/Support/lsregister -kill -r -domain system -domain local -domain user

But, in Leopard, the LaunchServices framework’s path has moved; it is now in the CoreServices framework bundle. You can find it with the “find” command:

$ find /System -name lsregister -type f -print 2>/dev/null
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/
Versions/A/Support/lsregister

Once you find it, you can get the usage statement for the “lsregister” command in Leopard, which will at least tell you what options it has:

$ /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/
Versions/A/Support/lsregister

lsregister: [OPTIONS] [ ... ]
[ -apps [,domain]... ]
[ -libs [,domain]... ]
[ -all [,domain]... ]
Paths are searched for applications to register with the Launch Service database.
Valid domains are "system", "local", "network" and "user". Domains can also
be specified using only the first letter.
-kill Reset the Launch Services database before doing anything else
-seed If database isn't seeded, scan default locations for applications and libraries to register
-lint Print information about plist errors while registering bundles
-convert Register apps found in older LS database files
-lazy n Sleep for n seconds before registering/scanning
-r Recursive directory scan, do not recurse into packages or invisible directories
-R Recursive directory scan, descending into packages and invisible directories
-f force-update registration even if mod date is unchanged
-u unregister instead of register
-v Display progress information
-dump Display full database contents after registration
-h Display this help

Note that if you’re having Launch Services-related problems in one user account but not another, you’ll likely want to start with the “user” domain. (It pays to understand the domain structure of Mac OS X, so that you only make changes where you need to.)

Untar archive contents directly into a target folder

In my Mercurial-based workflow for updating Drupal sites, there is a sequence of commands I need whenever a new version of Drupal comes out. I have a hard time remembering the options for “tar” in this sequence — and my original source for the instructions differs from what I need to do on my Web host — so I need to help my memory. The tar command, as constructed below, places its output into the specified destination directory.

Here it is, with tar’s “--strip-path=1” and “-C” options:

$ cd path/to/repository/parent/directory
$ curl -O http://ftp.drupal.org/files/projects/drupal-5.12.tar.gz
$ tar --strip-path=1 -C drupal_source -zxv -f drupal-5.12.tar.gz

Nikon (and other) 2009 predictions

These are some really interesting predictions for the digital camera market of 2009. Although it’s supposed to be Nikon predictions, it touches upon other vendors, especially those in the DSLR space.

Find Info.plist files for applications on Mac OS X

There is some important information in the Info.plist files contained in Mac OS X applications. But, some of that information isn’t really standardized — I’m looking at all of you, you crazy version number and vendor attributes (just the ones I'm interested in!). So, given that, how do you find them all to make comparisons between Apple and third-party apps?

Answer: You can use the “find” command to find all of the Info.plist files for applications in your /Applications directory.

$ find /Applications -name Info.plist -ipath /Applications/\*.app/Contents/Info.plist -depth 3 -print 2>/dev/null

Since that intentionally limits the depth traversal, you could modify it slightly to support finding Info.plists in your /Applications/Utilities directory, as well. However, I would say it’s less likely you’ll be dropping third-party applications in the Utilities directory, so you might not care.

Paper cuts: Layoffs and buyouts at U.S. newspapers

Having once been a newsroom intern, I have a soft spot for newspapers and newspaper people. It’s a bit disheartening to see the scale of layoffs and buyouts at U.S. newspapers.

Even though some would newspapers are anachronistic or dinosaurs, this mashup still represents good people trying to do important work.

Syndicate content