From decwrl!ucbvax!ucsd!usc!cs.utexas.edu!uunet!allbery Mon May  7 07:40:50 PDT 1990
Article 1528 of comp.sources.misc:
Path: decwrl!ucbvax!ucsd!usc!cs.utexas.edu!uunet!allbery
From: brian@ucsd.edu (Brian Kantor)
Newsgroups: comp.sources.misc
Subject: v12i048: El-cheapo E-mail to Fax for sendmail
Message-ID: <87551@uunet.UU.NET>
Date: 5 May 90 17:27:15 GMT
Sender: allbery@uunet.UU.NET
Lines: 283
Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)

Posting-number: Volume 12, Issue 48
Submitted-by: brian@ucsd.edu (Brian Kantor)
Archive-name: cheap-fax/part01

: This is a shar archive.  Extract with sh, not csh.
echo x - README
cat > README << '!Funky!Stuff!'
This is an el-cheapo way to implement outgoing-only text-only e-mail to
fax.

We use a $198 fax card ("The Complete FAX") in an old IBM-PC.  The PC
is set up as needed by the fax card, with the AUTOEXEC.BAT file set up
to cd into the CFAX directory (where all the fax stuff is stored),
start the fax background process, and then execute the AUTOFAX.BAT file
included in this distribution.

On our Sun mailserver, a dedicated serial line (on /dev/tty0d in our
case) runs from the Sun to the serial port on the PC.

When someone sends mail to 12345@fax.ucsd.edu, we run the mail through
the 'faxmailer' shell script, which extracts the phone number (after
applying some sanity and security checks), and then queues it into a
fax job in /var/spool/fax.

Every 15 minutes or so (from crontab), we run the 'faxq' script, which
fetches previous fax transmission history files from the PC, examines
them to determine whether the transmission was successful, whether to
requeue the message for retransmission, or to return it to the sender
as undeliverable.

It then transfers the outgoing text files to the PC, and then finally
transfers a batch script 'QUEUE.BAT' which performs the actual
transmission and then loops back to the 'AUTOFAX' batch script.

For $200 and an old PC, we have the ability for E-mail users to send
mail to Fax machines on campus (at last estimate, there were around
200-400 or so fax machines around UCSD).

This is an incredible hack that I dreamed up one afternoon, but it's
been working fine for about two months, and it has demonstrated that
people want the capability.  We're looking into getting some more
sophisticated FAX capability for our E-mail system, but the low demand
(we handle maybe two to five E-Fax messages a day now) doesn't justify
the expense of the available commercial solutions.

You'll need Kermit on both the mail server and the PC.  Or maybe you can
get fancy and use some Ethernet mechanism, but I didn't think it was
worth the cost of putting an Ethernet card into the PC and we had lots
of leftover ports on the Ariel card in our Sun.

Enjoy.  Hack on it; it'll do you good.

(BTW: this is the only document on this there is.  You're on your own
now, son.)
	- Brian Kantor, UCSD, Nov 1989
!Funky!Stuff!
echo x - autofax.bat
cat > autofax.bat << '!Funky!Stuff!'
del queue.bat
del *.txt
del *.0*
kermit server
queue
!Funky!Stuff!
echo x - faxmailer
cat > faxmailer << '!Funky!Stuff!'
#!/bin/sh
cd /var/spool/fax
# make a copy of the file
echo "==============================================================" > f$$.txt
echo "==============================================================" >> f$$.txt
echo "	Wonderous Electronic Mail to FAX System " `date` >> f$$.txt
echo "==============================================================" >> f$$.txt
echo "==============================================================" >> f$$.txt
echo " " >> f$$.txt
echo " " >> f$$.txt
echo " " >> f$$.txt

head -200 >> f$$.txt

# find the phone number in the Subject: line
PH=`awk -f /usr/local/lib/faxnumber f$$.txt`

if [ $PH ] ; then
	:
else
	echo "No valid fax number found in To: or Subject: line"
	rm f$$.txt
	# ( error 65 is "data error" to sendmail)
	exit 65
	fi

# put out the actual command to be run
echo "cfaxsend f$$.txt $PH /x /f > f$$.err" > f$$.q

exit 0
!Funky!Stuff!
echo x - faxnumber
cat > faxnumber << '!Funky!Stuff!'
BEGIN	{ for (i=1; i <= 5; i++)  number[i] = "" }

/^To: / { 
	number[1] = substr($0,5);
		if (q = index(number[1], "@"))
			number[1]=substr(number[1], 1, (q-1));
		}

