The Expendables

It’s no secret that I’m a fan of action movies.  Movies are a form of escapism, and heroic sacrifice driven action movies always take me away from the mundane world and keep me amused.  I can cope with a lot of cheese if the action is dramatic and the quotes memorable.  I don’t need much of a plot.  Some good guys, some bad guys, a reason for the good guys to be after the bad guys, and I’m a happy man.

Cool shots, dramatic action, sassy dialog and plenty of sarcasm and the movie is approaching action nirvana.

I grew up with two kinds of movies.  John Hughes / Harold Ramis / John Landis comedies, and Stallone / Schwarzenegger / Willis / Lungren / van Damme / Gibson action flicks.  My tastes are clear.

It was therefore with both excitement and trepidation that I sat down in the cinema today to watch The Expendables.  So much potential, so much that could potentially go wrong.  There have been three ensemble action movies this year.  The Losers, The A-Team and The Expendables.  Unable to commit to seeing them all – we picked The Expendables by dint of timing and health.

Was I going to leave the cinema regretting it?  Was it going to sour lasting memories of enjoyable 80’s action flicks?  (Could anything sour it more than Twins?)  Was I going to be left with a lasting image of 60 year old men trying to relive their best years?

No, no and well, yes actually in that order.

The Expendables gets plenty right and only a few things wrong.  I thought it was actually too slow in places, some of the bonding scenes didn’t have enough pace or enough wit to elevate them to the right level of interest.  However, that’s a minor quibble in what otherwise was an excellent homage to the 80’s our rose tinted glasses show us.  Don’t be fooled by the trailers, this is actually quite a small cast.  Willis and Schwarzenegger have tiny walk on roles (and I’m not even sure they were all in the same room).  The focus is Stallone, Statham and Jet Li and for me that ended up working really well.

I love Statham and he plays this role to the hilt, I wouldn’t describe his acting range as ‘broad’ but this isn’t the Transporter or Crank or Lock Stock.  His by-play with Stallone is great and if they’re not great friends in real life I’ll eat my socks.  Jet Li is suitably amusing, Stallone is superb, Dolf is hulking and brooding, Randy Couture was surprisingly entertaining and Terry Crews was okay.  The weakest roles were the bad guys, they were pretty flat cardboard cut-outs and never really delivered any serious menace.  I could have done with a Hans Gruber or a Karl, maybe even a Mr Joshua.

After the setup to demonstrate how Bad Ass our heroes are, and an underused relationship bit with Statham and Charisma Carpenter, we are given the rest of the plot in 3 scenes and then slowly watch the tension build (too slowly at times).  Just before the final epic action sequence started I was thinking ‘there hasn’t been much actual shooting yet?’  But they fixed that!

Mickey Rourke added an interesting reflective moment, which you can take on the surface to be banal and patronising or you can choose to accept it for what it is – a statement that if we give up on others, then we’re basically giving up on ourselves as well.  I was glad they used Mickey as the wizened old wizard archetype, I’m not sure it would have been credible watching his pot belly take on the bad guys.

As I said, the interplay between Statham and Stallone was excellent, and the chemistry between all of the main good guys was very good.  These guys clearly respect each other and clearly know how to poke fun at themselves.  The conversation with Schwarzenegger felt forced but it got some good laughs (he wants to be president).

There’s plenty of exploding bullets, vehicles and bodies once the action gets going, and I laughed as much as I cheered.  I’ve seen reviews which say the movie was tired, awkward or ancient.  I can’t disagree more.  Rather than remake the movies of the 80’s and get it so glaringly wrong (hello Clash of the Titans), Stallone has lit a candle for the memories we have of how good those movies were, and given us something to cheer for in an otherwise bleak world of terrible reality.

The Expendables – it is what it is and it’s very good at being it.

Opal Fail

I was a loyal and happy Nildram ADSL customer for a good few years.  They’re not the cheapest, but they were very reliable, and they didn’t bug me.

When they were bought by Pipex, not much changed.  I remained loyal, they left me alone.

When they were bought by Tiscali, not much changed.  I remained loyal, they left me alone.

They’ve finally been bought by Opal.

So far, Opal have called my home once trying to get me to change my package to take on their phone as well as ADSL (although their terminology was intentionally deceptive), and they’ve sent me 3 promotional e-mails in the space of two weeks to the same end.

