Patch: EMI UUCP DLRs (final)

"Nikos Balkanas" <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <DA46FF7B42F74C9190614D3F3355A2B1@drwho>
Hi,

I believe I have accounted for almost all your comments to produce the final 
working patch. I have no way of testing, other than compilation.

This patch will povide:

1) Align dlr_oracle.c with the rest. Currently, Oracle does a full dst 
find/remove/update on each DLR.
2) Dst use on find/remove/update is controlled in dlr_find by a single 
variable, use_dst. This is currently set only at driver level and only in 
the emi driver, while everyone else has it false. However, very easily, if 
need arises, it can be set in smsc configuration.
3) All DLR handling for all smscs will remain as it used to be till now. 
Only emi handling changes, hopefully for the better (that is the purpose of 
the patch :-)).
4) It will try to match the last 7 digits of the destination or the length 
of the destination if it smaller. This is defined in gw/dlr_p.h as 
MIN_DST_LEN. Didn't want to make it larger, wanted to avoid prefix territory 
at all costs, since I have seen a lot of mangling there by the SMScs. 
Besides, I believe that 7 digits give enough resolution
5) People using emi, should rebuild their indeces, especially if they are 
running large batch jobs through EMI. The LIKE % construction is not very 
efficient.

Enjoy,
Nikos
kannel.diff (application/octet-stream, 37.6 KB)
Index: gw/dlr_mysql.c
===================================================================
--- gw/dlr_mysql.c	(revision 4833)
+++ gw/dlr_mysql.c	(working copy)
@@ -138,7 +138,7 @@
 
 static struct dlr_entry* dlr_mysql_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like = NULL;
     DBPoolConn *pconn;
     List *result = NULL, *row;
     struct dlr_entry *res = NULL;
@@ -148,26 +148,45 @@
     if (pconn == NULL) /* should not happens, but sure is sure */
         return NULL;
 
-    sql = octstr_format("SELECT `%S`, `%S`, `%S`, `%S`, `%S`, `%S` FROM `%S` WHERE `%S`=? AND `%S`=? LIMIT 1",
+    if (dst)
+       sql = octstr_format("SELECT `%S`, `%S`, `%S`, `%S`, `%S`, `%S` FROM `%S` WHERE `%S`=? AND `%S`=? AND `%S` LIKE ? LIMIT 1",
                         fields->field_mask, fields->field_serv,
                         fields->field_url, fields->field_src,
                         fields->field_dst, fields->field_boxc,
                         fields->table, fields->field_smsc,
+                        fields->field_ts, fields->field_dst);
+    else
+       sql = octstr_format("SELECT `%S`, `%S`, `%S`, `%S`, `%S`, `%S` FROM `%S` WHERE `%S`=? AND `%S`=? LIMIT 1",
+                        fields->field_mask, fields->field_serv,
+                        fields->field_url, fields->field_src,
+                        fields->field_dst, fields->field_boxc,
+                        fields->table, fields->field_smsc,
                         fields->field_ts);
 
     gwlist_append(binds, (Octstr *)smsc);
     gwlist_append(binds, (Octstr *)ts);
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       like = octstr_create(strcat("%", p));
+       gwlist_append(binds, like);
+    }
+
 #if defined(DLR_TRACE)
     debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
 
     if (dbpool_conn_select(pconn, sql, binds, &result) != 0) {
         octstr_destroy(sql);
+        if (like) octstr_destroy(like);
         dbpool_conn_produce(pconn);
         return NULL;
     }
     octstr_destroy(sql);
+    if (like) octstr_destroy(like);
     gwlist_destroy(binds, NULL);
     dbpool_conn_produce(pconn);
 
@@ -195,7 +214,7 @@
 
 static void dlr_mysql_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like = NULL;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -207,13 +226,27 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("DELETE FROM `%S` WHERE `%S`=? AND `%S`=? LIMIT 1",
+    if (dst)
+       sql = octstr_format("DELETE FROM `%S` WHERE `%S`=? AND `%S`=? AND `%S` LIKE ? LIMIT 1",
                         fields->table, fields->field_smsc,
+                        fields->field_ts, fields->field_dst);
+    else
+       sql = octstr_format("DELETE FROM `%S` WHERE `%S`=? AND `%S`=? LIMIT 1",
+                        fields->table, fields->field_smsc,
                         fields->field_ts);
 
     gwlist_append(binds, (Octstr *)smsc);
     gwlist_append(binds, (Octstr *)ts);
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       like = octstr_create(strcat("%", p));
+       gwlist_append(binds, like);
+    }
+
 #if defined(DLR_TRACE)
     debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -226,11 +259,12 @@
     dbpool_conn_produce(pconn);
     gwlist_destroy(binds, NULL);
     octstr_destroy(sql);
