]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
more clean up
authorBrian West <brian@freeswitch.org>
Sat, 27 Jun 2009 00:33:29 +0000 (00:33 +0000)
committerBrian West <brian@freeswitch.org>
Sat, 27 Jun 2009 00:33:29 +0000 (00:33 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13997 d0543943-73ff-0310-b7d9-9358b9ac24b2

scripts/s25vmail/README [deleted file]
scripts/s25vmail/README.park [deleted file]
scripts/s25vmail/s25park.js [deleted file]
scripts/s25vmail/s25vmail.js [deleted file]
scripts/s25vmail/s25vmail_mwi.c [deleted file]

diff --git a/scripts/s25vmail/README b/scripts/s25vmail/README
deleted file mode 100644 (file)
index 040bf5a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-This directory contains software used for interfacing the
-FreeSWITCH voicemail application with the AT&T (aka Lucent
-aka Avaya) System 25 PBX.  It's possible that System 75
-and Definity PBXs may also work.
-
-s25vmail.js goes into the FreeSWITCH scripts directory.
-s25vmail_mwi.c should be compiled and the resulting binary
-put into the FreeSWITCH bin directory.  Modify the FreeSWITCH
-rc.d script to also start / stop s25vmail_mwi.
-
-Configuration fragments look something like:
-
-  conf/openzap.conf:
-
-    [span zt]
-    ; A204DX
-    name => OpenZAP
-    dtmf_hangup = ##99
-
-    number => 551
-    fxo-channel => 49
-
-    number => 552
-    fxo-channel => 50
-
-    number => 553
-    fxo-channel => 51
-
-    number => 554
-    fxo-channel => 52
-
-  conf/dialplan/default.xml
-
-    <extension name="system25_vmail">
-      <condition field="destination_number" expression="^(55[1-4])$">
-        <action application="javascript" data="s25vmail.js"/>
-      </condition>
-    </extension>
-
-Tested using FreeSWITCH SVN 10428 running on FreeBSD 6.3
-with a Sangoma A200DX Analog Series w/ Echo Cancellation
-ports card containing 2 FXO modules.
-
-Note that the PBX is * very * sensitive to how long it takes
-for the line to be hung up after it sends the DTMF hangup
-command.  Failure to apply the following patch will cause
-the PBX to occasionally believe that some vmail lines were
-off hook for too long and are therfore out of service.
-
-Index: src/zap_io.c
-===================================================================
---- src/zap_io.c       (revision 745)
-+++ src/zap_io.c       (working copy)
-@@ -1728,7 +1728,8 @@
-                       zchan->dtmf_hangup_buf[zchan->span->dtmf_hangup_len - 1] = *p;
-                       if (!strcmp(zchan->dtmf_hangup_buf, zchan->span->dtmf_hangup)) {
-                               zap_log(ZAP_LOG_DEBUG, "DTMF hangup detected.\n");
--                              zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP);
-+                              zchan->caller_data.hangup_cause = ZAP_CAUSE_NORMAL_CLEARING;
-+                              zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
-                               break;
-                       }
-               }
diff --git a/scripts/s25vmail/README.park b/scripts/s25vmail/README.park
deleted file mode 100644 (file)
index a6f1519..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-This directory contains software for configuring FreeSWITCH
-to provide AT&T (aka Lucent aka Avaya) System 25 PBX compatible
-park and pickup park functions.  Specifically:
-
-  a) Putting a call on hold and then dialing *5 will park the
-     call on your phone.
-
-  b) Dialing *8 followed by an extension will pickup a call parked
-     on that extension.
-
-as a bonus:
-
-  c) Doing a blind transfer of a call to *5 will park the call
-     on your phone.
-
-  d) Doing a blind transfer of a call to *5 followed by an extension
-     will park the call on that extension.
-
-  e) Dialing *8 without an extension will prompt for an extension.
-
-s25park.js goes into the FreeSWITCH scripts directory.
-
-Configuration fragments look something like:
-
-  conf/dialplan/default.xml
-
-    <extension name="system25_park">
-      <condition field="source" expression="mod_sofia"/>
-      <condition field="destination_number" expression="^\*5$"/>
-      <condition field="${sip_h_Referred-By}" expression="^<sip:([0-9]{4})@.*$">
-        <action application="transfer" data="*5$1"/>
-        <anti-action application="javascript" data="s25park.js"/>
-      </condition>
-    </extension>
-
-    <extension name="system25_park_on_extension">
-      <condition field="destination_number" expression="^\*5([0-9]{4})$">
-        <action application="set" data="fifo_music=$${hold_music}"/>
-        <action application="set" data="fifo_orbit_exten=$1:120"/>
-        <action application="fifo" data="$1@$${domain} in"/>
-      </condition>
-    </extension>
-
-    <extension name="system25_pickup">
-      <condition field="destination_number" expression="^\*8$">
-        <action application="answer"/>
-        <action application="sleep" data="1"/>
-        <action application="read" data="3 5 $${base_dir}/sounds/en/us/callie/ivr/8000/ivr-enter_ext.wav ext 1000 #"/>
-        <action application="transfer" data="*8${ext}"/>
-      </condition>
-    </extension>
-
-    <extension name="system25_pickup_from_extension">
-      <condition field="destination_number" expression="^\*8[0-9]{3,4}$"/>
-      <condition field="destination_number" expression="^\*8([0-9]{4})$">
-        <action application="fifo" data="$1@$${domain} out nowait"/>
-        <anti-action application="bridge" data="openzap/5/a/${destination_number}"/>
-      </condition>
-    </extension>
-
-The system25 park and pickup dialplan patterns are designed
-to only consider four digit extensions for local parking.
-"system25_pickup_from_extension" recognizes three digit
-extensions as being parked on a foreign PBX ... modify
-as appropriate for your installation.
-
-Be aware that the default dialplan contains an extension
-called "group-intercept" which needs to be commented out
-in order for "system25_pickup" to work since they both
-match *8.
-
-Tested using FreeSWITCH SVN 13769 running on FreeBSD 6.4.
diff --git a/scripts/s25vmail/s25park.js b/scripts/s25vmail/s25park.js
deleted file mode 100644 (file)
index a6be33c..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  File:    s25park.js
- *  Purpose: Implement AT&T System 25 PBX style parking.
- *  Machine:                      OS:
- *  Author:  John Wehle           Date: June 9, 2009
- */
-
-/*
- *  Copyright (c)  2009  Feith Systems and Software, Inc.
- *                      All Rights Reserved
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/* RE to sanity check that the caller id is a valid extension */
-var extRE = /^[0-9]{3,4}$/g;
-
-
-var dtmf_digits;
-
-function on_dtmf (session, type, obj, arg)
-  {
-
-  if (type == "dtmf") {
-    dtmf_digits += obj.digit;
-    return false;
-    }
-
-  return true;
-  }
-
-
-function normalize_channel_name (name, direction, ip_addr)
-  {
-  var re = /^sofia\//g;
-  var length = name.search (re);
-  var new_name = name;
-  
-  if (length == -1)
-    return new_name;
-
-  if (direction == "inbound") {
-    re = /@.*$/g;
-
-    new_name = name.replace (re, "@" + ip_addr);
-    }
-  else if (direction == "outbound") {
-    re = /\/sip:(.*@[^:]*):.*$/g;
-
-    new_name = name.replace (re, "/$1");
-    }
-
-  return new_name;
-  }
-
-
-session.answer ();
-
-session.execute ("sleep", "1000");
-
-/*
- * Figure out the normalized form of the requester's channel name.
- */
-
-var requester_channel_name = normalize_channel_name (
-  session.getVariable ("channel_name"), "inbound",
-  session.getVariable ("network_addr"));
-
-/*
- * Find the uuid for a call on the requester's phone.
- */
-
-var channels = apiExecute ("show", "channels as xml");
-var re = /\s+$/g;
-var length = channels.search (re);
-
-if (length == -1)
-  length = channels.length;
-
-channels = channels.substring (0, length);
-
-var xchannels = new XML (channels);
-var our_uuid = session.getVariable ("uuid");
-var requester_uuid = "";
-
-for each (var channel in xchannels.row) {
-  if (channel.uuid.toString () == our_uuid)
-    continue;
-
-  var channel_name =  normalize_channel_name (channel.name.toString (),
-             channel.direction.toString (), channel.ip_addr.toString ());
-
-  if (channel_name == requester_channel_name) {
-    requester_uuid = channel.uuid.toString ();
-    break;
-    }
-  }
-
-if (requester_uuid == "") {
-  session.sayPhrase ("voicemail_invalid_extension", "#", "", on_dtmf, "");
-  session.hangup ();
-  exit ();
-  }
-
-/*
- * Find the peer uuid.
- */
-
-var udump = apiExecute ("uuid_dump", requester_uuid + " xml");
-var re = /\s+$/g;
-var length = udump.search (re);
-
-if (length == -1)
-  length = udump.length;
-
-udump = udump.substring (0, length);
-
-var xudump = new XML (udump);
-var uuid = xudump.headers['Other-Leg-Unique-ID'].toString ();
-
-if (uuid == "") {
-  session.sayPhrase ("voicemail_invalid_extension", "#", "", on_dtmf, "");
-  session.hangup ();
-  exit ();
-  }
-
-var requester_id_number = session.getVariable ("caller_id_number");
-
-if (requester_id_number.search (extRE) == -1) {
-  session.sayPhrase ("voicemail_invalid_extension", "#", "", on_dtmf, "");
-  session.hangup ();
-  exit ();
-  }
-
-apiExecute ("uuid_setvar", uuid + " hangup_after_bridge false");
-apiExecute ("uuid_transfer", uuid + " *5" + requester_id_number + " XML default");
-
-/*
- * Provide confirmation beeps followed by some silence.
- */
-
-var confirmation = "tone_stream://L=3;%(100,100,350,440)";
-
-session.execute ("playback", confirmation);
-
-var i;
-
-for (i = 0; session.ready () && i < 100; i++)
-  session.execute("sleep", "100");
-
-exit ();
diff --git a/scripts/s25vmail/s25vmail.js b/scripts/s25vmail/s25vmail.js
deleted file mode 100644 (file)
index 5c4e864..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- *  File:    s25vmail.js
- *  Purpose: Invoke voicemail based on AT&T System 25 PBX voicemail mode codes
- *  Machine:                      OS:
- *  Author:  John Wehle           Date: June 24, 2008
- *
- *  The message waiting indicator is handled by a separate program.
- */
-
-/*
- *  Copyright (c)  2008  Feith Systems and Software, Inc.
- *                      All Rights Reserved
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-var id_digits_required = 3;
-
-var digitTimeOut = 3000;
-var interDigitTimeOut = 1000;
-var absoluteTimeOut = 10000;
-
-
-var dtmf_digits = "";
-function on_dtmf (session, type, obj, arg)
-  {
-
-  if (type == "dtmf") {
-    dtmf_digits += obj.digit;
-    }
-
-  return true;
-  }
-
-
-function prompt_for_id ()
-  {
-  var dto;
-  var id;
-  var index;
-  var repeat;
-  
-  dtmf_digits = "";
-  id = "";
-  repeat = 0;
-
-  while (session.ready () && repeat < 3) {
-    session.flushDigits ();
-  
-    /* play phrase - if digit keyed while playing callback will catch them*/
-    session.sayPhrase ("voicemail_enter_id", "#", "", on_dtmf, "");
-
-    if (! session.ready ())
-      return "";
-
-    id = dtmf_digits;
-
-    if (id.indexOf ('#') == -1) {
-      dto = digitTimeOut;
-      if (dtmf_digits.length != 0)
-        dto = interDigitTimeOut;
-      dtmf_digits = session.getDigits (5, '#', dto,
-                                       interDigitTimeOut, absoluteTimeOut);
-      id += dtmf_digits;
-      id += '#';
-      }
-
-    /* a valid id must meet the minimum length requirements */
-    if ((index = id.indexOf ('#')) >= id_digits_required) {
-      id = id.substring (0,index);
-      break;
-      }
-
-    dtmf_digits = "";
-    id = "";
-    repeat++;
-    }
-
-  return id;
-  }
-
-
-var start = "";
-var mode = "";
-var from = "";
-var to = "";
-
-var domain = session.getVariable ("domain");
-
-session.answer ();
-
-start = session.getDigits (1, '', digitTimeOut,
-                           interDigitTimeOut, absoluteTimeOut);
-
-if (start != "#") {
-  var destination_number = session.getVariable ("destination_number");
-
-  console_log ("err", destination_number + " received an invalid VMAIL start code from PBX\n");
-  if (session.ready ())
-    session.sayPhrase ("voicemail_goodbye", "#", "", on_dtmf, "");
-  else
-    console_log ("err", "Possibly due to early hangup from PBX\n");
-  session.hangup ();
-  exit();
-  }
-
-mode = session.getDigits (5, '#', digitTimeOut,
-                          interDigitTimeOut, absoluteTimeOut);
-
-from = session.getDigits (5, '#', digitTimeOut,
-                          interDigitTimeOut, absoluteTimeOut);
-
-to = session.getDigits (5, '#', digitTimeOut,
-                        interDigitTimeOut, absoluteTimeOut);
-
-session.execute("sleep", "1000");
-
-// Verify that the proper parameters are present
-switch (mode) {
-
-  // Direct Inside Access
-  case "00":
-    if (isNaN (parseInt (from, 10))) {
-      console_log ("err", "Invalid VMAIL calling PDC from PBX\n");
-      break;
-      }
-
-    session.setVariable ("voicemail_authorized", "false");
-    session.execute ("voicemail", "check default " + domain + " " + from);
-    break;
-
-  // Direct Dial Access
-  case "01":
-    from = prompt_for_id ();
-
-    if (! session.ready ()) {
-      session.hangup ();
-      exit();
-      }
-
-    if (isNaN (parseInt (from, 10))) {
-      console_log ("err", "Invalid VMAIL mailbox from caller\n");
-      break;
-      }
-
-    session.setVariable ("voicemail_authorized", "false");
-    session.execute ("voicemail", "check default " + domain + " " + from);
-    break;
-
-  // Coverage - caller is inside
-  case "02":
-    if (isNaN (parseInt (from, 10)) || isNaN (parseInt (to, 10))) {
-      console_log ("err", "Invalid VMAIL calling or called PDC from PBX\n");
-      break;
-      }
-
-    session.setVariable ("effective_caller_id_name", "inside caller");
-    session.setVariable ("effective_caller_id_number", from);
-
-    session.execute ("voicemail", "default " + domain + " " + to);
-    break;
-
-  // Coverage - caller is dial
-  case "03":
-    if (isNaN (parseInt (to, 10))) {
-      console_log ("err", "Invalid VMAIL called PDC from PBX\n");
-      break;
-      }
-
-    session.setVariable ("effective_caller_id_name", "outside caller");
-    session.setVariable ("effective_caller_id_number", "Unknown");
-
-    session.execute ("voicemail", "default " + domain + " " + to);
-    break;
-
-  // Coverage - not yet defined
-  case "04":
-    break;
-
-  // Leave Word Calling
-  case "05":
-    if (isNaN (parseInt (from, 10)) || isNaN (parseInt (to, 10))) {
-      console_log ("err", "Invalid VMAIL calling or called PDC from PBX\n");
-      break;
-      }
-    break;
-
-  // Refresh MW lamps
-  case "06":
-    break;
-
-  // Voice Port failed to answer
-  case "08":
-    if (isNaN (parseInt (to, 10))) {
-      console_log ("err", "Invalid VMAIL PDC from PBX\n");
-      break;
-      }
-
-    console_log ("err", "PBX reports problem with VMAIL PDC " + to + "\n");
-    break;
-
-  // Unknown
-  default:
-    console_log ("err", "Invalid VMAIL mode code from PBX\n");
-    break;
-  }
-
-exit();
diff --git a/scripts/s25vmail/s25vmail_mwi.c b/scripts/s25vmail/s25vmail_mwi.c
deleted file mode 100644 (file)
index d9c6798..0000000
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- *  File:    s25vmail_mwi.c
- *  Purpose: Send AT&T System 25 PBX MWI DTMF based on MWI events
- *  Machine:                      OS:
- *  Author:  John Wehle           Date: July 24, 2008
- *
- *  Tested using a Zyxel U90e configured using:
- *
- *    at OK at&f OK at&d3&y2q2 OK ats0=0s2=255s15.7=0s18=4s35.1=0 OK
- *    ats38.3=1s42.3=1s42.6=1 OK atl0 OK at&w OK at&v
- *
- *  though just about any modem should work.  Preferred settings are
- *
- *    DTR OFF causes hangup and reset from profile 0
- *    RTS / CTS flow control
- *    allow abort during modem handshake
- *    auto answer off
- *    ring message off
- */
-
-/*
- *  Copyright (c)  2008  Feith Systems and Software, Inc.
- *                      All Rights Reserved
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <ctype.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <termios.h>
-
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <unistd.h>
-
-
-#define LOGFILE                    "/var/log/s25vmail_mwi.log"
-
-
-static const char *MyName = "s25vmail_mwi";
-
-static int daimon = 0;
-static int error_msg_throttle = 0;
-static volatile int shutdown_server = 0;
-
-
-static void
-debugmsg (const char *fmt, ...)
-  {
-  char message[256];
-  va_list args;
-
-  if (daimon)
-    return;
-
-  va_start (args, fmt);
-  vsprintf (message, fmt, args);
-  va_end (args);
-
-  fprintf (stderr, "%s: %s", MyName, message);
-  if ( !strchr (message, '\n'))
-    fprintf (stderr, "\n");
-  fflush (stderr);
-  }
-
-
-static void
-errmsg (const char *fmt, ...)
-  {
-  char time_stamp[256];
-  struct tm *tmp;
-  time_t now;
-  va_list args;
-
-  if (! daimon) {
-    fprintf (stderr, "%s: ", MyName);
-
-    va_start (args, fmt);
-    vfprintf (stderr, fmt, args);
-    va_end (args);
-
-    if (! strchr (fmt, '\n'))
-      fputc ('\n', stderr);
-
-    fflush (stderr);
-    return;
-    }
-
-  if (error_msg_throttle)
-    return;
-
-  time (&now);
-
-  if ( !(tmp = localtime (&now)) ) {
-    fprintf (stderr, "%s: errmsg -- localtime failed.\n", MyName);
-    perror (MyName);
-    fflush (stderr);
-    return;
-    }
-
-  strftime (time_stamp, sizeof (time_stamp), "%b %d %H:%M:%S", tmp);
-  fprintf (stderr, "%s %s[%d]: ", time_stamp, MyName, (int)getpid ());
-
-  va_start (args, fmt);
-  vfprintf (stderr, fmt, args);
-  va_end (args);
-
-  if (! strchr (fmt, '\n'))
-    fputc ('\n', stderr);
-
-  fflush (stderr);
-  }
-
-
-static void
-catch_signal ()
-  {
-
-  shutdown_server = 1;
-  }
-
-
-static void
-daemonize()
-  {
-
-#ifdef SIGTSTP
-  (void)signal(SIGTSTP, SIG_IGN);
-#endif
-#ifdef SIGTTIN
-  (void)signal(SIGTTIN, SIG_IGN);
-#endif
-#ifdef SIGTTOU
-  (void)signal(SIGTTOU, SIG_IGN);
-#endif
-
-  switch (fork ()) {
-    case 0:
-      break;
-
-    case -1:
-      fprintf (stderr, "%s: daemonize -- fork failed.", MyName);
-      perror (MyName);
-      exit (1);
-    /* NOTREACHED */
-      break;
-
-    default:
-      exit (0);
-    /* NOTREACHED */
-      break;
-    }
-
-  setsid();
-
-  close (0);
-  close (1);
-  close (2);
-
-  (void)open ("/dev/null", O_RDWR);
-  (void)open ("/dev/null", O_RDWR);
-  (void)open (LOGFILE, O_WRONLY | O_APPEND | O_CREAT, 0644);
-
-  daimon = 1;
-  }
-
-
-static void
-install_signal_handlers ()
-  {
-  struct sigaction act;
-
-  memset (&act, '\0', sizeof (act));
-
-  act.sa_handler = catch_signal;
-  sigemptyset (&act.sa_mask);
-  act.sa_flags = 0;
-
-  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
-    sigaction (SIGHUP, &act, NULL);
-  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
-    sigaction (SIGINT, &act, NULL);
-  (void)sigaction (SIGTERM, &act, NULL);
-  }
-
-
-static int
-connect_to_service (const char *hostname, const char *port)
-  {
-  int sock;
-  struct hostent *hp;
-  struct in_addr address;
-  struct servent *servp;
-  struct sockaddr_in sin;
-  
-  if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
-    char *errstr = strerror (errno);
-
-    errmsg ("socket failed\n");
-    errmsg (errstr);
-    return -1;
-    }
-
-  memset (&sin, 0, sizeof (sin));
-
-  if (isalpha (hostname[0])) {
-    if ( !(hp = gethostbyname (hostname))) {
-      char *errstr = strerror (errno);
-
-      errmsg ("gethostbyname failed\n");
-      errmsg (errstr);
-      close (sock);
-      return -1;
-      }
-    if (hp->h_addrtype != AF_INET) {
-      errmsg ("gethostbyname returned unsupported family\n");
-      close (sock);
-      return -1;
-      }
-    memcpy (&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
-    }
-  else {
-    address.s_addr = inet_addr (hostname);
-
-    if ((long)address.s_addr == -1) {
-      char *errstr = strerror (errno);
-
-      errmsg ("inet_addr failed\n");
-      errmsg (errstr);
-      close (sock);
-      return -1;
-      }
-    sin.sin_addr.s_addr = address.s_addr;
-    }
-
-  if (isalpha (*port)) {
-    if ( !(servp = getservbyname(port, "tcp"))) {
-      char *errstr = strerror (errno);
-
-      errmsg ("getservbyname failed\n");
-      errmsg (errstr);
-      close (sock);
-      return -1;
-      }
-    sin.sin_port = servp->s_port;
-    }
-  else
-    sin.sin_port = htons ((unsigned short)atoi (port));
-
-  sin.sin_family = AF_INET;
-
-  if (connect (sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
-    char *errstr = strerror (errno);
-
-    errmsg ("connect failed\n");
-    errmsg (errstr);
-    close (sock);
-    return -1;
-    }
-
-  debugmsg ("Connected to service\n");
-
-  return sock;
-  }
-
-
-static ssize_t
-read_line (int fd, char *buf, size_t buf_len)
-  {
-  size_t l;
-  ssize_t nbytes_read;
-
-  l = 0;
-
-  for ( ; ; ) {
-    nbytes_read = read (fd, &buf[l], 1);
-
-    if (nbytes_read < 0) {
-      char *errstr = strerror (errno);
-
-      errmsg ("read failed in middle of line\n");
-      errmsg (errstr);
-      return -1;
-      }
-
-    if (nbytes_read == 0) {
-      if (l)
-        errmsg ("EOF in middle of line\n");
-      return l ? -1 : 0;
-      }
-
-    if (buf[l] == '\n') {
-      while (l && buf[l - 1] == '\r')
-        l--;
-      buf[l++] = '\0';
-      break;
-      }
-
-    l++;
-
-    if (l == buf_len) {
-      errmsg ("line too long\n");
-      return -1;
-      }
-    }
-
-  return l;
-  }
-
-
-static int
-read_trailing_newline(int fd)
-  {
-  char c;
-  ssize_t nbytes_read;
-
-  nbytes_read = read (fd, &c, 1);
-
-  if (nbytes_read < 0) {
-    char *errstr = strerror (errno);
-
-    errmsg ("read failed in trailing newline\n");
-    errmsg (errstr);
-    return -1;
-    }
-
-  if (nbytes_read == 0) {
-    errmsg ("EOF in trailing newline\n");
-    return -1;
-    }
-
-  if (c != '\n') {
-    errmsg ("missing trailing newline\n");
-    return -1;
-    }
-
-  return 0;
-  }
-
-
-static char *
-retrieve_message (int fd)
-  {
-  char cl_buf[64];
-  char ct_buf[64];
-  char *h;
-  char *m;
-  ssize_t cl;
-  ssize_t nbytes_read;
-  size_t l;
-  size_t nbytes_to_read;
-
-  if (shutdown_server)
-    return NULL;
-
-  /*
-   * Read / parse Content-Length and Content-Type.
-   */
-
-  nbytes_read = read_line (fd, cl_buf, sizeof (cl_buf));
-
-  if (nbytes_read < 0) {
-    errmsg ("read_line failed\n");
-    return NULL;
-    }
-
-  if (nbytes_read == 0) {
-
-    /*
-     * EOF
-     */
-
-    return NULL;
-    }
-
-  nbytes_read = read_line (fd, ct_buf, sizeof (ct_buf));
-
-  if (nbytes_read < 0) {
-    errmsg ("read_line failed\n");
-    return NULL;
-    }
-
-  if (nbytes_read == 0) {
-    errmsg ("EOF in middle of headers\n");
-    return NULL;
-    }
-
-  h = "Content-Length: ";
-  l = strlen (h);
-
-  if (strncmp (cl_buf, h, l) != 0) {
-
-    /*
-     * If the message header doesn't being with Content-Length,
-     * then it needs to be a Content-Type we understand.
-     */
-
-    h = "Content-Type: ";
-    l = strlen (h);
-
-    if (strncmp (cl_buf, h, l) != 0) {
-      errmsg ("missing Content-Type\n");
-      return NULL;
-      }
-
-    if (strcmp (&cl_buf[l], "auth/request") != 0
-        && strcmp (&cl_buf[l], "command/reply") != 0) {
-      errmsg ("Unsupported Content-Type\n");
-      return NULL;
-      }
-
-    if (ct_buf[0])
-      if (read_trailing_newline (fd) < 0) {
-        return NULL;
-        }
-
-    m = malloc (strlen (cl_buf) + 1 + strlen (ct_buf) + 1 + 1);
-
-    if (! m) {
-      char *errstr = strerror (errno);
-
-      errmsg ("malloc failed\n");
-      errmsg (errstr);
-      return NULL;
-      }
-
-    sprintf (m, "%s\n%s\n", cl_buf, ct_buf);
-
-    return m;
-    }
-
-  cl = atoi (&cl_buf[l]);
-
-  if (cl <= 0) {
-    errmsg ("Content-Length must be greater than zero\n");
-    return NULL;
-    }
-
-  h = "Content-Type: ";
-  l = strlen (h);
-
-  if (strncmp (ct_buf, h, l) != 0) {
-    errmsg ("missing Content-Type\n");
-    return NULL;
-    }
-
-  if (strcmp (&ct_buf[l], "text/event-plain") != 0) {
-    errmsg ("Unsupported Content-Type\n");
-    return NULL;
-    }
-
-  if (read_trailing_newline (fd) < 0) {
-    return NULL;
-    }
-
-  /*
-   * Read the event.
-   */
-
-  m = malloc (cl);
-
-  if (! m) {
-    char *errstr = strerror (errno);
-
-    errmsg ("malloc failed\n");
-    errmsg (errstr);
-    return NULL;
-    }
-
-  for (nbytes_to_read = cl; nbytes_to_read; nbytes_to_read -= nbytes_read) {
-    nbytes_read = read (fd, m + (cl - nbytes_to_read), nbytes_to_read);
-
-    if (nbytes_read < 0) {
-      char *errstr = strerror (errno);
-
-      errmsg ("read failed in middle of message\n");
-      errmsg (errstr);
-      free (m);
-      return NULL;
-      }
-
-    if (nbytes_read == 0) {
-      errmsg ("EOF in middle of message\n");
-      free (m);
-      return NULL;
-      }
-    }
-
-  if (m[cl - 2] != '\n' || m[cl - 1] != '\n') {
-    errmsg ("Message is missing trailing newlines\n");
-    free (m);
-    return NULL;
-    }
-
-  return m;
-  }
-
-
-static int
-send_password (int fd, const char *passwd)
-  {
-  char *h;
-  char *last;
-  char *m;
-  char *p;
-  int l;
-  size_t ml;
-
-  m = retrieve_message (fd);
-  if (! m)
-    return -1;
-
-  p = strtok_r (m, "\n", &last);
-
-  h = "Content-Type: auth/request";
-
-  if (strcmp (p, h) != 0) {
-    errmsg ("Content-Type wasn't auth/request\n");
-    free (m);
-    return -1;
-    }
-
-  free (m);
-
-  l = snprintf (NULL, 0, "auth %s\n\n", passwd);
-  if (l <= 0) {
-    errmsg ("snprintf failed\n");
-    return -1;
-    }
-  l++;
-
-  m = malloc (l);
-  if (! m) {
-    char *errstr = strerror (errno);
-
-    errmsg ("malloc failed\n");
-    errmsg (errstr);
-    return -1;
-    }
-
-  ml = snprintf (m, l, "auth %s\n\n", passwd);
-  if ((ml + 1) != l) {
-    errmsg ("snprintf failed\n");
-    free (m);
-    return -1;
-    }
-
-  if (write (fd, m, ml) != ml) {
-    char *errstr = strerror (errno);
-
-    errmsg ("write failed\n");
-    errmsg (errstr);
-    free (m);
-    return -1;
-    }
-
-  m = retrieve_message (fd);
-  if (! m )
-    return -1;
-
-  p = strtok_r (m, "\n", &last);
-
-  h = "Content-Type: command/reply";
-
-  if (! p || strcmp (p, h) != 0) {
-    errmsg ("Content-Type wasn't command/reply\n");
-    free (m);
-    return -1;
-    }
-
-  p = strtok_r (NULL, "\n", &last);
-
-  h = "Reply-Text: +OK accepted";
-
-  if (! p || strcmp (p, h) != 0) {
-    errmsg ("auth wasn't accepted\n");
-    free (m);
-    return -1;
-    }
-
-  free (m);
-
-  debugmsg ("Logged into service\n");
-
-  return 0;
-  }
-
-
-static int
-enable_mwi_event (int fd)
-  {
-  char *h;
-  char *last;
-  char *m;
-  char *p;
-  size_t ml;
-
-  m = "event plain MESSAGE_WAITING\n\n";
-  ml = strlen (m);
-
-  if (write (fd, m, ml) != ml) {
-    char *errstr = strerror (errno);
-
-    errmsg ("write failed\n");
-    errmsg (errstr);
-    return -1;
-    }
-
-  m = retrieve_message (fd);
-  if (! m )
-    return -1;
-
-  p = strtok_r (m, "\n", &last);
-
-  h = "Content-Type: command/reply";
-
-  if (! p || strcmp (p, h) != 0) {
-    errmsg ("Content-Type wasn't command/reply\n");
-    free (m);
-    return -1;
-    }
-
-  p = strtok_r (NULL, "\n", &last);
-
-  h = "Reply-Text: +OK event listener enabled plain";
-
-  if (! p || strcmp (p, h) != 0) {
-    errmsg ("event wasn't enabled\n");
-    free (m);
-    return -1;
-    }
-
-  free (m);
-
-  debugmsg ("Enabled message waiting event\n");
-
-  return 0;
-  }
-
-
-static int
-process_mwi_event (char *m, const char *device)
-  {
-  char cbuf[64];
-  char rbuf[64];
-  char *h;
-  char *last;
-  char *ma;
-  char *mw;
-  char *p;
-  int fd;
-  int mwi_off;
-  int mwi_on;
-  int r;
-  int w;
-  size_t l;
-  ssize_t ml;
-  ssize_t nbytes_read;
-  struct termios tio;
-
-  debugmsg ("Processing MWI event\n");
-
-  ma = NULL;
-  mw = NULL;
-
-  p = m;
-
-  while ( (p = strtok_r (p, "\n", &last)) ) {
-    h = "MWI-Messages-Waiting: ";
-    l = strlen (h);
-
-    if (strncmp (p, h, l) == 0)
-      mw = p + l;
-
-    h = "MWI-Message-Account: ";
-    l = strlen (h);
-
-    if (strncmp (p, h, l) == 0)
-      ma = p + l;
-
-    p = NULL;
-    }
-
-  if (! (ma && mw) ) {
-    errmsg ("message account or message waiting missing\n");
-    return -1;
-    }
-
-  p = strchr (ma, '\n');
-  if (p)
-    *p = '\n';
-
-  p = strchr (mw, '\n');
-  if (p)
-    *p = '\n';
-
-  /*
-   * The account is considered to be a System 25 extension if
-   * it's of the form:
-   *
-   *   numeric_string@host
-   */
-
-  p = strchr (ma, '%');
-  if (! p)
-    p = strchr (ma, '@');
-
-  if (! p || (strncmp (p, "%40", 3) != 0 && strncmp (p, "@", 1) != 0)) {
-    debugmsg ("  %s is not a System 25 extension\n", ma);
-    return 0;
-    }
-
-  *p = '\0';
-
-  for (p = ma; *p; p++)
-    if (! isdigit (*p)) {
-      debugmsg ("  %s is not a System 25 extension\n", ma);
-      return 0;
-      }
-
-  mwi_off = strcasecmp (mw, "no") == 0;
-  mwi_on = strcasecmp (mw, "yes") == 0;
-
-  if (mwi_off == mwi_on) {
-    errmsg ("Unsupported Messages-Waiting\n");
-    return 0;
-    }
-
-  for (r = 0; r < 3; r++) {
-    if ((fd = open (device, O_RDWR)) < 0) {
-      char *errstr = strerror (errno);
-
-      errmsg ("open failed for device node <%s>.\n", device);
-      errmsg (errstr);
-      return -1;
-      }
-
-    cfmakeraw (&tio);
-
-    tio.c_cflag = CS8 | CREAD | HUPCL | CCTS_OFLOW | CRTS_IFLOW;
-
-    tio.c_cc[VMIN] = 0;
-    tio.c_cc[VTIME] = 50;
-
-    cfsetispeed (&tio, B9600);
-    cfsetospeed (&tio, B9600);
-
-    if (tcsetattr (fd, TCSAFLUSH, &tio) < 0) {
-      char *errstr = strerror (errno);
-
-      errmsg ("tcsetattr failed\n");
-      errmsg (errstr);
-      close (fd);
-      return -1;
-      }
-
-    m = "AT";
-    ml = strlen (m);
-
-    if (write (fd, m, ml) != ml
-        || write (fd, "\r\n", 2) != 2) {
-      char *errstr = strerror (errno);
-
-      errmsg ("write failed\n");
-      errmsg (errstr);
-      close (fd);
-      return -1;
-      }
-
-    for (w = 0; w < 2; w++) {
-      nbytes_read = read_line (fd, rbuf, sizeof (rbuf));
-      if (nbytes_read > 0 && (rbuf[0] == '\0' || strcmp (rbuf, m) == 0))
-        continue;
-      break;
-      }
-
-    if (nbytes_read < 0) {
-      errmsg ("read_line failed\n");
-      close (fd);
-      return -1;
-      }
-
-    if (nbytes_read == 0
-        || strcmp (rbuf, "OK") != 0) {
-      errmsg ("modem failed to wake up\n");
-      close (fd);
-      continue;
-      }
-
-    m = cbuf;
-    ml  = snprintf (cbuf, sizeof (cbuf),
-                    "ATDT%s%s", (mwi_on ? "#90" : "#91"),  ma);
-    if (ml <= 0 || ml >= sizeof (cbuf)) {
-      errmsg ("snprintf failed.\n");
-      close (fd);
-      return -1;
-      }
-
-    if (write (fd, m, ml) != ml
-        || write (fd, "\r\n", 2) != 2) {
-      char *errstr = strerror (errno);
-
-      errmsg ("write failed\n");
-      errmsg (errstr);
-      close (fd);
-      return -1;
-      }
-
-    sleep (5);
-
-    if (write (fd, "\r\n", 2) != 2) {
-      char *errstr = strerror (errno);
-
-      errmsg ("write failed\n");
-      errmsg (errstr);
-      close (fd);
-      return -1;
-      }
-
-    for (w = 0; w < 2; w++) {
-      nbytes_read = read_line (fd, rbuf, sizeof (rbuf));
-      if (nbytes_read > 0 && (rbuf[0] == '\0' || strcmp (rbuf, m) == 0))
-        continue;
-      break;
-      }
-
-    if (nbytes_read < 0) {
-      errmsg ("read_line failed\n");
-      close (fd);
-      return -1;
-      }
-
-    if (nbytes_read > 0 && strcmp (rbuf, "NO DIALTONE") == 0) {
-      errmsg ("modem failed to detect dialtone\n");
-      close (fd);
-      return -1;
-      }
-
-    if (nbytes_read == 0
-        || strcmp (rbuf, "NO CARRIER") != 0) {
-      errmsg ("modem failed to update MWI\n");
-      close (fd);
-      continue;
-      }
-
-    close (fd);
-
-    debugmsg ("  message waiting indicator updated for %s\n", ma);
-    return 0;
-    }
-
-  errmsg (" failed to update message waiting indicator for %s\n", ma);
-
-  return -1;
-  }
-
-
-int
-main (int argc, char **argv)
-  {
-  const char *device = "/dev/cuad0";
-  const char *machine = "localhost";
-  const char *port = "8021";
-  const char *passwd = "ClueCon";
-  char *m;
-  int c;
-  int debug;
-  int fd;
-  struct stat statbuf;
-
-  debug = 0;
-
-  while ((c = getopt (argc, argv, "dm:p:w:")) != -1)
-    switch (c) {
-      case 'd':
-        debug = 1;
-        break;
-
-      case 'm':
-        machine = optarg;
-        break;
-
-      case 'p':
-        port = optarg;
-        break;
-
-      case 'w':
-        passwd = optarg;
-        break;
-
-      case 'l':
-        device = optarg;
-        break;
-
-      default:
-        fprintf (stderr,
-          "Usage: %s [-d] [-m machine] [-p port] [-w passwd] [-l device]\n",
-                 MyName);
-        exit(1);
-      /* NOTREACHED */
-        break;
-      }
-
-  if (stat (device, &statbuf) < 0 || ! S_ISCHR (statbuf.st_mode)) {
-    fprintf (stderr, "%s: stat failed for path <%s>\n", MyName, device);
-    fprintf (stderr, "%s: or the path isn't a character special file.\n",
-             MyName);
-    perror (MyName);
-    exit (1);
-    }
-
-  install_signal_handlers ();
-
-  if (! debug)
-    daemonize ();
-
-  while (! shutdown_server) {
-    sleep (5);
-
-    fd = connect_to_service (machine, port);
-    if (fd < 0) {
-      error_msg_throttle = 1;
-      continue;
-      }
-
-    if (send_password (fd, passwd) < 0
-        || enable_mwi_event (fd) < 0) {
-      error_msg_throttle = 1;
-      close (fd);
-      continue;
-      }
-
-    error_msg_throttle = 0;
-
-    while (m = retrieve_message (fd)) {
-      process_mwi_event (m, device);
-      free (m);
-      }
-
-    close (fd);
-    }
-
-  exit (0);
-  }