Code!


Last updated: Sunday September 12 2004

I've written lots and lots of code, but I guess it's time to release some of the code that I haven't written in a hurry for public review. I don't know why people have this weird embarassment about releasing ugly code; I think that it's important that we do that so that others can comment on it.

I mean, I write ugly code all the time! I'll be working on some obscure system administration task that I only have to do once in a blue moon, and I execute a command, then another command, then eventually I have a four-line pipeline that I should probably feed into a shell script for later execution, instead of building it up line by line like I usually do. And hoo boy, does that pipeline look ugly. For example:

for i in $(perl -e 'foreach $i (1 .. 30) { print"$i ";}'); 
do echo G$i:345:respawn:/usr/local/sbin/portslave ttyG0_$i;
done

Which was 3 different languages (perl, inittab, and shell) in 3 lines. And the only way it's going to get better is if I release it so people can tell me how I screwed up. Case in point: I'll send you $5 American if you can spot the error in the above. If you tell me about bugs in the stuff below I can't pay you, but you'll get my gratitude, an entry in the CREDITS file, and a beer if you're in the Bay Area or you go to DefCon.

Thanks to my buddy Peter Wang for the spiffy background image.

There's some more stuff in my cvsweb here, including the code I use to do my email signatures.

Perl


template.pl (download source)
template.pl is a template for a generic command-line perl program. It implements getopt and the usual usage() and version() functionality.

cryptmd5 (download source)
cryptmd5 is a program that wraps the unix_md5_crypt() function in the Crypt::PasswdMD5 perl module. You can use it to create password hashes to pass to the Linux useradd command's -p argument, or see if you can tweak the salt to make your password hash to interesting words.

chpasswds (download source)
chpasswds is a program which uses ssh(1) to ssh into some servers and change passwords for you. It works on OpenBSD and Linux, and probably other operating systems with a usermod(8) command that takes the -p flag and supports MD5 passwords. It's pretty robust; it'll print out a list of servers which didn't get the passwords changed after it finishes and escapes the MD5 hashes before executing the ssh command.

create-index (download source)
Create-index is an automatic directory indexer that I use to maintain the directory index on my site.

make-logs (download source)
A tool that I'm using to parse out my master notes file into the various pages on my site. Not complete yet, and I probably won't work on it until my existing system sucks enough to give me a reason to.

howmuch (download source)
A program I wrote to query fi1.net's financial server, which my bank uses for on-line banking.

ariswatch (download source)
This program constantly queries securityfocus to determine the current threatcon level they're reporting via their ARIS service. It pages you when the threatcon level changes, giving you a handle on the state of the Internet.

new-page (download source)
This is the utility I use to create new pages for my web site from the template.

ascii-histogram (download source)
This is a utility to do frequency counts of data. I couldn't figure out how to make it a one-liner, but I'd be interested if you can!

find (download source)
Ever wish you could find all the files that were installed during when you typed "make install" for that package 6 months ago? Well, this utility will find all files which have an inode change time close to a file you specify. Pipe the output to xargs rm for deletion.

mailer (download source)
A dinky cgi to email gateway. Doesn't do taint checks. Use it to impress your "web designer" friends.

Mason


jbtimecard (browse CVS)
This is an employee time clock system I wrote for my good friend John Bodo, who supplies me with nifty hardware. His company's website and email are hosted on the Light Consulting server constellation. It's written in Mason, a pretty robust Perl template system I've used for many projects. You can add/change/delete employees, and get a dump of the employee punch history, including per-hour totals ready to drag-and-drop into Excel.

Win32 Perl


w32odbctest (download source)
This is a simple utility which demonstrates how to query things using ODBC in Windows. It is written against the Extent RBS package, which is a somewhat decent ISP administration package (except their programmers seem to have problems calling FormatMessage() and setting the proper security flags for subprocesses). You'll have to define an ODBC source in Control Panel, of course. Most people don't know that modern versions of Windows allow you to create an empty Access database (AKA an .mdb file) and do INSERT and SELECT on it without having Access installed. In 2000, go to Control Panel->Administrative Tools->Data Sources (ODBC)->System DSN->Add->Microsoft Access Driver (*.mdb)->Create and type in a DSN and description for it. Needs Win32::ODBC. You can either find out why masochists like installing Perl modules under cygwin or you can download the Activestate distribution which comes with it.

