Creating a FAX Server
with HylaFAX

11/12/2007
Eric Low

On a stock SuSE installation, install HylaFAX (current version was 4.3.0 at the time of this writing). I decided to use an external modem to make the job easy (actually, I spent two days trying to get a WinModem to work in Linux.. good luck with that!). I plugged it into COM1, which meant that it was accessible via /dev/ttyS0 . Next, I ran faxsetup and used all of the default options (aside from area code and max pages). It automatically detected my USR Sportster and added all the correct options.

In order to allow access to users on our subnet without having to supply a usename/password, I edited /var/spool/fax/etc/hosts.hfaxd and added the following line:

192\.168\.100\.[0-9]+


It took me a while to figure out how to get this to work, allowing a whole subnet via regex, since you can't specify a * or just leaving off the last octet or any of the usual methods. I then restarted hylafax (service hylafax restart).

In order for hylafax to be able to communicate with your modem, you must run faxgetty for each configured modem. Otherwise, when you send a fax to the server, hylafax will just sit there with the job doing nothing until the kill time expires. Faxgetty can be started by simply typing /usr/lib/fax/faxgetty -D ttyS0 if you want to start it manually; an easier way, at least in SuSE, would be to add the following line to /etc/inittab:

mo:35:respawn:/usr/lib/fax/faxgetty ttyS0

This line was actually in the inittab file by default, it just had to be uncommented. In Fedora, I would probably run faxgetty from rc.local.

HylaFax sends out reports when your job succeeds or fails, etc. To change the email address that this is sent from, edit /etc/aliases and change the following line:

faxmaster: faxuser@thisdomain.com

To change modem settings, such as the number of rings to wait before answering look for a config.tty# file. For me, this file is /var/spool/fax/etc/config.ttyS0 (this file lets you set certain other key things as well, such as LocalIdentifier, which is usually the fax's phone number displayed at the top of each page).

Things to look at:
man doneq
man recvq

 

 

I followed this suggestion to avoid problems with our USR Sportster:

Modem Wedged

After a month of good work (11,000 faxes) suddenly the modem become wedged. Because USR modem doesn't have the un-wedged option as the Mainpine modem, you have to tell hylafax to try to set it up more then (default)2 times. Add this to your config.tty#

MaxSetupAttempts: 10

 

Adding a second modem to an existing HylaFAX installation..

This proved to be stupid easy. The second modem that I was installing was the same model as the first modem, so I simply copied the old configuration. I did this manually by coping /var/spool/fax/etc/config.ttyS0 to /var/spool/fax/etc/config.ttyS1. (make sure to preserve the permissions! The config file should have permissions 644 with ownder fax:uucp).

Next, I had to run faxgetty in order for HylaFAX to be able to communicate with the modem. The command I ran was /usr/lib/fax/faxgetty -D ttyS1. In addition, I added the following line to /etc/inittab so that it would run at startup and be respawned:

mo:35:respawn:/usr/lib/fax/faxgetty /dev/ttyS1

Once a second modem is configured, it can be dynamically added to Hylafax to send jobs with the faxmodem command. I did this by typing faxmodem ttyS1. I did not actually have to run this; as soon as I ran the faxgetty command, HylaFAX started using the modem immediately.

Now, if I wanted to make the modem send-only, I could do it one of two ways. The more complicated way would be to add a separate modem class, set to send-only, and add the modem(s) to that class. The easier, and recommended way as described here, is to change the number of rings to 0 in the config.ttySX file:

RingsBeforeAnswer: 0

To make a modem receive-only, change the following setting in the config.ttySX file:

ModemReadyState: D

Other programs to look at:
faxstate

 

Some other solutions for interfacing with the FAX server:

Winprint HylaFAX - Print individual print jobs to the server. A pop-up prompts for the phone number for each print job. I could not get this one to work correctly! It looked nice, but never sent anything to the FAX server!!

Frog FaxMail - I tried Frogfax 1.8.10.3 (without language pack) - Unfortunately, it froze every time I tried to fax.

In Windows, the best way to fax is by using the whfc client:

WHFC

First, install WHFC (I installed 1.3.0 beta) with the default options (which will install the program itself and something called RegMon (which handles the virtual printer port), but it will not install any printers). This will run the WHFC client after the install. Go to Fax -> System Preferences and enter the hostname of your HylaFax server.

You will *probably* get a "Connection timed out" error message at first. To fix this, change the following registry entry:

HKLM\SOFTWARE\WHFC\UsePasv (set to 0)

Then, close the program (which may have to be forced) and restart it.

Now install the printer. Start Menu -> Settings -> Printers -> Add Printer. Select Local Printer (uncheck "Automatically detect..") and use WHFCFAX: as the port. Select "Apple Laserwriter 16/600" for the driver (this is just a basic PostScript driver). Name the printer hylafax.

Start up WHFC if it is not already started. Go to Fax -> User Settings and enter your Name, Email, and Login. Select any other options, such as changing Pagesize to Letter

To perform a Fax Merge from Microsoft Word, some Word macros are made available at the WHFC site. I prefer the MergeFax macro by Michael DeWitt.