/^Subject: / {
	if (p = index($0, "["))
		{
		if (q = index($0, "]"))
			number[2]=substr($0, p+1, (q-p-1));
		}
	if (p = index($0, "("))
		{
		if (q = index($0, ")"))
			number[3]=substr($0, p+1, (q-p-1));
		}
	if (p = index($0, "<"))
		{
		if (q = index($0, ">"))
			number[4]=substr($0, p+1, (q-p-1));
		}
	if (p = index($0, "{"))
		{
		if (q = index($0, "}"))
			number[5]=substr($0, p+1, (q-p-1));
		}
	}
END	{
	for (i=1; i <= 5; i++)
		{
		p = index(number[i],"%");
		if (p > 1)
			number[i] = substr(number[i], 1, p-1);
		# check for illegal first digit - campus phones start 3,4,5
		fd = substr(number[i],1,1);
		if ( fd != 3 && fd != 4 && fd != 5 )
			number[i] = "";
		}
	print number[1] number[2] number[3] number[4] number[5]
	}
!Funky!Stuff!
echo x - faxq
cat > faxq << '!Funky!Stuff!'
#!/bin/sh
#
# this one dequeues the messages from where they're spooling and
# moves them over to the PC.

cd /var/spool/fax

# following stuffed in to prevent more than one of these running at a
# time 
# Note that shlock compares
# pids so it doesn't matter if a process dies and leaves a lock sitting
#		- Brian

if /usr/lib/news/shlock -p $$ -f FAXLOCK ; then
	:
else
	echo ${pname}: "[$$]" already running "[`cat FAXLOCK`]"
	exit 0
fi

nfiles=`find . -name '*.q*' -print | wc -l`
if [ $nfiles = "0" ] ; then
	rm FAXLOCK
	exit 0;
fi


# zap commands left over from last time
rm queue.bat

# following grabs all the error files from the last go-round,
/usr/local/bin/kermit << EOF
set line /dev/tty0d
set baud 9600
get f*.err
quit
EOF

# analyze the .err files we got, and add the appropriate
# deletes to the outgoing batch file.  Successful faxes get deleted
# from the current spool directory here too; unsuccessful ones get
# requeued

for f in *.err ; do
	if [ ! -r $f ] ; then
		continue;
	fi
	fb=`basename $f .err`
	echo $f $fb ;

	# we got the errors file, blow it away on the PC
	echo "DEL $f" >> queue.bat ;

	# see if it was sent ok
	if ( egrep -i 'Sent successfully' $f ) ; then
		rm $fb.* ;
		continue ;
	fi

	# see if it failed miserably
	if ( egrep -i 'error' $f ) ; then
		frm=`egrep From: $fb.txt | sed -e 's/From: //'` ;
		more FAXERR $fb.* | Mail -s "Fax mail error" $frm brian ;
		rm $fb.* ;
		continue ;
	fi;

	# otherwise, requeue and remove the errors file
	cat $fb.q.o >> queue.bat ;
	rm $f ;
done

# cat all the new queue files onto the batch file
nq=`find . -name '*.q' -print | wc -l`
if [ $nq -gt 0 ] ; then
	for f in *.q ; do
		cat $f >> queue.bat ;
		mv $f $f.o ;
	done ;

	# ship over the current text files
	/usr/local/bin/kermit << EOF
set line /dev/tty0d
set baud 9600
send f*.txt
quit
EOF
fi

# make sure that the last thing in the batch restarts the PC script
echo "AUTOFAX" >> queue.bat

# ship over batch list of things to do
# 'finish' makes the PC kermit exit and execute the queue.bat file
# we just delivered
/usr/local/bin/kermit << EOF
set line /dev/tty0d
set baud 9600
send queue.bat
finish
quit
EOF

echo "===================================================" >> /var/log/fax
date >> /var/log/fax
cat queue.bat >> /var/log/fax
rm -f  FAXLOCK
exit 0
!Funky!Stuff!
echo x - sendmail.stuff
cat > sendmail.stuff << '!Funky!Stuff!'
This goes in Ruleset Zero:

# resolve the FAX mailer
R$*<@$*fax>$*		$#FAX$@$2$:$1$3			user@fax
R$*<@$*fax.$D>$*	$#FAX$@$2$:$1$3			user@fax.ucsd.edu

And this goes wherever you stuff your mailer definitions

############################################################
############################################################
#####		FAX Mailer specification
############################################################
############################################################

Mfax,	P=/usr/local/lib/faxmailer, F=rsDFMmnC, S=17, R=27,
	A=faxmailer $u

S17
#null
S27
#null
!Funky!Stuff!
echo x - usr.lib.aliases
cat > usr.lib.aliases << '!Funky!Stuff!'
fax:fax@fax.ucsd.edu
!Funky!Stuff!
exit 0


