Hello community,
here is the log from the commit of package hylafax+ for openSUSE:Factory checked in at 2016-04-03 23:07:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hylafax+ (Old)
and /work/SRC/openSUSE:Factory/.hylafax+.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hylafax+"
Changes:
--------
--- /work/SRC/openSUSE:Factory/hylafax+/hylafax+.changes 2016-02-18 12:36:53.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.hylafax+.new/hylafax+.changes 2016-04-03 23:07:37.000000000 +0200
@@ -1,0 +2,12 @@
+Sun Apr 3 10:39:42 UTC 2016 - axel.braun@gmx.de
+
+- hylafax+ 5.5.8
+* stop using mktemp() (5 Feb 2016)
+* fix LDAP authentication broken in 5.5.4 (24-26 Jan 2016)
+* reset senderinfo properly when receiving faxes (22 Jan 2016)
+* cope with V.21 HDLC carrier loss following +FRH:3 better (22, 26 Jan 2016)
+* increase the time Class1SwitchingCmd will wait for a response (14 Jan 2016)
+* undo faulty/incorrect previous "fix" to ntries/npages (13 Jan 2016)
+* fix short blocking problems in reading from the device (12 Jan 2016)
+
+-------------------------------------------------------------------
Old:
----
hylafax-5.5.7.tar.gz
New:
----
hylafax-5.5.8.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ hylafax+.spec ++++++
--- /var/tmp/diff_new_pack.uhNkkp/_old 2016-04-03 23:07:38.000000000 +0200
+++ /var/tmp/diff_new_pack.uhNkkp/_new 2016-04-03 23:07:38.000000000 +0200
@@ -19,7 +19,7 @@
%global faxspool %{_localstatedir}/spool/hylafax
%define lib_version %(echo %{version} | tr \. _)
Name: hylafax+
-Version: 5.5.7
+Version: 5.5.8
Release: 0
Summary: An enterprise-strength fax server
License: BSD-3-Clause
++++++ hylafax-5.5.7.tar.gz -> hylafax-5.5.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/CHANGES new/hylafax-5.5.8/CHANGES
--- old/hylafax-5.5.7/CHANGES 2015-12-28 17:26:09.000000000 +0100
+++ new/hylafax-5.5.8/CHANGES 2016-02-06 22:32:30.000000000 +0100
@@ -2,6 +2,16 @@
New Changes
+* stop using mktemp() (5 Feb 2016)
+* fix LDAP authentication broken in 5.5.4 (24-26 Jan 2016)
+* reset senderinfo properly when receiving faxes (22 Jan 2016)
+* cope with V.21 HDLC carrier loss following +FRH:3 better (22, 26 Jan 2016)
+* increase the time Class1SwitchingCmd will wait for a response (14 Jan 2016)
+* undo faulty/incorrect previous "fix" to ntries/npages (13 Jan 2016)
+* fix short blocking problems in reading from the device (12 Jan 2016)
+
+(5.5.7)
+
* fix ntries counter to apply to pages instead of documents (5 Dec 2015)
* reject jobs rejected by the proxy (18-19 Nov 2015)
* add RewriteFaxName and RewriteFaxNumber jobcontrol features (14 Nov 2015)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/VERSION new/hylafax-5.5.8/VERSION
--- old/hylafax-5.5.7/VERSION 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/VERSION 2016-02-06 22:32:30.000000000 +0100
@@ -1 +1 @@
-5.5.7
+5.5.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/Class1.c++ new/hylafax-5.5.8/faxd/Class1.c++
--- old/hylafax-5.5.7/faxd/Class1.c++ 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/Class1.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -501,7 +501,7 @@
scmd = scmd.head(7) | fxStr(dur, "%d");
}
}
- if (!silenceHeard && !atCmd(scmd, AT_OK)) {
+ if (!silenceHeard && !atCmd(scmd, AT_OK, 60*1000)) {
emsg = "Failure to receive silence (synchronization failure). {E100}";
protoTrace(emsg);
if (wasTimeout()) abortReceive();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/Class1.h new/hylafax-5.5.8/faxd/Class1.h
--- old/hylafax-5.5.7/faxd/Class1.h 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/Class1.h 2016-02-06 22:32:30.000000000 +0100
@@ -223,7 +223,7 @@
void getDataStats(FaxSetup* setupinfo);
void sendSetupPhaseB(const fxStr& pwd, const fxStr& sub);
FaxSendStatus sendPhaseB(TIFF* tif, Class2Params&, FaxMachineInfo&,
- fxStr& pph, fxStr& emsg, u_int& batched, u_short& npages);
+ fxStr& pph, fxStr& emsg, u_int& batched);
void sendEnd();
void sendAbort();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/Class1Recv.c++ new/hylafax-5.5.8/faxd/Class1Recv.c++
--- old/hylafax-5.5.7/faxd/Class1Recv.c++ 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/Class1Recv.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -97,6 +97,8 @@
capsUsed = 0; // no DCS or CTC seen yet
dataSent = 0; // start with a clean slate...
dataMissed = 0; // unfortunately, this will reset after EOM
+ senderSkipsV29 = false;
+ senderHasV17Trouble = false;
if (setupinfo) {
senderSkipsV29 = setupinfo->senderSkipsV29;
@@ -276,7 +278,22 @@
if (lastResponse == AT_FRH3 && waitFor(AT_CONNECT,0)) {
// It's unclear if we are in "COMMAND REC" or "RESPONSE REC" mode,
// but since we are already detecting the carrier, wait the longer.
- gotframe = recvFrame(frame, FCF_RCVR, conf.t2Timer, true, true, false);
+ gotframe = recvFrame(frame, FCF_RCVR, conf.t2Timer, true, false, false);
+ if (!gotframe && !frame.getLength() && lastResponse == AT_NOCARRIER) {
+ /*
+ * The modem may have incorrectly detected V.21 HDLC.
+ * The TCF signal is yet to come. So, try again.
+ */
+ if (recvTraining()) {
+ emsg = "";
+ return (true);
+ }
+ if (lastResponse == AT_FRH3 && waitFor(AT_CONNECT,0)) {
+ // It's unclear if we are in "COMMAND REC" or "RESPONSE REC" mode,
+ // but since we are already detecting the carrier, wait the longer.
+ gotframe = recvFrame(frame, FCF_RCVR, conf.t2Timer, true, true, false);
+ }
+ }
lastResponse = AT_NOTHING;
}
}
@@ -618,86 +635,102 @@
messageReceived = true;
prevPage++;
} else {
- /*
- * Look for message carrier and receive Phase C data.
- */
- /*
- * Same reasoning here as before receiving TCF.
- */
- if (!atCmd(conf.class1MsgRecvHackCmd, AT_OK)) {
- emsg = "Failure to receive silence (synchronization failure). {E100}";
- return (false);
- }
- /*
- * Set high speed carrier & start receive. If the
- * negotiated modulation technique includes short
- * training, then we use it here (it's used for all
- * high speed carrier traffic other than the TCF).
- *
- * Timing here is very critical. It is more "tricky" than timing
- * for AT+FRM for TCF because unlike with TCF, where the direction
- * of communication doesn't change, here it does change because
- * we just sent CFR but now have to do AT+FRM. In practice, if we
- * issue AT+FRM after the sender does AT+FTM then we'll get +FCERROR.
- * Using Class1MsgRecvHackCmd often only complicates the problem.
- * If the modem doesn't drop its transmission carrier (OK response
- * following CFR) quickly enough, then we'll see more +FCERROR.
- */
- fxStr rmCmd(curcap[HasShortTraining(curcap)].value, rmCmdFmt);
- u_short attempts = 0;
+ bool retryrmcmd;
+ int rmattempted = 0;
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);
- if (rmResponse == AT_CONNECT) {
+ retryrmcmd = false;
/*
- * We don't want the AT+FRM=n command to get buffered,
- * so buffering and flow control must be done after CONNECT.
- * Flushing now would be a mistake as data may already be
- * in the buffer.
+ * Look for message carrier and receive Phase C data.
*/
- setInputBuffering(true);
- if (flowControl == FLOW_XONXOFF)
- (void) setXONXOFF(FLOW_NONE, FLOW_XONXOFF, ACT_NOW);
/*
- * The message carrier was recognized;
- * receive the Phase C data.
+ * Same reasoning here as before receiving TCF.
*/
- protoTrace("RECV: begin page");
- pageGood = recvPageData(tif, emsg);
- protoTrace("RECV: end page");
- if (!wasTimeout()) {
+ if (!atCmd(conf.class1MsgRecvHackCmd, AT_OK)) {
+ emsg = "Failure to receive silence (synchronization failure). {E100}";
+ return (false);
+ }
+ /*
+ * Set high speed carrier & start receive. If the
+ * negotiated modulation technique includes short
+ * training, then we use it here (it's used for all
+ * high speed carrier traffic other than the TCF).
+ *
+ * Timing here is very critical. It is more "tricky" than timing
+ * for AT+FRM for TCF because unlike with TCF, where the direction
+ * of communication doesn't change, here it does change because
+ * we just sent CFR but now have to do AT+FRM. In practice, if we
+ * issue AT+FRM after the sender does AT+FTM then we'll get +FCERROR.
+ * Using Class1MsgRecvHackCmd often only complicates the problem.
+ * If the modem doesn't drop its transmission carrier (OK response
+ * following CFR) quickly enough, then we'll see more +FCERROR.
+ */
+ fxStr rmCmd(curcap[HasShortTraining(curcap)].value, rmCmdFmt);
+ u_short attempts = 0;
+ 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);
+ if (rmResponse == AT_CONNECT) {
/*
- * The data was received correctly, wait patiently
- * for the modem to signal carrier drop. Some senders
- * may send a lot of garbage after RTC, so be patient.
+ * We don't want the AT+FRM=n command to get buffered,
+ * so buffering and flow control must be done after CONNECT.
+ * Flushing now would be a mistake as data may already be
+ * in the buffer.
*/
- time_t nocarrierstart = Sys::now();
- do {
- messageReceived = waitFor(AT_NOCARRIER, 60*1000);
- } while (!messageReceived && Sys::now() < (nocarrierstart + 60));
- if (messageReceived)
- prevPage++;
- timer = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer; // wait longer for PPM (estimate 80KB)
- }
- } else {
- if (wasTimeout()) {
- abortReceive(); // return to command mode
- setTimeout(false);
- }
- bool getframe = false;
- long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
- if (rmResponse == AT_FRH3) getframe = waitFor(AT_CONNECT, 0);
- else if (rmResponse != AT_NOCARRIER && rmResponse != AT_ERROR) getframe = atCmd(rhCmd, AT_CONNECT, wait); // wait longer
- if (getframe) {
- HDLCFrame frame(conf.class1FrameOverhead);
- if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true)) {
- traceFCF("RECV recv", frame.getFCF());
- signalRcvd = frame.getFCF();
- messageReceived = true;
+ setInputBuffering(true);
+ if (flowControl == FLOW_XONXOFF)
+ (void) setXONXOFF(FLOW_NONE, FLOW_XONXOFF, ACT_NOW);
+ /*
+ * The message carrier was recognized;
+ * receive the Phase C data.
+ */
+ protoTrace("RECV: begin page");
+ pageGood = recvPageData(tif, emsg);
+ protoTrace("RECV: end page");
+ if (!wasTimeout()) {
+ /*
+ * The data was received correctly, wait patiently
+ * for the modem to signal carrier drop. Some senders
+ * may send a lot of garbage after RTC, so be patient.
+ */
+ time_t nocarrierstart = Sys::now();
+ do {
+ messageReceived = waitFor(AT_NOCARRIER, 60*1000);
+ } while (!messageReceived && Sys::now() < (nocarrierstart + 60));
+ if (messageReceived)
+ prevPage++;
+ timer = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer; // wait longer for PPM (estimate 80KB)
+ }
+ } else {
+ if (wasTimeout()) {
+ abortReceive(); // return to command mode
+ setTimeout(false);
+ }
+ bool getframe = false;
+ long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
+ if (rmResponse == AT_FRH3) getframe = waitFor(AT_CONNECT, 0);
+ else if (rmResponse != AT_NOCARRIER && rmResponse != AT_ERROR) getframe = atCmd(rhCmd, AT_CONNECT, wait); // wait longer
+ if (getframe) {
+ HDLCFrame frame(conf.class1FrameOverhead);
+ if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true, false)) {
+ traceFCF("RECV recv", frame.getFCF());
+ signalRcvd = frame.getFCF();
+ messageReceived = true;
+ } else {
+ /*
+ * V.21 HDLC was detected and then the carrier was lost without
+ * receiving any data. It's possible that the modem erred in
+ * its detection of the high-speed carrier. But, it's also
+ * possible that echo of our CFR was detected or that there is
+ * another receiver on the line (another fax machine sharing the
+ * line on the send-side), and we heard them. Often we can still
+ * acquire the high-speed carrier if we just re-issue AT+FRM=n.
+ */
+ if (lastResponse == AT_NOCARRIER) retryrmcmd = true;
+ }
}
}
- }
+ } while (retryrmcmd && ++rmattempted < 2);
}
if (signalRcvd != 0) {
if (flowControl == FLOW_XONXOFF)
@@ -812,10 +845,22 @@
} while (!trainok && traincount++ < 3 && lastResponse != AT_FRH3 && recvFrame(frame, FCF_RCVR, timer));
if (messageReceived && lastResponse == AT_FRH3 && waitFor(AT_CONNECT,0)) {
messageReceived = false;
- if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true)) {
+ if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true, false)) {
messageReceived = true;
signalRcvd = frame.getFCF();
}
+ if (!frame.getLength() && lastResponse == AT_NOCARRIER) {
+ // The modem may have indicated V.21 HDLC incorrectly. TCF may be coming. Get ready.
+ trainok = recvTraining();
+ messageReceived = (!trainok && lastResponse == AT_FRH3);
+ if (messageReceived && lastResponse == AT_FRH3 && waitFor(AT_CONNECT,0)) {
+ messageReceived = false;
+ if (recvFrame(frame, FCF_RCVR, conf.t2Timer, true)) {
+ messageReceived = true;
+ signalRcvd = frame.getFCF();
+ }
+ }
+ }
lastResponse = AT_NOTHING;
} else messageReceived = false;
break;
@@ -1178,237 +1223,258 @@
signalRcvd = 0;
rcpcnt = 0;
bool dataseen = false;
- if (!useV34 && !gotoPhaseD) {
- gotRTNC = false;
- if (!raiseRecvCarrier(dolongtrain, emsg) && !gotRTNC) {
- if (wasTimeout()) {
- abortReceive(); // return to command mode
- setTimeout(false);
- }
- long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
- if (lastResponse != AT_NOCARRIER && atCmd(rhCmd, AT_CONNECT, wait)) { // wait longer
- // sender is transmitting V.21 instead, we may have
- // missed the first signal attempt, but should catch
- // the next attempt. This "simulates" adaptive receive.
- emsg = ""; // reset
- gotRTNC = true;
- } else {
- if (wasTimeout()) abortReceive();
- abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
- return (false);
- }
- }
- }
- if (useV34 || gotRTNC) { // V.34 mode or if +FRH:3 in adaptive reception
- if (!gotEOT) {
- bool gotprimary = false;
- if (useV34) gotprimary = waitForDCEChannel(false);
- while (!sendERR && !gotEOT && (gotRTNC || (ctrlFrameRcvd != fxStr::null))) {
- /*
- * Remote requested control channel retrain, the remote didn't
- * properly hear our last signal, and/or we got an EOR signal
- * after PPR. So now we have to use a signal from the remote
- * and then respond appropriately to get us back or stay in sync.
- * DCS::CFR - PPS::PPR/MCF - EOR::ERR
- */
- HDLCFrame rtncframe(conf.class1FrameOverhead);
- bool gotrtncframe = false;
- if (useV34) {
- if (ctrlFrameRcvd != fxStr::null) {
- gotrtncframe = true;
- for (u_int i = 0; i < ctrlFrameRcvd.length(); i++)
- rtncframe.put(frameRev[ctrlFrameRcvd[i] & 0xFF]);
- traceHDLCFrame("-->", rtncframe);
- } else
- gotrtncframe = recvFrame(rtncframe, FCF_RCVR, conf.t2Timer);
+ bool retryrmcmd;
+ int rmattempted = 0;
+ do {
+ retryrmcmd = false;
+ if (!useV34 && !gotoPhaseD) {
+ gotRTNC = false;
+ if (!raiseRecvCarrier(dolongtrain, emsg) && !gotRTNC) {
+ if (wasTimeout()) {
+ abortReceive(); // return to command mode
+ setTimeout(false);
+ }
+ long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
+ if (lastResponse != AT_NOCARRIER && atCmd(rhCmd, AT_CONNECT, wait)) { // wait longer
+ // sender is transmitting V.21 instead, we may have
+ // missed the first signal attempt, but should catch
+ // the next attempt. This "simulates" adaptive receive.
+ emsg = ""; // reset
+ gotRTNC = true;
} else {
- gotrtncframe = recvFrame(rtncframe, FCF_RCVR, conf.t2Timer, true);
+ if (wasTimeout()) abortReceive();
+ abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
+ return (false);
}
- if (gotrtncframe) {
- traceFCF("RECV recv", rtncframe.getFCF());
- switch (rtncframe.getFCF()) {
- case FCF_PPS:
- if (rtncframe.getLength() > 5) {
- u_int fc = frameRev[rtncframe[6]] + 1;
- if ((fc == 256 || fc == 1) && !dataseen) fc = 0; // distinguish 0 from 1 and 256
- traceFCF("RECV recv", rtncframe.getFCF2());
- u_int pgcount = u_int(prevPage/256)*256+frameRev[rtncframe[4]]; // cope with greater than 256 pages
- protoTrace("RECV received %u frames of block %u of page %u", \
- fc, frameRev[rtncframe[5]]+1, pgcount+1);
- switch (rtncframe.getFCF2()) {
- case 0: // PPS-NULL
- case FCF_EOM:
- case FCF_MPS:
- case FCF_EOP:
- case FCF_PRI_EOM:
- case FCF_PRI_MPS:
- case FCF_PRI_EOP:
- if (!useV34 && !switchingPause(emsg)) {
- abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
- return (false);
- }
- if (pgcount > prevPage || (pgcount == prevPage && frameRev[rtncframe[5]] >= prevBlock)) {
- (void) transmitFrame(FCF_PPR, fxStr(ppr, 32));
- traceFCF("RECV send", FCF_PPR);
- } else {
- (void) transmitFrame(FCF_MCF|FCF_RCVR);
- traceFCF("RECV send", FCF_MCF);
- }
- break;
- }
- }
- break;
- case FCF_EOR:
- if (rtncframe.getLength() > 5) {
- traceFCF("RECV recv", rtncframe.getFCF2());
- switch (rtncframe.getFCF2()) {
- case 0: // PPS-NULL
- case FCF_EOM:
- case FCF_MPS:
- case FCF_EOP:
- case FCF_PRI_EOM:
- case FCF_PRI_MPS:
- case FCF_PRI_EOP:
- if (fcount) {
- /*
- * The block hasn't been written to disk.
- * This is expected when the sender sends
- * EOR after our PPR (e.g. after the 4th).
- */
- blockgood = true;
- signalRcvd = rtncframe.getFCF2();
- if (signalRcvd) lastblock = true;
- sendERR = true;
- } else {
+ }
+ }
+ if (useV34 || gotRTNC) { // V.34 mode or if +FRH:3 in adaptive reception
+ if (!gotEOT) {
+ bool gotprimary = false;
+ if (useV34) gotprimary = waitForDCEChannel(false);
+ while (!sendERR && !gotEOT && (gotRTNC || (ctrlFrameRcvd != fxStr::null))) {
+ /*
+ * Remote requested control channel retrain, the remote didn't
+ * properly hear our last signal, and/or we got an EOR signal
+ * after PPR. So now we have to use a signal from the remote
+ * and then respond appropriately to get us back or stay in sync.
+ * DCS::CFR - PPS::PPR/MCF - EOR::ERR
+ */
+ HDLCFrame rtncframe(conf.class1FrameOverhead);
+ bool gotrtncframe = false;
+ if (useV34) {
+ if (ctrlFrameRcvd != fxStr::null) {
+ gotrtncframe = true;
+ for (u_int i = 0; i < ctrlFrameRcvd.length(); i++)
+ rtncframe.put(frameRev[ctrlFrameRcvd[i] & 0xFF]);
+ traceHDLCFrame("-->", rtncframe);
+ } else
+ gotrtncframe = recvFrame(rtncframe, FCF_RCVR, conf.t2Timer);
+ } else {
+ gotrtncframe = recvFrame(rtncframe, FCF_RCVR, conf.t2Timer, true, false);
+ }
+ if (gotrtncframe) {
+ traceFCF("RECV recv", rtncframe.getFCF());
+ switch (rtncframe.getFCF()) {
+ case FCF_PPS:
+ if (rtncframe.getLength() > 5) {
+ u_int fc = frameRev[rtncframe[6]] + 1;
+ if ((fc == 256 || fc == 1) && !dataseen) fc = 0; // distinguish 0 from 1 and 256
+ traceFCF("RECV recv", rtncframe.getFCF2());
+ u_int pgcount = u_int(prevPage/256)*256+frameRev[rtncframe[4]]; // cope with greater than 256 pages
+ protoTrace("RECV received %u frames of block %u of page %u", \
+ fc, frameRev[rtncframe[5]]+1, pgcount+1);
+ switch (rtncframe.getFCF2()) {
+ case 0: // PPS-NULL
+ case FCF_EOM:
+ case FCF_MPS:
+ case FCF_EOP:
+ case FCF_PRI_EOM:
+ case FCF_PRI_MPS:
+ case FCF_PRI_EOP:
if (!useV34 && !switchingPause(emsg)) {
abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
return (false);
}
- (void) transmitFrame(FCF_ERR|FCF_RCVR);
- traceFCF("RECV send", FCF_ERR);
- }
- break;
+ if (pgcount > prevPage || (pgcount == prevPage && frameRev[rtncframe[5]] >= prevBlock)) {
+ (void) transmitFrame(FCF_PPR, fxStr(ppr, 32));
+ traceFCF("RECV send", FCF_PPR);
+ } else {
+ (void) transmitFrame(FCF_MCF|FCF_RCVR);
+ traceFCF("RECV send", FCF_MCF);
+ }
+ break;
+ }
}
- }
- break;
- case FCF_CTC:
- {
- u_int dcs; // possible bits 1-16 of DCS in FIF
- if (useV34) {
- // T.30 F.3.4.5 Note 1 does not permit CTC in V.34-fax
- emsg = "Received invalid CTC signal in V.34-Fax. {E113}";
- abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
- return (false);
+ break;
+ case FCF_EOR:
+ if (rtncframe.getLength() > 5) {
+ traceFCF("RECV recv", rtncframe.getFCF2());
+ switch (rtncframe.getFCF2()) {
+ case 0: // PPS-NULL
+ case FCF_EOM:
+ case FCF_MPS:
+ case FCF_EOP:
+ case FCF_PRI_EOM:
+ case FCF_PRI_MPS:
+ case FCF_PRI_EOP:
+ if (fcount) {
+ /*
+ * The block hasn't been written to disk.
+ * This is expected when the sender sends
+ * EOR after our PPR (e.g. after the 4th).
+ */
+ blockgood = true;
+ signalRcvd = rtncframe.getFCF2();
+ if (signalRcvd) lastblock = true;
+ sendERR = true;
+ } else {
+ if (!useV34 && !switchingPause(emsg)) {
+ abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
+ return (false);
+ }
+ (void) transmitFrame(FCF_ERR|FCF_RCVR);
+ traceFCF("RECV send", FCF_ERR);
+ }
+ break;
+ }
}
- /*
- * See the other comments about T.30 A.1.3. Some senders
- * are habitually wrong in sending CTC at incorrect moments.
- */
- // use 16-bit FIF to alter speed, curcap
- dcs = rtncframe[3] | (rtncframe[4]<<8);
- curcap = findSRCapability(dcs&DCS_SIGRATE, recvCaps);
- processNewCapabilityUsage();
- // requisite pause before sending response (CTR)
- if (!switchingPause(emsg)) {
+ break;
+ case FCF_CTC:
+ {
+ u_int dcs; // possible bits 1-16 of DCS in FIF
+ if (useV34) {
+ // T.30 F.3.4.5 Note 1 does not permit CTC in V.34-fax
+ emsg = "Received invalid CTC signal in V.34-Fax. {E113}";
+ abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
+ return (false);
+ }
+ /*
+ * See the other comments about T.30 A.1.3. Some senders
+ * are habitually wrong in sending CTC at incorrect moments.
+ */
+ // use 16-bit FIF to alter speed, curcap
+ dcs = rtncframe[3] | (rtncframe[4]<<8);
+ curcap = findSRCapability(dcs&DCS_SIGRATE, recvCaps);
+ processNewCapabilityUsage();
+ // requisite pause before sending response (CTR)
+ if (!switchingPause(emsg)) {
+ abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
+ return (false);
+ }
+ (void) transmitFrame(FCF_CTR|FCF_RCVR);
+ traceFCF("RECV send", FCF_CTR);
+ dolongtrain = true;
+ pprcnt = 0;
+ break;
+ }
+ case FCF_CRP:
+ // command repeat... just repeat whatever we last sent
+ if (!useV34 && !switchingPause(emsg)) {
abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
return (false);
}
- (void) transmitFrame(FCF_CTR|FCF_RCVR);
- traceFCF("RECV send", FCF_CTR);
- dolongtrain = true;
- pprcnt = 0;
+ transmitFrame(signalSent);
+ traceFCF("RECV send", (u_char) signalSent[2]);
break;
- }
- case FCF_CRP:
- // command repeat... just repeat whatever we last sent
- if (!useV34 && !switchingPause(emsg)) {
+ case FCF_DCN:
+ emsg = "COMREC received DCN (sender abort) {E108}";
+ gotEOT = true;
+ recvdDCN = true;
+ continue;
+ case FCF_MCF:
+ case FCF_CFR:
+ case FCF_CTR:
+ if ((rtncframe[2] & 0x80) == FCF_RCVR) {
+ /*
+ * Echo on the channel may be so lagged that we're hearing
+ * ourselves. Ignore it. Try again.
+ */
+ break;
+ }
+ /* intentional pass-through */
+ default:
+ // The message is not ECM-specific: fall out of ECM receive, and let
+ // the earlier message-handling routines try to cope with the signal.
+ signalRcvd = rtncframe.getFCF();
+ messageReceived = true;
abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
- return (false);
+ if (getRecvEOLCount() == 0) {
+ prevPage--; // counteract the forthcoming increment
+ return (true);
+ } else {
+ emsg = "COMREC invalid response received {E110}"; // plain ol' error
+ return (false);
+ }
+ }
+ if (!sendERR) { // as long as we're not trying to send the ERR signal (set above)
+ if (useV34) gotprimary = waitForDCEChannel(false);
+ else {
+ gotRTNC = false;
+ if (!raiseRecvCarrier(dolongtrain, emsg) && !gotRTNC) {
+ if (wasTimeout()) {
+ abortReceive(); // return to command mode
+ setTimeout(false);
+ }
+ long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
+ if (lastResponse != AT_NOCARRIER && atCmd(rhCmd, AT_CONNECT, wait)) { // wait longer
+ // simulate adaptive receive
+ emsg = ""; // clear the failure
+ gotRTNC = true;
+ } else {
+ if (wasTimeout()) abortReceive();
+ abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
+ return (false);
+ }
+ } else gotprimary = true;
}
- transmitFrame(signalSent);
- traceFCF("RECV send", (u_char) signalSent[2]);
- break;
- case FCF_DCN:
- emsg = "COMREC received DCN (sender abort) {E108}";
- gotEOT = true;
- recvdDCN = true;
- continue;
- case FCF_MCF:
- case FCF_CFR:
- case FCF_CTR:
- if ((rtncframe[2] & 0x80) == FCF_RCVR) {
- /*
- * Echo on the channel may be so lagged that we're hearing
- * ourselves. Ignore it. Try again.
- */
+ }
+ } else {
+ gotprimary = false;
+ if (!useV34) {
+ if (wasTimeout()) {
+ abortReceive();
break;
}
- /* intentional pass-through */
- default:
- // The message is not ECM-specific: fall out of ECM receive, and let
- // the earlier message-handling routines try to cope with the signal.
- signalRcvd = rtncframe.getFCF();
- messageReceived = true;
- abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
- if (getRecvEOLCount() == 0) {
- prevPage--; // counteract the forthcoming increment
- return (true);
- } else {
- emsg = "COMREC invalid response received {E110}"; // plain ol' error
- return (false);
- }
- }
- if (!sendERR) { // as long as we're not trying to send the ERR signal (set above)
- if (useV34) gotprimary = waitForDCEChannel(false);
- else {
- gotRTNC = false;
- if (!raiseRecvCarrier(dolongtrain, emsg) && !gotRTNC) {
- if (wasTimeout()) {
- abortReceive(); // return to command mode
- setTimeout(false);
- }
- long wait = BIT(curcap->br) & BR_ALL ? 273066 / (curcap->br+1) : conf.t2Timer;
- if (lastResponse != AT_NOCARRIER && atCmd(rhCmd, AT_CONNECT, wait)) { // wait longer
- // simulate adaptive receive
- emsg = ""; // clear the failure
- gotRTNC = true;
+ if (lastResponse == AT_NOCARRIER) {
+ /*
+ * The modem reported V.21 HDLC but then reported that carrier was lost.
+ * The modem may have erred in its detection of the high-speed carrier.
+ * But it may also have detected echo from our end or there may be
+ * another receiver on the line (the sender is sharing the line with two
+ * machines). Try AT+FRM=n again.
+ */
+ retryrmcmd = true;
+ if (rmattempted+1 < 2) {
+ gotRTNC = false;
} else {
- if (wasTimeout()) abortReceive();
- abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
- return (false);
+ gotRTNC = true;
+ if (!atCmd(rhCmd, AT_CONNECT, conf.t1Timer)) break;
}
- } else gotprimary = true;
+ } else {
+ if (!atCmd(rhCmd, AT_CONNECT, conf.t1Timer)) break;
+ }
}
}
- } else {
- gotprimary = false;
- if (!useV34) {
- if (wasTimeout()) {
- abortReceive();
- break;
- }
- if (lastResponse == AT_NOCARRIER || lastResponse == AT_ERROR ||
- !atCmd(rhCmd, AT_CONNECT, conf.t1Timer)) break;
+ }
+ if (!gotprimary && !sendERR && !(retryrmcmd && rmattempted+1 < 2)) {
+ if (emsg == "") {
+ if (useV34) emsg = "Failed to properly open V.34 primary channel. {E114}";
+ else emsg = "Failed to properly detect high-speed data carrier. {E112}";
}
+ protoTrace(emsg);
+ abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
+ return (false);
}
}
- if (!gotprimary && !sendERR) {
- if (emsg == "") {
- if (useV34) emsg = "Failed to properly open V.34 primary channel. {E114}";
- else emsg = "Failed to properly detect high-speed data carrier. {E112}";
- }
+ if (gotEOT) { // intentionally not an else of the previous if
+ if (useV34 && emsg == "") emsg = "Received premature V.34 termination. {E115}";
protoTrace(emsg);
abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
return (false);
}
}
- if (gotEOT) { // intentionally not an else of the previous if
- if (useV34 && emsg == "") emsg = "Received premature V.34 termination. {E115}";
- protoTrace(emsg);
- abortPageECMRecv(tif, params, block, fcount, seq, pagedataseen, emsg);
- return (false);
- }
- }
+ } while (retryrmcmd && ++rmattempted < 2);
/*
* Buffering and flow control must be done after AT+FRM=n.
* We do not flush in order avoid losing data already buffered.
@@ -1447,7 +1513,11 @@
rcpcnt++;
} else {
dataseen = true;
- protoTrace("HDLC frame with bad FCF %#x", frame[2]);
+ if (frame.getLength() > 4 && frame.checkCRC()) {
+ traceFCF("Invalid and confusing placement of", frame.getFCF());
+ } else {
+ protoTrace("HDLC frame with bad FCF %#x", frame[2]);
+ }
}
} else {
dataseen = true; // assume that garbage was meant to be data
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/Class1Send.c++ new/hylafax-5.5.8/faxd/Class1Send.c++
--- old/hylafax-5.5.7/faxd/Class1Send.c++ 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/Class1Send.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -305,7 +305,7 @@
*/
FaxSendStatus
Class1Modem::sendPhaseB(TIFF* tif, Class2Params& next, FaxMachineInfo& info,
- fxStr& pph, fxStr& emsg, u_int& batched, u_short& npages)
+ fxStr& pph, fxStr& emsg, u_int& batched)
{
int ntrys = 0; // # retraining/command repeats
bool morePages = true; // more pages still to send
@@ -457,7 +457,6 @@
/* fall thru... */
case FCF_MCF: // ack confirmation
case FCF_PIP: // ack, w/ operator intervention
- npages++;
countPage(); // bump page count
notifyPageSent(tif); // update server
if (pph[4] == 'Z')
@@ -521,7 +520,6 @@
// ignore error and try to send next page
// after retraining
params.br = (u_int) -1; // force retraining above
- npages++;
countPage(); // bump page count
notifyPageSent(tif); // update server
if (pph[4] == 'Z')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/Class2.h new/hylafax-5.5.8/faxd/Class2.h
--- old/hylafax-5.5.7/faxd/Class2.h 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/Class2.h 2016-02-06 22:32:30.000000000 +0100
@@ -143,7 +143,7 @@
CallStatus dialResponse(fxStr& emsg);
FaxSendStatus getPrologue(Class2Params&, bool&, fxStr&, u_int&);
FaxSendStatus sendPhaseB(TIFF* tif, Class2Params&, FaxMachineInfo&,
- fxStr& pph, fxStr& emsg, u_int& batched, u_short& npages);
+ fxStr& pph, fxStr& emsg, u_int& batched);
void sendAbort();
void getDataStats(FaxSetup* setupinfo);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/Class2Send.c++ new/hylafax-5.5.8/faxd/Class2Send.c++
--- old/hylafax-5.5.7/faxd/Class2Send.c++ 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/Class2Send.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -248,7 +248,7 @@
*/
FaxSendStatus
Class2Modem::sendPhaseB(TIFF* tif, Class2Params& next, FaxMachineInfo& info,
- fxStr& pph, fxStr& emsg, u_int& batched, u_short& npages)
+ fxStr& pph, fxStr& emsg, u_int& batched)
{
int ntrys = 0; // # retraining/command repeats
u_int ppm, previousppm = 0;
@@ -298,7 +298,6 @@
case PPR_PIP: // page good, interrupt requested
case PPR_RTP: // page good, retrain requested
ignore:
- npages++;
countPage(); // bump page count
notifyPageSent(tif);// update server
if (pph[4] == 'Z')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/FaxModem.h new/hylafax-5.5.8/faxd/FaxModem.h
--- old/hylafax-5.5.7/faxd/FaxModem.h 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/FaxModem.h 2016-02-06 22:32:30.000000000 +0100
@@ -266,7 +266,7 @@
bool& hasDoc, fxStr& emsg, u_int& batched) = 0;
virtual void sendSetupPhaseB(const fxStr& pwd, const fxStr& sub);
virtual FaxSendStatus sendPhaseB(TIFF*, Class2Params&, FaxMachineInfo&,
- fxStr& pph, fxStr& emsg, u_int& batched, u_short& npages) = 0;
+ fxStr& pph, fxStr& emsg, u_int& batched) = 0;
virtual void sendEnd();
virtual void sendAbort() = 0;
// query interfaces for optional state
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/FaxSend.c++ new/hylafax-5.5.8/faxd/FaxSend.c++
--- old/hylafax-5.5.7/faxd/FaxSend.c++ 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/FaxSend.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -558,7 +558,7 @@
*/
u_int prevPages = fax.npages;
fax.status = modem->sendPhaseB(tif, clientParams, clientInfo,
- fax.pagehandling, fax.notice, batched, fax.npages);
+ fax.pagehandling, fax.notice, batched);
modem->getDataStats(&setupinfo);
clientInfo.setDataSent2(clientInfo.getDataSent1());
clientInfo.setDataSent1(clientInfo.getDataSent());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/ModemServer.h new/hylafax-5.5.8/faxd/ModemServer.h
--- old/hylafax-5.5.7/faxd/ModemServer.h 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/ModemServer.h 2016-02-06 22:32:30.000000000 +0100
@@ -89,7 +89,21 @@
int gotByte; // byte held for bit destruction
bool sawBlockEnd; // whether DLE+ETX has been seen
bool inputBuffered; // whether or not modem input is buffered
- u_char rcvBuf[1024]; // receive buffering
+
+/*
+ * Since the very first HylaFAX (before it was even named such) rcvBuf
+ * was always 1024 bytes. However, since we usually read from modemFd without
+ * O_NONBLOCK, attempting to read 1024 bytes from modemFd would introduce
+ * small (~100ms) delays as the read operation would not return as long
+ * as the device's write operation was occuring and the 1024 byte buffer
+ * was not yet filled. These delays can really impact fax operations because
+ * they are longer than most fax-spec tolerances. So, we now only use
+ * rcvBuf of 1 byte - and that resolves the short read blocking issue. The
+ * downside is that the ModemIO tracing is "wordy" with this (using one
+ * whole line of logging per-byte). The other upside, though, is that the
+ * timestamps on the session logging are accurate to the millisecond.
+ */
+ u_char rcvBuf[1]; // receive buffering
friend class ClassModem;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/faxd/faxGettyApp.c++ new/hylafax-5.5.8/faxd/faxGettyApp.c++
--- old/hylafax-5.5.7/faxd/faxGettyApp.c++ 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/faxd/faxGettyApp.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -380,6 +380,7 @@
ai.owner = "";
FaxMachineInfo info;
+ info.resetConfig();
if (callingnumber.length()) {
info.updateConfig(canonicalizePhoneNumber(callingnumber));
// if updateConfig returns false it's probably because the info file doesn't exist, no need to raise alarms
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/hfaxd/Login.c++ new/hylafax-5.5.8/hfaxd/Login.c++
--- old/hylafax-5.5.7/hfaxd/Login.c++ 2015-12-28 17:26:09.000000000 +0100
+++ new/hylafax-5.5.8/hfaxd/Login.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -189,12 +189,22 @@
goto cleanup;
}
- if (!ldapBaseDN || !ldapBaseDN[0]){
-// FIXME: Should we leak this error message to an unathenticated client?
+// FIXME: Should we leak these error message to an unathenticated client?
+ if (ldapBaseDN.length() == 0){
reply(530, "LDAP misconfigured (ldapBaseDN)");
goto cleanup;
}
+ if (ldapReqGroup.length() == 0){
+ reply(530, "LDAP misconfigured (ldapReqGroup)");
+ goto cleanup;
+ }
+
+ if (ldapVersion < 2){
+ reply(530, "LDAP misconfigured (ldapVersion)");
+ goto cleanup;
+ }
+
// Avoid NULL pointers, empty strings, incomplete LDAP configs.
if (!user || !strlen(user) || !pass) {
goto cleanup;
@@ -289,6 +299,7 @@
* Check each value to see if it matches
* our desired value specifed in the config
*/
+ i = 0;
while (p_arr_values[i] != NULL) {
if (strcmp(ldapReqGroup, p_arr_values[i]->bv_val) == 0) {
bValidUser = true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/util/SNPPJob.c++ new/hylafax-5.5.8/util/SNPPJob.c++
--- old/hylafax-5.5.7/util/SNPPJob.c++ 2015-12-28 17:26:08.000000000 +0100
+++ new/hylafax-5.5.8/util/SNPPJob.c++ 2016-02-06 22:32:30.000000000 +0100
@@ -25,6 +25,7 @@
*/
#include "config.h"
#include "Sys.h"
+#include "Socket.h"
#include