]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Add passive support into libfaxutil for all client programs.
authorAidan Van Dyk <aidan@ifax.com>
Mon, 26 Nov 2007 14:03:29 +0000 (14:03 +0000)
committerAidan Van Dyk <aidan@ifax.com>
Mon, 26 Nov 2007 14:03:29 +0000 (14:03 +0000)
This is based on :
| commit aee4d63ae667f7e60b0013419a35b109883787d0
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Thu Nov 1 05:00:32 2007 +0000
|
|     This adds PassiveMode hfaxd support for all of the client programs.  It is
|     enabled in hyla.conf.  There may be some lingering issues yet to discover,
|     but this works for the testing that I've done.

and
| commit 055ae429731f64f240b885489353df882840312d
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Wed Nov 21 06:04:10 2007 +0000
|
|     JPR reports that this is apparently needed for SCO to build.

man/faxalter.1
man/faxrm.1
man/faxstat.1
man/sendfax.1
util/FaxClient.c++
util/FaxClient.h
util/InetTransport.c++
util/SNPPClient.c++
util/SNPPClient.h

index dba899821f0b009b6651f4aa32d2ed0ee2c7b888..f2bfe21429d3cf9d7d5cf3ae849357e5bc813b1c 100644 (file)
@@ -180,6 +180,7 @@ The following configuration parameters are recognized:
 .ta \w'AutoCoverPage    'u +\w'boolean    'u +\w'\s-1\fIsee below\fP\s+1    'u
 \fBTag Type    Default Description\fP
 Host   string  \s-1localhost\s+1       host to contact for service
+PassiveMode    boolean \s-1false\s+1   whether or not to use passive mode
 Port   integer \s-14559\s+1    port to use in contacting server
 Protocol       string  \s-1tcp\s+1     protocol to use in contacting server
 Verbose        boolean \s-1No\s+1      whether or not to enable protocol tracing
@@ -193,6 +194,9 @@ The host to contact for service.
 .B \-h
 option.)
 .TP 10
+.B PassiveMode
+Whether or not to use passive mode in communication with the server.
+.TP 10
 .B Port
 The network port to contact for service.
 (Equivalent to the
index 4761daeff6605d4dd3cc7e1ee8a42822d942fd6f..7b24b9a87a725e8619dd9fad01377aa9cf0f4e9c 100644 (file)
@@ -130,6 +130,7 @@ The following configuration parameters are recognized:
 .ta \w'AutoConverPage    'u +\w'boolean    'u +\w'\s-1\fIsee below\fP\s+1    'u
 \fBTag Type    Default Description\fP
 Host   string  \s-1localhost\s+1       host to contact for service
+PassiveMode    boolean \s-1false\s+1   whether or not to use passive mode
 Port   integer \s-14559\s+1    port to use in contacting server
 Protocol       string  \s-1tcp\s+1     protocol to use in contacting server
 Verbose        boolean \s-1No\s+1      whether or not to enable protocol tracing
@@ -143,6 +144,9 @@ The host to contact for service.
 .B \-h
 option.)
 .TP 10
+.B PassiveMode
+Whether or not to use passive mode in communication with the server.
+.TP 10
 .B Port
 The network port to contact for service.
 (Equivalent to the
index 15095960c5dd4a25b94aed0f7eb286ce880ab9cc..facbd44de73161a554ae9f6dec2ca930b9076b63 100644 (file)
@@ -188,6 +188,7 @@ FileFmt     string  \s-1\fIsee below\fP\s+1 format string for file status results
 Host   string  \s-1localhost\s+1       host to contact for service
 JobFmt string  \s-1\fIsee below\fP\s+1 format string for job status results
 ModemFmt       string  \s-1\fIsee below\fP\s+1 format string for modem status results
+PassiveMode    boolean \s-1false\s+1   whether or not to use passive mode
 Port   integer \s-14559\s+1    port to use in contacting server
 Protocol       string  \s-1tcp\s+1     protocol to use in contacting server
 RcvFmt string  \s-1\fIsee below\fP\s+1 format string for received facsimile status results
@@ -400,6 +401,9 @@ t   Server and session tracing levels (xxxxx:yyyyy)
 v      Modem speaker volume as one-character symbol
 z      A ``*'' if a \fIfaxgetty\fP\|(${MANNUM1_8}) process is running; otherwise `` '' (space)
 .fi
+.TP 10
+.B PassiveMode
+Whether or not to use passive mode in communication with the server.
 .TP 14
 .B Port
 The network port to contact for service.
index 57a2fa069cb862bff7b0d63bf0583062569546ee..d17ef55fc56873d0ef256e73f6e1a5860b3b59cf 100644 (file)
@@ -726,6 +726,7 @@ PageChop    string  \s-1default\s+1 control page chop handling
 PageLength     float   \-      page length in millimeters
 PageSize       string  \s-1default\s+1 page size by name
 PageWidth      float   \-      page width in millimeters
+PassiveMode    boolean \s-1false\s+1   whether or not to use passive mode
 Port   integer \s-14559\s+1    port to use in contacting server
 Priority       string  \s-1default\s+1 job scheduling priority
 Protocol       string  \s-1tcp\s+1     protocol to use in contacting server
@@ -918,6 +919,9 @@ option.)
 .B PageWidth
 Set the transmitted page width in millimeters.
 .TP 16
