I wish Ming had documentation

Documentation is a good thing. Especially for programmers. When you're working with a new API, you like to know exactly what all those functions, objects, and methods do. Otherwise, you're just kind of guessing - and that makes the programming process quite painful.

I spent much of today messing around with the Ming bindings for PHP. Ming is an open-source library for creating Flash movies. It's a nice library and pretty much perfect for what I'm trying to do - dynamically create SWF files from user-uploaded data.

The only problem with Ming is that the documentation is practically non-existent. Oh, sure, PHP has a documentation section for it, but it's largely just shell docs - auto-generated function declarations with parameters. Little to no information on what the functions actually do. Fortunately, gazb has a nice Ming example site which makes up for that. It includes basic samples of all sorts of common scenarios, so I was able to figure out the stuff I needed pretty quickly.

The problem I'm having now, however, is not with the basic usage of the library, but rather with some of the deeper details, i.e. the ones that go beyond the basic syntax and usage. In particular, I'm working with SWFSound objects, trying to bind an arbirtary, user-uploaded audio file to a button. The problem is, the Ming documentation cointains zero informtation on exactly what formats SWFSound can handle. I've tried several variations on WAV files - some work, others just produce static. Apparently SWFSound also supports some compressed formats, apparently including MP3, but I've yet to get any results with those.

So now it looks like I'm stuck with the scenario of converting all the user-uploaded audio into a known-good format before passing it off the Ming. Now I've just got to figure out how to do that. Ming seemed to like the WAV files produced by MPlayer, but we don't have that on our servers. Rather, we have FFMPEG, and Ming barfed all over itself when I tried creating the WAV files with that (meaning it segfaulted trying to write the SWF). Apparently I just don't know the magic flags to make it work.

In any event, it would be really nice to have some hard information here. But I guess that's what happens when you use extensions that are listed as experimental. Maybe I should just get an ActionScript compiler installed on the servers and write a script to populate a template source file.... Of course, that would mean I'd have to learn ActionScript.

No, that spam didn't come from me

I found a nice surprise in my e-mail the other morning: about 200 new messages. All of them bounce notifications from undeliverable spam I didn't send.

Apparently some sleaze-bag decided to forge my e-mail address as the sender on a batch of spam. That sucks. Unfortunately, there's not really anything I can do about it. Forging e-mail headers is ridiculously easy and there isn't really any way to keep someone from using your address. So I guess it just sucks to be me.

As to the nature of the spam, I noticed a number of commonalities from the bounce messages. First, all the bounced messages I checked had the same mailer header:
X-Mailer: Microsoft Outlook Express 6.00.2900.3138
Second, I noticed two big trends in the actual content. Lots of them were targeted at Russians and eastern Europeans, as evidenced by the target domains and the use of the Cyrillic alphabet, and there were also a bunch that simply contained links to what appeared to be a Google ad for a German taco restaurant. As for the originating IP addresses, most of the ones I checked were from eastern Europe, but I also saw IPs from China, Turkey, Germany, and several from the US.

Here's a representative example of one of the German taco link messages, as encapsulated in a bounce message.
Received: (qmail 74968 invoked from network); 31 Mar 2008 10:24:57 -0000
Received: from unknown (66.218.66.72)
by m54.grp.scd.yahoo.com with QMQP; 31 Mar 2008 10:24:57 -0000
Received: from unknown (HELO 84.255.241.179) (84.255.241.179)
by mta14.grp.scd.yahoo.com with SMTP; 31 Mar 2008 10:24:56 -0000
Message-ID: <000501c89319$05ef79a0$e3e718b8@kdjpt>
From: "dom carey" <pageer@skepticats.com>
To: <XXXXXX@yahoogroups.com>
Subject: Your neighbour naked!! watch
Date: Mon, 31 Mar 2008 08:37:48 +0000
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_NextPart_000_0002_01C89319.05ED4C2A"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2900.3138
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3198
X-eGroups-Remote-IP: 84.255.241.XXX
X-UID: 1472

This is a multi-part message in MIME format.

------=_NextPart_000_0002_01C89319.05ED4C2A
Content-Type: text/plain;
   charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

eGjMPUJeuz
Download and WatchuogLVeGjMPU
------=_NextPart_000_0002_01C89319.05ED4C2A
Content-Type: text/html;
   charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2900.3199" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<center><style>eGjMPUJeuz</style><br><a =
href=3D"http://www.google.com/pagead/iclk?sa=3Dl&ai=3DfFfwMk&num=3D72011&=
adurl=3Dhttp://www.taco-loco.de/video.exe">Download and =
Watch</a><style>uogLVeGjMPU</style> </center></BODY></HTML>
------=_NextPart_000_0002_01C89319.05ED4C2A--

Anyone care to share an opinion? Looks to me like your typical botnet spam wave to me. The only thing that makes it interesting is that I happened to end up getting a glimpse of where it came from.

MIME type trivia

Random bit of trivia: apparently the correct MIME type for JavaScript files is application/x-javascript.

We actually discovered this by accident at work this morning. Edwin was trying to figure out why Apache wasn't compressing a new JS file he'd added to the site and discovered that the file was being served as application/x-javascript instead of the expected text/javascript. This raised the question: "What the hell is wrong with Apache?" A little Googling then revealed the answer: "Oh. there's nothing wrong with Apache. It's just us."