That’s not much maybe, certainly not in the deluge of spam I already get.

But you know what?  It’s really fucking annoying when I’m already a customer of theirs.  I do not want to change my package to their phone line, if I did, I would.  I’m like that.  Do they provide an easy way to contact customer services?  Not that I can find, although I did mail the one address I could find after the first e-mail.  No way on the subsequent e-mails to say ‘don’t send me this crap’ ((there is a link, but apparently no way to say, mail me important service stuff, but not this advertising shit)).

It’s lesson 101 in how not to retain customers.

BE is looking very promising.

Dragon Age: Round 2

When I wrote the title of this post, I went to search the blog to find the first one I wrote on Dragon Age: Origins only to find I didn’t write one (and to be reminded of how annoying the search feature in WordPress is).

So, I guess this is Dragon Age: Origins, Rounds 1 and 2.

As usual, it’s a not-review well after the game has been released, played to death by millions, had a bunch of DLC released and is being replaced with a sequel, but hey ho, what can you do.

I’ve played a few games on the PS3 now, and it’s easily earned back the cost in terms of entertainment per pound compared to say the cinema or reading, but two games really stick in my mind in terms of amount of game-play and replayability.  They are Dragon Age: Origins and Fallout 3.  My first play through DA: Origins probably took around 60 hours.  Grete played it a little bit, so probably 70 hours between us.  However, we’ve both played it through fully again now, so another 60 hours each, that’s 190 hours of play out of a single game.  And as I sit here writing this, Grete is starting a new character and playing it again.

That replayability is testimony to BioWare’s excellent writing and world building.  The game interface is sometimes annoying, the combat is sometimes a little frustrating, but those issues melt away once you get involved in the story.  Reading the codex entries, listening to the dialog, talking to your companions, actually recruiting the companions and earning the right to do their quests, and learning about the world immerse you in the story so engagingly that you want to see it again and again through a fresh pair of eyes.

I love the subtle touches with the different starting stories, and how they all weave together into the main plot.  As a dwarf, returning to Orzammar to quest there gives you a different perspective than heading there as a human or an Elf, while playing a city Elf makes the quests in the Elven alienage that more poignant.  Seeing how your actions as a starting Mage snowball into serious consequences later on is just excellent.  BioWare really do know how to write engaging and totally absorbing computer RPG’s.

The way in which your conversational choices lead to different outcomes is excellent, although you can’t help but feel the authors were limited by the complexity of offering too much choice, and like all delicious things it leaves you wanting even more.

Maybe in a few years when storage is even cheaper, processing power even greater and collective software development even better we’ll get computer based RPG’s with almost as many choices as you can imagine, but until then, BioWare offer the next best thing with Dragon Age: Origins.

Dry day for a change

Last few weeks have been pretty wet (clearly, not on the same scale as some parts of the world), but it’s been a useful excuse not to get into the garden.  Today I’m on holiday and it’s sunny and dry, so no chance at any excuses.  To the left is the picture of one of our apple trees.  The other (much smaller, and looking pretty unhealthy) is in the middle of the garden.  This one is at the top, and despite some rather vicious pruning last year it’s grown huge again this year with a bumper crop of apples.  Which is nice, except it then slowly drops them onto the grass throughout the late summer and early autumn.  I’m not a huge fan of apples and Grete’s not a huge fan of apples which look like they’ve been used as living quarters.  Even if we were, there’s no way we could eat a tree’s worth.  Anyway, this is how it looks when it’s being nice and giving us gifts.

And here’s how those gifts look if you take a close look at them.

Anyway, we clear them up once a week or so, and I got them done today, so now it looks like this!

Since I was already wearing my gardening stuff I finally decided to move the wood from the side of the house and get rid of it.  Yes, it’s true, the deck is almost finally almost all gone nearly.

And while moving it, I found a guest.

Orange is a state of mind

Finally settled on a new theme (the excellent Suffusion) which comes with a bunch of colour schemes, and I’ve picked Orange on Black (for now).  I know it makes little difference since the 6 people who actually read the blog do so via RSS so never see the colours anyway, and the other hits are all chinese ‘bots trawling data to try and gimp Google out of some cash.  Some folk are tired of dark themes, but I still like them.

