CardioThink, Inc. Public Download Site

A simple perl script to bulk-email a PDF file

With the winter season upon us, it is time to send newsletters to friends and family far and wide. This simple perl script reads a text file that contains a list of email addresses and attaches exactly one PDF file to an email to each.
More than one email may appear on one line in the input text file.
There are three defaults you will want to change in the script: your return email address, the subject line to be used for each message, and the default text body message.
Optionally, you can include a unique text message that appears in the body of the email sent for each line in the file. If you want to do this, you will need to pay attention to the (optional) formatting characters in the input file.
The script writes an output file which, for each line in the input file, reproduces the email address(es), the text body line that was used, and the year in which email was sent. If you rerun the script with the same input and output files, duplicate messages will not be sent so you can add new addresses to the input file and rerun the script. This arrangement is somewhat clumsy, but avoids use of a database that would add even more complexity.

Unblocking your IP address in is widely used by mail servers that receive mail, including mine, to filter spam. If your mailserver's public-side IP address is listed by, some but not all of your email will be rejected. Often, the reason for rejection (ie, "your IP is listed with will not be given.
One common reason for listing is that your mailserver is identifying itself as "localhost.localdomain" when it sends mail to remote mail servers. This is taken by as a sign that your mail server may be infected, but the problem is easily solved.

Download and convert sound files from the Olympus VN 480PC digital voice recorder on Linux

The Olympus VN 480PC requires a nonstandard USB driver and uses a nonstandard audio storage format, for which the vendor supplies a driver only for Windows. Thanks to the author of odvr, its recordings can now easily be transferred to linux, as can those of a variety of related models. Here is how.

Configuring multiple static IP addresses with AT&T Residential U-verse service

The AT&T Residental U-verse service can be purchased with static IP addresses. However, the technical support necessary for configuring the router that AT&T supplies, the 2Wire 3600HGV, is hard to come by and many discussion forums document the difficulty in doing so.
Here is a step-by-step guide to configuring the 3600HGV to use static IP address, and also a guide to using an inner router configured with multiple outside-facing VLANs to work around the limitation that aliased IP addresses associated with single MAC addresses are not recognized as separate IP addresses by the 3600HGV.

[PARTIALLY SOLVED] "I/O error" with Kodak i1210 high-speed Scanner and saned over net

A recurring problem with using saned for using USB-based scanners over the network is an incomprehensible "I/O error" with a variety of scanners. This issue was explored using one high-speed scanner, and a work-around is presented here to what may be a bug in the closed source library supplied by the vendor. (submitted to the sane-devel maillist here.)

Basic256 BASIC-language interpreter

The Basic256 BASIC language interpreter is a maintained project intended to help beginning programmers learn in a fun way. An accompanying book is available in print. For those who like to try before they buy, a no-charge PDF of the book is also available on that web site.
Unfortunately, binary packages may not be available for your platform, and the source code has dependencies that can be tricky.

Here is a step-by-step guide to installing the required packages on Fedora 15. Note the tricky modification to the source code tree of espeak to compile it with portaudio version 19. It's not hard, but you do have to know about it.

Also, for Fedora 15, the way to find out which packages include files of a given name is

yum provides */filename
yum provides */pathname/filename
The wild-card character is important because otherwise it will produce a warning to use the wild-card but will not produce otherwise-useful output.

The source code will also compile on Ubuntu 9.10. I did not keep notes, but attention to detail will help you find the packages you need to install.

freeradius / radiusclient patch to fix PPTP "unknown attribute" problem

This section describes patches to radiusclient that fix a problem with CHAP authentication via PPTP with freeradius and provide a program radlistdictionary that lists the libraries and their contents as the user's radiusclient processes them, and also makes a minor fix to allow the use of both "$INCLUDE" and "INCLUDE" in dictionaries to include other dictionaries.
PPTP is widely used to create VPNs using the RADIUS protocol for accessing a back-end database of user data. An open software implementation freeradius is widely used to provide this backend authentication/authorization/accounting support. In commonly used architectures, pppd is configured to use the plugin radius.o, which in turn uses radiusclient to communicate with the RADIUS daemon (commonly radiusd). Since at least 2005, the technical blogs have shown a recurring problem with apparent failure by radiusclient to understand the RADIUS attributes 11 and 25, which are used by Microsoft to denote the Challenge-Handshake Authentication Protocol (CHAP) MS-CHAP-Challenge and MS-CHAP2-Response, respectively. This lack results in failure of CHAP authentication.
The otherwise superb leading wiki document on the subject does not seem to help although it does provide the missing document that is required.
It turns out that this particular problem arises from a combination of three factors: the dictionary "" is not distributed as part of the distribution, the version of that dictionary provided by the web page cited above has a space at the start of each data line in the file, and the parsing code in dict.c of radiusclient version 1.1.6 (which compiles to does not skip over spaces.
The simple fix, of course, is to use a text editor to delete the space at the start of each data line in the provided file. Since there are *a lot* of copies of that file out there, though, I have prepared and submitted a separate patch to skip over spaces and tabs at the start of data lines, as well as to accept both "INCLUDE" and "$INCLUDE" as keywords since confusion already exists and will not be resolved soon.
This patch can be applied against both the current stable 1.1.6 release, available here and here, as well as the CVS version as of 7/03/2011 available via this link. Please note that by default this source tree will configure itself to install into the /usr/local tree; the usual configure options can be used to put the component files into your favorite system directories. Please also note that this distribution does not include or microsoft.merit, but both are available here. You will need to insert the lines
$INCLUDE dictionary.merit
or, after applying the patch,
INCLUDE dictionary.merit
at the end of the file dictionary that is read by the radiusclient. As above, you can use the program radlistdictionary, included in the patch above, to use the newly installed library to read the dictionary/dictionaries it knows about, and to show what it is doing so you can fix what needs to be fixed. You may need to make links between the newly installed library and the /usr/lib entry that your pppd uses to implement radius.o.

ecg2png: convert electrocardiograms to a Web-friendly png format

ecg2png-0.30.tar.gz: a command-line program that converts scanned electrocardiograms from a variety of standard image formats to the PNG format. During the conversion, it reduces the file size by discarding unnecessary colors and by reducing the number of pixels as specified by the user. This software is released under the GPL license in source form. It is known to compile under Linux of the RedHat 6.0 flavor. The README and ecg2png.lsm documents are here.

ecg2png-0.30.tar.gz.asc: PGP signature key for ecg2png-0.30.tar.gz. You can retrieve our public key from Search for

msqldates2mysql: convert msql format dates to mysql format dates

msqldates2mysq-0.30.tar.gz: a very simple program that converts the dates in the output of msqldump to the format used by mysql. To compile, just untar it and type "make".

There are other steps required to convert data from msql to mysql. The mysql distribution comes with a utility that converts most msql functions to their mysql equivalents. You still have to fix up the variable types by hand. The string concatenation operator changes from "+" to ".". There are a few other odds and ends: write me if you are interested in my draft list of them.

Setting up a multihomed Linux box with an ADSL modem

How to set up a multihomed Linux box (with more than one IP addresses) with an Alcatel ADSL modem and get all the addresses working. There is lots of help on setting up multihomed Linux boxes and setting up Linux with ADSL modems. But I couldn't find anything to help me get all of the aliased IP addresses visible from the Internet. Here is how I did it.