+    if (like) octstr_destroy(like);
 }
 
 static void dlr_mysql_update(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
 {
-    Octstr *sql, *os_status;
+    Octstr *sql, *os_status, *like = NULL;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -242,15 +276,30 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("UPDATE `%S` SET `%S`=? WHERE `%S`=? AND `%S`=? LIMIT 1",
+    if (dst)
+       sql = octstr_format("UPDATE `%S` SET `%S`=? WHERE `%S`=? AND `%S`=? AND `%S` LIKE ? LIMIT 1",
                         fields->table, fields->field_status,
+                        fields->field_smsc, fields->field_ts,
+                        fields->field_dst);
+    else
+       sql = octstr_format("UPDATE `%S` SET `%S`=? WHERE `%S`=? AND `%S`=? LIMIT 1",
+                        fields->table, fields->field_status,
                         fields->field_smsc, fields->field_ts);
 
     os_status = octstr_format("%d", status);
     gwlist_append(binds, (Octstr *)os_status);
     gwlist_append(binds, (Octstr *)smsc);
     gwlist_append(binds, (Octstr *)ts);
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       like = octstr_create(strcat("%", p));
+       gwlist_append(binds, like);
+    }
+
 #if defined(DLR_TRACE)
     debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -263,6 +312,7 @@
     gwlist_destroy(binds, NULL);
     octstr_destroy(os_status);
     octstr_destroy(sql);
+    if (like) octstr_destroy(like);
 }
 
 
@@ -446,4 +496,3 @@
     return NULL;
 }
 #endif /* HAVE_MYSQL */
-
Index: gw/dlr_oracle.c
===================================================================
--- gw/dlr_oracle.c	(revision 4833)
+++ gw/dlr_oracle.c	(working copy)
@@ -171,7 +171,7 @@
 
 static void dlr_remove_oracle(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like = NULL;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -183,14 +183,25 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("DELETE FROM %S WHERE %S=:1 AND %S=:2 AND %S=:3 AND ROWNUM < 2",
+    if (dst)
+       sql = octstr_format("DELETE FROM %S WHERE %S=:1 AND %S=:2 AND %S LIKE :3 AND ROWNUM < 2",
                         fields->table, fields->field_smsc,
                         fields->field_ts, fields->field_dst);
+    else sql = octstr_format("DELETE FROM %S WHERE %S=:1 AND %S=:2 AND ROWNUM < 2",
+                        fields->table, fields->field_smsc, fields->field_ts);
 
-    gwlist_append(binds, (Octstr *)smsc);      /* :1 */
-    gwlist_append(binds, (Octstr *)ts);        /* :2 */
-    gwlist_append(binds, (Octstr *)dst);       /* :3 */
+    gwlist_append(binds, (Octstr *)smsc);               /* :1 */
+    gwlist_append(binds, (Octstr *)ts);                 /* :2 */
+    if (dst){                                           /* :3 */
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       like = octstr_create(strcat("%", p));
+       gwlist_append(binds, like);
+    }
+
 #if defined(DLR_TRACE)
     debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -203,11 +214,12 @@
     dbpool_conn_produce(pconn);
     gwlist_destroy(binds, NULL);
     octstr_destroy(sql);
+    if (like) octstr_destroy(like);
 }
 
 static struct dlr_entry* dlr_get_oracle(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
-    Octstr *sql;
+    Octstr *sql, *like = NULL;
     DBPoolConn *pconn;
     List *result = NULL, *row;
     struct dlr_entry *res = NULL;
@@ -217,26 +229,44 @@
     if (pconn == NULL) /* should not happens, but sure is sure */
         return NULL;
 
-    sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S=:1 AND %S=:2 AND %S=:3 AND ROWNUM < 2",
+    if (dst)
+       sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S=:1 AND %S=:2 AND %S LIKE :3 AND ROWNUM < 2",
                         fields->field_mask, fields->field_serv,
                         fields->field_url, fields->field_src,
                         fields->field_dst, fields->field_boxc,
                         fields->table, fields->field_smsc,
                         fields->field_ts, fields->field_dst);
+    else
+       sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S=:1 AND %S=:2 AND ROWNUM < 2",
+                        fields->field_mask, fields->field_serv,
+                        fields->field_url, fields->field_src,
+                        fields->field_dst, fields->field_boxc,
+                        fields->table, fields->field_smsc,
+                        fields->field_ts);
 