Enter MS Word, start a new (blank) document and save it as a Document Template (I used mergefax.dot). Go to Tools -> Macro -> VB Editor. In the Project window, double-click ThisDocument and paste the macro code. Save, then File -> Close and Return. Exit Word.

Copy the template to Word's startup directory (C:\Program Files\Microsoft Office\Office\Startup).

Start Word, and make sure the template is loaded by going to Tools -> Templates and Add-ins. Ensure that the .dot file that you put in the startup directory is there, and is checked.

Add a button to the menu by going to Tools -> Customize. Under the Commands tab, select Macros from the Categories menu. The MergeFax macro should appear in the window on the right. Simply drag it up to the toolbar or to a menu, and a button should be created. Right-click on the button while the Customize window is still open to change the name.

Now, to perform a merge, you do it much like a Mail Merge:

First, you should have an Excel spreadsheet containing the data that you want merged in. The first row of the spreadsheet should be the field names to be inserted into the appropriate spots in your Word document. One of your fields should be the fax number, entitled "fax." (Note that this is case-sensitive! I actually edited the template via the VB Editor on my copy and changed the field name to "Fax" and then changed the printer name as well).

Ensure that Excel is closed, then open Word and start with a blank document. Go to Tools->Mail Merge. This will pop up the "Mail Merge Helper" box. Under Main Document, select Create->Form Letter. Select "Active Window."

Under Data Source, select Get Data->Open Data Source. In the Open Data Source Dialog Box, change the Files of Type to "MS Excel Worksheets." Navigate to, and open, your spreadsheet. Select "Entire Spreadsheet."

Word will, at this point, open Excel in another window. It will also notice that you have no merge fields in your document yet, and make you edit that document. It will also add the "Mail Merge" toolbar. Start typing your letter, and then at the point where you want to insert a field from your spreadsheet, select the appropriate field name from the "Insert Merge Field" pull-down menu.

When you are ready to do the Fax Merge, click the button that you added (instead of the "Merge" button that you would normally hit). As long as WHFC is open, and your printer and field names are correct in the script, everything should start appearing in your HylaFax queue!

* For me, when I do the Fax Merge, WHFC actually dies. It seems to do so after everything is added to the queue though, so if I open it back up, the Fax jobs are still there.

 

Receiving Faxes

At one point we decided we'd like to receive faxes with this fax server rather than just send. There are several ways to accomplish this; the two most typical ways are as follows:

1. When a FAX is received, send an email that contains an FTP link to download the file from the server.

2. Send an email with the FAX attached.

We decided that the second way would be best. In addition, we wanted them in PDF format rather than the default of TIFF. To do this, I simply modified the /var/spool/fax/bin/faxrcvd script with the following changes (please not that it appears that faxrcvd is overwritten on HylaFax upgrades, but FaxDispatch is not; therefore customizations should be done the FaxDispatch file if possible):

TOADDR=eric@emailaddress.com
NOTIFY_FAXMASTER=errors
FILETYPE=pdf
HOSTNAME=`localhost`
SENDTO=faxqueue@emailaddress.com

The TOADDR email address would only receive notifications of any errors during reception of a FAX (although it could also be set to receive a notification of everything received).

The SENDTO email address, on the other hand, would receive the PDF version of the FAX as an attachment (as well as some useful information in the email, including the number of pages, number received from, etc.)

Note that this will NOT delete the original .TIF file! To do so, and delete the individual log at the same time, add the following lines to the end of the faxrcvd script:

rm $FILE
rm log/c$COMMID

Or, even better, add these lines to keep the files around for a few days just in case (ie. delete files older than 2 days):

perl -e 'unlink grep {-M > 2}</var/spool/fax/recvq/*.tif>';
perl -e 'unlink grep {-M > 2}</var/spool/fax/log/c*>';

Or, even better than that, use the utilities that come with HylaFax (faxcron and faxqclean) to clean everything! Run these via a cron job:

30 3 * * * /usr/sbin/faxcron -info 2 -log 2 -rcv 2 -tmp 2 | mail -r faxreport faxadmin@emailaddress.com
0 * * * * /usr/sbin/faxqclean

Notice that I have the faxcron program directing its output to the mail program so that a daily report is emailed to me. Also, an observation I made-- faxcron seems to do its math wrong. If you tell it to purge things older than two days, it actually only purges things older than three days. So, I actually changed all those 2's on the command line to 1's to account for this.

 

I also noticed that Outlook Web Access (OWA) does not interpret the Content-Type email header correctly and therefore neither names the attached file correctly nor realizes that it is a PDF. Instead, it merely looks at the file extension of the Content-Description header (which, of course, is completely incorrect behavior). To account for this, I changed the following lines in the faxrcvd script:

from:
echo "Content-Description: FAX document"
to:
echo "Content-Description: $FILENAME.pdf"

To change the email's From: address from the default of "The HylaFAX receive Agent," edit the /var/spool/fax/bin/dictionary file and set the DICTRECEIVEAGENT= line.

 

 

To send a fax from the command line on Linux, you should have the hylafax-client package installed and use the sendfax program (which is different than the sendfax program included in the sendfax package). Use a command similar to the following:

sendfax -vv -f "eric@thisdomain.com" -D -R -n -o faxuser -d 18005551212 -h ourfaxmachine.com graphpaper1.ps

The -vv option will actually show you the FTP session. If it times out with the following error...

200 PORT command successful.
-> STOT
425 Cannot build data connection: Connection timed out.

...it is because sendfax will only use an ACTIVE FTP session. I cannot find any easy way to change this. Therefore, you must let the HylaFax server connect back to your machine from a random source port (it's usually tcp port 4558, but you never know). Add an iptables rule to allow that entire IP address to connect back, and voila!


When we started really using the fax server heavily in production to send out mass faxes, it became obvious very quickly that the default "killtime" of three hours (the time after which a fax in the queue is deleted, no matter if a send has even been attempted yet) was waaaay too short. It easily takes two minutes to send a four-page fax, and when you're sending a few hundred, the time adds up quickly. I upped the KillTime by adding the following line to /usr/lib/fax/sendfax.conf:

KillTime: "now +18 hours"

In fact, this does NOT work. I'm guessing that it will only work if you originally submit the fax through the sendfax command line utility from the same machine that contains that modified sendfax.conf.

This did not actually work, at least not if the job was sent via WHFC. WHFC also does not let you change the value in the settings (it shows it to you, but does not let you alter it). Apparently though, you can change the following registry key (set this to the number of hours):

HKEY_CURRENT_USER/Software/Whfc/KillTime

Hhhmmmm.. that did not work either. (to be continued...)

Also, the maximum number of tries proved to be way too high. This is because busy signalswere automatically bumbed back up to the top of the queue. In other words, everything else in the queue had to wait until one number with a busy signal was tried twelve full times. I simply added the line Max Tries: 3 to /usr/lib/fax/sendfax.conf.

Even better, check out this link for some finer tune settings regarding things like busy signals:
http://www.hylafax.org/archive/2007-06/msg00143.php

 

To restrict what time outbound faxes are sent:
This can easily be done on a server-wide basis using the TimeOfDay parameter (which goes in the /var/spool/fax/etc/config file). I put in the following parameter:

TimeOfDay: "0830-2230"

If you want to get any fancier, see here.

 

Logging outgoing faxes when done (completed or failed):
/var/spool/fax/bin/notify is called to send a notification email. This only seems to be called if the owner requested, at the time they submitted the fax, to be notified. This script also calls a script called /var/spool/fax/etc/FaxNotify if it exists. It does not exist unless you created it; if you do create it, it will be called.

http://hylafax.sourceforge.net/man/notify.php
http://hylafax.sourceforge.net/man/faxrcvd.php

to customize:
bin/FaxDispatch
etc/FaxNotify

Because I wanted a log of ALL completed/killed outgoing faxes, but I did not wish to have an email notification for successfully sent jobs, I modified the bin/notify script so that it would NOT execute the main section if the job's specified notification email was set to "none" by adding the following lines to the MAIN section:

if [ ! "$mailaddr" = "none" ] ; then
(if [ -z "$jobtag" ] ; then
...
...
...
) 2>$ERRORSTO | $SENDMAIL -f$FROMADDR -oi -t
fi

So, when submitting the job, I set the "notifyaddr" parameter to none and the notify parameter to done. This ensured that the notify script would be called (it will not be called unless both of these parameters are set to something) every time a job was done, for whatever reason.

 

OCR'ing incoming FAXes
Ocrad - http://www.gnu.org/software/ocrad/
Tesseract - http://sourceforge.net/projects/tesseract-ocr/



Check this link for detailed config.ttyS0 options: http://www.hylafax.org/man/current/hylafax-config.4f.html

PPS description here.

 

port 4559 tcp

hylafax and hylafax-client rpm's installed.

/var/spool/fax directory
/usr/lib/fax directory
/var/spool/fax/sendq directory (for fax jobs that are being sent)
logs for each file are stored in /var/spool/fax/log

To customize the notification email(s):
check out the /var/spool/fax/bin/notify.awk file.


Some important files:
/etc/rc.d/hylafax
/var/spool/fax/etc/config.ttyS0
/usr/bin/fax*

Some useful commands:
faxstat
kdesendfax?
to test, where testpage is a simple ASCII file: sendfax -n -D -d 7346651212 testpage
to see current fax jobs: faxstat -s
to remove one of those jobs: faxrm
Good, general help: man hfaxd
Log of all activity: /var/spool/fax/etc/xferfaxlog
faxadduser

More documentation:
http://wiki.debian.org/HylaFax
Man pages: http://www.hylafax.org/man/6.0.3/
Helpful email notification doc: http://osdir.com/ml/telephony.fax.hylafax.devel/2005-09/msg00033.html
HOWTO: http://www.cs.bgu.ac.il/~piavka/hylafax-howto/
WHFC Installation: http://whfc.uli-eckhardt.de/1.0/docu/install.shtml
HylaFAX+ Tweaking: http://hylafax.sourceforge.net/howto/tweaking.php
Singing Fool: http://steepturns.com/singingfool
Tweaking and Customization HylaFAX Handbook