ACME Updates

What's new at ACME Laboratories!

26nov2016 mini_httpd 1.26 (permalink):
This fixes a long-standing bug on FreeBSD using http but not https. Files were getting truncated at 1MB. This was due to improper usage of sendfile(2), and not testing the http path since I only use mini_httpd for https. Since Linux has a completely different sendfile(2) call, it was not affected. And since https does not use sendfile(2), it also was not affected.

New tarfile available on the mini_http web page.

21Jun2016 Space War (permalink):
Back in 2007 I wrote a version of the classic Space War game in JavaScript. It used sprites for graphics, which worked ok but was complicated and inflexible. Since then, web browsers have gotten good support for HTML5 Canvas, a way to draw arbitrary graphics on a web page. I adapted my old Space War code to use Canvas instead of sprites, and it looks great! Try it out.

11jun2016 Zoom5 (permalink):
Google's map API folks decided to get rid of the slider-style zoom control. I thought about re-implementing it, and actually made a pretty good prototype, but then I had a different idea. How about in addition to the standard +/- buttons, an extra pair of +5/-5 buttons that zoom five steps at a time? This turned out to be very simple to implement. It's called acme.maps3.zoom5.

10May2016 mini_httpd 1.24 released (permalink):
New version of mini_httpd to fix an obvious and serious bug in binary POST request reading.

09Mar2016 DROWN (permalink):
Stored out new versions of all my SSL-capable programs - mini_httpd, http_get, http_post, http_ping, xmlrpc - with SSLv2 disabled to prevent the "DROWN" attack. SSLv3 had already been disabled in February 2015 to prevent the "POODLE" attack.

28Dec2015 mini_httpd 1.23 released (permalink):
I made a new version of mini_httpd to fix CVE-2015-1548, a buffer overflow via snprintf.

20Oct2015 self-overlapping strcpy() (permalink):
I recently got a bug report about mini_sendmail involving some string corruption. The reporter had done an excellent job of tracking down the likely cause: using strcpy() on two strings that overlap. Turns out this is undefined. See the C89/ANSI C standard, section
If copying takes place between objects that overlap, the behavior is undefined.
and also section A.6.2, in a huge long list of undefined behaviors:
- An attempt is made to copy an object to an overlapping object by use of a library function other than memmove
My code uses overlapping strcpy() all over the place, typically for eliding a substring. E.g. to remove the first character:
strcpy( str, str + 1 );
Apparently I'm supposed to use this instead:
memmove( str, str + 1, strlen( str + 1 ) + 1 );
The memmove() version is ugly and takes twice as many CPU cycles, but it's "standard".

It's likely that the string corruption is not actually due to a strcpy() implementation copying the bytes in some weird order. It's implausible that a strcpy() implementation has ever been written or will ever be written that doesn't just copy bytes from the beginning of the source string until it finds a NUL. I suspect the problem here is more like a compiler optimiztion taking advantage of the guarantee that strcpy()'s args do not alias each other.

Self-overlapping strcpy()'s behavior is not actually undefined, it's precisely defined. It always works when copying backwards, and it always fails when copying forwards. Every version of strcpy() behaves this way, and always will. Calling it undefined behavior doesn't improve anything, and does break lots of existing code going back decades. A typical standards committee botch.

Anyway, I grepped through a couple hundred kilolines of code for self-overlapping strcpy() calls, and found & fixed a couple dozen. I've stored out new versions of mini_sendmail, thttpd, mini_httpd, coords, sfcmilter, and xml2c.

16feb2015 Precedence Day (permalink):
Merry Precedence Day!

12feb2015 All The Milters (permalink):

I updated all my "milter" mail filtering plugins for ACME's new OS:

The changes include conforming to the current milter API, updating the FreeBSD rc.conf startup scripts to modern standards, and a new data structure for storing IP addresses that handles IPv6.

The new data structure is actually pretty interestng. The previous version was a four-dimensional sparse array - four because IPv4 addresses have four octets. Netmasks were handled by special pointer values. Expanding that to handle IPv6's 16 octets would have meant a fourfold increase in code complexity. Instead I re-wrote it as a hash table. Handling netmasks / prefixes in a hash table was not simple, and handling prefix lengths that are not a multiple of 8 bits was an additional complication. But I managed it and it all seems to work perfectly.

06feb2015 new hardware (permalink):
ACME is now running on new hardware, a nifty eight-core Atom C2750 machine that I built myself. There are still some glitches to solve internally but external web and mail service seems to be working just fine.

Here's a table showing the evolution of ACME's hardware:
name when type CPU memory disk OS cost
hydra 06Feb2015 - ? home built! 8-core 2.4 GHz Atom C2750 16 GB 5.1 TB FreeBSD 10.1 $1370
safe 01May2004 - 06Feb2015 Fine Tec Computer 3.2 GHz Pentium IV 2 GB 200 GB FreeBSD 4.9 $1689
pill 17Mar2004 - 01May2004 Packard-Bell 450 MHz Pentium II 160 MB 60 GB FreeBSD 4.5 $?
bomb 25Nov1999 - 17Mar2004 ACME Microsystems 450 MHz K6-2 64 MB 8 GB FreeBSD 3.3 $665
best 03Nov1995 - 25Nov1999 shared server 200 MHz Pentium Pro ? 70 MB FreeBSD 2.2.8 $50/month
anvil 17Apr1991 - 03Nov1995 Sun 3/50 16 MHz MC68020 4 MB 1 GB SunOS 4.1 $1950

26jan2015 newmail (permalink):
While setting up my new server (news on that soon), I noticed that I no longer had source for the "newmail" program. This was a simple mailbox watcher that was included in the "elm" mail client from back in the 1980s. Rather than edit my .login to use a different mail watch program, I wrote a new version of newmail from scratch.