-    gwlist_append(binds, (Octstr *)smsc);      /* :1 */
-    gwlist_append(binds, (Octstr *)ts);        /* :2 */
-    gwlist_append(binds, (Octstr *)dst);       /* :3 */
+    gwlist_append(binds, (Octstr *)smsc);               /* :1 */
+    gwlist_append(binds, (Octstr *)ts);                 /* :2 */
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       like = octstr_create(strcat("%", p));
+       gwlist_append(binds, like);
+    }
+
 #if defined(DLR_TRACE)
     debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
     if (dbpool_conn_select(pconn, sql, binds, &result) != 0) {
         octstr_destroy(sql);
+        if (like) octstr_destroy(like);
         dbpool_conn_produce(pconn);
         return NULL;
     }
     octstr_destroy(sql);
+    if (like) octstr_destroy(like);
     gwlist_destroy(binds, NULL);
     dbpool_conn_produce(pconn);
 
@@ -264,7 +294,7 @@
 
 static void dlr_update_oracle(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
 {
-    Octstr *sql, *os_status;
+    Octstr *sql, *os_status, *like = NULL;
     DBPoolConn *pconn;
     List *binds = gwlist_create();
     int res;
@@ -276,15 +306,28 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("UPDATE %S SET %S=:1 WHERE %S=:2 AND %S=:3 AND %S=:4 AND ROWNUM < 2",
+    if (dst)
+       sql = octstr_format("UPDATE %S SET %S=:1 WHERE %S=:2 AND %S=:3 AND %S LIKE :4 AND ROWNUM < 2",
                         fields->table, fields->field_status,
                         fields->field_smsc, fields->field_ts, fields->field_dst);
+    else sql = octstr_format("UPDATE %S SET %S=:1 WHERE %S=:2 AND %S=:3 AND ROWNUM < 2",
+                        fields->table, fields->field_status,
+                        fields->field_smsc, fields->field_ts);
 
     os_status = octstr_format("%d", status);
-    gwlist_append(binds, (Octstr *)os_status); /* :1 */
-    gwlist_append(binds, (Octstr *)smsc);      /* :2 */
-    gwlist_append(binds, (Octstr *)ts);        /* :3 */
-    gwlist_append(binds, (Octstr *)dst);       /* :4 */
+    gwlist_append(binds, (Octstr *)os_status);          /* :1 */
+    gwlist_append(binds, (Octstr *)smsc);               /* :2 */
+    gwlist_append(binds, (Octstr *)ts);                 /* :3 */
+    if (dst){                                           /* :4 */
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
+
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       like = octstr_create(strcat("%", p));
+       gwlist_append(binds, like);
+    }
+
 #if defined(DLR_TRACE)
     debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
@@ -297,6 +340,7 @@
     gwlist_destroy(binds, NULL);
     octstr_destroy(os_status);
     octstr_destroy(sql);
+    if (like) octstr_destroy(like);
 }
 
 static void dlr_flush_oracle (void)
Index: gw/dlr_pgsql.c
===================================================================
--- gw/dlr_pgsql.c	(revision 4833)
+++ gw/dlr_pgsql.c	(working copy)
@@ -168,14 +168,34 @@
     Octstr *sql;
     List *result, *row;
 
-    sql = octstr_format("SELECT \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\" FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1;",
-                        octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_serv),
-                        octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_src),
-                        octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_boxc),
-                        octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
-                        octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
 
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       sql = octstr_format("SELECT \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", "
+             "\"%s\" FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' AND \"%s\""
+             " LIKE '%%%s' LIMIT 1;", octstr_get_cstr(fields->field_mask),
+             octstr_get_cstr(fields->field_serv), octstr_get_cstr(fields->
+             field_url), octstr_get_cstr(fields->field_src), octstr_get_cstr
+             (fields->field_dst), octstr_get_cstr(fields->field_boxc),
+             octstr_get_cstr(fields->table), octstr_get_cstr(fields->
+             field_smsc), octstr_get_cstr(smsc), octstr_get_cstr(fields->
+             field_ts), octstr_get_cstr(ts), octstr_get_cstr(fields->
+             field_dst), p);
+    }
+    else
+       sql = octstr_format("SELECT \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", "
+             "\"%s\" FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1;",
+             octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->
+             field_serv), octstr_get_cstr(fields->field_url), octstr_get_cstr
+             (fields->field_src), octstr_get_cstr(fields->field_dst),
+             octstr_get_cstr(fields->field_boxc), octstr_get_cstr(fields->
+             table), octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
+             octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+
     result = pgsql_select(sql);
     octstr_destroy(sql);
 