w32logs (download source)
This is a Perl utility which uses Win32::EventLog to dump the NT event log in something resembling syslog format on Windows NT/2000/XP. Watch out, I've seen log messages in binary. If you don't have any messages in your log, you can use this simple VBScript to generate one:

dim wsh
set wsh = wscript.createobject("wscript.shell")
wsh.logevent WARNING, "This is a test."

Run it using cscript foo.vbs or by double-clicking on it in Explorer.

CGI


gd_test.cgi (download source)
gd_test.cgi is a simple cgi script which demonstrates how to create a simple graphic using the GD graphics library. You have to install the GD Perl module and the GD DLL for your operating system (Linux RPM or BSD port). The Perl module can be installed with the command "perl -MCPAN -e 'install GD'".

gd_graph.cgi (download source)
gd_graph.cgi is a simple cgi script which demonstrates how to use the GD::Graph perl module to create simple graphs.

Visual Basic for Applications


visio-autoexport.vb (download source)
This is a simple hack I did which causes a Visio document to automatically export PNGs of every page in the document when you save it. There's even a cutesy little progress bar and everything. Just download the code above as well as this and this and import them into the Visual Basic Editor in your Visio document via Tools->Macros->Visual Basic Editor.

Mathematica


DiffPlot (download notebook)
This is a Mathematica notebook which defines a function called DiffPlot, which greatly simplifies plotting slope fields for differential equations and their possible solution curves in Mathematica. To use, just evaluate the cell containing the DiffPlot definition by selecting it and hitting shift-enter, then use say ?DiffPlot to get usage instructions.

Assembly


CMOS Wiper (download source)
This is an NASM source file which assembles to a set of instructions which WIPES YOUR BIOS SETTINGS! This isn't as bad as it sounds, as your BIOS almost always has default settings which it uses in case it detects the CMOS data area is bad, but some computers (like IBM Thinkpads) start to act really funny when their CMOS data area is wiped, so be careful. The main reason you would use this is to wipe your BIOS password in case you forgot it - just write the program to a floppy using rawrite or UNIX dd, and boot off the floppy. You'll get a couple pretty messages and then your computer will tell you to reboot it. I have commercial versions of this utility for use on Windows and in a network boot environment (in case you have to bulk erase the CMOS settings on a whole bunch of network boot capable machines) - contact me for details. Licensing for the windows version is $20, and the network boot environment version is as low as $5 per seat.

C


dbtest (download source) (browse CVS)
dbtest is a shell wrapper around the Berkeley DB 1.85 API. Unlike the tools included with the package, this one is very script-friendly (no extra output, proper return codes) and provides both read and write functions in the same tool. Note that the Berkeley DB 3.x and 4.x files are incompatible with the 1.85 style format, so you'll have to use different tools if you're trying to read one of those (Perl is pretty good at this - see the tie() function).

enummodules (download source)
This program dumps a list of all the modules loaded by a Win32 process. This is useful to see if, for example, AOL's idle DLL is injecting itself into your process without you knowing and causing stupid crashes to happen. Also useful to see what absolute pathnames the system is resolving required module names in the import table to; useful if you're developing something and there might be some ambiguity about which DLL you want the system to import.

blddeps (download source) (browse CVS)
blddeps is an open/open64(2) and stat/stat64(2) wrapper which detects if a build script (like a GNU configure script or make(1)) is seeing if a header or static library exists and automatically installs it with no support from the build script or operating system. This is some really cool stuff - you should check it out if you're a developer or have ever experienced "dependency hell" in Linux. I have an improved version with Solaris pkg and Linux .rpm and .deb support, but I'm thinking of productizing it so I'm only making my proof-of-concept code available on this site.

template (download tarball) (browse CVS)
template is a simple C program template for a console application. It includes the canonical --help and --version GNU options using the getopt_long(3). It includes a Perl script which sets the program name in the Makefile and code as well as a short description for the --help option.

cmosdump (download source)
cmosdump dumps the CMOS RAM area in your machine to standard output. You should redirect it to a file or to 'hexdump -C' or perhaps 'xxd' on RedHat systems. What it's really good for is for figuring out where your BIOS stores which config settings in the CMOS area - just dump, reboot, change settings, dump again, and diff the results. And since your BIOS stores its password information in the CMOS, you can use this as a template for resetting the password in case you forget it and the BIOS reset jumper is in an awkward place (like on a laptop or a remote server). You must compile this utility with -O, since inb() and outb() are assembly macros on Linux, and gcc won't interpret assembly unless you compile with optimization.

