magicfilter is an extensible and customizable automatic printer filter. It selects an appropriate conversion technique for the input data by seeking for magic numbers, and then utilizing the appropriate conversion utility.

magicfilter is primarily intended for use as the “input filter” by the lpd print spooler. The options accepted by magicfilter are exactly the ones passed to the input filter by lpd (unless you build it on a LPRng system — in that case, magicfilter accepts no options.)


Magicfilter 2 is a complete rewrite of H. Peter Anvin’s Magicfilter 1.2, using slightly more standard components. It has the following features:

Source Code

version 2.3.i
This is almost as trivial as 2.3.h, but not quite; the reasons for 2.3.i are that I needed to rename getline() to getrule() to compensate for gl*bc, and I had to modify some of the internals of to deal with the extra-gnuified toolset in MacOS 10.5.
version 2.3.h
2.3.h is the most trivial release there ever was; for some inexplicable reason, I’d put two DEVICE lines on the dj500 def file, which broke it. This release strips the additional DEVICE line out (sigh).
version 2.3.g
All 2.3.g does is clean up the install when a system libmagic exists; when I last reworked the install rules I managed to break them so a “make install” would error out on me; It’s not much of a release, but changing things so that they build is probably a good reason to roll the software.
version 2.3.f
This release properly detects versions of libmagic that require libz to link, and cleans up some of the text in the magic patterns. It’s only a release because I made these changes last fall, but forgot to put them into version control until I got around to examining some (unreproducable) bug reports this last week.
version 2.3.d
This is a patch release for printer job language files; when I wrote magicfilter 2, file(1) identfied pjl as pjl or printer job language (pjl). Well, that’s not the case any more, and now that I’m encouraging the use of libfile instead of the version of file I ship with magicfilter, that means there are a lot of people out there who might be unpleasantly surprised by unexpected output to their printers. I’ve also cleaned up some of the rough edges on the magic.m4 file, so that text printing might actually work properly when TEXT is defined as FALSE, or when it’s routed through a PRINTER.
version 2.3.c

Tim Johnston reported a bug trying to build on Mandrake Linux 10.0, which uses gcc 3.3. When magicfilter is built on a system that uses lprng, it includes code that unsets the various magic environment variables that lprng passes around.

Part of this code is this simple (if somewhat gross) #if switch that sets up the proper sort of unset depending on whether your machine has unsetenv() or putenv():

#   define UNSET(x) unsetenv(x)
#   define UNSET(x) putenv(x ## "=")

This code works with gcc 2.95 (and gcc 2.7, but I don’t think there’s anyone who uses that code except me anymore). But apparently the people who “maintain” (for lack of a sufficiently profane better word) gcc have changed the way token pasting works in the preprocessor for gcc 3.3.2. Changed, in this case, means broken; so I’ve ripped this code out and replaced it with an even grosser version that doesn’t use anything experimental like ANSI token pasting.

version 2.3.b
The system libraries on modern versions of Linux has mutated to the point where libfile doesn’t build because it can’t find errno anymore. To corrects this feature, offending modules in libfile now #include <errno.h>. Other than compiling on recent machines, there are no changes of note in 2.3.b.
version 2.3.a

magicfilter 2.3 has the libfile code rewritten to look like the new libmagic in recent versions of file(1). If you’ve got a recent copy of file(1), magicfilter will use that one instead of the copy that’s included in the tarball, but if you don’t have a recent copy, I don’t want to have to carry around two separate interfaces that do the same thing.

The configuration process also builds a script which attempts to make directories without erroring out if the directory exists but isn’t owned by you (on some versions of Linux, mkdir -p chokes when a directory exists but isn’t owned by the caller. This has some unfortunate side effects, which don’t interact well with GNU make (which, in the grand tradition of Unix, is close to but not completely compatable with the BSD make that I use on FreeBSD and Mastodon Linux.)

On the bugfixing front, magicfilter now uses the the $PATH that was given when it configured everything.

Older versions of the code are still available.