]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Bug 503: add DynamicLocalID configuration option to allow for dynamic
authorLee Howard <faxguy@howardsilvan.com>
Fri, 18 Jun 2004 03:55:46 +0000 (03:55 +0000)
committerLee Howard <faxguy@howardsilvan.com>
Fri, 18 Jun 2004 03:55:46 +0000 (03:55 +0000)
         configuration of CSI.

faxd/Class1.c++
faxd/Class1.h
faxd/Class2.c++
faxd/Class2.h
faxd/FaxModem.h
faxd/FaxServer.c++
faxd/FaxServer.h
faxd/faxGettyApp.c++
faxd/faxGettyApp.h
man/hylafax-config.4f

index 436f22f004919749cd0df0e1627ae9cab9c0ff51..7204804ce5802d1cbc8e8d95f449982dfaf8b1c3 100644 (file)
@@ -324,7 +324,7 @@ Class1Modem::ready(long ms)
  * Set the local subscriber identification.
  */
 void
-Class1Modem::setLID(const fxStr& number)
+Class1Modem::setLID(const fxStr& number, bool now)
 {
     encodeTSI(lid, number);
 }
index 716c3a08a92291319b6159fc31f7b5521e1084f3..7ef4bd977b5e9dfa237e84bdf7c0793d464bf12a 100644 (file)
@@ -222,7 +222,7 @@ public:
     bool       faxService(bool enableV34);     // switch to fax mode
     bool       reset(long ms);                 // reset modem
     bool       ready(long ms);                 // ready modem
-    void       setLID(const fxStr& number);    // set local id string
+    void       setLID(const fxStr& number, bool now = false);  // set local id string
     bool       supportsPolling() const;        // modem capability
 };
 #endif /* _CLASS1_ */
index ae20aca96db21842664d544059af19b0c6cb98d5..8c32d568f5bec20a00940ac0e7db41aa8468d45f 100644 (file)
@@ -499,7 +499,7 @@ Class2Modem::stripQuotes(const char* cp)
  * length is 20 characters (per the spec).
  */
 void
-Class2Modem::setLID(const fxStr& number)
+Class2Modem::setLID(const fxStr& number, bool now)
 {
     lid.resize(0);
     for (u_int i = 0, n = number.length(); i < n; i++) {
@@ -509,6 +509,7 @@ Class2Modem::setLID(const fxStr& number)
     }
     if (lid.length() > 20)
        lid.resize(20);
+    if (now) class2Cmd(lidCmd, lid);   // for DynamicLocalID
 }
 
 /* 
index 20fc3acac1d37a3b315667cd542b91fb4fdf3dc8..216948e2e8943a72e1552c3a715444839cfdedf7 100644 (file)
@@ -159,7 +159,7 @@ public:
 // miscellaneous
     bool       faxService(bool enableV34);     // switch to fax mode
     bool       reset(long ms);                 // reset modem
-    void       setLID(const fxStr& number);    // set local id string
+    void       setLID(const fxStr& number, bool now = false);  // set local id string
     bool       supportsPolling() const;        // modem capability
     int                lastByte;
 };
index cef4feefef5facad830b07dc0ce9a31fa98a65a7..76ad9548a584559e25c38bccb9cb42de71867baf 100644 (file)
@@ -171,7 +171,7 @@ public:
     bool isFaxModem() const;
 
 // configuration controls
-    virtual void setLID(const fxStr& number) = 0;
+    virtual void setLID(const fxStr& number, bool now = false) = 0;
     u_int getCapabilities() const;
 // methods for querying modem capabilities
     virtual bool supports2D() const;
index 869af4ddace2e69ad591163b98893593e4aa9a67..a85fae1e2f5fe94281c417b82f894bd5813eccb5 100644 (file)
@@ -254,10 +254,10 @@ FaxServer::readConfig(const fxStr& filename)
  * modem (e.g. for Class 2-style modems).
  */
 void
-FaxServer::setLocalIdentifier(const fxStr& lid)
+FaxServer::setLocalIdentifier(const fxStr& lid, bool now)
 {
     ServerConfig::setLocalIdentifier(lid);
     if (modem)
-       modem->setLID(lid);
+       modem->setLID(lid, now);
 }
 const fxStr& FaxServer::getLocalIdentifier() const { return (localIdentifier); }