+.B PassiveMode
+Whether or not to use passive mode in communication with the server.
+.TP 16
 .B Port
 The network port to contact for service.
 (Equivalent to the
index cd156306b5f945c15d6b72d38ff7a971c643ed54..bad6b99fccf4261666defb9e0aeffa8a907756db 100644 (file)
@@ -64,6 +64,7 @@ FaxClient::init()
     fdOut = NULL;
     fdData = -1;
     state = 0;
+    pasv = false;
 
     setupConfig();
 }
@@ -295,6 +296,8 @@ FaxClient::setConfigItem(const char* tag, const char* value)
        setModemStatusFormat(value);
     } else if (streq(tag, "filefmt")) {
        setFileStatusFormat(value);
+    } else if (streq(tag, "passivemode")) {
+       pasv = getBoolean(value);
     } else
        return (false);
     return (true);
index df919a01abb9b46b945f30d77810a052be1ca04d..3fff1574be0ab3bd7ebc97b3c0eb1144b8194a9d 100644 (file)
@@ -111,6 +111,7 @@ private:
     int                fdData;         // data transfer connection
     char       buf[1024];      // input buffer
     int                code;           // code from last server repsonse
+    bool       pasv;           // use of passive mode
     fxStr      proto;          // protocol to use for service query
     fxStr      lastResponse;   // text message from last server response
     fxStr      lastContinuation; // continuation message from last server response
@@ -189,6 +190,7 @@ public:
     virtual bool callServer(fxStr& emsg);
     virtual bool hangupServer(void);
     bool isConnected(void) const;
+    bool isPassive(void) const;
     bool login(const char* user, fxStr& emsg);
     bool admin(const char* pass, fxStr& emsg);
     virtual const char* getPasswd(const char* prompt);
@@ -328,6 +330,7 @@ inline int FaxClient::getLastCode(void) const               { return code; }
 inline bool FaxClient::isLoggedIn(void) const
     { return (state&FS_LOGGEDIN) != 0; }
 inline bool FaxClient::isConnected(void) const { return fdIn != NULL; }
+inline bool FaxClient::isPassive(void) const   { return pasv; }
 inline u_int FaxClient::getType(void) const            { return type; }
 inline u_int FaxClient::getStruct(void) const          { return stru; }
 inline u_int FaxClient::getMode(void) const            { return mode; }
