Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package hylafax+ for openSUSE:Factory 
checked in at 2022-12-27 11:55:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hylafax+ (Old)
 and      /work/SRC/openSUSE:Factory/.hylafax+.new.1563 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hylafax+"

Tue Dec 27 11:55:04 2022 rev:43 rq:1045467 version:7.0.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/hylafax+/hylafax+.changes        2022-06-08 
14:24:48.932494525 +0200
+++ /work/SRC/openSUSE:Factory/.hylafax+.new.1563/hylafax+.changes      
2022-12-27 11:55:15.227378608 +0100
@@ -1,0 +2,15 @@
+Mon Dec 26 15:10:02 UTC 2022 - Axel Braun <[email protected]>
+
+- version 7.0.6
+  * add support for libtiff v4.4 (10 Jun 2022)
+  * libtiff44.diff removed
+  * cope with SSL Fax senders who skip Phase C (5 May 2022)
+  * add ability to trace SSL Fax data reception (3 May 2022)
+  * handle timeout OK response to +FRH=3 and +FRM=n (25 Apr 2022)
+  * don't leave the modem waiting for a response when in SSL Fax (25 Apr 2022)
+  * improve recovery from unexpected SSL Fax terminations during ECM (15, 18, 
26 Apr 2022)
+  * try to cope with false "no dialtone" results (4, 8 Apr 2022)
+  * add initial support for SSL Fax Proxy servers (4, 23 Feb; 4, 19 Apr; 10, 
24 Jun 2022)
+  * buildrequirement for libssl added (Thanks Dimstar)
+
+-------------------------------------------------------------------

Old:
----
  hylafax-7.0.5.tar.gz
  libtiff44.diff

New:
----
  hylafax-7.0.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ hylafax+.spec ++++++
--- /var/tmp/diff_new_pack.9D8tp4/_old  2022-12-27 11:55:15.983382813 +0100
+++ /var/tmp/diff_new_pack.9D8tp4/_new  2022-12-27 11:55:15.991382857 +0100
@@ -19,7 +19,7 @@
 %global faxspool    %{_localstatedir}/spool/hylafax
 %define lib_version %(echo %{version} | tr \. _)
 Name:           hylafax+
-Version:        7.0.5
+Version:        7.0.6
 Release:        0
 Summary:        A fax server
 License:        BSD-3-Clause
@@ -41,8 +41,6 @@
 Source15:       hylafax-service.xml
 Source16:       hylafax-helper.xml
 
-Patch0:         libtiff44.diff
-
 BuildRequires:  firewalld
 BuildRequires:  gcc-c++
 BuildRequires:  ghostscript
@@ -56,6 +54,7 @@
 # needed together with devel for proper configure detection
 BuildRequires:  tiff
 BuildRequires:  pkgconfig(lcms2)
+BuildRequires:  pkgconfig(libssl)
 BuildRequires:  pkgconfig(libtiff-4)
 BuildRequires:  pkgconfig(systemd)
 BuildRequires:  pkgconfig(zlib)
@@ -107,8 +106,6 @@
 %prep
 %setup -q -n hylafax-%{version}
 
-%autopatch -p1
-
 cp %{SOURCE8} .
 cp %{SOURCE9} .
 

++++++ hylafax-7.0.5.tar.gz -> hylafax-7.0.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/CHANGES new/hylafax-7.0.6/CHANGES
--- old/hylafax-7.0.5/CHANGES   2021-12-05 05:53:43.000000000 +0100
+++ new/hylafax-7.0.6/CHANGES   2022-06-24 21:36:27.000000000 +0200
@@ -2,6 +2,17 @@
 
 New Changes
 
+* add support for libtiff v4.4 (10 Jun 2022)
+* cope with SSL Fax senders who skip Phase C (5 May 2022)
+* add ability to trace SSL Fax data reception (3 May 2022)
+* handle timeout OK response to +FRH=3 and +FRM=n (25 Apr 2022)
+* don't leave the modem waiting for a response when in SSL Fax (25 Apr 2022)
+* improve recovery from unexpected SSL Fax terminations during ECM (15, 18, 26 
Apr 2022)
+* try to cope with false "no dialtone" results (4, 8 Apr 2022)
+* add initial support for SSL Fax Proxy servers (4, 23 Feb; 4, 19 Apr; 10, 24 
Jun 2022)
+
+(7.0.5)
+
 * extend Class1RecvAbortOK = 0 timeout to 500 ms (4 Dec 2021)
 * cope with Si2435 V.34/V.8 connection glitch (17, 19 Nov 2021)
 * cope with spurious +FCERROR or other delayed messages from modem (26 Oct 
2021)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/VERSION new/hylafax-7.0.6/VERSION
--- old/hylafax-7.0.5/VERSION   2021-09-08 04:03:25.000000000 +0200
+++ new/hylafax-7.0.6/VERSION   2022-02-23 23:56:08.000000000 +0100
@@ -1 +1 @@
-7.0.5
+7.0.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/configure new/hylafax-7.0.6/configure
--- old/hylafax-7.0.5/configure 2021-07-25 23:16:27.000000000 +0200
+++ new/hylafax-7.0.6/configure 2022-06-10 16:21:28.000000000 +0200
@@ -2583,7 +2583,7 @@
                                echo '#define TIFFSTRIPBYTECOUNTS uint32_t'
                                echo '#define TIFFVERSION TIFF_VERSION'
                                echo '#define TIFFHEADER TIFFHeader';;
-               4.[0123])       tiff_runlen_t="uint32_t"
+               4.[01234])      tiff_runlen_t="uint32_t"
                                tiff_offset_t="uint64_t"
                                echo '#define TIFFSTRIPBYTECOUNTS uint64_t'
                                echo '#define TIFFVERSION TIFF_VERSION_CLASSIC'
@@ -2625,7 +2625,7 @@
 Incompatible TIFF Library.
 
 HylaFAX ${VERSION} requires TIFF software distribution versions 3.4 through
-4.0.  If you do not have up to date TIFF software on your system
+4.4.  If you do not have up to date TIFF software on your system
 then you can retrieve it from the location where you obtained this software.
 The Home Page for version 3.5 and later is 
http://www.remotesensing.org/libtiff/
 EOF
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/etc/faxsetup.sh.in 
new/hylafax-7.0.6/etc/faxsetup.sh.in
--- old/hylafax-7.0.5/etc/faxsetup.sh.in        2021-10-12 21:39:04.000000000 
+0200
+++ new/hylafax-7.0.6/etc/faxsetup.sh.in        2022-06-09 01:48:18.000000000 
+0200
@@ -2128,7 +2128,7 @@
        echo
     fi
     if isOK "$ok"; then
-       $OPENSSL req -x509 -nodes -days 9999 -newkey rsa:1024 -keyout 
$DIR_SPOOL/etc/ssl.pem -out $DIR_SPOOL/etc/ssl.pem
+       $OPENSSL req -x509 -nodes -days 9999 -newkey rsa:2048 -keyout 
$DIR_SPOOL/etc/ssl.pem -out $DIR_SPOOL/etc/ssl.pem
        $CHOWN $faxUID $DIR_SPOOL/etc/ssl.pem; $CHGRP $faxGID 
$DIR_SPOOL/etc/ssl.pem
     else
        echo "Skipping creation of etc/ssl.pem for SSL Fax."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/Class1.c++ 
new/hylafax-7.0.6/faxd/Class1.c++
--- old/hylafax-7.0.5/faxd/Class1.c++   2021-12-05 05:52:46.000000000 +0100
+++ new/hylafax-7.0.6/faxd/Class1.c++   2022-05-05 18:37:22.000000000 +0200
@@ -311,8 +311,8 @@
        useSSLFax = false;
        isSSLFax = false;
        suppressSSLFax = false;
+       usingSSLFaxProxy = false;
        setSSLFaxFd(0);
-       if (sslWatchModem) abortReceive();
        sslWatchModem = false;
        wasSSLFax = true;
     }
@@ -382,6 +382,7 @@
     isSSLFax = false;
     wasSSLFax = false;
     suppressSSLFax = false;
+    usingSSLFaxProxy = false;
     remoteCSAinfo = "";
     sslFaxPasscode = randomString(10);
     remoteCSAType = 0x00;
@@ -410,6 +411,7 @@
     isSSLFax = false;
     wasSSLFax = false;
     suppressSSLFax = false;
+    usingSSLFaxProxy = false;
     sslRcvCC = sslRcvNext = sslRcvBit = sslGotByte = 0;
     sslSawBlockEnd = false;
     sslWatchModem = false;
@@ -538,7 +540,7 @@
  * T.30 5.3.6.2.12.
  */
 void
