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 - [email protected] + +- 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 <ctype.h> #include <string.h> @@ -95,7 +96,7 @@ char hostname[64]; (void) gethostname(hostname, sizeof (hostname)); #if CONFIG_INETTRANSPORT - struct hostent* hp = gethostbyname(hostname); + struct hostent* hp = Socket::gethostbyname(hostname); domainName = (hp ? hp->h_name : hostname); #else domainName = hostname; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/util/SendFaxClient.c++ new/hylafax-5.5.8/util/SendFaxClient.c++ --- old/hylafax-5.5.7/util/SendFaxClient.c++ 2015-12-28 17:26:08.000000000 +0100 +++ new/hylafax-5.5.8/util/SendFaxClient.c++ 2016-02-06 22:32:30.000000000 +0100 @@ -664,7 +664,7 @@ if (info.rule->getCmd() != "") { // conversion required const char* templ = _PATH_TMP "sndfaxXXXXXX"; char* buff = strcpy(new char[strlen(templ) + 1], templ); - Sys::mktemp(buff); + Sys::mkstemp(buff); tmpFile = buff; delete [] buff; /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/util/SendFaxJob.c++ new/hylafax-5.5.8/util/SendFaxJob.c++ --- old/hylafax-5.5.7/util/SendFaxJob.c++ 2015-12-28 17:26:08.000000000 +0100 +++ new/hylafax-5.5.8/util/SendFaxJob.c++ 2016-02-06 22:32:30.000000000 +0100 @@ -25,6 +25,7 @@ */ #include "config.h" #include "Sys.h" +#include "Socket.h" #include <ctype.h> #include <string.h> @@ -264,7 +265,7 @@ char hostname[64]; (void) gethostname(hostname, sizeof (hostname)); #if CONFIG_INETTRANSPORT - struct hostent* hp = gethostbyname(hostname); + struct hostent* hp = Socket::gethostbyname(hostname); domainName = (hp ? hp->h_name : hostname); #else domainName = hostname; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/util/Sys.h new/hylafax-5.5.8/util/Sys.h --- old/hylafax-5.5.7/util/Sys.h 2015-12-28 17:26:08.000000000 +0100 +++ new/hylafax-5.5.8/util/Sys.h 2016-02-06 22:32:30.000000000 +0100 @@ -123,8 +123,6 @@ static int gethostname(char* name, int namelen) { return ::gethostname(name, namelen); } - static char* mktemp(char* templ) { return ::mktemp(templ); } - static int mkstemp(char* templ) { int fd = ::mkstemp(templ); #if defined __GLIBC__ && __GLIBC__ <= 2 && __GLIBC_MINOR__ <= 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hylafax-5.5.7/util/dictionary.sh.in new/hylafax-5.5.8/util/dictionary.sh.in --- old/hylafax-5.5.7/util/dictionary.sh.in 2015-12-28 17:26:08.000000000 +0100 +++ new/hylafax-5.5.8/util/dictionary.sh.in 2016-02-06 22:32:30.000000000 +0100 @@ -46,6 +46,9 @@ uk_*) . bin/dict/uk ;; + he_*) + . bin/dict/he + ;; *) . bin/dict/en ;;