@@ -221,12 +241,28 @@
     Octstr *sql;
 
     debug("dlr.pgsql", 0, "removing DLR from database");
-    sql = octstr_format("DELETE FROM \"%s\" WHERE oid = (SELECT oid FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1);",
-                        octstr_get_cstr(fields->table), octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_smsc),
-                        octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
 
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       sql = octstr_format("DELETE FROM \"%s\" WHERE oid = (SELECT oid FROM "
+             "\"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' AND \"%s\" LIKE '%%%s' "
+             "LIMIT 1);", octstr_get_cstr(fields->table), octstr_get_cstr
+             (fields->table), octstr_get_cstr(fields->field_smsc),
+             octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts),
+             octstr_get_cstr(ts), octstr_get_cstr(fields->field_dst), p);
+    }
+    else
+       sql = octstr_format("DELETE FROM \"%s\" WHERE oid = (SELECT oid FROM "
+             "\"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1);",
+             octstr_get_cstr(fields->table), octstr_get_cstr(fields->table),
+             octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
+             octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+
+
     if (!pgsql_update(sql))
        warning(0, "DLR: PGSQL: No dlr deleted for DST<%s>", octstr_get_cstr(dst));
     octstr_destroy(sql);
@@ -238,12 +274,28 @@
     Octstr *sql;
 
     debug("dlr.pgsql", 0, "updating DLR status in database");
-    sql = octstr_format("UPDATE \"%s\" SET \"%s\"=%d WHERE oid = (SELECT oid FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1);",
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_status), status,
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                        octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
+
+
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       sql = octstr_format("UPDATE \"%s\" SET \"%s\"=%d WHERE oid = (SELECT "
+           "oid FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' AND \"%s\" LIKE "
+           "'%%%s' LIMIT 1);", octstr_get_cstr(fields->table), octstr_get_cstr
+           (fields->field_status), status, octstr_get_cstr(fields->table),
+           octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
+           octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts),
+           octstr_get_cstr(fields->field_dst), p);
+    }
+    else
+       sql = octstr_format("UPDATE \"%s\" SET \"%s\"=%d WHERE oid = (SELECT "
+             "oid FROM \"%s\" WHERE \"%s\"='%s' AND \"%s\"='%s' LIMIT 1);",
+             octstr_get_cstr(fields->table), octstr_get_cstr(fields->
+             field_status), status, octstr_get_cstr(fields->table),
+             octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
+             octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
     if (!pgsql_update(sql))
        warning(0, "DLR: PGSQL: No dlr updated for DST<%s> (status: %d)", octstr_get_cstr(dst), status);
     octstr_destroy(sql);
Index: gw/dlr_mem.c
===================================================================
--- gw/dlr_mem.c	(revision 4833)
+++ gw/dlr_mem.c	(working copy)
@@ -125,9 +125,23 @@
     /* XXX: check destination addr too, because e.g. for UCP is not enough to check only
      *          smsc and timestamp (timestamp is even without milliseconds)
      */
-    if(octstr_compare(dlr->smsc,smsc) == 0 && octstr_compare(dlr->timestamp,ts) == 0)
-        return 0;
+    if (dst){
+       int size, len1 = octstr_len(dlr->destination), len2 = octstr_len(dst);
+       char *p1 = octstr_get_cstr(dlr->destination), *p2 = octstr_get_cstr(dst);
 
+       size = (len1 < MIN_DST_LEN)? len1: MIN_DST_LEN;
+       size = (len2 < size)? len2: size;
+
+       if (octstr_compare(dlr->smsc, smsc) == 0 && octstr_compare(dlr->
+           timestamp, ts) == 0 && memcmp(p1 + len1 - size, p2 + len2 - size,
+           size) == 0)
+           return 0;
+    }
+    else
+       if (octstr_compare(dlr->smsc, smsc) == 0 && octstr_compare(dlr->
+           timestamp, ts) == 0)
+           return 0;
+
     return 1;
 }
 
Index: gw/dlr_mssql.c
===================================================================
--- gw/dlr_mssql.c	(revision 4833)
+++ gw/dlr_mssql.c	(working copy)
@@ -172,10 +172,21 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("SET ROWCOUNT 1\n"
-            "DELETE FROM %S WHERE %S='%S' AND %S='%S'\n"
-            "SET ROWCOUNT 0",
-            fields->table, fields->field_smsc, smsc,
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
+
+
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       sql = octstr_format("SET ROWCOUNT 1\nDELETE FROM %S WHERE %S='%S' AND "
+            "%S='%S' AND %S LIKE '%%%s'\nSET ROWCOUNT 0", fields->table,
+            fields->field_smsc, smsc, fields->field_ts, ts, fields->field_dst,
+            p);
+    }
+    else
+       sql = octstr_format("SET ROWCOUNT 1\nDELETE FROM %S WHERE %S='%S' AND "
+            "%S='%S'\nSET ROWCOUNT 0", fields->table, fields->field_smsc, smsc,
             fields->field_ts, ts);
 
 #if defined(DLR_TRACE)
