summaryrefslogtreecommitdiff
path: root/smsd/services
diff options
context:
space:
mode:
Diffstat (limited to 'smsd/services')
-rw-r--r--smsd/services/odbc.c7
-rw-r--r--smsd/services/sql-core.h4
-rw-r--r--smsd/services/sql.c149
3 files changed, 136 insertions, 24 deletions
diff --git a/smsd/services/odbc.c b/smsd/services/odbc.c
index a57a1a0..e3c385e 100644
--- a/smsd/services/odbc.c
+++ b/smsd/services/odbc.c
@@ -125,9 +125,14 @@ const char *SMSDODBC_GetString(GSM_SMSDConfig * Config, SQL_result *res, unsigne
gboolean SMSDODBC_GetBool(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
- long long intval;
+ long long intval = 0;
const char * charval;
+ /* Try bit field */
+ if (SQL_SUCCEEDED(SQLGetData(res->odbc, field + 1, SQL_C_BIT, &intval, 0, NULL))) {
+ return intval ? TRUE : FALSE;
+ }
+
/* Try to get numeric value first */
intval = SMSDODBC_GetNumber(Config, res, field);
if (intval == -1) {
diff --git a/smsd/services/sql-core.h b/smsd/services/sql-core.h
index 0383b9a..16e395e 100644
--- a/smsd/services/sql-core.h
+++ b/smsd/services/sql-core.h
@@ -119,6 +119,10 @@ enum {
SQL_QUERY_DELETE_OUTBOX_MULTIPART,
SQL_QUERY_CREATE_OUTBOX,
SQL_QUERY_CREATE_OUTBOX_MULTIPART,
+ SQL_QUERY_UPDATE_OUTBOX,
+ SQL_QUERY_UPDATE_OUTBOX_MULTIPART,
+ SQL_QUERY_UPDATE_OUTBOX_STATUSCODE,
+ SQL_QUERY_UPDATE_OUTBOX_MULTIPART_STATUSCODE,
SQL_QUERY_ADD_SENT_INFO,
SQL_QUERY_UPDATE_SENT,
SQL_QUERY_REFRESH_PHONE_STATUS,
diff --git a/smsd/services/sql.c b/smsd/services/sql.c
index 9e3ef33..1a2da63 100644
--- a/smsd/services/sql.c
+++ b/smsd/services/sql.c
@@ -49,7 +49,7 @@ const char now_plus_pgsql[] = "now() + interval '%d seconds'";
const char now_plus_sqlite[] = "datetime('now', '+%d seconds', 'localtime')";
const char now_plus_freetds[] = "DATEADD('second', %d, CURRENT_TIMESTAMP)";
const char now_plus_access[] = "now()+#00:00:%d#";
-const char now_plus_oracle[] = "CURRENT_TIMESTAMP + INTERVAL '%d' SECOND'";
+const char now_plus_oracle[] = "CURRENT_TIMESTAMP + INTERVAL '%d' SECOND";
const char now_plus_fallback[] = "NOW() + INTERVAL %d SECOND";
@@ -99,7 +99,9 @@ static const char *SMSDSQL_EscapeChar(GSM_SMSDConfig * Config)
return escape_char_pgsql;
} else if (strncasecmp(driver_name, "sqlite", 6) == 0) {
return escape_char_sqlite;
- } else if (strcasecmp(driver_name, "oracle") == 0 || strcasecmp(driver_name, "freetds") == 0 || strcasecmp(driver_name, "mssql") == 0 || strcasecmp(driver_name, "sybase") == 0) {
+ } else if (strcasecmp(driver_name, "oracle") == 0) {
+ return escape_char_fallback;
+ } else if (strcasecmp(driver_name, "freetds") == 0 || strcasecmp(driver_name, "mssql") == 0 || strcasecmp(driver_name, "sybase") == 0) {
return escape_char_freetds;
} else if (strcasecmp(Config->driver, "odbc") == 0 || strcasecmp(Config->driver, "mssql") == 0) {
return escape_char_odbc;
@@ -222,9 +224,9 @@ static const char *SMSDSQL_Now(GSM_SMSDConfig * Config)
return now_pgsql;
} else if (strncasecmp(driver_name, "sqlite", 6) == 0) {
return now_sqlite;
- } else if (strcasecmp(Config->driver, "oracle") == 0 || strcasecmp(driver_name, "freetds") == 0 || strcasecmp(driver_name, "mssql") == 0 || strcasecmp(driver_name, "sybase") == 0) {
+ } else if (strcasecmp(driver_name, "oracle") == 0 || strcasecmp(driver_name, "freetds") == 0 || strcasecmp(driver_name, "mssql") == 0 || strcasecmp(driver_name, "sybase") == 0) {
return now_freetds;
- } else if (strcasecmp(Config->driver, "access") == 0) {
+ } else if (strcasecmp(driver_name, "access") == 0) {
return now_access;
} else if (strcasecmp(Config->driver, "odbc") == 0) {
return now_odbc;
@@ -384,7 +386,16 @@ static GSM_Error SMSDSQL_NamedQuery(GSM_SMSDConfig * Config, const char *sql_que
if (sms != NULL) {
switch (c) {
case 'R':
- EncodeUTF8(static_buff, sms->Number);
+ /*
+ * Always store international numnbers with + prefix
+ * to allow easy matching later.
+ */
+ if (sms->Number[0] == '0' && sms->Number[1] == '0') {
+ static_buff[0] = '+';
+ EncodeUTF8(static_buff + 1, sms->Number + 2);
+ } else {
+ EncodeUTF8(static_buff, sms->Number);
+ }
to_print = static_buff;
break;
case 'F':
@@ -674,8 +685,8 @@ static GSM_Error SMSDSQL_SaveInboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig
found = FALSE;
while (db->NextRow(Config, &res)) {
- smsc = db->GetString(Config, &res, 4);
state = db->GetString(Config, &res, 1);
+ smsc = db->GetString(Config, &res, 4);
SMSD_Log(DEBUG_NOTICE, Config, "Checking for delivery report, SMSC=%s, state=%s", smsc, state);
if (strcmp(smsc, smsc_message) != 0) {
@@ -814,12 +825,18 @@ static GSM_Error SMSDSQL_UpdateRetries(GSM_SMSDConfig * Config, char *ID)
{
SQL_result res;
GSM_Error error;
+ size_t query_type;
struct GSM_SMSDdbobj *db = Config->db;
- SQL_Var vars[3] = {
+ /* 1 = ID, 2 = Retries, 3 = StatusCode, 4 = SequencePosition */
+ SQL_Var vars[5] = {
{SQL_TYPE_STRING, {ID}},
{SQL_TYPE_INT, {NULL}},
+ {SQL_TYPE_INT, {NULL}},
+ {SQL_TYPE_INT, {NULL}},
{SQL_TYPE_NONE, {NULL}}};
vars[1].v.i = Config->retries;
+ vars[2].v.i = Config->StatusCode;
+ vars[3].v.i = Config->Part;
error = SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_UPDATE_RETRIES], NULL, vars, &res);
if (error != ERR_NONE) {
@@ -833,6 +850,17 @@ static GSM_Error SMSDSQL_UpdateRetries(GSM_SMSDConfig * Config, char *ID)
}
db->FreeResult(Config, &res);
+
+ if (Config->StatusCode != -1) {
+ query_type = (Config->Part == 1) ? SQL_QUERY_UPDATE_OUTBOX_STATUSCODE : SQL_QUERY_UPDATE_OUTBOX_MULTIPART_STATUSCODE;
+ error = SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[query_type], NULL, vars, &res);
+ if (error != ERR_NONE) {
+ SMSD_Log(DEBUG_INFO, Config, "Error updating StatusCode (%s)", __FUNCTION__);
+ return error;
+ }
+ db->FreeResult(Config, &res);
+ }
+
return ERR_NONE;
}
@@ -844,6 +872,7 @@ static GSM_Error SMSDSQL_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig
SQL_result res;
struct GSM_SMSDdbobj *db = Config->db;
int i;
+ gboolean last;
time_t timestamp;
const char *coding;
const char *text;
@@ -852,6 +881,7 @@ static GSM_Error SMSDSQL_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig
const char *destination;
const char *udh;
const char *q;
+ const char *status;
size_t udh_len;
SQL_Var vars[3];
GSM_Error error;
@@ -917,21 +947,33 @@ static GSM_Error SMSDSQL_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig
return ERR_NONE;
}
- coding = db->GetString(Config, &res, 1);
+ status = db->GetString(Config, &res, i == 1 ? 12 : 7);
+ if (status != NULL && strncmp(status, "SendingOK", 9) == 0) {
+ SMSD_Log(DEBUG_NOTICE, Config, "Marking %s:%d message for skip", ID, i);
+ Config->SkipMessage[sms->Number] = TRUE;
+ } else {
+ Config->SkipMessage[sms->Number] = FALSE;
+ }
+
text = db->GetString(Config, &res, 0);
+ coding = db->GetString(Config, &res, 1);
if (text == NULL) {
text_len = 0;
} else {
text_len = strlen(text);
}
- text_decoded = db->GetString(Config, &res, 4);
udh = db->GetString(Config, &res, 2);
+ sms->SMS[sms->Number].Class = (int)db->GetNumber(Config, &res, 3);
+ text_decoded = db->GetString(Config, &res, 4);
if (udh == NULL) {
udh_len = 0;
} else {
udh_len = strlen(udh);
}
+ /* ID, we don't need it, but some ODBC backend need to fetch all values */
+ db->GetNumber(Config, &res, 5);
+
sms->SMS[sms->Number].Coding = GSM_StringToSMSCoding(coding);
if (sms->SMS[sms->Number].Coding == 0) {
if (text == NULL || text_len == 0) {
@@ -996,26 +1038,24 @@ static GSM_Error SMSDSQL_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig
}
}
- sms->SMS[sms->Number].Class = (int)db->GetNumber(Config, &res, 3);
sms->SMS[sms->Number].PDU = SMS_Submit;
sms->Number++;
if (i == 1) {
- strncpy(Config->CreatorID, db->GetString(Config, &res, 10), sizeof(Config->CreatorID));
- Config->CreatorID[sizeof(Config->CreatorID) - 1] = 0;
+ /* Is this a multipart message? */
+ last = !db->GetBool(Config, &res, 7);
Config->relativevalidity = (int)db->GetNumber(Config, &res, 8);
Config->currdeliveryreport = db->GetBool(Config, &res, 9);
+ strncpy(Config->CreatorID, db->GetString(Config, &res, 10), sizeof(Config->CreatorID));
+ Config->CreatorID[sizeof(Config->CreatorID) - 1] = 0;
Config->retries = (int)db->GetNumber(Config, &res, 11);
-
- /* Is this a multipart message? */
- if (!db->GetBool(Config, &res, 7)) {
- db->FreeResult(Config, &res);
- break;
- }
-
}
db->FreeResult(Config, &res);
+ if (last) {
+ last = FALSE;
+ break;
+ }
}
return ERR_NONE;
@@ -1110,9 +1150,10 @@ static GSM_Error SMSDSQL_AddSentSMSInfo(GSM_MultiSMSMessage * sms, GSM_SMSDConfi
SQL_result res;
struct GSM_SMSDdbobj *db = Config->db;
GSM_Error error;
+ size_t query_type;
const char *message_state;
- SQL_Var vars[6];
+ SQL_Var vars[7];
char smsc[GSM_MAX_NUMBER_LENGTH + 1];
char destination[GSM_MAX_NUMBER_LENGTH + 1];
@@ -1150,6 +1191,22 @@ static GSM_Error SMSDSQL_AddSentSMSInfo(GSM_MultiSMSMessage * sms, GSM_SMSDConfi
vars[4].v.s = Config->DT;
vars[5].type = SQL_TYPE_NONE;
+ query_type = (Part == 1) ? SQL_QUERY_FIND_OUTBOX_BODY : SQL_QUERY_FIND_OUTBOX_MULTIPART;
+ error = SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[query_type], NULL, vars, &res);
+ if (error != ERR_NONE) {
+ SMSD_Log(DEBUG_ERROR, Config, "Error reading from database (%s)", __FUNCTION__);
+ return error;
+ }
+ if (db->NextRow(Config, &res) != 1) {
+ db->FreeResult(Config, &res);
+ return ERR_NONE;
+ }
+ /* 6 = StatusCode */
+ vars[5].type = SQL_TYPE_INT;
+ vars[5].v.i = (int)db->GetNumber(Config, &res, Part == 1 ? 13 : 8);
+ vars[6].type = SQL_TYPE_NONE;
+ db->FreeResult(Config, &res);
+
error = SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_ADD_SENT_INFO], &sms->SMS[Part - 1], vars, &res);
if (error != ERR_NONE) {
SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__);
@@ -1164,6 +1221,16 @@ static GSM_Error SMSDSQL_AddSentSMSInfo(GSM_MultiSMSMessage * sms, GSM_SMSDConfi
}
db->FreeResult(Config, &res);
+ if (sms->Number != 1) {
+ query_type = (Part == 1) ? SQL_QUERY_UPDATE_OUTBOX : SQL_QUERY_UPDATE_OUTBOX_MULTIPART;
+ error = SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[query_type], &sms->SMS[Part - 1], vars, &res);
+ if (error != ERR_NONE) {
+ SMSD_Log(DEBUG_INFO, Config, "Error updating status of multipart messages (%s)", __FUNCTION__);
+ return error;
+ }
+ db->FreeResult(Config, &res);
+ }
+
return ERR_NONE;
}
@@ -1426,8 +1493,9 @@ GSM_Error SMSDSQL_ReadConfiguration(GSM_SMSDConfig *Config)
", ", ESCAPE_FIELD("UDH"),
", ", ESCAPE_FIELD("Class"),
", ", ESCAPE_FIELD("TextDecoded"),
- ", ", ESCAPE_FIELD("RecipientID"), ")"
- " VALUES (%d, %E, %R, %c, %F, %u, %x, %T, %P)", NULL) != ERR_NONE) {
+ ", ", ESCAPE_FIELD("RecipientID"),
+ ", ", ESCAPE_FIELD("Status"), ")",
+ " VALUES (%d, %E, %R, %c, %F, %u, %x, %T, %P, %e)", NULL) != ERR_NONE) {
return ERR_UNKNOWN;
}
@@ -1486,6 +1554,8 @@ GSM_Error SMSDSQL_ReadConfiguration(GSM_SMSDConfig *Config)
", ", ESCAPE_FIELD("DeliveryReport"),
", ", ESCAPE_FIELD("CreatorID"),
", ", ESCAPE_FIELD("Retries"),
+ ", ", ESCAPE_FIELD("Status"),
+ ", ", ESCAPE_FIELD("StatusCode"),
" FROM ", Config->table_outbox, " WHERE ",
ESCAPE_FIELD("ID"), "=%1", NULL) != ERR_NONE) {
return ERR_UNKNOWN;
@@ -1500,6 +1570,8 @@ GSM_Error SMSDSQL_ReadConfiguration(GSM_SMSDConfig *Config)
", ", ESCAPE_FIELD("TextDecoded"),
", ", ESCAPE_FIELD("ID"),
", ", ESCAPE_FIELD("SequencePosition"),
+ ", ", ESCAPE_FIELD("Status"),
+ ", ", ESCAPE_FIELD("StatusCode"),
" FROM ", Config->table_outbox_multipart, " WHERE ",
ESCAPE_FIELD("ID"), "=%1 AND ",
ESCAPE_FIELD("SequencePosition"), "=%2", NULL) != ERR_NONE) {
@@ -1547,6 +1619,36 @@ GSM_Error SMSDSQL_ReadConfiguration(GSM_SMSDConfig *Config)
return ERR_UNKNOWN;
}
+ if (SMSDSQL_option(Config, SQL_QUERY_UPDATE_OUTBOX, "update_outbox",
+ "UPDATE ", Config->table_outbox, " SET ",
+ ESCAPE_FIELD("Status"), "=%3 WHERE ",
+ ESCAPE_FIELD("ID"), "=%1", NULL) != ERR_NONE) {
+ return ERR_UNKNOWN;
+ }
+
+ if (SMSDSQL_option(Config, SQL_QUERY_UPDATE_OUTBOX_MULTIPART, "update_outbox_multipart",
+ "UPDATE ", Config->table_outbox_multipart, " SET ",
+ ESCAPE_FIELD("Status"), "=%3 WHERE ",
+ ESCAPE_FIELD("ID"), "=%1 AND ",
+ ESCAPE_FIELD("SequencePosition"), "=%2", NULL) != ERR_NONE) {
+ return ERR_UNKNOWN;
+ }
+
+ if (SMSDSQL_option(Config, SQL_QUERY_UPDATE_OUTBOX_STATUSCODE, "update_outbox_statuscode",
+ "UPDATE ", Config->table_outbox, " SET ",
+ ESCAPE_FIELD("StatusCode"), "=%3 WHERE ",
+ ESCAPE_FIELD("ID"), "=%1", NULL) != ERR_NONE) {
+ return ERR_UNKNOWN;
+ }
+
+ if (SMSDSQL_option(Config, SQL_QUERY_UPDATE_OUTBOX_MULTIPART_STATUSCODE, "update_outbox_multipart_statuscode",
+ "UPDATE ", Config->table_outbox_multipart, " SET ",
+ ESCAPE_FIELD("StatusCode"), "=%3 WHERE ",
+ ESCAPE_FIELD("ID"), "=%1 AND ",
+ ESCAPE_FIELD("SequencePosition"), "=%4", NULL) != ERR_NONE) {
+ return ERR_UNKNOWN;
+ }
+
if (SMSDSQL_option(Config, SQL_QUERY_ADD_SENT_INFO, "add_sent_info",
"INSERT INTO ", Config->table_sentitems, " "
"(", ESCAPE_FIELD("CreatorID"),
@@ -1565,10 +1667,11 @@ GSM_Error SMSDSQL_ReadConfiguration(GSM_SMSDConfig *Config)
", ", ESCAPE_FIELD("TextDecoded"),
", ", ESCAPE_FIELD("InsertIntoDB"),
", ", ESCAPE_FIELD("RelativeValidity"),
+ ", ", ESCAPE_FIELD("StatusCode"),
") "
" VALUES (%A, %1, %2, %3, ",
SMSDSQL_Now(Config),
- ", %F, %4, %P, %E, %R, %c, %u, %x, %T, %5, %V)", NULL) != ERR_NONE) {
+ ", %F, %4, %P, %E, %R, %c, %u, %x, %T, %5, %V, %6)", NULL) != ERR_NONE) {
return ERR_UNKNOWN;
}