The Orange on White version is pretty good as well and if I get bored with dark I might go for that.

I’ve had to work on some new headers, since the old ones were too tall and too narrow.  Managed to salvage the Matrix and floaty text ones, and added a couple of others.  Was very excited to find an Atari Space Invaders icon font!

Haven’t been doing much stuff out of work other than playing Dragon Age: Origins for the second time.  Tried playing it through a second time after originally completing it but it was too soon.  A lengthy break has done the trick and it’s almost as engaging the second time around.  Grete’s also playing it, so we’re taking turns like well behaved kids.  First time through I played as a warrior and was hugely frustrated by all the chests you can’t open until you find your first rogue companion.  So this time, started as a rogue!  Very different feel to the game, can’t go rushing into fights, need to somehow get the others engaged first, and if the warriors die, I’m not likely to survive (where-as when you’re the warrior you can hold on for quite a while with just Wynne).

Playing through again reminds me how good BioWare are at dialog and storyline.

Grete’s doing well at pretending I’m not annoying, when she plays and I shout ‘no, no, do Sten’s quest first’, or whatever.  So I thank her for that.

We bought a couple of the little add-ons, well bought one, got one free.  I’ve also bought Dragon Age: Awakening which was good but no where near worth the price.

I’ve also signed up to the PlayStation Plus service thing.  Got a few free games so far (Zen Pinball being the best).  Hopefully there’ll be enough free content in the next 10 months to justify the cost.

Custom Logwatch script for ngIRCd

So before I begin (or technically, just after I’ve begun), let me remind you that my perl skills are shockingly bad.  All my perl scripts are written in the same style as the script I was copying from at the time I wrote them.

Introduction

I’ve recently set up an IRC server, partly to mess about with it and partly to consider using it to keep in touch with friends.  I’m acutely aware that it’s the kind of thing that gets attacked, so I’ve made sure ngIRCd (the daemon I chose) is logging everything, and then I started looking for a logwatch (homepage) script to monitor the logs and alert me of anything suspicious going on.

Sadly, I couldn’t find one, so I decided to do the only sensible thing and write my own, which is fine, but as you’ll see if you search the web for ‘writing custom logwatch scripts’, it’s sort of both easy and hard.  It’s easy once all the bits fall into place, but sometimes the terminology gets in the way.  So, here’s how I did it.

Detail

You absolutely need two files, one which describes which logs you’re going to handle, and another which is the script which does the handling.  You should name them in some way which makes sense (after the service you’re monitoring for example).  Once you put them in the right place, logwatch will execute your script and you’re away.  There are some optional files, if you want to do some logfile pre-processing (I think) but as I never used those, I can’t comment.

So, I want to monitor ngIRCd which on my server logs everything it does to /var/log/messages under the service name ngircd.  Here’s an example line,

[sourcecode language=”plain” gutter=”false”]
Aug 13 08:01:54 hostname ngircd[10898]: User "bob!~ident@some.machine" registered (connection 8).
[/sourcecode]

The first thing I did was create a file describing which logs to monitor and how to filter the data, and I stole various bits of information from the other files distributed with logwatch.  I called my file ngircd.conf and place it in,

[sourcecode language=”plain” gutter=”false”]
/etc/logwatch/conf/services/
[/sourcecode]

That’s the default location on Debian.  Here’s the content of my file with some comments,

[sourcecode language=”bash”]
# set the title for the reports
Title = "ngIRCd"
# set the logfile to the messages log file *group*
LogFile = messages
# only return entries made by ngIRCd which reduces our effort in the script
*OnlyService = ngircd
# remove the date / time stamp, hostname, service name, etc.
*RemoveHeaders
[/sourcecode]

Line 3 is important and took me a little while to work out.  In the config file for your service, you describe the log file group that is used, which in turn tells logwatch which file in the /logfiles/ directory structure describes the actual log files which are scanned.  So the above line tells logwatch (in the case of Debian) to use the log files described in /usr/share/logwatch/default.conf/logfiles/messages.conf.  That file handles the log file names, how to deal with date/time stamps, archived logs, etc.

