Wednesday, July 8, 2009

Coding styles that make me twitch, part 3

Today's twitchiness is sponsored by ... no, wait, I don't have sponsors. Ah, well.

I have an issue with people who insist on using <"> as a string delimiter when the (static) string itself contains that very character. It gets fugly all too soon:

my $html_output = "<a href=\"http://www.example.com/foobar/$pagename.html\" title=\"Oh, a link to $pagename\"> ...\n";

It's so easy to avoid having to quote the <"> while still allowing variable interpolation:

my $html_output = qq(<a href="http://www.example.com/foobar/$pagename.html" title="Oh, a link to $pagename"> ...\n);

Since the example is HTML (and could be e.g. SQL), and it might be multi-line, why not ...
my $html_output = <<EOL;
<a href="http://www.example.com/foobar/$pagename.html"
title="Oh, a link to $pagename>
EOL

That wasn't so hard? Or fugly?

Thursday, July 2, 2009

Ruby users anonymous

Last weekend, I visited a couple of friends -- Ina and Stig -- and being nerdy geeks, we (well, Stig and I, anyway) ended up chatting about programming and stuff.

Stig has just started programming Perl again, after a long period where he'd probably claim to be apostate.

Everybody, meet Stig. Stig used to program Ruby, but now he's recovering.

Edit: Stig's blog address injected.

I hope this shows that there's hope for the ones who got lost.

Wednesday, June 24, 2009

Virus scanning with File::Scan::ClamAV

This is almost ridiculously easy.

Problem: a bunch of user directories need virus scanning and per-user reports

Solution: A Perl script using File::Scan::ClamAV

Prerequisites:
  • A unixy OS
  • Perl 5.8 or 5.10
  • A functional and running clamd, preferably listening to a socket
  • The module File::Scan::ClamAV (and its dependencies)

The following code could (after some sensible adjustments) run in a loop through all usernames on your system.

use File::Scan::ClamAV;
# (...)
# $dir contains the full path of the user's directory
my $av = new File::Scan::ClamAV (find_all => 1,
port => '/tmp/clamd.socket');
# find_all means that we wish to recurse directories.
# /tmp/clamd.socket is where my clamd has its socket.
# Other clamd configurations may differ.

unless ($av->ping) {
plogdie "clamd isn't running, aborting virus scan";
} else {
plog "Performing virus scan for $uname";

# Save virus information per username ($uname).
# Note! scan() returns a hash.
$a_viruses{$uname} = $av->scan($dir);

if ($a_viruses{$uname}) {
my @vfiles = sort keys %{$a_viruses{$uname}};
plog "$uname has ".@vfiles." viruses.";

# Home assignment: print contents of $a_viruses{$uname}
# to a file, using the sorted list @vfiles.
}
}