http:// www.jms1.net / osx-case-sensitive-fs.shtml

Problems with OS X and case-sensitive filesystems

The "HFS plus" filesystem, which has been Apple's filesystem of choice since the days of Mac OS 8, is normally not case-sensitive- which means that the filenames hello.txt, Hello.TXT, and HELLO.txt all refer to the same file.

Mac OS X version 10.4, or "Tiger" as it's more commonly known, introduced the ability to create an HFS plus filesystem which is case-sensitive (which means that the three names listed above would refer to three different files.)

For me this was a wonderful thing. I do a lot of programming in Perl, and one of the commonly used Perl modules, libwww-perl (or simply LWP) includes a program called HEAD (notice the filename in all capital letters.) There is also a standard *nix utility called head (notice the filename in lowercase letters.) On a non-case-sensitive filesystem, the names interfere with each other, but on a true case-sensitive filesystem (such as the filesystems used by Linux, Solaris, *BSD, and most other *nix variants) there is no problem.

So of course when I installed Tiger on my system, I formatted the disk as a case-sensitive filesystem. Since then I seem to be finding all kinds of programs which simply don't work correctly when installed on a case-sensitive filesystem... and much as I hate to say it, this usually boils down to sloppy programming.

If you write software for the Mac, you should get in the habit of using all lowercase filenames, or all capitals, or some variation- but pick a scheme and always stick with it. You should also test your program by trying to run it from a case-sensitive filesystem before you release it.


BZFlag

BZFflag is an open-source game, similar to the old "Battlezone" video game. You're driving a tank within an enclosed area, along with other players who are also driving their tanks within the same area. The idea is simple- shoot the other guys before they shoot you. The area contains "flags" which, when you roll over them, give your tank a special ability. One variant of the game is called "capture the flag", where the tanks join teams and each team has a flag. Your job is to capture another team's flag and return to your base with it, while at the same time preventing the other team from stealing your flag.

The game itself is rather simple, but it's a lot of fun. I usually play it during the "installfest" hosted by LEAP-CF, the Linux user group here in Orlando.

The first time I tried to play it after installing Tiger on my iBook, it wouldn't run- it told me that the application was corrupted. After a bunch of trial and error, I found and fixed the problem... and came to realize that this problem could become a recurring thing. (So far it hasn't been as wide spread as I had feared, but it's also not something to be ignored.)

Under Mac OS X, an "application" is actually a directory which contains a normal executable, along with a number of other files which relate to the program. These other files can be anything from graphic elements to sound files to icons, but they are all used by the program itself. By creating a "bundle" like this, Mac OS X makes it easy to keep all of the files relating to a given program together.

One of these files is called Info.plist (in the "Contents" directory within the .app bundle, every application has one.) This is an XML file which contains information about the application itself- what icon to use when showing it on the desktop, what version of the program it is, and so forth. One of these entries tells the name of the actual executable for the program. In BZFlag version 2.04, that file looked this:

$ cd /Applications/BZFlag-2.0.4.app/Contents
$ cat Info.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> <string>BZFlag</string> <key>CFBundleIconFile</key> <string>MacBZFlag.icns</string> <key>CFBundleIdentifier</key> <string>org.BZFlag</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>2.0</string> <key>CFBundleSignature</key> <string>BZFL</string> <key>CFBundleVersion</key> <string>2.0.4</string> </dict> </plist>

As you can see, the Info.plist file says that the name of the executable should be BZFlag. However, when we look in the MacOS directory (where the executables are normally kept,) we see this...

$ cd /Applications/BZFlag-2.0.4.app/Contents
$ ls -l MacOS/
total 8264 -rwxr-xr-x 1 jms1 admin 552060 Oct 1 22:25 bzadmin -rwxr-xr-x 1 jms1 admin 2276760 Oct 1 22:28 bzflag -rwxr-xr-x 1 jms1 admin 1400524 Oct 1 22:25 bzfs

On a non-case-sensitive filesystem (like the normal HFS or HFS plus filesystems) the names BZFlag and bzflag would refer to the same file, so no problem would exist... but on a case-sensitive filesystem like mine, the names don't match- which means when you double-click the BZFlag-2.0.4.app bundle to try and run the program, it can't run because it's looking for the wrong executable.

The solution for me was to edit the Info.plist file so it contained the correct filename.

<key>CFBundleExecutable</key>
<string>bzflag</string>

After making this change I am able to double-click the BZFlag-2.0.4.app bundle and run the program normally. (Of course that doesn't mean I'm any good at the game- I still get my butt handed to me whenever I play. I would use the name "Human Target" when playing the game but a friend already uses it...)


SereneScreen Aquarium

Most of us have seen this program at one time or another. It's a screensaver which makes your monitor look like an aquarium, with fish swimming around. It's claim to fame is that it looks very lifelike, and it uses whatever graphics acceleration your computer has in order to update the screen as quickly as possible.