@@ -202,9 +213,25 @@
     if (pconn == NULL) /* should not happens, but sure is sure */
         return NULL;
 
-    sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S='%S' AND %S='%S'",
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
+
+
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+        sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S="
+                "'%S' AND %S='%S' AND %S LIKE '%%%s'",
                 fields->field_mask, fields->field_serv, fields->field_url,
                 fields->field_src, fields->field_dst, fields->field_boxc,
+                fields->table, fields->field_smsc, smsc, fields->field_ts, ts,
+                fields->field_dst, p);
+    }
+    else
+       sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S="
+                "'%S' AND %S='%S'",
+                fields->field_mask, fields->field_serv, fields->field_url,
+                fields->field_src, fields->field_dst, fields->field_boxc,
                 fields->table, fields->field_smsc, smsc, fields->field_ts, ts);
 
 #if defined(DLR_TRACE)
@@ -253,12 +280,24 @@
     if (pconn == NULL)
         return;
 
-    sql = octstr_format("SET ROWCOUNT 1\n"
-            "UPDATE %S SET %S=%d WHERE %S='%S' AND %S='%S'\n"
-            "SET ROWCOUNT 0",
-            fields->table, fields->field_status, status,
-            fields->field_smsc, smsc, fields->field_ts, ts);
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
+
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       sql = octstr_format("SET ROWCOUNT 1\nUPDATE %S SET %S=%d WHERE %S='%S' "
+           "AND %S='%S' AND %S LIKE '%%%s'\nSET ROWCOUNT 0",
+           fields->table, fields->field_status, status,
+           fields->field_smsc, smsc, fields->field_ts, ts, fields->field_dst,
+           p);
+    }
+    else
+       sql = octstr_format("SET ROWCOUNT 1\nUPDATE %S SET %S=%d WHERE %S='%S' "
+            "AND %S='%S'\nSET ROWCOUNT 0", fields->table, fields->field_status,
+            status, fields->field_smsc, smsc, fields->field_ts, ts);
+
 #if defined(DLR_TRACE)
     debug("dlr.mssql", 0, "sql: %s", octstr_get_cstr(sql));
 #endif
Index: gw/dlr_sdb.c
===================================================================
--- gw/dlr_sdb.c	(revision 4833)
+++ gw/dlr_sdb.c	(working copy)
@@ -210,7 +210,7 @@
     return 0;
 }
 
-static struct dlr_entry*  dlr_sdb_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
+static struct dlr_entry* dlr_sdb_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
 {
     Octstr *sql;
     int	state;
@@ -218,14 +218,33 @@
 
     gw_assert(res != NULL);
 
-    sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s' %s",
-                        octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_serv),
-                        octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_src),
-                        octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_boxc),
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                        octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
 