-Class1Modem::encodeCSA(fxStr& binary, const fxStr& ascii)
+Class1Modem::encodeCSA(fxStr& binary, const fxStr& ascii, bool haspasscode)
 {
     u_int n = ascii.length();
     if (n > 60) {
@@ -547,8 +549,10 @@
        return;
     }
     fxStr url = ascii;
-    url.insert('@');
-    url.insert(sslFaxPasscode);
+    if (!haspasscode) {
+       url.insert('@');
+       url.insert(sslFaxPasscode);
+    }
     url.insert("ssl://");
     n = url.length();
     u_int i, j = 0;
@@ -719,8 +723,8 @@
        protoTrace("SSL FAX WRITE ERROR: %s", (const char*) sslFaxProcess.emsg);
        useSSLFax = false;
        isSSLFax = false;
+       usingSSLFaxProxy = false;
        setSSLFaxFd(0);
-       if (sslWatchModem) abortReceive();
        sslWatchModem = false;
        wasSSLFax = true;
        params.br = storedBitrate;
@@ -750,6 +754,7 @@
     if (wasSSLFax) {
        // the abort already happened
        wasSSLFax = false;
+       setTimeout(false);
        return;
     }
     bool b = wasTimeout();
@@ -817,13 +822,16 @@
     SSLFax sfp;
     int r = sfp.read(sslFaxProcess, buf, 1, (sslWatchModem ? getModemFd() : 
0), (ms ? ms : 60000));
     if (r > 0) {
+       if (getSSLFaxTracing()) protoTrace("--> SSL Fax <%u:%.2X>", r, (buf[0] 
& 0xFF));
+       memmove(sslFaxPastData, sslFaxPastData+1, 10);
+       sslFaxPastData[10] = buf[0] & 0xFF;
        return (buf[0] & 0xFF);
     }
     protoTrace("SSL FAX READ ERROR: %s", (const char*) sslFaxProcess.emsg);
     useSSLFax = false;
     isSSLFax = false;
+    usingSSLFaxProxy = false;
     setSSLFaxFd(0);
-    if (r != -1 && sslWatchModem) abortReceive();
     sslWatchModem = false;
     wasSSLFax = true;
     params.br = storedBitrate;
@@ -866,8 +874,11 @@
     }
     // enable this to simulate a VERY noisy connection
     // if (((int) Sys::now() & 1) && ((random() % 10000)/10000.0) > 0.95) 
return (1);
-    if (sslGotByte == EOF) return (EOF);
-    else if (sslGotByte & (0x80 >> --sslRcvBit)) return (1);
+    if (sslGotByte == EOF) {
+       sslSawBlockEnd = true;
+       sawBlockEnd();
+       return (EOF);
+    } else if (sslGotByte & (0x80 >> --sslRcvBit)) return (1);
     else return (0);
 }
 