pingx (download gzip tarball) (download bzip2 tarball) (browse CVS)
pingx is utility that uses the XNoOp(3x) call to see how fast your connection to your X server. Wonder whether your X performance is slower in a SSH tunnel? pingx can give you hard numbers so you can find out. It has an option to print out some details about the X server as well. It's also useful to see if a destination X server is up so you can fire up x2x or similar applications intelligently.

cdctl
cdctl is a little utility that calls the Linux cdrom driver's API to make your cdrom or dvdrom drive do cool things. Now with DVD support in CVS! cdctl is starting to become rather embarassingly out of date, so I'll do an update within the next few weeks. Promise.

socket_types (download source)
socket_types is a utility I used as part of my socket notes. It prints out the different values and socket types you are able to create on your computer. Runs on FreeBSD and Linux.

bin2asc (download source)
bin2asc is a utility which takes a file with binary numbers in it ("01010011\n01010111" etc etc) and prints out their character representations. Good for reading the binary output that nitrozac produces every once in a while.

perf (download source) (download executable)
This is a simple Win32 utility I use to figure out whether a machine has support for the high-resolution performance counters necessary for microsecond-level timers in user land. It just calls the QueryPerformanceFrequency() Win32 API and throws up a dialog with yay/nay and some statistics. One interesting thing I discovered is that the counter values halt and persist across hibernation cycles. UNIX guys can use this as an example of how to replace gettimeofday(3) in Win32 programs.

wintemplate (download source)
This is the usual Win32 GUI template / skeleton code every programmer has floating around their toolbox. It implements WndProc and WndMain. What makes this one nice is there's a fatal() which calls FormatMessage and tosses up a MessageBox with the results if something goes wrong - great for cutting and pasting into other applications. It doesn't use MFC.

fparray (browse CVS)
This is a really over-engineered floating-point array library I used to see if the new -msse and -mfpmath=sse options to gcc really output sse and sse2 instructions. It turns out that it does, and whooooo are they fast. And I mean fast - I'd have a tough time beating the compiler if I wrote the procedures in assembly myself. I don't think there's a project out there that couldn't benefit from using these new features... who wouldn't want 128-bit vector register support? :) Now I know why everyone is saying such good things about the Intel compiler's floating point support. I had plenty of time on my hands when I did this, so it has full Doxygen headers and a really good error handling system, good enough to use as a template in other projects. It also does __attribute__(format(printf)) in the error handling system, so it catches things like feeding integers to %s in the printf(3) format strings you pass to array_log(), the error output function. You ever wonder how printf(3) outputs those error messages saying things like "moron.c:4: warning: format argument is not a pointer (arg 2)"? It's the __attribute__ macro. The nice thing about the way the GNU guys did it is that you can easily redefine it to a no-op on non-GNU platforms, so it doesn't interfere with your builds for proprietary platforms.

threadtest.c (download source)
This is a simple threading skeleton / template with SIGSEGV segmentation fault handling and backtrace support on glibc-based platforms. I munge this every once in a while to test different things, so it might do something rather interesting if you try it today.

bin2c (download source)
bin2c reads a file and dumps the output in hex in a format suitable for inclusion into a C source file (for statically populating an array with data, for example). This only compiles on Linux, although porting to other Unices (or cygwin) should be easy. I find it comes in handy for hard-coding 'correct' test result data for unit test programs that have to compare the result of a test with the right answer. For example, you could do this in a bourne-type shell:

echo 'static unsigned char mydata[] = {' >> source.c && \ echo $(bin2c mydata.bin) >> source.c && \ echo '};' >> source.c

portability.c (download source)
This is a simple portability test for POSIX compliant operating systems. It outputs the following:

It's useful to get a handle on a new platform quickly without a lot of fuss.

hadamard.c (download source)
This is a simple recursive Hadamard matrix generator. Hadamard matrices have the interesting property that 50% of the bits each row are different from every other row. A sequence of bits encoded as rows from a Hadamard matrix can therefore survive single or multibit errors because a given sequence of bits can be unambigiously resolved to a row in the Hadamard matrix, and from there turned into the original sequence of bits.

Hadamard matrix encoding is very expensive, though. This version defaults to a 32 bit row and height; since log2(32) = 5, each group of 5 bits turns into 32 bits - a 640% expansion rate.