index 9a5328c6ce442f2b003ed22d0d55cdc4ada52d3c..0ee794a239d2f28734d497930b4661ada14d6fee 100644 (file)
@@ -147,37 +147,65 @@ InetTransport::initDataConn(fxStr& emsg)
 {
     struct sockaddr_in data_addr;
     socklen_t dlen = sizeof (data_addr);
-    if (Socket::getsockname(fileno(client.getCtrlFd()), &data_addr, &dlen) < 0) {
-       emsg = fxStr::format("getsockname(ctrl): %s", strerror(errno));
-       return (false);
+    if (client.isPassive()) {
+       if (client.command("PASV") != FaxClient::COMPLETE)
+           return (false);
+       const char *cp = strchr(client.getLastResponse(), '(');
+       if (!cp) return (false);
+       cp++;
+       unsigned int v[6];
+       int n = sscanf(cp, "%u,%u,%u,%u,%u,%u", &v[2],&v[3],&v[4],&v[5],&v[0],&v[1]);
+       if (n != 6) return (false);
+       if (!inet_aton(fxStr::format("%u.%u.%u.%u", v[2],v[3],v[4],v[5]), &data_addr.sin_addr)) {
+           return (false);
+       }
+       data_addr.sin_port = htons((v[0]<<8)+v[1]);
+       data_addr.sin_family = AF_INET;
+    } else {
+       if (Socket::getsockname(fileno(client.getCtrlFd()), &data_addr, &dlen) < 0) {
+           emsg = fxStr::format("getsockname(ctrl): %s", strerror(errno));
+           return (false);
+       }
+       data_addr.sin_port = 0;         // let system allocate port
     }
-    data_addr.sin_port = 0;            // let system allocate port
     int fd = socket(AF_INET, SOCK_STREAM, 0);
     if (fd < 0) {
        emsg = fxStr::format("socket: %s", strerror(errno));
        return (false);
     }
-    if (Socket::bind(fd, &data_addr, sizeof (data_addr)) < 0) {
-       emsg = fxStr::format("bind: %s", strerror(errno));
-       goto bad;
-    }
-    dlen = sizeof (data_addr);
-    if (Socket::getsockname(fd, &data_addr, &dlen) < 0) {
-       emsg = fxStr::format("getsockname: %s", strerror(errno));
-       goto bad;
-    }
-    if (listen(fd, 1) < 0) {
-       emsg = fxStr::format("listen: %s", strerror(errno));
-       goto bad;
-    }
-    const char* a; a = (const char*) &data_addr.sin_addr;      // XXX for __GNUC__
-    const char* p; p = (const char*) &data_addr.sin_port;      // XXX for __GNUC__
+    if (client.isPassive()) {
+       if (Socket::connect(fd, &data_addr, sizeof (data_addr)) >= 0) {
+           if (client.getVerbose())
+               client.traceServer("Connected to %s at port %u.",
+               inet_ntoa(data_addr.sin_addr), ntohs(data_addr.sin_port));
+       } else {
+           emsg = fxStr::format("Can not reach server at %s at port %u (%s).",
+               inet_ntoa(data_addr.sin_addr), ntohs(data_addr.sin_port), strerror(errno));
+           goto bad;
+       }
+    } else {
+       if (Socket::bind(fd, &data_addr, sizeof (data_addr)) < 0) {
+           emsg = fxStr::format("bind: %s", strerror(errno));
+           goto bad;
+       }
+       dlen = sizeof (data_addr);
+       if (Socket::getsockname(fd, &data_addr, &dlen) < 0) {
+           emsg = fxStr::format("getsockname: %s", strerror(errno));
+           goto bad;
+       }
+       if (listen(fd, 1) < 0) {
+           emsg = fxStr::format("listen: %s", strerror(errno));
+           goto bad;
+       }
+       const char* a; a = (const char*) &data_addr.sin_addr;   // XXX for __GNUC__
+       const char* p; p = (const char*) &data_addr.sin_port;   // XXX for __GNUC__
 #define UC(b) (((int) b) & 0xff)
-    if (client.command("PORT %u,%u,%u,%u,%u,%u",
-       UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
-       UC(p[0]), UC(p[1])) != FaxClient::COMPLETE)
-       return (false);
+       if (client.command("PORT %u,%u,%u,%u,%u,%u",
+           UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
+           UC(p[0]), UC(p[1])) != FaxClient::COMPLETE)
+           return (false);
 #undef UC
+    }
     client.setDataFd(fd);
     return (true);
 bad:
@@ -188,6 +216,9 @@ bad:
 bool
 InetTransport::openDataConn(fxStr& emsg)
 {
+    if (client.isPassive()) {
+       return (client.getDataFd() > 0);
+    }
     int s = Socket::accept(client.getDataFd(), NULL, NULL);
     if (s >= 0) {
        client.setDataFd(s);
index 6fc3c44a853dccdd7ecf2dac042c00614991c852..aadc336b41ec9c112f62413aa9a31b93122a46ce 100644 (file)
@@ -58,6 +58,7 @@ SNPPClient::init()
     fdOut = NULL;
     state = 0;
     msg = NULL;
+    pasv = false;
 
     setupConfig();
 }
@@ -394,6 +395,8 @@ SNPPClient::setConfigItem(const char* tag, const char* value)
        jproto.setServiceLevel(getNumber(value));
     } else if (streq(tag, "mailaddr")) {
        jproto.setMailbox(value);
+    } else if (streq(tag, "passivemode")) {
+       pasv = getBoolean(value);
     } else
        return (false);
     return (true);
index ce2e272581a6f4da817a6569cbb964fa5482236f..30de0f01d02a5f04fbc1177b1fbea0dc7ba14338 100644 (file)
@@ -70,6 +70,7 @@ private:
     FILE*      fdOut;          // control stream output handle
     char       buf[1024];      // input buffer
     int                code;           // code from last server repsonse
+    bool       pasv;           // whether or not to use passive mode
     fxStr      proto;          // protocol to use for service query
     fxStr      lastResponse;   // text message from last server response
     u_int      port;           // server port to connect to