+
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s="
+             "'%s' AND %s='%s' AND %s LIKE '%%%s' %s", octstr_get_cstr
+             (fields->field_mask), octstr_get_cstr(fields->field_serv),
+             octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->
+             field_src), octstr_get_cstr(fields->field_dst), octstr_get_cstr
+             (fields->field_boxc), octstr_get_cstr(fields->table),
+             octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
+             octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts),
+             octstr_get_cstr(fields->field_dst), p, sdb_get_limit_str());
+    }
+    else
+       sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s'"
+             " AND %s='%s' %s", octstr_get_cstr(fields->field_mask),
+             octstr_get_cstr(fields->field_serv), octstr_get_cstr(fields->
+             field_url), octstr_get_cstr(fields->field_src), octstr_get_cstr
+             (fields->field_dst), octstr_get_cstr(fields->field_boxc),
+             octstr_get_cstr(fields->table), octstr_get_cstr(fields->
+             field_smsc), octstr_get_cstr(smsc), octstr_get_cstr(fields->
+             field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
+
 #if defined(DLR_TRACE)
      debug("dlr.sdb", 0, "SDB: sql: %s", octstr_get_cstr(sql));
 #endif
@@ -256,12 +275,28 @@
     int	state;
 
     debug("dlr.sdb", 0, "SDB: updating DLR status in database");
-    sql = octstr_format("UPDATE %s SET %s=%d WHERE %s='%s' AND %s='%s' %s",
-                        octstr_get_cstr(fields->table),
-                        octstr_get_cstr(fields->field_status), status,
-                        octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                        octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
 
+    if (dst){
+       int len = octstr_len(dst);
+       char *p = octstr_get_cstr(dst);
+
+
+       if (len > MIN_DST_LEN)
+           p += len - MIN_DST_LEN;         /* get last MIN_DST_LEN digits */
+       sql = octstr_format("UPDATE %s SET %s=%d WHERE %s='%s' AND %s='%s' AND "
+             "%s LIKE '%%%s' %s", octstr_get_cstr(fields->table),
+             octstr_get_cstr(fields->field_status), status, octstr_get_cstr
+             (fields->field_smsc), octstr_get_cstr(smsc), octstr_get_cstr
+             (fields->field_ts), octstr_get_cstr(ts), octstr_get_cstr(fields->
+             field_dst), p, sdb_get_limit_str());
+    }
+    else
+       sql = octstr_format("UPDATE %s SET %s=%d WHERE %s='%s' AND %s='%s' %s",
+             octstr_get_cstr(fields->table), octstr_get_cstr(fields->
+             field_status), status, octstr_get_cstr(fields->field_smsc),
+             octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts),
+             octstr_get_cstr(ts), sdb_get_limit_str());
+
 #if defined(DLR_TRACE)
      debug("dlr.sdb", 0, "SDB: sql: %s", octstr_get_cstr(sql));
 #endif
@@ -288,19 +323,48 @@
          * to do vacuum regularly, even if it's virtually impossible
          * to hit duplicates since oid's are given in a row
          */
-        sql = octstr_format("DELETE FROM %s WHERE oid = \
-                            (SELECT oid FROM %s WHERE %s='%s' AND %s='%s' LIMIT 1)",
-                            octstr_get_cstr(fields->table),
-                            octstr_get_cstr(fields->table),
-                            octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                            octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
-    } else {
-        sql = octstr_format("DELETE FROM %s WHERE %s='%s' AND %s='%s' %s",
-                            octstr_get_cstr(fields->table),
-                            octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
-                            octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
+       if (dst){
+          int len = octstr_len(dst);
+          char *p = octstr_get_cstr(dst);
+
+
+          if (len > MIN_DST_LEN)
+              p += len - MIN_DST_LEN;      /* get last MIN_DST_LEN digits */
+          sql = octstr_format("DELETE FROM %s WHERE oid = (SELECT oid FROM %s "
+                "WHERE %s='%s' AND %s='%s' AND %s LIKE '%%%s' LIMIT 1)",
+                octstr_get_cstr(fields->table), octstr_get_cstr(fields->table),
+                octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
+                octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts),
+                octstr_get_cstr(fields->field_dst), p);
+       }
+       else
+          sql = octstr_format("DELETE FROM %s WHERE oid = (SELECT oid FROM %s "
+                "WHERE %s='%s' AND %s='%s' LIMIT 1)", octstr_get_cstr(fields->
+                table), octstr_get_cstr(fields->table), octstr_get_cstr
+                (fields->field_smsc), octstr_get_cstr(smsc), octstr_get_cstr
+                (fields->field_ts), octstr_get_cstr(ts));
     }
+    else {
+       if (dst){
+          int len = octstr_len(dst);
+          char *p = octstr_get_cstr(dst);
 
+
+          if (len > MIN_DST_LEN)
+              p += len - MIN_DST_LEN;       /* get last MIN_DST_LEN digits */
+          sql = octstr_format("DELETE FROM %s WHERE %s='%s' AND %s='%s' AND %s "
+                "LIKE '%%%s' %s", octstr_get_cstr(fields->table),
+                octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
+                octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts),
+                octstr_get_cstr(fields->field_dst), p, sdb_get_limit_str());
+       }
+       else
+          sql = octstr_format("DELETE FROM %s WHERE %s='%s' AND %s='%s' %s",
+                octstr_get_cstr(fields->table), octstr_get_cstr(fields->
+                field_smsc), octstr_get_cstr(smsc), octstr_get_cstr(fields->
+                field_ts), octstr_get_cstr(ts), sdb_get_limit_str());
+    }
+
 #if defined(DLR_TRACE)
      debug("dlr.sdb", 0, "SDB: sql: %s", octstr_get_cstr(sql));
 #endif