masmtsc.c (download source)
This is some example code which shows how to read the TSC register on modern Intelish chips. The TSC register initializes to 0 when the processor boots, and increments by 1 during every clock tick. You can query the TSC register for very fine-grained performance analysis, suitable for determining cache latency during loads and stores and other low level things like that. This code contains the assembly part in both gcc and MASM format, so it should compile on pretty much everything: watcom, icc, VC++, gcc, etc.

beancounter.c (download source)
This lets you do resource accounting on subprocesses on various unixen. This lets you do things like run "ls" or "perl" and see how many page faults are triggered, how much system and user time is used, the number of signals received, the number of context switches used, etc etc. Think of it as a more powerful version of the "time" builtin provided by most bourneish shells. Linux doesn't completely fill out the rusage structure returned by wait4(), which is used to gather the accounting data, so be wary there. Just give beancounter the program to run as its first argument to use it.

C++


Seraph (browse CVS)
This is the message processing code I use for Seraph, my network management system. The management UI, OS-dependant bindings, and other stuff to actually make it do something useful is deliberately not included in here because of the DMCA and other silly laws which I sincerely hope will be repealed. There is some useful stuff in here anyway - there's a rather nice C++ linked list class (similar to the GNU glib GSList APIs), some low-level socket glue, an example of how to use strtol() safely (because atoi(3) doesn't differentiate between "0" and "that wasn't a number"), and some other neato networking stuff. When the DMCA gets repealed, I'll post the whole thing and put the OpenNMS guys out of business :)

RationalNumber (browse CVS)
RationalNumber is a silly little class which I wrote for a C++ class in the back of my van one afternoon because the power was out at my old place in Fremont. It was kind of cool working at the emergency console in the van with all the batteries and computers humming.

Anyway, it serves as a good example of how to do operator overloading and lowest common denominator math as well as some other random operations on fractions.

Array (browse CVS)
Array is another program I wrote for a C++ class I took. Thanks to that self-enriching exercise, I now have the ability to say really bad things about the C++ template feature. But one day I'm going to have to use it and I'll have to dig this program up to remember how to get started. Hint: neither GCC nor MSVC are able to deal with resolving member functions of a template class if the member functions are outside file scope of the template class definition.

virtualtest1 (download source)
This is a simple demonstration of how virtual destructors work in C++ and why they're important to have in derived classes. There's a lot of confusion among C++ programmers (myself circa 3 years ago included) about how virtual functions work, and this should serve as a starting point for learning about the more esoteric aspects of this feature of C++. Personally, I'd prefer to have this stuff happen automagically behind the scenes without having to have the programmer think about it, but the "the programmer should be in full control" camp would lynch me if I proposed a change to the language committee at this point...

Java


CoaxImpedance (view applet) (download source)
This is a simple Java 1.1 applet to calculate the impedance of a coaxial cable given some parameters.

ZeroWing (view applet) (download source)
This is some Java 1.1 eye candy. Bugs: should be multithreaded with 2+ writer threads, background color should be configurable, and boundary detection seems to be broken so some messages fall off the edges. The font size info I get from the JVM seems to be a little different from platform to platform, I need to investigate that some more by adding an option to draw message boundary boxes.

Rollover (view applet) (download source)
This is a simple Java applet which tells you how long you have until your Unix system will think it's 1969 all over again. If you're lucky enough to have a Unix with a 64-bit time_t or an unsigned 32-bit time_t, then this will be (thankfully) wrong. Need a 1.1 or better JVM.

TinyBrowser (download source) (download class)
This is a simple wrapper around the JEditorPane swing widget. Turns out that swing includes a mostly featureful HTML 3.2 browser, and this enables you to poke around the web with it. There's no back button yet. Requires Java 1.2, will probably work better with 1.3 or the 1.4 beta JRE or SDK. Must be run as an application. Believe me, you don't want to have to try to cram a web browser into an applet and deal with the security manager. If you end up in that unfortunate situation, go search the Internet for "java policytool" and "java.net.SocketPermission" for information on how to allow appletviewer and the java plugin to talk to sites besides the one where you got the applet.