The Mac version includes both a screensaver module and a stand-alone application which lets you watch the fish without having to stop using the computer. There is also a way to run a screensaver module as the desktop- which means that with a powerful enough machine, you can have fish swimming around as your desktop, underneath all of your windows and icons and so forth.

The screensaver has a way to change certain options while it's running. For example, one of the features is a "bubbling" sound in the background, and you can turn this sound on and off by pressing the B key while the screensaver is running. (The default is to play the sound.) The screensaver remembers this option, and if you start using the computer again and the screensaver stops, the next time it starts up it will remember the same "sound or no sound" preference and use it automatically.

However, there is a problem. When the screensaver module is running on a case-sensitive filesystem, it doesn't seem to actually write its preferences anywhere. A screensaver running as the desktop doesn't have any way to capture keystrokes, which means that when I try to activate the screensaver as the desktop, the bubbling noise is in the background and there's no way to turn it off.

I've started poking around inside the program but I haven't yet been able to figure out what the problem is- but I do know that when it's installed on a system which boots from a non-case-sensitive filesystem, it stores the preferences correctly (and the "aquarium dekstop" effect has no noise.)

I have reported this as a problem, the developer of the Mac version has emailed me back to say that he will fix it, but didn't know exactly when it would be ready. I can live without the aquarium desktop for now, and if it ever starts to bug me I'll take another look at it.


Bejeweled 2

Bejeweled 2 is an updated version of the old "Bejeweled" game which has been floating around for several years now. The game started (and is still available) as a web-based game, and then they made a version that people without Internet access could run on their own computer. Of course the first stand-alone version was for Windows, but they later teamed up with MacPlay to develop a Mac version of the game.

I picked up a copy, thinking it would be cool to play when I need to mentally "calm down" from a long session of writing code, and also to see what they added to the game in order to justify adding a "2" to the name. The install was the usual "drag the .app bundle to your Applications folder" routine that we Mac users know and love so well, but when I tried to run the program it started and then showed an error message saying Cannot access image/flash-Loader.

What looked funny to me, and made me think of it being an upper/lowercase issue, was the capital "L" in the name of what it was looking for. I looked inside the Bejeweled 2.app bundle, and found a file with the name "Flash-Loader.jpg" (notice the "F" is capitalized on the disk, but not capitalized in what it's looking for.) I renamed the file to have the same funky capitalization as what it was looking for and tried to run the program again- same result, but this time it was "image/frame"... and sure enough, there's a "FRAME.gif" file.

After about fifteen minutes of renaming files and trying the program over and over, only to find the next thing it couldn't open, it occurred to me that instead of renaming all these files, it would probably be easier to change the list so that IT matches the actual names of the files on the disk.

It turns out this list is in a file called resources.xml within the .app bundle- and the file uses the old Mac OS line ending convention (each line ends with a CR, or ASCII 0x0D, character) instead of the normal *nix convention (ending with LF, or ASCII 0x0A.) I converted the line endings and then used a text editor to edit the lines within the file which needed to be changed. I was right- it was much easier to update this one file than to rename 50 or 60 graphics files (plus a font file.)

Once I got it working, I noticed a few oddities in the game- the "MENU" and "HINT" labels on top of the buttons to the left of the board were the wrong colour, and there was a black rectangle around the blobby thing showing your score and game level (they seem to call this thing the "score pod".) Looking at the images contained in the files and the way the filenames are built, it looks like these items (the MENU and HINT buttons, as well as the score pod) actually consist of two items- a normal image and a transparency mask, which has the same filename with an "_" character added to the end... and if SCOREPOD.gif is the image, the name scorePod_.gif as the transparency mask just isn't going to work.

Here's how I got it to work, along with a download link for the updated resources.xml file.

$ cd /Applications/Bejeweled 2.app/Contents/Resources/properties
$ curl -O http://www.jms1.net/resources.xml
...
$ cd ../images
$ mv scorePod_.gif SCOREPOD_.gif
$ mv Pause_.gif PAUSE_.gif
$ mv Podslit_.gif PodsLit_.gif

As for the new features... the first thing I noticed, even before I got the game working, is that the sound quality of the music is much better than the original game. The same goes for the quality of the graphics- you can tell that their backgrounds were designed for 24-bit colour screens rather than 8-bit colour.

As for the game play... the classic game is still there, with better looking gems and a few new features (exploding gems, magic gems which remove all gems of a certain colour from the board, maybe some others I haven't found yet.) There is a time-based variation on the game where you're racing the clock, and in addition to earning points, every time you make a match it gives you a few more seconds... another is a puzzle variation where each board starts with a fixed pattern of gems and you have to make matches in the right order to clear the board in order to reach the next level... and the last is described as a "never ending" game, which seems to be like the regular game but with an extra routine added to ensure that whenever new gems are dropped from the top, the result will always leave at least one match available.

Other than the problem with the filenames, I'm pretty happy with the game- it was certainly worth the $19 pricetag.