Purchase  Copyright © 2002 Paul Sheer. Click here for copying permissions.  Home 

next up previous contents
Next: 34. uucp and uux Up: rute Previous: 32. init, ? getty,   Contents

Subsections

33. Sending Faxes

This chapter discusses the sendfax program, with reference to the specific example of setting up an artificial printer that will automatically use a modem to send its print jobs to remote fax machines.

33.1 Fax Through Printing

Continuing from Section 21.10...

You should go now and read the sendfax section of the info page for mgetty. The sendfax command is just one program that sends faxes through the modem. Like mgetty, it reads a config file in /etc/mgetty+sendfax/. This config file is just sendfax.config and can contain as little as

 
 
 
 
5 
 
verbose y
debug 5
fax-devices ttyS0
fax-id 27 21 7654321
max-tries 3
max-tries-continue y

Below, fax_filter.sh is a script that sends the print job through the fax machine after requesting the telephone number through gdialog. [ gdialog is part of the gnome-utils package.] An appropriate /etc/printcap entry is:

 
 
 
 
5 
 
fax:\
        :sd=/var/spool/lpd/fax:\
        :mx#0:\
        :sh:\
        :lp=/dev/null:\
        :if=/var/spool/lpd/fax/fax_filter.sh:

The file fax_filter.sh itself could contain a script like this [Remember to rotate the /var/log/fax log file, see page [*].] for a modem on /dev/ttyS0:

 
 
 
 
5 
 
 
 
 
10 
 
 
 
 
15 
 
 
 
 
20 
 
 
 
 
25 
 
 
 
 
30 
 
 
 
 
35 
 
 
 
 
40 
 
 
 
 
45 
 
 
 
 
50 
 
 
 
 
55 
 
#!/bin/sh
 
exec 1>>/var/log/fax
exec 2>>/var/log/fax
 
echo
echo
echo $@
 
echo "Starting fax `date`: I am `id`"
 
export DISPLAY=localhost:0.0
export HOME=/home/lp
 
function error()
{
    gdialog --title "Send Fax" --msgbox "$1" 10 75 || \
        echo 'Huh? no gdialog on this machine'
    cd /
    rm -Rf /tmp/$$fax || \
        gdialog \
            --title "Send Fax" \
            --msgbox "rm -Rf /tmp/$$fax failed" \
            10 75
    exit 1
}
 
mkdir /tmp/$$fax || error "mkdir /tmp/$$fax failed"
cd /tmp/$$fax || error "cd /tmp/$$fax failed"
 
cat > fax.ps
 
if /usr/bin/gdialog \
            --title "Send Fax" \
            --inputbox "Enter the phone number to fax:" \
            10 75 "" 2>TEL ; then
    :
else
    echo "gdialog failed `< TEL`"
    rm -Rf /tmp/$$fax
    exit 0
fi
 
TEL=`< TEL`
test -z "$TEL" && error 'no telephone number given'
 
cat fax.ps | gs -r204x98 -sOutputFile=- -sDEVICE=faxg3 -dBATCH -q - \
    1>fax.ps.g3 || error 'gs failed'
 
ls -al /var/lock/
/usr/sbin/sendfax -x 5 -n -l ttyS0 $TEL fax.ps.g3 || \
    error "sendfax failed"
 
rm -Rf /tmp/$$fax
 
exit 0

33.2 Setgid Wrapper Binary

The above script is not enough however. Above, sendfax requires access to the /dev/ttyS0 device as well as the /var/lock/ directory (to create a modem lock file--see Section 34.4). It cannot do that as the lp user (under which the above filter runs). On RedHat, the command ls -ald /var/lock /dev/ttyS0 reveals that only uucp is allowed to access modems. We can get around this restriction by creating a setgid (see Chapter 14) binary that runs as the uucp user. Do this by compiling the C program,

 
 
 
 
5 
 
 
 
 
10 
 
 
 
 
15 
 
 
 
 
20 
 
 
 
 
25 
 
 
 
 
30 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
 
int main (int argc, char **argv)
{
    char **a;
    int i;
 
/* set the real group ID to that of the effective group ID */
    if (setgid (getegid ())) {
        perror ("sendfax_wrapper: setgid failed");
        exit (1);
    }
 
/* copy all arguments */
    a = (char **) malloc ((argc + 1) * sizeof (char *));
    for (i = 1; i < argc; i++)
        a[i] = (char *) strdup (argv[i]);
    a[argc] = NULL;
 
/* execute sendfax */
    a[0] = "/usr/sbin/sendfax";
    execvp (a[0], a);
 
/* exit on failure */
    perror ("sendfax_wrapper: failed to exececute /usr/sbin/sendfax");
    exit (1);
}

using the commands,

 
 
 
gcc sendfax_wrapper.c -o /usr/sbin/sendfax_wrapper -Wall
chown lp:uucp /usr/sbin/sendfax_wrapper
chmod g+s,o-rwx /usr/sbin/sendfax_wrapper

Then, replace sendfax with sendfax_wrapper in the filter script. You can see that sendfax_wrapper just executes sendfax after changing the group ID to the effective group ID (GID) as obtained from the getegid function on line 12. The effective group ID is uucp because of the setgid group bit (i.e., g+s) in the chmod command, and hence sendfax runs under the uucp group with full access to the modem device.

On your own system it may be cleaner to try implement this without a wrapper. Debian, for example, has a dialout group for the purposes of accessing modems. Also be aware that some distributions may not use the uucp user in the way RedHat does and you may have to create an alternative user especially for this task.


next up previous contents
Next: 34. uucp and uux Up: rute Previous: 32. init, ? getty,   Contents