home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / voice2.zip / V_MBXLAN.CMD < prev    next >
OS/2 REXX Batch file  |  1997-05-22  |  28KB  |  774 lines

  1. /* V_MBXLAN.CMD - Voice/Fax Answer Script for FaxWorks/PMfax (REXX) */
  2. /* 
  3.                   Keller Group Inc.  May 22, 1997
  4.    You may freely use or modify this script for use with licensed
  5.         products which are developed by Keller Group Inc.
  6.       For new scripts or to share your scripts with others,
  7.                  see http://www.kellergroup.com
  8. */
  9. /*******************************************************************
  10. V_MBXLAN.CMD - Advanced voice/fax mailbox system - LAN Private Mode
  11.  
  12. For use with the following Keller software configurations:
  13.   LAN Private Mode (retrieval from private fax logs)
  14.  
  15. Features:
  16.  
  17.   Callers can:
  18.      select a LAN user by their "extension"
  19.      hear both a "company" greeting and the extension's "personal" greeting
  20.      send a fax (to an extension, or by default to the server),
  21.      leave a voice message (to an extension, or by default to the server),
  22.      listen to an announcement, or
  23.      enter extension and private password to enter remote retrieval mode
  24.  
  25.   In the password-protected remote retrieval mode, you can do:
  26.      greeting modification - remotely update your personal greeting message
  27.      password modification - remotely modify your personal access code
  28.      voice retrieval - get voice messages by phone
  29.      fax retrieval - get fax messages, or send them to a fax number
  30.      log retrieval - get a fax of your log (or the last part of it)
  31.      "fax on demand" from log - retrieve voice and fax items from your log
  32.  
  33.  
  34. DESCRIPTION:
  35. -----------
  36. This script plays your outgoing message (OGM).  The caller can enter
  37. the "extension" (Route ID) of a LAN user followed by the '#' key to
  38. hear that user's personal outgoing message and then record a message
  39. or send a fax directly to them.  If the caller doesn't enter any
  40. extension or enters '0#' or '#', the caller can record a message to
  41. the "receptionist" (the administrative router of the LAN system).
  42.  
  43. The caller can press the # or * key to skip the outgoing message and
  44. immediately record their message, otherwise the script will provide a
  45. beep and record the caller's message if no further action is taken.
  46.  
  47. If the call is from a fax device and your fax hardware detects the
  48. caller's fax (CNG) tones, the script automatically receives the fax.
  49.  
  50. If the caller enters '2' during playing of the outgoing message, the
  51. script plays the "announcement" and then returns to the outgoing
  52. message again so that the caller can leave a message on the same
  53. call.  If a LAN user's extension is selected, the LAN user's personal
  54. announcement is played, otherwise the system's main announcement is
  55. played.
  56.  
  57. If the caller enters '9' during or immediately after the playing of
  58. the OGM and then enters the user-configurable access code followed by
  59. the # key, the script enters its "remote retrieval" mode so the
  60. caller can hear received voice messages, have received faxes sent to
  61. them via fax, and other features.  When in this mode, the keys on the
  62. telephone do the following:
  63.  
  64.    1 - HELP       - Play help message which describes these commands
  65.    2 - SET CODE   - Changes LAN user's private access code (default: 42)
  66.    3 - GREETING   - Enter new outgoing message (change greeting)
  67.  
  68.    4 - PREV MSG   - Play previous voice message
  69.    5 - REPLAY MSG - Play current voice message (again)
  70.    6 - NEXT MSG   - Play next voice message
  71.  
  72.    7 - GET FAXES  - Retrieve new fax messages by fax
  73.    8 - GET LOG    - Retrieve fax log by fax
  74.    9 - FOD LOG    - Retrieve voice/fax msgs from log ("fax-on-demand")
  75.  
  76.    0 - TOP        - Return to top level and play outgoing message again
  77.  
  78.  
  79. USAGE INSTRUCTIONS:
  80. ------------------
  81. You must be using the program with supported voice/fax hardware to
  82. use this script.  Consult the README.DOC file for tested voice/fax
  83. hardware and recommended configuration settings for your hardware.
  84. Before using this script, first test your system with our built-in
  85. voice answering machine feature by enabling "Voice" and setting the
  86. "Answer script" to * (an asterisk character) on the Voice page of the
  87. Settings notebook.  If you are using supported voice/fax hardware
  88. with the proper configuration settings, you can then use
  89. "Fax/Receive/All calls" mode to answer calls, play the outgoing
  90. message (OGM), and record a voice message (or receive a fax).
  91.  
  92. Then, to change to this advanced script, specify the full pathname of
  93. this file in the "Answer script" field on the Voice page of the
  94. settings notebook.
  95.  
  96. NOTE: The script expects to find the LIB_FOD.CMD file and its Wave
  97. audio files in the fax program (EXE) directory.  The script also uses
  98. Wave files from the c:\mmos2\sounds directory for special effects.
  99.  
  100. SCRIPT VARIABLES:
  101. ----------------
  102. The following script variable is used by this script.  Script
  103. variables are set on the Voice page of the Fax Server's Settings
  104. Notebook.
  105.  
  106. General:
  107.  
  108.     OGM - Pathname of the main "outgoing message" which is played
  109.     to the caller.  By default, the program sets OGM to be the
  110.     file OGM.WAV in the fax server's program directory.
  111.     Example: OGM = C:\FAX\OGM.WAV
  112.     [LAN users can also place a personal OGM.WAV file in their fax
  113.     data directory or record one using remote access command '3'.]
  114.  
  115.     CODE - Access code for retrieving messages or changing
  116.     settings from the fax server's log.  By default, the program
  117.     sets CODE to be 42.  You can change this to be any number of up
  118.     to 5 digits in length.
  119.     Example: CODE = 42
  120.     [LAN users can also set a personal access code for their mailbox
  121.     using the '2' command when they call in, and this personal value
  122.     is saved in the ACCESS.COD file in their fax directory.  If no
  123.     personal access code is set, the default value is 42.]
  124.  
  125.     CALLER - (optional, default "Person") - Name of the person/company
  126.     who will be using the access code to retrieve messages/faxes
  127.     by phone.  This is used for addressing faxes when the caller
  128.     uses the access code for remote retrieval.  
  129.     Example: CALLER = Your Company Inc.
  130.  
  131.     LOGMAXLINE - (optional, default 56) - Maximum number of log
  132.     entries, from the end of the log, to be sent to the caller
  133.     when they retrieve the log by fax.  If set to 0, then
  134.     the entire log is sent.
  135.     Example: LOGMAXLINE = 120
  136.  
  137.  
  138. VOICE PROMPT FILES:
  139. ------------------
  140. The script expects to find the following Wave audio files in the fax
  141. program (EXE) directory.  The script also uses Wave files from the
  142. c:\mmos2\sounds directory for special effects.
  143.  
  144. To record or modify your own voice prompt files, use your OS/2
  145. Multimedia microphone and record voice prompts using the "Fax/New
  146. message" command then save them to a .WAV file with the "Fax/Save
  147. file/Wave" command.  You can also use the OS/2 Digital Audio program
  148. to record, save, edit and modify the Wave files (be sure to use
  149. "Type" of Mono, 8-bit, 11.025 kHz).
  150.  
  151.     OGM.WAV - The main "outgoing message" as recorded with the
  152.     Utilities/Outgoing message command.
  153.  
  154.     ENTR_COD.WAV - Short: "Enter code."
  155.     Long: "Please enter your access code and the # key."
  156.  
  157.     ENTR_CMD.WAV - Short: "Enter command."
  158.     Long: "To play current message press 5, to play next message
  159.     press 6, to play previous message press 4...."
  160.  
  161.     ENTR_MSG.WAV - Short: "Enter message, then press # key."
  162.     Long: "Please leave your message at the beep.  Press # key to end."
  163.  
  164.     ANNOUNC.WAV - Short: "No announcement."
  165.     Long: "Our annoucement for this week is...."
  166.  
  167.     HELP.WAV - "Press 3 to change outgoing message, 4 for previous..."
  168.  
  169.     NO_MSGS.WAV - Short: "No more messages."
  170.  
  171. And used by any fax retrieval actions (LIB_FOD.CMD procedure):
  172.  
  173.     ENTR_DOC.WAV - Short: "Enter document number and # key, or
  174.     press the # key if done."
  175.     Long: "Please enter the document number followed by the # key,
  176.     or press the # key if done.  To receive an index of available
  177.     documents, enter document 1000."
  178.  
  179.     HOW_FAX.WAV - Short: "Enter 1 if calling from fax machine, 2
  180.     if not."
  181.     Long: "If you are calling from your fax machine and are ready
  182.     to receive the fax press 1, to send the fax to a different
  183.     number press 2." 
  184.  
  185.     ENTR_FAX.WAV - Short: "Enter fax number and # key."
  186.     Long: "Please enter your fax number followed by the # key,
  187.     including 1 and area code if this is not a local call." 
  188.  
  189.     NO_FILE.WAV - Short: "File not found."
  190.     Long: "That document was not found, please try again."
  191.  
  192.     WAIT.WAV - Short: "Please wait."
  193.     Long: "Please wait while we process your request."
  194.  
  195.     THANKYOU.WAV - Short: "Thank you."
  196.  
  197. TO MODIFY THE SCRIPT:
  198. --------------------
  199. The script is REXX and uses calls from the Keller REXX API which are
  200. automatically loaded into the OS/2 REXX environment by the retail
  201. versions of Keller's fax products (version 3.0 and later).  See the
  202. Reference Manual for documentation of the FxRx and FxLn calls.  You
  203. may modify the script as desired, and then use it as the "Answer
  204. script" with Keller fax software products.
  205.  
  206. Note - For voice message retrieval, this script uses the RCVD/N_RCVD
  207. mode of FxRxFind, which means that it will report only those voice
  208. messages which have been received but not already played at the
  209. computer and not previously retrieved via phone.  If desired, you can
  210. change this to use READ/N_READ mode which will report all voice
  211. messages which have not been previously retrieved via phone (even
  212. those that have been played at the computer).  You can also retrieve
  213. any desired voice message, whether or not it has been played or
  214. retrieved, using the "fax log" and "fax-on-demand" features in this
  215. script which allow you to play any voice message by its index number.
  216.  
  217. Note - For fax message retrieval, this script uses the RCVD/N_RCVD
  218. mode of FxRxFind, which means that it will report only those faxes
  219. which have been received but not already viewed at the computer and
  220. not previously retrieved via phone.  If desired, you can change this
  221. to use READ/N_READ mode which will report all faxes which have not
  222. been previously retrieved via phone (even those that have been viewed
  223. at the computer).  You can also retrieve any desired fax, whether or
  224. not it has been viewed or retrieved, using the "fax log" and
  225. "fax-on-demand" features in this script which allow you to retrieve
  226. any fax by its index number.  In version 3 of the fax program,
  227. viewing a received fax changes its status from Rcvd to Read, but
  228. printing of faxes does NOT change the status, so you can auto-print
  229. all received faxes at the computer and still retrieve them as "Rcvd"
  230. faxes by phone. 
  231.  
  232. HOW TO PROVIDE FORWARDING, PAGING, ETC. ON A PER-USER BASIS:
  233. -----------------------------------------------------------
  234. Some users may wish to provide actions which are automatically
  235. invoked when a fax or voice message is routed to a LAN user's private
  236. fax directory.  For example, you could have all received faxes
  237. forwarded to a fax number or emailed.  One way of doing this is by
  238. using the "Notify Command" field on the Option/Settings dialog of the
  239. FxRDR program on the fax server.  This command is executed whenever a
  240. fax is routed to a LAN user, so you can write a REXX program which is
  241. passed the UserID and then uses the REXX API commands (including
  242. FxRxSelect to select the LAN user's fax log using the UserID) to take
  243. appropriate actions whenever a fax or message is routed.  The
  244. V_MBX.CMD script shows how to do fax forwarding and email, and the
  245. Notify Command features are documented in the LAN Guide.
  246.  
  247. TO USE WITH MULTILINE VERSIONS:
  248. ------------------------------
  249. This script can be used with multiline versions of Keller fax
  250. software.  All lines are handled identically, so calls can be
  251. received on any of your "receive" lines.  If you prefer to have
  252. different lines be handled differently you can modify the script to
  253. test the LID variable.  For example, to have line 1 immediately jump
  254. to the "please enter your message" prompt, you could add a line like
  255. the following after the "call FxLnInit" line in the script: "if LID =
  256. 1 then signal voice" where "voice" is a label in the script.
  257.  
  258. *******************************************************************/
  259.  
  260.   call FxLnInit
  261.  
  262.   VOXDIR = FxRxPath( 'EXE' )    /* get voice prompts from exe dir */
  263.   LIBDIR = FxRxPath( 'EXE' )    /* get REXX subroutines from exe dir */
  264.   FODPROCEDURE = LIBDIR||'lib_fod.cmd'  /* use this external procedure */
  265.  
  266.   /* default values for script variables */
  267.   if CALLER = 'CALLER' then CALLER = 'Person'
  268.   if LOGMAXLINE = 'LOGMAXLINE' then LOGMAXLINE = 56
  269.  
  270.   DEFAULTCODE = '42'        /* default access code */
  271.  
  272. hello:
  273.   LREC. = ""                /* be sure this is clean */
  274.   USERID = ''            /* if blank, use the fax server's log */
  275.   USERDIR = ''
  276.  
  277.   /* If using Brooktrout, you may need to use certain lines for fax since */
  278.   /* it has trouble hearing calling fax CNG tones when you are using      */
  279.   /* voice and DTMF commands. For example... */
  280.   /* if LID = 1 then signal fax */
  281.  
  282.   call FxRxSelect ''
  283.   call FxLnMsg 'OGM'                /* show in status window */
  284.     if result = 'NOTOK' then signal byebye
  285.   call FxLnPlay OGM                /* play greeting prompt */
  286.     if result = 'NOTOK' then signal byebye
  287.     if result = 'FAX' then signal fax
  288.     if result = 'DATA' then signal data
  289.  
  290.   digits = GetExtension( 5, 10, 5 )        /* get extension or number */
  291.     if digits = 'NOTOK' then signal byebye
  292.     if digits = 'FAX' then signal fax
  293.     if digits = 'DATA' then signal data
  294.  
  295.   if digits = '' | digits = '0' then signal voice  
  296.   if digits = 2 then signal announce        /* use key value... */
  297.   if digits = 9 then signal accesscode
  298.  
  299.   /* else they must have entered an extension... */
  300.   call FxRxSelect digits
  301.  
  302.   if result = 'NOTOK' then signal hello
  303.  
  304.   /* else it is 'OK', meaning it is a valid LAN user */
  305.   USERID = digits
  306.   USERDIR = FxRxPath( 'LOG' )
  307.   if stream(USERDIR||'OGM.WAV', 'C', 'QUERY EXISTS' ) <> ''
  308.   then call FxLnPlay USERDIR||'OGM.WAV'
  309.   call FxRxSelect ''  
  310.  
  311.   call FxLnDtmf 1, 3, 'digits'            /* get key, if any... */
  312.     if result = 'NOTOK' then signal byebye
  313.     if result = 'FAX' then signal fax
  314.     if result = 'DATA' then signal data
  315.     if result <> 'DTMF' then signal voice
  316.  
  317.   if digits = 2 then signal announce        /* use key value... */
  318.   if digits = 3 then signal fax
  319.   if digits = 9 then signal accesscode
  320.  
  321.  
  322. voice:                    /* take voice message, hangup */
  323.   call FxLnMsg "Record Msg"
  324.   call FxLnTone 1850
  325.     if result = 'NOTOK' then signal byebye
  326.   call FxLnDtmf     /* flush buffer */
  327.   call FxLnRecord
  328.     if result = 'NOTOK' then signal byebye
  329.     if result = 'FAX' then signal fax
  330.     if result = 'DATA' then signal data
  331.   /* caller can hang up or press a key to end recording */
  332.   call FxLnTone 1850, 1850, 1850
  333.   if USERID <> '' then do
  334.     LREC.!Owner_ID = '#'||USERID    /* route to extension, if any */
  335.   end
  336.   signal out
  337.  
  338.  
  339. fax:                    /* receive fax and hangup */
  340.   call FxLnReceive
  341.   if USERID <> '' then do
  342.     LREC.!Owner_ID = '#'||USERID    /* route to extension, if any */
  343.   end
  344.   signal out
  345.  
  346.  
  347. data:                    /* report data call, hangup */
  348.   call FxLnMsg 'Data call, oh well...'
  349.   LREC.!Status = '*Data!'   /* log status of call */
  350.   signal out
  351.  
  352.  
  353. announce:                /* play annoucement, restart */
  354.   call FxLnMsg "Announcement"
  355.   call FxRxSelect USERID
  356.   if stream(FxRxPath('LOG')||'ANNOUNC.WAV', 'C', 'QUERY EXISTS' ) <> ''
  357.   then call FxLnPlay FxRxPath('LOG')||'ANNOUNC.WAV'
  358.   else call FxLnPlay VOXDIR||'ANNOUNC.WAV'
  359.   call FxRxSelect ''
  360.   signal hello
  361.  
  362.  
  363. accesscode:
  364.   if USERID <> '' then do
  365.     call FxRxSelect USERID    /* work from the private log, if found */
  366.   end
  367.   call FxLnMsg 'Code ???'        /* get & check access code */
  368.   call FxLnPlay VOXDIR||'ENTR_COD.WAV'
  369.     if result = 'NOTOK' then signal byebye
  370.   digits = GetNumber( 6, 10 )
  371.  
  372.   if USERID = '' then do
  373.     if digits <> CODE then signal evil
  374.   end
  375.   else do
  376.     if digits <> FetchCode() then signal evil
  377.   end
  378.  
  379.   call FxLnMsg 'Code Mode'
  380.   call FxLnVout 'Valid code entered'
  381.   call FxRxBeep 354, 393, 295, 354, 0, 393
  382.  
  383.   call FxRxFind 'MSG', 'N_RCVD'        /* get # of new voice msgs */
  384.   if result = 'NOTOK' then do
  385.     call FxLnPlay 'c:\mmos2\sounds\BOING.wav'
  386.     signal byebye
  387.   end
  388.   n = result
  389.  
  390.   /* if no messages... stay in command mode for other (fax) commands */
  391.   if n = 0 then do
  392.         call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  393.         if result = 'NOTOK' then signal byebye
  394.   end
  395.  
  396.   i = n                /* Play 1 beep for each voice message */
  397.   call FxLnMsg 'Code Mode' n 'messages'
  398.   call FxLnVout 'Beep' n 'times'
  399.   do while i > 0
  400.     call FxLnTone 2100
  401.     i = i - 1
  402.   end
  403.  
  404.   call FxLnVout 'Enter message loop'
  405.   i = 0
  406.   j = 0
  407.   do forever
  408.     call FxLnMsg 'Waiting for next command'
  409.     call FxLnPlay VOXDIR||'ENTR_CMD.WAV'
  410.     call FxLnDtmf 1, 30, 'digits'
  411.     if result <> 'DTMF' then do
  412.       signal goodbye
  413.     end
  414.     else do
  415.       call FxLnMsg 'Code Mode command' digits
  416.       call FxLnVout 'Command' digits 'entered'
  417.  
  418.  
  419.       if digits = '1' then do            /* 1 = Play help msg */
  420.         call FxLnVout 'Help message'
  421.         call FxLnPlay VOXDIR||'HELP.WAV'
  422.       if result = 'NOTOK' then signal byebye
  423.         iterate
  424.       end
  425.  
  426.  
  427.       if digits = '2' & USERID <> '' then do    /* 2 = change access code */
  428.         /* Only access codes for LAN users are changed through this. */
  429.         /* For the fax server, use the CODE script variable on Voice page. */
  430.         call FxLnVout 'Change access code for' USERID
  431.         call FxLnMsg 'Code Mode command' digits
  432.         call FxLnPlay VOXDIR||'ENTR_COD.WAV'
  433.           if result = 'NOTOK' then signal byebye
  434.         code1 = GetNumber( 6, 10 )
  435.         call FxLnPlay VOXDIR||'ENTR_COD.WAV'
  436.           if result = 'NOTOK' then signal byebye
  437.         code2 = GetNumber( 6, 10 )
  438.         if code1 = code2 then do
  439.           call SaveCode code1
  440.           call FxLnPlay VOXDIR||'THANKYOU.WAV'
  441.         end
  442.         else do
  443.           call FxLnVout 'New code mismatch:' code1 'vs' code2
  444.           call FxLnPlay 'c:\mmos2\sounds\BOO.wav'
  445.         end
  446.         iterate
  447.       end
  448.  
  449.  
  450.       if digits = '3' then do            /* 3 = Enter outgoing msg */
  451.         call FxLnVout 'Enter outgoing message for' USERID
  452.         call FxLnPlay VOXDIR||'ENTR_MSG.WAV'
  453.       if result = 'NOTOK' then signal byebye
  454.         call FxLnTone 1850
  455.       if result = 'NOTOK' then signal byebye
  456.         call FxLnDtmf        /* flush buffer */
  457.         if USERID = ''
  458.         then call FxLnRecord OGM
  459.         else call FxLnRecord USERDIR||'OGM.WAV'
  460.       if result = 'NOTOK' then signal byebye
  461.         call FxLnTone 1850, 1850, 1850
  462.         call FxLnDtmf        /* flush buffer */
  463.         if USERID = ''
  464.         then call FxLnPlay OGM
  465.         else call FxLnPlay USERDIR||'OGM.WAV'
  466.       if result = 'NOTOK' then signal byebye
  467.         iterate
  468.       end
  469.  
  470.  
  471.       if digits = '4' then do            /* 4 = Previous msg */
  472.         call FxLnVout 'Play previous message' i
  473.         if i <= 1
  474.     then call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  475.     else do
  476.       i = i - 1
  477.           call FxLnMsg 'Code Mode command' digits 'Msg' list.i
  478.         call FxLnPlay list.i
  479.       end
  480.         iterate
  481.       end
  482.  
  483.  
  484.       if digits = '5' then do            /* 5 = Replay msg */
  485.         call FxLnVout 'Replay message' i
  486.         if i <= 0
  487.     then digits = '6'    /* replay = next if just starting */
  488.     else do
  489.           call FxLnMsg 'Code Mode command' digits 'Msg' list.i
  490.       call FxLnPlay list.i
  491.           iterate
  492.     end
  493.       end
  494.  
  495.  
  496.       if digits = '6' then do            /* 6 = Next message */
  497.         call FxLnVout 'Play next message' i j
  498.         if i = n 
  499.     then call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  500.     else do
  501.         i = i + 1
  502.         if i > j then do
  503.         call FxRxFind 'MSG', 'RCVD', 'LREC'
  504.         call FxLnVout 'Found' LREC.!ID
  505.         list.i = FxRxIndexToFax( LREC.!ID )    /* use pathname! */
  506.             /* Need path rather than index since FxRxSelect switch */
  507.             /* applies to FxRx calls, but not FxLn calls. */
  508.         j = i
  509.       end
  510.           call FxLnMsg 'Code Mode command' digits 'Msg' list.i
  511.         call FxLnPlay list.i
  512.         end
  513.         iterate
  514.       end
  515.  
  516.  
  517.       if digits = '7' then do            /* 7 = send rcvd faxes */
  518.         call FxLnVout 'Send rcvd faxes'
  519.         call FxLnMsg 'Code Mode command' digits
  520.         call FxRxFind 'FAX', 'N_RCVD'        /* get # of new faxes */
  521.         if result = 'NOTOK' then do
  522.           call FxLnPlay 'c:\mmos2\sounds\BOING.wav'
  523.           signal byebye
  524.         end
  525.         nfax = result
  526.         if nfax = 0 then do
  527.           call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  528.           if result = 'NOTOK' then signal byebye
  529.         end
  530.         else do
  531.           ifax = nfax        /* Get faxes into list and beep per fax */
  532.           faxlist = ''
  533.           flist = ''
  534.           call FxLnMsg 'Code Mode' nfax 'faxes'
  535.           call FxLnVout 'FaxBeep' nfax 'times'
  536.           do while ifax > 0
  537.             call FxLnTone 2100
  538.             ifax = ifax - 1
  539.             call FxRxFind 'FAX', 'RCVD', 'LREC'
  540.             call FxLnVout 'Found' LREC.!ID
  541.             /* Note use of filenames rather than ID values.  This is done */
  542.             /* because FxLnSend, which could be used in the FOD procedure,*/
  543.             /* cannot be given IDs from an FxRxSelect LAN user directory. */
  544.             faxlist = AddToCsvList( FxRxIndexToFax( LREC.!ID ), faxlist )
  545.             flist = flist LREC.!ID
  546.           end
  547.           /* call our FOD procedure to do the faxing */
  548.           FODPARAMS = "FxRxPath( 'LOG' ), VOXDIR, , CALLER, faxlist," ,
  549.             "'As you requested, your received faxes are attached:' flist," ,
  550.             "'Remote fax retrieval...'"
  551.           interpret 'call' "'"||FODPROCEDURE||"'" FODPARAMS
  552.           if result = 'BYEBYE' then signal BYEBYE
  553.           if result = 'OUT' then signal OUT
  554.         end
  555.         iterate
  556.       end
  557.  
  558.  
  559.       if digits = '8' then do            /* 8 = send log */
  560.         call FxLnVout 'Send log'
  561.         call FxLnMsg 'Code Mode command' digits
  562.         call FxLnPlay VOXDIR||'WAIT.WAV'
  563.       if result = 'NOTOK' then signal byebye
  564.         call SendLog
  565.           if result = 'BYEBYE' then signal BYEBYE
  566.           if result = 'OUT' then signal OUT
  567.         iterate
  568.       end
  569.  
  570.  
  571.       if digits = '9' then do            /* 9 = FOD from log */
  572.         call FxLnVout 'FOD from log'
  573.         call FxLnMsg 'Code Mode command' digits
  574.         FODPARAMS = "FxRxPath( 'LOG' ), VOXDIR, , CALLER, , ," ,
  575.                "'FOD Retrieval...'"
  576.         interpret 'call' "'"||FODPROCEDURE||"'" FODPARAMS
  577.           if result = 'BYEBYE' then signal BYEBYE
  578.           if result = 'OUT' then signal OUT
  579.         iterate
  580.       end
  581.  
  582.  
  583.       if digits = '0' then do            /* 0 = back to top level */
  584.         call FxLnVout 'Return to HELLO'
  585.     signal hello
  586.       end
  587.  
  588.  
  589.       if digits = '*' | digits = '#' then do
  590.         signal goodbye
  591.       end
  592.  
  593.  
  594.       /* otherwise, if none were matched... */
  595.       call FxLnVout 'Unknown command' i
  596.       call FxLnPlay 'c:\mmos2\sounds\EEERRUPP.wav'
  597.       iterate
  598.  
  599.     end
  600.   end
  601.  
  602.  
  603. goodbye:
  604.   call FxLnVout 'Exit Code Mode'
  605.   call FxLnPlay VOXDIR||'THANKYOU.WAV'
  606.   call FxLnPlay 'c:\mmos2\sounds\DRUMROLL.wav'
  607.   signal byebye
  608.  
  609.  
  610. evil:
  611.   call FxLnVout 'Bad code entered:' digits 'vs' CODE
  612.   call FxLnPlay 'c:\mmos2\sounds\BOO.wav'
  613.   call FxRxBeep 1318, 1396, 1318, 1090, 1318, 1396, 1318, 1090
  614.   signal byebye
  615.  
  616.  
  617. byebye:                    /* called for error cases */
  618.   LREC.!Status = ''            /* don't log anything */
  619.   signal out
  620.  
  621.  
  622. out:                    /* clean up and quit */
  623.   call FxLnTerm
  624.   exit
  625.  
  626.  
  627. /************************ Procedures ************************/
  628.  
  629.  
  630. GetNumber: procedure
  631.   /* Gets DTMF input until # or * key or "digits" are entered. */
  632.   /* TimeOut is seconds to wait for each digit (default 15).       */
  633.   parse arg digits, TimeOut
  634.   number = ''
  635.   if TimeOut = '' then TimeOut = 15  /* default to 15 seconds */
  636.   do digits
  637.     call FxLnDtmf 1, TimeOut, 'newkey'
  638.       if result <> 'DTMF' | newkey = '#' | newkey = '*' then leave
  639.     number = number||newkey
  640.   end
  641.   return number
  642.  
  643.  
  644. GetExtension: procedure
  645.   /* Gets DTMF input until # or * key or "digits" are entered. */
  646.   /* TimeOut is seconds to wait for first digit (default 15).   */
  647.   /* NextTime is seconds to wait for subsequent digits (default TimeOut)*/
  648.   /* Returns 'FAX' or 'DATA' or 'NOTOK' results or the number. */
  649.   parse arg digits, TimeOut, NextTime
  650.   number = ''
  651.   if TimeOut = '' then TimeOut = 15  /* default to 15 seconds */
  652.   if NextTime = '' then NextTime = TimeOut
  653.   do digits
  654.     call FxLnDtmf 1, TimeOut, 'newkey'
  655.       if result = 'FAX' | result = 'DATA' | result = 'NOTOK' then return result
  656.       if result <> 'DTMF' | newkey = '#' | newkey = '*' then leave
  657.     number = number||newkey
  658.     TimeOut = NextTime
  659.   end
  660.   return number
  661.  
  662.  
  663. TmpFile: procedure
  664.   /* Generate a unique base file name using seconds since midnight */
  665.   return 'TMP'||time( S )
  666.  
  667.  
  668. AddToCsvList: procedure
  669.   /* returns a comma-separated value list with item added */
  670.   parse arg item, list
  671.   if list = ''
  672.     then list = item
  673.     else list = list||','||item
  674.   return list
  675.  
  676.  
  677. SendLog:    /* sends the log file by fax */
  678.   tmp1 = VOXDIR||TmpFile()||'.TXT'
  679.   tmp2 = VOXDIR||TmpFile()||'.FAX'
  680.   log = FxRxPath( 'LOG' )||'fax.log'
  681.  
  682.   call LineOut tmp1, 'Fax Log   ' Date('W') ' '||Date('N') ' ' Time('C')
  683.   call LineOut tmp1, ''
  684.   call LineOut tmp1, ,
  685.        'Type ID      Date    Time  Pg Status Elpsd  Name/RemoteID/CallerID'
  686.   call LineOut tmp1, ''
  687.  
  688.   if LOGMAXLINE <= 0 then do /* send the entire fax log */
  689.     do while Lines( log ) > 0
  690.       record = LineIn( log )        /* read a record from log */
  691.       if FxRxParseLog( record, 'lrec' ) = OK then do
  692.         call LogRpt tmp1
  693.       end
  694.     end
  695.   end
  696.   else do /* send the last x lines from the log */
  697.     head = 1
  698.     tail = 1
  699.     do while Lines( log ) > 0    /* collect last x lines */
  700.       buf.head = LineIn( log )
  701.       head = head + 1
  702.       if head > LOGMAXLINE then head = 1
  703.       if head = tail then tail = tail + 1
  704.       if tail > LOGMAXLINE then tail = 1
  705.     end
  706.     if tail <> head & FxRxParseLog( buf.head, 'lrec' ) = OK then do
  707.       call LogRpt tmp1
  708.     end
  709.     do while tail <> head
  710.       if FxRxParseLog( buf.tail, 'lrec' ) = OK then do
  711.         call LogRpt tmp1
  712.       end
  713.       tail = tail + 1
  714.       if tail > LOGMAXLINE then tail = 1
  715.     end
  716.   end
  717.   rc = LineOut( log )            /* close the files */
  718.   rc = LineOut( tmp1 )
  719.   call FxRxTextToFax tmp1, tmp2        /* convert text to fax */
  720.   /* call our FOD procedure to do the faxing */
  721.   FODPARAMS = "FxRxPath( 'LOG' ), VOXDIR, , CALLER, tmp2," ,
  722.           "'As you requested, the log is attached.', 'Log retrieval...'"
  723.   interpret 'call' "'"||FODPROCEDURE||"'" FODPARAMS
  724.   fodresult = result
  725.   call FxLnVout 'Deleting:' tmp1
  726.   'DEL "'||tmp1||'"'
  727.   call FxLnVout 'Deleting:' tmp2
  728.   'DEL "'||tmp2||'"'
  729.   return fodresult
  730.  
  731.  
  732. LogRpt:
  733.   /* Using global lrec., write a report line to a file */
  734.   parse arg Rfile
  735.  
  736.   if BitTest( lrec.!Flags, 256 ) then mtype = 'MSG'
  737.   else if BitTest( lrec.!Flags, 512 ) then mtype = 'Txt'
  738.   else if BitTest( lrec.!Flags, 1024 ) then mtype = 'Dat'
  739.   else mtype = 'Fax'
  740.  
  741.   if lrec.!Company = ''
  742.   then namestr = lrec.!Name
  743.   else namestr = lrec.!Name||', '||lrec.!Company
  744.  
  745.   if lrec.!Pages = 0
  746.   then pagestr = ''    /* don't show 0 pages */
  747.   else pagestr = lrec.!Pages
  748.       
  749.   call LineOut Rfile, mtype left( lrec.!ID, 6 ) ,
  750.          left( lrec.!Date, 9 ) left( lrec.!Time, 5 ) ,
  751.          right( pagestr, 2 ) left( lrec.!Status, 6 ) ,
  752.          right( lrec.!Elapsed, 5) ' '||strip( left( namestr, 46 ) )
  753.   return
  754.  
  755.  
  756. BitTest: procedure
  757.   /* Given a number and a bit number, return 1 if bit is set */
  758.   parse arg value, bit
  759.   return (value % bit) // 2
  760.  
  761. SaveCode:
  762.   /* Save access code to file ACCESS.COD in user's log directory */
  763.   parse arg newcode
  764.   call LineOut USERDIR||'access.cod', newcode, 1
  765.   call LineOut USERDIR||'access.cod'        /* close file */
  766.   return
  767.  
  768. FetchCode:
  769.   /* Returns the access code for the current USERID */
  770.   newcode = LineIn( USERDIR||'access.cod', 1 )
  771.   call LineOut USERDIR||'access.cod'        /* close file */
  772.   if newcode = '' then newcode = DEFAULTCODE
  773.   return newcode
  774.