16sep2014 Three Foot Passing Law (permalink):

Some Q & A about California's new Three Foot Passing Law, CVC 21760, which goes into effect today, September 16th.

Q. Where is the three feet measured from? The centerline of the bicycle?
A. It's from any part of the bicycle or rider to any part of the motor vehicle. So for example, from my elbow to your side view mirror.

Q. What if there's not enough room to pass with three feet of space?
A. Wait until there is.

Q. WHAT? You want me to WAIT? A few SECONDS??
A. Yes.

Q. Can I at least throw a tantrum while I wait?
A. If you like.

Q. Can't I slow down and squeeze past if I'm really careful?
A. Well, hmm, maybe. Subsection (d) seems to say something like that, although it's pretty vague. Tell you what - try it and see if you get cited!

Q. Isn't there something about I can cross a double yellow line to pass a cyclist?
A. No. Some of the six previous versions of the bill had such a provision. Those versions were vetoed. The version that became law does not include an exception for double yellow lines.

Q. Does it also apply to passing motorcycles?
A. No, only bicycles. Knock yourself out. Or knock the motorcyclist out. Whatever.

Q. Does it mean bicycles must also stay three feet away from cars?
A. No, it only applies to motor vehicles passing bicycles. When you are stuck in traffic, bikes can still lane-split past you.

Q. That doesn't sound very fair.
A. Tough.

Q. What's the fine?
A. It's Thirty Five Dollars. Thirty Five Big Ones. Thirty Five Dollaroonies. Oh and if you actually hit a cyclist and cause an injury, the fine goes up to $220!

Q. Hey, does that mean I can now hit a bicyclist, pay $220, and get away with it? That sounds like kind of a good deal!
A. ....Um....

14aug2014 More Clangification (permalink):

I pushed out new versions of all but one of my C/C++ packages. A few more clang-related fixes and cleanup in every package. The exception was pbmplus, I've still got a few minor fixes to make there.

24jul2014 Fixr (permalink):

I've written a Flickr API app that includes a couple different fixes to inadequacies in Flickr. You can pick and choose which ones you want to enable. Current offerings:

Geotag Interoperation
Standard geotags look like this:
geotagged geo:lat=37.88185 geo:lon=-122.29556
When Flickr first implemented maps back in 2005, they used this standard format. Later they switched to a non-standard custom system. If you prefer to use the standard tags, this fix automatically copies them to Flickr's system every night.
Set Sorting
All image sequences throughout Flickr are shown with the newest image first and oldest image last, with one exception: sets. Sets get new images added at the end, instead of the beginning. If you don't like this inconsistency, you can reorder your sets every time you add to them, but that gets tedious. This fix automatically reorders your sets every night.

Here's the URL:

19jul2014 ChuMaker Update (permalink):

I took a break from clangification to do a little update to the ACME ChuMaker. Now the images are 60% larger.

16jul2014 Clangification (permalink):

After three weeks or so I'm getting down to the short strokes on my clangification project. Out of an initial couple of hundred packages I'm down to five.

All the rest now build cleanly with clang! I've also updated all the corresponding web pages to be HTML 4.01 compliant.

25jun2014 FreeBSD 10.0 (permalink):

I am finishing off my first FreeBSD 10.0 install, on my new desktop machine. I thought I'd post some notes here.

The hardware is an HP Pavilion 23 "all in one". Nice big screen, four core CPU, 500GB disk. $500.

The first problem I ran into was that it wouldn't boot from the install media. This was "Secure Boot" in action. I had to figure out how to get into the BIOS settings page (ESC while booting), disable Secure Boot, reboot, enable Legacy Boot, then boot into the install.

The second problem was that after the install process completed, the BIOS claimed it couldn't find anything to boot. I asked around and guessed the problem was the HP BIOS couldn't deal with GPT, so I redid the install with old-style BSD Labels partitioning. That was more complicated than it should have been because the 10.0 installer switched from sysinstall to bsdinstall and the partitioning page is just different enough to confuse old-timers like me. I ended up doing something ridiculous: starting a 9.2 install, partitioning using good old sysinstall, quitting, starting the 10.0 install, and skipping the partitioning step. Anyway, it worked.

After that things went pretty smoothly. I installed rsync from ports, Xorg and Firefox from packages, and everything is running pretty smoothly. My remaining issues list:

24may2014 countdown (permalink):
I added a new little program to the ACME freeware collection. It counts down a specified time interval. I use it mainly as an egg timer.


13may2014 Overheated (permalink):
We had a heat wave predicted for today. It didn't actually get that hot - except inside I got home at 9pm and a motherboard alert tone was going. Opened up the case and the problem was obvious - a wire had gotten caught in the CPU fan and stopped it. I moved the wire away, the fan started, and the alert tone stopped.

Here's the CPU temperature graph. Looks like it didn't get hot enough to fry.

As for why the wire moved, I found a rotted rubber band at the bottom of the case - time and temperature did it in. Tie-wraps are much better.

22nov2013 New Map Versions (permalink):
I have installed new versions of all the ACME maps. This was necessary because Google finally retired version 2 of their Maps API, so I had to switch everything to version 3. I resisted switching as long as possible because version 3 seems much slower, but the time has come.

Most of the code conversions were fairly simple, but ACME Mapper took a few extra days since it is by far my most complicated map.

I bumped Mapper's version number to 2.1 - if you are still seeing "ACME Mapper 2.0", you have the old version. Try clicking Reload and see if that gets you the new one. If you use other maps such as Planimeter or Two Maps One Scale, you may also need to click Reload to get the new one.

26jun2012 Denial of Service (permalink):
Some of you ACME fans may have noticed poor response times on the web site for a couple weeks. You were not imagining it, and it wasn't just you. was undergoing a denial of service attack. It started early in June and lasted two weeks, on and off.

