Many current Unix operating systems provide some sort of fax support. In this section, we'll consider the free HylaFAX package, originally written by Sam Leffler while at Silicon Graphics, because it is the most widely used and is available for many different Unix versions. HylaFAX is capable of sending and receiving faxes on the local system, and accepting fax jobs from other hosts on the network. Outgoing faxes are queued as necessary. An interface to electronic mail is also available. The package's home page is http://www.hylafax.org.
Fax services are provided by three daemons:
The package also includes a variety of utilities, many of which we'll consider here; the corresponding binary files are mainly stored in /usr/local/bin and /usr/local/sbin, although a few are in /var/spool/hylafax/bin (if you use the default installation directories).
Actual fax images are stored in the subdirectories docq (outgoing) and recvq (incoming) under /var/spool/hylafax. Other important subdirectories of this main HylaFAX spooling location are sendq (outgoing job control files), log (contains log files for each fax session), config (modem type definitions), and etc (most HylaFAX configuration files).
HylaFAX installs easily on most systems, and the documentation provides lots of information about the process, so we won't spend time considering it here. Once the software is installed, you use the faxsetup script to perform initial configuration. The script asks you a series of questions about your system setup and desired package usage, and automatically generates configuration files based upon that information.
The faxaddmodem script is used to configure a modem within the HylaFAX system, and it is called by faxsetup during the initial setup process. You can also use it to change the settings for an existing modem.
Be sure to specify the outgoing serial line device to these scripts on systems that use multiple device special files to refer to the same serial line: e.g., /dev/cuaa0, /dev/cua0p0, and /dev/cua/0 under FreeBSD, HP-UX, and Solaris (respectively).
Once the faxsetup script has completed, there are still a few items to deal with:
12.7.1 Sending Faxes
The HylaFAX package provides the sendfax utility for submitting faxes. The following example briefly illustrates its features and use:
$ sendfax -s na-let \ Use letter size images (use a4 for A4). -T 5 -t 2 \ Dial call up to 5 times; attempt to transmit twice. -f "Erika Plantagenet" \ Fax sender name. -r "Sales Data" \ Contents of Re: field (subject). -c "Call if any questions." \ Comments. -P high \ Priority (vs. bulk or normal). -h dalton.ahania.com \ Send to HylaFAX server on this host. -a 20:05 \ Transmit fax at 8:05 P.M. -d "Amy Ng@1.293.555.1212" \ Recipient name and phone number. letter.txt graph.tif Files to transmit.
A few notes:
I try to avoid being a prima donna as much as possible, but setting up fax cover templates for HylaFAX is one place where I draw the line, pointing to my job description as I refuse to help. Don't get suckered into doing this or you'll be ensnared in an infinite time sink. These files must be in PostScript format and use the dictionary mechanism for passing fax-specific parameters (e.g., the sender and recipient names). There is no easy way to generate them, and I'm no PostScript hacker. I leave creating one as an exercise for the fax user (and fortunately no one has ever ordered me to do otherwise).
The key point to make with users is that they can always create a cover sheet as the first page of the fax file that they create. Using the sendfax command's -n option will suppress the HylaFAX cover page, as will setting AutoCoverPage to no (see below).
12.7.2 Managing Faxes
HylaFAX provides several utilities for monitoring the fax facility and manipulating fax jobs. For example, the faxstat command displays information about fax jobs, as in these examples:
# faxstat -s -l List faxes to send. HylaFAX scheduler on dalton.ahania.com: Running Modem ttyS0 (1.293.555.9988): Sending job 4 JID Pri S Owner Number Pages Dials TTS Status 4 127 R chavez 2032390846 0:2 0:12 5 127 B jones 2032390846 0:0 0:12 Blocked # faxstat -r -l List faxes that have been received. HylaFAX scheduler on dalton.ahania.com: Running Modem ttyS0 (1.293.555.9988): Sending job 4 Protect Page Owner Sender/TSI Recvd@ Filename -rw---- 1 14 2935551122 19:52 fax00012.tif
This system is currently sending a fax, has one more job waiting to send and has recently received one as well. The xferfaxstats command may be used to produce a summary report of all fax activity, broken down by sending user.
Several other utilities are provided for manipulating individual fax jobs, which are referred to by job ID (listed in the first column in the faxstat -s output). The faxrm and faxabort commands can be used to remove/terminate fax jobs, as in these examples:
$ faxrm 4 Remove pending fax (abort if sending). Job 4 removed. $ faxrm -a -h mahler 28 Remove fax job on another host as fax admin. Password: Fax administration password (see below). Job 28 removed.
A user removes a fax job on the local system in the first example. Another user removes a job from a remote host in the second command by specifying the proper HylaFAX administrative password.
The faxalter command may be used to modify the characteristics of a pending fax job. For example, the following command sets job 24 to be released for transmission at 9:00 P.M. and sets its priority to bulk (low):
$ faxalter -p bulk -a 21:00 24
As we've seen, the faxstat command also lists the status of faxes that have been received, including the files where they are stored. The faxabort command may be used to abort a current incoming fax. The faxinfo command may be used to view the characteristics of a received fax:
# faxinfo fax00027.tif /var/spool/fax/recvq/fax00027.tif: Sender: +12935557778 Pages: 3 Quality: Normal Page: North American Letter Received: 2002:02:02 11:23:21 TimeToRecv: 0:24 SignalRate: 38400 bit/s DataFormat: 2-D MR
Incoming faxes are saved in TIFF format. They may be viewed with any TIFF viewer, or you may use the fax2ps command to convert them to PostScript format.
Ideally, I'd like to be able to route incoming faxes to their recipient automatically. However, current fax technology doesn't provide a general way to specify a recipient electronically. Beyond the fax data itself, all an incoming fax includes is the originating phone number, the incoming phone number and/ortransmitting station identifier (TSI), a string associated with the sending fax machine (or modem).
HylaFAX can route faxes based on any of these. In practical terms, the most useful routing items are the originating phone number (which must be obtained via caller ID) and the incoming phone number. In the latter case, HylaFAX has the ability to route on the direct inward dial (DID) ordirect number identification service (DNIS) telephone number. DID and DNIS are services offered by the telephone company in which a block of virtual telephone numbers are all routed to one or more real phone lines. Using either of them, various employees in a company can each be assigned their own, unique fax number, but all incoming faxes actually go to one or more phone lines managed by the HylaFAX server. The DID/DNIS number of the incoming call is passed to HylaFAX which can use it as a key for determining where to route the fax.
Processing of received faxes is handled automatically by the /var/spool/hylafax/bin/faxrcvd script. In its delivered form, it calls a script named FaxDispatch in /var/spool/hylafax/etc via the shell's dot command. This script has the responsibility for setting the SENDTO and FILETYPE environment variables. They specify the mail recipient and file type to be used for routing the file, which default to FaxMaster and ps, respectively.
This file must be a valid sh script. The HylaFAX documentation suggests a from like the one is this simple version:
case "$DEVICE" in Attempt to match the incoming modem line. ttyS4) SENDTO=amy_ng ;; ttyS5) SENDTO=sam_wood ;; esac case "$SENDER" in Attempt to match originating phone number in TLS. 12935551212) SENDTO=chavez ;; esac case "$CIDNUMBER" in Attempt to match the DNIS or caller ID number. 8985551212) SENDTO=harvey FILETYPE=tif ;; *41255512*) SENDTO=mktg ;; esac
If FaxDispatch finds a match, it resets the value of SENDTO and possibly FILETYPE which were initialized in faxrcvd. Ultimately, faxrcvd sends the fax in a mail message to the SENDTO user, converting it to the format specified in FILETYPE (PostScript format by default); the converted fax is included in the message as a MIME attachment. Note that the CIDNUMBER variable is used for both Caller ID and DID/DNIS numbers (based on which of them is in use).
In general, the order of statements in FaxDispatch will be significant. Using the logic in the preceding example, the final matching entry will prevail over any previous ones.
Unfortunately, this routing feature is not of any practical use at my site because we don't have DID, and users at my site cannot predict who is going to send them faxes. In such cases, however, you can modify the faxrcvd script to perform whatever actions you want for an incoming fax rather than always generating email. For example, we replace most of its logic with a simple command that just prints each incoming fax, something like this:
/usr/bin/fax2ps -S $1 | lpr -P $FAX_PRINTER
Faxes are then delivered the old fashioned way, via sneakernet.
12.7.3 HylaFAX Configuration Files
The HylaFAX package uses a number of configuration files. These are the most important:
12.7.4 Controlling Access to HylaFAX
Host and user-based access control to the local HylaFAX facility is defined in the /var/spool/hylafax/etc/hosts.hfaxd file. Entries in this file have the following form:
where sender is a regular expression against which potential fax senders are compared. It can contain patterns to match the username and/or host name. The second field, map-to-uid, is the local UID to which matched senders should be mapped for permissions and accounting purposes (if desired). send-password is an optional encoded password to be used for validation prior to accepting a fax, and admin-password is an encoded password which must be entered in order for matching users to perform administrative functions (e.g., modifying or removing other users' faxes).
The order of entries within the file is important since the first matching entry is used. If no entry matches, access is denied. Thus, entries are generally ordered from most to least specific.
Here is a sample hosts.hfaxd file:
^chavez@.*ahania\.com$:::xxxxx chavez can administer from anywhere in domain. !^s_king@ User s_king uses too much paper: deny access. ahania\.com$:::: Users in the domain can send (no password). zoas\.org$:1234:yyy: zoas.org's users need password (UID mapped). 192.168.10.33 All users on this host can fax.
As the second entry indicates, a leading exclamation point indicates an access denial entry.
The HylaFAX package provides the faxadduser and faxdeluser commands for adding and removing entries to this file. However, they are required only when you need to generate an encoded password; in other cases, it is just as easy to edit the file directly.
Here is a faxadduser command which creates an entry allowing user mercury to administer the fax system:
# faxadduser -a olympus mercury
This is the resulting entry:
This is actually too broad, since any user from any FQDN containing "mercury" would also match. However, once the encoded password is created, it is easy to edit manually. Alternatively, you could use a faxadduser command like this one:
# faxadduser -a olympus 'mercury@.*ahania\.com'
Be aware that faxadduser does not check to see if an existing entry like the one you are adding already exists; it simply blindly adds what you specify to the file.