Index: gw/dlr.c
===================================================================
--- gw/dlr.c	(revision 4833)
+++ gw/dlr.c	(working copy)
@@ -371,7 +371,7 @@
  * NOTE: If typ is end status (e.g. DELIVERED) then dlr entry
  *       will be removed from DB.
  */
-Msg *dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ)
+Msg *dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
 {
     Msg	*msg = NULL;
     struct dlr_entry *dlr = NULL;
@@ -388,7 +388,10 @@
     debug("dlr.dlr", 0, "DLR[%s]: Looking for DLR smsc=%s, ts=%s, dst=%s, type=%d",
                                  dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(ts), octstr_get_cstr(dst), typ);
 
-    dlr = handles->dlr_get(smsc, ts, dst);
+    if (use_dst)
+       dlr = handles->dlr_get(smsc, ts, dst);
+    else
+       dlr = handles->dlr_get(smsc, ts, NULL);
     if (dlr == NULL)  {
         warning(0, "DLR[%s]: DLR from SMSC<%s> for DST<%s> not found.",
                 dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(dst));         
@@ -436,12 +439,19 @@
     if ((typ & DLR_BUFFERED) && ((dlr->mask & DLR_SUCCESS) || (dlr->mask & DLR_FAIL))) {
         debug("dlr.dlr", 0, "DLR[%s]: DLR not destroyed, still waiting for other delivery report", dlr_type());
         /* update dlr entry status if function defined */
-        if (handles != NULL && handles->dlr_update != NULL)
-            handles->dlr_update(smsc, ts, dst, typ);
+        if (handles != NULL && handles->dlr_update != NULL){
+            if (use_dst)
+               handles->dlr_update(smsc, ts, dst, typ);
+            else
+               handles->dlr_update(smsc, ts, NULL, typ);
+        }
     } else {
-        if (handles != NULL && handles->dlr_remove != NULL) {
+        if (handles != NULL && handles->dlr_remove != NULL){
             /* it's not good for internal storage, but better for all others */
-            handles->dlr_remove(smsc, ts, dst);
+            if (use_dst)
+               handles->dlr_remove(smsc, ts, dst);
+            else
+               handles->dlr_remove(smsc, ts, NULL);
         } else {
             warning(0, "DLR[%s]: Storage don't have remove operation defined", dlr_type());
         }
Index: gw/dlr.h
===================================================================
--- gw/dlr.h	(revision 4833)
+++ gw/dlr.h	(working copy)
@@ -103,7 +103,8 @@
  * Find an entry in the list. If there is one a message is returned and 
  * the entry is removed from the list otherwhise the message returned is NULL 
  */
-Msg* dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int type);
+Msg* dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int type,
+ int use_dst);
 
 /* return the number of DLR messages in the current waiting queue */
 long dlr_messages(void);
Index: gw/dlr_p.h
===================================================================
--- gw/dlr_p.h	(revision 4833)
+++ gw/dlr_p.h	(working copy)
@@ -70,6 +70,8 @@
 
 #define DLR_TRACE 1
 
+/* Used in destination based queries for EMI/UUCP DLRs */
+#define MIN_DST_LEN 7
 /*
  * The structure of a delivery report  entry.
  */
Index: gw/smsc/smsc_cimd2.c
===================================================================
--- gw/smsc/smsc_cimd2.c	(revision 4833)
+++ gw/smsc/smsc_cimd2.c	(working copy)
@@ -2114,7 +2114,7 @@
         code = 0;
     }
     if(code)
-    	msg = dlr_find(conn->name, timestamp, destination, code);
+    	msg = dlr_find(conn->name, timestamp, destination, code, 0);
     else
         msg = NULL;
 
Index: gw/smsc/smsc_soap.c
===================================================================
--- gw/smsc/smsc_soap.c	(revision 4833)
+++ gw/smsc/smsc_soap.c	(working copy)
@@ -1616,7 +1616,7 @@
     /* fetch the DLR */
 
     dlrmsg = dlr_find(conn->id, octstr_imm(msgid), octstr_imm("receiver"), /* destination */
-                      dlrtype);
+                      dlrtype, 0);
 
     if (!dlrmsg) {
         error(0,"SOAP[%s]: parse_dlr invoked (%ld), but no DLR found for MsgID %s", octstr_get_cstr(privdata->name),dlrtype,msgid);
Index: gw/smsc/smsc_oisd.c
===================================================================
--- gw/smsc/smsc_oisd.c	(revision 4833)
+++ gw/smsc/smsc_oisd.c	(working copy)
@@ -1306,7 +1306,7 @@
     }
 
     if (code)