If the log files for your new service don’t already have a matching log file group configuration file, you should create one in /etc/logwatch/conf/logfiles, using an example from /usr/share/logwatch/default.conf/logfiles.  Anyway, in my case, since I was using /var/log/messages which is already described in /usr/share/logwatch/default.conf/logfiles/messages.conf I didn’t need to create one.

Now that you’ve got the service configuration covered, you need a script, and it needs to be named after the config file (so if you call your config file foo.conf, then your script needs to be called foo).  You can write this script in any language that can read from STDIN and write to STDOUT, but like other folk before me I made the joyful error of sticking to perl.

You place this file in

[sourcecode language=”plain” gutter=”false”]
/etc/logwatch/scripts/services
[/sourcecode]

The important things to remember are,

  1. your script will receive the content of the appropriate logs via STDIN
  2. it should write output to STDOUT and should use the environment variable LOGWATCH_DETAIL_LEVEL to determine the detail level passed to the logwatch program
  3. the output should be tidy and should avoid being verbose
  4. if you’ve configured the service conf script correctly you won’t need to worry about parsing dates, stripping headers, or other rubbish.  This does depend on the log file in question though and the application.
  5. To keep in line with other scripts, you should capture everything you know you don’t care about and ignore it, process stuff you do care about, and report stuff you don’t recognise.

The link below is the script I cobbled together to handle ngIRCd so far.  At the moment, I ignore my own advice and don’t check the detail level, I just wanted initially to get my data out.  I have no idea if the regexp’s are correct or efficient, but at present, it displays what I care about. Is that enough caveats?  I’m not looking for feedback on the quality of my perl! I’m just trying to show how it can be done.

ngircd

[sourcecode language=”perl”]
#!/usr/bin/perl
##########################################################################
# ngircd
##########################################################################

use Logwatch ‘:all’;

my $Detail = $ENV{‘LOGWATCH_DETAIL_LEVEL’} || 0;
my $Debug = $ENV{‘LOGWATCH_DEBUG’} || 0;

my %FailedLogin = ();
my %FailedOpers = ();
my $FailedOpCommands;
my %TriedConnections = ();
my %GoodConnectionsi = ();
my %GoodOper = () ;
my %BadOpCommands = ();
my %OtherList = ();

if ( $Debug >= 5 ) {
print STDERR "\n\nDEBUG: Inside ngircd Filter \n\n";
$DebugCounter = 1;
}