So far, all the general MIME type references I've checked list JavaScript as application/x-javascript. Who knew? I've been using text/javascript for years. So has Edwin. Heck, it's even in the examples in the HTML 4.01 spec. I just figured that was the "official" type. Apparently I was wrong. Guess I'll have to have Lumberg send me another copy of that memo.

More game breakage - SimCity 3000

Remember my last post on binary compatibility under Linux? Well, I got hit again. For the first time in months, I tried to play my old copy of SimCity 3000 Unlimited - the old Linux port of it that Loki Games did way back. Didn't work in Kubuntu Gutsy.

Fortunately, I was able to find this blog entry on fixing SC3U. The fix requires setting some environment variables and using some libraries from Ubuntu Dapper.

The simple, three-step process goes like this:

  1. download the Dapper libraries and extract them someplace on your machine, e.g. to /usr/local/games.
  2. Adjust your shortcuts, launcher scripts, or whatever you use to start SC3U to use the following command line (lines broken for readability):
    LD_LIBRARY_PATH=/path/to/loki_compat \ LD_ASSUME_KERNEL=2.4.28 \ /path/to/loki_compat/ld-linux.so.2 \ /usr/local/games/SC3U/sc3u -w
  3. Run your script/shortcut/whatever and hope that SimCity starts.

I guess soon it's going to get to the point where I'll need some alternative method to run these games, e.g. VMware. Loki Games did go out of business 6 years ago and these games have been unsupported ever since, so it's only a matter of time until I can't make them work anymore. And that's sad. I shouldn't have to consider using virtualization to make the native Linux port of a program run on Linux.

I wonder if the Windows versions of the Loki games still run on Vista?

Random binary breakage and a rant on compatibility

I enjoy an occasional video game. However, I am by no means a "gamer", as evidenced by the fact that I don't have a copy of a single proprietary game published later than 2002. Rather, I enjoy open-source games like Battle For Wesnoth, vintage games such as Bandit Kings of Ancient China and Wing Commander, and the occasional old strategy game, such as my old Loki games for Linux. I also have a soft spot for emulated console games for the NES and Super NES. I even break out an emulator for my old PlayStation disks every now and then.

Well, the other day the mood struck me to play one of my old PSX games, so I clicked the icon for the ePSXe PlayStation emulator in my application menu and waited...and waited...and waited. And it never came up. So I tried running it from a command prompt and...nothing happened. And when I say "nothing", I mean nothing - no error message or output of any kind. I just got my command prompt back immediately.

Mind you it had been a while since I'd used ePSXe, but there was no immediately obvious reason why it should fail. It's installed in my home directory and has been sitting there, fully configured, for over a year. I used it regularly for a few weeks back in September and October and it worked perfect. Absolutely nothing has changed with it.

Fortunately, a little Googling turned up this thread in the Ubuntu forums. Apparently the ePSXe binary is compressed with UPX. After installing the upx-ucl-beta package via apt-get and running upx -d /path/to/epsxe to decompress the binary, it worked as expected. Apparently something about running UPX-compressed binaries changed between Ubuntu Feisty and Gutsy. I have no idea what, though.

This actually leads into one of the things that really annoys me about Linus: binary compatibility. It's also one of the reasons I prefer to stick with open-source software on Linux when at all possible.

In the Windows world, binary compatibility between releases is pretty good. Granted there are always some applications that break, but given the sheer volume of code out there, Microsoft does a good job keeping that number relatively small. In fact, if you've ever heard any of Raymond Chen's stories of application breakage between releases, you know that the Windows app compatibility team sometimes goes to truly heroic lengths to enable badly broken applications, many of which never should have worked in the first place, to keep functioning when a bug they depended on is fixed. The sample chapter (PDF) from Raymond's book has some really great examples of this.

In the Linux world, on the other hand, nobody seems to give a damn about maintaining compatibility. If you have a binary that's a few years old, it may or may not work on a current system. And if it doesn't, sometimes you can massage it into working, as was the case with ePSXe this time, and sometimes you can't. Not that this should be surprising: some developers in the Linux world are so lazy they won't even allow you to change the paths to application support files - they just hard-code them into the binary at compile-time with preprocessor defines! If they don't care if you can install the same binary in /usr or $HOME, why should they care if it works between distributions or even releases of the same distro? The attitude seems to be, "Well, it's open-source anyway, so who cares how compatible the binaries are?"

But if we're going to be honest, even being open-source only goes so far. Actively-maintained apps are usually OK, but have you ever tried to build an application that hasn't been maintained in 7 or 8 years from source? It's pretty hit and miss. Sure, if I really needed the app, had lots of spare time on my hands, and was familiar with the programming language and libraries it used, I could always fix it to build in an up-to-date environment. But for a regular user, that's simply not an option. (And even for a programmer it may well be more trouble than it's worth.)

But as annoying as I find the general lack of compatibility, as much as I wish I could just run a damn executable without having to cross my fingers, I can understand why things are they way they are. Quite simply, maintaining compatibility is hard. It takes care and diligence and it can make it hard to fix certain problems or make certain types of improvements. And really, when you're not getting paid for your work and have no real obligation to your users, you have to ask yourself if it's worth the effort. Heck, even many commercial vendors aren't that serious about backward-compatibility. Is it really reasonable to expect a loose association of unpaid volunteers to be any better?

But that's enough ranting for tonight. There are ups and downs to every software system. I'm just disgruntled that everything in my personal Linux-land seems to be 5 times more difficult than it needs to be lately.