-        msg = dlr_find(conn->name, timestamp, destination, code);
+        msg = dlr_find(conn->name, timestamp, destination, code, 0);
 
     octstr_destroy(destination);
     octstr_destroy(timestamp);
Index: gw/smsc/smsc_at.c
===================================================================
--- gw/smsc/smsc_at.c	(revision 4833)
+++ gw/smsc/smsc_at.c	(working copy)
@@ -2124,7 +2124,7 @@
      * categories. It will catch "reserved" values where the first 3 MSBits 
      * are not set as "Success" which may not be correct. */
 
-    if ((dlrmsg = dlr_find(privdata->conn->id, msg_id, receiver, type)) == NULL) {
+    if ((dlrmsg = dlr_find(privdata->conn->id, msg_id, receiver, type, 0)) == NULL) {
         debug("bb.smsc.at2", 1, "AT2[%s]: Received delivery notification but can't find that ID in the DLR storage",
               octstr_get_cstr(privdata->name));
 	    goto error;
Index: gw/smsc/smsc_fake.c
===================================================================
--- gw/smsc/smsc_fake.c	(revision 4833)
+++ gw/smsc/smsc_fake.c	(working copy)
@@ -291,7 +291,7 @@
                     dlrmsg = dlr_find(conn->id,
                                       tmp, /* smsc message id */
                                       copy->sms.receiver, /* destination */
-                                      dlrstat);
+                                      dlrstat, 0);
                     if (dlrmsg != NULL) {
                         /* XXX TODO: Provide a SMPP DLR text in msgdata */
                         bb_smscconn_receive(conn, dlrmsg);
Index: gw/smsc/smsc_http.c
===================================================================
--- gw/smsc/smsc_http.c	(revision 4833)
+++ gw/smsc/smsc_http.c	(working copy)
@@ -643,7 +643,7 @@
         dlrmsg = dlr_find(conn->id,
             dlrmid, /* message id */
             to, /* destination */
-            dlrmask);
+            dlrmask, 0);
 
         if (dlrmsg != NULL) {
             dlrmsg->sms.sms_type = report_mo;
@@ -931,8 +931,8 @@
 	}
         dlrmsg = dlr_find(conn->id,
             apimsgid, /* smsc message id */
-            dest , /* destination */
-            dlrstat);
+            dest, /* destination */
+            dlrstat, 0);
 
         if (dlrmsg != NULL) {
             /* dlrmsg->sms.msgdata = octstr_duplicate(apimsgid); */
@@ -1410,8 +1410,8 @@
 
         dlrmsg = dlr_find(conn->id,
             mid, /* smsc message id */
-            dest , /* destination */
-            dlrstat);
+            dest, /* destination */
+            dlrstat, 0);
 
         if (dlrmsg != NULL) {
             dlrmsg->sms.msgdata = octstr_duplicate(mid);
@@ -1681,7 +1681,7 @@
         dlrmsg = dlr_find(conn->id,
             dlrmid, /* message id */
             to, /* destination */
-            dlrmask);
+            dlrmask, 0);
 
         if (dlrmsg != NULL) {
             dlrmsg->sms.sms_type = report_mo;
Index: gw/smsc/smsc_smpp.c
===================================================================
--- gw/smsc/smsc_smpp.c	(revision 4833)
+++ gw/smsc/smsc_smpp.c	(working copy)
@@ -1392,7 +1392,7 @@
         dlrmsg = dlr_find(smpp->conn->id,
             tmp, /* smsc message id */
             destination_addr, /* destination */
-            dlrstat);
+            dlrstat, 0);
 
         octstr_destroy(msgid);
     } else
Index: gw/smsc/smsc_cgw.c
===================================================================
--- gw/smsc/smsc_cgw.c	(revision 4833)
+++ gw/smsc/smsc_cgw.c	(working copy)
@@ -1137,19 +1137,19 @@
                 dlrmsg = dlr_find(conn->id,
                                             ts,     /* timestamp */
                                             msid,   /* destination */
-                                  DLR_SUCCESS);
+                                  DLR_SUCCESS, 0);
                 break;
             case 1:     /* buffered */
                 dlrmsg = dlr_find(conn->id,
                                             ts,     /* timestamp */
                                             msid,   /* destination */
-                                  DLR_BUFFERED);
+                                  DLR_BUFFERED, 0);
                 break;
             case 2:     /* not delivered */
                 dlrmsg = dlr_find(conn->id,
                                             ts,     /* timestamp */
                                             msid,   /* destination */
-                                  DLR_FAIL);
+                                  DLR_FAIL, 0);
                 break;
             }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.