faxaddmodem.sh.in
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:56k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. #! @SCRIPT_SH@
  2. # $Id: faxaddmodem.sh.in,v 1.21 2009/05/25 15:49:16 faxguy Exp $
  3. #
  4. # @WARNING@
  5. #
  6. # HylaFAX Facsimile Software
  7. #
  8. # Copyright (c) 1990-1996 Sam Leffler
  9. # Copyright (c) 1991-1996 Silicon Graphics, Inc.
  10. # HylaFAX is a trademark of Silicon Graphics
  11. # Permission to use, copy, modify, distribute, and sell this software and 
  12. # its documentation for any purpose is hereby granted without fee, provided
  13. # that (i) the above copyright notices and this permission notice appear in
  14. # all copies of the software and related documentation, and (ii) the names of
  15. # Sam Leffler and Silicon Graphics may not be used in any advertising or
  16. # publicity relating to the software without the specific, prior written
  17. # permission of Sam Leffler and Silicon Graphics.
  18. # THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  19. # EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  20. # WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  21. # IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22. # ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23. # OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24. # WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25. # LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26. # OF THIS SOFTWARE.
  27. #
  28. #
  29. # VERSION: @VERSION@
  30. # DATE: @DATE@
  31. # TARGET: @TARGET@
  32. #
  33. #
  34. # faxaddmodem [tty]
  35. #
  36. # This script interactively configures a HylaFAX server
  37. # from keyboard input on a standard terminal.  There may
  38. # be some system dependencies in here; hard to say with
  39. # this mountain of shell code!
  40. #
  41. SPOOL=@SPOOL@
  42. die()
  43. {
  44.     kill -1 $$ # use kill so trap handler is called
  45. }
  46. INTERACTIVE=yes
  47. SKELFILE=
  48. SPEED=
  49. DOFUSER=no
  50. while [ x"$1" != x"" ] ; do
  51.     case $1 in
  52.     -s)     SPEED=$2; shift;;
  53.     -nointeractive) INTERACTIVE=no;;
  54.     -skel=*) SKELFILE="`echo $1 | sed 's/^-skel=//'`";;
  55.     -f)     DOFUSER=yes;;
  56.     -*)     echo "Usage: $0 [-s SPEED] [-f] [-nointeractive] [-skel=proto_file] [ttyname]"; exit 1;;
  57.     *)     TTY=$1;;
  58.     esac
  59.     shift
  60. done
  61. # Test selected modem speed against a list of known standards
  62. if [ "$SPEED" != "" ] && [ "$SPEED" != 38400 ] && [ "$SPEED" != 19200 ] 
  63.    && [ "$SPEED" != 9600 ] && [ "$SPEED" != 4800 ] && [ "$SPEED" != 2400 ] 
  64.    && [ "$SPEED" != 1200 ]; then
  65.    cat<<EOF
  66. Warning, you have selected a DTE-DCE communication rate ($SPEED) that
  67. differs from known standards. $SPEED may not work correctly for sending
  68. and receiving facsimile: check your modem manual to make sure that
  69. $SPEED is acceptable.
  70. EOF
  71. fi
  72. test -f $SPOOL/etc/setup.cache || {
  73.     cat<<EOF
  74. FATAL ERROR: $SPOOL/etc/setup.cache is missing!
  75. The file $SPOOL/etc/setup.cache is not present.  This
  76. probably means the machine has not been setup using the faxsetup(@MANNUM1_8@)
  77. command.  Read the documentation on setting up HylaFAX before you
  78. startup a server system.
  79. EOF
  80.     exit 1
  81. }
  82. . $SPOOL/etc/setup.cache # common configuration stuff
  83. . $SPOOL/etc/setup.modem # modem-specific stuff
  84. #
  85. # Deduce the effective user id:
  86. #   1. POSIX-style, the id program
  87. #   2. the old whoami program
  88. #   3. last gasp, check if we have write permission on /dev
  89. #
  90. euid=`id|$SED -e 's/.*uid=[0-9]*(([^)]*)).*/1/'`
  91. test -z "$euid" && euid=`(whoami) 2>/dev/null`
  92. test -z "$euid" && test -w /dev && euid=root
  93. if [ "$euid" != "root" ]; then
  94.     echo "Sorry, but you must run this script as the super-user!"
  95.     exit 1
  96. fi
  97. # security
  98. TMPDIR=`(mktemp -d /tmp/.faxaddmodem.XXXXXX) 2>/dev/null`
  99. if test X$TMPDIR = X; then
  100.     TMPDIR=/tmp/.faxaddmodem$$
  101. fi
  102. @RM@ -rf $TMPDIR
  103. (umask 077 ; mkdir $TMPDIR) || exit 1
  104. SH=$SCRIPT_SH # shell for use below
  105. CPATH=$SPOOL/etc/config # prefix of configuration file
  106. OUT=$TMPDIR/faxaddmodem.sh$$ # temp file in which modem output is recorded
  107. SVR4UULCKN=$LIBEXEC/lockname # SVR4 UUCP lock name construction program
  108. ONDELAY=$LIBEXEC/ondelay # prgm to open devices blocking on carrier
  109. CAT="$CAT -u" # something to do unbuffered reads and writes
  110. FAX=@FAXUID@ # identity of the fax user
  111. GROUP=/etc/group # where to go for group entries
  112. PROTOGID=@FAXGID@ # group who's gid we use for FAX user
  113. defPROTOGID=10 # use this gid if PROTOGID doesn't exist
  114. MODEMCONFIG=$SPOOL/config # location of prototype modem config files
  115. RMCMD="$RM -f" # forced removal
  116. #
  117. # Build a list of config files in a portable way for grepping...
  118. #
  119. cd $MODEMCONFIG
  120. CONFIG_LIST=""
  121. for file in *; do
  122.   if [ -f "$file" ]; then
  123.     CONFIG_LIST="$CONFIG_LIST $file"
  124.   fi
  125. done
  126. #
  127. # Prompt the user for a string that can not be null.
  128. #
  129. promptForNonNullStringParameter()
  130. {
  131.     x=""
  132.     while [ -z "$x" ]; do
  133. prompt "$2 [$1]?";
  134. if [ "$INTERACTIVE" != "no" ]; then
  135.     read x
  136. else
  137.     echo
  138.     x=
  139. fi
  140. if [ "$x" ]; then
  141.     # strip leading and trailing white space
  142.     x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  143. else
  144.     x="$1"
  145. fi
  146.     done
  147.     param="$x"
  148. }
  149. #
  150. # Prompt the user for a string that can be null.
  151. #
  152. promptForStringParameter()
  153. {
  154.     prompt "$2 [$1]?";
  155.     if [ "$INTERACTIVE" != "no" ]; then
  156. read x
  157.     else
  158. echo
  159. x=
  160.     fi
  161.     if [ "$x" ]; then
  162. # strip leading and trailing white space
  163. x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  164.     else
  165. x="$1"
  166.     fi
  167.     param="$x"
  168. }
  169. #
  170. # Prompt the user for a numeric value.
  171. #
  172. promptForNumericParameter()
  173. {
  174.     x=""
  175.     while [ -z "$x" ]; do
  176. prompt "$2 [$1]?";
  177. if [ "$INTERACTIVE" != "no" ]; then
  178.     read x
  179. else
  180.     echo
  181.     x=
  182. fi
  183. if [ "$x" ]; then
  184.     # strip leading and trailing white space
  185.     x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  186.     match=`expr "$x" : "([0-9]*)"`
  187.     if [ "$match" != "$x" ]; then
  188. echo ""
  189. echo "This must be entirely numeric; please correct it."
  190. echo ""
  191. x="";
  192.     fi
  193. else
  194.     x="$1"
  195. fi
  196.     done
  197.     param="$x"
  198. }
  199. #
  200. # Prompt the user for a C-style numeric value.
  201. #
  202. promptForCStyleNumericParameter()
  203. {
  204.     x=""
  205.     while [ -z "$x" ]; do
  206. prompt "$2 [$1]?";
  207. if [ "$INTERACTIVE" != "no" ]; then
  208.     read x
  209. else
  210.     echo
  211.     x=
  212. fi
  213. if [ "$x" ]; then
  214.     # strip leading and trailing white space and C-style 0x prefix
  215.     x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  216.     match=`expr "$x" : "([0-9]*)" | "$x" : "(0x[0-9a-fA-F]*)"`
  217.     if [ "$match" != "$x" ]; then
  218. echo ""
  219. echo "This must be entirely numeric; please correct it."
  220. echo ""
  221. x="";
  222.     fi
  223. else
  224.     x="$1"
  225. fi
  226.     done
  227.     param="$x"
  228. }
  229. #
  230. # Prompt the user for a boolean value.
  231. #
  232. promptForBooleanParameter()
  233. {
  234.     x=""
  235.     while [ -z "$x" ]; do
  236. prompt "$2 [$1]?";
  237. if [ "$INTERACTIVE" != "no" ]; then
  238.     read x
  239. else
  240.     echo
  241.     x=
  242. fi
  243. if [ "$x" ]; then
  244.     # strip leading and trailing white space
  245.     x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  246.     case "$x" in
  247.     n|no|off) x=no;;
  248.     y|yes|on) x=yes;;
  249.     *)
  250. cat <<EOF
  251. "$x" is not a valid boolean parameter setting;
  252. use one of: "yes", "on", "no", or "off".
  253. EOF
  254. x="";;
  255.     esac
  256. else
  257.     x="$1"
  258. fi
  259.     done
  260.     param="$x"
  261. }
  262. faxGID=`$GREP "^$PROTOGID:" $GROUP | cut -d: -f3`
  263. if [ -z "$faxGID" ]; then faxGID=$defPROTOGID; fi
  264. DEVPATH="/dev/"
  265. if [ -n "`echo $TTY | grep "^/"`" ]; then
  266.     DEVPATH=""
  267. fi
  268. while [ -z "$TTY" ] || [ ! -c $DEVPATH$TTY ]; do
  269.     test "$TTY" != "" && echo "$DEVPATH$TTY is not a terminal device." 1>&2
  270.     if [ "$INTERACTIVE" = "no" ]; then exit 1; fi
  271.     prompt "Serial port that modem is connected to [$TTY]?"; read TTY
  272. done
  273. JUNK="$OUT"
  274. trap "$RMCMD $JUNK; $RMCMD -r $TMPDIR; exit 1" 1 2 15
  275. if [ ! -d $UUCP_LOCKDIR ]; then
  276.     cat<<EOF
  277. The UUCP lock file directory, $UUCP_LOCKDIR, does not appear
  278. to exist or be a directory.  This must be corrected before you
  279. can use this script to setup a modem for use.  Rerun the faxsetup
  280. command to correct this problem.
  281. EOF
  282.     die
  283. fi
  284. PORT=`ttyPort $TTY` # shortened tty port name
  285. LOCKX=`ttyLocks $TTY` # UUCP lock file names
  286. DEVS=`ttyAliases $TTY` # all TTY aliases
  287. tdev=`ttyDev $TTY` # TTY device to use for communication
  288. DEVID="`echo $TTY | tr '/' '_'`" # HylaFAX device identifier
  289. CONFIG=$CPATH.$DEVID # HylaFAX configuration filename
  290. #
  291. # Check that device is not currently being used.
  292. #
  293. for x in $LOCKX; do
  294.     if [ -f $x ]; then
  295. echo "Sorry, the device is currently in use by another program."
  296. die
  297.     fi
  298. done
  299. #
  300. # Look for old/conflicting configuration stuff.
  301. #
  302. OLDCONFIG= OLDFIFO= # set by checkPort
  303. checkPort $TTY
  304. #
  305. # Lock the device for later use when deducing the modem type.
  306. #
  307. JUNK="$JUNK $LOCKX"
  308. LOCKSTR=`expr "         $$" : '.*(..........)'`
  309. # lock the device by all of its names
  310. for x in $LOCKX; do
  311.     echo "$LOCKSTR" > $x
  312. done
  313. if [ "$DOFUSER" = "yes" ]; then
  314.     # zap any gettys or other users
  315.     if [ ! -f $FUSER ]; then
  316. cat<<EOF
  317. Hmm, there does not appear to be an fuser command on your machine.
  318. This means that I am unable to ensure that all processes using the
  319. modem have been killed.  I will keep going, but beware that you may
  320. have competition for the modem.
  321. EOF
  322.     else $FUSER -k $DEVS >/dev/null 2>&1
  323.     fi
  324. fi
  325. cat<<EOF
  326. Ok, time to setup a configuration file for the modem.  The manual
  327. page config(@MANNUM4_5@) may be useful during this process.  Also be aware
  328. that at any time you can safely interrupt this procedure.
  329. EOF
  330. #
  331. # Configuration parameters specific to server operation
  332. # (as opposed to that of the fax modem).  The required
  333. # parameters are *always* emitted in the final created
  334. # configuration file; otherwise parameters are emitted
  335. # only if the configured value differs from the default
  336. # value known to be used by the server.
  337. #
  338. # NB: the order of some parameters is important; e.g.
  339. #     FAXNumber must be after AreaCode and CountryCode.
  340. #
  341. RequiredServerParameters="
  342.     CountryCode
  343.     AreaCode
  344.     FAXNumber
  345.     LongDistancePrefix
  346.     InternationalPrefix
  347.     DialStringRules
  348.     ServerTracing
  349.     SessionTracing
  350.     RecvFileMode
  351.     LogFileMode
  352.     DeviceMode
  353.     RingsBeforeAnswer
  354.     SpeakerVolume
  355.     GettyArgs
  356. "
  357. #
  358. # Some of these things are also modem-dependent.  It's a
  359. # hard call whether to treat them as server-related and
  360. # propagate them to a new config file or to treat them as
  361. # modem-specific and taken them from the prototype modem
  362. # configuration file.
  363. #
  364. OptionalServerParameters="
  365.     LocalIdentifier
  366.     LogFacility
  367.     ClocalAsRoot
  368.     PriorityScheduling
  369.     TagLineFont
  370.     TagLineFormat
  371.     QualifyTSI
  372.     AdaptiveAnswer
  373.     AnswerRotary
  374.     AnswerBias
  375.     NoCarrierRetrys
  376.     PercentGoodLines
  377.     MaxConsecutiveBadLines
  378.     MaxRecvPages
  379.     JobReqBusy
  380.     JobReqNoCarrier
  381.     JobReqNoAnswer
  382.     JobReqNoFConn
  383.     JobReqDataConn
  384.     JobReqProto
  385.     JobReqOther
  386.     PollModemWait
  387.     PollLockWait
  388.     LockDataCalls
  389.     LockVoiceCalls
  390.     FaxRcvdCmd
  391.     NotifyCmd
  392.     PollRcvdCmd
  393.     RingData
  394.     RingFax
  395.     RingVoice
  396.     UUCPLockDir
  397.     UUCPLockTimeout
  398.     UUCPLockType
  399.     PagerMaxMsgLength
  400.     IXOService
  401.     IXODeviceID
  402.     IXOMaxUnknown
  403.     IXOIDProbe
  404.     IXOIDTimeout
  405.     IXOLoginRetries
  406.     IXOLoginTimeout
  407.     IXOGATimeout
  408.     IXOXmitRetries
  409.     IXOXmitTimeout
  410.     IXOAckTimeout
  411. "
  412. ServerParameters="$RequiredServerParameters $OptionalServerParameters"
  413. #
  414. # Default values for server configuration parameters.
  415. #
  416. defaultFAXNumber=""
  417. defaultLocalIdentifier=""
  418. defaultAreaCode=""
  419. defaultCountryCode=""
  420. defaultLongDistancePrefix=""
  421. defaultInternationalPrefix=""
  422. defaultDialStringRules=""
  423. defaultServerTracing=1
  424. defaultSessionTracing=0xFFF
  425. defaultRecvFileMode=0600
  426. defaultLogFileMode=0600
  427. defaultDeviceMode=0600
  428. defaultRingsBeforeAnswer=0
  429. defaultSpeakerVolume=quiet
  430. defaultGettyArgs=""
  431. defaultQualifyTSI=""
  432. defaultJobReqBusy=180
  433. defaultJobReqNoCarrier=300
  434. defaultJobReqNoAnswer=300
  435. defaultJobReqNoFConn=300
  436. defaultJobReqDataConn=300
  437. defaultJobReqProto=60
  438. defaultJobReqOther=300
  439. defaultPollModemWait=30
  440. defaultPollLockWait=30
  441. defaultTagLineFont=""
  442. defaultTagLineFormat=""From %%n|%c|Page %%P of %%T""
  443. defaultPercentGoodLines=95
  444. defaultMaxConsecutiveBadLines=5
  445. defaultMaxRecvPages=1000
  446. defaultLogFacility=daemon
  447. defaultClocalAsRoot=""
  448. defaultPriorityScheduling=""
  449. defaultAdaptiveAnswer=""
  450. defaultAnswerRotary=""
  451. defaultAnswerBias=""
  452. defaultFaxRcvdCmd=""
  453. defaultNoCarrierRetrys=""
  454. defaultNotifyCmd="bin/notify"
  455. defaultPollRcvdCmd=""
  456. defaultRingData=""
  457. defaultRingFax=""
  458. defaultRingVoice=""
  459. defaultUUCPLockDir="$UUCP_LOCKDIR"
  460. defaultUUCPLockTimeout=30
  461. defaultUUCPLockType="$UUCP_LOCKTYPE"
  462. defaultLockDataCalls=Yes
  463. defaultLockVoiceCalls=Yes
  464. defaultPagerMaxMsgLength=""
  465. defaultIXOService=""
  466. defaultIXODeviceID=""
  467. defaultIXOMaxUnknown=""
  468. defaultIXOIDProbe=""
  469. defaultIXOIDTimeout=""
  470. defaultIXOLoginRetries=""
  471. defaultIXOLoginTimeout=""
  472. defaultIXOGATimeout=""
  473. defaultIXOXmitRetries=""
  474. defaultIXOXmitTimeout=""
  475. defaultIXOAckTimeout=""
  476. #
  477. # Initialize server parameters from the defaults.
  478. #
  479. setupServerParameters()
  480. {
  481.     for i in $ServerParameters; do
  482. eval $i=$default$i
  483.     done
  484. }
  485. #
  486. # Get server config values from an existing config file.
  487. #
  488. getServerParameters()
  489. {
  490.     eval `$SED -e 's/[  ]*#.*$//' 
  491. -e "s;([^:]*):[  ]*(.*);1='2';" $1`
  492. }
  493. #
  494. # Echo the configuration lines for those server parameters
  495. # whose value is different from the default value.  Note
  496. # that we handle the case where there is embedded whitespace
  497. # by enclosing the parameter value in quotes.
  498. #
  499. echoServerSedCommands()
  500. {
  501.     (for i in $RequiredServerParameters; do
  502. eval echo "$i:$$i:"
  503.      done
  504.      for i in $OptionalServerParameters; do
  505. eval echo "$i:$$i:$default$i"
  506.      done) | $AWK -F: '
  507. function p(tag, value)
  508. {
  509.     tabs = substr("ttt", 1, 3-int((length(tag)+1)/8));
  510.     if (match(value, "^[^"].*[ ]") == 0)
  511. printf "%s:%s%s\n", tag, tabs, value
  512.     else
  513. printf "%s:%s"%s"\n", tag, tabs, value
  514. }
  515. BEGIN { printf "/^#.*BEGIN-SERVER/,/^#.*END-SERVER/c\n" }
  516. $2 != $3{ p($1, $2) }
  517. END { printf "#n" }' # terminate input text to ``c'' command
  518. }
  519. #
  520. # Compile a table of configuration parameters prompts into
  521. # a shell program that can be ``eval'd'' to prompt the user
  522. # for changes to the current parameter settings.
  523. #
  524. compilePrompts()
  525. {
  526.     $AWK -F'[ ]+' '
  527. function p(t)
  528. {
  529.     printf "promptFor%sParameter "$%s" "%s";%s="$param"n", t, $2, $3, $2
  530. }
  531. $1 == "#" { p("Numeric"); next }
  532. $1 == "C#" { p("CStyleNumeric"); next }
  533. $1 == "S" { p("String"); next }
  534. $1 == "NNS" { p("NonNullString"); next }
  535. $1 == "B" { p("Boolean"); next }
  536. { printf "promptFor%sn", $1 }
  537. '
  538. }
  539. #
  540. # Prompt the user for volume setting.
  541. #
  542. promptForSpeakerVolume()
  543. {
  544.     x=""
  545.     while [ -z "$x" ]; do
  546. prompt "Modem speaker volume [$SpeakerVolume]?";
  547. if [ "$INTERACTIVE" != "no" ]; then
  548.     read x
  549. else
  550.     echo
  551.     x=
  552. fi
  553. if [ "$x" != "" ]; then
  554.     # strip leading and trailing white space
  555.     x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  556.     case "$x" in
  557.     [oO]*) x=off;;
  558.     [lL]*) x=low;;
  559.     [qQ]*) x=quiet;;
  560.     [mM]*) x=medium;;
  561.     [hH]*) x=high;;
  562.     *)
  563. cat <<EOF
  564. "$x" is not a valid speaker volume setting; use one
  565. of: "off", "low", "quiet", "medium", and "high".
  566. EOF
  567. x="";;
  568.     esac
  569. else
  570.     x="$SpeakerVolume"
  571. fi
  572.     done
  573.     SpeakerVolume="$x"
  574. }
  575. #
  576. # Verify that the fax number, area code, and country
  577. # code jibe.  Perhaps this is too specific to the USA?
  578. #
  579. checkFaxNumber()
  580. {
  581.     pat="["]*+$CountryCode[-. ]*$AreaCode[-. ]*[0-9][- .0-9]*["]*"
  582.     match=`expr "$FAXNumber" : "($pat)"`
  583.     if [ "$match" != "$FAXNumber" ]; then
  584. cat<<EOF
  585. Your facsimile phone number ($FAXNumber) does not agree with your
  586. country code ($CountryCode) or area code ($AreaCode).  The number
  587. should be a fully qualified international dialing number of the form:
  588.     +$CountryCode $AreaCode <local phone number>
  589. Spaces, hyphens, and periods can be included for legibility.  For example,
  590.     +$CountryCode.$AreaCode.555.1212
  591. is a possible phone number (using your country and area codes).
  592. EOF
  593. ok=no;
  594.     fi
  595. }
  596. #
  597. # Verify that a number is octal and if not, add a prefixing "0".
  598. #
  599. checkOctalNumber()
  600. {
  601.     param=$1
  602.     if [ "`expr "$param" : '(.)'`" != 0 ]; then
  603. param="0${param}"
  604. return 0
  605.     else
  606. return 1
  607.     fi
  608. }
  609. checkForLocalFile()
  610. {
  611.     f="`echo $1 | $SED 's/"//g'`"
  612.     if [ ! -f $SPOOL/$f ]; then
  613. cat<<EOF
  614. Warning, the $2 file,
  615.     $SPOOL/$f
  616. does not exist, or is not a plain file.  This file must
  617. reside in the $SPOOL directory tree.
  618. EOF
  619. ok=no;
  620.     fi
  621. }
  622. #
  623. # Print the current server configuration parameters.
  624. #
  625. printServerConfig()
  626. {
  627.     (for i in $ServerParameters; do
  628. eval echo "$i:$$i:$default$i"
  629.     done) | $AWK -F: '
  630. function p(tag, value)
  631. {
  632.     tabs = substr("ttt", 1, 3-int((length(tag)+1)/8));
  633.     printf "%s:%s%sn", tag, tabs, value
  634. }
  635. BEGIN { printf "nThe non-default server configuration parameters are:nn" }
  636. $2 != $3{ p($1, $2) }
  637. END { printf "n" }'
  638. }
  639. setupServerParameters
  640. SCHEDCONFIG=$CPATH
  641. if [ -f $SCHEDCONFIG ]; then
  642.     echo "Reading scheduler config file $SCHEDCONFIG."
  643.     echo ""
  644.     getServerParameters $SCHEDCONFIG
  645. fi
  646. if [ -f $CONFIG ] || [ -z "$OLDCONFIG" ]; then
  647.     OLDCONFIG=$CONFIG
  648. fi
  649. if [ -f $OLDCONFIG ]; then
  650.     echo "Hey, there is an existing config file $OLDCONFIG..."
  651.     getServerParameters $OLDCONFIG
  652.     ok="skip" # skip prompting first time through
  653. else
  654.     echo "No existing configuration, let's do this from scratch."
  655.     echo ""
  656.     if [ -n "$SKELFILE" ]; then
  657. getServerParameters "$SKELFILE" # get from specified skeletal file
  658.     else
  659. getServerParameters $MODEMCONFIG/skel # get from skeletal file
  660.     fi
  661.     ok="prompt" # prompt for parameters
  662. fi
  663. CHECK="`$GREP "AreaCode:" $SPOOL/etc/config | sed 's/.*:[  ]*//g'`"
  664. if [ -n "$CHECK" ]; then
  665.     AreaCode="$CHECK"
  666. fi
  667. CHECK="`$GREP "CountryCode:" $SPOOL/etc/config | sed 's/.*:[  ]*//g'`"
  668. if [ -n "$CHECK" ]; then
  669.     CountryCode="$CHECK"
  670. fi
  671. if [ -z "$FAXNumber" ]; then
  672.     FAXNumber="+$CountryCode $AreaCode 555-1212"
  673. fi
  674. isOK()
  675. {
  676.     x="$1"
  677.     test -z "$x" || test "$x" = y || test "$x" = yes
  678. }
  679. isNotOK()
  680. {
  681.     x="$1"
  682.     test -n "$x" && test "$x" != y && test "$x" != yes
  683. }
  684. #
  685. # Prompt user for server-related configuration parameters
  686. # and do consistency checking on what we get.
  687. #
  688. PROMPTS=$TMPDIR/faxpr$$
  689. JUNK="$JUNK $PROMPTS"
  690. while isNotOK $ok; do
  691.     if [ "$ok" != skip ]; then
  692. test -f $PROMPTS || compilePrompts>$PROMPTS<<EOF
  693. # CountryCode Country code
  694. # AreaCode Area code
  695. NNS FAXNumber Phone number of fax modem
  696. S LocalIdentifier Local identification string (for TSI/CIG)
  697. # LongDistancePrefix Long distance dialing prefix
  698. # InternationalPrefix International dialing prefix
  699. NNS DialStringRules Dial string rules file (relative to $SPOOL)
  700. C# ServerTracing Tracing during normal server operation
  701. C# SessionTracing Tracing during send and receive sessions
  702. # RecvFileMode Protection mode for received facsimile
  703. # LogFileMode Protection mode for session logs
  704. # DeviceMode Protection mode for $TTY
  705. # RingsBeforeAnswer Rings to wait before answering
  706. SpeakerVolume
  707. S GettyArgs Command line arguments to getty program
  708. S QualifyTSI
  709. Pathname of TSI access control list file (relative to $SPOOL)
  710. S TagLineFont Tag line font file (relative to $SPOOL)
  711. S TagLineFormat Tag line format string
  712. C# UUCPLockTimeout
  713. Time before purging a stale UUCP lock file (secs)
  714. B LockDataCalls Hold UUCP lockfile during inbound data calls
  715. B LockVoiceCalls Hold UUCP lockfile during inbound voice calls
  716. # PercentGoodLines
  717. Percent good lines to accept during copy quality checking
  718. # MaxConsecutiveBadLines
  719. Max consecutive bad lines to accept during copy quality checking
  720. # MaxRecvPages
  721. Max number of pages to accept in a received facsimile
  722. S LogFacility Syslog facility name for ServerTracing messages
  723. B ClocalAsRoot Set UID to 0 to manipulate CLOCAL
  724. B PriorityScheduling Use available priority job scheduling mechanism
  725. EOF
  726. . $PROMPTS
  727.     fi
  728.     checkOctalNumber $RecvFileMode && RecvFileMode=$param
  729.     checkOctalNumber $LogFileMode && LogFileMode=$param
  730.     checkOctalNumber $DeviceMode && DeviceMode=$param
  731.     checkForLocalFile $DialStringRules "dial string rules"
  732.     checkFaxNumber;
  733.     if [ "$TagLineFont" != "" ] && [ "$TagLineFont" != '""' ]; then
  734. checkForLocalFile $TagLineFont "tag line font";
  735.     fi
  736.     printServerConfig; prompt "Are these ok [yes]?";
  737.     if [ "$INTERACTIVE" != "no" ]; then
  738. read ok
  739.     else
  740. echo
  741. ok=
  742.     fi
  743. done
  744. #
  745. # We've got all the server-related parameters, now for the modem ones.
  746. #
  747. cat<<EOF
  748. Now we are going to probe the tty port to figure out the type
  749. of modem that is attached.  This takes a few seconds, so be patient.
  750. Note that if you do not have the modem cabled to the port, or the
  751. modem is turned off, this may hang (just go and cable up the modem
  752. or turn it on, or whatever).
  753. EOF
  754. case $TARGET in
  755. *-sunos*)
  756.     #
  757.     # Sun systems have a command for manipulating software
  758.     # carrier on a terminal line.  Set or reset carrier
  759.     # according to the type of tty device being used.
  760.     #
  761.     case $TTY in
  762.     tty*) ttysoftcar -y $TTY >/dev/null 2>&1;;
  763.     cua*) ttysoftcar -n $TTY >/dev/null 2>&1;;
  764.     esac
  765.     ;;
  766. esac
  767. if [ -x ${ONDELAY} ]; then
  768.     onDev() {
  769. if [ "$1" = -c ]; then
  770.     shift; catpid=`${ONDELAY} $tdev $SH -c "$* >$OUT" & echo $!`
  771. else
  772.     ${ONDELAY} $tdev $SH -c "$*"
  773. fi
  774.     }
  775. else
  776. cat<<'EOF'
  777. The "ondelay" program to open the device without blocking is not
  778. present.  We're going to try to continue without it; let's hope that
  779. the serial port won't block waiting for carrier...
  780. EOF
  781.     onDev() {
  782. if [ "$1" = -c ]; then
  783.     shift; catpid=`$SH <$tdev >$tdev -c "$* >$OUT" & echo $!`
  784. else
  785.     $SH <$tdev >$tdev -c "$*"
  786. fi
  787.     }
  788. fi
  789. STTY=`ttyStty $tdev` # appropriate stty cmd
  790. #
  791. # Send each command in SendString to the modem and collect
  792. # the result in $OUT.  Read this very carefully.  It's got
  793. # a lot of magic in it!
  794. #
  795. SendToModem()
  796. {
  797.     COMMAND=$*
  798.     sleep 1 # wait for previous kill
  799.     case $TARGET in
  800.     *-linux*) ;;
  801.     *) onDev $STTY 0; sleep 1 ;; # reset the modem (hopefully)
  802.     esac
  803. # start listening for output
  804.     onDev -c "$STTY clocal && exec $CAT $tdev"; sleep 2
  805.     #
  806.     # NB: eof is set to ^A so that only 1 character is needed
  807.     #     for a pending read on HPUX systems
  808.     #
  809.     onDev $STTY -echo -icrnl -ixon -ixoff -isig eof '"^A"' clocal $SPEED;
  810. sleep 1
  811.     # NB: merging r & ATQ0 causes some modems problems
  812.     printf "r" >$tdev; sleep 1; # force consistent state
  813.     printf "ATQ0V1E1r" >$tdev; sleep 1; # enable echo and result codes
  814.     for i in $COMMAND; do
  815. printf "$ir" >$tdev; sleep 1;
  816.     done
  817.     kill -9 $catpid; catpid=
  818.     # NB: [*&\\$] must have the "$" last for AIX (yech)
  819.     pat=`echo "$i"|$SED -e 's/[*&\\$]/\\&/g'` # escape regex metacharacters
  820.     RESPONSE=`tr -ds '15' '12' < $OUT | 
  821. $SED -n "/$pat/{n;s/ *$//;p;q;}"`
  822. }
  823. echo ""
  824. if [ -z "$SPEED" ]; then
  825.     #
  826.     # Probe for the highest speed at which the modem
  827.     # responds to "AT" with "OK".
  828.     #
  829.     printf "Probing for best speed to talk to modem:"
  830.     SPEEDS=`ttySpeeds $tdev` # set of speeds for auto-bauding
  831.     for SPEED in $SPEEDS
  832.     do
  833. printf " $SPEED"
  834. SendToModem AT >/dev/null 2>&1
  835. sleep 1
  836. RESULT=`tr -ds '15' '12' < $OUT | $SED -n '$p'`
  837. test "$RESULT" = OK && break;
  838.     done
  839.     if [ "$RESULT" != OK ]; then
  840. echo ""
  841. echo "Unable to deduce DTE-DCE speed; check that you are using the"
  842. echo "correct device and/or that your modem is setup properly.  If"
  843. echo "all else fails, try the -s option to lock the speed."
  844. die
  845.     fi
  846.     echo " OK."
  847. else
  848.     echo "Using user-specified $SPEED to talk to modem."
  849. fi
  850. RESULT="";
  851. while [ -z "$RESULT" ]; do
  852.     #
  853.     # This goes in the background while we try to
  854.     # reset the modem.  If something goes wrong, it'll
  855.     # nag the user to check on the problem.
  856.     #
  857.     (trap "exit 1" 1 2 15;
  858.      while true; do
  859. sleep 10;
  860. echo ""
  861. echo "Hmm, something seems to be hung, check your modem eh?"
  862.      done)& nagpid=$!
  863.     trap "$RMCMD $JUNK; $RMCMD -r $TMPDIR; kill $nagpid $catpid; exit 1" 1 2 15
  864.     SendToModem "AT+FCLASS=?"  # ask for class support
  865.     exec 3>&2 2> /dev/null  # Mute stderr against child death
  866.     kill $nagpid
  867.     wait $nagpid            # Really waits its end
  868.     exec 2>&3 3>&-          # Restore stderr
  869.     trap "$RMCMD $JUNK; $RMCMD -r $TMPDIR; test "$catpid" && kill $catpid; exit 1" 1 2 15
  870.     sleep 1
  871.     RESULT=`tr -ds '15' '12' < $OUT | $SED -n '$p'`
  872.     if [ -z "$RESPONSE" ]; then
  873. echo ""
  874. echo "There was no response from the modem.  Perhaps the modem is"
  875. echo "turned off or the cable between the modem and host is not"
  876. echo "connected.  Please check the modem and hit a carriage return"
  877. prompt "when you are ready to try again:"
  878. read x
  879.     fi
  880. done
  881. ModemType="" Manufacturer="" Model="" ProtoType=skel
  882. #
  883. # Initialize desired flow control scheme
  884. # according to the device name (if it's
  885. # meaningful).  Otherwise, setup to use any
  886. # default flow control defined in the prototype
  887. # configuration file.
  888. #
  889. FlowControl=default
  890. case $TARGET in
  891. *-irix*)
  892.     case $TTY in
  893.     ttym${PORT}) FlowControl=xonxoff;;
  894.     ttyf${PORT}) FlowControl=rtscts;;
  895.     esac
  896.     ;;
  897. esac
  898. #
  899. # Prompt the user for a flow control scheme.
  900. #
  901. promptForFlowControlParameter()
  902. {
  903.     x=""
  904.     while [ -z "$x" ]; do
  905. prompt "$2 [$1]?";
  906. if [ "$INTERACTIVE" != "no" ]; then
  907.     read x
  908. else
  909.     echo
  910.     x=
  911. fi
  912. if [ "$x" ]; then
  913.     # strip leading and trailing white space
  914.     x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  915.     case "$x" in
  916.     xon*|XON*) x=xonxoff;;
  917.     rts*|RTS*) x=rtscts;;
  918.     def*|DEF*) x=default;;
  919.     *)
  920. cat <<EOF
  921. "$x" is not a valid flow control parameter setting; use one of:
  922. xonxoff for software flow control
  923. rtscts for hardware flow control
  924. default for whatever is set in a prototype config file
  925. Note that this setting defines the scheme to use when sending
  926. and receiving facsimile.  Many modems do not support hardware
  927. flow control during fax operation though they do support it for
  928. data communication.
  929. EOF
  930. x="";;
  931.     esac
  932. else
  933.     x="$1"
  934. fi
  935.     done
  936.     param="$x"
  937. }
  938. getFlowControlConfig()
  939. {
  940.     promptForFlowControlParameter "$FlowControl" "DTE-DCE flow control scheme"
  941.     case "$param" in
  942.     xon*|XON*) FlowControl=XONXOFF;;
  943.     rts*|RTS*) FlowControl=RTSCTS;;
  944.     def*|DEF*) FlowControl=DEFAULT;;
  945.     esac
  946. }
  947. #
  948. # Select a configuration file for a modem based on the
  949. # deduced modem type.  Each routine below sends a set
  950. # of commands to the modem to figure out the modem model
  951. # and manufacturer and then compares them against the
  952. # set of known values in associated config files.
  953. # Note that this is done with a tricky bit of shell
  954. # hacking--generating a case statement that is then
  955. # eval'd with the result being the setup of the
  956. # ProtoType shell variable.
  957. #
  958. configureClass2Modem()
  959. {
  960.     ModemType=Class2
  961.     echo "Hmm, this looks like a Class 2 modem."
  962.     SendToModem "AT+FCLASS=2" "AT+FMFR?"
  963.     Manufacturer=$RESPONSE
  964.     echo "Modem manufacturer is "$Manufacturer"."
  965.     SendToModem "AT+FCLASS=2" "AT+FMDL?"
  966.     Model=$RESPONSE
  967.     echo "Modem model is "$Model"."
  968.     getFlowControlConfig
  969.     eval `(cd $MODEMCONFIG; 
  970. $GREP 'CONFIG:[  ]*CLASS2:' $CONFIG_LIST |
  971. $AWK -F: '
  972.     BEGIN { print "case "$Manufacturer-$Model-$FlowControl" in" }
  973.     FILENAME ~ /^OLD/ { next }
  974.     FILENAME ~ /^config./ { next }
  975.     { print $4 ") ProtoType=" $1 ";;" }
  976.     END { print "*) ProtoType=class2;;"; print "esac" }
  977. ')`
  978. }
  979. #
  980. # As above, but for Class 2.0/2.1 modems.
  981. # Class 2.1 modems without a prototype also use class2.0.
  982. #
  983. configureClass2dot0Modem()
  984. {
  985.     if [ "$ModemType" = "Class2.1" ]; then
  986. echo "Hmm, this looks like a Class 2.1 modem."
  987. MATCHSTR=CLASS2.1
  988. ATSTR=AT+FCLASS=2.1
  989. PROTOSTR=class2.1
  990.     else echo "Hmm, this looks like a Class 2.0 modem."
  991. MATCHSTR=CLASS2.0
  992. ATSTR=AT+FCLASS=2.0
  993. PROTOSTR=class2.0
  994.     fi
  995.     #
  996.     SendToModem "$ATSTR" "AT+FMI?"
  997.     # if we get an ERROR revert to ATI
  998.     if [ "$RESPONSE" = "ERROR" ]; then SendToModem "$ATSTR" "ATI"; fi
  999.     Manufacturer=$RESPONSE
  1000.     echo "Modem manufacturer is "$Manufacturer"."
  1001.     SendToModem "$ATSTR" "AT+FMM?"
  1002.     Model=$RESPONSE
  1003.     echo "Modem model is "$Model"."
  1004.     getFlowControlConfig
  1005.     eval `(cd $MODEMCONFIG; 
  1006. $GREP "CONFIG:[  ]*$MATCHSTR:" $CONFIG_LIST |
  1007. $AWK -F: '
  1008.     BEGIN { print "case "$Manufacturer-$Model-$FlowControl" in" }
  1009.     FILENAME ~ /^OLD/ { next }
  1010.     FILENAME ~ /^config./ { next }
  1011.     { print $4 ") ProtoType=" $1 ";;" }
  1012.     END { print "*) ProtoType=$PROTOSTR;;"; print "esac" }
  1013. ')`
  1014. }
  1015. #
  1016. # Class 1/1.0 modems are handled a bit differently as
  1017. # there may be no commands to obtain the manufacturer
  1018. # and model.  Instead we use ATI0 and ATI3 to get the
  1019. # product codes and then compare them against the set
  1020. # of known values in the config files.
  1021. #
  1022. configureClass1Modem()
  1023. {
  1024.     Manufacturer=Unknown Model=Unknown
  1025.     if [ "$ModemType" = "Class1" ]; then
  1026. echo "Hmm, this looks like a Class 1 modem."
  1027. MATCHSTR=CLASS1
  1028. PROTOSTR=class1
  1029.     else echo "Hmm, this looks like a Class 1.0 modem."
  1030. MATCHSTR=CLASS1.0
  1031. PROTOSTR=class1.0
  1032.     fi
  1033.     SendToModem "ATI0"; CODE="$RESPONSE"
  1034.     echo "Product code (ATI0) is "$CODE"."
  1035.     SendToModem "ATI3"; INFO="$RESPONSE"
  1036.     echo "Other information (ATI3) is "$INFO"."
  1037.     getFlowControlConfig
  1038.     eval `(cd $MODEMCONFIG; $GREP "CONFIG:[  ]*$MATCHSTR:" $CONFIG_LIST) |
  1039. $SED 's/:[  ]*/:/g' |
  1040. $AWK -F: '
  1041. BEGIN { proto = "" }
  1042. FILENAME ~ /^OLD/ { next }
  1043. FILENAME ~ /^config./ { next }
  1044. (C == $4 || (C ~ $4 && $4 ~ /*/)) && I ~ $5 && F ~ $6 {
  1045.   if (proto != "") {
  1046.       print "echo "Warning, multiple configuration files exist for this modem,";"
  1047.       print "echo "   the file " $1 " is ignored.";"
  1048.   } else
  1049.       proto = $1 " " $7;
  1050. }
  1051. END { if (proto == "")
  1052.       proto = "$PROTOSTR"
  1053.   print "ProtoType=" proto
  1054. }
  1055. ' C="$CODE" I="$INFO" F="$FlowControl" -`
  1056.     echo "Modem manufacturer is "$Manufacturer"."
  1057.     echo "Modem model is "$Model"."
  1058. }
  1059. giveup()
  1060. {
  1061.     echo "The result of the AT+FCLASS=? command was:"
  1062.     echo ""
  1063.     cat $OUT
  1064.     cat<<EOF
  1065. We were unable to deduce what type of modem you have.  This means that
  1066. it did not respond as a Class 1, Class 2, or Class 2.0 modem should.
  1067. If you believe that your modem conforms to the Class 1, Class 2, or
  1068. Class 2.0 interface specification, then check that the modem is
  1069. operating properly and that you can communicate with the modem from the
  1070. host.  If your modem is not one of the above types of modems, then this
  1071. software does not support it and you will need to write a driver that
  1072. supports it.
  1073. EOF
  1074.     die
  1075. }
  1076. echo ""
  1077. if [ "$RESULT" = "OK" ]; then
  1078.     # Looks like a usable fax modem.  Get more information.
  1079.     cat<<EOF
  1080. About fax classes:
  1081. The difference between fax classes has to do with how HylaFAX interacts
  1082. with the modem and the fax protocol features that are used when sending
  1083. or receiving faxes.  One class isn't inherently better than another;
  1084. however, one probably will suit a user's needs better than others.
  1085.     
  1086. Class 1 relies on HylaFAX to perform the bulk of the fax protocol.
  1087. Class 2 relies on the modem to perform the bulk of the fax protocol.
  1088. Class 2.0 is similar to Class 2 but may include more features.
  1089. Class 1.0 is similar to Class 1 but may add V.34-fax capability.
  1090. Class 2.1 is similar to Class 2.0 but adds V.34-fax capability.
  1091.       
  1092. HylaFAX generally will have more features when using Class 1/1.0 than
  1093. when using most modems' Class 2 or Class 2.0 implementations.  Generally
  1094. any problems encountered in Class 1/1.0 can be resolved by modifications
  1095. to HylaFAX, but usually any problems encountered in Class 2/2.0/2.1 will
  1096. require the modem manufacturer to resolve it.
  1097. Use Class 1 unless you have a good reason not to.
  1098. EOF
  1099.     # Here we build up a MODEMCLASSES string and follow
  1100.     # (for no real reason) the enumeration in faxd/ClassModem.c++
  1101.     # Class 1 = 1; Class 2 = 2; Class 2.0 = 3;
  1102.     # Class 1.0 = 4; Class 2.1 = 5;   
  1103.     RESPONSE="`echo $RESPONSE | $SED -e 's/[()]//g' 
  1104. -e 's/2.0/3/g' -e 's/1.0/4/g' -e 's/2.1/5/g'`";
  1105.     SUPPORT="This modem looks to have support for Class "
  1106.     MODEMCLASSES="";
  1107.     for CLASS in 1 4 2 3 5; do
  1108. if [ "`echo $RESPONSE | $GREP $CLASS`" != "" ]; then
  1109.     if [ "$MODEMCLASSES" != "" ]; then
  1110.  SUPPORT=`echo $SUPPORT | $SED 's/ and /, /g'`" and ";
  1111.     fi
  1112.     MODEMCLASSES=$MODEMCLASSES$CLASS" ";
  1113.     SUPPORT=$SUPPORT$CLASS
  1114. fi
  1115.     done;
  1116.     MODEMCLASSES=`echo $MODEMCLASSES | $SED -e 's/3/2.0/g' -e 's/4/1.0/g' -e 's/5/2.1/g' -e 's/ $//g'`
  1117.     SUPPORT=`echo $SUPPORT | $SED -e 's/3/2.0/g' -e 's/4/1.0/g' -e 's/5/2.1/g'`.
  1118.     if [ "`echo $SUPPORT | $GREP " "`" = "" ]; then echo $SUPPORT; fi
  1119.     case "$MODEMCLASSES" in
  1120.     "") giveup;;
  1121.     "1") ModemType=Class1; configureClass1Modem;;
  1122.     "2") configureClass2Modem;;
  1123.     "2.0") ModemType=Class2.0; configureClass2dot0Modem;;
  1124.     "1.0") ModemType=Class1.0; configureClass1Modem;;
  1125.     "2.1") ModemType=Class2.1; configureClass2dot0Modem;;
  1126.     *)
  1127. DEFAULTCLASS=`echo $MODEMCLASSES | $SED 's/([^ ]*).*/1/g'`
  1128. x=""
  1129. while [ "`echo " $MODEMCLASSES " | $GREP " $x "`" = "" ]; do
  1130.     echo $SUPPORT
  1131.     prompt "How should it be configured [$DEFAULTCLASS]?";
  1132.     if [ "$INTERACTIVE" != "no" ]; then
  1133. read x
  1134.     else
  1135. echo
  1136. x=
  1137.     fi
  1138.     if [ "$x" = "" ]; then x=$DEFAULTCLASS; fi
  1139. done
  1140. echo ""
  1141. case "$x" in
  1142. "1") ModemType=Class1; configureClass1Modem;;
  1143. "2") configureClass2Modem;;
  1144. "2.0") ModemType=Class2.0; configureClass2dot0Modem;;
  1145. "1.0") ModemType=Class1.0; configureClass1Modem;;
  1146. "2.1") ModemType=Class2.1; configureClass2dot0Modem;;
  1147. esac
  1148.     esac
  1149. else
  1150.     giveup
  1151. fi
  1152. #
  1153. # Given a modem type, manufacturer and model, select
  1154. # a prototype configuration file to work from.
  1155. #
  1156. echo ""
  1157. echo "Using prototype configuration file $ProtoType..."
  1158. proto=$MODEMCONFIG/$ProtoType
  1159. if [ ! -f $proto ]; then
  1160.     echo "Uh oh, I can't find the prototype file"
  1161.     echo ""
  1162.     echo ""$proto""
  1163.     echo ""
  1164.     if [ "$ProtoType" != "skel" ]; then
  1165.         prompt "Do you want to continue using the skeletal configuration file [yes]?"
  1166. if [ "$INTERACTIVE" != "no" ]; then
  1167.     read x
  1168. else
  1169.     echo
  1170.     x=
  1171. fi
  1172. isOK $x || die
  1173. ProtoType=skel;
  1174. if [ -n "$SKELFILE" ]; then
  1175.     proto="$SKELFILE"
  1176. else
  1177.     proto=$MODEMCONFIG/$ProtoType;
  1178. fi
  1179. if [ ! -f $proto ]; then
  1180.     cat<<EOF
  1181. Sigh, the skeletal configuration file is not available either.  There
  1182. is nothing that I can do without some kind of prototype config file;
  1183. I'm bailing out...
  1184. EOF
  1185.     die
  1186. fi
  1187.     else
  1188. echo "There is nothing more that I can do; I'm bailing out..."
  1189. die
  1190.     fi
  1191. fi
  1192. #
  1193. # Prompt the user for an AT-style command.
  1194. #
  1195. promptForATCmdParameter()
  1196. {
  1197.     prompt "$2 [$1]?";
  1198.     if [ "$INTERACTIVE" != "no" ]; then
  1199. read x
  1200.     else
  1201. echo
  1202. x=
  1203.     fi
  1204.     if [ "$x" ]; then
  1205. # strip leading and trailing white space, quote marks;
  1206. # redouble any backslashes lost through shell processing
  1207. x=`echo "$x" | $SED 
  1208.     -e 's/^[  ]*//' 
  1209.     -e 's/[  ]*$//' 
  1210.     -e 's/"//g' -e 's/\\/&&/g'`
  1211.     else
  1212. x="$1"
  1213.     fi
  1214.     param="$x"
  1215. }
  1216. #
  1217. # Prompt the user for a bit order.
  1218. #
  1219. promptForBitOrderParameter()
  1220. {
  1221.     x=""
  1222.     while [ -z "$x" ]; do
  1223. prompt "$2 [$1]?";
  1224. if [ "$INTERACTIVE" != "no" ]; then
  1225.     read x
  1226. else
  1227.     echo
  1228.     x=
  1229. fi
  1230. if [ "$x" ]; then
  1231.     # strip leading and trailing white space
  1232.     x=`echo "$x" | $SED -e 's/^[  ]*//' -e 's/[  ]*$//'`
  1233.     case "$x" in
  1234.     [lL]*) x=LSB2MSB;;
  1235.     [mM]*) x=MSB2LSB;;
  1236.     *)
  1237. cat <<EOF
  1238. "$x" is not a valid bit order parameter setting; use one of:
  1239. lsb2msb for x86-style machines
  1240. msb2lsb for other machines
  1241. EOF
  1242. x="";;
  1243.     esac
  1244. else
  1245.     x="$1"
  1246. fi
  1247.     done
  1248.     param="$x"
  1249. }
  1250. ModemParameters="
  1251.     ModemAnswerAnyCmd
  1252.     ModemAnswerCmd
  1253.     ModemAnswerDataBeginCmd
  1254.     ModemAnswerDataCmd
  1255.     ModemAnswerFaxBeginCmd
  1256.     ModemAnswerFaxCmd
  1257.     ModemAnswerResponseTimeout
  1258.     ModemAnswerVoiceBeginCmd
  1259.     ModemAnswerVoiceCmd
  1260.     ModemBaudRateDelay
  1261.     ModemClassQueryCmd
  1262.     ModemCommaPauseTimeCmd
  1263.     ModemDialCmd
  1264.     ModemDialResponseTimeout
  1265.     ModemEchoOffCmd
  1266.     ModemFlowControl
  1267.     ModemFrameFillOrder
  1268.     ModemHardFlowCmd
  1269.     ModemAtCmdDelay
  1270.     ModemMfrQueryCmd
  1271.     ModemModelQueryCmd
  1272.     ModemNoAutoAnswerCmd
  1273.     ModemNoFlowCmd
  1274.     ModemOnHookCmd
  1275.     ModemPageDoneTimeout
  1276.     ModemPageStartTimeout
  1277.     ModemRate
  1278.     ModemRecvFillOrder
  1279.     ModemResetCmds
  1280.     ModemResetDelay
  1281.     ModemResultCodesCmd
  1282.     ModemRevQueryCmd
  1283.     ModemSendBeginCmd
  1284.     ModemSendFillOrder
  1285.     ModemSetVolumeCmd
  1286.     ModemSetupAACmd
  1287.     ModemSetupDCDCmd
  1288.     ModemSetupDTRCmd
  1289.     ModemSoftFlowCmd
  1290.     ModemSoftResetCmd
  1291.     ModemSoftResetCmdDelay
  1292.     ModemVerboseResultsCmd
  1293.     ModemWaitForConnect
  1294.     ModemWaitTimeCmd
  1295.     FaxT1Timer
  1296.     FaxT2Timer
  1297.     FaxT4Timer
  1298.     Class0Cmd
  1299.     PagerSetupCmds
  1300. "
  1301. Class1Parameters="
  1302.     Class1Cmd
  1303.     Class1NFLOCmd
  1304.     Class1HFLOCmd
  1305.     Class1SFLOCmd
  1306.     Class1PPMWaitCmd
  1307.     Class1ResponseWaitCmd
  1308.     Class1TCFWaitCmd
  1309.     Class1EOPWaitCmd
  1310.     Class1FrameOverhead
  1311.     Class1MsgRecvHackCmd
  1312.     Class1RecvAbortOK
  1313.     Class1RecvIdentTimer
  1314.     Class1SwitchingCmd
  1315.     Class1TCFMaxNonZero
  1316.     Class1TCFMinRun
  1317.     Class1TCFRecvTimeout
  1318. "
  1319. Class2Parameters="
  1320.     Class2AbortCmd
  1321.     Class2BORCmd
  1322.     Class2BUGCmd
  1323.     Class2CIGCmd
  1324.     Class2CQCmd
  1325.     Class2CQQueryCmd
  1326.     Class2CRCmd
  1327.     Class2Cmd
  1328.     Class2DCCCmd
  1329.     Class2DCCQueryCmd
  1330.     Class2DISCmd
  1331.     Class2DDISCmd
  1332.     Class2LIDCmd
  1333.     Class2NRCmd
  1334.     Class2PHCTOCmd
  1335.     Class2PIECmd
  1336.     Class2PTSCmd
  1337.     Class2PTSQueryCmd
  1338.     Class2RecvDataTrigger
  1339.     Class2RELCmd
  1340.     Class2SendRTC
  1341.     Class2SPLCmd
  1342.     Class2TBCCmd
  1343.     Class2XmitWaitForXON
  1344.     Class2UseHex
  1345.     Class2NFLOCmd
  1346.     Class2HFLOCmd
  1347.     Class2SFLOCmd
  1348. "
  1349. #
  1350. # Get the default modem parameter values
  1351. # from the prototype configuration file.
  1352. #
  1353. getModemProtoParameters()
  1354. {
  1355.     eval `$SED -e 's/[  ]*#.*$//' 
  1356.  -e "s;([^:]*):[  ]*(.*);proto1='2';1='2';" $1`
  1357. }
  1358. #
  1359. # Setup the sed commands for crafting the configuration file:
  1360. #
  1361. echoModemSedCommands()
  1362. {
  1363.     ModemCmds=""
  1364.     (for i in $ModemParameters; do
  1365. eval echo "$i:$$i:$proto$i"
  1366.     done
  1367.     case "$ModemType" in
  1368.     Class1*)
  1369. for i in $Class1Parameters; do
  1370.     eval echo "$i:$$i:$proto$i"
  1371. done
  1372. ;;
  1373.     Class2*)
  1374. for i in $Class2Parameters; do
  1375.     eval echo "$i:$$i:$proto$i"
  1376. done
  1377. ;;
  1378.     esac) | $AWK -F: '
  1379. function p(tag, value)
  1380. {
  1381.     if (match(value, "^[^"].*[ ]") == 0)
  1382. printf "/^%s:/s/\(:[  ]*\).*/\1%s/n", tag, value
  1383.     else
  1384. printf "/^%s:/s/\(:[  ]*\).*/\1"%s"/n", tag, value
  1385. }
  1386. $2 != $3{ p($1, $2) }
  1387. END { printf "/CONFIG:/dn" }'
  1388. }
  1389. #
  1390. # Check if the configured flow control scheme is
  1391. # consistent with the tty device being used.
  1392. #
  1393. checkFlowControlAgainstTTY()
  1394. {
  1395.     case "$ModemFlowControl" in
  1396.     xonxoff|XONXOFF)
  1397. if [ "$TTY" = ttyf${PORT} ] && [ -c $DEVPATHttym${PORT} ]; then
  1398.     echo ""
  1399.     echo "Warning, the modem is setup to use software flow control,"
  1400.     echo "but the "$TTY" device is used with hardware flow control"
  1401.     prompt "Do you want to use "ttym${PORT}" instead [yes]?"
  1402.     if [ "$INTERACTIVE" != "no" ]; then
  1403. read x
  1404.     else
  1405. echo
  1406. x=
  1407.     fi
  1408.     if isOK $x; then
  1409. TTY="ttym${PORT}"
  1410. DEVID="`echo $TTY | tr '/' '_'`"
  1411. CONFIG=$CPATH.$DEVID
  1412.     fi
  1413. fi
  1414. ;;
  1415.     rtscts|RTSCTS)
  1416. if [ "$TTY" = ttym${PORT} ] && [ -c $DEVPATHttyf${PORT} ]; then
  1417.     echo ""
  1418.     echo "Warning, the modem is setup to use hardware flow control,"
  1419.     echo "but the "$TTY" device does not honor the RTS/CTS signals."
  1420.     prompt "Do you want to use "ttyf${PORT}" instead [yes]?"
  1421.     if [ "$INTERACTIVE" != "no" ]; then
  1422. read x
  1423.     else
  1424. echo
  1425. x=
  1426.     fi
  1427.     if isOK $x; then
  1428. TTY="ttyf${PORT}"
  1429. DEVID="`echo $TTY | tr '/' '_'`"
  1430. CONFIG=$CPATH.$DEVID
  1431.     fi
  1432. fi
  1433. ;;
  1434.     esac
  1435. }
  1436. #
  1437. # Print the current modem-related parameters.
  1438. #
  1439. printModemConfig()
  1440. {
  1441.     (for i in $ModemParameters; do
  1442. eval echo "$i:$$i:$proto$i"
  1443.     done
  1444.     case "$ModemType" in
  1445.     Class1*)
  1446. for i in $Class1Parameters; do
  1447.     eval echo "$i:$$i:$proto$i"
  1448. done
  1449. ;;
  1450.     Class2*)
  1451. for i in $Class2Parameters; do
  1452.     eval echo "$i:$$i:$proto$i"
  1453. done
  1454. ;;
  1455.     esac) | $AWK -F: '
  1456. function p(tag, value)
  1457. {
  1458.     tabs = substr("ttt", 1, 3-int((length(tag)+1)/8));
  1459.     printf "%s:%s%sn", tag, tabs, value
  1460. }
  1461. BEGIN { printf "nThe modem configuration parameters are:nn" }
  1462. $3 != ""{ p($1, $2) }
  1463. END { printf "n" }'
  1464. }
  1465. promptFor()
  1466. {
  1467.     eval test "$proto$2" && {
  1468. eval promptFor${1}Parameter "$$2" "$3";
  1469. eval $2="$param";
  1470.     }
  1471. }
  1472. #
  1473. # Compile a table of configuration parameters prompts into
  1474. # a shell program that can be ``eval'd'' to prompt the user
  1475. # for changes to the current parameter settings.
  1476. #
  1477. compileModemPrompts()
  1478. {
  1479.     $AWK -F'[ ]+' '
  1480. function p(t)
  1481. {
  1482.     printf "test -n "$proto%s" && { promptFor%sParameter "$%s" "%s";%s="$param"; }n", $2, t, $2, $3, $2
  1483. }
  1484. $1 == "#" { p("Numeric"); next }
  1485. $1 == "C#" { p("CStyleNumeric"); next }
  1486. $1 == "S" { p("String"); next }
  1487. $1 == "NNS" { p("NonNullString"); next }
  1488. $1 == "BO" { p("BitOrder"); next }
  1489. $1 == "FC" { p("FlowControl"); next }
  1490. $1 == "B" { p("Boolean"); next }
  1491. $1 == "AT" { p("ATCmd"); next }
  1492. { print }
  1493. '
  1494. }
  1495. #
  1496. # Build the script that prompts the user to edit the current
  1497. # modem configuration parameters.  Note that we can only edit
  1498. # parameters that are in the prototype config file; thus all
  1499. # the checks to see if the prototype value exists.
  1500. #
  1501. buildModemPrompts()
  1502. {
  1503.     compileModemPrompts<<EOF
  1504. AT ModemAnswerCmd Command for answering the phone
  1505. AT ModemAnswerAnyCmd Command for answering any type of call
  1506. AT ModemAnswerDataCmd Command for answering a data call
  1507. AT ModemAnswerFaxCmd Command for answering a fax call
  1508. AT ModemAnswerVoiceCmd Command for answering a voice call
  1509. AT ModemAnswerDataBeginCmd Command for start of a data call
  1510. AT ModemAnswerFaxBeginCmd Command for start of a fax call
  1511. AT ModemAnswerVoiceBeginCmd Command for start of a voice call
  1512. # ModemAnswerResponseTimeout Answer command response timeout (ms)
  1513. # ModemBaudRateDelay Delay after setting tty baud rate (ms)
  1514. AT ModemClassQueryCmd Command to query modem services
  1515. AT ModemCommaPauseTimeCmd
  1516. Command for setting time to pause for "," in dialing string
  1517. AT ModemDialCmd Command for dialing (%s for number to dial)
  1518. # ModemDialResponseTimeout Dialing command response timeout (ms)
  1519. AT ModemEchoOffCmd Command for disabling command echo
  1520. FC ModemFlowControl DTE-DCE flow control scheme
  1521. BO ModemFrameFillOrder Bit order for HDLC frames
  1522. AT ModemHardFlowCmd
  1523. Command for setting DCE-DTE hardware flow control
  1524. # ModemAtCmdDelay Delay before sending each modem AT cmd (ms)
  1525. AT ModemMfrQueryCmd Command for querying modem manufacture
  1526. AT ModemModelQueryCmd Command for querying modem model
  1527. AT ModemNoAutoAnswerCmd Command for disabling auto-answer
  1528. AT ModemNoFlowCmd Command for disabling DCE-DTE flow control
  1529. AT ModemOnHookCmd Command for placing phone "on hook" (hangup)
  1530. # ModemPageDoneTimeout Page send/receive timeout (ms)
  1531. # ModemPageStartTimeout Page send/receive timeout (ms)
  1532. # ModemRate DTE-DCE communication baud rate
  1533. BO ModemRecvFillOrder
  1534. Bit order that modem sends received facsimile data
  1535. AT ModemResetCmds Additional commands for resetting the modem
  1536. # ModemResetDelay Delay after sending modem reset commands (ms)
  1537. AT ModemResultCodesCmd Command for enabling result codes
  1538. AT ModemRevQueryCmd Command for querying modem firmware revision
  1539. BO ModemSendFillOrder
  1540. Bit order that modem expects for transmitted facsimile data
  1541. AT ModemSetVolumeCmd Commands for setting modem speaker volume levels
  1542. AT ModemSetupAACmd Command for setting up adaptive-answer
  1543. AT ModemSetupDCDCmd Command for setting up DCD handling
  1544. AT ModemSetupDTRCmd Command for setting up DTR handling
  1545. AT ModemSoftFlowCmd
  1546. Command for setting DCE-DTE software flow control
  1547. AT ModemSoftResetCmd Command for doing a soft reset
  1548. # ModemSoftResetCmdDelay Time in ms to pause after a soft reset
  1549. AT ModemVerboseResultsCmd Command for enabling verbose result codes
  1550. B ModemWaitForConnect
  1551. Force server to wait for "CONNECT" response on answer
  1552. AT ModemWaitTimeCmd
  1553. Command for setting time to wait for carrier when dialing
  1554. # FaxT1Timer CCITT T.30 T1 timer (ms)
  1555. # FaxT2Timer CCITT T.30 T2 timer (ms)
  1556. # FaxT4Timer CCITT T.30 T4 timer (ms)
  1557. AT Class0Cmd Command to enter Class 0
  1558. EOF
  1559.     case "$ModemType" in
  1560.     Class1*)
  1561. compileModemPrompts<<EOF
  1562. AT Class1Cmd Command to enter Class 1
  1563. AT Class1NFLOCmd
  1564. Command to setup no flow control after switch to Class 1
  1565. AT Class1HFLOCmd
  1566. Command to setup hardware flow control after switch to Class 1
  1567. AT Class1SFLOCmd
  1568. Command to setup software flow control after switch to Class 1
  1569. AT Class1PPMWaitCmd
  1570. Command to stop and wait prior to sending PPM
  1571. AT Class1ResponseWaitCmd
  1572. Command to stop and wait prior to looking for the TCF response
  1573. AT Class1TCFWaitCmd
  1574. Command to stop and wait prior to sending TCF
  1575. AT Class1EOPWaitCmd
  1576. Command to stop and wait prior to sending EOP
  1577. # Class1FrameOverhead Extra bytes in a received HDLC frame
  1578. # Class1MsgRecvHackCmd Command to avoid +FCERROR before image data
  1579. # Class1RecvAbortOK
  1580. Maximum time to wait for OK after aborting a receive (ms)
  1581. # Class1RecvIdentTimer
  1582. Maximum wait for initial identification frame (ms)
  1583. # Class1SwitchingCmd
  1584. Command to ensure silence after receiving HDLC and before sending
  1585. # Class1TCFRecvTimeout Timeout for receiving TCF (ms)
  1586. EOF
  1587. ;;
  1588.     Class2*)
  1589. compileModemPrompts<<EOF
  1590. AT Class2Cmd Command to enter $ModemType
  1591. AT Class2NFLOCmd
  1592. Command to setup no flow control after switch to $ModemType
  1593. AT Class2HFLOCmd
  1594. Command to setup hardware flow control after switch to $ModemType
  1595. AT Class2SFLOCmd
  1596. Command to setup software flow control after switch to $ModemType
  1597. AT Class2AbortCmd Command to abort an active session
  1598. AT Class2BORCmd Command to setup data bit order
  1599. AT Class2BUGCmd Command to enable HDLC frame tracing
  1600. AT Class2CIGCmd Command to set polling identifer
  1601. AT Class2CQCmd Command to setup copy quality parameters
  1602. AT Class2CRCmd Command to enable receive capability
  1603. AT Class2DCCCmd Command to set/constrain modem capabilities
  1604. AT Class2DCCQueryCmd Command to query modem capabilities
  1605. AT Class2DISCmd Command to set session parameters
  1606. AT Class2LIDCmd Command to set local identifier string
  1607. AT Class2NRCmd Command to enable status reporting
  1608. AT Class2PHCTOCmd Command to set Phase C timeout
  1609. AT Class2PIECmd Command to disable procedure interrupt handling
  1610. AT Class2RELCmd Command to receive byte-aligned EOL codes
  1611. AT Class2RecvDataTrigger Character sent before receiving page data
  1612. AT Class2SPLCmd Command to set polling request
  1613. AT Class2TBCCmd Command to enable DTE-DCE stream comm. mode
  1614. B Class2XmitWaitForXON Wait for XON before sending page data
  1615. EOF
  1616. ;;
  1617.     esac
  1618. }
  1619. #
  1620. # Construct the configuration file.
  1621. #
  1622. case $ProtoType in
  1623. skel|class*)
  1624.     # Go through each important parameter (sigh)
  1625.     cat<<EOF
  1626. There is no prototype configuration file for your modem, so we will
  1627. have to fill in the appropriate parameters by hand.  You will need the
  1628. manual for how to program your modem to do this task.  In case you are
  1629. uncertain of the meaning of a configuration parameter you should
  1630. consult the config(@MANNUM4_5@) manual page for an explanation.
  1631. Note that modem commands must be specified exactly as they are to be
  1632. sent to the modem.  Note also that quote marks (") will not be displayed
  1633. and will automatically be deleted.  You can use this facility to supply
  1634. null parameters as "".
  1635. Finally, beware that the set of parameters is long.  If you prefer to
  1636. use your favorite editor instead of this script you should fill things
  1637. in here as best you can and then edit the configuration file
  1638. "$CONFIG"
  1639. after completing this procedure.
  1640. EOF
  1641.     ok=no;;
  1642. *)  ok=skip;;
  1643. esac
  1644. getModemProtoParameters $proto
  1645. #
  1646. # Override any default flow control setting
  1647. # in the prototype configuration file.
  1648. #
  1649. case $FlowControl in
  1650. RTS*) ModemFlowControl=rtscts;;
  1651. XON*) ModemFlowControl=xonxoff;;
  1652. esac
  1653. rm -f $PROMPTS
  1654. while isNotOK $ok; do
  1655.     if [ "$ok" != skip ]; then
  1656. test -f $PROMPTS || buildModemPrompts>$PROMPTS
  1657. . $PROMPTS
  1658.     fi
  1659.     printModemConfig
  1660.     case $TARGET in
  1661.     *-irix*) checkFlowControlAgainstTTY;;
  1662.     esac
  1663.     #
  1664.     # XXX not sure what kind of consistency checking that can
  1665.     # be done w/o knowing more about the modem...
  1666.     #
  1667.     prompt "Are these ok [yes]?";
  1668.     if [ "$INTERACTIVE" != "no" ]; then
  1669. read ok
  1670.     else
  1671. echo
  1672. ok=
  1673.     fi
  1674. done
  1675. TMPSED=$TMPDIR/faxsed$$; JUNK="$JUNK $TMPSED"
  1676. (echoServerSedCommands; echoModemSedCommands)>$TMPSED
  1677. #
  1678. # All done with the prompting; edit up a config file!
  1679. #
  1680. echo ""
  1681. echo "Creating new configuration file $CONFIG..."
  1682. JUNK="$JUNK $CONFIG.new"
  1683. if $SED -f $TMPSED $proto >$CONFIG.new; then
  1684.     if cmp -s $CONFIG.new $CONFIG >/dev/null 2>&1; then
  1685. echo "...nothing appears to have changed; leaving the original file."
  1686. $RMCMD $CONFIG.new
  1687.     else
  1688. if [ -f $CONFIG ]; then
  1689.     echo "...saving current file as $CONFIG.sav."
  1690.     mv $CONFIG $CONFIG.sav
  1691. fi
  1692. $MV $CONFIG.new $CONFIG
  1693. $CHOWN $FAX $CONFIG
  1694. $CHGRP $faxGID $CONFIG
  1695. $CHMOD 644 $CONFIG
  1696.     fi
  1697. else
  1698.     echo ""
  1699.     echo "*** Sorry, something went wrong building $CONFIG.new."
  1700.     echo "*** The original config file is unchanged; I'm terminating before"
  1701.     echo "***    I do something stupid."
  1702.     echo ""
  1703.     die
  1704. fi
  1705. #
  1706. # Create FIFO.<tty> special file and remove any old one.
  1707. #
  1708. FIFO=$SPOOL/FIFO.$DEVID
  1709. test -p $FIFO || {
  1710.     prompt "Creating fifo $FIFO for faxgetty..."
  1711.     if (mkfifo $FIFO) >/dev/null 2>&1; then
  1712. echo "done."
  1713.     elif (mknod $FIFO p) >/dev/null 2>&1; then
  1714. echo "done."
  1715.     else
  1716. echo ""
  1717. echo "*** Unable to create fifo "$FIFO"; terminating."
  1718. die
  1719.     fi
  1720. }
  1721. $CHOWN $FAX $FIFO; $CHGRP $faxGID $FIFO; $CHMOD 600 $FIFO
  1722. if [ "$OLDFIFO" ]; then
  1723.     echo "Removing old fifo $OLDFIFO.";
  1724.     $RMCMD $OLDFIFO;
  1725. fi
  1726. echo "Done setting up the modem configuration."
  1727. echo ""
  1728. #
  1729. # Configuration parameters specific to scheduler operation.
  1730. # Required parameters are *always* emitted in the created
  1731. # configuration file; optional parameters are emitted
  1732. # only if the configured value differs from the default
  1733. # value known to be used by the server.
  1734. #
  1735. # NB: the order of some parameters is important; e.g.
  1736. #     DialStringRules must be after AreaCode and CountryCode.
  1737. #
  1738. RequiredSchedulerParameters="
  1739.     LogFacility
  1740.     CountryCode
  1741.     AreaCode
  1742.     LongDistancePrefix
  1743.     InternationalPrefix
  1744.     DialStringRules
  1745.     ServerTracing
  1746. "
  1747. OptionalSchedulerParameters="
  1748.     ContCoverPage
  1749.     ContCoverCmd
  1750.     MaxConcurrentCalls
  1751.     MaxDials
  1752.     MaxSendPages
  1753.     MaxTries
  1754.     ModemGroup
  1755.     PostScriptTimeout
  1756.     PS2FaxCmd
  1757.     SendFaxCmd
  1758.     SendPageCmd
  1759.     SendUUCPCmd
  1760.     SessionTracing
  1761.     TimeOfDay
  1762.     Use2D
  1763. "
  1764. defaultContCoverPage=
  1765. defaultContCoverCmd="bin/mkcover"
  1766. defaultMaxConcurrentCalls=1
  1767. defaultMaxDials=12
  1768. defaultMaxSendPages=0xffffffff
  1769. defaultMaxTries=3
  1770. defaultModemGroup=
  1771. defaultPostScriptTimeout=180
  1772. defaultPS2FaxCmd="bin/ps2fax"
  1773. defaultSendFaxCmd="bin/faxsend"
  1774. defaultSendPageCmd="bin/pagesend"
  1775. defaultSendUUCPCmd="bin/uucpsend"
  1776. defaultSessionTracing=0xFFF
  1777. defaultTimeOfDay="Any"
  1778. defaultUse2D=Yes
  1779. #
  1780. # NB: these defaults are set above
  1781. #
  1782. OptionalParameters="
  1783.     $OptionalSchedulerParameters
  1784.     JobReqOther
  1785.     NotifyCmd
  1786.     UUCPLockDir
  1787.     UUCPLockTimeout
  1788.     UUCPLockType
  1789. "
  1790. SchedulerParameters="
  1791.     $RequiredSchedulerParameters
  1792.     $OptionalParameters
  1793. "
  1794. #
  1795. # The following parameters are checked to make sure
  1796. # they have values consistent with what was just written
  1797. # to the modem configuration file.  It is ok for some
  1798. # of these to be different, but usually they should be
  1799. # the same so if they disagree we prompt the user to
  1800. # see if we should propagate the new values from the
  1801. # modem config file to the scheduler config file.
  1802. #
  1803. CheckedParameters="
  1804.     LogFacility
  1805.     CountryCode
  1806.     AreaCode
  1807.     LongDistancePrefix
  1808.     InternationalPrefix
  1809.     DialStringRules
  1810.     JobReqOther
  1811.     NotifyCmd
  1812.     UUCPLockDir
  1813.     UUCPLockTimeout
  1814.     UUCPLockType
  1815. "
  1816. #
  1817. # Echo the configuration lines for those scheduler parameters
  1818. # whose value is different from the default value.  Note
  1819. # that we handle the case where there is embedded whitespace
  1820. # by enclosing the parameter value in quotes.
  1821. #
  1822. echoSchedulerParameters()
  1823. {
  1824.     (for i in $RequiredSchedulerParameters; do
  1825. eval echo "$i:$$i:"
  1826.      done
  1827.      for i in $OptionalSchedulerParameters; do
  1828. eval echo "$i:$$i:$default$i"
  1829.      done) | $AWK -F: '
  1830. function p(tag, value)
  1831. {
  1832.     tabs = substr("ttt", 1, 3-int((length(tag)+1)/8));
  1833.     if (match(value, "^[^"].*[ ]") == 0)
  1834. printf "%s:%s%sn", tag, tabs, value
  1835.     else
  1836. printf "%s:%s"%s"n", tag, tabs, value
  1837. }
  1838. $2 != $3{ p($1, $2) }'
  1839. }
  1840. #
  1841. # Print the current server configuration parameters.
  1842. #
  1843. printSchedulerConfig()
  1844. {
  1845.     (for i in $SchedulerParameters; do
  1846. eval echo "$i:$$i:$default$i"
  1847.     done) | $AWK -F: '
  1848. function p(tag, value)
  1849. {
  1850.     tabs = substr("ttt", 1, 3-int((length(tag)+1)/8));
  1851.     printf "%s:%s%sn", tag, tabs, value
  1852. }
  1853. BEGIN { printf "nThe non-default scheduler parameters are:nn" }
  1854. $2 != $3{ p($1, $2) }
  1855. END { printf "n" }'
  1856. }
  1857. #
  1858. # Check the current contents of the scheduler configuration file
  1859. # against that parameters just setup for the per-modem config file.
  1860. # If anything has changed (e.g. phone number info), then prompt
  1861. # the user to update the file.
  1862. #
  1863. updateConfig=yes
  1864. #
  1865. # Initialize server parameters from the defaults.
  1866. #
  1867. for i in $OptionalSchedulerParameters; do
  1868.     eval $i=$default$i
  1869. done
  1870. if [ -f $SCHEDCONFIG ]; then
  1871.     echo "Checking $SCHEDCONFIG for consistency..."
  1872.     #
  1873.     # Save current settings in variables with a ``modem'' prefix.
  1874.     #
  1875.     for i in $CheckedParameters; do
  1876. eval modem$i=$$i
  1877.     done
  1878.     #
  1879.     # Read old configuration file in as the ``current settings''.
  1880.     #
  1881.     getServerParameters $SCHEDCONFIG
  1882.     #
  1883.     # Check current parameter settings against ``modem settings''.
  1884.     # If inconsistencies are detected in the parameters that should
  1885.     # (by default) be kept consistent, then try to propagate the new
  1886.     # parameter settings from the modem config file to the scheduler
  1887.     # config file.
  1888.     #
  1889.     ok=yes
  1890.     for i in $CheckedParameters; do
  1891. eval test "$$i" != "$modem$i" && { ok=skip; break; }
  1892.     done
  1893.     if [ $ok != yes ]; then
  1894. echo "...some parameters are different."
  1895. #
  1896. # Move the ``modem settings'' to the current settings
  1897. # and let the user ok them or change them to what they
  1898. # want.  We do this shuffle w/o touching the default
  1899. # settings so that optional parameter handling works
  1900. # (i.e. that only non-default values for optional params
  1901. # are displayed and/or written to the file).
  1902. #
  1903. for i in $CheckedParameters; do
  1904.     eval $i=$modem$i
  1905. done
  1906.     else
  1907. echo "...everything looks ok; leaving existing file unchanged."
  1908. updateConfig=no
  1909.     fi
  1910. else
  1911.     echo "No scheduler configuration file exists, creating one from scratch."
  1912.     ok=skip # got important params above
  1913. fi
  1914. rm -f $PROMPTS
  1915. while isNotOK $ok; do
  1916.     if [ "$ok" != skip ]; then
  1917. test -f $PROMPTS || compilePrompts>$PROMPTS<<EOF
  1918. # CountryCode Country code
  1919. # AreaCode Area code
  1920. # LongDistancePrefix Long distance dialing prefix
  1921. # InternationalPrefix International dialing prefix
  1922. NNS DialStringRules Dial string rules file (relative to $SPOOL)
  1923. C# ServerTracing Tracing during normal server operation
  1924. C# SessionTracing
  1925. Default tracing during send and receive sessions
  1926. S ContCoverPage Continuation cover page (relative to $SPOOL)
  1927. C# PostScriptTimeout
  1928. Timeout when converting PostScript documents (secs)
  1929. C# MaxConcurrentCalls
  1930. Maximum number of concurrent jobs to a destination
  1931. S ModemGroup Define a group of modems
  1932. S TimeOfDay Time of day restrictions for outbound jobs
  1933. C# UUCPLockTimeout
  1934. Timeout before purging a stale UUCP lock file (secs)
  1935. C# MaxSendPages Max number of pages to permit in an outbound job
  1936. S LogFacility Syslog facility name for ServerTracing messages
  1937. EOF
  1938. . $PROMPTS
  1939.     fi
  1940.     checkForLocalFile $DialStringRules "dial string rules"
  1941.     printSchedulerConfig; prompt "Are these ok [yes]?";
  1942.     if [ "$INTERACTIVE" != "no" ]; then
  1943. read ok
  1944.     else
  1945. echo
  1946. ok=
  1947.     fi
  1948. done
  1949. if [ $updateConfig = yes ]; then
  1950.     #
  1951.     # All done with the prompting; edit up a config file!
  1952.     #
  1953.     echo ""
  1954.     echo "Creating new configuration file $SCHEDCONFIG..."
  1955.     JUNK="$JUNK $SCHEDCONFIG.new"
  1956.     echoSchedulerParameters >$SCHEDCONFIG.new 2>/dev/null
  1957.     if cmp -s $SCHEDCONFIG.new $SCHEDCONFIG >/dev/null 2>&1; then
  1958. echo "...nothing appears to have changed; leaving the original file."
  1959. rm -f $SCHEDCONFIG.new
  1960.     elif [ -s $SCHEDCONFIG.new ]; then
  1961. if [ -f $SCHEDCONFIG ]; then
  1962.     echo "...saving current file as $SCHEDCONFIG.sav."
  1963.     $MV $SCHEDCONFIG $SCHEDCONFIG.sav
  1964. fi
  1965. $MV $SCHEDCONFIG.new $SCHEDCONFIG
  1966. $CHOWN $FAX $SCHEDCONFIG
  1967. $CHGRP $faxGID $SCHEDCONFIG
  1968. $CHMOD 644 $SCHEDCONFIG
  1969.     else
  1970. echo ""
  1971. echo "*** Sorry, something went wrong building $SCHEDCONFIG.new."
  1972. echo "*** The original config file is unchanged; check your disk space?"
  1973. echo ""
  1974. die
  1975.     fi
  1976. fi
  1977. echo ""
  1978. echo "Don't forget to run faxmodem(@MANNUM1_8@) (if you have a send-only environment)"
  1979. echo "or configure init to run faxgetty on $TTY."
  1980. exec >/dev/null 2>&1
  1981. # cleanup
  1982. $RMCMD $JUNK; $RMCMD -r $TMPDIR
  1983. exit 0