1#!/bin/sh
2# 
3# fax - script to make, send, receive, view or print a fax
4# Copyright 1993-1999 by Ed Casas 
5# 
6# --- Start of user configuration section --- 
7# 
8# Notes: 
9#
10#  - do not put spaces before or after the equal (=) signs.
11#
12#  - variables can also be set on the command line, for example:
13#       fax DEV=cua0 send file.ps
14#    or in a configuration file (see CONFIGFILES below)
15#
16
17# The names of the fax script, efax and efix, including full path
18# if necessary.
19
20FAX=fax
21EFAX=efax
22EFIX=efix
23
24# The device to which the fax modem is connected (e.g. ttya for
25# /dev/ttya).  Use a dial-out (cua) device if available.  If
26# there are links to this device then all programs must use same
27# name or the UUCP locking mechanism will fail.  For example, if
28# /dev/modem is a link to /dev/cua1, then getty, uucp, kermit,
29# pppd, dip, etc. must *all* use either /dev/modem or /dev/cua1.
30
31DEV=cua1
32
33# Your fax number in international format, 20 characters maximum.
34# Use only digits, spaces, and the "+" character.
35
36FROM="+1 800 555 5555"
37
38# Your name as it should appear on the page header.
39
40NAME="Put Your Name Here"
41
42# The preferred page size for creating and printing faxes.
43# Allowed values are "letter", "legal", and "a4".
44
45PAGE=letter
46# PAGE=legal
47# PAGE=a4
48
49# The type of printer. Use 'pcl' for HP-PCL or 'ps' for
50# Postscript.  See definition of PRINT (below) for more options.
51
52PRTYPE=ps				# Postscript (e.g. Apple LaserWriter)
53# PRTYPE=pcl				# HP-PCL (e.g. HP LaserJet) 
54
55# The command to print image files from standard input.  Typically
56# this is "lpr" or "lp".
57
58PRCMD="lpr"
59
60# The command to view a Portable Gray Map (PGM) image from the
61# standard input.  Typically "xv -" or "xloadimage stdin".
62
63VIEWCMD="xloadimage stdin"		# best
64# VIEWCMD="pnmtoxwd | xwud"		# slower alternative
65# VIEWCMD="xv -"			# much slower alternative	
66
67# The name of the Ghostscript executable including full path if
68# necessary.  Only required if faxing Postscript files.
69
70GS=gs
71
72# Dial string prefix and suffix such as T for tone dialing, P for
73# pulse dialing, 9 to get an external line, commas for delays or
74# W to wait for dial tone.  See definition of TELCVT below if you
75# have more complex requirements.
76
77DIALPREFIX="T"
78DIALSUFFIX=""
79
80# The name(s) of lock file(s) according to your system's
81# conventions. Protect with single quotes for delayed evaluation.
82# Add a leading '#' to the file name to use binary format.
83
84# LOCK='-x /var/lock/LCK..$DEV'			# modern systems
85# LOCK='-x /usr/spool/uucp/LCK..$DEV'		# older systems
86# LOCK='-x /var/lock/LCK..$DEV -x /var/spool/uucp/LCK..$DEV' # both
87# LOCK='-x #/usr/spool/uucp/LCK..$DEV'		# binary format
88# LOCK='-x /usr/spool/locks/LK.047.040.011'	# SysV style names
89LOCK=''					# no lock file
90
91# Uncomment one of the following lines to force xon/xoff flow
92# control only if you have one of the types of modems listed.
93
94# FCINIT='-j\Q4'		# AT&T (Dataport, Paradyne)
95# FCINIT='-j\Q1'		# Motorola (Power Modem, 3400 Pro,...)
96# FCINIT='-j*F1'		# QuickComm (Spirit II)
97# FCINIT='-j&H2&I0&R1&D3I4'	# USR (Courier, Sportster)
98# FCINIT='-or'			# Multi-Tech (for bit reversal)
99
100# FCINIT="$FCINIT -j+FBO=0"	# USR modems using Class 2.0
101
102# ****************************************************************
103# The remaining options probably won't need to be changed.
104# ****************************************************************
105
106# Configuration files that are sourced if they exist.  Comment
107# out if you don't need to use config files. Warning: any type of
108# shell command in these files will be executed.
109
110CONFIGFILES="/etc/efax.rc ${HOME:-~}/.efaxrc ./.efaxrc"
111
112# A command that will generate unique names for logs and received
113# files.  'date +%m%d%H%M%S' works on most systems.  Protect with
114# single quotes.
115
116TSTAMP='date +%m%d%H%M%S'
117# TSTAMP='echo $$'		# alternative - use process number
118
119# Shell command to convert aliases to phone numbers when sending
120# faxes.  When executed $1 will be the alias and $f the file name
121# to search.  The example below uses a directory file where alias
122# lines start with the keyword "fax" followed by the alias in
123# parentheses and a colon.  The remainder of the line is taken to
124# be the phone number. Other lines are ignored.  For example, if
125# one of the files in DIRFILES (defined below) contained the line
126# "fax(kpmg): 691-3031", you could use the command "fax send kpmg
127# invoice.24". Protect with single quotes.
128
129LOOKUP='eval sed -n -e "/^fax($1):/{" -e "s/^[^:]*://p" -eq -e"}" $f'
130
131# List of telephone directory file(s) to be searched.  The
132# default is the file .faxdir in the user's home directory.
133
134DIRFILES="${HOME:-.}/.faxdir"
135
136# Shell command to convert phone numbers to dial strings.  This
137# lets you to store numbers without the long distance or
138# alternate carrier access codes, passwords, accounting digits,
139# etc.  In the examples below this is used to convert numbers
140# beginning with '+'; the first substitution handles same-country
141# calls and the second handles international calls.
142
143TELCVT='sed -e s/+1/1/ -e s/+/011/'	# North America
144# TELCVT='sed -e s/+61/0/ -e s/+/0011/' # Australia
145# TELCVT='sed -e s/+44/0/ -e s/+/00/'	# UK
146# TELCVT='sed -e s/+49/0/ -e s/+/00/'	# Germany
147# TELCVT='sed -e s/+852// -e s/+/001/'	# Hong Kong
148# TELCVT='sed -e s/+33// -e s/+/19W/'	# France (?)
149# TELCVT='sed -e s/+34/0/ -e s/+/07W/'	# Spain
150# TELCVT='sed -e s/+1/10288/'		# use AT&T
151# TELCVT='sed -e s/+/T82W1682W9W/'	# get out of PBX
152
153# efix options to use a bitmap font for text-to-fax conversion.
154# The option -l66 puts 66 lines of text per page, -d1,1 sets 1
155# inch top & left margin.  Comment these out to use the built-in
156# font. Use "fax makefont" to make bitmap fonts from Postscript
157# fonts.
158
159# TEXTFONT="-l66 -d1,1 -f /usr/bin/efaxfont"
160
161# efax options to specify a different font for headers. Generate
162# using "fax makefont."
163
164# HDRFONT="-f /usr/bin/efaxfont"
165
166# Dimensions of page sizes.
167
168PAGE_letter="8.465x11in"	# fax width x letter length
169PAGE_legal="8.465x14in"		# fax width x legal length
170PAGE_a4="21x29.7cm"		# ISO A4
171
172# Default resolution for converting to fax format. Can only be
173# 204x196 or 204x98.
174
175RES=204x196			# default "Fine" resolution (196 lpi)
176# RES=204x98			# standard resolution (98 lpi)
177
178# When the print and view commands below are executed, $f will be
179# the input file name and $PAGEDIM will be one of the above page
180# dimensions. Protect with single quotes.
181
182# PRINT: A command to convert fax files to a printable format.
183# For printers other than Postscript or PCL you can use efix's
184# PBM output and an appropriate pbm filter (such as pbmtoepson)
185# or efix's Postsript output and Ghostscript as a filter. Change
186# the scaling (-s) and displacement (-d) options as required to
187# fit the image onto the area your printer can print.
188
189PRINT='$EFIX -ve -p$PAGEDIM -r300 -s0.98 -d0,0.125 -o$PRTYPE $f'
190
191# example using pbm utilities:
192# PRINT='$EFIX -ve -p$PAGEDIM -r60x72 -opbm $f | pbmtoepson'
193
194# example using Ghostscript:
195# PRINT='$EFIX -ve -p$PAGEDIM -r120x144 -ops $f | \
196#	$GS -q  -sPAPERSIZE=$PAGE -sDEVICE=epson -r120x144 \
197#	-dNOPAUSE -dSAFER -sOutputFile=- - '
198
199# VIEW: A command to convert fax files to PGM format for
200# previewing.  efix's pgm output reduces image dimensions by 4X.
201
202# VIEW='$EFIX -ve -p$PAGEDIM -r200 -opgm $f' 	# 50dpi: fast, whole-page view
203VIEW='$EFIX -ve -p$PAGEDIM -r300 -opgm $f'	# 75dpi: slower, readable size
204
205# Commands to set up modem.  "-iZ -iE0&D2S7=120"
206# works with almost all modems.  See the efax(1) man page for
207# details.
208
209INIT="-iZ -i&FE0&D2S7=120"
210
211# Command(s) to reset modem when efax finishes. "-kZ" works in
212# almost all cases.
213
214RESET="-kZ"
215# RESET="-kZ -k&F+FCLASS=0"	# for modems that stay in fax mode after reset
216
217# Speaker mode(M) and loudness(L). Mn sets speaker mode where n
218# means: 0:never, 1:until carrier, 2:always, 3:on receive only.
219
220SPKR="-iM1L0"
221
222# Options to use a particular command sets.  Normally efax
223# selects the command set based on the modem's capabilities.  Use
224# -o1 to force Class 1, -o2 for Class 2 and -o0 for Class 2.0.
225# Class 2 is not the same as Class 2.0
226
227CLASSINIT="-o1"	# Class 1
228# CLASSINIT=""		# Class 2
229# CLASSINIT="-o0"	# Class 2.0
230
231# The modem's capabilities for sending faxes.  Normally efax
232# chooses these by querying the modem.  "-c 1,3,0,0,0,0,0,0"
233# forces 9600 bps maximum speed.  See the efax(1) man page for a
234# description of the fields.
235
236# TXCAP="-c 1,3,0,2,0,0,0,0"
237
238# Capabilities for receiving faxes.  Usually the same as TXCAP.
239# If your modem only receives at 4800 bps use "-c 1,1,0,0,0,0,0,0".
240
241# RXCAP="$TXCAP"
242
243# Additional options required only for transmit or only for
244# receive.  None normally required.
245
246RXINIT=""
247TXINIT=""
248
249# Command to make a date for the page header. Protect with single
250# quotes.  'date "+%Y/%m/%d %H:%M"' works on most systems.
251
252DATECMD='date "+%Y/%m/%d %H:%M"'	# YYYY/MM/DD HH:MM (24hour)
253# DATECMD='date'			# longer, more readable
254
255# Page header format.  You may use $DATE, $NAME, $FROM, $TO, and
256# "%d/%d" (for page number and count).  Protect with single
257# quotes.  Example: '$DATE $FROM $NAME p. %d/%d'.
258
259HDR='$DATE     $FROM      $NAME     p. %d/%d'
260
261# BUSYRETRIES is a list of delays in seconds between attempts to
262# redial busy numbers.  Comment out if you don't want to retry
263# busy numbers.
264
265BUSYRETRIES="30 60 120 300 60 600 60 60 1200 60 60"
266
267# FAILRETRIES is a list of delays in seconds between attempts to
268# retry failed transmissions.  Retries are only attempted if at
269# least one page was sent in the previous attempt. Retries
270# include only pages not already sent. Comment out if you don't
271# want to retry failed transmissions.
272
273FAILRETRIES="300 300"	# try two more times at 5 minute intervals
274
275# Command to run another program (efax) at a higher-than-normal
276# scheduling priority.  This command isn't used if it fails
277# (e.g. because the current user isn't privileged).  Comment this
278# out if it causes problems.
279
280NICE="nice -n -10"
281
282# Standard versions of commands that are often aliased.
283
284RM="/bin/rm -f"
285LS="/bin/ls"
286
287# Messages to display.  VERB sets the messages displayed (stderr)
288# and VERBLOG the messages written to log files (stdout).
289
290VERB="ewin"		# show errors, warnings, progress & negotiation
291VERBLOG="chewmainrxtf"	# log everything
292
293# ****************************************************************
294# The remaining configuration options apply only to the `fax
295# answer' command.  You can ignore these if you will only be
296# running efax manually.  See "USING INIT TO RUN EFAX" in the
297# efax man page for more information.
298# ****************************************************************
299
300# device or file where fatal error messages should be written
301
302CONSOLE=/dev/console
303
304# The directory to store incoming faxes and log files.  This directory
305# should already exist and be writable by the user(s) of this script.
306
307FAXDIR=/var/spool/fax
308LOGDIR=/var/log/fax
309
310# The strftime(3) pattern that generates the file name for
311# received files.  For example, at 10:45:36 on February 25,
312# "%m%d%H%M%S" would produce 0225104536, "%j-%H%M" would produce
313# 056-1045, and %d%b%H%M 25Feb1045.
314
315ANSFNAME="%m%d%H%M%S"
316
317# umask for received files. Use 022 to allow anyone to retrieve faxes.
318
319UMASK=022
320
321# The user to be sent mail when a fax is received.
322
323FAXMGR=root
324
325# The sendmail executable including full path if necessary.  Only
326# required if forwarding received faxes by e-mail in $NOTIFY.
327
328SENDMAIL=/usr/sbin/sendmail
329
330# The command to execute when a fax is received.  Normally this
331# sends FAXMGR e-mail or prints the received fax.  The variable
332# $f will be the name of the log file, $FILES will contain the
333# names of the received files, and $REMID will have the remote ID
334# string or '?' if none. The faxmail function will e-mail the fax
335# as MIME image/tiff attachments.  Comment this out to do
336# nothing.  Protect with single quotes.
337
338NOTIFY='faxmail | $SENDMAIL $FAXMGR'
339# NOTIFY='mail -s "fax/message from $REMID: $FILES" $FAXMGR <$f'
340# NOTIFY='lpr $f ; $FAX print $OPT $FILES'
341
342# The number of rings to wait before answering.
343
344ANSRINGS=4
345
346# If you want to enable fax/data adaptive answer (AA) read the
347# efax man page and define DATAINIT to be the options that enable
348# AA. Note: AA does not work properly on some (2400/9600) modems
349# unless the modem initialization is done at 2400 bps (not
350# possible with efax). USR modems do not support modem adaptive
351# answer (+FAE=) in Class 1.  &C1 enables most modems' DCD line
352# so a signal can be sent to shells when a call is dropped.  You
353# must also define DCMD (see below).
354
355DATAOPT="-j&C1 -j+FCLASS=0 -jS7=30"
356# DATAINIT="$DATAOPT -j+FAE=1"		# Class 1 modem adaptive answer
357# DATAINIT="$DATAOPT -j+FAA=1"		# Class 2[.0] modem adaptive answer
358# DATAINIT="$DATAOPT -oa"		# software adaptive answer
359# DATAINIT="$DATAOPT"			# data-only answer
360
361# If you have a voice modem and want to answer in voice mode
362# define VOICEINIT to be the options that enable voice mode.  You
363# must also set VCMD below. Voice support is not yet available.
364
365# VOICEINIT="-j#CLS=8"			# Rockwell voice modems
366# VOICEINIT="-jM2L2#CLS=8#VLS=4"	#    with speaker on
367
368# Argument to exec(2) of "/bin/sh -c" for incoming data calls.
369# This command will usually exec getty(8) but can include other
370# commands to set up the serial port, etc.  Up to 6 %d arguments
371# are replaced by the baud rate following the CONNECT response
372# from the modem or 19200 if none.  If using getty_ps ensure
373# /etc/gettydefs has entries for all possible %d values
374# (e.g. 19200). Use 'nice' if required to reduce any special
375# priority set by NICE.
376
377DCMD="exec /sbin/getty -h $DEV %d vt100"	# for getty_ps (Linux)
378# DCMD="exec /sbin/agetty -h $DEV %d vt100"	# for agetty (Linux)
379# DCMD="exec pppd $DEV %d"			# start PPP server
380
381# Argument to exec(2) of "/bin/sh -c" for incoming voice calls.
382# This command will usually be a shell script that interacts with
383# the caller by using efone to play/record audio and detect DTMF
384# tones.  Up to 6 %d arguments are replaced by the modem file
385# descriptor.  VCMD can "exec fax reanswer" to switch to fax or
386# data mode if required.
387
388FONE=/usr/bin/fone				# minimal voice mail
389VCMD="exec $FONE %d"
390
391# The owner.group and mode to which "fax answer" sets the serial
392# device.  This allows non-root processes to grab the device from
393# efax even if a previous process (e.g. login) has changed it.
394# Comment out if you don't need to reset device ownership.
395
396OWNER=root.tty		# typical
397MODE=666		# anybody
398# MODE=660		# only owner & group
399
400# Regular expression for efax exit codes in log files that will
401# *not* be saved.  For example, use [145] to ignore exits due to
402# `locked' (1), `no modem' (4), and `signal' (5) conditions
403
404NOLOG='[145]'
405
406# ****************************************************************
407# --- End of user configuration section ---
408# ****************************************************************
409
410# --- source configuration files
411
412for f in $CONFIGFILES
413do
414	if [ -r $f ]
415	then
416		. $f
417	fi
418done
419
420# --- set any variables given on command line
421
422while : ; do
423	case $# in 0) break ;; esac
424	case "$1" in [A-Z]*=*) eval $1 ; shift ;; *) break ;; esac
425done
426
427# -------- initialize 
428
429ERR=0
430
431$NICE true 2>/dev/null ; case $? in 0) ;; *) NICE="" ;; esac
432
433# --- check for a command or alias and optional flags
434
435cmd=""
436case $0 in
437*/faxlpr|faxlpr) cmd=faxlpr ;; 
438*) 
439	while : ; do
440	case $# in 0) case $cmd in '') cmd=receive ;; esac ; break ;; esac
441   	case $1 in 
442	-l) OPT="$OPT -l" ; RES=204x98 ; shift ;; 
443	-h) OPT="$OPT -h" ; RES=204x196 ; shift ;; 
444	-v) OPT="$OPT -v" ; VERB=$VERBLOG ; shift ;; 
445	*) 
446		case $cmd in '') cmd=$1 ; shift ;; *) break ;; esac
447	;;
448   	esac
449	done
450;; 
451esac
452
453
454# -------- If answer mode use the optional answer device
455
456if [ "x$cmd" = "xanswer" ]; then
457	if [ "x$DEVANSWER" != "x" ]; then
458		DEV=$DEVANSWER
459	fi
460fi
461
462# -------- resolve dependencies on command-line arguments
463
464eval LOCK=\"$LOCK\"			# depends on DEV
465
466# make device name w/o directories
467
468case $DEV in
469	*/*) DEVN=`echo $DEV|sed -e s./._.g` ;;
470	*) DEVN=$DEV ;;
471esac
472
473case $PAGE in
474	letter)	PAGEDIM="$PAGE_letter" ;;
475	legal) 	PAGEDIM="$PAGE_legal" ;;
476	a4) 	PAGEDIM="$PAGE_a4" ;;
477	*) 	echo "Error: PAGE=\"${PAGE}\" not valid." ; exit 2 ;;
478esac	
479
480# -------- functions
481
482faxmail () {
483   echo "Subject: fax/message from $REMID : $FILES"
484   echo "Mime-Version: 1.0"
485   echo "Content-Type: multipart/mixed; boundary=EFAX_MAIL"
486   echo ""
487   echo "--EFAX_MAIL"
488   echo "Content-Type: text/plain; charset=\"us-ascii\""
489   echo "Content-Transfer-Encoding: 7bit"
490   echo ""
491   cat $f
492   for f in $FILES
493   do
494     echo "--EFAX_MAIL"
495     echo "Content-Type: image/tiff; name=\"$f.tiff\""
496     echo "Content-Transfer-Encoding: base64"
497     echo "Content-Disposition: attachment; filename=\"$f.tiff\""
498     echo ""
499     $EFIX -M <$f
500     echo "--EFAX_MAIL--"
501   done
502   echo "--EFAX_MAIL--"
503}
504
505# -------- export variables for fone script
506
507export DEV TSTAMP
508
509# -------- do the appropriate command
510
511while : ; do 	# so we can use `break' to get to the end of the script
512
513case $cmd in 
514
515# fax answer : clean up logs and exec efax. normally run by launchd(8).
516
517	answer)
518
519	if cd $FAXDIR ; then :
520	else
521		echo "Error: $FAX cannot cd to $FAXDIR" >>$CONSOLE
522		sleep 30
523		break
524	fi
525
526	umask $UMASK
527	case $OWNER in '') ;; *) chown $OWNER /dev/$DEV ;; esac
528	case $MODE  in '') ;; *) chmod $MODE  /dev/$DEV ;; esac
529
530	for f in ${DEVN}.[0-9]*  	# clean up old log files
531	do
532	  if [ -r $f ]
533	  then
534	    egrep	"done, returning $NOLOG|exec'ing" $f >/dev/null 2>/dev/null
535	    case $? in
536	    1)    FILES=`sed -n -e  '/received ->/s/^.*-> \(.*\)$/\1/p' $f`
537		  FILES=`echo $FILES`
538		  REMID=`sed -n -e '/remote ID ->/s/^.*-> \(.*\)$/\1/p' \
539			  -e tok -e b -e ':ok' -e q $f`
540		  case $REMID in '') REMID='?' ;; esac
541		  eval $NOTIFY
542	    ;;
543	    esac
544
545	    echo   >>${LOGDIR}/${DEVN}.log && \
546	    cat $f >>${LOGDIR}/${DEVN}.log && \
547  	    $RM $f || \
548	    echo "Error: $FAX cannot save log files" >>$CONSOLE
549	  fi
550	done	
551
552	while [ -f ${DEVN}.stop ] ; do sleep 15 ; done
553
554	exec $NICE $EFAX -v "" -v "$VERBLOG" -d/dev/$DEV $INIT $SPKR \
555	$CLASSINIT $FCINIT $RXINIT $LOCK \
556	$RXCAP -l "$FROM" $RESET \
557	$DATAINIT -g "$DCMD" $VOICEINIT -e "$VCMD" \
558	-jS0=$ANSRINGS -w -s -r "$ANSFNAME" 2>$CONSOLE >${DEVN}.$$
559
560	echo ERROR: $FAX answer exec failed >>$CONSOLE ; sleep 30
561
562	break
563	;;
564
565
566# fax reanswer : switch from voice mode to fax[/data] mode
567
568	reanswer)
569
570	# we should already be in the fax spool directory, the
571	# device locked, the modem answered and initialized in
572	# voice mode and stdout/stderr redirected appropriately
573
574	umask $UMASK
575
576	exec $NICE $EFAX -v "" -v "$VERBLOG" -d/dev/$DEV '-i#CLS=0' \
577	$CLASSINIT $FCINIT $RXINIT \
578	$RXCAP -l "$FROM" $RESET \
579	$DATAINIT -g "$DCMD" \
580	-r "$ANSFNAME"
581
582	echo ERROR: $FAX reanswer exec failed >>$CONSOLE ; sleep 30
583
584	break
585	;;
586
587# fax queue : list received fax files
588
589	q*)
590
591 	cd $FAXDIR
592 	case $? in 0) ;; *) echo "cannot cd to $FAXDIR" ; break ;; esac
593 
594 	for f in [0-9]*.[0-9][0-9][0-9] [0-9]*.v
595	do
596		if [ -r $f ]
597		then
598			echo
599			echo Fax files in `pwd` :
600			echo
601			${LS} -l [0-9]*.[0-9][0-9][0-9]  [0-9]*.v 2>/dev/null
602			echo
603		       	break
604 		fi
605	done
606
607	break 
608	;;	
609
610# faxlpr : get phone number and user from current cf* file and run fax send 
611
612	faxlpr)
613
614	# display permissions for debugging
615	echo "$0: running as:" >&2 ; id -a >&2
616	${LS} -ld $FAXDIR >&2
617
618	# the lpr spool directory for printer 'fax'
619	if ! cd $FAXDIR
620	then 
621		echo "$0: cannot cd to $FAXDIR" >&2 ; break 
622	fi
623
624	if ! test -r lock
625	then 
626		echo "$0: can't read lock file" >&2  ; break 
627	fi
628	
629	cfile=`tail -1 lock`
630
631	if ! test -r $cfile
632	then
633		echo "$0: can't read control file" >&2  ; break 
634	fi
635
636	cfile=`cat $cfile`
637
638	num=` echo "$cfile" | sed -e /^[^J]/d -e s/.//`
639	host=`echo "$cfile" | sed -e /^[^H]/d -e s/.//`
640	user=`echo "$cfile" | sed -e /^[^P]/d -e s/.//`
641
642	if ! test "$num"
643	then
644		echo "$0: can't read phone number" >&2  ; break 
645	fi
646
647	# save stdin in a file
648	if ! cat - >> fax$$
649	then
650		echo "$0: can't write `pwd`/fax$$" >&2  ; break 
651	fi
652
653	l=`$FAX send "$num" fax$$`
654
655	case $? in
656	0) echo "$l" | mail -s "fax to $num succeeded" $user@$host ;;
657	*) echo "$l" | mail -s "fax to $num failed   " $user@$host ;;
658	esac
659
660	$RM fax$$ fax$$.???
661
662	break 
663	;;	
664
665# fax start/stop/status : manage fax receive daemon
666
667	start|stop|st*)		# common section
668
669	cd $FAXDIR ; 
670	case $? in 0) ;; *) echo "cannot cd to $FAXDIR" ; break ;; esac
671
672	n= ; for f in ${DEVN}.[0-9]* ; do logfile="$f" ; n=x$n ; done
673
674	case $n in 
675	xx*) echo Warning: multiple logs for $DEV : ; ${LS} ${DEVN}.[0-9]* ;;
676	esac
677
678	case $logfile in 
679	*\*) echo no fax answer process for device $DEV ; break ;;
680	esac
681
682	efaxpid=`echo $logfile | sed -e "s/${DEVN}\.//g"`
683
684	case $cmd in
685
686# fax start - remove stop file so fax answer will continue
687
688	start)
689
690	if [ ! -w . ] ; then echo "can't write  `pwd`" ; break ; fi
691        $RM ${DEVN}.stop
692	break 
693	;;
694
695# fax stop - make a stop file and kill current fax answer daemon
696
697	stop)
698
699	if [ ! -w . ] ; then echo "can't write `pwd`" ; break ; fi
700	touch ${DEVN}.stop
701	echo stopping fax daemon for ${DEV}, pid=$efaxpid
702	kill -HUP $efaxpid
703	break 
704	;;
705
706
707# fax status - display pid and log file for current daemon
708
709	st*)
710
711	if [ -f ${DEVN}.stop ] ; then stat="(set to stop)" ; fi
712
713      	if ps -u $efaxpid 2>/dev/null ; then :
714      	else
715		echo "NOT ACTIVE (last daemon was $efaxpid)"
716      	fi
717
718	echo
719	echo from: $FAXDIR/$logfile
720	echo
721
722	egrep "Warning|Error|starts|activity|opened|received -|done" $logfile
723
724	case $# in 
725	0) ;; *) echo "---------------" ; sleep $1 ; exec $FAX status $1 ;;
726	esac
727
728	break
729	;;
730
731	esac	# common section
732	;;
733
734# fax makefont : rasterize a PS font into a 256-character-wide bitmap
735
736	makefont)
737
738	if [ $# -lt 5 ]
739	then
740        	echo Usage: fax makefont fontname fontsize \
741			cellwidth cellheight filename
742		echo "(cellwidth and cellheight in pixels, fontsize in points)"
743		echo "Example: fax makefont Courier-Bold 8 16 24 efaxfont"
744		echo "will make an 8pt font (there are about 3 pixels per pt)"
745        	exit 1
746	fi
747
748	FNTFMT=pbmraw	# format for font files
749	# FNTFMT=tiffg3	# smaller, available with Ghostscript 3.x or later
750
751	pelwidth=`expr 256 \* $3`
752	gs -q -sDEVICE=$FNTFMT -r204x196 -g${pelwidth}x$4 \
753		-sOutputFile=$5 - <<EOF
754        /$1 findfont $2 scalefont setfont 
755        /buf 1 string def
756        /dx $3 204 div 72 mul def	% x offset per character
757        0 1 255 { 
758           dup dx mul 0.7 add 3 moveto
759           buf exch 0 exch put 
760           buf show
761        } for
762        showpage
763EOF
764	break
765	;;
766
767# fax make : convert a text or Postscript file to fax format
768
769	m*)
770
771	case $# in 0) echo "No files specified" ; ERR=2 ; break ;; esac
772
773	if [ ! -r $1 ] ; then echo "Can't read $1" ; ERR=2 ; break ; fi
774
775
776	read x <$1
777	case $x in
778	%!*|?%!*)
779		echo "$1 is postscript..."
780		# GS can't deal with long paths so we 'cd' 
781		DIRNAME=`dirname $1` ; BASENAME=`basename $1`
782		( cd $DIRNAME ; \
783		$GS -q -sDEVICE=tiffg3 -r$RES -dNOPAUSE -dSAFER \
784		-sOutputFile=$BASENAME.%03d \
785		-sPAPERSIZE=$PAGE \
786		$BASENAME </dev/null >/dev/null )
787		;;
788	II*|MM*|P4*)
789		echo "$1 is an image file..."
790		$EFIX -ve -otiffg3 -p$PAGEDIM -r$RES -n $1.%03d $1
791		;;
792	*)	echo "$1 is text..."
793		$EFIX -ve -otiffg3 -p$PAGEDIM -r$RES -n $1.%03d $TEXTFONT $1
794		;;
795	esac
796
797	break
798	;;
799
800# fax send : fax files to given number, converting first if necessary
801
802	s*)
803	
804	case $# in
805	0) echo "missing phone number to call" ; ERR=2 ; break ;;
806	esac
807
808	# look up names
809
810	case $1 in 
811		[A-Za-z]*) 
812		for f in $DIRFILES ; do
813			if [ -r $f ] ; then TELNO=`$LOOKUP` ; fi
814			case "$TELNO" in '') continue ;; *) break ;; esac
815		done
816		case "$TELNO" in
817			'') echo "Name lookup for $1 failed" ; ERR=2 ; break ;;
818			*) echo "Lookup: $1 = $TELNO" ;;
819		esac
820		;;
821		*) TELNO="$1" ;;
822	esac
823
824	shift 
825
826	case "$TO" in '') TO="$TELNO" ;; *) ;; esac
827
828	TELNO=`echo $TELNO|sed "s/[ 	()][ 	()]*//g"`
829
830	# handle manual dialing and number->dial string conversions
831
832	case "$TELNO" in
833	-m*)	MANINIT="-jX3" ; TELNO="" ;;
834	+*)	TELNO=`echo $TELNO | $TELCVT` ;;
835	esac
836	
837	case $TELNO in 
838	'') 	;; 
839	*)	TELNO="${DIALPREFIX}${TELNO}${DIALSUFFIX}" ;; 
840	esac
841
842	# use `fax make' to convert files if they need to be updated
843
844	FILES=""
845	for f in $* ; do
846		case $f in -) FILES="$FILES -" ; continue ;; esac
847		if [ ! -r $f ] ; then
848	      		echo "can't read file $f" ; ERR=2 ; break 2 
849		fi
850		case $f in
851		*.[0-9][0-9][0-9]) FILES="$FILES $f" ;;	# skip image files
852	   	*)	if echo ${f}.001: $f \; x | make -r -q -f - ; then
853				echo ${f}.nnn is up-to-date
854			else
855	 			$RM ${f}.[0-9][0-9][0-9]
856	 			$FAX make $OPT $f
857			fi
858			if [ -r $f.001 ] ; then 
859                		FILES="$FILES $f.[0-9][0-9][0-9]"
860	      		else		# something's wrong, catch it later
861	        		FILES="$FILES $f.001"
862	      		fi
863			;;
864		esac
865        done
866
867	# check that all files are OK
868
869	for f in $FILES ; do
870		case $f in -) continue ;; esac
871		if [ ! -r $f ] ; then
872	      		echo "can't read file $f" ; ERR=2 ; break 2 
873   	   	fi
874	done
875
876	# send it
877
878	for s in 0 $FAILRETRIES ; do
879
880	case $s in
881	0) ;; *) echo "Will try again in $s seconds" ; sleep $s ;;
882	esac
883
884#	logfile=`$TSTAMP`.log
885        logfile="$TELNO".log
886
887	for t in 0 $BUSYRETRIES ; do
888
889		case $t in 
890		0) ;; *) echo "Will try again in $t seconds" ; sleep $t ;;
891		esac
892
893		DATE=`eval "$DATECMD"`
894		eval HDR=\"$HDR\"
895
896		$NICE $EFAX -v "$VERB" -v "$VERBLOG" \
897		-d/dev/$DEV $LOCK $INIT $SPKR \
898		$CLASSINIT $FCINIT $TXINIT \
899		$TXCAP -l "$FROM" $RESET $HDRFONT -h "$HDR" \
900		$MANINIT -t "$TELNO" $FILES >$logfile
901
902		ERR=$?
903
904		case $ERR in
905		0)	$RM $logfile ; break 2 ;;
906		1)	echo Busy... ;;
907		*)	echo "There were errors (see ${logfile})." ; break ;;
908		esac
909
910	done
911
912	SENT=` sed -n -e '/sent ->/s/^.*-> \([^ ]*\).*/\1/p' $logfile`
913	FILES=`sed -n -e '/failed ->/s/^.*-> \([^ ]*\).*/\1/p' $logfile`
914	case $SENT  in '') break ;; esac
915	case $FILES in '') break ;; esac
916	echo Failed...
917
918	done
919
920	break 
921	;;
922
923# fax hangup : hang up the phone
924
925	hangup*)
926	$NICE exec $EFAX -v $VERB -d/dev/$DEV $LOCK -iZ -T 
927	break
928	;;
929
930# fax fone : open modem device and exec fone script
931
932	fone)
933	
934 	cd $FAXDIR
935 	case $? in 0) ;; *) echo "cannot cd to $FAXDIR" ; break ;; esac
936 
937	$NICE exec $EFAX -v $VERB -d/dev/$DEV $LOCK $INIT \
938		-j#CLS=8 -a#VLS=1 -e "$VCMD $*"
939
940	break
941	;;
942
943# fax (rm|print|view) commands possibly on files in spool directory
944
945	rm|p*|v*)	# common code
946
947	# switch to spool directory if first file is found there
948
949	for f in $FAXDIR/$1 ; do 
950		if test -r $f ; then cd $FAXDIR ; break ; fi
951	done
952	
953	for f in $* ; do
954		case $cmd in 
955
956		rm)	# fax rm : delete files
957		if $RM $f ; then echo deleted $f ; fi
958		;;
959
960	        p*) 	# fax print : print files
961  		echo "$f ... "
962		eval "$PRINT | $PRCMD"
963		;;
964		
965		v*)	# fax view : display images
966  		echo "$f ... "
967		eval "$VIEW | $VIEWCMD"
968		;;
969
970		esac
971	done
972
973	break
974	;;
975
976# fax [receive] : answer phone now and receive fax files
977
978	r*)
979	
980	case $1 in '') file=`$TSTAMP` ;; *) file=$1 ;; esac
981	logfile=${file}.log
982
983	$NICE $EFAX -v "$VERB" -v "$VERBLOG" -d/dev/$DEV $LOCK $INIT $SPKR \
984	$CLASSINIT $FCINIT $RXINIT \
985	$RXCAP -l "$FROM" $RESET \
986	-r $file >$logfile
987
988	ERR=$?
989
990	case $ERR in
991	0)	$RM $logfile ; break ;;
992	1)	echo Busy... ;;
993	*)	echo "There were errors (see ${logfile})." ; break ;;
994	esac
995
996	break
997	;;
998
999# fax new : create a cover page for a fax (needs work)
1000
1001	new)
1002
1003	fname=${1-new.fax}
1004	DATE=`date "+%B %d %Y"`
1005	cat >$fname 2>/dev/null << EOF
1006
1007	________________________________________________
1008
1009			 FAX COVER PAGE
1010	________________________________________________
1011
1012	 To:	x
1013	fax:
1014
1015	________________________________________________
1016
1017	From:	$NAME
1018	 fax:	$FROM
1019
1020	Date:	$DATE
1021
1022	Pages:	1 (including this page)
1023
1024	________________________________________________
1025
1026EOF
1027	${VISUAL-${EDITOR-vi}} $fname
1028
1029	break
1030	;;
1031
1032# fax help : show command arguments
1033
1034	-\?|\?|-h*|h*)
1035
1036cat 1>&2 <<EOF
1037 Usage: 
1038
1039   fax [ r[eceive] [-v] [filename-prefix] ]
1040   fax m[ake] [-l] { postscript-file-name | text-file-name }
1041   fax s[end] [-l] [-v] { -m | telephone-number } filename...
1042   fax { p[rint] | v[iew] | rm } [-l] filename...
1043
1044   fax [ stop | start | st[atus] | q[ueue] ]
1045   fax answer
1046
1047 use -l to create low resolution (98 lpi) faxes
1048 use -m if the number has been dialed manually 	
1049 use -v for verbose output 
1050
1051 if given no arguments, answers the phone and receives a fax.
1052
1053 use VAR=value to set variables (e.g. "fax DEV=cua2 receive")
1054
1055 session logs are written to a file with the date/time as the
1056 file name and extension of .log (except for automatic reception).
1057
1058 fax device is /dev/$DEV, incoming spool directory is $FAXDIR
1059
1060EOF
1061
1062	ERR=1
1063	break
1064	;;
1065
1066	*)
1067	echo "Error. Invalid command (${cmd})" ; ERR=2 ; break
1068	;;
1069
1070esac	
1071done
1072
1073exit $ERR
1074