diff options
Diffstat (limited to 'smsd/services')
-rw-r--r-- | smsd/services/odbc.c | 7 | ||||
-rw-r--r-- | smsd/services/sql-core.h | 4 | ||||
-rw-r--r-- | smsd/services/sql.c | 149 |
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; } |