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