index d293b05779380bb8961e53e14bd353d3f2776684..6e49abab350b1776d659600a0d23d5920dc8ab3b 100644 (file)
@@ -88,7 +88,7 @@ protected:
     fxStr      getModemCapabilities() const;
 
     void       readConfig(const fxStr& filename);
-    void       setLocalIdentifier(const fxStr& lid);
+    void       setLocalIdentifier(const fxStr& lid, bool now = false);
 
     void       sendFax(FaxRequest&, FaxMachineInfo&, FaxAcctInfo&, u_int&);
     bool       recvFax(const CallerID& cid);
index d6982e7f5975b5615c8f8ac90a0d563b484d38a3..29a294ed1342cba7e6cde3fab53c9f6d35a19926 100644 (file)
@@ -315,43 +315,76 @@ faxGettyApp::answerPhone(AnswerType atype, CallType ctype, const CallerID& cid,
        traceServer("ANSWER: CID REJECTED");
        callResolved = false;
        advanceRotary = false;
-    } else if (ctype != ClassModem::CALLTYPE_UNKNOWN) {
-       /*
-        * Distinctive ring or other means has already identified
-        * the type of call.  If we're to answer the call in a
-        * different way, then treat this as an error and don't
-        * answer the phone.  Otherwise answer according to the
-        * deduced call type.
-        */
-       if (atype != ClassModem::ANSTYPE_ANY && ctype != atype) {
-           traceServer("ANSWER: Call deduced as %s,"
-                "but told to answer as %s; call ignored",
-                ClassModem::callTypes[ctype],
-                ClassModem::answerTypes[atype]);
-           callResolved = false;
-           advanceRotary = false;
+    } else {
+       if (dynamicLocalId.length()) {
+           fxStr cmd(dynamicLocalId | quote | cid.name | enquote | 
+               quote | cid.number | enquote | quote | getModemDevice() | enquote);
+           fxStr localid = "";
+           int pipefd[2], idlength, status;
+           char dlid[21];      // max CSI size (20) plus '\0'
+           pipe(pipefd);
+           pid_t pid = fork();
+           switch (pid) {
+               case -1:
+                   logError("Could not fork for local ID.");
+                   break;
+               case  0:
+                   dup2(pipefd[1], STDOUT_FILENO);
+                   Sys::close(pipefd[0]);
+                   Sys::close(pipefd[1]);
+                   execl("/bin/sh", "sh", "-c", (const char*) cmd, (char*) NULL);
+                   sleep(1);
+                   exit(0);
+               default:
+                   Sys::close(pipefd[1]);
+                   idlength = Sys::read(pipefd[0], dlid, sizeof(dlid));
+                   Sys::waitpid(pid, status);
+                   if (status != 0)
+                       logError("Bad exit status %#o for \'%s\'", status, (const char*) cmd);
+                   localid = fxStr(dlid, idlength-1);
+                   FaxServer::setLocalIdentifier(localid, true);       // Class 2 must issue command
+                   break;
+           }
+           traceServer("ANSWER: LOCAL ID '%s'", (const char*) localid);
+       }
+       if (ctype != ClassModem::CALLTYPE_UNKNOWN) {
+           /*
+            * Distinctive ring or other means has already identified
+            * the type of call.  If we're to answer the call in a
+            * different way, then treat this as an error and don't
+            * answer the phone.  Otherwise answer according to the
+            * deduced call type.
+            */
+           if (atype != ClassModem::ANSTYPE_ANY && ctype != atype) {
+               traceServer("ANSWER: Call deduced as %s,"
+                    "but told to answer as %s; call ignored",
+                    ClassModem::callTypes[ctype],
+                    ClassModem::answerTypes[atype]);
+               callResolved = false;
+               advanceRotary = false;
+           } else {
+               // NB: answer based on ctype, not atype
+               ctype = modemAnswerCall(ctype, emsg, dialnumber);
+               callResolved = processCall(ctype, emsg, cid);
+           }
+       } else if (atype == ClassModem::ANSTYPE_ANY) {
+           /*
+            * Normal operation; answer according to the settings
+            * for the rotary and adaptive answer capabilities.
+            */
+           int r = answerRotor;
+           do {
+               callResolved = answerCall(answerRotary[r], ctype, emsg, cid, dialnumber);
+               r = (r+1) % answerRotorSize;
+           } while (!callResolved && adaptiveAnswer && r != answerRotor);
        } else {
-           // NB: answer based on ctype, not atype
-           ctype = modemAnswerCall(ctype, emsg, dialnumber);
-           callResolved = processCall(ctype, emsg, cid);
+           /*
+            * Answer for a specific type of call but w/o
+            * any existing call type information such as
+            * distinctive ring.
+            */
+           callResolved = answerCall(atype, ctype, emsg, cid, dialnumber);
        }
-    } else if (atype == ClassModem::ANSTYPE_ANY) {
-       /*
-        * Normal operation; answer according to the settings
-        * for the rotary and adaptive answer capabilities.
-        */
-       int r = answerRotor;
-       do {
-           callResolved = answerCall(answerRotary[r], ctype, emsg, cid, dialnumber);
-           r = (r+1) % answerRotorSize;
-       } while (!callResolved && adaptiveAnswer && r != answerRotor);
-    } else {
-       /*
-        * Answer for a specific type of call but w/o
-        * any existing call type information such as
-        * distinctive ring.
-        */
-       callResolved = answerCall(atype, ctype, emsg, cid, dialnumber);
     }
     /*
      * Call resolved.  If we were able to recognize the call
@@ -882,6 +915,7 @@ faxGettyApp::stringtag faxGettyApp::strings[] = {
 { "vgettyargs",                &faxGettyApp::vgettyArgs },
 { "egettyargs",                &faxGettyApp::egettyArgs },
 { "faxrcvdcmd",                &faxGettyApp::faxRcvdCmd,       FAX_FAXRCVDCMD },
+{ "dynamiclocalid",    &faxGettyApp::dynamicLocalId },
 };
 faxGettyApp::numbertag faxGettyApp::numbers[] = {
 { "answerbias",                &faxGettyApp::answerBias,       (u_int) -1 },
index 69d9ac843da34aecc55b040a098acd61f956acda..e0b1b1e613323454e02dd2323e341e2a7f4b0a88 100644 (file)
@@ -84,6 +84,7 @@ private:
     u_short    answerRotorSize;        // rotor table size
     AnswerType answerRotary[3];        // rotary selection of answer types
     fxStr      faxRcvdCmd;             // fax received command
+    fxStr      dynamicLocalId;         // command to dynamically generate local id
     u_int      modemPriority;          // modem priority passed to faxq
 
     static faxGettyApp* _instance;
index 6fd71d33fa863ee25160f9d12959f143e45f52e4..732b1268c839cfcb56e1a74fbba4e2f441b88947 100644 (file)
@@ -131,6 +131,7 @@ CountryCode\(S2     string  \-      local country code
 DestControls\(S1       string  \-      per-destination controls file
 DeviceMode     octal   \s-10600\s+1    protection mode to use for modem device
 DialStringRules\(S2    string  \-      dial string rules file
+DynamicLocalID string  \-      script for dynamic configuration of local ID
 FAXNumber      string  \-      facsimile modem phone number
 FaxRcvdCmd     string  \s-1bin/faxrcvd\s+1     notification script for received facsimile
 GettyArgs      string  \-      arguments passed to getty program
@@ -638,6 +639,19 @@ The specified pathname must be relative to the top of the fax server's
 spooling area; e.g.
 .BR etc/dialrules .
 .TP
+.B DynamicLocalID
+The pathname of the optional shell script, e.g. ``etc/localid'', that replaces
+.B LocalIdentifier
+based on CIDName, CIDNumber, and device ID.  The script is passed those
+three values as the first, second, and third parameters ($1, $2, $3), 
+respectively when answering an incoming call.  The script can then 
+perform local processing as desired to send on standard output the 
+value with which to replace
+.B LocalIdentifier.
+This is commonly used to dynamically alter the local identification 
+of systems which use DID/DNIS. 
+Note that this script must be marked as executable by the faxgetty process.
+.TP
 .B FAXNumber
 The phone number associated with the facsimile modem.
 This string is used to generate the