The attack consisted of a flood of UDP DNS packets from a variety of source addresses, all asking for any records associated with the name RIPE.NET. does not provide DNS service and never has. The DNS port is closed, the packets did not get in, they were just dropped. Nevertheless, the sheer volume clogged up the internet connection and made it hard for anyone else to use it. You can see the effects in the graphs on the right, as dropped packets and increased round-trip times.

Attacks like this are fairly common on the internet these days. I heard through the old-skool hacker grapevine that other sites got hit with similar attacks around the same time. They are trivial to block, but because in my case the limiting resource is my internet link's bandwidth, I needed to block the attack on the upstream end of the link. That's when I ran into problems.

I called my ISP's tech support line. I told them about the attack, and laid out two simple measures they could use to block it. Those were literally the first three sentences out of my mouth. Either of the block methods would take me five minutes to accomplish, so I figured an ISP's tech team should be able to accomplish the same in a day or so.

After two weeks of daily phone calls and email exchanges, my ISP had not managed to do anything. The last email from them indicated they were about to do the exact wrong thing, disabling the wrong one of my two IP addresses. Luckily for me, that's when the attacker lost interest and decided to go harass someone else. All that was left for me to do was make sure the ISP trouble ticket indicated that the attack had ceased and they should not do anything.

I had already been thinking about upgrading my internet connection. This incident raised the priority of that task. More bandwidth might have lessened the severity of the attack, and I would definitely like to dump my current ISP over their handling of this. I am considering three options:

Your input is welcome.

01apr2012 Ok, ok. (permalink):
Hah hah, April Fool. I'll turn the color back on now.

Actually I needed to re-make all the photos anyway, because I increased the size of the images from 576 pixels to 640 pixels. So I did it twice instead of once. Took over five hours each time!

01apr2012 New image-processing algorithm (permalink):
Flickr deploying the Atkinson Dither today got me interested in the subject of image-processing algorithms. I read about another nifty technique called Floyd-Steinberg Error Diffusion, and immediately applied it to all my photographs. The results are amazing! Check it out:

06feb2012 Welcome Back AdSense (permalink):
Last week I blogged about how Google AdSense had cut me off, sending two form letters with no specifics. I appealed, and they denied the appeal. I had no idea what was going on, and AdSense wasn't saying.

People had a bunch of theories for why AdSense disabled me.

Personally, I took AdSense at their (form letter) word, that the reason was invalid clicks. But you can see how the lack of specific information caused folks to go a little bit crazy, assuming malevolent intent and/or stupidity on Google's part.

My post about this went a little bit viral on Google+. Lots of comments, lots of re-shares. Maybe half the comments were from other former AdSense partners saying they had gotten the same form letters.

I want to highlight two of the comments. First, by Matt Cutts, head of the webspam team at Google:

I can't easily imagine Jef Poskanzer was click-spamming AdSense, while at the same time I trust the judgment and abilities of the AdSense team.

Another Google+er, Viswa Vutharkar, said this:

Take this example scenario. Someone who hates created an elaborate bot net or somehow influenced some legion of their followers to simply visit acme website and click on ads willy nilly. Its no fault of acme.

Anyway all the attention on Google+ got the AdSense folks to re-re-review my case. The attention did not affect the outcome, it just got me a third chance, which I am very grateful for. And the result was, I was reinstated. Yay!

So the first thing I did after my account was turned back on was to go look at my stats. That's when I found out that AdSense had been absolutely right to flag my account. There was a big bulge in the stats between late November and early January. Views remained about the same while clicks rose by about a factor of eight. I had nothing to do with it, of course. But AdSense has to defend itself and its advertisers against stuff like this.

However. The way AdSense defends itself is, I think, poor. As we saw above, the lack of specifics makes people play crazy guessing games. It detracts from Google's reputation for trying to do the right thing. And by dumping long-term partners like ACME instead of working with us to solve the problem, it is unprofitable.

I have three suggestions to improve the process.

  1. Add a step between 'fully enabled account' and 'completely disabled account'. Some sort of 'limbo' where ads are not running but the publisher still has read-only access to the web site so they can see their stats.
  2. Send publishers an email alert when the fraud filters start seeing something bad, instead of waiting a month and a half and then disabling the account.
  3. Open up an authenticated API for automated fetching of AdSense publisher stats. Then publishers could do their own automated analysis and generate their own email alerts on unusual activity.

I remain, for now, a happy AdSense publisher. And if we go another round and I get disabled again, well at least now I know more about what's going on.

30jan2012 Goodbye AdSense (permalink):

I have been using Google's AdSense web advertising system since it opened to the public, eight and a half years ago. Aside from one quickly-resolved incident eight years ago, Google and I have been very happy with each other and have made a lot of money for each other.

Two weeks ago I got a form letter from AdSense telling me that my account had been disabled. The letter explained how I could file an appeal, so I did. This morning I got their response to my appeal: denied. That would seem to be the end of my relationship with AdSense.

Other folks dealing with AdSense might be interested in the details, so I'll post them below. But there's really not much, the form letters are nearly devoid of information. This is intentional - the first item in AdSense's Disabled Account FAQ says:

Q. Why was my account disabled? Can you tell me more about the invalid click activity you detected?
A. Because we have a need to protect our proprietary detection system, we're unable to provide our publishers with any information about their account activity, including any web pages, users, or third-party services that might have been involved.

Wikipedia's page on AdSense includes a section of criticism with this paragraph:

According to critics, AdSense is one of the worst publisher programs who really don't care about its publishers. Many cases were reported about the accounts being disabled once a publisher reaches the minimum payout amount of $100. Publishers will only get an automated email which says that their site is a threat to the advertisers and other publishers. The email contains a link to the help forum which is unlikely to get the account reinstated, even if their account was disabled in error. About 99% of affected publishers say that their account has not been reinstated, and they believe that the termination was done in error.
I don't agree with the rest of the criticism but this part would appear to be both correct and alarming.