while (defined(my $ThisLine = <STDIN>)) {
if ( $Debug >= 5 ) {
print STDERR "DEBUG($DebugCounter): $ThisLine";
$DebugCounter++;
}

chomp($ThisLine);
if ( # We don’t care about these
( $ThisLine =~ m/connection .* shutting down / ) or
( $ThisLine =~ m/^New TLSv1 connection using cipher/ ) or
( $ThisLine =~ m/^Now listening on/ ) or
( $ThisLine =~ m/^IO subsystem: epoll/ ) or
( $ThisLine =~ m/^Reading configuration from/ ) or
( $ThisLine =~ m/^ngircd .* started/ ) or
( $ThisLine =~ m/^Created pre-defined channel/ ) or
( $ThisLine =~ m/^Not running with changed root directory/ ) or
( $ThisLine =~ m/^Notice: Can’t change working directory to/ ) or
( $ThisLine =~ m/^getnameinfo: Can’t resolve address/ ) or
( $ThisLine =~ m/^Shutting down all listening sockets/ ) or
( $ThisLine =~ m/^ServerUID must not be 0, using/ ) or
( $ThisLine =~ m/^OpenSSL .* initialized/ ) or
( $ThisLine =~ m/^Configuration option .* not set/ ) or
( $ThisLine =~ m/^User .* unregistered/ ) or
( $ThisLine =~ m/^Server restarting NOW/ ) or
( $ThisLine =~ m/^Server going down NOW/ ) or
( $ThisLine =~ m/^Shutting down connection .* \(Got QUIT command\.\)/ ) or
( $ThisLine =~ m/^Connection .* with .* closed / ) or
( $ThisLine =~ m/^Running as user/ ) or
( $ThisLine =~ m/^Shutting down connection .* \(Server going down/ ) or
( $ThisLine =~ m/^Shutting down connection .* \(Socket closed/ ) or
( $ThisLine =~ m/^Shutting down connection .* \(Ping timeout/ ) or
( $ThisLine =~ m/is closing the connection/ ) or
( $ThisLine =~ m/^ngircd done/ ) or
( $ThisLine =~ m/^Client unregistered/ ) or
( $ThisLine =~ m/^Client .* unregistered/ ) or
( $ThisLine =~ m/^User .* changed nick/ )
) {
# We don’t care, do nothing
} elsif ( my ($Host) = ($ThisLine =~ /Accepted connection .* from ([\d\.]+)/ )) {
$TriedConnections{$Host}++;
} elsif ( my ($User,$Connection) = ($ThisLine =~ /^User \"([^ ]+)!([^ ]+)\" registered /)) {
$GoodConnections{$Connection}++;
} elsif ( my ($User,$Connection) = ($ThisLine =~ /^Got invalid OPER from \"([^ ]+)!([^ ]+)\": / )) {
$FailedOpers{$Connection}++;
} elsif ( my ($User,$Connection) = ($ThisLine =~ /^No privileges: client \"([^ ]+)!([^ ]+)\", command / )) {
$BadOpCommands{$Connection}++;
} elsif ( my ($Host) = ($ThisLine =~ /^Shutting down connection .* \(Bad password\) with ([^ ]*):/)) {
$FailedLogin{$Host}++;
} elsif ( my ($User,$Connection) = ($ThisLine =~ /^Got valid OPER from \"([^ ]+)!([^ ]+)\", user is an IRC operator now/ )) {
$GoodOper{$Connection}++;
} else {
# Report any unmatched entries…
$OtherList{$ThisLine}++;
}
}

#######################################################

if (keys %BadOpCommands) {
print "\nIRCOp commands from regular users:\n";
foreach my $key (keys %BadOpCommands) {
my $totcount = 0;
$totcount += $BadOpCommands{$key};
my $plural = ($totcount > 1) ? "s" : "";
print " $key: $totcount time$plural\n";
}
}

if (keys %FailedLogin) {
print "\nFailed logins from:\n";
foreach my $key (keys %FailedLogin) {
my $totcount = 0;
$totcount += $FailedLogin{$key};
my $plural = ($totcount > 1) ? "s" : "";
print " $key: $totcount time$plural\n";
}
}

if (keys %FailedOpers) {
print "\nFailed attempts to become IRCOps from:\n";
foreach my $key (keys %FailedOpers) {
my $totcount = 0;
$totcount += $FailedOpers{$key};
my $plural = ($totcount > 1) ? "s" : "";
print " $key: $totcount time$plural\n";
}
}

if (keys %GoodOper) {
print "\nGood attempts to become IRCOps from:\n";
foreach my $key (keys %GoodOper) {
my $totcount = 0;
$totcount += $GoodOper{$key};
my $plural = ($totcount > 1) ? "s" : "";
print " $key: $totcount time$plural\n";
}
}

if (keys %TriedConnections) {
print "\nAttempted connections from:\n";
foreach my $ip (sort SortIP keys %TriedConnections) {
my $name = LookupIP($ip);
my $totcount = 0;
$totcount += $TriedConnections{$ip};
my $plural = ($totcount > 1) ? "s" : "";
print " $name: $totcount time$plural\n";
}
}

if (keys %GoodConnections) {
print "\nGood connections from:\n";
foreach my $key (keys %GoodConnections) {
my $totcount = 0;
$totcount += $GoodConnections{$key};
my $plural = ($totcount > 1) ? "s" : "";
print " $key: $totcount time$plural\n";
}
}

if (keys %OtherList) {
print "\n**Unmatched Entries**\n";
foreach $line (sort {$OtherList{$b}<=>$OtherList{$a} } keys %OtherList) {
print " $line: $OtherList{$line} Time(s)\n";
}
}

exit(0);
[/sourcecode]

If I have the inclination, I plan to update this to display different levels of detail based on the logwatch detail option, format the output a little nicer, handle some different bits of information and split the input lines up into more fields.  But you know, now it does 90% of what I want, that might never happen.

Summary

  • Pick a name (based on the service you’re reporting on)
  • Create /etc/logwatch/conf/services/myname.conf and describe the log file group to use, and any other options
  • Create a script /etc/logwatch/scripts/services/myname in your favourite language and parse STDIN, sending useful information to STDOUT
  • Bingo