Cccp (view applet) (download source)
Want to know what's happening in the world? Itching to get that news fix but don't have a TV / capture card / radio? The CNN Closed Captioning Protocol is your answer! This is going to be an applet which knows the Cccp protocol and can connect to a Cccp repeater (running on lightconsulting.com's server) which will feed the CNN closed captions down to the Cccp client. CNN has an IRC server at chat.cnn.com:7000 which has a channel named #cnn_newsfeed. Inside that channel is a bot which repeats the CNN closed captions most of the day. I'm writing a daemon which sits on my server and translates those IRC messages to Cccp messages which get fed to clients who ask for them. I had to learn Java socket programming first (why doesn't InputStream something like the available() method but with error conditions??), so it's just getting started.

BayonneMon (download source)
This is a simple application which listens for broadcasts from GNU Bayonne and reports the line status for each machine. Much better than the bayonne_status console tool. You must configure your bayonne.conf with the correct broadcast address for your network; bayonne isn't smart enough to figure it out.

BUGS: layout (should have more obvious grouping), doesn't remove machines it hasn't heard from in a while, doesn't translate the bayonne line codes to something human-readable.

Bourne Shell


vinumprep.sh (download source)
This is a script to auto-partition and auto-label a virgin disk in preparation for inclusion into a FreeBSD vinum plex. It is really only useful for FreeBSD machines. It's pretty dangerous because it doesn't check very hard for any existing data on the disk before wiping it, other than to see if it's mounted. Please be careful with this, as you would with any auto-partitioning tool. It's a good idea to tag any drives with data you'd prefer not to lose with little colored stickums when playing with tools like this, that way there's less chance of plugging an important disk from your pile into your testing boxes. For the hardcore geeks, this includes an example of how to do a combination of here-documents and a ed(1) script to programatically edit a text file.

dumppkg.pl (browse CVS)
This dumps the Solaris package database in a line-oriented format, better for feeding to sort(1) and awk(1). One thing it's especially useful for is figuring out which packages are taking up the most space on your Ultra 5 with a 4 GB drive. To get a list sorted by size, say "./dumppkg.pl | sort +0" and the last few lines are your culprits.

varnish (browse CVS)
This is a tool which I use to help port patches generated against an older tarball to a newer tarball. It's mostly automatic, but assumes your project is in a tarball with a single top-level directory. What it's really great for is cleaning up patches for a RPM when you bump the version on the upstream tarball - this usually results in a bunch of broken patches. This tool changes this usually horrible situation into a simple matter of bumping the version number in the spec file and running varnish - all the patches will automagically be generated so they apply perfectly against the newer tarball (and it even ignores whitespace errors).

autologin.s (download source)
This is a shell script I wrote to copy my ssh public keys to a remote system. It has been superceded by the ssh-copy-id tool included with the latest openssh distributions. You should only need to use this if you are doing work on an older system. Even then, you should think about upgrading, as there have been published vulnerabilities in the ssh 1.x protocol.

mkboot.sh (download source)
This is a simple script to create a Linux boot and root disk from a kernel image and a directory containing the mini filesystem to put on the disk. Note that this does this WITHOUT LILO! The script manually determines the size of the kernel and uses rdev to program the kernel image on the floppy with the location of the start of the compressed filesystem image. It should work without problems if you have a fairly modern Linux environment, such as Debian 2.2 or above. Also note that when you construct the boot image, you really should have at the very least these files if you want the boot floppy to do anything useful:

Also note that glibc 2.2.x is HUGE! I can't seem to get it to compile down to anything less than 1.1 megs for 2.2.4, and 1.2 megs for 2.2.5. The LRP folks say that they're using 2.1 instead for space reasons. Another option is to use NFS to mount a root filesystem from somewhere on the Internet to get the necessary space - an NFS enabled kernel is really quite small, like around 540KB for a customized 2.4 kernel.

Other Stuff


winner.spec (download source)
This is a simple RPM spec template for when your project is big enough to need RPM packages. It's best to refer to the RPM source for more information since the RPM-HOWTO is quite out of date and the rpmdp.org guys seem to have forgotten to pay their DNS bill. You can get to what's left of their web site at 216.228.140.176 if you want.

rhsysv-skeleton (download source)
This is a SysV init script skeleton for modernish RedHat distributions. You can use it as a template for creating your own SysV init scripts if you're packaging something for RedHat or you need to SysV initify some program.

susesysv-skeleton (download source)
This is a SysV init script skeleton for older SuSE systems. It's based on the init script for sendmail from SuSE 7.1.


Home | Site Index | email me