@@ -1760,7 +1771,7 @@
                }
            }
        } while (((u_int) Sys::now()-start < howmany(conf.t1Timer, 1000)) && 
!wasTimeout() &&
-           (lastResponse == AT_FCERROR || lastResponse == AT_NOCARRIER || 
(lastResponse == AT_ERROR && onhooks <= conf.class1HookSensitivity)));
+           (lastResponse == AT_FCERROR || lastResponse == AT_NOCARRIER || 
lastResponse == AT_OK || (lastResponse == AT_ERROR && onhooks <= 
conf.class1HookSensitivity)));
     }
     if (readPending) {
         stopTimeout("waiting for HDLC flags");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/Class1.h 
new/hylafax-7.0.6/faxd/Class1.h
--- old/hylafax-7.0.5/faxd/Class1.h     2021-07-25 23:16:27.000000000 +0200
+++ new/hylafax-7.0.6/faxd/Class1.h     2022-05-05 18:37:22.000000000 +0200
@@ -143,8 +143,10 @@
     bool       isSSLFax;       // whether or not SSL Fax handshaking succeeded
     bool       wasSSLFax;      // whether or not SSL Fax handshaking succeeded 
before
     bool       suppressSSLFax; // whether or not to suspend SSL Fax for this 
session
+    bool       usingSSLFaxProxy; // whether or not an SSL Fax proxy is used
     fxStr      remoteCSAinfo;  // remote CSA string (host:port)
     u_char     remoteCSAType;  // remote CSA type
+    u_char     sslFaxPastData[11]; // most recent 11 bytes of received SSL Fax 
data
 #if defined(HAVE_SSL)
     SSLFaxProcess sslFaxProcess;// contains data about SSL Fax process
 #endif
@@ -200,7 +202,7 @@
     virtual bool atCmd(const fxStr& cmd, ATResponse = AT_OK, long ms = 
30*1000);
     bool       switchingPause(fxStr& emsg, u_int times = 1);
     void       encodeTSI(fxStr& binary, const fxStr& ascii);
-    void       encodeCSA(fxStr& binary, const fxStr& ascii);
+    void       encodeCSA(fxStr& binary, const fxStr& ascii, bool haspasscode);
     void       encodeNSF(fxStr& binary, const fxStr& ascii);
     const fxStr& decodeTSI(fxStr& ascii, const HDLCFrame& binary);
     const fxStr& decodeCSA(fxStr& ascii, const HDLCFrame& binary);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/Class1Recv.c++ 
new/hylafax-7.0.6/faxd/Class1Recv.c++
--- old/hylafax-7.0.5/faxd/Class1Recv.c++       2021-10-20 01:11:46.000000000 
+0200
+++ new/hylafax-7.0.6/faxd/Class1Recv.c++       2022-06-10 17:43:32.000000000 
+0200
@@ -584,7 +584,7 @@
        if (sslFaxProcess.emsg != "") protoTrace("SSL Fax: \"%s\"", (const 
char*) sslFaxProcess.emsg);
        if (!sslFaxProcess.server) {
            protoTrace("SSL Fax connection failed.");
-           if (!conf.class1SSLFaxInfo.length()) useSSLFax = false;
+           if (!conf.class1SSLFaxInfo.length() && 
!conf.class1SSLFaxProxy.length()) useSSLFax = false;
        } else {
            protoTrace("SSL Fax connection was successful.");
            ok = true;
@@ -748,7 +748,7 @@
                    if (sslFaxProcess.emsg != "") protoTrace("SSL Fax: \"%s\"", 
(const char*) sslFaxProcess.emsg);
                    if (!sslFaxProcess.server) {
                        protoTrace("SSL Fax connection failed.");
-                       if (!conf.class1SSLFaxInfo.length()) useSSLFax = false;
+                       if (!conf.class1SSLFaxInfo.length() && 
!conf.class1SSLFaxProxy.length()) useSSLFax = false;
                    } else {
                        protoTrace("SSL Fax connection was successful.");
                        isSSLFax = true;
@@ -757,9 +757,38 @@
                    }
                }
 
-               if (!isSSLFax && useSSLFax && conf.class1SSLFaxInfo.length()) {
+               if (!isSSLFax && useSSLFax && (conf.class1SSLFaxInfo.length() 
|| conf.class1SSLFaxProxy.length())) {
                    SSLFax sslfax;
-                   sslFaxProcess = sslfax.startServer(conf.class1SSLFaxInfo, 
conf.class1SSLFaxCert);
+                   fxStr info = conf.class1SSLFaxInfo;
+                   bool haspasscode = false;
+                   if (conf.class1SSLFaxInfo.length()) {
+                       sslFaxProcess = 
sslfax.startServer(conf.class1SSLFaxInfo, conf.class1SSLFaxCert);
+                   } else {
+                       u_int atpos = conf.class1SSLFaxProxy.next(0, '@');
+                       fxStr passcode;
+                       if (atpos < conf.class1SSLFaxProxy.length()) {
+                           passcode = conf.class1SSLFaxProxy.extract(0, atpos);
+                       } else {
+                           passcode = "";
+                           atpos = -1;
+                       }
+                       fxStr hostport = 
conf.class1SSLFaxProxy.extract(atpos+1, 
conf.class1SSLFaxProxy.length()-atpos-1);
+                       protoTrace("Connecting to SSL Fax Proxy %s", (const 
char*) conf.class1SSLFaxProxy);
+
+                       sslFaxProcess = sslfax.startClient(hostport, passcode, 
rtcRev, conf.class1SSLFaxServerTimeout);
+                       if (sslFaxProcess.server) {
+                           info = "";
+                           haspasscode = true;
+                           char buf[2];
+                           int r;
+                           do {
+                               r = sslfax.read(sslFaxProcess, buf, 1, 0, 1000);
+                               if (r > 0 && buf[0] != 0) info.append( 
buf[0]&0xFF );
+                           } while (r > 0 && (buf[0]&0xFF) != 0);
+                           protoTrace("Proxy SSL Fax info: \"%s\"", (const 
char*) info);
+                           usingSSLFaxProxy = true;
+                       }
+                   }
                    if (sslFaxProcess.emsg.length()) protoTrace("SSL Fax: 
\"%s\"", (const char*) sslFaxProcess.emsg);
                    if (sslFaxProcess.server == 0 ) {
                        setSSLFaxFd(0);
@@ -767,7 +796,7 @@
                    }
                    if (useSSLFax) {
                        fxStr csa;
-                       encodeCSA(csa, conf.class1SSLFaxInfo);
+                       encodeCSA(csa, info, haspasscode);
                        protoTrace("Send CSA frame to accept HylaFAX SSL fax 
feature.");
                        startTimeout(7550);
                        transmitFrame(FCF_CSA|FCF_RCVR, csa, false);
@@ -846,7 +875,7 @@
                        do {
                            (void) atCmd(rmCmd, AT_NOTHING);
                            rmResponse = atResponse(rbuf, 
conf.class1RMPersistence ? conf.t2Timer + 2900 : conf.t2Timer - 2900);
-                       } while ((rmResponse == AT_NOTHING || rmResponse == 
AT_FCERROR) && ++attempts < conf.class1RMPersistence && !getSSLFaxConnection());
+                       } while ((rmResponse == AT_NOTHING || rmResponse == 
AT_FCERROR || rmResponse == AT_OK) && ++attempts < conf.class1RMPersistence && 
!getSSLFaxConnection());
 #if defined(HAVE_SSL)
                        if (useSSLFax) {
                            SSLFax sslfax;
@@ -857,19 +886,23 @@
                                sslWatchModem = false;
                                setSSLFaxFd(0);
                            } else {
-                               protoTrace("SSL Fax connection detected.");
-                               sslfax.acceptClient(sslFaxProcess, 
sslFaxPasscode, getModemFd(), conf.class1SSLFaxClientTimeout);
-                               if (sslFaxProcess.emsg != "") protoTrace("SSL 
Fax accept client: %s", (const char*) sslFaxProcess.emsg);
+                               if (!usingSSLFaxProxy) {
+                                   protoTrace("SSL Fax connection detected.");
+                                   sslfax.acceptClient(sslFaxProcess, 
sslFaxPasscode, getModemFd(), conf.class1SSLFaxClientTimeout);
+                                   if (sslFaxProcess.emsg != "") 
protoTrace("SSL Fax accept client: %s", (const char*) sslFaxProcess.emsg);
+                               }
+                               sslWatchModem = false;
+                               setSSLFaxFd(0);
                                if (!sslFaxProcess.server) {
                                    protoTrace("SSL Fax client accept failure.  
Expecting a traditional fax now.");
                                    sslfax.cleanup(sslFaxProcess);
                                    useSSLFax = false;
-                                   sslWatchModem = false;
-                                   setSSLFaxFd(0);
                                    do {
                                        rmResponse = atResponse(rbuf, 
conf.class1RMPersistence ? conf.t2Timer + 2900 : conf.t2Timer - 2900);
                                    } while ((rmResponse == AT_NOTHING || 
rmResponse == AT_FCERROR) && ++attempts < conf.class1RMPersistence && 
atCmd(rmCmd, AT_NOTHING));
                                } else {
+                                   abortReceive();
+                                   setSSLFaxFd(sslFaxProcess.server);
                                    isSSLFax = true;
                                    storedBitrate = params.br;
                                    params.br = BR_SSLFAX;
@@ -1470,7 +1503,7 @@
     do {
        (void) atCmd(rmCmd, AT_NOTHING);
        lastResponse = atResponse(rbuf, conf.class1RMPersistence ? conf.t2Timer 
+ 2900 : conf.t2Timer - 2900);
-    } while ((lastResponse == AT_NOTHING || lastResponse == AT_FCERROR) && 
++attempts < conf.class1RMPersistence && !getSSLFaxConnection());
+    } while ((lastResponse == AT_NOTHING || lastResponse == AT_FCERROR || 
lastResponse == AT_OK) && ++attempts < conf.class1RMPersistence && 
!getSSLFaxConnection());
 #if defined(HAVE_SSL)
     if (useSSLFax) {
        SSLFax sslfax;
@@ -1481,19 +1514,23 @@
            sslWatchModem = false;
            setSSLFaxFd(0);
        } else {
-           protoTrace("SSL Fax connection detected.");
-           sslfax.acceptClient(sslFaxProcess, sslFaxPasscode, getModemFd(), 
conf.class1SSLFaxClientTimeout);
-           if (sslFaxProcess.emsg != "") protoTrace("SSL Fax accept client: 
%s", (const char*) sslFaxProcess.emsg);
+           if (!usingSSLFaxProxy) {
+               protoTrace("SSL Fax connection detected.");
+               sslfax.acceptClient(sslFaxProcess, sslFaxPasscode, 
getModemFd(), conf.class1SSLFaxClientTimeout);
+               if (sslFaxProcess.emsg != "") protoTrace("SSL Fax accept 
client: %s", (const char*) sslFaxProcess.emsg);
+           }
+           sslWatchModem = false;
+           setSSLFaxFd(0);
            if (!sslFaxProcess.server) {
                protoTrace("SSL Fax client accept failure.  Expecting a 
traditional fax now.");
                sslfax.cleanup(sslFaxProcess);
                useSSLFax = false;
-               sslWatchModem = false;
-               setSSLFaxFd(0);
                do {
                    lastResponse = atResponse(rbuf, conf.class1RMPersistence ? 
conf.t2Timer + 2900 : conf.t2Timer - 2900);
                } while ((lastResponse == AT_NOTHING || lastResponse == 
AT_FCERROR) && ++attempts < conf.class1RMPersistence && atCmd(rmCmd, 
AT_NOTHING));
            } else {
+               abortReceive();
+               setSSLFaxFd(sslFaxProcess.server);
                isSSLFax = true;
                storedBitrate = params.br;
                params.br = BR_SSLFAX;
@@ -1633,17 +1670,20 @@
                                    sslWatchModem = false;
                                    setSSLFaxFd(0);
                                } else {
-                                   protoTrace("SSL Fax connection detected.");
-                                   sslfax.acceptClient(sslFaxProcess, 
sslFaxPasscode, getModemFd(), conf.class1SSLFaxClientTimeout);
-                                   if (sslFaxProcess.emsg != "") 
protoTrace("SSL Fax accept client: %s", (const char*) sslFaxProcess.emsg);
+                                   if (!usingSSLFaxProxy) {
+                                       protoTrace("SSL Fax connection 
detected.");
+                                       sslfax.acceptClient(sslFaxProcess, 
sslFaxPasscode, getModemFd(), conf.class1SSLFaxClientTimeout);
+                                       if (sslFaxProcess.emsg != "") 
protoTrace("SSL Fax accept client: %s", (const char*) sslFaxProcess.emsg);
+                                   }
+                                   sslWatchModem = false;
+                                   setSSLFaxFd(0);
                                    if (!sslFaxProcess.server) {
                                        protoTrace("SSL Fax client accept 
failure.  Expecting a traditional fax now.");
                                        sslfax.cleanup(sslFaxProcess);
                                        useSSLFax = false;
-                                       sslWatchModem = false;
-                                       setSSLFaxFd(0);
                                        gotprimary = waitForDCEChannel(false);  
// resume V.34-Fax session
                                    } else {
+                                       setSSLFaxFd(sslFaxProcess.server);
                                        isSSLFax = true;
                                        storedBitrate = params.br;
                                        params.br = BR_SSLFAX;
@@ -1933,7 +1973,7 @@
                        }
                    } else {
                        dataseen = true;        // assume that garbage was 
meant to be data
-                       if (wasTimeout()) break;
+                       if (wasTimeout() || sslSawBlockEnd) break;
                        if (isSSLFax || !useV34) syncECMFrame();
                        if ((!isSSLFax && useV34) && (gotEOT || gotCTRL)) 
rcpcnt = 3;
                    }
@@ -1966,7 +2006,7 @@
                        }
                    }
                }
-               if (!isSSLFax && !useV34) {
+               if (!isSSLFax && !useV34 && !sslSawBlockEnd) {
                    // wait for message carrier to drop
                    time_t nocarrierstart = Sys::now();
                    bool gotnocarrier = false;
@@ -1976,6 +2016,8 @@
                    } while (!gotnocarrier && lastResponse != AT_EMPTYLINE && 
Sys::now() < (nocarrierstart + 5));
                }
                bool gotpps = false;
+               sslSawBlockEnd = false;
+               wasSSLFax = false;
                HDLCFrame ppsframe(conf.class1FrameOverhead);
                u_short recvFrameCount = 0;
                do {
@@ -1998,9 +2040,17 @@
                     * believe that we've hung up.  This latter option seems the
                     * least likely to be problematic, so that's what we're 
doing.
                     */
-                   u_int br = useV34 ? primaryV34Rate : curcap->br + 1;
-                   long wait = br >= 1 && br <= 15 ? 273066 / br : 
conf.t2Timer;
-                   gotpps = recvFrame(ppsframe, FCF_RCVR, wait, false, false); 
// wait longer, no CRP
+                   if (isSSLFax && fcount == 0 && rcpcnt == 1 && 
sslFaxPastData[0] == 0xFF && sslFaxPastData[1] == 0x13 && sslFaxPastData[2] == 
0xBF) {
+                       // For some reason the sender has skipped over Phase C 
data and sent PPS.  Cope as best we can.
+                       protoTrace("The sender seems to have skipped Phase C.");
+                       for (u_int i = 0; i < 9; i++) 
ppsframe.put(frameRev[sslFaxPastData[i] & 0xFF]);
+                       traceHDLCFrame("-->", ppsframe);
+                       gotpps = true;
+                   } else {
+                       u_int br = useV34 ? primaryV34Rate : curcap->br + 1;
+                       long wait = br >= 1 && br <= 15 ? 273066 / br : 
conf.t2Timer;
+                       gotpps = recvFrame(ppsframe, FCF_RCVR, wait, false, 
false);     // wait longer, no CRP
+                   }
                } while (!gotpps && gotCONNECT && !wasTimeout() && !gotEOT && 
++recvFrameCount < 5);
                if (gotpps) {
                    traceFCF("RECV recv", ppsframe.getFCF());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/Class1Send.c++ 
new/hylafax-7.0.6/faxd/Class1Send.c++
--- old/hylafax-7.0.5/faxd/Class1Send.c++       2021-11-19 15:29:34.000000000 
+0100
+++ new/hylafax-7.0.6/faxd/Class1Send.c++       2022-04-26 01:33:13.000000000 
+0200
@@ -928,12 +928,42 @@
     if (!frameSent)
        return (false);
 #if defined(HAVE_SSL)
-    if (!suppressSSLFax && !isSSLFax && conf.class1SSLFaxSupport && 
conf.class1SSLFaxInfo.length() && \
+    if (!suppressSSLFax && !isSSLFax && conf.class1SSLFaxSupport && \
+       (conf.class1SSLFaxInfo.length() || conf.class1SSLFaxProxy.length()) && \
        (dis_caps.features & FaxParams::FEATURE_SSLFAX || 
(dis_caps.isBitEnabled(FaxParams::BITNUM_T37) && 
dis_caps.isBitEnabled(FaxParams::BITNUM_T38)))) {
        // We can't trust T.38 support indications to indicate that the remote 
device actually supports TSA frames.
        useSSLFax = true;
        SSLFax sslfax;
-       sslFaxProcess = sslfax.startServer(conf.class1SSLFaxInfo, 
conf.class1SSLFaxCert);
+       fxStr info = conf.class1SSLFaxInfo;
+       bool haspasscode = false;
+       if (conf.class1SSLFaxInfo.length()) {
+           sslFaxProcess = sslfax.startServer(conf.class1SSLFaxInfo, 
conf.class1SSLFaxCert);
+       } else {
+           int atpos = conf.class1SSLFaxProxy.next(0, '@');
+           fxStr passcode;
+           if (atpos < conf.class1SSLFaxProxy.length()) {
+               passcode = conf.class1SSLFaxProxy.extract(0, atpos);
+           } else {
+               passcode = "";
+               atpos = -1;
+           }
+           fxStr hostport = conf.class1SSLFaxProxy.extract(atpos+1, 
conf.class1SSLFaxProxy.length()-atpos-1);
+           protoTrace("Connecting to SSL Fax Proxy %s", (const char*) 
conf.class1SSLFaxProxy);
+
+           sslFaxProcess = sslfax.startClient(hostport, passcode, rtcRev, 
conf.class1SSLFaxServerTimeout);
+           if (sslFaxProcess.server) {
+               info = "";
+               haspasscode = true;
+               char buf[2];
+               int r;
+               do {
+                   r = sslfax.read(sslFaxProcess, buf, 1, 0, 1000);
+                   if (r > 0 && buf[0] != 0) info.append( buf[0]&0xFF );
+               } while (r > 0 && (buf[0]&0xFF) != 0);
+               protoTrace("Proxy SSL Fax info: \"%s\"", (const char*) info);
+               usingSSLFaxProxy = true;
+           }
+       }
        if (sslFaxProcess.emsg.length()) protoTrace("SSL Fax: \"%s\"", (const 
char*) sslFaxProcess.emsg);
        if (sslFaxProcess.server == 0 ) {
            setSSLFaxFd(0);
@@ -941,7 +971,7 @@
        }
        if (useSSLFax) {
            fxStr tsa;
-           encodeCSA(tsa, conf.class1SSLFaxInfo);
+           encodeCSA(tsa, info, haspasscode);
            protoTrace("Sending TSA frame to initiate HylaFAX SSL fax 
feature.");
            startTimeout(7550);
            frameSent = sendFrame(FCF_TSA|FCF_SNDR, tsa, false);
@@ -1174,18 +1204,21 @@
                    sslWatchModem = false;
                    setSSLFaxFd(0);
                } else {
-                   protoTrace("SSL Fax connection detected.");
-                   sslfax.acceptClient(sslFaxProcess, sslFaxPasscode, 
getModemFd(), conf.class1SSLFaxClientTimeout);
-                   if (sslFaxProcess.emsg != "") protoTrace("SSL Fax accept 
client: %s", (const char*) sslFaxProcess.emsg);
+                   if (!usingSSLFaxProxy) {
+                       protoTrace("SSL Fax connection detected.");
+                       sslfax.acceptClient(sslFaxProcess, sslFaxPasscode, 
getModemFd(), conf.class1SSLFaxClientTimeout);
+                       if (sslFaxProcess.emsg != "") protoTrace("SSL Fax 
accept client: %s", (const char*) sslFaxProcess.emsg);
+                   }
+                   sslWatchModem = false;
+                   setSSLFaxFd(0);
                    if (!sslFaxProcess.server) {
                        protoTrace("SSL Fax client accept failure.  Proceeding 
with a traditional fax now.");
                        sslfax.cleanup(sslFaxProcess);
                        useSSLFax = false;
-                       sslWatchModem = false;
-                       setSSLFaxFd(0);
                    } else {
+                       abortReceive();
+                       setSSLFaxFd(sslFaxProcess.server);
                        isSSLFax = true;
-                       sslWatchModem = true;
                        storedBitrate = params.br;
                        params.br = BR_SSLFAX;
                    }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/ClassModem.c++ 
new/hylafax-7.0.6/faxd/ClassModem.c++
--- old/hylafax-7.0.5/faxd/ClassModem.c++       2021-10-26 21:40:18.000000000 
+0200
+++ new/hylafax-7.0.6/faxd/ClassModem.c++       2022-04-08 20:37:50.000000000 
+0200
@@ -161,7 +161,19 @@
        }
     }
     emsg = "";
-    CallStatus cs = (atCmd(dialcmd, AT_NOTHING) ? dialResponse(emsg) : 
FAILURE);
+    int nodialtones = 0;
+    bool repeat;
+    CallStatus cs;
+    do {
+       repeat = false;
+       cs = (atCmd(dialcmd, AT_NOTHING) ? dialResponse(emsg) : FAILURE);
+       if (cs == NODIALTONE && nodialtones++ < conf.noDialtoneRetries) {
+           repeat = true;
+           sleep(1);
+           atCmd(conf.onHookCmd, AT_OK, 5000);
+           sleep(3);
+       }
+    } while (repeat);
     if (cs != OK && emsg == "") {
         emsg = callStatus[cs];
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/FaxModem.c++ 
new/hylafax-7.0.6/faxd/FaxModem.c++
--- old/hylafax-7.0.5/faxd/FaxModem.c++ 2021-07-25 23:16:27.000000000 +0200
+++ new/hylafax-7.0.6/faxd/FaxModem.c++ 2022-05-04 05:38:19.000000000 +0200
@@ -771,6 +771,8 @@
     { return (server.getSessionTracing() & FAXTRACE_HDLC) != 0; }
 bool FaxModem::getECMTracing()
     { return (server.getSessionTracing() & FAXTRACE_ECM) != 0; }
+bool FaxModem::getSSLFaxTracing()
+    { return (server.getSessionTracing() & FAXTRACE_SSLFAX) != 0; }
 void FaxModem::setSSLFaxFd(int fd)
     { server.setSSLFaxFd(fd); }
 int FaxModem::getSSLFaxFd()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/FaxModem.h 
new/hylafax-7.0.6/faxd/FaxModem.h
--- old/hylafax-7.0.5/faxd/FaxModem.h   2021-07-25 23:16:27.000000000 +0200
+++ new/hylafax-7.0.6/faxd/FaxModem.h   2022-05-04 05:38:19.000000000 +0200
@@ -148,6 +148,7 @@
 // server-related stuff
     bool       getHDLCTracing();
     bool       getECMTracing();
+    bool       getSSLFaxTracing();
     void       setSSLFaxFd(int fd);
     int                getModemFd();
     int                getSSLFaxFd();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/FaxTrace.h 
new/hylafax-7.0.6/faxd/FaxTrace.h
--- old/hylafax-7.0.5/faxd/FaxTrace.h   2015-07-27 02:46:05.000000000 +0200
+++ new/hylafax-7.0.6/faxd/FaxTrace.h   2022-05-04 05:38:19.000000000 +0200
@@ -48,6 +48,7 @@
 const int FAXTRACE_DOCREFS     = 0x20000;      // document reference handling
 const int FAXTRACE_TIFF                = 0x40000;      // TIFF library msgs
 const int FAXTRACE_ECM         = 0x80000;      // ECM HDLC image data frames
+const int FAXTRACE_SSLFAX      = 0x100000;     // SSL Fax data
 const int FAXTRACE_ANY         = 0xffffffff;
 
 const int FAXTRACE_MASK                = 0xfffff;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/Makefile.in 
new/hylafax-7.0.6/faxd/Makefile.in
--- old/hylafax-7.0.5/faxd/Makefile.in  2018-11-09 22:12:30.000000000 +0100
+++ new/hylafax-7.0.6/faxd/Makefile.in  2022-02-04 23:47:09.000000000 +0100
@@ -98,6 +98,8 @@
        faxGettyApp.c++ \
        faxQueueApp.c++ \
        faxSendApp.c++ \
+       sslfaxproxy.c++ \
+       sslfaxproxytest.c++ \
        tagtest.c++ \
        tsitest.c++ \
        pageSendApp.c++
@@ -159,7 +161,7 @@
 FAXGETTYOBJS= Getty.o Getty@[email protected] faxGettyApp.o
 TARGETS=libfaxserver.${DSO} \
        faxq faxsend faxgetty pagesend faxqclean \
-       tsitest tagtest cqtest choptest
+       sslfaxproxy sslfaxproxytest tsitest tagtest cqtest choptest
 
 default all::
        @${MAKE} incdepend
@@ -199,6 +201,10 @@
 pagesend:${PAGESENDOBJS} libfaxserver.${DSO} ${LIBS}
        ${C++F} -o $@ ${PAGESENDOBJS} ${LIBFAXSERVER} ${LDFLAGS}
 
+sslfaxproxy: sslfaxproxy.o libfaxserver.${DSO} ${LIBS}
+       ${C++F} -o $@ sslfaxproxy.o ${LIBFAXSERVER} ${LDFLAGS}
+sslfaxproxytest: sslfaxproxytest.o libfaxserver.${DSO} ${LIBS}
+       ${C++F} -o $@ sslfaxproxytest.o ${LIBFAXSERVER} ${LDFLAGS}
 tagtest: tagtest.o libfaxserver.${DSO} ${LIBS}
        ${C++F} -o $@ tagtest.o ${LIBFAXSERVER} ${LDFLAGS}
 cqtest:        cqtest.o libfaxserver.${DSO} ${LIBS}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/ModemConfig.c++ 
new/hylafax-7.0.6/faxd/ModemConfig.c++
--- old/hylafax-7.0.5/faxd/ModemConfig.c++      2021-08-16 19:18:24.000000000 
+0200
+++ new/hylafax-7.0.6/faxd/ModemConfig.c++      2022-04-08 20:37:50.000000000 
+0200
@@ -172,6 +172,7 @@
 { "tiff2faxcmd",               &ModemConfig::tiff2faxCmd,      FAX_TIFF2FAXCMD 
},
 { "class1sslfaxinfo",          &ModemConfig::class1SSLFaxInfo, "" },
 { "class1sslfaxcert",          &ModemConfig::class1SSLFaxCert,         
"etc/ssl.pem" },
+{ "class1sslfaxproxy",         &ModemConfig::class1SSLFaxProxy,        "" },
 { "class2recvdatatrigger",     &ModemConfig::class2RecvDataTrigger },
 { "ringdata",                  &ModemConfig::ringData },
 { "ringfax",                   &ModemConfig::ringFax },
@@ -212,6 +213,7 @@
 { "modemringsbeforeresponse",  &ModemConfig::ringsBeforeResponse,   0 },
 { "modemsoftresetcmddelay",    &ModemConfig::softResetCmdDelay,     3000 },
 { "modemnoautoanswercmddelay", &ModemConfig::noAutoAnswerCmdDelay,  0 },
+{ "modemnodialtoneretries",    &ModemConfig::noDialtoneRetries,     1 },
 { "class1tcfrecvtimeout",      &ModemConfig::class1TCFRecvTimeout,  4500 },
 { "class1recvabortok",         &ModemConfig::class1RecvAbortOK,     200 },
 { "class1rmpersistence",       &ModemConfig::class1RMPersistence,   2 },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/ModemConfig.h 
new/hylafax-7.0.6/faxd/ModemConfig.h
--- old/hylafax-7.0.5/faxd/ModemConfig.h        2021-08-16 19:18:24.000000000 
+0200
+++ new/hylafax-7.0.6/faxd/ModemConfig.h        2022-04-08 20:37:50.000000000 
+0200
@@ -167,6 +167,7 @@
     bool       class1SSLFaxSupport;    // to enable/disable SSL Fax
     fxStr      class1SSLFaxInfo;       // host:port information for "SSL Fax" 
server feature
     fxStr      class1SSLFaxCert;       // SSL encryption certificate for "SSL 
Fax" feature
+    fxStr      class1SSLFaxProxy;      // password@host:port information for 
"SSL Fax" proxy
     fxStr      class1TCFRecvHackCmd;   // cmd to avoid +FCERROR before TCF
     u_int      class1TCFRecvTimeout;   // timeout receiving TCF
     u_int      class1RecvAbortOK;      // if non-zero, OK sent after recv abort
@@ -255,6 +256,7 @@
     u_int      maxConsecutiveBadLines; // max consecutive bad lines in page
     u_int      minAcceptedLineCount;   // min accepted number of lines in page
     u_int      minSpeed;               // minimum speed for fax transmits
+    u_int      noDialtoneRetries;      // maximum number of attempts to get 
dialtone
     bool       softRTFCC;              // real-time fax compression conversion 
(software)
     bool       waitForConnect;         // modem sends multiple answer responses
     fxStr      tagLineFmt;             // format string for tag lines
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/sslfax.c++ 
new/hylafax-7.0.6/faxd/sslfax.c++
--- old/hylafax-7.0.5/faxd/sslfax.c++   2020-01-31 19:41:10.000000000 +0100
+++ new/hylafax-7.0.6/faxd/sslfax.c++   2022-02-04 23:47:09.000000000 +0100
@@ -32,6 +32,7 @@
 #include <sys/time.h>
 #include "sslfax.h"
 #include "Sys.h"
+#include "Socket.h"
 
 timeval currentTime() {
     timeval curTime;
@@ -89,6 +90,7 @@
     addr.sin_family = AF_INET;
     addr.sin_port = htons (port);
     addr.sin_addr.s_addr = INADDR_ANY;
+
     if (bind (sd, (struct sockaddr*)&addr, sizeof (addr)) != 0) {
        emsg = fxStr::format("Can't bind port %d: %s", port, strerror(errno));
        return 0;
@@ -257,7 +259,7 @@
     return (SSL_pending(sfp.ssl));
 }
 
-int SSLFax::read(SSLFaxProcess& sfp, void *buf, size_t count, int modemFd, 
long ms)
+int SSLFax::read(SSLFaxProcess& sfp, void *buf, size_t count, int modemFd, 
long ms, bool sustain, bool carryon)
 {
     /*
      * We cannot just use select() on the socket to see if there is data 
waiting
@@ -326,17 +328,19 @@
                }
                if (!selret) {
                    sfp.emsg = fxStr::format("Timeout waiting for SSL Fax read 
(wanting to %s).", (cerror == SSL_ERROR_WANT_READ ? "read" : "write"));
-                   cleanup(sfp);
+                   cleanup(sfp, sustain);
                    return (0);
                } else if (selret < 0) {
                    sfp.emsg = fxStr::format("Error waiting for SSL Fax read 
(wanting to %s): %s", (cerror == SSL_ERROR_WANT_READ ? "read" : "write"), 
strerror(errno));
-                   cleanup(sfp);
+                   cleanup(sfp, sustain);
                    return (0);
                }
                if (modemFd && FD_ISSET(modemFd, &rfds)) {
                    // The modem got a signal.  This probably means that SSL 
Fax is not happening.
-                   sfp.emsg = "Modem has data when waiting for SSL Fax read.  
Terminating SSL Fax.";
-                   cleanup(sfp);
+                   if (!carryon) {
+                       sfp.emsg = "Modem has data when waiting for SSL Fax 
read.  Terminating SSL Fax.";
+                       cleanup(sfp, sustain);
+                   }
                    return (-1);
                }
            }
@@ -348,13 +352,13 @@
        } else {
            sfp.emsg = fxStr::format("Unable to read from SSL Fax connection.  
Error %d: %s", cerror, ssl_err_string());
        }
-       cleanup(sfp);
+       cleanup(sfp, sustain);
        return (-2);
     }
     return (ret);
 }
 
-int SSLFax::write(SSLFaxProcess& sfp, const u_char *buf, u_int count, const 
u_char* bitrev, int modemFd, long ms, bool filter)
+int SSLFax::write(SSLFaxProcess& sfp, const u_char *buf, u_int count, const 
u_char* bitrev, int modemFd, long ms, bool filter, bool sustain)
 {
     /*
      * Similar approach here as with read() above; however...
@@ -406,17 +410,17 @@
                    }
                    if (!selret) {
                        sfp.emsg = fxStr::format("Timeout waiting for SSL Fax 
write (wanting to %s).", (cerror == SSL_ERROR_WANT_READ ? "read" : "write"));
-                       cleanup(sfp);
+                       cleanup(sfp, sustain);
                        return (0);
                    } else if (selret < 0) {
                        sfp.emsg = fxStr::format("Error waiting for SSL Fax 
write (wanting to %s): %s", (cerror == SSL_ERROR_WANT_READ ? "read" : "write"), 
strerror(errno));
-                       cleanup(sfp);
+                       cleanup(sfp, sustain);
                        return (0);
                    }
                    if (modemFd && FD_ISSET(modemFd, &rfds)) {
                        // The modem got a signal.  This probably means that 
SSL Fax is not happening.
                        sfp.emsg = "Modem has data when waiting for SSL Fax 
write.  Terminating SSL Fax.";
-                       cleanup(sfp);
+                       cleanup(sfp, sustain);
                        return (-1);
                    }
                }
@@ -428,7 +432,7 @@
            } else {
                sfp.emsg = fxStr::format("Unable to write to SSL Fax 
connection.  Error %d: %s", cerror, ssl_err_string());
            }
-           cleanup(sfp);
+           cleanup(sfp, sustain);
            return (-2);
        }
        if (filter && buf[pos] == bitrev[16] && !isDLE) {
@@ -439,7 +443,7 @@
            isDLE = false;
        }
     }
-    return (ret);
+    return (count);
 }
 
 SSLFaxProcess SSLFax::null()
@@ -571,6 +575,9 @@
        sfp.emsg = fxStr::format("Could not determine port number from \"%s\", 
got \"%s\".", (const char*) info, (const char*) port);
        return (sfp);
     }
+    // portnum = 1 is a special case for dynamic port allocation by the server
+    if (portnum == 1) portnum = 0;
+
     SSL_library_init();                /* Initialize the SSL library */
     sfp.ctx = InitServerCTX(); /* initialize SSL */
     if (sfp.ctx == NULL) {
@@ -599,7 +606,7 @@
     return (sfp);
 }
 
-void SSLFax::acceptClient(SSLFaxProcess& sfp, fxStr passcode, int modemFd, 
long ms)
+bool SSLFax::acceptClient1(SSLFaxProcess& sfp, long ms, bool sustain)
 {
     /* Now we wait for the client to connect. */
     /* We can use select() here without SSL telling us to because SSL hasn't 
started yet. */
@@ -610,13 +617,13 @@
     tv.tv_sec = (int) ms / 1000;
     tv.tv_usec = (ms % 1000)*1000;
 #if CONFIG_BADSELECTPROTO
-    if (!select(sfp.server+1, (int*) &sfd, NULL, NULL, &tv)) {
+    if (!select(sfp.server+1, (int*) &sfd, NULL, NULL, ms == 0 ? NULL : &tv)) {
 #else
-    if (!select(sfp.server+1, &sfd, NULL, NULL, &tv)) {
+    if (!select(sfp.server+1, &sfd, NULL, NULL, ms == 0 ? NULL : &tv)) {
 #endif
        sfp.emsg = "Timeout waiting for SSL Fax client connection.";
-       cleanup(sfp);
-       return;
+       cleanup(sfp, sustain);
+       return (false);
     }
     /* A client is waiting... */
     struct sockaddr_in addr;
@@ -624,8 +631,8 @@
     sfp.client = accept(sfp.server, (struct sockaddr*) &addr, &len);  /* 
accept connection as usual */
     if (fcntl(sfp.client, F_SETFL, fcntl(sfp.client, F_GETFL, 0) | O_NONBLOCK) 
== -1) {
        sfp.emsg.append("Unable to set client SSL Fax socket to non-blocking.");
-       cleanup(sfp);
-       return;
+       cleanup(sfp, sustain);
+       return (false);
     }
     char address[50];
     if (inet_ntop(addr.sin_family, &addr.sin_addr, address, 50)) {
@@ -637,6 +644,11 @@
     } else {
            sfp.emsg = fxStr::format("SSL Fax connection: <unknown address>:%d 
", ntohs(addr.sin_port));
     }
+    return (true);
+}
+
+void SSLFax::acceptClient2(SSLFaxProcess& sfp, fxStr passcode, int modemFd, 
long ms, bool sustain)
+{
     sfp.ssl = SSL_new(sfp.ctx);                /* get new SSL state with 
context */
     SSL_set_fd(sfp.ssl, sfp.client);   /* set connection socket to SSL state */
 
@@ -676,17 +688,17 @@
                }
                if (!selret) {
                    sfp.emsg = fxStr::format("Timeout in waiting for SSL Fax 
accept (wanting to %s).", (cerror == SSL_ERROR_WANT_READ ? "read" : "write"));
-                   cleanup(sfp);
+                   cleanup(sfp, sustain);
                    return;
                } else if (selret < 0) {
                    sfp.emsg = fxStr::format("Error in waiting for SSL Fax 
accept (wanting to %s): %s", (cerror == SSL_ERROR_WANT_READ ? "read" : 
"write"), strerror(errno));
-                   cleanup(sfp);
+                   cleanup(sfp, sustain);
                    return;
                }
                if (modemFd && FD_ISSET(modemFd, &rfds)) {
                    // The modem got a signal.  This probably means that SSL 
Fax is not happening.
                    sfp.emsg = "Modem has data when waiting for SSL Fax accept. 
 Terminating SSL Fax.";
-                   cleanup(sfp);
+                   cleanup(sfp, sustain);
                    return;
                }
            }
@@ -698,7 +710,7 @@
        } else {
            sfp.emsg = fxStr::format("Unable to accept SSL Fax connection.  
Error %d: %s", cerror, ssl_err_string());
        }
-       cleanup(sfp);
+       cleanup(sfp, sustain);
        return;
     }
 
@@ -707,12 +719,12 @@
     for (u_int i = 0; i < passcode.length(); i++) {
        if (read(sfp, p, 1, modemFd, 1000) <= 0) {
            sfp.emsg.append(" (passcode)");
-           cleanup(sfp);
+           cleanup(sfp, sustain);
            return;
        }
        if (p[0] != passcode[i]) {
            sfp.emsg.append("Invalid Passcode");
-           cleanup(sfp);
+           cleanup(sfp, sustain);
            return;
        }
     }
@@ -720,23 +732,33 @@
     return;
 }
 
-void SSLFax::cleanup(SSLFaxProcess& sfp)
+void SSLFax::acceptClient(SSLFaxProcess& sfp, fxStr passcode, int modemFd, 
long ms)
+{
+    if (!acceptClient1(sfp, ms)) return;
+    acceptClient2(sfp, passcode, modemFd, (ms == 0) ? 1000 : ms); // Set a 
reasonable timeout after our indefinite wait for a client connection.
+    return;
+}
+
+void SSLFax::cleanup(SSLFaxProcess& sfp, bool sustain)
 {
-    if (sfp.ctx) {
-       ERR_free_strings();     /* free memory from SSL_load_error_strings */
-       EVP_cleanup();          /* free memory from OpenSSL_add_all_algorithms 
*/
-       SSL_CTX_free(sfp.ctx);  /* release context */
-    }
-    sfp.ctx = NULL;
     sfp.ssl = NULL;
-    if (sfp.server) {
-       /*
-        * This is the client.  We want the client-side to shut down
-        * first so that the server-side is not left with TIME_WAIT.
-        * We'll get the TIME_WAIT on the client-side, and that's okay.
-        */
-       shutdown(sfp.server, SHUT_RDWR);
-       close(sfp.server);
+    if (!sustain) {
+       if (sfp.ctx) {
+           ERR_free_strings();         /* free memory from 
SSL_load_error_strings */
+           EVP_cleanup();              /* free memory from 
OpenSSL_add_all_algorithms */
+           SSL_CTX_free(sfp.ctx);      /* release context */
+       }
+       sfp.ctx = NULL;
+       if (sfp.server) {
+           /*
+            * This is the client.  We want the client-side to shut down
+            * first so that the server-side is not left with TIME_WAIT.
+            * We'll get the TIME_WAIT on the client-side, and that's okay.
+            */
+           shutdown(sfp.server, SHUT_RDWR);
+           close(sfp.server);
+       }
+       sfp.server = 0;
     }
     if (sfp.client) {
        /*
@@ -772,7 +794,6 @@
        } while (!done);
        close(sfp.client);
     }
-    sfp.server = 0;
     sfp.client = 0;
     return;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/sslfax.h 
new/hylafax-7.0.6/faxd/sslfax.h
--- old/hylafax-7.0.5/faxd/sslfax.h     2020-01-31 19:41:10.000000000 +0100
+++ new/hylafax-7.0.6/faxd/sslfax.h     2022-02-04 23:47:09.000000000 +0100
@@ -58,10 +58,12 @@
     SSLFaxProcess startServer(fxStr info, fxStr pemFile);
     SSLFaxProcess startClient(fxStr info, fxStr passcode, const u_char* 
bitrev, long ms);
     void acceptClient(SSLFaxProcess& sfp, fxStr passcode, int modemFd, long 
ms);
-    void cleanup(SSLFaxProcess& sfp);
+    bool acceptClient1(SSLFaxProcess& sfp, long ms, bool sustain = false);
+    void acceptClient2(SSLFaxProcess& sfp, fxStr passcode, int modemFd, long 
ms, bool sustain = false);
+    void cleanup(SSLFaxProcess& sfp, bool sustain = false);
     int pending(SSLFaxProcess& sfp);
-    int read(SSLFaxProcess& sfp, void *buf, size_t count, int modemFd, long 
ms);
-    int write(SSLFaxProcess& sfp, const u_char *buf, u_int count, const 
u_char* bitrev, int modemFd, long ms, bool eod);
+    int read(SSLFaxProcess& sfp, void *buf, size_t count, int modemFd, long 
ms, bool sustain = false, bool carryon = false);
+    int write(SSLFaxProcess& sfp, const u_char *buf, u_int count, const 
u_char* bitrev, int modemFd, long ms, bool eod, bool sustain = false);
 };
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/sslfaxproxy.c++ 
new/hylafax-7.0.6/faxd/sslfaxproxy.c++
--- old/hylafax-7.0.5/faxd/sslfaxproxy.c++      1970-01-01 01:00:00.000000000 
+0100
+++ new/hylafax-7.0.6/faxd/sslfaxproxy.c++      2022-06-24 21:36:08.000000000 
+0200
@@ -0,0 +1,268 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <tiffio.h>
+#include <pthread.h>
+#include <sys/time.h>
+
+#include "config.h"
+#if defined(HAVE_SSL)
+#include "Sys.h"
+#include "ClassModem.h"
+#include "sslfax.h"
+
+const u_char* bitrev = TIFFGetBitRevTable(false);
+
+void
+printlog(FILE *fp, const char *fmt, ...)
+{
+  va_list ap;
+  char buf[32];
+  struct timeval tv;
+
+  gettimeofday(&tv, NULL);
+  time_t tt = tv.tv_sec;
+  strftime(buf, sizeof(buf), "[%Y-%m-%d %H:%M:%S", localtime(&tt));
+  fprintf(fp, "%s.%.6ld] ", buf, tv.tv_usec);
+
+  va_start(ap, fmt);
+  vfprintf(fp, fmt, ap);
+  va_end(ap);
+  fflush(fp);
+}
+
+timeval currentTime() {
+    timeval curTime;
+    gettimeofday(&curTime, 0);
+    return curTime;
+}
+
+/*
+ * Data structure for pthread argument for SSLFax endpoint thread.
+ */
+struct sslFaxThreadData {
+    int id, rfd, wfd;
+    SSLFax* sslfax;
+    SSLFaxProcess* sfp;
+};
+
+/*
+ * Wrapper function for SSLFax endpoint thread.
+ */
+void*
+sslFaxThread(void* sd)
+{
+    sslFaxThreadData *s = (sslFaxThreadData*) sd;
+
+    if (fcntl(s->rfd, F_SETFL, fcntl(s->rfd, F_GETFL, 0) | O_NONBLOCK) == -1) {
+       printlog(stderr, "Unable to set pipe read descriptor to 
non-blocking.\n");
+        return (NULL);
+    }
+
+    char buf[1024];
+    int cc;
+    int loops = 0;
+    while ((cc = s->sslfax->read(*(s->sfp), buf, 1024, s->rfd, 60000, true, 
true)) != 0) {
+       if (cc > 0) {
+           // Write read buf data to pipe.
+           cc = Sys::write(s->wfd, buf, cc);
+           if (cc <= 0) {
+               s->sfp->emsg = "Error writing to pipe";
+               break;;
+           }
+       } else if (cc == -1) {
+           // Data is waiting to be read from pipe.
+           while ((cc = Sys::read(s->rfd, buf, 1024)) > 0) {
+               loops = 0;
+               cc = s->sslfax->write(*(s->sfp), (u_char*) buf, cc, bitrev, 0, 
60000, false, true);
+               if (cc <= 0) {
+                   s->sfp->emsg = "Error writing to SSL Fax client";
+                   goto done;
+               }
+           }
+           if (cc <= 0) {
+               if (loops++ > 100 || cc == 0 || errno != EAGAIN) {
+                   s->sfp->emsg = "Error reading from pipe";
+                   break;
+               }
+           }
+       } else {
+           // Some error occurred.
+           break;
+       }
+    }
+done:
+    Sys::close(s->wfd);
+    Sys::close(s->rfd);
+    return (NULL);
+}
+
+char*
+randomString(int len)
+{
+    static char charset[] = 
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    int cs = sizeof(charset) - 1;
+    char* rstr = (char*) malloc((len + 1) * sizeof(char));
+    for (int i = 0; i < len; i++) rstr[i] = charset[rand() % cs];
+    rstr[len] = '\0';
+    return rstr;
+}
+
+void
+pairingThread(SSLFaxProcess* sfp, const char* infohost, const char* pemfile)
+{
+    // we have a client connection for proxy-server service.  Now start up the 
other end...
+
+    SSLFax sslfax;
+    SSLFaxProcess sslFaxProcess2 = sslfax.startServer(":1", pemfile);  // "1" 
indicates randomly assigned port
+
+    if (sslFaxProcess2.server) {
+       struct sockaddr_in data_addr;
+       socklen_t dlen = sizeof (data_addr);
+       if (getsockname(sslFaxProcess2.server, (struct sockaddr *) &data_addr, 
&dlen) < 0) {
+           printlog(stderr, "getsockname(ctrl): %s\n", strerror(errno));
+       }
+
+       srand(currentTime().tv_sec);
+       const char* passcode = randomString(10);
+
+       fxStr info = fxStr::format("%s@%s:%d", passcode, infohost, 
ntohs(data_addr.sin_port));
+       printlog(stdout, "Listening for paired client on: %s\n", (const char*) 
info);
+       const char* infostr = info;
+       int cs = sslfax.write(*sfp, (const u_char*) infostr, info.length(), 
bitrev, 0, 60000, false);
+       u_char buf[1];
+       buf[0] = 0;
+       cs = sslfax.write(*sfp, buf, 1, bitrev, 0, 60000, false);
+
+       sslfax.acceptClient(sslFaxProcess2, passcode, 0, 120000);       // 2 
min timeout for connection
+       printlog(stdout, "SSL Fax accept paired client: %s\n", (const char*) 
sslFaxProcess2.emsg);
+
+       if (sslFaxProcess2.ssl) {
+           // Make a pretty-looking log entry describing the communication 
path.
+           int str1len = sfp->emsg.next(20, ' ') - 20;
+           int str2len = sslFaxProcess2.emsg.next(20, ' ') - 20;
+           if (str1len > 0 && str2len > 0) {
+               printlog(stdout, "%s <--> %s <--> %s\n", (const char*) 
sfp->emsg.extract(20, str1len), (const char*) info, (const char*) 
sslFaxProcess2.emsg.extract(20, str2len));
+           }
+
+           /*
+            * We now have two SSLFax connections, one to each client, and we 
need simply exchange data
+            * between them.  So, we just read bytes from each connection and 
write them to the other.
+            * To do both concurrently we'll start up a thread and set of pipes 
for each and pass data
+            * between the two threads.
+            */
+           int pfd1[2];        // read communication pipe for sslFaxProcess1 
("a")
+           int pfd2[2];        // read communication pipe for sslFaxProcess2 
("b")
+           if (pipe(pfd1) >= 0 && pipe(pfd2) >= 0) {
+               pthread_t at;
+               struct sslFaxThreadData *a = (struct sslFaxThreadData *) 
malloc(sizeof(struct sslFaxThreadData));
+               a->id = 1;
+               a->rfd = pfd1[0];
+               a->wfd = pfd2[1];
+               a->sslfax = &sslfax;
+               a->sfp = sfp;
+               pthread_t bt;
+               struct sslFaxThreadData *b = (struct sslFaxThreadData *) 
malloc(sizeof(struct sslFaxThreadData));
+               b->id = 2;
+               b->rfd = pfd2[0];
+               b->wfd = pfd1[1];
+               b->sslfax = &sslfax;
+               b->sfp = &sslFaxProcess2;
+               if (pthread_create(&at, NULL, &sslFaxThread, (void *) a) != 0) {
+                   printlog(stderr, "Error starting thread a.\n");
+               }
+               if (pthread_create(&bt, NULL, &sslFaxThread, (void *) b) != 0) {
+                   printlog(stderr, "Error starting thread b.\n");
+               }
+
+               pthread_join(at, NULL);
+               pthread_join(bt, NULL);
+
+               sslfax.cleanup(sslFaxProcess2, false);
+
+               printlog(stdout, "Terminating connection with client on: %s\n", 
(const char*) info);
+           } else {
+               printlog(stderr, "Error starting communication pipes.\n");
+           }
+       } else {
+           // Connection failure message would have been shown above.
+       }
+    } else {
+       printlog(stderr, "Error creating pairing SSL Fax service: %s\n", (const 
char*) sslFaxProcess2.emsg);
+    }
+    return;
+}
+
+int
+main(int argc, char* argv[])
+{
+    if (argc != 4 && argc != 5) {
+       printlog(stderr, "usage: %s port passcode infohost [pemfile]\n", 
argv[0]);
+       exit(-1);
+    }
+    printlog(stdout, "%s started\n", argv[0]);
+    const char* pemfile;
+    if (argc == 5) pemfile = argv[4];
+    else pemfile = "/var/spool/hylafax/etc/ssl.pem";
+
+    char portstr[7];
+    snprintf(portstr, sizeof(portstr), ":%s", argv[1]);
+
+    bool repeat = true;
+
+    SSLFax sslfax;
+    SSLFaxProcess sfp = sslfax.startServer(portstr, pemfile);
+
+    do {
+       SSLFaxProcess sslFaxProcess;
+       sslFaxProcess.ctx = sfp.ctx;
+       sslFaxProcess.ssl = NULL;
+       sslFaxProcess.emsg = sfp.emsg;
+       sslFaxProcess.server = sfp.server;
+       sslFaxProcess.client = 0;
+
+       if (sslFaxProcess.server && sslfax.acceptClient1(sslFaxProcess, 0, 
true)) {
+
+           switch (fork()) {
+               case 0:         /* child */
+               {
+                   sslfax.acceptClient2(sslFaxProcess, argv[2], 0, 1000, true);
+                   if (!sslFaxProcess.ssl) {
+                       printlog(stderr, "Error accepting SSL Fax client: 
%s\n", (const char*) sslFaxProcess.emsg);
+                   } else {
+                       printlog(stdout, "SSL Fax accept client: %s\n", (const 
char*) sslFaxProcess.emsg);
+                       pairingThread(&sslFaxProcess, argv[3], pemfile);
+                   }
+                   sslfax.cleanup(sslFaxProcess, true);
+                   exit(0);
+               }
+               case -1:        /* fork failure */
+                   printlog(stderr, "Error forking for SSL Fax service.\n");
+                   break;
+               default:        /* parent */
+                   close(sslFaxProcess.client);        // close parent 
thread's handle on the forked client
+                   break;
+           }
+
+       } else {
+           printlog(stderr, "Error creating primary SSL Fax service: %s\n", 
(const char*) sslFaxProcess.emsg);
+           sleep(60);
+           if (!sslFaxProcess.server) {
+               sfp.emsg = "";
+               sfp = sslfax.startServer(portstr, pemfile);
+           }
+       }
+       int wstatus;
+       while (waitpid(-1, &wstatus, WNOHANG) > 0);     // clean up defunct 
child processes
+    } while (repeat);
+
+    exit (0);
+}
+#else
+int
+main(int argc, char* argv[])
+{
+    printlog(stderr, "%s not available due to lack of SSL Fax support.\n", 
argv[0]);
+    exit (0);
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/faxd/sslfaxproxytest.c++ 
new/hylafax-7.0.6/faxd/sslfaxproxytest.c++
--- old/hylafax-7.0.5/faxd/sslfaxproxytest.c++  1970-01-01 01:00:00.000000000 
+0100
+++ new/hylafax-7.0.6/faxd/sslfaxproxytest.c++  2022-02-04 23:47:09.000000000 
+0100
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <tiffio.h>
+
+#include "config.h"
+#include "ClassModem.h"
+#if defined(HAVE_SSL)
+#include "sslfax.h"
+#endif
+
+const u_char* bitrev = TIFFGetBitRevTable(false);
+
+int
+main(int argc, char* argv[])
+{
+    if (argc != 3) {
+       fprintf(stderr, "usage: %s info passcode\n", argv[0]);
+       exit(-1);
+    }
+
+    SSLFax sslfax;
+    SSLFaxProcess sslFaxProcess = sslfax.startClient(argv[1], argv[2], bitrev, 
1000);
+    printf("%s\n", (const char*) sslFaxProcess.emsg);
+
+    char buf[1024];
+    int r;
+    fxStr info;
+    do {
+       r = sslfax.read(sslFaxProcess, buf, 1, 0, 60000);
+       if (r > 0 && buf[0] != 0) info.append( buf[0]&0xFF );
+    } while (r > 0 && (buf[0]&0xFF) != 0);
+    printf("Got info: %s\n", (const char*) info);
+
+    int atpos = info.next(0, '@');
+    fxStr passcode = info.extract(0, atpos);
+    fxStr hostport = info.extract(atpos+1, info.length()-atpos-1);
+    printf("Connecting to %s with passcode %s\n", (const char*) hostport, 
(const char*) passcode);
+
+    SSLFaxProcess sslFaxProcess2 = sslfax.startClient(hostport, passcode, 
bitrev, 1000);
+    printf("%s\n", (const char*) sslFaxProcess2.emsg);
+
+    u_char test[7] = { 0xFF, 0x13, 0x84, 0xEA, 0x7D, 0x10, 0x03 };  // a CFR 
signal
+
+    do {
+
+       int cs = sslfax.write(sslFaxProcess2, test, 7, bitrev, 0, 60000, false);
+       int cc = 0;
+       while (cc < 7) {
+           int cr = sslfax.read(sslFaxProcess, buf, 1024, 0, 60000);
+           if (cr > 0) cc += cr;
+       }
+       printf("%.2X/%.2X %.2X/%.2X %.2X/%.2X %.2X/%.2X %.2X/%.2X %.2X/%.2X 
%.2X/%.2X\n", buf[0]&0xFF, test[0], buf[1]&0xFF, test[1], buf[2]&0xFF, test[2], 
buf[3]&0xFF, test[3], buf[4]&0xFF, test[4], buf[5]&0xFF, test[5], buf[6]&0xFF, 
test[6]);
+
+       cs = sslfax.write(sslFaxProcess, test, 7, bitrev, 0, 60000, false);
+        cc = 0;
+       while (cc < 7) {
+           int cr = sslfax.read(sslFaxProcess2, buf, 1024, 0, 60000);
+           if (cr > 0) cc += cr;
+       }
+       printf("%.2X/%.2X %.2X/%.2X %.2X/%.2X %.2X/%.2X %.2X/%.2X %.2X/%.2X 
%.2X/%.2X\n", buf[0]&0xFF, test[0], buf[1]&0xFF, test[1], buf[2]&0xFF, test[2], 
buf[3]&0xFF, test[3], buf[4]&0xFF, test[4], buf[5]&0xFF, test[5], buf[6]&0xFF, 
test[6]);
+
+    } while (true);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hylafax-7.0.5/man/hylafax-config.4f 
new/hylafax-7.0.6/man/hylafax-config.4f
--- old/hylafax-7.0.5/man/hylafax-config.4f     2021-12-05 05:57:28.000000000 
+0100
+++ new/hylafax-7.0.6/man/hylafax-config.4f     2022-05-04 05:41:00.000000000 
+0200
@@ -274,6 +274,7 @@
 ModemModelQueryCmd     string  \-      command for querying modem model
 ModemNoAutoAnswerCmd   string  \s-1ATS0=0\s+1  command for disabling 
auto-answer
 ModemNoAutoAnswerCmdDelay      integer \s-10\s+1       time, in ms, to pause 
after a disabling auto-answer
+ModemNoDialtoneRetries integer \s-11\s+1       maximum number of attempts to 
get dialtone
 ModemNoFlowCmd string  \-      command for disabling hardware flow control 
between \s-1DTE\s+1 and \s-1DCE\s+1
 ModemOnHookCmd string  \s-1ATH0\s+1    command for placing phone ``on hook''
 ModemPageDoneTimeout   integer \s-1180000\s+1  page send/receive timeout (ms)
@@ -351,6 +352,7 @@
 Class1SSLFaxCert       string  \s-1etc/ssl.pem\s+1     Class 1/1.0: PEM 
certificate file for SSL Fax
 Class1SSLFaxClientTimeout      integer \s-15000\s+1    Class 1/1.0: timeout 
waiting for client connection
 Class1SSLFaxInfo       string  \-      Class 1/1.0: hostname and port number 
for SSL Fax
+Class1SSLFaxProxy      string  \-      Class 1/1.0: hostname and port number 
for SSL Fax Proxy
 Class1SSLFaxSupport    boolean \s-1Yes\s+1     Class 1/1.0: support for SSL Fax
 Class1SSLFaxServerTimeout      integer \s-12000\s+1    Class 1/1.0: timeout 
waiting for server connection
 Class1TCFRecvHackCmd   string  \s-1""\s+1      Class 1/1.0: command to avoid 
+FCERROR before TCF
@@ -1749,6 +1751,7 @@
 131072 (0x20000)       Docq Changes    document reference handling
 262144 (0x40000)       TIFF library    any messages produced by the TIFF 
library
 524288 (0x80000)       ECM Frames      binary \s-1T.30-A HDLC\s+1 ECM frames
+1048576 (0x100000)     SSL Fax data    SSL Fax data bytes
 .sp .5
 .fi
 For example, to enable tracing of server operations and
@@ -2500,6 +2503,9 @@
 before any further commands are sent to the modem.  All input from
 the modem is flushed after pausing.
 .TP
+.B ModemNoDialtoneRetries
+The maximum number of attempts that can be made to obtain dialtone from the 
line when placing a call.
+.TP
 .B ModemNoFlowCmd
 The command to disable flow control between
 .SM DTE
@@ -3115,6 +3121,16 @@
 is configured for one system, then it is always dependent on the remote
 systems to operate as the SSL Fax server.
 .TP
+.B Class1SSLFaxProxy
+The formatted password, hostname, and port number
+(``<passcode@<hostname>:<port>'') for an SSL Fax proxy connection
+to be used if no
+.B Class1SSLFaxInfo
+is configured.  This causes \*(Fx to establish an outbound SSL Fax connection
+to a configured SSL Fax proxy server when fax connections to remote systems
+support SSL Fax.  The proxy server will provide the proxied SSL Fax URL back
+to \*(Fx which will be used in CSA and TSA signals for SSL Fax.
+.TP
 .B Class1SSLFaxServerTimeout
 The time, in milliseconds, that the SSL Fax client should wait for the
 connection to the server to complete before abandoning SSL Fax and proceeding

Reply via email to