Opensmppbox patch with MSSQL support (DLR module part)
Aarno Syvanen <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi List, this DLR module for supporting MSSQL storage Aarno
box-dlr.c
(application/octet-stream, 73.1 KB)
/* * gw/box-dlr.c * * Implementation of handling of opensmppbox additions to delivery reports * (DLRs) * * Aarno Syvanen <[email protected]> */ #include <ctype.h> #include <time.h> #include <errno.h> #include <limits.h> #include <string.h> #include <unistd.h> #include "box-dlr.h" #include "gw/dlr.h" #include "gw/dlr_p.h" #include "gwlib/dbpool.h" /* Our connection pool. */ static DBPool *box_pool = NULL; /* * This is the global list used by internal memory where all messages being sent * out are being kept track of his list is looked up once a delivery report comes in */ static List *box_dlr_waiting_list; static RWLock rwlock; typedef struct _box_dlr_entry { struct dlr_entry *entry; Octstr *id; } box_dlr_entry; /* * dlr-peek: Find and return box_dlr_entry, using msg id as key. * If entry not found return NULL. * NOTE: Caller will destroy box_dlr_entry */ typedef struct _box_dlr_storage { const char *type; box_dlr_entry* (*dlr_peek) (const Octstr *id, int usesmpp); void (*dlr_add_with_id)(box_dlr_entry *entry); void (*dlr_add_mem_with_id)(box_dlr_entry *entry, Msg *msg); void (*dlr_shutdown) (void); } box_dlr_storage; typedef struct _box_dlr_db_fields { struct dlr_db_fields *dlr_db_fields; Octstr *field_id; } box_dlr_db_fields; static box_dlr_storage *handles = NULL; static box_dlr_db_fields *box_fields = NULL; static void box_dlr_storage_destroy(box_dlr_storage *handles); static box_dlr_entry *box_dlr_entry_create(void); static box_dlr_entry *box_dlr_entry_duplicate(const box_dlr_entry *dlr); static void dlr_entry_dump(const box_dlr_entry *box_dlr); static void box_dlr_entry_destroy(box_dlr_entry *box_dlr); static void box_dlr_db_fields_destroy(box_dlr_db_fields *fields); static box_dlr_db_fields *box_dlr_db_fields_create(CfgGroup *grp1, CfgGroup *grp2); static void box_dlr_db_fields_destroy(box_dlr_db_fields *fields); static void add_true(const Octstr *smsc, const Octstr *ts, Msg *msg); #ifdef HAVE_MYSQL static void dlr_mysql_add_with_id(box_dlr_entry *entry); static box_dlr_entry* dlr_mysql_peek(const Octstr *id, int use_smpp_id); #endif static box_dlr_storage *box_dlr_init_mysql(Cfg *cfg); #ifdef HAVE_SDB static int gw_sdb_query(char *query,int (*callback)(int, char **, void *), void *closure); static const char* sdb_get_limit_str(void); static int sdb_callback_find(int n, char **p, void *data); static void dlr_sdb_add_with_id(box_dlr_entry *entry); static box_dlr_entry* dlr_sdb_peek(const Octstr *id, int use_smpp_id); #endif static box_dlr_storage *box_dlr_init_sdb(Cfg *cfg); #ifdef HAVE_ORACLE static void dlr_oracle_add_with_id(box_dlr_entry *entry); static box_dlr_entry* dlr_oracle_peek(const Octstr *id, int use_smpp_id); #endif static box_dlr_storage *box_dlr_init_oracle(Cfg *cfg); static void dlr_mem_add_with_id(box_dlr_entry *box_dlr, Msg *msg); static int dlr_mem_entry_match(box_dlr_entry *box_dlr, const Octstr *id, int use_smpp_id); static box_dlr_entry *dlr_mem_peek(const Octstr *id, int use_smpp_id); static void box_dlr_mem_shutdown(void); static box_dlr_storage *box_dlr_init_mem(Cfg *cfg); #ifdef HAVE_PGSQL static void dlr_pgsql_add_with_id(box_dlr_entry *entry); static box_dlr_entry* dlr_pgsql_peek(const Octstr *id, int use_smpp_id); #endif static box_dlr_storage *box_dlr_init_pgsql(Cfg *cfg); #ifdef HAVE_MSSQL static void dlr_mssql_add_with_id(box_dlr_entry *entry); static box_dlr_entry* dlr_mssql_peek(const Octstr *id, int use_smpp_id); #endif static box_dlr_storage *box_dlr_init_mssql(Cfg *cfg); #ifdef HAVE_SQLITE3 static void dlr_sqlite3_add_with_id(box_dlr_entry *entry); static box_dlr_entry *dlr_sqlite3_peek(const Octstr *id, int use_smpp_id); #endif static box_dlr_storage *box_dlr_init_sqlite3(Cfg *cfg); static void box_dlr_storage_destroy(box_dlr_storage *s) { gw_free(s); } void box_dlr_init(Cfg *cfg) { CfgGroup *grp; Octstr *dlr_type; /* check which DLR storage type we are using */ grp = cfg_get_single_group(cfg, octstr_imm("opensmppbox")); if(grp == NULL) panic(0, "opensmppbox: DLR: can't find group opensmppbox"); dlr_type = cfg_get(grp, octstr_imm("box-dlr-storage")); /* * assume we are using internal memory in case no directive * has been specified, warn the user anyway */ if (dlr_type == NULL) { dlr_type = octstr_imm("internal"); warning(0, "opensmmpbox: DLR: using default 'internal' for storage type."); } /* call the sub-init routine */ if (octstr_compare(dlr_type, octstr_imm("mysql")) == 0) { handles = box_dlr_init_mysql(cfg); } else if (octstr_compare(dlr_type, octstr_imm("sdb")) == 0) { handles = box_dlr_init_sdb(cfg); } else if (octstr_compare(dlr_type, octstr_imm("oracle")) == 0) { handles = box_dlr_init_oracle(cfg); } else if (octstr_compare(dlr_type, octstr_imm("internal")) == 0) { handles = box_dlr_init_mem(cfg); } else if (octstr_compare(dlr_type, octstr_imm("pgsql")) == 0) { handles = box_dlr_init_pgsql(cfg); } else if (octstr_compare(dlr_type, octstr_imm("mssql")) == 0) { handles = box_dlr_init_mssql(cfg); } else if (octstr_compare(dlr_type, octstr_imm("sqlite3")) == 0) { handles = box_dlr_init_sqlite3(cfg); } if (!handles) { panic(0, "opensmppbox: DLR: storage type '%s' is not supported!", octstr_get_cstr(dlr_type)); } /* check needed function pointers */ if (!(handles->dlr_add_with_id) || !(handles->dlr_peek)) panic(0, "opensmppbox: DLR: storage type '%s' don't implement needed functions", octstr_get_cstr(dlr_type)); /* get info from storage */ info(0, "opensmppbox DLR storage using type: %s", handles->type); octstr_destroy(dlr_type); } void box_dlr_shutdown(void) { dbpool_destroy(box_pool); box_dlr_db_fields_destroy(box_fields); box_dlr_storage_destroy(handles); } void box_dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg) { /* check if delivery receipt requested */ if (!DLR_IS_ENABLED(msg->sms.dlr_mask)) return; add_true(smsc, ts, msg); } void msg_add(const Octstr *smsc, const Octstr *ts, Msg *msg) { add_true(smsc, ts, msg); } /* * Return Msg* if dlr entry found in DB, otherwise NULL. * NOTE: msg is not removed. This funsction is used to * fetch data from dlr table. */ Msg *dlr_find_by_id(const Octstr *id, int usesmpp) { Msg *msg = NULL; box_dlr_entry *dlr = NULL; /* check if we have handler registered */ if (handles == NULL || handles->dlr_peek == NULL) return NULL; debug("opensmppbox", 0, "DLR[%s]:Looking for DLR id=%s", handles->type, octstr_get_cstr(id)); dlr = handles->dlr_peek(id, usesmpp); if (!dlr) { warning(0, "opensmppbox DLR for ID <%s> not found.", octstr_get_cstr(id)); return NULL; } #define O_SET(x, val) if (octstr_len(val) > 0) { x = val; val = NULL; } msg = msg_create(sms); msg->sms.sms_type = report_mo; O_SET(msg->sms.service, dlr->entry->service); O_SET(msg->sms.smsc_id, dlr->entry->smsc); O_SET(msg->sms.receiver, dlr->entry->destination); O_SET(msg->sms.sender, dlr->entry->source); /* if dlr_url was present, recode it here again */ O_SET(msg->sms.dlr_url, dlr->entry->url); /* * If id is available, use it to restore box id for smppbox * usage */ O_SET(msg->sms.foreign_id, dlr->id); /* * insert original message to the data segment * later in the smsc module */ msg->sms.msgdata = NULL; /* * If a boxc_id is available, then instruct smppbox to * route this msg back to originating client */ O_SET(msg->sms.boxc_id, dlr->entry->boxc_id); time(&msg->sms.time); debug("opensmppbox", 0, "created DLR message for ID <%s>", (msg->sms.foreign_id ? octstr_get_cstr(msg->sms.foreign_id) : "")); #undef O_SET /* destroy struct dlr_entry */ box_dlr_entry_destroy(dlr); debug("", 0, "we have a message"); msg_dump(msg, 0); return msg; } static void add_true(const Octstr *smsc, const Octstr *ts, Msg *msg) { box_dlr_entry *dlr = NULL; /* Add the foreign_id so all SMSC modules can use it. * Obey also the original message in the split_parts list. */ if (msg->sms.foreign_id != NULL) octstr_destroy(msg->sms.foreign_id); msg->sms.foreign_id = octstr_duplicate(ts); if (msg->sms.split_parts != NULL) { struct split_parts *split = msg->sms.split_parts; if (split->orig->sms.foreign_id != NULL) octstr_destroy(split->orig->sms.foreign_id); split->orig->sms.foreign_id = octstr_duplicate(ts); } /* sanity check */ if (!handles || !msg) return; const char *type = dlr_type(); int is_internal = 0; if (strcmp(type, "internal") == 0) { if (!handles->dlr_add_mem_with_id) return; is_internal = 1; } else if (!handles->dlr_add_with_id) return; if (smsc && octstr_len(smsc) == 0) { warning(0, "opensmppbox DLR[%s]: Can't add a dlr without smsc-id", handles->type); return; } /* allocate new struct box_dlr_entry struct */ dlr = box_dlr_entry_create(); /* now copy all values, we are interested in */ dlr->entry->smsc = (smsc ? octstr_duplicate(smsc) : octstr_create("")); dlr->entry->timestamp = (ts ? octstr_duplicate(ts) : octstr_create("")); dlr->entry->source = (msg->sms.sender ? octstr_duplicate(msg->sms.sender) : octstr_create("")); dlr->entry->destination = (msg->sms.receiver ? octstr_duplicate(msg->sms.receiver) : octstr_create("")); dlr->entry->service = (msg->sms.service ? octstr_duplicate(msg->sms.service) : octstr_create("")); dlr->entry->url = (msg->sms.dlr_url ? octstr_duplicate(msg->sms.dlr_url) : octstr_create("")); dlr->entry->boxc_id = (msg->sms.boxc_id ? octstr_duplicate(msg->sms.boxc_id) : octstr_create("")); dlr->entry->mask = msg->sms.dlr_mask; char uuidbuf[UUID_STR_LEN + 1]; Octstr *id; uuid_unparse(msg->sms.id, uuidbuf); id = octstr_create_from_data(uuidbuf, UUID_STR_LEN + 1); dlr->id = octstr_duplicate(id); debug("opensmppbox", 0, "DLR[%s]: Adding DLR smsc=%s, ts=%s, src=%s, dst=%s, mask=%d, boxc=%s, id=%s", handles->type, octstr_get_cstr(dlr->entry->smsc), octstr_get_cstr(dlr->entry->timestamp), octstr_get_cstr(dlr->entry->source), octstr_get_cstr(dlr->entry->destination), dlr->entry->mask, octstr_get_cstr(dlr->entry->boxc_id), octstr_get_cstr(id)); /* call registered function */ if (is_internal) handles->dlr_add_mem_with_id(dlr, msg); else handles->dlr_add_with_id(dlr); octstr_destroy(id); } static box_dlr_entry *box_dlr_entry_create(void) { box_dlr_entry *dlr; dlr = gw_malloc(sizeof(box_dlr_entry)); dlr->entry = dlr_entry_create(); dlr->id = NULL; return dlr; } static box_dlr_entry *box_dlr_entry_duplicate(const box_dlr_entry *dlr) { box_dlr_entry *copy; if (!dlr) return NULL; copy = box_dlr_entry_create(); copy->entry = dlr_entry_duplicate(dlr->entry); copy->id = octstr_duplicate(dlr->id); return copy; } static void dlr_entry_dump(const box_dlr_entry *box_dlr) { if (!box_dlr) { debug("opensmppbox", 0, "dlr entry points to NULL"); return; } if (box_dlr->entry->smsc) debug("opensmppbox", 0, "dlr entry smsc id was %s", octstr_get_cstr(box_dlr->entry->smsc)); if (box_dlr->entry->timestamp) debug("opensmppbox", 0, "dlr entry timestamp was %s", octstr_get_cstr(box_dlr->entry->timestamp)); if (box_dlr->entry->source) debug("opensmppbox", 0, "dlr entry source was %s", octstr_get_cstr(box_dlr->entry->source)); if (box_dlr->entry->destination) debug("opensmppbox", 0, "dlr entry destination was %s", octstr_get_cstr(box_dlr->entry->destination)); if (box_dlr->entry->service) debug("opensmppbox", 0, "dlr entry service was %s", octstr_get_cstr(box_dlr->entry->service)); if (box_dlr->entry->url) debug("opensmppbox", 0, "dlr entry dlr URL was %s", octstr_get_cstr(box_dlr->entry->url)); if (box_dlr->entry->boxc_id) debug("opensmppbox", 0, "dlr entry box id was %s", octstr_get_cstr(box_dlr->entry->boxc_id)); if (box_dlr->id) debug("opensmppbox", 0, "dlr entry msg id was %s", octstr_get_cstr(box_dlr->id)); } void box_dlr_entry_destroy(box_dlr_entry *box_dlr) { if (!box_dlr) return; dlr_entry_destroy(box_dlr->entry); #define O_DELETE(a) { if (a) octstr_destroy(a); a = NULL; } O_DELETE(box_dlr->id); gw_free(box_dlr); #undef O_DELETE } static box_dlr_db_fields *box_dlr_db_fields_create(CfgGroup *grp1, CfgGroup *grp2) { box_dlr_db_fields *fields = NULL; fields = gw_malloc(sizeof(box_dlr_db_fields)); fields->dlr_db_fields = dlr_db_fields_create(grp1); fields->field_id = cfg_get(grp2, octstr_imm("box-msg-id")); return fields; } static void box_dlr_db_fields_destroy(box_dlr_db_fields *fields) { /* sanity check */ if (!fields) return; dlr_db_fields_destroy(fields->dlr_db_fields); #define O_DELETE(a) { if (a) octstr_destroy(a); a = NULL; } O_DELETE(fields->field_id); #undef O_DELETE gw_free(fields); } #ifdef HAVE_MYSQL static void dlr_mysql_add_with_id(box_dlr_entry *entry) { Octstr *sql, *os_mask; DBPoolConn *pconn; List *binds = gwlist_create(); int res; debug("opensmppbox", 0, "adding DLR entry wirh id into database"); pconn = dbpool_conn_consume(box_pool); /* just for sure */ if (!pconn) { box_dlr_entry_destroy(entry); return; } if (box_fields->field_id == NULL || octstr_len(box_fields->field_id) == 0) sql = octstr_format("INSERT INTO `%S` (`%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`) VALUES " "(?, ?, ?, ?, ?, ?, ?, ?, 0)", box_fields->dlr_db_fields->table, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->field_ts, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_boxc, box_fields->dlr_db_fields->field_status); else sql = octstr_format("INSERT INTO `%S` (`%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`) VALUES " "(?, ?, ?, ?, ?, ?, ?, ?, ?, 0)", box_fields->dlr_db_fields->table, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->field_ts, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_status); os_mask = octstr_format("%d", entry->entry->mask); gwlist_append(binds, entry->entry->smsc); gwlist_append(binds, entry->entry->timestamp); gwlist_append(binds, entry->entry->source); gwlist_append(binds, entry->entry->destination); gwlist_append(binds, entry->entry->service); gwlist_append(binds, entry->entry->url); gwlist_append(binds, os_mask); gwlist_append(binds, entry->entry->boxc_id); if (box_fields->field_id && octstr_len(box_fields->field_id) > 0) gwlist_append(binds, entry->id); #if defined(DLR_TRACE) debug("opensmppbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if ((res = dbpool_conn_update(pconn, sql, binds)) == -1) error(0, "opensmppbox: DLR: MYSQL: Error while adding dlr entry for DST<%s>", octstr_get_cstr(entry->entry->destination)); else if (!res) warning(0, "opensmppbox: DLR: MYSQL: No dlr inserted for DST<%s>", octstr_get_cstr(entry->entry->destination)); dbpool_conn_produce(pconn); octstr_destroy(sql); gwlist_destroy(binds, NULL); octstr_destroy(os_mask); box_dlr_entry_destroy(entry); } static box_dlr_entry* dlr_mysql_peek(const Octstr *id, int use_smpp_id) { Octstr *sql = NULL, *like = NULL, *smpp_id = NULL; DBPoolConn *pconn = NULL; List *result = NULL, *row = NULL; box_dlr_entry *res = NULL; List *binds = gwlist_create(); pconn = dbpool_conn_consume(box_pool); if (pconn == NULL) /* should not happens, but sure is sure */ return NULL; if (use_smpp_id) { smpp_id = octstr_copy(id, 0, 8); like = octstr_format("LIKE '%s%%'", octstr_get_cstr(smpp_id)); octstr_destroy(smpp_id); sql = octstr_format("SELECT `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S` FROM `%S` WHERE `%S` %S LIMIT 1", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, like); } else sql = octstr_format("SELECT `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S`, `%S` FROM `%S` WHERE `%S`=? LIMIT 1", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id); gwlist_append(binds, (Octstr *)id); #if defined(DLR_TRACE) debug("opensmppbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if (dbpool_conn_select(pconn, sql, binds, &result) != 0) { octstr_destroy(sql); octstr_destroy(like); dbpool_conn_produce(pconn); gwlist_destroy(result, NULL); return NULL; } octstr_destroy(sql); octstr_destroy(like); gwlist_destroy(binds, NULL); dbpool_conn_produce(pconn); #define LO2CSTR(r, i) octstr_get_cstr(gwlist_get(r, i)) if (gwlist_len(result) > 0) { row = gwlist_extract_first(result); res = box_dlr_entry_create(); gw_assert(res != NULL); res->entry->mask = atoi(LO2CSTR(row,0)); res->entry->service = octstr_create(LO2CSTR(row, 1)); res->entry->url = octstr_create(LO2CSTR(row,2)); res->entry->source = octstr_create(LO2CSTR(row, 3)); res->entry->destination = octstr_create(LO2CSTR(row, 4)); res->entry->boxc_id = octstr_create(LO2CSTR(row, 5)); res->id = octstr_create(LO2CSTR(row, 6)); res->entry->smsc = octstr_create(LO2CSTR(row, 7)); gwlist_destroy(row, octstr_destroy_item); }; #undef LO2CSTR gwlist_destroy(result, NULL); return res; } static box_dlr_storage *box_dlr_init_mysql(Cfg *cfg) { CfgGroup *grp1, *grp2; List *grplist; Octstr *p = NULL; Octstr *mysql_host, *mysql_user, *mysql_pass, *mysql_db, *mysql_id; long mysql_port = 0; long pool_size; DBConf *db_conf = NULL; handles = gw_malloc(sizeof(box_dlr_storage)); handles->type = "mysql"; handles->dlr_add_with_id = dlr_mysql_add_with_id; handles->dlr_peek = dlr_mysql_peek; handles->dlr_shutdown = box_dlr_shutdown; /* * check for all mandatory directives that specify the field names * of the used MySQL table */ if (!(grp1 = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "opensmppbox: DLR: MySQL: group 'dlr-db' is not specified!"); if (!(mysql_id = cfg_get(grp1, octstr_imm("id")))) panic(0, "opensmppbox: DLR: MySQL: directive 'id' is not specified!"); if (!(grp2 = cfg_get_single_group(cfg, octstr_imm("opensmppbox")))) panic(0, "opensmppbox: DLR: MySQL: group 'opensmppbox' is not specified!"); box_fields = box_dlr_db_fields_create(grp1, grp2); /* * Escaping special quotes for field/table names */ octstr_replace(box_fields->dlr_db_fields->table, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_smsc, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_ts, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_src, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_dst, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_serv, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_url, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_mask, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_status, octstr_imm("`"), octstr_imm("``")); octstr_replace(box_fields->dlr_db_fields->field_boxc, octstr_imm("`"), octstr_imm("``")); if (box_fields->field_id && octstr_len(box_fields->field_id) > 0) octstr_replace(box_fields->field_id, octstr_imm("`"), octstr_imm("``")); /* * now grap the required information from the 'mysql-connection' group * with the mysql-id we just obtained * * we have to loop through all available MySQL connection definitions * and search for the one we are looking for */ grplist = cfg_get_multi_group(cfg, octstr_imm("mysql-connection")); while (grplist && (grp1 = gwlist_extract_first(grplist)) != NULL) { p = cfg_get(grp1, octstr_imm("id")); if (p != NULL && octstr_compare(p, mysql_id) == 0) { goto found; } if (p != NULL) octstr_destroy(p); } panic(0, "opensmppbox: DLR: MySQL: connection settings for id '%s' are not specified!", octstr_get_cstr(mysql_id)); found: octstr_destroy(p); gwlist_destroy(grplist, NULL); if (cfg_get_integer(&pool_size, grp1, octstr_imm("max-connections")) == -1 || pool_size == 0) pool_size = 1; if (!(mysql_host = cfg_get(grp1, octstr_imm("host")))) panic(0, "DLR: MySQL: directive 'host' is not specified!"); if (!(mysql_user = cfg_get(grp1, octstr_imm("username")))) panic(0, "DLR: MySQL: directive 'username' is not specified!"); if (!(mysql_pass = cfg_get(grp1, octstr_imm("password")))) panic(0, "DLR: MySQL: directive 'password' is not specified!"); if (!(mysql_db = cfg_get(grp1, octstr_imm("database")))) panic(0, "DLR: MySQL: directive 'database' is not specified!"); cfg_get_integer(&mysql_port, grp1, octstr_imm("port")); /* optional */ /* * ok, ready to connect to MySQL */ db_conf = gw_malloc(sizeof(DBConf)); db_conf->mysql = gw_malloc(sizeof(MySQLConf)); db_conf->mysql->host = mysql_host; db_conf->mysql->port = mysql_port; db_conf->mysql->username = mysql_user; db_conf->mysql->password = mysql_pass; db_conf->mysql->database = mysql_db; box_pool = dbpool_create(DBPOOL_MYSQL, db_conf, pool_size); if (dbpool_conn_count(box_pool) == 0) panic(0,"DLR: MySQL: database pool has no connections!"); octstr_destroy(mysql_id); return handles; } #else /* * Return NULL , so we point dlr-core that we were * not compiled in. */ static box_dlr_storage *box_dlr_init_mysql(Cfg *cfg) { return NULL; } #endif #ifdef HAVE_SDB enum { SDB_ORACLE, SDB_MYSQL, SDB_POSTGRES, SDB_OTHER }; static long sdb_conn_type = SDB_OTHER; static int gw_sdb_query(char *query,int (*callback)(int, char **, void *), void *closure) { DBPoolConn *pc; int rows; pc = dbpool_conn_consume(box_pool); if (pc == NULL) { error(0, "opensmppbox: SDB: Database pool got no connection!"); return -1; } rows = sdb_query(pc->conn, query, callback, closure); dbpool_conn_produce(pc); return rows; } static const char* sdb_get_limit_str(void) { switch (sdb_conn_type) { case SDB_ORACLE: return "AND ROWNUM < 2"; case SDB_MYSQL: case SDB_POSTGRES: return "LIMIT 1"; case SDB_OTHER: default: return ""; } } static int sdb_callback_find(int n, char **p, void *data) { box_dlr_entry *res = (box_dlr_entry *) data; if (n != 8) { debug("dlr.sdb", 0, "SDB: Result has incorrect number of columns: %d", n); return 0; } #if defined(DLR_TRACE) debug("dlr.sdb", 0, "row=%s,%s,%s,%s,%s,%s,%s,%s",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); #endif res->entry->mask = atoi(p[0]); res->entry->service = octstr_create(p[1]); res->entry->url = octstr_create(p[2]); res->entry->source = octstr_create(p[3]); res->entry->destination = octstr_create(p[4]); res->entry->boxc_id = octstr_create(p[5]); res->id = octstr_create(p[6]); res->entry->smsc = octstr_create(p[7]); return 0; } static box_dlr_entry *dlr_sdb_peek(const Octstr *id, int use_smpp_id) { Octstr *sql = NULL, *smpp_id = NULL, *like = NULL; int state; box_dlr_entry *res = box_dlr_entry_create(); if (use_smpp_id) { smpp_id = octstr_copy(id, 0, 8); like = octstr_format("LIKE '%s%%'", octstr_get_cstr(smpp_id)); sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE %S %S %s", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, like, sdb_get_limit_str()); octstr_destroy(smpp_id); } else sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE %S='%S' %s", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, id, sdb_get_limit_str()); #if defined(DLR_TRACE) debug("opensmppbox", 0, "SDB: sql: %s", octstr_get_cstr(sql)); #endif state = gw_sdb_query(octstr_get_cstr(sql), sdb_callback_find, res); octstr_destroy(sql); octstr_destroy(like); if (state == -1) { error(0, "opensmppbox: SDB: error in finding DLR"); goto notfound; } else if (state == 0) { debug("opensmppbox", 0, "SDB: no entry found for ID <%s>.", octstr_get_cstr(id)); goto notfound; } return res; notfound: box_dlr_entry_destroy(res); res = NULL; return NULL; } static void dlr_sdb_add_with_id(box_dlr_entry *entry) { Octstr *sql; int state; box_dlr_entry *res = NULL; if (box_fields->field_id == NULL || octstr_len(box_fields->field_id) == 0) sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES " "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d')", octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->field_ts), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->dlr_db_fields->field_status), octstr_get_cstr(entry->entry->smsc), octstr_get_cstr(entry->entry->timestamp), octstr_get_cstr(entry->entry->source), octstr_get_cstr(entry->entry->destination), octstr_get_cstr(entry->entry->service), octstr_get_cstr(entry->entry->url), entry->entry->mask, octstr_get_cstr(entry->entry->boxc_id), 0); else sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES " "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d', '%s')", octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->field_ts), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->dlr_db_fields->field_status), octstr_get_cstr(box_fields->field_id), octstr_get_cstr(entry->entry->smsc), octstr_get_cstr(entry->entry->timestamp), octstr_get_cstr(entry->entry->source), octstr_get_cstr(entry->entry->destination), octstr_get_cstr(entry->entry->service), octstr_get_cstr(entry->entry->url), entry->entry->mask, octstr_get_cstr(entry->entry->boxc_id), 0, octstr_get_cstr(entry->id)); #if defined(DLR_TRACE) debug("dlr.sdb", 0, "SDB: sql: %s", octstr_get_cstr(sql)); #endif state = gw_sdb_query(octstr_get_cstr(sql), NULL, NULL); if (state == -1) error(0, "opensmppbox: SDB: error in inserting DLR for DST <%s>", octstr_get_cstr(entry->entry->destination)); octstr_destroy(sql); box_dlr_entry_destroy(entry); } static box_dlr_storage *box_dlr_init_sdb(Cfg *cfg) { CfgGroup *grp1, *grp2; List *grplist; Octstr *p = NULL; Octstr *sdb_url, *sdb_id; long pool_size; DBConf *db_conf = NULL; handles = gw_malloc(sizeof(box_dlr_storage)); handles->type = "sdb"; handles->dlr_add_with_id = dlr_sdb_add_with_id; handles->dlr_peek = dlr_sdb_peek; handles->dlr_shutdown = box_dlr_shutdown; /* * check for all mandatory directives that specify the field names * of the used SDB table */ if (!(grp1 = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "opensmppbox: DLR: SDB: group 'dlr-db' is not specified!"); if (!(sdb_id = cfg_get(grp1, octstr_imm("id")))) panic(0, "opensmppbox: DLR: SDB: directive 'id' is not specified!"); if (!(grp2 = cfg_get_single_group(cfg, octstr_imm("opensmppbox")))) panic(0, "opensmppbox: DLR: SDB: group 'opensmppbox' is not specified!"); box_fields = box_dlr_db_fields_create(grp1, grp2); /* * now grap the required information from the 'mysql-connection' group * with the sdb-id we just obtained * * we have to loop through all available SDB connection definitions * and search for the one we are looking for */ grplist = cfg_get_multi_group(cfg, octstr_imm("sdb-connection")); while (grplist && (grp1 = gwlist_extract_first(grplist)) != NULL) { p = cfg_get(grp1, octstr_imm("id")); if (p != NULL && octstr_compare(p, sdb_id) == 0) { goto found; } if (p != NULL) octstr_destroy(p); } panic(0, "opensmppbox: DLR: SDB: connection settings for id '%s' are not specified!", octstr_get_cstr(sdb_id)); found: octstr_destroy(p); gwlist_destroy(grplist, NULL); if (cfg_get_integer(&pool_size, grp1, octstr_imm("max-connections")) == -1 || pool_size == 0) pool_size = 1; if (!(sdb_url = cfg_get(grp1, octstr_imm("url")))) panic(0, "opensmppbox: DLR: SDB: directive 'url' is not specified!"); if (octstr_search(sdb_url, octstr_imm("oracle:"), 0) == 0) sdb_conn_type = SDB_ORACLE; else if (octstr_search(sdb_url, octstr_imm("mysql:"), 0) == 0) { warning(0, "DLR[sdb]: Please use native MySQL support, instead of libsdb."); sdb_conn_type = SDB_MYSQL; } else if (octstr_search(sdb_url, octstr_imm("postgres:"), 0) == 0) { sdb_conn_type = SDB_POSTGRES; } else sdb_conn_type = SDB_OTHER; /* * ok, ready to connect */ info(0,"opensmppbox connecting to sdb resource <%s>.", octstr_get_cstr(sdb_url)); db_conf = gw_malloc(sizeof(DBConf)); db_conf->sdb = gw_malloc(sizeof(SDBConf)); db_conf->sdb->url = sdb_url; box_pool = dbpool_create(DBPOOL_SDB, db_conf, pool_size); if (dbpool_conn_count(box_pool) == 0) panic(0,"opensmppbox: DLR: SDB: database pool has no connections!"); octstr_destroy(sdb_id); sdb_id = NULL; return handles; } #else /* * Return NULL , so we point dlr core that we were * not compiled in. */ static box_dlr_storage *box_dlr_init_sdb(Cfg *cfg) { return NULL; } #endif #ifdef HAVE_ORACLE static void dlr_oracle_add_with_id(box_dlr_entry *entry) { Octstr *sql, *os_mask; DBPoolConn *pconn; List *binds = gwlist_create(); int res; debug("opensmppbox", 0, "adding DLR entry wirh id into database"); pconn = dbpool_conn_consume(box_pool); /* just for sure */ if (!pconn) { box_dlr_entry_destroy(entry); return; } if (box_fields->field_id == NULL || octstr_len(box_fields->field_id) == 0) sql = octstr_format("INSERT INTO %S (%S, %S, %S, %S, %S, %S, %S, %S, %S) VALUES " "(:1, :2, :3, :4, :5, :6, :7, :8, 0)", box_fields->dlr_db_fields->table, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->field_ts, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_boxc, box_fields->dlr_db_fields->field_status); else sql = octstr_format("INSERT INTO %S (%S, %S, %S, %S, %S, %S, %S, %S, %S, %S) VALUES " "(:1, :2, :3, :4, :5, :6, :7, :8, :9, 0)", box_fields->dlr_db_fields->table, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->field_ts, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_status); os_mask = octstr_format("%d", entry->entry->mask); gwlist_append(binds, entry->entry->smsc); gwlist_append(binds, entry->entry->timestamp); gwlist_append(binds, entry->entry->source); gwlist_append(binds, entry->entry->destination); gwlist_append(binds, entry->entry->service); gwlist_append(binds, entry->entry->url); gwlist_append(binds, os_mask); gwlist_append(binds, entry->entry->boxc_id); if (box_fields->field_id && octstr_len(box_fields->field_id) > 0) gwlist_append(binds, entry->id); #if defined(DLR_TRACE) debug("opensmppbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if ((res = dbpool_conn_update(pconn, sql, binds)) == -1) error(0, "opensmppbox: DLR: ORACLE: Error while adding dlr entry for DST<%s>", octstr_get_cstr(entry->entry->destination)); else if (!res) warning(0, "opensmppbox: DLR: ORACLE: No dlr inserted for DST<%s>", octstr_get_cstr(entry->entry->destination)); dbpool_conn_produce(pconn); octstr_destroy(sql); gwlist_destroy(binds, NULL); octstr_destroy(os_mask); box_dlr_entry_destroy(entry); } static box_dlr_entry* dlr_oracle_peek(const Octstr *id, int use_smpp_id) { Octstr *sql, *like, *smpp_id; DBPoolConn *pconn; List *result = NULL, *row; box_dlr_entry *res = NULL; List *binds = gwlist_create(); pconn = dbpool_conn_consume(box_pool); if (pconn == NULL) /* should not happens, but sure is sure */ return NULL; if (use_smpp_id) { smpp_id = octstr_copy(id, 0, 8); like = octstr_format("LIKE '%s%%'", octstr_get_cstr(smpp_id)); sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE %S:1 %S ROWNUM < 2", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, like); octstr_destroy(smpp_id); } else sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE `%S`=:1 ROWNUM < 2", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id); gwlist_append(binds, (Octstr *)id); #if defined(DLR_TRACE) debug("opensmppbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if (dbpool_conn_select(pconn, sql, binds, &result) != 0) { octstr_destroy(sql); octstr_destroy(like); dbpool_conn_produce(pconn); return NULL; } octstr_destroy(sql); octstr_destroy(like); gwlist_destroy(binds, NULL); dbpool_conn_produce(pconn); #define LO2CSTR(r, i) octstr_get_cstr(gwlist_get(r, i)) if (gwlist_len(result) > 0) { row = gwlist_extract_first(result); res = box_dlr_entry_create(); res->entry->mask = atoi(LO2CSTR(row, 0)); res->entry->service = octstr_create(LO2CSTR(row, 1)); res->entry->url = octstr_create(LO2CSTR(row,2)); res->entry->source = octstr_create(LO2CSTR(row, 3)); res->entry->destination = octstr_create(LO2CSTR(row, 4)); res->entry->boxc_id = octstr_create(LO2CSTR(row, 5)); res->id = octstr_create(LO2CSTR(row, 6)); res->entry->smsc = octstr_create(LO2CSTR(row, 7)); gwlist_destroy(row, octstr_destroy_item); } gwlist_destroy(result, NULL); #undef LO2CSTR return res; } static box_dlr_storage *box_dlr_init_oracle(Cfg *cfg) { CfgGroup *grp1, *grp2; List *grplist; Octstr *p = NULL; Octstr *id, *username, *password, *tnsname; long pool_size; DBConf *db_conf = NULL; int found; handles = gw_malloc(sizeof(box_dlr_storage)); handles->type = "oracle"; handles->dlr_add_with_id = dlr_oracle_add_with_id; handles->dlr_peek = dlr_oracle_peek; handles->dlr_shutdown = box_dlr_shutdown; /* * check for all mandatory directives that specify the field names * of the used Oracle table */ if (!(grp1 = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "opensmppbox: DLR: Oracle: group 'dlr-db' is not specified!"); if (!(id = cfg_get(grp1, octstr_imm("id")))) panic(0, "opensmppbox: DLR: Oracle: directive 'id' is not specified!"); if (!(grp2 = cfg_get_single_group(cfg, octstr_imm("opensmppbox")))) panic(0, "opensmppbox: DLR: Oracle: group 'opensmppbox' is not specified!"); box_fields = box_dlr_db_fields_create(grp1, grp2); grplist = cfg_get_multi_group(cfg, octstr_imm("oracle-connection")); found = 0; while (grplist && (grp1 = gwlist_extract_first(grplist)) != NULL) { Octstr *p = cfg_get(grp1, octstr_imm("id")); if (p != NULL && octstr_compare(p, id) == 0) { found = 1; } if (p != NULL) octstr_destroy(p); if (found == 1) break; } gwlist_destroy(grplist, NULL); if (found == 0) panic(0, "Opensmppbox: DLR: ORACLE: connection settings for id '%s' are not specified!", octstr_get_cstr(id)); username = cfg_get(grp1, octstr_imm("username")); password = cfg_get(grp1, octstr_imm("password")); tnsname = cfg_get(grp1, octstr_imm("tnsname")); if (cfg_get_integer(&pool_size, grp1, octstr_imm("max-connections")) == -1) pool_size = 1; if (username == NULL || password == NULL || tnsname == NULL) panic(0, "opensmppbox: DLR: ORACLE: connection settings missing for id '%s', please" " check you configuration.",octstr_get_cstr(id)); /* ok we are ready to create dbpool */ db_conf = gw_malloc(sizeof(*db_conf)); db_conf->oracle = gw_malloc(sizeof(OracleConf)); db_conf->oracle->username = username; db_conf->oracle->password = password; db_conf->oracle->tnsname = tnsname; box_pool = dbpool_create(DBPOOL_ORACLE, db_conf, pool_size); if (dbpool_conn_count(box_pool) == 0) panic(0, "opensmppbox: DLR: ORACLE: Could not establish oracle connection(s)."); octstr_destroy(id); return handles; } #else /* no oracle support build in */ static box_dlr_storage *box_dlr_init_oracle(Cfg *cfg) { return NULL; } #endif /* * add box_dlr_entry to our list, and Kannel's, if storage type * is internal */ static void dlr_mem_add_with_id(box_dlr_entry *box_dlr, Msg *msg) { const char *type; /* Remove \0 from the end of the id.*/ octstr_delete(box_dlr->id, UUID_STR_LEN, 1); gw_rwlock_wrlock(&rwlock); gwlist_append(box_dlr_waiting_list, box_dlr); gw_rwlock_unlock(&rwlock); type = dlr_type(); if (strcmp(type, "internal") == 0) dlr_add(box_dlr->entry->smsc, box_dlr->entry->timestamp, msg); } /* * Return 0 if entry match and 1 if not. */ static int dlr_mem_entry_match(box_dlr_entry *box_dlr, const Octstr *id, int use_smpp_id) { if (use_smpp_id) { if (octstr_ncompare(box_dlr->id, id, 8) == 0) return 0; } else { if (octstr_compare(box_dlr->id, id) == 0) return 0; } return 1; } /* * Find matching entry and return copy of it, otherwise NULL */ static box_dlr_entry *dlr_mem_peek(const Octstr *id, int use_smpp_id) { long i; long len; box_dlr_entry *dlr = NULL, *ret = NULL; gw_rwlock_rdlock(&rwlock); len = gwlist_len(box_dlr_waiting_list); for (i=0; i < len; i++) { dlr = gwlist_get(box_dlr_waiting_list, i); if (dlr_mem_entry_match(dlr, id, use_smpp_id) == 0) { ret = box_dlr_entry_duplicate(dlr); break; } } gw_rwlock_unlock(&rwlock); /* we couldnt find a matching entry */ return ret; } /* * Destroy dlr_waiting_list. */ static void box_dlr_mem_shutdown() { gw_rwlock_wrlock(&rwlock); gwlist_destroy(box_dlr_waiting_list, (gwlist_item_destructor_t *)box_dlr_entry_destroy); gw_rwlock_unlock(&rwlock); gw_rwlock_destroy(&rwlock); } static box_dlr_storage *box_dlr_init_mem(Cfg *cfg) { handles = gw_malloc(sizeof(box_dlr_storage)); handles->type = "internal"; handles->dlr_add_mem_with_id = dlr_mem_add_with_id; handles->dlr_peek = dlr_mem_peek; handles->dlr_shutdown = box_dlr_mem_shutdown; box_dlr_waiting_list = gwlist_create(); gw_rwlock_init_static(&rwlock); return handles; } #ifdef HAVE_PGSQL static void dlr_pgsql_add_with_id(box_dlr_entry *entry) { Octstr *sql; DBPoolConn *pconn; debug("opensmppbox", 0, "adding DLR entry wirh id into database"); pconn = dbpool_conn_consume(box_pool); /* just for sure */ if (!pconn) { box_dlr_entry_destroy(entry); return; } if (box_fields->field_id == NULL || octstr_len(box_fields->field_id) == 0) sql = octstr_format("INSERT INTO \"%s\" (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\") VALUES " "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d');", octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->field_ts), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->dlr_db_fields->field_status), octstr_get_cstr(entry->entry->smsc), octstr_get_cstr(entry->entry->timestamp), octstr_get_cstr(entry->entry->source), octstr_get_cstr(entry->entry->destination), octstr_get_cstr(entry->entry->service), octstr_get_cstr(entry->entry->url), entry->entry->mask, octstr_get_cstr(entry->entry->boxc_id), 0); else sql = octstr_format("INSERT INTO \"%s\" (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\") VALUES " "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d', '%s');", octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->field_ts), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->dlr_db_fields->field_status), octstr_get_cstr(box_fields->field_id), octstr_get_cstr(entry->entry->smsc), octstr_get_cstr(entry->entry->timestamp), octstr_get_cstr(entry->entry->source), octstr_get_cstr(entry->entry->destination), octstr_get_cstr(entry->entry->service), octstr_get_cstr(entry->entry->url), entry->entry->mask, octstr_get_cstr(entry->entry->boxc_id), 0, octstr_get_cstr(entry->id)); if (dbpool_conn_update(pconn, sql, NULL) == -1) error(0, "opensmppbox: PGSQL: DB update failed!"); dbpool_conn_produce(pconn); octstr_destroy(sql); box_dlr_entry_destroy(entry); } static box_dlr_entry *dlr_pgsql_peek(const Octstr *id, int use_smpp_id) { Octstr *sql = NULL, *like = NULL, *smpp_id = NULL; List *result = NULL, *row = NULL; box_dlr_entry *res = NULL; DBPoolConn *pconn; pconn = dbpool_conn_consume(box_pool); if (pconn == NULL) /* should not happens, but sure is sure */ return NULL; if (use_smpp_id) { smpp_id = octstr_copy(id, 0, 8); like = octstr_format("LIKE '%s%%'", octstr_get_cstr(smpp_id)); sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE %S %S LIMIT 1", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, like); octstr_destroy(smpp_id); } else sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE %S='%S' LIMIT 1", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, id); if (dbpool_conn_select(pconn, sql, NULL, &result) == -1) error(0, "opensmppbox: PGSQL: Select failed!"); if (result == NULL || gwlist_len(result) < 1) { debug("opensmppbox", 0, "PGSQL: no rows found"); gwlist_destroy(result, NULL); octstr_destroy(sql); octstr_destroy(like); return NULL; } /* Note that we used id as search key; it is unique so we would have oly one * result row. */ row = gwlist_get(result, 0); res = box_dlr_entry_create(); res->entry->mask = atoi(octstr_get_cstr(gwlist_get(row, 0))); res->entry->service = octstr_duplicate(gwlist_get(row, 1)); res->entry->url = octstr_duplicate(gwlist_get(row, 2)); res->entry->source = octstr_duplicate(gwlist_get(row, 3)); res->entry->destination = octstr_duplicate(gwlist_get(row, 4)); res->entry->boxc_id = octstr_duplicate(gwlist_get(row, 5)); res->id = octstr_duplicate(gwlist_get(row, 6)); res->entry->smsc = octstr_duplicate(gwlist_get(row, 7)); while((row = gwlist_extract_first(result))) gwlist_destroy(row, octstr_destroy_item); gwlist_destroy(result, NULL); gwlist_destroy(row, octstr_destroy_item); dbpool_conn_produce(pconn); octstr_destroy(sql); octstr_destroy(like); return res; } static box_dlr_storage *box_dlr_init_pgsql(Cfg *cfg) { CfgGroup *grp1, *grp2; List *grplist; Octstr *pgsql_host, *pgsql_user, *pgsql_pass, *pgsql_db, *pgsql_id; long pgsql_port = 0; Octstr *p = NULL; long pool_size; DBConf *db_conf = NULL; handles = gw_malloc(sizeof(box_dlr_storage)); handles->type = "pgsql"; handles->dlr_add_with_id = dlr_pgsql_add_with_id; handles->dlr_peek = dlr_pgsql_peek; handles->dlr_shutdown = box_dlr_shutdown; /* * check for all mandatory directives that specify the field names * of the used Oracle table */ if (!(grp1 = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "opensmppbox: DLR: PgSQL: group 'dlr-db' is not specified!"); if (!(pgsql_id = cfg_get(grp1, octstr_imm("id")))) panic(0, "opensmppbox: DLR: PgSQL: directive 'id' is not specified!"); if (!(grp2 = cfg_get_single_group(cfg, octstr_imm("opensmppbox")))) panic(0, "opensmppbox: DLR: PgSQL: group 'opensmppbox' is not specified!"); box_fields = box_dlr_db_fields_create(grp1, grp2); /* * Escaping special quotes for field/table names */ octstr_replace(box_fields->dlr_db_fields->table, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_smsc, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_ts, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_src, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_dst, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_serv, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_url, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_mask, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_status, octstr_imm("\""), octstr_imm("\"\"")); octstr_replace(box_fields->dlr_db_fields->field_boxc, octstr_imm("\""), octstr_imm("\"\"")); if (box_fields->field_id && octstr_len(box_fields->field_id) > 0) octstr_replace(box_fields->field_id, octstr_imm("`"), octstr_imm("``")); /* * now grap the required information from the 'pgsql-connection' group * with the pgsql-id we just obtained * * we have to loop through all available PgSQL connection definitions * and search for the one we are looking for */ grplist = cfg_get_multi_group(cfg, octstr_imm("pgsql-connection")); while (grplist && (grp1 = gwlist_extract_first(grplist)) != NULL) { p = cfg_get(grp1, octstr_imm("id")); if (p != NULL && octstr_compare(p, pgsql_id) == 0) { goto found; } if (p != NULL) octstr_destroy(p); } panic(0, "opensmppbox: DLR: PgSQL: connection settings for id '%s' are not specified!", octstr_get_cstr(pgsql_id)); found: octstr_destroy(p); gwlist_destroy(grplist, NULL); if (cfg_get_integer(&pool_size, grp1, octstr_imm("max-connections")) == -1 || pool_size == 0) pool_size = 1; if (!(pgsql_host = cfg_get(grp1, octstr_imm("host")))) panic(0, "opensmppbox: DLR: PgSQL: directive 'host' is not specified!"); if (!(pgsql_user = cfg_get(grp1, octstr_imm("username")))) panic(0, "opensmppbox: DLR: PgSQL: directive 'username' is not specified!"); if (!(pgsql_pass = cfg_get(grp1, octstr_imm("password")))) panic(0, "opendmppbox: DLR: PgSQL: directive 'password' is not specified!"); if (!(pgsql_db = cfg_get(grp1, octstr_imm("database")))) panic(0, "DLR: PgSQL: directive 'database' is not specified!"); cfg_get_integer(&pgsql_port, grp1, octstr_imm("port")); /* optional */ /* * ok, ready to connect to the database */ db_conf = gw_malloc(sizeof(DBConf)); db_conf->pgsql = gw_malloc(sizeof(PgSQLConf)); db_conf->pgsql->host = pgsql_host; db_conf->pgsql->port = pgsql_port; db_conf->pgsql->username = pgsql_user; db_conf->pgsql->password = pgsql_pass; db_conf->pgsql->database = pgsql_db; box_pool = dbpool_create(DBPOOL_PGSQL, db_conf, pool_size); if (dbpool_conn_count(box_pool) == 0) panic(0,"DLR: PgSQL: database pool has no connections!"); octstr_destroy(pgsql_id); return handles; } #else /* * Return NULL , so we point dlr core that we were * not compiled in. */ static box_dlr_storage *box_dlr_init_pgsql(Cfg *cfg) { return NULL; } #endif #ifdef HAVE_MSSQL static void dlr_mssql_add_with_id(box_dlr_entry *entry) { Octstr *sql; DBPoolConn *pconn; int res; debug("opensmppbox", 0, "adding DLR entry with id into database"); pconn = dbpool_conn_consume(box_pool); /* just for sure */ if (!pconn) { box_dlr_entry_destroy(entry); return; } if (box_fields->field_id == NULL || octstr_len(box_fields->field_id) == 0) sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES " "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d')", octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->field_ts), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->dlr_db_fields->field_status), octstr_get_cstr(entry->entry->smsc), octstr_get_cstr(entry->entry->timestamp), octstr_get_cstr(entry->entry->source), octstr_get_cstr(entry->entry->destination), octstr_get_cstr(entry->entry->service), octstr_get_cstr(entry->entry->url), entry->entry->mask, octstr_get_cstr(entry->entry->boxc_id), 0); else sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES " "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d', '%s')", octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->field_ts), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->dlr_db_fields->field_status), octstr_get_cstr(box_fields->field_id), octstr_get_cstr(entry->entry->smsc), octstr_get_cstr(entry->entry->timestamp), octstr_get_cstr(entry->entry->source), octstr_get_cstr(entry->entry->destination), octstr_get_cstr(entry->entry->service), octstr_get_cstr(entry->entry->url), entry->entry->mask, octstr_get_cstr(entry->entry->boxc_id), 0, octstr_get_cstr(entry->id)); #if defined(DLR_TRACE) debug("opensmmpbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if ((res = dbpool_conn_update(pconn, sql, NULL)) == -1) error(0, "opensmppbox: DLR: MSSQL: Error while adding dlr entry for DST<%s>", octstr_get_cstr(entry->entry->destination)); dbpool_conn_produce(pconn); octstr_destroy(sql); box_dlr_entry_destroy(entry); } static box_dlr_entry *dlr_mssql_peek(const Octstr *id, int use_smpp_id) { Octstr *sql, *like, *smpp_id; List *result = NULL, *row; box_dlr_entry *res = NULL; DBPoolConn *pconn; pconn = dbpool_conn_consume(box_pool); if (pconn == NULL) /* should not happens, but sure is sure */ return NULL; if (use_smpp_id) { smpp_id = octstr_copy(id, 0, 8); like = octstr_format("LIKE '%s%%'", octstr_get_cstr(smpp_id)); sql = octstr_format("SELECT TOP 1 %s, %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s %s", octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->field_id), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->field_id), octstr_get_cstr(like)); octstr_destroy(smpp_id); octstr_destroy(like); } else sql = octstr_format("SELECT TOP 1 %s, %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s'", octstr_get_cstr(box_fields->dlr_db_fields->field_mask), octstr_get_cstr(box_fields->dlr_db_fields->field_serv), octstr_get_cstr(box_fields->dlr_db_fields->field_url), octstr_get_cstr(box_fields->dlr_db_fields->field_src), octstr_get_cstr(box_fields->dlr_db_fields->field_dst), octstr_get_cstr(box_fields->dlr_db_fields->field_boxc), octstr_get_cstr(box_fields->field_id), octstr_get_cstr(box_fields->dlr_db_fields->field_smsc), octstr_get_cstr(box_fields->dlr_db_fields->table), octstr_get_cstr(box_fields->field_id), octstr_get_cstr(id)); #if defined(DLR_TRACE) debug("opensmppbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if (dbpool_conn_select(pconn, sql, NULL, &result) != 0) { octstr_destroy(sql); dbpool_conn_produce(pconn); return NULL; } octstr_destroy(sql); dbpool_conn_produce(pconn); #define LO2CSTR(r, i) octstr_get_cstr(gwlist_get(r, i)) if (gwlist_len(result) > 0) { row = gwlist_extract_first(result); res = box_dlr_entry_create(); res->entry->mask = atoi(LO2CSTR(row,0)); res->entry->service = octstr_create(LO2CSTR(row, 1)); res->entry->url = octstr_create(LO2CSTR(row,2)); res->entry->source = octstr_create(LO2CSTR(row, 3)); res->entry->destination = octstr_create(LO2CSTR(row, 4)); res->entry->boxc_id = octstr_create(LO2CSTR(row, 5)); res->id = octstr_create(LO2CSTR(row, 6)); res->entry->smsc = octstr_create(LO2CSTR(row, 7)); gwlist_destroy(row, octstr_destroy_item); } gwlist_destroy(result, NULL); #undef LO2CSTR return res; } static box_dlr_storage *box_dlr_init_mssql(Cfg *cfg) { CfgGroup *grp1, *grp2; List *grplist; long pool_size; DBConf *db_conf = NULL; Octstr *id, *username, *password, *server, *database; int found; handles = gw_malloc(sizeof(box_dlr_storage)); handles->type = "mssql"; handles->dlr_add_with_id = dlr_mssql_add_with_id; handles->dlr_peek = dlr_mssql_peek; handles->dlr_shutdown = box_dlr_shutdown; /* * check for all mandatory directives that specify the field names * of the used MSSQL table */ if (!(grp1 = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "opensmppbox: DLR: MSSQL: group 'dlr-db' is not specified!"); if (!(id = cfg_get(grp1, octstr_imm("id")))) panic(0, "opensmppbox: DLR: MSSQL: directive 'id' is not specified!"); if (!(grp2 = cfg_get_single_group(cfg, octstr_imm("opensmppbox")))) panic(0, "opensmppbox: DLR: MSSQL: group 'opensmppbox' is not specified!"); box_fields = box_dlr_db_fields_create(grp1, grp2); grplist = cfg_get_multi_group(cfg, octstr_imm("mssql-connection")); found = 0; while (grplist && (grp1 = gwlist_extract_first(grplist)) != NULL) { Octstr *p = cfg_get(grp1, octstr_imm("id")); if (p != NULL && octstr_compare(p, id) == 0) { found = 1; } if (p != NULL) octstr_destroy(p); if (found == 1) break; } gwlist_destroy(grplist, NULL); if (found == 0) panic(0, "opensmppbox: DLR: MSSQL: connection settings for id '%s' are not specified!", octstr_get_cstr(id)); username = cfg_get(grp1, octstr_imm("username")); password = cfg_get(grp1, octstr_imm("password")); server = cfg_get(grp1, octstr_imm("server")); database = cfg_get(grp1, octstr_imm("database")); if (cfg_get_integer(&pool_size, grp1, octstr_imm("max-connections")) == -1) pool_size = 1; if (username == NULL || password == NULL || server == NULL || database == NULL) { panic(0, "opensmppbox: DLR: MSSQL: connection settings missing for id '%s'. " "Please check you configuration.", octstr_get_cstr(id)); } /* ok we are ready to create dbpool */ db_conf = gw_malloc(sizeof(*db_conf)); db_conf->mssql = gw_malloc(sizeof(MSSQLConf)); db_conf->mssql->username = username; db_conf->mssql->password = password; db_conf->mssql->server = server; db_conf->mssql->database = database; box_pool = dbpool_create(DBPOOL_MSSQL, db_conf, pool_size); if (dbpool_conn_count(box_pool) == 0) panic(0, "opensmppbox: DLR: MSSQL: Could not establish mssql connection(s)."); octstr_destroy(id); octstr_destroy(database); return handles; } #else /* no mssql support build in */ static box_dlr_storage *box_dlr_init_mssql(Cfg *cfg) { return NULL; } #endif #ifdef HAVE_SQLITE3 static void dlr_sqlite3_add_with_id(box_dlr_entry *entry) { Octstr *sql, *os_mask; DBPoolConn *pconn; List *binds = gwlist_create(); int res; debug("opensmppbox", 0, "adding DLR entry into database"); pconn = dbpool_conn_consume(box_pool); /* just for sure */ if (pconn == NULL) { box_dlr_entry_destroy(entry); return; } if (box_fields->field_id == NULL || octstr_len(box_fields->field_id) == 0) sql = octstr_format("INSERT INTO %S (%S, %S, %S, %S, %S, %S, %S, %S, %S) VALUES " "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, 0)", box_fields->dlr_db_fields->table, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->field_ts, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_boxc, box_fields->dlr_db_fields->field_status); else sql = octstr_format("INSERT INTO %S (%S, %S, %S, %S, %S, %S, %S, %S, %S, %S) VALUES " "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, 0, ?9)", box_fields->dlr_db_fields->table, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->field_ts, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_boxc, box_fields->dlr_db_fields->field_status, box_fields->field_id); 1 #if defined(DLR_TRACE) debug("opensmmpbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif os_mask = octstr_format("%d", entry->entry->mask); gwlist_append(binds, entry->entry->smsc); /* ?1 */ gwlist_append(binds, entry->entry->timestamp); /* ?2 */ gwlist_append(binds, entry->entry->source); /* ?3 */ gwlist_append(binds, entry->entry->destination); /* ?4 */ gwlist_append(binds, entry->entry->service); /* ?5 */ gwlist_append(binds, entry->entry->url); /* ?6 */ gwlist_append(binds, os_mask); /* ?7 */ gwlist_append(binds, entry->entry->boxc_id); /* ?8 */ if (box_fields->field_id && octstr_len(box_fields->field_id) > 0) gwlist_append(binds, entry->id); /* ?9 */ #if defined(DLR_TRACE) debug("opensmppbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if ((res = dbpool_conn_update(pconn, sql, binds)) == -1) error(0, "DLR: SQLite3: Error while adding dlr entry for DST<%s>", octstr_get_cstr(entry->entry->destination)); else if (!res) warning(0, "DLR: SQLite3: No dlr inserted for DST<%s>", octstr_get_cstr(entry->entry->destination)); dbpool_conn_produce(pconn); octstr_destroy(sql); gwlist_destroy(binds, NULL); octstr_destroy(os_mask); box_dlr_entry_destroy(entry); } static box_dlr_entry *dlr_sqlite3_peek(const Octstr *id, int use_smpp_id) { Octstr *sql = NULL, *like = NULL, *smpp_id = NULL; DBPoolConn *pconn = NULL; List *result = NULL, *row = NULL; box_dlr_entry *res = NULL; List *binds = gwlist_create(); pconn = dbpool_conn_consume(box_pool); if (pconn == NULL) /* should not happens, but sure is sure */ return NULL; if (use_smpp_id) { smpp_id = octstr_copy(id, 0, 8); like = octstr_format("LIKE '%s%%'", octstr_get_cstr(smpp_id)); sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE %S %S LIMIT 1", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, like); octstr_destroy(smpp_id); } else { like = octstr_format("LIKE '%s'", octstr_get_cstr(id)); sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S, %S, %S FROM %S WHERE %S %S LIMIT 1", box_fields->dlr_db_fields->field_mask, box_fields->dlr_db_fields->field_serv, box_fields->dlr_db_fields->field_url, box_fields->dlr_db_fields->field_src, box_fields->dlr_db_fields->field_dst, box_fields->dlr_db_fields->field_boxc, box_fields->field_id, box_fields->dlr_db_fields->field_smsc, box_fields->dlr_db_fields->table, box_fields->field_id, like); } #if defined(DLR_TRACE) debug("opensmppbox", 0, "sql: %s", octstr_get_cstr(sql)); #endif if (dbpool_conn_select(pconn, sql, binds, &result) != 0) { octstr_destroy(sql); dbpool_conn_produce(pconn); return NULL; } dbpool_conn_produce(pconn); octstr_destroy(sql); octstr_destroy(like); gwlist_destroy(binds, NULL); #define LO2CSTR(r, i) octstr_get_cstr(gwlist_get(r, i)) /* We have only one roe - we asked only for one. */ if (gwlist_len(result) > 0) { row = gwlist_extract_first(result); res = box_dlr_entry_create(); res->entry->mask = atoi(LO2CSTR(row,0)); res->entry->service = octstr_create(LO2CSTR(row, 1)); res->entry->url = octstr_create(LO2CSTR(row,2)); res->entry->source = octstr_create(LO2CSTR(row, 3)); res->entry->destination = octstr_create(LO2CSTR(row, 4)); res->entry->boxc_id = octstr_create(LO2CSTR(row, 5)); res->id = octstr_create(LO2CSTR(row,6)); res->entry->smsc = octstr_create(LO2CSTR(row,7)); gwlist_destroy(row, octstr_destroy_item); } gwlist_destroy(result, NULL); #undef LO2CSTR return res; } static box_dlr_storage *box_dlr_init_sqlite3(Cfg *cfg) { CfgGroup *grp1, *grp2; List *grplist; long pool_size; DBConf *db_conf = NULL; Octstr *id, *file; int found; handles = gw_malloc(sizeof(box_dlr_storage)); handles->type = "sqlite3"; handles->dlr_add_with_id = dlr_sqlite3_add_with_id; handles->dlr_peek = dlr_sqlite3_peek; handles->dlr_shutdown = box_dlr_shutdown; /* * check for all mandatory directives that specify the field names * of the used SQLite table */ if (!(grp1 = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "opensmppbox: DLR: SQLite3: group 'dlr-db' is not specified!"); if (!(id = cfg_get(grp1, octstr_imm("id")))) panic(0, "opensmppbox: DLR: SQLite3: directive 'id' is not specified!"); if (!(grp2 = cfg_get_single_group(cfg, octstr_imm("opensmppbox")))) panic(0, "opensmppbox: DLR: SQLite3: group 'opensmppbox' is not specified!"); box_fields = box_dlr_db_fields_create(grp1, grp2); grplist = cfg_get_multi_group(cfg, octstr_imm("sqlite3-connection")); found = 0; while (grplist && (grp1 = gwlist_extract_first(grplist)) != NULL) { Octstr *p = cfg_get(grp1, octstr_imm("id")); if (p != NULL && octstr_compare(p, id) == 0) { found = 1; } if (p != NULL) octstr_destroy(p); if (found == 1) break; } gwlist_destroy(grplist, NULL); if (found == 0) panic(0, "opensmppbox: DLR: SQLite3: connection settings for id '%s' are not specified!", octstr_get_cstr(id)); file = cfg_get(grp1, octstr_imm("database")); if (cfg_get_integer(&pool_size, grp1, octstr_imm("max-connections")) == -1) pool_size = 1; if (file == NULL) panic(0, "opensmppbox: DLR: SQLite3: connection settings missing for id '%s', please" " check you configuration.",octstr_get_cstr(id)); /* ok we are ready to create dbpool */ db_conf = gw_malloc(sizeof(*db_conf)); db_conf->sqlite3 = gw_malloc(sizeof(SQLite3Conf)); db_conf->sqlite3->file = file; box_pool = dbpool_create(DBPOOL_SQLITE3, db_conf, pool_size); if (dbpool_conn_count(box_pool) == 0) panic(0, "DLR: SQLite3: Could not establish sqlite3 connection(s)."); octstr_destroy(id); return handles; } #else /* no sqlite3 support build in */ static box_dlr_storage *box_dlr_init_sqlite3(Cfg *cfg) { return NULL; } #endif