Here's the relevant part of the initial form letter:

Date: Sun, 15 Jan 2012 18:43:23 -0000
From: "Google AdSense" <>
Subject: Google AdSense Account Disabled


After reviewing our records, we've determined that your AdSense account poses a risk of generating invalid activity. Because we have a responsibility to protect our AdWords advertisers from inflated costs due to invalid activity, we've found it necessary to disable your AdSense account. Your outstanding balance and Google's share of the revenue will both be fully refunded back to the affected advertisers.

Here's my appeal, with my responses in italics:

Jeffrey Poskanzer

Company's name (If applicable):
ACME Laboratories

Example URLs where you've placed your ads:

Date your account was disabled:
15 January 2012

Have you appealed the disabling of this account in the past?

Do you have any other active AdSense accounts?

Who are the intended users of your site?
software developers, map users, photographers

From what parts of the world do your users view your site?

How are your users accessing the web? (e.g. Internet cafes, home DSL lines, mobile devices, university / office intranets)
no idea

Does your site content include content copied from other sites on the web (not including RSS feeds)?

What is the source of your site's content?

How many people are involved with the administration of the site?
just me

How often do you update your site?

Have you ever purchased traffic to your site(s)?

Have you ever signed up for services that give users incentives to visit your site/ads? (e.g. auto-surf, pay-to-read, pay-to-click)

How do users get to your site? How do you promote your site?
My site is very well known, with links all over the net.

Why do you believe the traffic to your Google ads is valuable to advertisers?
I provide excellent and highly-respected services andsoftware.

Would visitors to your site have any reason to increase your AdSense earnings? If so, why?

Have you or your site ever violated the AdSense program policies or Terms & Conditions? If so, how?
In 2003 and 2004 there were a couple of incidents where ads on one of my software projects' pages were considered borderline invalid, because of how users were getting to those pages. We resolved the situation by removing the ads from just those pages. In the eight years since then the Google-ACME relationship has been very happy.

Any relevant information that you believe may explain the invalid click activity we detected:
I have no idea why your detector triggered.

Any data in your site traffic logs or reports that indicate suspicious IP addresses, referrers, or requests:
I took a look and saw nothing unusual. If you give me some hint of what to look for, maybe I could be more helpful.

Here's their acknowledgement of my appeal:

Date: Sun, 15 Jan 2012 19:40:52 -0000
From: "Google AdSense" <>
Subject: Re: [#946896951] Invalid Activity Appeal


This message confirms that we've received your appeal submission.

We'll get to your appeal as soon as we can, though due to the high volume of emails we receive, it may take us up to a week or more to process it. If you've previously submitted an appeal for this account, you might not receive a response to this or future appeals.

Also, please be aware that appealing the disabling of your AdSense account does not guarantee that it will be reinstated.

And here's today's response to my appeal:

Date: Mon, 30 Jan 2012 11:19:47 -0000
From: "Google AdSense" <>
Subject: Re: [#946896951] Invalid Activity Appeal


Thank you for your appeal. We appreciate the additional information you've provided, as well as your continued interest in the AdSense program. However, after thoroughly re-reviewing your account data and taking your feedback into consideration, our specialists have confirmed that we're unable to reinstate your AdSense account.

14dec2011 photo calendar (permalink):
Each year I make a photo calendar for friends & family. The photo for each month was taken in that month the previous year (well, I cheat on December). I haven't offered the calendar for sale before but it's easy enough to do so let's see what happens. $19.99 + shipping.

10oct2011 xml2c (permalink):
I wrote a little tool to convert XML files into static C structs. It's called xml2c.

02jul2010 oauth_sign (permalink):
Twitter is turning off Basic Authentication soon, and switching to the OAuth three-party authorization protocol. I have a few simple command-line twitter clients that I use when I'm on my antique H19 terminal instead of a pee cee, and those programs would stop working unless I updated them to use OAuth. But there was no simple command-line oriented OAuth request signer written in plain old C. So, I wrote one. It's called oauth_sign. There's both a command-line version and a C function.

22jan2010 SecurePage (permalink):
SecurePage is a little tool that lets you generate self-decrypting web pages. That is, you give it a regular HTML file and it makes a new HTML file that is encrypted by a passphrase. If you have the passphrase then the file will decrypt itself back to the original HTML. Without the passphrase it cannot be read. The decryption happens right in your web browser, no server interaction needed.

29dec2009 New topo map tiles (permalink):
I switched ACME Mapper's topo map mode from using Terraserver to using Service should be faster and more reliable now.

30nov2009 Two Maps One Scale (permalink):
I made a simple Google Maps app called Two Maps One Scale. It shows two locations at the same zoom level, so you can visually compare sizes. See for example San Francisco and Paris.

25sep2009 Panoramio pix in ACME Mapper (permalink):
And now ACME Mapper shows geotagged photos from Panoramio as well as from flickr.

23sep2009 flickr pix in ACME Mapper (permalink):
I made a minor update to ACME Mapper, adding an option to show geotagged photos from flickr. To try it, first click Options then click the flickr checkbox.

22apr2009 ChuMaker (permalink):
Added a little toy I call the ChuMaker. It creates imitation Frank Chu protest signs.

09apr2009 Discussr (permalink):
Ok, here's the app that I needed db for: Discussr. It's an alternate front-end for flickr's group discussions.

14mar2009 db (permalink):
I'm working on a web app whose database is a little too big for tab-separated ASCII files but not big enough to merit a full-fleged SQL database. It would be nice if there was a mid-range option, say a command-line interface to the dbopen(3) library routines. So I wrote one.

17feb2008 ACME Annotator (permalink):
Another new AJAXy page: the Annotator. It lets you add notes to any image on the web.

22jan2008 ACME Chartmaker (permalink):
The latest product from ACME Labs is a front-end for Google's graphing system which makes it much easier to use. Check it out.

20jan2008 Power Failure (permalink):
Unexplained power failure this evening. I don't know when it started, but it ended at 10:05pm, just 15 minutes after my UPS ran down. "Ooo so close."

02jun2007 Power Failure (permalink):
Berkeley lost electricity for 2.5 hours due to someone's mylar graduation balloons hitting a power line. ACME stayed up.

14feb2007 googrep (permalink):
I wrote a little program that combines Unix grep-style text searching with Google-style pattern syntax. It's called googrep.

12jun2006 Mapper Updates (permalink):
I made two small upgrades to ACME Mapper:

24may2006 Outage (permalink):
We had a 9.5 hour power failure yesterday afternoon/evening. The UPS kept things going for 3 hours, so ACME was down for 6.5 hours.

16may2006 Outage (permalink):
ACME's SDSL line was out from 3pm 15may to 11am 16may.

10apr2006 ACME Mapper 2.0 (permalink):
I have been working on a new version of my map page. The old one was an improved front-end for TerraServer. The new version is based on the Google Maps API, so it has a much nicer user interface. Check it out: Mapper 2.0.

15feb2006 Hearts (permalink):
As usual, Valentine's Day was busy for because of the Heartmaker - 1.2 million hits. In fact the only busier day I've had was last June when my mail filtering tutorial got slashdotted for 1.6 million hits. Here's a graph of this week's traffic:

12dec2005 micro_httpd (permalink):
I stored out a new version of my tiny web server, micro_httpd. It has a better directory lister, and it now handles filenames with spaces in them. This puts it over 200 lines of code, but that's still pretty small.

18nov2005 Golden Gate Sunsets map (permalink):
For my first map based on the ACME GeoRSS Map Viewer, I plotted out all the spots from which you can see the sun setting right in the middle of the Golden Gate.

12nov2005 ACME GeoRSS Map Viewer (permalink):
I made a page that displays GeoRSS map files as a Google map. This lets people make nice pretty maps very easily.

12oct2005 Hot Springs (permalink):
Yet another Google Maps app: USA Hot Springs. This one is a good example of how to present thousands of data points, way more than the Google Maps API can normally support.

18sep2005 Planimeter (permalink):
I remembered the name of the doohickey used to measure areas on a map, so I changed the name of the Areometer to the Planimeter. Links using the old name will continue to work.

14sep2005 Areometer (permalink):
Inspired by the Gmaps Pedometer, I made a map that computes the area enclosed by a given path: the Google Areometer.

Actually there already was at least one other map that does this, but it only does a planar approximation. My version uses completely accurate spherical geometry, including drawing great circle arcs instead of straight lines.

There are a couple other features of interest to Google Maps authors: it remembers the most recent position/zoom/map-type in a cookie; and it correctly handles lines & regions that cross the International Dateline.

18aug2005 Metro (permalink):
I made a Google Maps version of the Paris Metro map. And it does route-finding! It's very slick.

29jul2005 BART (permalink):
I made a Google Maps version of the BART schedule.

26jul2005 js_httpd (permalink):
I wrote yet another tiny web server, but this one is in JavaScript. Why? People tend to think of JavaScript as a crippled Java, but it's really more like awk on steroids, and not in the bad way that perl went. The version of the language I'm using for this has some non-standard extra objects added for file I/O and system access. With these additions, I think it makes a fairly good general-purpose scripting language, and I wrote the web server to illustrate the point. Perhaps someday if the I/O extensions become standardized, general use of JavaScript will catch on.

09jun2005 /. (permalink):
The mail filtering pages got slashdotted yesterday. The server handled the load pretty well, except that there were a lot of packet collisions on the two-foot ethernet segment between the server and the DSL box.

05jun2005 ipizer (permalink):
First release of ipizer, a filter to improve sendmail log files so they are easier to analyze.

03jun2005 Outage (permalink):
Had a two-hour power outage this evening. The server stayed up, on UPS. My workstation lasted less than an hour on its smaller UPS, so I read a book while waiting.

25may2005 Filtering (permalink):
The new ACME Labs Mail Filtering Tutorial is now open to the public.

18mar2005 Prints (permalink):
I added an "Order Prints" button to all of my photos. This uploads the picture to smugmug if necessary, and then redirects you there. You can also order stuff besides prints, such as t-shirts, coffee mugs, and jigsaw puzzles.

16mar2005 xmlrpc (permalink):
I wrote a simple command-line XML-RPC client, xmlrpc.

11mar2005 Mapper (permalink):
I added geocoding to the ACME Mapper. This means you can type in a street address and it will find the coordinates. It does this by making an HTTP request to Google Local and parsing the results.

11feb2005 sfcmilter (permalink):
I did some work on sfcmilter to make it a little less susceptible to false positives.

10feb2005 stat (permalink):
Trivial new program available - stat. It displays info on a file, like "ls", but in programmer-level detail. I've actually had this kicking around my personal src dir for years, but never got around to publishing it.

02feb2005 graymilter (permalink):
New version of graymilter available - now it has an optional initial whitelist.

24jan2005 Missile Defense (permalink):
Found an amusing editorial cartoon on the net - ACME Missile Defense, by Bruce Plante from the Chattanooga Times Free Press by way of Slate and 12thharmonic.

22jan2005 Comments (permalink):
I wrote a little web-comments widget and added it to my blogs and photo pages.

21jan2005 texttohtml (permalink):
Minor tweak to texttohtml to better handle files with CRs as well as newlines.

18jan2005 Outage (permalink):
Another power outage this morning. The UPS battery lasted for three and a half hours! Too bad the outage lasted four hours. Oh well.

12jan2005 RSS (permalink):
My political page is now RSSified too.

11jan2005 RSS (permalink):
This page now has an RSS feed, by way of some trivial blogging shell scripts that I might release at some point. I also recently added RSS to my photos page, using a more specialized set of scripts.

03jan2005 file_date (permalink):
Added a trivial program to display a formatted date for a given file: file_date.

21dec2004 Outage (permalink):
We were off the net for an hour again this morning while SBC and Covad switched in a new phone line.

20dec2004 XIP (permalink):
Another XIP tweak, to throw an exception for one more type of malformed XML file.

19dec2004 XIP (permalink):
Trivial fix to XIP; the header file was missing a couple of consts it should have had.

17dec2004 Outage (permalink): was off the net from 10am on Thursday the 16th until 1pm today - 27 hours! There was a real three-way clusterfsck going on between Speakeasy, SBC, and Covad. The SBC guy showed up promptly, checked the line, and said there was a short-circuit in Covad's part. Speakeasy then dropped the ball until I called them at 5pm. Covad showed up at noon Friday and said it's SBC's problem. They are going to meet here on Monday and sort it out. Meanwhile I can keep things going by rebooting the DSL modem whenever it loses the link.

14dec2004 date_parse (permalink):
A couple of minor enhancements to the timegraph program in the date_parse package.

05dec2004 copy_exif (permalink):
First release of copy_exif, a little utility program for copying EXIF data from one JPEG file to another.

02dec2004 Outage (permalink):
We had an hour-long power outage this morning, but the system stayed up due to the massive UPS I installed this spring. It's an APC Back-UPS RS1500 ($227) plus an RS/XS auxillary battery pack ($123). Very nice.

28nov2004 graymilter (permalink):
First release of graymilter, a very simple graylisting milter.

27nov2004 Hi-Res Images (permalink):
TerraServer has added hi-resolution color images for some urban areas, so I added them to the ACME Mapper.

24sep2004 Digicams (permalink):
Added sensor size, sensor type, and pixel pitch to the digital camera database. Also, we passed 400 camera listings!

14sep2004 sfcmilter (permalink):
First release of sfcmilter, designed to work alongside spfmilter and plug a hole in the design of SPF.

28may2004 spfmilter (permalink):
Another new milter released: spfmilter, which implements the SPF mail-forgery prevention protocol.

18may2004 blackmilter (permalink):
First (very beta) release of blackmilter, a mail filtering module for blacklisting large numbers of IP addresses.

14may2004 sample_milter (permalink):
Wrote sample_milter, an example of a sendmail mail filtering module.

06may2004 Clam AV (permalink): is now running Clam AV, an anti-worm/virus mail filter. Before installing this we were getting about three worms per second, using up about 1/4 of the DSL line's bandwidth. Clam AV rejects them earlier in the mail transaction, saving some CPU cycles and possibly even some bandwidth by shutting them down before the entire worm gets transmitted.

01may2004 New Server (permalink): has switched to the real new server, still running over a DSL line to my office. Details on the hardware page.

17mar2004 Temporary Server (permalink): has switched to a temporary new server running over a DSL line to my office. Details on the hardware page.

16feb2004 Precedence Day (permalink):
In honor of Precedence Day, I made an HTML version of this table.

19dec2003 mini_httpd/thttpd (permalink):
Released version 1.19 of mini_httpd and 2.25 of thttpd.

26oct2003 mini_httpd/thttpd (permalink):
Released new versions of mini_httpd and thttpd.

18aug2003 Digicams (permalink):
The digital camera database passed 300 listings today.

21mar2003 Boardfinder (permalink):
And 1000 boards today!

18mar2003 Boardfinder (permalink):
Boardfinder passed 900 boards today.

12oct2002 Digicams (permalink):
Finished the initial data entry for the digital camera database. 189 cameras listed!

05oct2002 Digicams (permalink):
Opened up a new database for digital cameras. Only 19 entries so far but I'll add more soon.

15aug2002 Boardfinder (permalink):
Boardfinder reached 800 boards today.

23jul2002 date_parse (permalink):
Added a date_merge program to the date_parse package.

26may2002 mini_httpd/thttpd (permalink):
Released new beta versions of mini_httpd and thttpd.

25may2002 Build-A-PC (permalink):
Completely updated the Build-A-PC page. I'm particularly happy with the redone memory page. Also the Boardfinder is now up to 582 boards.

17apr2002 Mapper (permalink):
Added a few new features to the ACME Mapper: it remembers your previous settings and start location; you can mark a location and get the distance and direction from there; the Save Map page displays the "World File" parameters of the map; and you can turn the little red dot off if you like.

26mar2002 phoon (permalink):
Updated phoon to use the latest verison of date_parse.

18mar2002 http_get (permalink):
Added a new feature to http_get - now the exit status reflects the HTTP response code.

04jan2002 date_parse (permalink):
Minor update to date_parse.

04jan2002 IPv6 (permalink):
Updated all my network software to be IPv6-ready.

02jan2002 Label Maker (permalink):
Added 18 fonts to the Label Maker.

19dec2001 HTTPS (permalink):
We are now serving our entire web tree via HTTPS as well as regular HTTP. Same content, slower but more secure service.

07dec2001 Firewalls (permalink):
Updated the FreeBSD firewall tutorial to reflect FreeBSD 4.x and IPv6.

04dec2001 Boardfinder (permalink):
Rewrote some of the Boardfinder's shell scripts in C for speed. Now searching is basically instant.

29nov2001 Boardfinder (permalink):
Updated the Boardfinder with about seventy new boards, cleaned up broken links, and added AGP Pro.

14nov2001 http_load (permalink):
New version of http_load with a bunch of new features - settable timeout, HTTP response-code histogram, random source-IP, SSL cipher specification.

12nov2001 mini_httpd/thttpd (permalink):
Released new beta versions of mini_httpd and thttpd.

09nov2001 mini_sendmail (permalink):
Minor update to mini_sendmail.

26aug2001 Email (permalink):
Added email capability to the Label Maker, License Maker, and Heart Maker. You can mail yourself the images you make.

14aug2001 New IP (permalink):
Had to reboot to change IP addresses.

10aug2001 Mapper (permalink):
The ACME Mapper is open for business. This is a topographic & photographic mapping system based on Terraserver, with some significant improvements.

09aug2001 coords (permalink):
Released coords, a set of geographical coordinate conversion routines.

01aug2001 Photos (permalink):
I finished a total re-write of my photography web pages & scripts. Now it's completely database-driven. The system currently has 1650 photos, using 329 MB.

16jul2001 Boardfinder (permalink):
Added a few more boards to Boardfinder, bringing the total to 405. Also sped up the searching, which was getting a little slow with that many boards.

15jul2001 mini_sendmail (permalink):
mini_sendmail updated.

20jun2001 Creeks (permalink):
A geographic / photographic database of Berkeley Creeks.

12may2001 revpar (permalink):
Released revpar, to reverse files by paragraphs.

11may2001 http_ping (permalink):
Released http_ping, a little program to measure HTTP latency.

09may2001 Zippo (permalink):
The folks at sent me a free Zippo lighter engraved with "ACME LABS"! It's very nice.

08may2001 Outage (permalink):
A rolling blackout hit, and due to a loose power cable the battery backup had much less capacity than planned. We were down for about half an hour.

23apr2001 thttpd (permalink):
thttpd version 2.21b released - had to do a quick fix to a problem that was causing the server to hang.

20apr2001 thttpd (permalink):
thttpd version 2.21 released.

02apr2001 Domains (permalink):
Added to the ACME family of vanity domain names: and Also I officially enabled the free email systems on all the domains.

01apr2001 Ads (permalink):
The first month of ads from Aaddzz ended up bringing in $504.52, which is not bad. The distribution was uneven - there were many days with only a few bucks, and then there were a few days with more than $60. Anyway, I'll keep them for now.

The donations page has brought in $225.20 through PayPal, $167.80 through Amazon, and $200 direct, for a total of $593.00 in two months. That's also not bad!

14mar2001 Donate (permalink):
ACME Labs received a $200 donation from Maniacal Contributor Arvind Ghanekar. Woo hoo!

06mar2001 Ads (permalink):
Looks like that first $30 day at Aaddzz was some sort of fluke. $5/day is more like it. Oh well, that's acceptable. I'm making more off direct donations though.

05mar2001 Ads (permalink):
The first ACME Labs banner ad is up and running on Aaddzz. I made it using pbmplus and the labelmaker. It's not beautiful but it gets the message across.

04mar2001 Outage (permalink): was down most of today due to a power plug being not completely plugged in at explosive. Oh well, I guess they're not perfect.

02mar2001 Ads (permalink):
We have started running banner ads from Aaddzz. They seem like a pretty good broker. For example, they let publishers set options like maximum ad size in bytes, and whether to disallow animated ads. First day's commissions were about $30, or $900/month, which is not bad at all if it keeps up. That's about twice what I was making at Burst! Media, my previous broker. I also got about $20 of "promotional" money, which can be used to run my own ads on other Aaddzz sites. Guess I have to come up with an ACME Labs banner now.

23feb2001 Outage (permalink):
Explosive moved their operation tonight, including this machine. About 3.5 hours downtime, no apparent problems.

21feb2001 All Your Candy (permalink):
All your candy are belong to us.

20feb2001 Heart Maker (permalink):
The Heart Maker was made Cruel Site of the Day. Another 10000 visitors!

15feb2001 Heart Maker (permalink):
The Heart Maker got mentioned in Even though it was a day after Valentine's, it brought in over 6000 visitors.

07feb2001 Outage (permalink):
We were down for five hours today due to a car crashing into a utility pole down the street from my ISP.

06feb2001 License Maker (permalink):
The License Maker got mentioned in memepool, bringing in about 3000 visitors.

28jan2001 Donate (permalink):
I started a trial run of this - voluntary $5 donations to support the site. We shall see if anyone goes for it.

18jan2001 Outage (permalink):
The California energy/finance crisis hit us yesterday - our co-location ISP got blacked out for 90 minutes. Fortunately they have two hours of battery backup installed, and it worked flawlessly, so we stayed on the air.

06jan2001 Dates (permalink):
I noticed this morning that the short 06jan01 date format I like to use is now ambiguous. Furthermore, it will remain ambiguous for the next thirty years! Y2K wasn't enough to make me switch to four-digit dates, but this is.

25dec2000 Boardfinder (permalink):
Boardfinder passed 300 boards.

11dec2000 Thief (permalink):
Added to the ACME Labs family of web pages.

01dec2000 Boardfinder (permalink):
Added 13 more boards to the Boardfinder, including the first Pentium-4 boards. Since the only current chipset for the P4 requires the use of RAMBUS memory, I had to add that into the system too, which is unfortunate cause it sucks.

01dec2000 /. (permalink):
We got Slashdotted yesterday and I didn't even notice! It was for this amusing palindromic C program that I grabbed off the net years ago. Not even my own code. Traffic approximately doubled for about ten hours - not too big a deal.

30nov2000 Boardfinder (permalink):
Added 33 new boards to the ACME Boardfinder, including ten with DDR memory.

27oct2000 Build-A-PC (permalink):
Updated the Build-A-PC page. Actually it's now pages, I split it up into separate files by topic. Memory prices have been falling a lot, down by almost 50% since the previous update five weeks prior.

19oct2000 License Maker (permalink):
Finally got around to adding all the historic license plates to the License Maker.

08oct2000 select (permalink):
Added -all flag to select, and fixed a bug with schema-mode databases.

05oct2000 Ciphers (permalink):
Added the AES and RC6 cryptosystems to the Acme.Crypto Java package. AES is the just-announced Advanced Encryption Standard, and was formerly known as Rijndael. RC6 was a candidate for the AES and didn't win the competition, but is still quite good.

30sep2000 select (permalink):
Added ignore-case flag to select.

27sep2000 thttpd (permalink):
thttpd 2.20 released.

24sep2000 Boardfinder (permalink):
Added name searching to the ACME Boardfinder.

13sep2000 http_load (permalink):
New version of http_load with a couple of enhancements and bug fixes - max & min timings, SSL random-number seeding fix, proxy support, timer improvements.

06sep2000 RSA (permalink):
Two weeks before their patent was to expire, RSA has released their public key encryption algorithm into the public domain. This means I can add actual RSA programs to the bigint package, instead of just including directions for performing it with the bic calculator.

06sep2000 Updates (permalink):
Started the ACME Updates file.

04sep2000 Build-A-PC (permalink):
Medium-sized update to the Build-A-PC guide. The sample Athlon design changed from Slot-A to Socket-A. The sample dual-Pentium design changed from Slot-1 to FC-370. The sample compute-server design changed from a Celeron to a Duron.

23aug2000 Boardfinder (permalink):
I added a motherboard database to the Build-A-PC page.

11aug2000 select (permalink):
select, a little ASCII-database program.

27jul2000 bigint (permalink):
bigint, a new large integer math package.

18jun2000 closest_fractions (permalink):
closest_fractions, a little program to find the rational numbers closest to a given real number.

18may2000 Testbed (permalink):
I've been working on a gigabit ethernet testbed.

09may2000 Colormap (permalink):
A colormap sampler.

21mar2000 Build-A-PC (permalink):
Wrote a Build-A-PC guide.

28jan2000 thttpd (permalink):
Added referer-checking to thttpd, to deter bandwidth parasites.

25jan2000 thttpd (permalink):
thttpd now supports IPv6. It's the first Unix web server to do so out of the box, without patching.

18jan2000 Calendar (permalink):
The ACME Calendar.

31dec1999 http_post (permalink):
http_post, a little program to do HTTP POST requests and return the results. Same idea as http_get.

16dec1999 BlueLight (permalink):
K-Mart's web site went on the air, powered by thttpd.

10dec1999 mini_httpd (permalink):
mini_httpd now handles SSL/HTTPS. It is almost certainly the smallest/simplest web server to do so.

25nov1999 New Server (permalink): is now running on a 450 MHz K6-2 box co-located at Here's a rundown of the changes:
Old setup New setup
OS FreeBSD 2.2.8 FreeBSD 3.3
CPU 200MHz shared 450MHz dedicated
Server bestwwwd/2.4 thttpd 2.07
chrooted no yes
Disk space 70 MB about 6 GB
Bandwidth limit 200 MB/day 5.4 GB/day
CGI CPU limit 1000 seconds/day 86400 seconds/day
Cost $50/month $100/month

24nov1999 weblog_parse (permalink):
weblog_parse, a program to parse and extract data from standard web log files.

27oct1999 Privacy (permalink):
ACME Labs now has a privacy policy. This is intensely boring, but apparently necessary if you want to carry any ads from IBM.

17sep1999 mini_httpd (permalink):
Released mini_httpd. This is an old-fashioned forking web server, making a new process for each request, just like the first version of NCSA before they invented pre-forking. It's intended as a simple testbed for trying out things like SSL. It's surprisingly fast, though. On my old 100MHz Pentium it clocked 70 ops/sec, 90% as fast as Apache on that platform. I suppose forks are pretty fast when the program's size is minuscule - the executable is only 8KB.

12sep1999 License Maker (permalink):
The ACME License Maker.

05sep1999 http_load (permalink):
Added SSL to http_load.

16mar1999 micro_proxy (permalink):
micro_proxy - the world's smallest web proxy?

15mar1999 micro_httpd (permalink):
micro_httpd - the world's smallest web server?

15nov1998 Outage (permalink):
ACME Labs was mostly off the net for the last week because some moron at Network Solutions let a host registration for go through.

24jun1998 Benchmarks (permalink):
Some web server benchmarks.

23jun1998 thttpd (permalink):
thttpd 2.00 released.

27nov1997 Serve (permalink):
Acme.Serve won a Byte Editor's Choice Award of Distinction. JavaSoft's JWS (the server formerly known as Jeeves) won the same award.

28sep1997 ECLI (permalink):
Experimental Command Line Interface.

07feb1997 Label Maker (permalink):
The ACME Label Maker.

20dec1996 Nnrpd (permalink):
First release of Acme.Nnrpd, a netnews reading daemon in Java.

27nov1996 Widgets (permalink):
First release of Acme.Widgets, a few Java GUI utility classes.

18aug1996 Under Construction (permalink):
The Under Construction page.

10aug1996 Serve (permalink):
First release of Acme.Serve, a tiny Servlet engine.

11jun1996 Psg (permalink):
Released Acme.Psg, a Postscript-like graphics package for Java.

25mar1996 Stats (permalink):
Started producing daily web stats reports.

03nov1995 On The Air (permalink): goes on the air, hosted at

19oct1995 thttpd (permalink):
First beta version of thttpd released.

07jul1994 First (permalink):
My first web page, at

17apr1991 Registered (permalink):
Registered domain name.
Back to ACME Labs.