/* Check if the connection is alive and usable */ static int mongodb_check_conn(void *mconn) { int res = 0; mongo_connection *conn = (mongo_connection*)mconn; if (conn == NULL || mongo_conf == NULL) { return -1; } if (!conn->connected) { return -1; } MONGO_TRY { if (!mongodb_cmd_ping(conn, octstr_get_cstr(mongo_conf->database))) { res = -1; } } MONGO_CATCH { error(0, "MongoDB: mongodb_check_conn failed!"); res = -1; } return res; }
static List *make_reply_headers(WSPMachine *m) { List *headers; Octstr *encoding_version; /* Add all server wsp level hop-by-hop headers. Currently only * Encoding-Version, as defined by wsp, chapter 8.4.2.70. * What headers belong to which version is defined in appendix A, * table 39.. encoding_version = request_version = NULL; * Essentially, if the client sends us an Encoding-Version * higher than ours (1.3) we send our version number to it, * if it is lower, we left version number intact. */ /* First the case that we have no Encoding-Version header at all. * This case we must assume that the client supports version 1.2 * or lower. */ headers = http_create_empty_headers(); encoding_version = wsp_encoding_version_to_string(m->encoding_version); http_header_add(headers, "Encoding-Version", octstr_get_cstr(encoding_version)); octstr_destroy(encoding_version); return headers; }
static void mime_entity_dump_real(MIMEEntity *m, unsigned int level) { long i, items; Octstr *prefix, *type, *charset; Octstr *tmp; unsigned int j; gw_assert(m != NULL && m->headers != NULL); prefix = octstr_create(""); for (j = 0; j < level * 2; j++) octstr_append_cstr(prefix, " "); http_header_get_content_type(m->headers, &type, &charset); debug("mime.dump",0,"%sContent-Type `%s'", octstr_get_cstr(prefix), octstr_get_cstr(type)); for(i = 0; i < gwlist_len(m->headers); i++) { tmp = gwlist_get(m->headers,i); debug("mime.dump",0, "Header: %s", octstr_get_cstr(tmp)); } if (m->start != NULL) { Octstr *cid = http_header_value(m->start->headers, octstr_imm("Content-ID")); debug("mime.dump",0,"%sRelated to Content-ID <%s> MIMEEntity at address `%p'", octstr_get_cstr(prefix), octstr_get_cstr(cid), m->start); octstr_destroy(cid); } items = gwlist_len(m->multiparts); debug("mime.dump",0,"%sBody contains %ld MIME entities, size %ld", octstr_get_cstr(prefix), items, (items == 0 && m->body) ? octstr_len(m->body) : -1); octstr_destroy(prefix); octstr_destroy(type); octstr_destroy(charset); for (i = 0; i < items; i++) { MIMEEntity *e = gwlist_get(m->multiparts, i); mime_entity_dump_real(e, level + 1); } }
int main(int argc, char **argv) { Octstr *mime_content, *pap_content, *push_data, *rdf_content, *boundary, *push_content_file = NULL, *this_header, *pap_osname, *data_osname; List *content_headers, *source_parts; char *pap_content_file, *push_data_file, *rdf_content_file; int ret, std_out, opt, d_file, c_file; FILE *fp1, *fp2, *fp3; gwlib_init(); std_out = 0; d_file = 0; c_file = 0; data_osname = NULL; pap_osname = NULL; while ((opt = getopt(argc, argv, "hd:sc:")) != EOF) { switch(opt) { case 'h': help(); exit(1); break; case 'd': d_file = 1; data_osname = octstr_create(optarg); break; case 'c': c_file = 1; pap_osname = octstr_create(optarg); break; case 's': std_out = 1; break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping"); break; } } if (optind >= argc) { help(); panic(0, "missing arguments, stopping"); } if (!c_file) pap_content_file = "test/pap.txt"; else pap_content_file = octstr_get_cstr(pap_osname); if (!d_file) push_data_file = "test/data.txt"; else push_data_file = octstr_get_cstr(data_osname); rdf_content_file = "test/rdf.txt"; mime_content = octstr_read_file(argv[optind]); if (mime_content == NULL) { octstr_destroy(mime_content); error(0, "No MIME source"); panic(0, "Stopping"); } source_parts = octstr_split(mime_content, octstr_imm("content=")); if (gwlist_len(source_parts) == 1) { /* a hack to circumvent a bug */ error(0, "Badly formatted source:"); octstr_destroy(mime_content); gwlist_destroy(source_parts, octstr_destroy_item); panic(0, "Stopping"); } boundary = gwlist_extract_first(source_parts); octstr_delete(boundary, 0, octstr_len(octstr_imm("boundary="))); if (skip_tail(&boundary, ';') == 0) { error(0, "Cannot determine boundary, no delimiter; possible"); octstr_dump(boundary, 0); goto no_parse; } octstr_destroy(mime_content); mime_content = gwlist_extract_first(source_parts); if (skip_tail(&mime_content, ';') == 0){ error(0, "Cannot determine mime content, no delimiter"); octstr_dump(mime_content, 0); goto no_parse; } prepend_crlf(&mime_content); add_crs(mime_content); append_crlf(mime_content); ret = mime_parse(boundary, mime_content, &pap_content, &push_data, &content_headers, &rdf_content); if (ret == 0) { error(0, "Mime_parse returned 0, cannot continue"); goto error; } remove_crs(pap_content); if (!std_out) { fp1 = fopen(pap_content_file, "a"); if (fp1 == NULL) { error(0, "Cannot open the file for pap control message"); goto error; } octstr_print(fp1, pap_content); debug("test.mime", 0, "pap control message appended to the file"); fclose(fp1); } else { debug("test.mime", 0, "pap control message was"); octstr_dump(pap_content, 0); } remove_crs(push_data); if (!std_out) { fp2 = fopen(push_data_file, "a"); if (fp2 == NULL) { error(0, "Cannot open the push data file"); goto error; } push_content_file = octstr_create(""); octstr_append(push_content_file, octstr_imm("headers=")); while (gwlist_len(content_headers) > 0) { octstr_append(push_content_file, this_header = gwlist_extract_first(content_headers)); octstr_format_append(push_content_file, "%c", ' '); octstr_destroy(this_header); } octstr_append(push_content_file, octstr_imm(";\n")); octstr_append(push_content_file, octstr_imm("content=")); octstr_append(push_content_file, push_data); octstr_append(push_content_file, octstr_imm(";\n")); octstr_print(fp2, push_content_file); debug("test.mime", 0, "push content appended to the file"); fclose(fp2); } else { debug("test.mime", 0, "Content headers were"); http_header_dump(content_headers); debug("test.mime", 0, "And push content itself"); octstr_dump(push_data, 0); } if (rdf_content != NULL) remove_crs(rdf_content); if (!std_out && rdf_content != NULL) { fp3 = NULL; if (rdf_content != NULL) { fp3 = fopen(rdf_content_file, "a"); if (fp3 == NULL) { error(0, "Cannot open the rdf file"); goto cerror; } octstr_print(fp3, rdf_content); debug("test.mime", 0, "push caps message appended to the file"); fclose(fp3); } } else { if (rdf_content != NULL) { debug("test.mime", 0, "push caps message was"); octstr_dump(rdf_content, 0); } } octstr_destroy(boundary); octstr_destroy(mime_content); octstr_destroy(pap_content); octstr_destroy(push_data); octstr_destroy(rdf_content); octstr_destroy(pap_osname); octstr_destroy(data_osname); http_destroy_headers(content_headers); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(push_content_file); gwlib_shutdown(); info(0, "MIME data parsed successfully"); return 0; no_parse: octstr_destroy(mime_content); octstr_destroy(pap_osname); octstr_destroy(data_osname); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(boundary); gwlib_shutdown(); panic(0, "Stopping"); error: octstr_destroy(mime_content); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(boundary); octstr_destroy(pap_content); octstr_destroy(push_data); octstr_destroy(pap_osname); octstr_destroy(data_osname); http_destroy_headers(content_headers); octstr_destroy(rdf_content); gwlib_shutdown(); panic(0, "Stopping"); cerror: octstr_destroy(mime_content); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(boundary); octstr_destroy(pap_content); octstr_destroy(push_data); octstr_destroy(push_content_file); octstr_destroy(pap_osname); octstr_destroy(data_osname); http_destroy_headers(content_headers); octstr_destroy(rdf_content); gwlib_shutdown(); panic(0, "Stopping"); /* return after panic always required by gcc */ return 1; }
static void* oracle_open_conn(const DBConf *db_conf) { OracleConf *cfg = db_conf->oracle; sword errorcode = 0; text version[512]; struct ora_conn *conn = gw_malloc(sizeof(struct ora_conn)); gw_assert(conn != NULL); memset(conn, 0, sizeof(struct ora_conn)); debug("dbpool.oracle",0,"oracle_open_conn called"); /* init OCI environment */ errorcode = OCIEnvCreate(&conn->envp, OCI_THREADED|OCI_ENV_NO_MUTEX, NULL, oracle_malloc, oracle_realloc, oracle_free, 0,0); if (errorcode != OCI_SUCCESS) { oracle_checkerr(NULL, errorcode); error(0, "Got error while OCIEnvCreate %d", errorcode); gw_free(conn); return NULL; } debug("dbpool.oracle",0,"oci environment created"); /* allocate error handle */ errorcode = OCIHandleAlloc(conn->envp, (dvoid**) &conn->errhp, OCI_HTYPE_ERROR, 0, 0); if (errorcode != OCI_SUCCESS) { oracle_checkerr(NULL, errorcode); OCIHandleFree(conn->envp, OCI_HTYPE_ENV); gw_free(conn); return NULL; } debug("dbpool.oracle",0,"oci error handle allocated"); /* open oracle user session */ errorcode = OCILogon(conn->envp, conn->errhp, &conn->svchp, (unsigned char*)octstr_get_cstr(cfg->username), octstr_len(cfg->username), (unsigned char*)octstr_get_cstr(cfg->password), octstr_len(cfg->password), (unsigned char*)octstr_get_cstr(cfg->tnsname), octstr_len(cfg->tnsname)); if (errorcode != OCI_SUCCESS) { oracle_checkerr(conn->errhp, errorcode); OCIHandleFree(conn->errhp, OCI_HTYPE_ERROR); OCIHandleFree(conn->envp, OCI_HTYPE_ENV); gw_free(conn); return NULL; } debug("dbpool.oracle",0,"connected to database"); errorcode = OCIServerVersion(conn->svchp, conn->errhp, version, sizeof(version), OCI_HTYPE_SVCCTX); if (errorcode != OCI_SUCCESS) { oracle_checkerr(conn->errhp, errorcode); } else { info(0, "Connected to: %s", version); } return conn; }
static Octstr *get_pattern(SMSCConn *conn, Msg *msg, const char *message) { int nextarg, j; struct tm tm; int num_words; List *word_list; Octstr *result; const char *pattern; Octstr *temp, *text, *udh; size_t n; long i; text = msg->sms.msgdata ? octstr_duplicate(msg->sms.msgdata) : octstr_create(""); udh = msg->sms.udhdata ? octstr_duplicate(msg->sms.udhdata) : octstr_create(""); if ((msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2)) octstr_binary_to_hex(text, 1); else octstr_convert_printable(text); octstr_binary_to_hex(udh, 1); if (octstr_len(text)) { word_list = octstr_split_words(text); num_words = gwlist_len(word_list); } else { word_list = gwlist_create(); num_words = 0; } result = octstr_create(""); pattern = octstr_get_cstr(custom_log_format); nextarg = 1; while(*pattern != '\0') { n = strcspn(pattern, "%"); octstr_append_data(result, pattern, n); pattern += n; gw_assert(*pattern == '%' || *pattern == '\0'); if (*pattern == '\0') break; pattern++; switch (*pattern) { case 'k': if (num_words <= 0) break; octstr_append(result, gwlist_get(word_list, 0)); break; case 's': if (nextarg >= num_words) break; octstr_append(result, gwlist_get(word_list, nextarg)); ++nextarg; break; case 'S': if (nextarg >= num_words) break; temp = gwlist_get(word_list, nextarg); for (i = 0; i < octstr_len(temp); ++i) { if (octstr_get_char(temp, i) == '*') octstr_append_char(result, '~'); else octstr_append_char(result, octstr_get_char(temp, i)); } ++nextarg; break; case 'r': for (j = nextarg; j < num_words; ++j) { if (j != nextarg) octstr_append_char(result, '+'); octstr_append(result, gwlist_get(word_list, j)); } break; case 'l': if (message) octstr_append_cstr(result, message); break; case 'P': if (msg->sms.receiver) octstr_append(result, msg->sms.receiver); break; case 'p': if (msg->sms.sender) octstr_append(result, msg->sms.sender); break; case 'a': for (j = 0; j < num_words; ++j) { if (j > 0) octstr_append_char(result, ' '); octstr_append(result, gwlist_get(word_list, j)); } break; case 'b': if (text) octstr_append(result, text); break; case 'L': octstr_append_decimal(result, octstr_len(msg->sms.msgdata)); break; case 't': tm = gw_gmtime(msg->sms.time); octstr_format_append(result, "%04d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); break; case 'T': if (msg->sms.time != MSG_PARAM_UNDEFINED) octstr_format_append(result, "%ld", msg->sms.time); break; case 'i': if (conn && smscconn_id(conn)) octstr_append(result, smscconn_id(conn)); else if (conn && smscconn_name(conn)) octstr_append(result, smscconn_name(conn)); else if (msg->sms.smsc_id) octstr_append(result, msg->sms.smsc_id); break; case 'I': if (!uuid_is_null(msg->sms.id)) { char id[UUID_STR_LEN + 1]; uuid_unparse(msg->sms.id, id); octstr_append_cstr(result, id); } break; case 'n': if (msg->sms.service != NULL) octstr_append(result, msg->sms.service); break; case 'd': octstr_append_decimal(result, msg->sms.dlr_mask); break; case 'c': octstr_append_decimal(result, msg->sms.coding); break; case 'm': octstr_append_decimal(result, msg->sms.mclass); break; case 'C': octstr_append_decimal(result, msg->sms.compress); break; case 'M': octstr_append_decimal(result, msg->sms.mwi); break; case 'u': if (octstr_len(udh)) { octstr_append(result, udh); } break; case 'U': octstr_append_decimal(result, octstr_len(msg->sms.udhdata)); break; case 'B': /* billing identifier/information */ if (octstr_len(msg->sms.binfo)) { octstr_append(result, msg->sms.binfo); } break; case 'A': /* account */ if (octstr_len(msg->sms.account)) { octstr_append(result, msg->sms.account); } break; /* XXX add more here if needed */ case '%': octstr_format_append(result, "%%"); break; default: warning(0, "Unknown escape code (%%%c) within custom-log-format, skipping!", *pattern); octstr_format_append(result, "%%%c", *pattern); break; } /* switch(...) */ pattern++; } /* for ... */ gwlist_destroy(word_list, octstr_destroy_item); return result; }
static int store_spool_save(Msg *msg) { char id[UUID_STR_LEN + 1]; Octstr *id_s; /* always set msg id and timestamp */ if (msg_type(msg) == sms && uuid_is_null(msg->sms.id)) uuid_generate(msg->sms.id); if (msg_type(msg) == sms && msg->sms.time == MSG_PARAM_UNDEFINED) time(&msg->sms.time); if (spool == NULL) return 0; /* blocke here if store still not loaded */ gwlist_consume(loaded); switch(msg_type(msg)) { case sms: { Octstr *os = store_msg_pack(msg); Octstr *filename, *dir; int fd; size_t wrc; if (os == NULL) { error(0, "Could not pack message."); return -1; } uuid_unparse(msg->sms.id, id); id_s = octstr_create(id); dir = octstr_format("%S/%ld", spool, octstr_hash_key(id_s) % MAX_DIRS); octstr_destroy(id_s); if (mkdir(octstr_get_cstr(dir), S_IRUSR|S_IWUSR|S_IXUSR) == -1 && errno != EEXIST) { error(errno, "Could not create directory `%s'.", octstr_get_cstr(dir)); octstr_destroy(dir); octstr_destroy(os); return -1; } filename = octstr_format("%S/%s", dir, id); octstr_destroy(dir); if ((fd = open(octstr_get_cstr(filename), O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR)) == -1) { error(errno, "Could not open file `%s'.", octstr_get_cstr(filename)); octstr_destroy(filename); octstr_destroy(os); return -1; } for (wrc = 0; wrc < octstr_len(os); ) { size_t rc = write(fd, octstr_get_cstr(os) + wrc, octstr_len(os) - wrc); if (rc == -1) { /* remove file */ error(errno, "Could not write message to `%s'.", octstr_get_cstr(filename)); close(fd); if (unlink(octstr_get_cstr(filename)) == -1) error(errno, "Oops, Could not remove failed file `%s'.", octstr_get_cstr(filename)); octstr_destroy(os); octstr_destroy(filename); return -1; } wrc += rc; } close(fd); counter_increase(counter); octstr_destroy(filename); octstr_destroy(os); break; } case ack: { Octstr *filename; uuid_unparse(msg->ack.id, id); id_s = octstr_create(id); filename = octstr_format("%S/%ld/%s", spool, octstr_hash_key(id_s) % MAX_DIRS, id); octstr_destroy(id_s); if (unlink(octstr_get_cstr(filename)) == -1) { error(errno, "Could not unlink file `%s'.", octstr_get_cstr(filename)); octstr_destroy(filename); return -1; } counter_decrease(counter); octstr_destroy(filename); break; } default: return -1; } return 0; }
int smscconn_send(SMSCConn *conn, Msg *msg) { int ret = -1; List *parts = NULL; gw_assert(conn != NULL); mutex_lock(conn->flow_mutex); if (conn->status == SMSCCONN_DEAD || conn->why_killed != SMSCCONN_ALIVE) { mutex_unlock(conn->flow_mutex); return -1; } /* if this a retry of splitted message, don't unify prefix and don't try to split */ if (msg->sms.split_parts == NULL) { /* normalize the destination number for this smsc */ char *uf = conn->unified_prefix ? octstr_get_cstr(conn->unified_prefix) : NULL; normalize_number(uf, &(msg->sms.receiver)); /* split msg */ parts = sms_split(msg, NULL, NULL, NULL, NULL, 1, counter_increase(split_msg_counter) & 0xff, 0xff, conn->max_sms_octets); if (gwlist_len(parts) == 1) { /* don't create split_parts of sms fit into one */ gwlist_destroy(parts, msg_destroy_item); parts = NULL; } } if (parts == NULL) ret = conn->send_msg(conn, msg); else { long i, parts_len = gwlist_len(parts); struct split_parts *split = gw_malloc(sizeof(*split)); /* must duplicate, because smsc2_route will destroy this msg */ split->orig = msg_duplicate(msg); split->parts_left = counter_create(); split->status = SMSCCONN_SUCCESS; counter_set(split->parts_left, parts_len); split->smsc_conn = conn; debug("bb.sms.splits", 0, "new split_parts created %p", split); for (i = 0; i < parts_len; i++) { msg = gwlist_get(parts, i); msg->sms.split_parts = split; ret = conn->send_msg(conn, msg); if (ret < 0) { if (i == 0) { counter_destroy(split->parts_left); gwlist_destroy(parts, msg_destroy_item); gw_free(split); mutex_unlock(conn->flow_mutex); return ret; } /* * Some parts were sent. So handle this within * bb_smscconn_XXX(). */ split->status = SMSCCONN_FAILED_REJECTED; counter_increase_with(split->parts_left, -(parts_len - i)); warning(0, "Could not send all parts of a split message"); break; } } gwlist_destroy(parts, msg_destroy_item); } mutex_unlock(conn->flow_mutex); return ret; }
struct dlr_storage *dlr_init_sdb(Cfg* cfg) { CfgGroup *grp; List *grplist; Octstr *sdb_url, *sdb_id; Octstr *p = NULL; long pool_size; DBConf *db_conf = NULL; /* * check for all mandatory directives that specify the field names * of the used table */ if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "DLR: SDB: group 'dlr-db' is not specified!"); if (!(sdb_id = cfg_get(grp, octstr_imm("id")))) panic(0, "DLR: SDB: directive 'id' is not specified!"); fields = dlr_db_fields_create(grp); gw_assert(fields != NULL); /* * 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 && (grp = gwlist_extract_first(grplist)) != NULL) { p = cfg_get(grp, octstr_imm("id")); if (p != NULL && octstr_compare(p, sdb_id) == 0) { goto found; } if (p != NULL) octstr_destroy(p); } panic(0, "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, grp, octstr_imm("max-connections")) == -1 || pool_size == 0) pool_size = 1; if (!(sdb_url = cfg_get(grp, octstr_imm("url")))) panic(0, "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,"Connecting to sdb resource <%s>.", octstr_get_cstr(sdb_url)); db_conf = gw_malloc(sizeof(DBConf)); gw_assert(db_conf != NULL); db_conf->sdb = gw_malloc(sizeof(SDBConf)); gw_assert(db_conf->sdb != NULL); db_conf->sdb->url = sdb_url; pool = dbpool_create(DBPOOL_SDB, db_conf, pool_size); gw_assert(pool != NULL); /* * XXX should a failing connect throw panic?! */ if (dbpool_conn_count(pool) == 0) panic(0,"DLR: SDB: database pool has no connections!"); return &handles; }
static int kannel_send_sms(SMSCConn *conn, Msg *sms) { ConnData *conndata = conn->data; Octstr *url; List *headers; if (!conndata->no_sep) { url = octstr_format("%S?" "username=%E&password=%E&to=%E&text=%E", conndata->send_url, conndata->username, conndata->password, sms->sms.receiver, sms->sms.msgdata); } else { Octstr *msgdata = octstr_duplicate(sms->sms.msgdata); octstr_binary_to_hex(msgdata, HEX_NOT_UPPERCASE); url = octstr_format("%S?" "username=%E&password=%E&to=%E&text=%S", conndata->send_url, conndata->username, conndata->password, sms->sms.receiver, msgdata); octstr_destroy(msgdata); } if (octstr_len(sms->sms.udhdata)) { if (!conndata->no_sep) { octstr_format_append(url, "&udh=%E", sms->sms.udhdata); } else { Octstr *udhdata = octstr_duplicate(sms->sms.udhdata); octstr_binary_to_hex(udhdata, HEX_NOT_UPPERCASE); octstr_format_append(url, "&udh=%S", udhdata); octstr_destroy(udhdata); } } if (!conndata->no_sender) octstr_format_append(url, "&from=%E", sms->sms.sender); if (sms->sms.mclass != MC_UNDEF) octstr_format_append(url, "&mclass=%d", sms->sms.mclass); if (!conndata->no_coding && sms->sms.coding != DC_UNDEF) octstr_format_append(url, "&coding=%d", sms->sms.coding); /* Obey that smsbox's sendsms HTTP interface is still expecting * WINDOWS-1252 as default charset, while all other internal parts * use UTF-8 as internal encoding. This means, when we pass a SMS * into a next Kannel instance, we need to let the smsbox know which * charset we have in use. * XXX TODO: change smsbox interface to use UTF-8 as default * in next major release. */ if (sms->sms.coding == DC_7BIT) octstr_append_cstr(url, "&charset=UTF-8"); else if (sms->sms.coding == DC_UCS2) octstr_append_cstr(url, "&charset=UTF-16BE"); if (sms->sms.mwi != MWI_UNDEF) octstr_format_append(url, "&mwi=%d", sms->sms.mwi); if (sms->sms.account) /* prepend account with local username */ octstr_format_append(url, "&account=%E:%E", sms->sms.service, sms->sms.account); if (sms->sms.binfo) /* prepend billing info */ octstr_format_append(url, "&binfo=%S", sms->sms.binfo); if (sms->sms.smsc_id) /* proxy the smsc-id to the next instance */ octstr_format_append(url, "&smsc=%S", sms->sms.smsc_id); if (conndata->dlr_url) { char id[UUID_STR_LEN + 1]; Octstr *mid; /* create Octstr from UUID */ uuid_unparse(sms->sms.id, id); mid = octstr_create(id); octstr_format_append(url, "&dlr-url=%E", conndata->dlr_url); /* encapsulate the original DLR-URL, escape code for DLR mask * and message id */ octstr_format_append(url, "%E%E%E%E%E", octstr_imm("&dlr-url="), sms->sms.dlr_url != NULL ? sms->sms.dlr_url : octstr_imm(""), octstr_imm("&dlr-mask=%d"), octstr_imm("&dlr-mid="), mid); octstr_destroy(mid); } else if (sms->sms.dlr_url != NULL) octstr_format_append(url, "&dlr-url=%E", sms->sms.dlr_url); if (sms->sms.dlr_mask != DLR_UNDEFINED && sms->sms.dlr_mask != DLR_NOTHING) octstr_format_append(url, "&dlr-mask=%d", sms->sms.dlr_mask); if (sms->sms.validity != SMS_PARAM_UNDEFINED) octstr_format_append(url, "&validity=%ld", (sms->sms.validity - time(NULL)) / 60); if (sms->sms.deferred != SMS_PARAM_UNDEFINED) octstr_format_append(url, "&deferred=%ld", (sms->sms.deferred - time(NULL)) / 60); headers = gwlist_create(); debug("smsc.http.kannel", 0, "HTTP[%s]: Start request", octstr_get_cstr(conn->id)); http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers, NULL, 0, sms, NULL); octstr_destroy(url); http_destroy_headers(headers); return 0; }
int date_parse_iso (struct universaltime *ut, Octstr *os) { int n = 0; char *p, *q; /* assign defaults */ ut->month = 0; ut->day = 1; ut->hour = 0; ut->minute = 0; ut->second = 0; p = octstr_get_cstr(os); q = p + ((n = octstr_search_char(os, 'T', 0)) >= 0 ? n : octstr_len(os)); /* stop at the end of string or at the time separator */ if (sscanf(p, "%4ld%n", &ut->year, &n) < 1) return -1; p += n; if (ut->year < 70) ut->year += 2000; else if (ut->year < 100) ut->year += 1900; while (p < q && !gw_isdigit(*p)) p++; if (sscanf(p, "%2ld%n", &ut->month, &n) < 1) return 0; p += n; /* 0-based months */ if (ut->month > 0) ut->month--; while (p < q && !gw_isdigit(*p)) p++; if (sscanf(p, "%2ld%n", &ut->day, &n) < 1) return 0; p += n; if (*q == 'T') p = q+1; else return 0; while (*p && !gw_isdigit(*p)) p++; if (sscanf(p, "%2ld%n", &ut->hour, &n) < 1) return 0; p += n; while (*p && !gw_isdigit(*p)) p++; if (sscanf(p, "%2ld%n", &ut->minute, &n) < 1) return 0; p += n; while (*p && !gw_isdigit(*p)) p++; if (sscanf(p, "%2ld%n", &ut->second, &n) < 1) return 0; p += n; return 0; }
/* * Thread to listen to HTTP requests from SMSC entity */ static void httpsmsc_receiver(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; HTTPClient *client; Octstr *ip, *url, *body; List *headers, *cgivars; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while (conndata->shutdown == 0) { /* reset */ ip = url = body = NULL; headers = cgivars = NULL; /* XXX if conn->is_stopped, do not receive new messages.. */ client = http_accept_request(conndata->port, &ip, &url, &headers, &body, &cgivars); if (client == NULL) break; if (cgivars != NULL) { octstr_append_char(url, '?'); http_cgivar_dump_into(cgivars, url); } debug("smsc.http", 0, "HTTP[%s]: Got request `%s'", octstr_get_cstr(conn->id), octstr_get_cstr(url)); if (connect_denied(conndata->allow_ip, ip)) { info(0, "HTTP[%s]: Connection `%s' tried from denied " "host %s, ignored", octstr_get_cstr(conn->id), octstr_get_cstr(url), octstr_get_cstr(ip)); http_close_client(client); } else conndata->callbacks->receive_sms(conn, client, headers, body, cgivars); debug("smsc.http", 0, "HTTP[%s]: Destroying client information", octstr_get_cstr(conn->id)); octstr_destroy(url); octstr_destroy(ip); octstr_destroy(body); http_destroy_headers(headers); http_destroy_cgiargs(cgivars); } debug("smsc.http", 0, "HTTP[%s]: httpsmsc_receiver dying", octstr_get_cstr(conn->id)); conndata->shutdown = 1; http_close_port(conndata->port); /* unblock http_receive_result() if there are no open sends */ if (counter_value(conndata->open_sends) == 0) http_caller_signal_shutdown(conndata->http_ref); if (conndata->sender_thread != -1) { gwthread_wakeup(conndata->sender_thread); gwthread_join(conndata->sender_thread); } if (conndata->send_cb_thread != -1) { gwthread_wakeup(conndata->send_cb_thread); gwthread_join(conndata->send_cb_thread); } mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_DEAD; mutex_unlock(conn->flow_mutex); if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL) conndata->callbacks->destroy(conn); conn->data = NULL; conndata_destroy(conndata); bb_smscconn_killed(); }
/* * Thread to handle finished sendings */ static void httpsmsc_send_cb(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; Msg *msg; int status; List *headers; Octstr *final_url, *body; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while(conndata->shutdown == 0 || counter_value(conndata->open_sends)) { msg = http_receive_result(conndata->http_ref, &status, &final_url, &headers, &body); if (msg == NULL) break; /* they told us to die, by unlocking */ counter_decrease(conndata->open_sends); if (conndata->max_pending_sends) semaphore_up(conndata->max_pending_sends); /* Handle various states here. */ /* request failed and we are not in shutdown mode */ if (status == -1 && conndata->shutdown == 0) { error(0, "HTTP[%s]: Couldn't connect to SMS center." "(retrying in %ld seconds) %ld.", octstr_get_cstr(conn->id), conn->reconnect_delay, counter_value(conndata->open_sends)); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_RECONNECTING; mutex_unlock(conn->flow_mutex); /* XXX how should we know whether it's temp. error ?? */ bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); /* * Just sleep reconnect delay and set conn to ACTIVE again; * otherwise if no pending request are here, we leave conn in * RECONNECTING state for ever and no routing (trials) take place. */ if (counter_value(conndata->open_sends) == 0) { gwthread_sleep(conn->reconnect_delay); /* and now enable routing again */ mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } continue; } /* request failed and we *are* in shutdown mode, drop the message */ else if (status == -1 && conndata->shutdown == 1) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } /* request succeeded */ else { /* we received a response, so this link is considered online again */ if (conn->status != SMSCCONN_ACTIVE) { mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } conndata->callbacks->parse_reply(conn, msg, status, headers, body); } http_destroy_headers(headers); octstr_destroy(final_url); octstr_destroy(body); } debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying", octstr_get_cstr(conn->id)); conndata->shutdown = 1; if (counter_value(conndata->open_sends)) { warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.", octstr_get_cstr(conn->id), counter_value(conndata->open_sends)); } }
struct dlr_storage *dlr_init_pgsql(Cfg *cfg) { CfgGroup *grp; 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; /* * check for all mandatory directives that specify the field names * of the table used */ if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "DLR: PgSQL: group 'dlr-db' is not specified!"); if (!(pgsql_id = cfg_get(grp, octstr_imm("id")))) panic(0, "DLR: PgSQL: directive 'id' is not specified!"); fields = dlr_db_fields_create(grp); gw_assert(fields != NULL); /* * now grap the required information from the 'pgsql-connection' group * with the pgsql-id we just obtained * * we have to loop through all available PostgreSQL connection definitions * and search for the one we are looking for */ grplist = cfg_get_multi_group(cfg, octstr_imm("pgsql-connection")); while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) { p = cfg_get(grp, octstr_imm("id")); if (p != NULL && octstr_compare(p, pgsql_id) == 0) { goto found; } if (p != NULL) octstr_destroy(p); } panic(0, "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, grp, octstr_imm("max-connections")) == -1 || pool_size == 0) pool_size = 1; if (!(pgsql_host = cfg_get(grp, octstr_imm("host")))) panic(0, "DLR: PgSQL: directive 'host' is not specified!"); if (!(pgsql_user = cfg_get(grp, octstr_imm("username")))) panic(0, "DLR: PgSQL: directive 'username' is not specified!"); if (!(pgsql_pass = cfg_get(grp, octstr_imm("password")))) panic(0, "DLR: PgSQL: directive 'password' is not specified!"); if (!(pgsql_db = cfg_get(grp, octstr_imm("database")))) panic(0, "DLR: PgSQL: directive 'database' is not specified!"); cfg_get_integer(&pgsql_port, grp, octstr_imm("port")); /* optional */ /* * ok, ready to connect to the database */ db_conf = gw_malloc(sizeof(DBConf)); gw_assert(db_conf != NULL); db_conf->pgsql = gw_malloc(sizeof(PgSQLConf)); gw_assert(db_conf->pgsql != NULL); 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; pool = dbpool_create(DBPOOL_PGSQL, db_conf, pool_size); gw_assert(pool != NULL); /* * XXX should a failing connect throw panic?! */ if (dbpool_conn_count(pool) == 0) panic(0,"DLR: PgSQL: database pool has no connections!"); octstr_destroy(pgsql_id); return &handles; }
static struct dlr_entry *dlr_pgsql_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst) { struct dlr_entry *res = NULL; 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)); result = pgsql_select(sql); octstr_destroy(sql); if (result == NULL || gwlist_len(result) < 1) { debug("dlr.pgsql", 0, "no rows found"); while((row = gwlist_extract_first(result))) gwlist_destroy(row, octstr_destroy_item); gwlist_destroy(result, NULL); return NULL; } row = gwlist_get(result, 0); debug("dlr.pgsql", 0, "Found entry, col1=%s, col2=%s, col3=%s, col4=%s, col5=%s col6=%s", octstr_get_cstr(gwlist_get(row, 0)), octstr_get_cstr(gwlist_get(row, 1)), octstr_get_cstr(gwlist_get(row, 2)), octstr_get_cstr(gwlist_get(row, 3)), octstr_get_cstr(gwlist_get(row, 4)), octstr_get_cstr(gwlist_get(row, 5)) ); res = dlr_entry_create(); gw_assert(res != NULL); res->mask = atoi(octstr_get_cstr(gwlist_get(row, 0))); res->service = octstr_duplicate(gwlist_get(row, 1)); res->url = octstr_duplicate(gwlist_get(row, 2)); res->source = octstr_duplicate(gwlist_get(row, 3)); res->destination = octstr_duplicate(gwlist_get(row, 4)); res->boxc_id = octstr_duplicate(gwlist_get(row, 5)); res->smsc = octstr_duplicate(smsc); while((row = gwlist_extract_first(result))) gwlist_destroy(row, octstr_destroy_item); gwlist_destroy(result, NULL); return res; }
static void dlr_pgsql_add(struct dlr_entry *entry) { Octstr *sql; 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(fields->table), octstr_get_cstr(fields->field_smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(fields->field_src), octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_serv), octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_boxc), octstr_get_cstr(fields->field_status), octstr_get_cstr(entry->smsc), octstr_get_cstr(entry->timestamp), octstr_get_cstr(entry->source), octstr_get_cstr(entry->destination), octstr_get_cstr(entry->service), octstr_get_cstr(entry->url), entry->mask, octstr_get_cstr(entry->boxc_id), 0); pgsql_update(sql); octstr_destroy(sql); dlr_entry_destroy(entry); }
static int oracle_select(void *theconn, const Octstr *sql, List *binds, List **res) { List *row; OCIStmt *stmt; OCIParam *dparam; sword status; ub4 columns; ub4 i; struct data_s { text *data; ub2 size; sb2 ind; ub2 type; }; struct data_s *data; struct ora_conn *conn = (struct ora_conn*) theconn; int binds_len = (binds ? gwlist_len(binds) : 0); *res = NULL; /* allocate statement handle */ status = OCIHandleAlloc(conn->envp, (dvoid**)&stmt, OCI_HTYPE_STMT, 0,0); if (OCI_SUCCESS != status) { oracle_checkerr(conn->errhp, status); return -1; } /* prepare statement */ status = OCIStmtPrepare(stmt, conn->errhp, (unsigned char*)octstr_get_cstr(sql), octstr_len(sql), OCI_NTV_SYNTAX, OCI_DEFAULT); if (OCI_SUCCESS != status) { oracle_checkerr(conn->errhp, status); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } /* bind variables */ for (i = 0; i < binds_len; i++) { OCIBind *bndhp = NULL; Octstr *bind = gwlist_get(binds, i); status = OCIBindByPos(stmt, &bndhp, conn->errhp, (i+1), (dvoid *) octstr_get_cstr(bind), (sword) octstr_len(bind)+1, SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT); if (OCI_SUCCESS != status) { oracle_checkerr(conn->errhp, status); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } } /* execute our statement */ status = OCIStmtExecute(conn->svchp, stmt, conn->errhp, 0, 0, NULL, NULL, OCI_DEFAULT); if (OCI_SUCCESS != status && OCI_NO_DATA != status) { oracle_checkerr(conn->errhp, status); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } /* receive column count */ status = OCIAttrGet(stmt, OCI_HTYPE_STMT, &columns, 0, OCI_ATTR_PARAM_COUNT, conn->errhp); if (status != OCI_SUCCESS) { oracle_checkerr(conn->errhp, status); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } debug("dbpool.oracle",0,"SQL has %d columns", columns); /* allocate array of pointers */ debug("dbpool.oracle",0,"alloc size=%ld",sizeof(text*)*columns); data = gw_malloc(sizeof(struct data_s)*columns); debug("dbpool.oracle",0,"retrieve data_size"); /* retrieve data size for every column and allocate it */ for (i=0 ; i < columns; i++) { OCIDefine *defh; status = OCIParamGet(stmt, OCI_HTYPE_STMT, conn->errhp, (dvoid**) &dparam, i+1); if (status != OCI_SUCCESS) { oracle_checkerr(conn->errhp, status); columns = i; for (i = 0; i < columns; i++) gw_free(data[i].data); gw_free(data); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } status = OCIAttrGet(dparam, OCI_DTYPE_PARAM, (dvoid*) &data[i].size, 0, OCI_ATTR_DATA_SIZE, conn->errhp); if (status != OCI_SUCCESS) { oracle_checkerr(conn->errhp, status); columns = i; for (i = 0; i < columns; i++) gw_free(data[i].data); gw_free(data); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } status = OCIAttrGet(dparam, OCI_DTYPE_PARAM, (dvoid*) &data[i].type, 0, OCI_ATTR_DATA_TYPE, conn->errhp); if (status != OCI_SUCCESS) { oracle_checkerr(conn->errhp, status); columns = i; for (i = 0; i < columns; i++) gw_free(data[i].data); gw_free(data); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } /* convert all data types to C-Strings except DATE */ if (data[i].type != SQLT_DAT) { data[i].size++; /* terminating zero */ data[i].type = SQLT_STR; } debug("dbpool.oracle",0,"alloc size=%d", data[i].size); data[i].data = gw_malloc(data[i].size); /* bind allocated values to statement handle */ status = OCIDefineByPos(stmt, &defh, conn->errhp, i+1, data[i].data, data[i].size, data[i].type, &data[i].ind, 0, 0, OCI_DEFAULT); if (status != OCI_SUCCESS) { oracle_checkerr(conn->errhp, status); columns = i; for (i = 0; i <= columns; i++) gw_free(data[i].data); gw_free(data); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } } *res = gwlist_create(); /* fetch data */ while ((status = OCIStmtFetch(stmt, conn->errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT)) == OCI_SUCCESS || status == OCI_SUCCESS_WITH_INFO) { row = gwlist_create(); for (i = 0; i < columns; i++) { if (data[i].data == NULL || data[i].ind == -1) { gwlist_insert(row, i, octstr_create("")); } else { gwlist_insert(row, i, octstr_create_from_data((const char*)data[i].data, data[i].size)); } /* debug("dbpool.oracle",0,"inserted value = '%s'", octstr_get_cstr(gwlist_get(row,i))); */ } gwlist_append(*res, row); } /* ignore OCI_NO_DATA error */ if (status != OCI_NO_DATA) { List *row; oracle_checkerr(conn->errhp, status); for (i = 0; i < columns; i++) gw_free(data[i].data); gw_free(data); while ((row = gwlist_extract_first(*res)) != NULL) gwlist_destroy(row, octstr_destroy_item); gwlist_destroy(*res, NULL); *res = NULL; OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } for (i = 0; i < columns; i++) gw_free(data[i].data); gw_free(data); OCIHandleFree(stmt, OCI_HTYPE_STMT); return 0; }
static void kannel_receive_sms(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars) { ConnData *conndata = conn->data; Octstr *user, *pass, *from, *to, *text, *udh, *account, *binfo, *charset; Octstr *dlrmid, *dlrerr; Octstr *tmp_string, *retmsg; int mclass, mwi, coding, validity, deferred, dlrmask; List *reply_headers; int ret; mclass = mwi = coding = validity = deferred = dlrmask = SMS_PARAM_UNDEFINED; user = http_cgi_variable(cgivars, "username"); pass = http_cgi_variable(cgivars, "password"); from = http_cgi_variable(cgivars, "from"); to = http_cgi_variable(cgivars, "to"); text = http_cgi_variable(cgivars, "text"); udh = http_cgi_variable(cgivars, "udh"); charset = http_cgi_variable(cgivars, "charset"); account = http_cgi_variable(cgivars, "account"); binfo = http_cgi_variable(cgivars, "binfo"); dlrmid = http_cgi_variable(cgivars, "dlr-mid"); tmp_string = http_cgi_variable(cgivars, "flash"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mclass); } tmp_string = http_cgi_variable(cgivars, "mclass"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mclass); } tmp_string = http_cgi_variable(cgivars, "mwi"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mwi); } tmp_string = http_cgi_variable(cgivars, "coding"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &coding); } tmp_string = http_cgi_variable(cgivars, "validity"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &validity); } tmp_string = http_cgi_variable(cgivars, "deferred"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &deferred); } tmp_string = http_cgi_variable(cgivars, "dlr-mask"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &dlrmask); } dlrerr = http_cgi_variable(cgivars, "dlr-err"); debug("smsc.http.kannel", 0, "HTTP[%s]: Received an HTTP request", octstr_get_cstr(conn->id)); if (user == NULL || pass == NULL || octstr_compare(user, conndata->username) != 0 || octstr_compare(pass, conndata->password) != 0) { error(0, "HTTP[%s]: Authorization failure", octstr_get_cstr(conn->id)); retmsg = octstr_create("Authorization failed for sendsms"); } else if (dlrmask != 0 && dlrmid != NULL) { /* we got a DLR, and we don't require additional values */ Msg *dlrmsg; dlrmsg = dlr_find(conn->id, dlrmid, /* message id */ to, /* destination */ dlrmask, 0); if (dlrmsg != NULL) { dlrmsg->sms.sms_type = report_mo; dlrmsg->sms.msgdata = octstr_duplicate(text); dlrmsg->sms.account = octstr_duplicate(conndata->username); debug("smsc.http.kannel", 0, "HTTP[%s]: Received DLR for DLR-URL <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(dlrmsg->sms.dlr_url)); if (dlrerr != NULL) { /* pass errorcode as is */ if (dlrmsg->sms.meta_data == NULL) dlrmsg->sms.meta_data = octstr_create(""); meta_data_set_value(dlrmsg->sms.meta_data, METADATA_DLR_GROUP, octstr_imm(METADATA_DLR_GROUP_ERRORCODE), dlrerr, 1); } ret = bb_smscconn_receive(conn, dlrmsg); if (ret == -1) retmsg = octstr_create("Not accepted"); else retmsg = octstr_create("Sent."); } else { error(0,"HTTP[%s]: Got DLR but could not find message or was not interested " "in it id<%s> dst<%s>, type<%d>", octstr_get_cstr(conn->id), octstr_get_cstr(dlrmid), octstr_get_cstr(to), dlrmask); retmsg = octstr_create("Unknown DLR, not accepted"); } } else if (from == NULL || to == NULL || text == NULL) { error(0, "HTTP[%s]: Insufficient args", octstr_get_cstr(conn->id)); retmsg = octstr_create("Insufficient args, rejected"); } else if (udh != NULL && (octstr_len(udh) != octstr_get_char(udh, 0) + 1)) { error(0, "HTTP[%s]: UDH field misformed, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("UDH field misformed, rejected"); } else if (udh != NULL && octstr_len(udh) > MAX_SMS_OCTETS) { error(0, "HTTP[%s]: UDH field is too long, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("UDH field is too long, rejected"); } else { /* we got a normal MO SMS */ Msg *msg; msg = msg_create(sms); debug("smsc.http.kannel", 0, "HTTP[%s]: Constructing new SMS", octstr_get_cstr(conn->id)); msg->sms.service = octstr_duplicate(user); msg->sms.sender = octstr_duplicate(from); msg->sms.receiver = octstr_duplicate(to); msg->sms.msgdata = octstr_duplicate(text); msg->sms.udhdata = octstr_duplicate(udh); msg->sms.smsc_id = octstr_duplicate(conn->id); msg->sms.time = time(NULL); msg->sms.mclass = mclass; msg->sms.mwi = mwi; msg->sms.coding = coding; msg->sms.validity = (validity == SMS_PARAM_UNDEFINED ? validity : time(NULL) + validity * 60); msg->sms.deferred = (deferred == SMS_PARAM_UNDEFINED ? deferred : time(NULL) + deferred * 60); msg->sms.account = octstr_duplicate(account); msg->sms.binfo = octstr_duplicate(binfo); /* re-encode content if necessary */ if (sms_charset_processing(charset, msg->sms.msgdata, msg->sms.coding) == -1) { error(0, "HTTP[%s]: Charset or body misformed, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("Charset or body misformed, rejected"); } else { ret = bb_smscconn_receive(conn, msg); if (ret == -1) retmsg = octstr_create("Not accepted"); else retmsg = octstr_create("Sent."); } } reply_headers = gwlist_create(); http_header_add(reply_headers, "Content-Type", "text/plain"); debug("smsc.http.kannel", 0, "HTTP[%s]: Sending reply", octstr_get_cstr(conn->id)); http_send_reply(client, HTTP_ACCEPTED, reply_headers, retmsg); octstr_destroy(retmsg); http_destroy_headers(reply_headers); }
static int oracle_update(void *theconn, const Octstr *sql, List *binds) { OCIStmt *stmt; sword status; ub4 rows = 0, i; struct ora_conn *conn = (struct ora_conn*) theconn; int binds_len = (binds ? gwlist_len(binds) : 0); /* allocate statement handle */ status = OCIHandleAlloc(conn->envp, (dvoid**)&stmt, OCI_HTYPE_STMT, 0,0); if (OCI_SUCCESS != status) { oracle_checkerr(conn->errhp, status); return -1; } debug("dbpool.oracle",0,"OCIStmt allocated"); /* prepare statement */ status = OCIStmtPrepare(stmt, conn->errhp, (unsigned char*)octstr_get_cstr(sql), octstr_len(sql), OCI_NTV_SYNTAX, OCI_DEFAULT); if (OCI_SUCCESS != status) { oracle_checkerr(conn->errhp, status); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } debug("dbpool.oracle",0,"OCIStmtPrepare done"); /* bind variables */ for (i = 0; i < binds_len; i++) { Octstr *bind = gwlist_get(binds, i); OCIBind *bndhp = NULL; status = OCIBindByPos(stmt, &bndhp, conn->errhp, (i+1), (dvoid *) octstr_get_cstr(bind), (sword) octstr_len(bind)+1, SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT); if (OCI_SUCCESS != status) { oracle_checkerr(conn->errhp, status); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } } /* execute our statement */ status = OCIStmtExecute(conn->svchp, stmt, conn->errhp, 1, 0, NULL, NULL, /*OCI_DEFAULT*/ OCI_COMMIT_ON_SUCCESS); if (OCI_SUCCESS != status && OCI_NO_DATA != status) { oracle_checkerr(conn->errhp, status); OCIHandleFree(stmt, OCI_HTYPE_STMT); return -1; } debug("dbpool.oracle",0,"OCIStmtExecute done"); /* retrieve #rows processed so far */ status = OCIAttrGet(stmt, OCI_HTYPE_STMT, &rows, 0, OCI_ATTR_ROW_COUNT, conn->errhp); if (status != OCI_SUCCESS) { oracle_checkerr(conn->errhp, status); /* we doesn't return error here, because sql is executed and commited already */ } debug("dbpool.oracle",0,"rows processed = %d", rows); OCIHandleFree(stmt, OCI_HTYPE_STMT); return (int) rows; }
int smsc_http_create(SMSCConn *conn, CfgGroup *cfg) { ConnData *conndata = NULL; Octstr *type; int ssl = 0; /* indicate if SSL-enabled server should be used */ long max_ps; if ((type = cfg_get(cfg, octstr_imm("system-type"))) == NULL) { error(0, "HTTP[%s]: 'system-type' missing in smsc 'http' record.", octstr_get_cstr(conn->id)); octstr_destroy(type); return -1; } conndata = gw_malloc(sizeof(ConnData)); /* reset conndata */ memset(conndata, 0, sizeof(ConnData)); conn->data = conndata; conndata->http_ref = NULL; conndata->data = NULL; if (cfg_get_integer(&conndata->port, cfg, octstr_imm("port")) == -1) { warning(0, "HTTP[%s]: 'port' not set in smsc 'http' group.", octstr_get_cstr(conn->id)); conndata->port = -1; } conndata->allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip")); conndata->send_url = cfg_get(cfg, octstr_imm("send-url")); conndata->username = cfg_get(cfg, octstr_imm("smsc-username")); conndata->password = cfg_get(cfg, octstr_imm("smsc-password")); conndata->system_id = cfg_get(cfg, octstr_imm("system-id")); cfg_get_bool(&conndata->no_sender, cfg, octstr_imm("no-sender")); cfg_get_bool(&conndata->no_coding, cfg, octstr_imm("no-coding")); cfg_get_bool(&conndata->no_sep, cfg, octstr_imm("no-sep")); conndata->proxy = cfg_get(cfg, octstr_imm("system-id")); cfg_get_bool(&ssl, cfg, octstr_imm("use-ssl")); conndata->dlr_url = cfg_get(cfg, octstr_imm("dlr-url")); conndata->alt_charset = cfg_get(cfg, octstr_imm("alt-charset")); if (cfg_get_integer(&max_ps, cfg, octstr_imm("max-pending-submits")) == -1 || max_ps < 1) max_ps = 10; conndata->max_pending_sends = semaphore_create(max_ps); if (conndata->port <= 0 && conndata->send_url == NULL) { error(0, "Sender and receiver disabled. Dummy SMSC not allowed."); goto error; } if (conndata->send_url == NULL) panic(0, "HTTP[%s]: Sending not allowed. No 'send-url' specified.", octstr_get_cstr(conn->id)); if (octstr_case_compare(type, octstr_imm("kannel")) == 0) { if (conndata->username == NULL || conndata->password == NULL) { error(0, "HTTP[%s]: 'username' and 'password' required for Kannel http smsc", octstr_get_cstr(conn->id)); goto error; } conndata->callbacks = &smsc_http_kannel_callback; } else if (octstr_case_compare(type, octstr_imm("brunet")) == 0) { conndata->callbacks = &smsc_http_brunet_callback; } else if (octstr_case_compare(type, octstr_imm("xidris")) == 0) { conndata->callbacks = &smsc_http_xidris_callback; } else if (octstr_case_compare(type, octstr_imm("generic")) == 0) { conndata->callbacks = &smsc_http_generic_callback; } else if (octstr_case_compare(type, octstr_imm("clickatell")) == 0) { conndata->callbacks = &smsc_http_clickatell_callback; } else if (octstr_case_compare(type, octstr_imm("wapme")) == 0) { conndata->callbacks = &smsc_http_wapme_callback; } /* * ADD NEW HTTP SMSC TYPES HERE */ else { error(0, "HTTP[%s]: system-type '%s' unknown smsc 'http' record.", octstr_get_cstr(conn->id), octstr_get_cstr(type)); goto error; } if (conndata->callbacks != NULL && conndata->callbacks->init != NULL && conndata->callbacks->init(conn, cfg)) { error(0, "HTTP[%s]: submodule '%s' init failed.", octstr_get_cstr(conn->id), octstr_get_cstr(type)); goto error; } conndata->open_sends = counter_create(); conndata->msg_to_send = gwlist_create(); gwlist_add_producer(conndata->msg_to_send); conndata->http_ref = http_caller_create(); conn->name = octstr_format("HTTP%s:%S:%d", (ssl?"S":""), type, conndata->port); if (conndata->send_url != NULL) { conn->status = SMSCCONN_ACTIVE; } else { conn->status = SMSCCONN_ACTIVE_RECV; } conn->connect_time = time(NULL); conn->shutdown = httpsmsc_shutdown; conn->queued = httpsmsc_queued; conn->send_msg = httpsmsc_send; conndata->shutdown = 0; /* start receiver thread */ if (conndata->port > 0) { if (http_open_port(conndata->port, ssl) == -1) goto error; if ((conndata->receive_thread = gwthread_create(httpsmsc_receiver, conn)) == -1) goto error; } else conndata->receive_thread = -1; /* start sender threads */ if (conndata->send_url) { if ((conndata->send_cb_thread = gwthread_create(httpsmsc_send_cb, conn)) == -1) goto error; if ((conndata->sender_thread = gwthread_create(httpsmsc_sender, conn)) == -1) goto error; } else { conndata->send_cb_thread = conndata->sender_thread = -1; } info(0, "HTTP[%s]: Initiated and ready", octstr_get_cstr(conn->id)); octstr_destroy(type); return 0; error: error(0, "HTTP[%s]: Failed to create HTTP SMSC connection", octstr_get_cstr(conn->id)); if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL) conndata->callbacks->destroy(conn); conn->data = NULL; conndata_destroy(conndata); conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT; conn->status = SMSCCONN_DEAD; octstr_destroy(type); return -1; }
SMSCConn *smscconn_create(CfgGroup *grp, int start_as_stopped) { SMSCConn *conn; Octstr *smsc_type; int ret; Octstr *allowed_smsc_id_regex; Octstr *denied_smsc_id_regex; Octstr *allowed_prefix_regex; Octstr *denied_prefix_regex; Octstr *preferred_prefix_regex; Octstr *tmp; if (grp == NULL) return NULL; conn = gw_malloc(sizeof(*conn)); memset(conn, 0, sizeof(*conn)); conn->why_killed = SMSCCONN_ALIVE; conn->status = SMSCCONN_CONNECTING; conn->connect_time = -1; conn->is_stopped = start_as_stopped; conn->received = counter_create(); conn->received_dlr = counter_create(); conn->sent = counter_create(); conn->sent_dlr = counter_create(); conn->failed = counter_create(); conn->flow_mutex = mutex_create(); conn->outgoing_sms_load = load_create(); /* add 60,300,-1 entries */ load_add_interval(conn->outgoing_sms_load, 60); load_add_interval(conn->outgoing_sms_load, 300); load_add_interval(conn->outgoing_sms_load, -1); conn->incoming_sms_load = load_create(); /* add 60,300,-1 entries */ load_add_interval(conn->incoming_sms_load, 60); load_add_interval(conn->incoming_sms_load, 300); load_add_interval(conn->incoming_sms_load, -1); conn->incoming_dlr_load = load_create(); /* add 60,300,-1 entries to dlr */ load_add_interval(conn->incoming_dlr_load, 60); load_add_interval(conn->incoming_dlr_load, 300); load_add_interval(conn->incoming_dlr_load, -1); conn->outgoing_dlr_load = load_create(); /* add 60,300,-1 entries to dlr */ load_add_interval(conn->outgoing_dlr_load, 60); load_add_interval(conn->outgoing_dlr_load, 300); load_add_interval(conn->outgoing_dlr_load, -1); #define GET_OPTIONAL_VAL(x, n) x = cfg_get(grp, octstr_imm(n)) #define SPLIT_OPTIONAL_VAL(x, n) \ do { \ Octstr *tmp = cfg_get(grp, octstr_imm(n)); \ if (tmp) x = octstr_split(tmp, octstr_imm(";")); \ else x = NULL; \ octstr_destroy(tmp); \ }while(0) GET_OPTIONAL_VAL(conn->id, "smsc-id"); SPLIT_OPTIONAL_VAL(conn->allowed_smsc_id, "allowed-smsc-id"); SPLIT_OPTIONAL_VAL(conn->denied_smsc_id, "denied-smsc-id"); SPLIT_OPTIONAL_VAL(conn->preferred_smsc_id, "preferred-smsc-id"); GET_OPTIONAL_VAL(conn->allowed_prefix, "allowed-prefix"); GET_OPTIONAL_VAL(conn->denied_prefix, "denied-prefix"); GET_OPTIONAL_VAL(conn->preferred_prefix, "preferred-prefix"); GET_OPTIONAL_VAL(conn->unified_prefix, "unified-prefix"); GET_OPTIONAL_VAL(conn->our_host, "our-host"); GET_OPTIONAL_VAL(conn->log_file, "log-file"); cfg_get_bool(&conn->alt_dcs, grp, octstr_imm("alt-dcs")); GET_OPTIONAL_VAL(allowed_smsc_id_regex, "allowed-smsc-id-regex"); if (allowed_smsc_id_regex != NULL) if ((conn->allowed_smsc_id_regex = gw_regex_comp(allowed_smsc_id_regex, REG_EXTENDED)) == NULL) panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_smsc_id_regex)); GET_OPTIONAL_VAL(denied_smsc_id_regex, "denied-smsc-id-regex"); if (denied_smsc_id_regex != NULL) if ((conn->denied_smsc_id_regex = gw_regex_comp(denied_smsc_id_regex, REG_EXTENDED)) == NULL) panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_smsc_id_regex)); GET_OPTIONAL_VAL(allowed_prefix_regex, "allowed-prefix-regex"); if (allowed_prefix_regex != NULL) if ((conn->allowed_prefix_regex = gw_regex_comp(allowed_prefix_regex, REG_EXTENDED)) == NULL) panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_prefix_regex)); GET_OPTIONAL_VAL(denied_prefix_regex, "denied-prefix-regex"); if (denied_prefix_regex != NULL) if ((conn->denied_prefix_regex = gw_regex_comp(denied_prefix_regex, REG_EXTENDED)) == NULL) panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_prefix_regex)); GET_OPTIONAL_VAL(preferred_prefix_regex, "preferred-prefix-regex"); if (preferred_prefix_regex != NULL) if ((conn->preferred_prefix_regex = gw_regex_comp(preferred_prefix_regex, REG_EXTENDED)) == NULL) panic(0, "Could not compile pattern '%s'", octstr_get_cstr(preferred_prefix_regex)); if ((tmp = cfg_get(grp, octstr_imm("throughput"))) != NULL) { if (octstr_parse_double(&conn->throughput, tmp, 0) == -1) conn->throughput = 0; octstr_destroy(tmp); info(0, "Set throughput to %.3f for smsc id <%s>", conn->throughput, octstr_get_cstr(conn->id)); } /* Sets the admin_id. Equals to connection id if empty */ GET_OPTIONAL_VAL(conn->admin_id, "smsc-admin-id"); if (conn->admin_id == NULL) conn->admin_id = octstr_duplicate(conn->id); /* configure the internal rerouting rules for this smsc id */ init_reroute(conn, grp); if (cfg_get_integer(&conn->log_level, grp, octstr_imm("log-level")) == -1) conn->log_level = 0; if (cfg_get_integer(&conn->max_sms_octets, grp, octstr_imm("max-sms-octets")) == -1) conn->max_sms_octets = MAX_SMS_OCTETS; if (cfg_get_bool(&conn->dead_start, grp, octstr_imm("dead-start")) == -1) conn->dead_start = 0; /* default to connect at start-up time */ /* open a smsc-id specific log-file in exlusive mode */ if (conn->log_file) conn->log_idx = log_open(octstr_get_cstr(conn->log_file), conn->log_level, GW_EXCL); #undef GET_OPTIONAL_VAL #undef SPLIT_OPTIONAL_VAL if (conn->allowed_smsc_id && conn->denied_smsc_id) warning(0, "Both 'allowed-smsc-id' and 'denied-smsc-id' set, deny-list " "automatically ignored"); if (conn->allowed_smsc_id_regex && conn->denied_smsc_id_regex) warning(0, "Both 'allowed-smsc-id_regex' and 'denied-smsc-id_regex' set, deny-regex " "automatically ignored"); if (cfg_get_integer(&conn->reconnect_delay, grp, octstr_imm("reconnect-delay")) == -1) conn->reconnect_delay = SMSCCONN_RECONNECT_DELAY; smsc_type = cfg_get(grp, octstr_imm("smsc")); if (smsc_type == NULL) { error(0, "Required field 'smsc' missing for smsc group."); smscconn_destroy(conn); octstr_destroy(smsc_type); return NULL; } if (octstr_compare(smsc_type, octstr_imm("fake")) == 0) ret = smsc_fake_create(conn, grp); else if (octstr_compare(smsc_type, octstr_imm("cimd2")) == 0) ret = smsc_cimd2_create(conn, grp); else if (octstr_compare(smsc_type, octstr_imm("emi")) == 0) ret = smsc_emi2_create(conn, grp); else if (octstr_compare(smsc_type, octstr_imm("http")) == 0) ret = smsc_http_create(conn, grp); else if (octstr_compare(smsc_type, octstr_imm("smpp")) == 0) ret = smsc_smpp_create(conn, grp); else if (octstr_compare(smsc_type, octstr_imm("at")) == 0) ret = smsc_at2_create(conn,grp); else if (octstr_compare(smsc_type, octstr_imm("cgw")) == 0) ret = smsc_cgw_create(conn,grp); else if (octstr_compare(smsc_type, octstr_imm("smasi")) == 0) ret = smsc_smasi_create(conn, grp); else if (octstr_compare(smsc_type, octstr_imm("oisd")) == 0) ret = smsc_oisd_create(conn, grp); else if (octstr_compare(smsc_type, octstr_imm("loopback")) == 0) ret = smsc_loopback_create(conn, grp); #ifdef HAVE_GSOAP else if (octstr_compare(smsc_type, octstr_imm("parlayx")) == 0) ret = smsc_soap_parlayx_create(conn, grp); #endif else ret = smsc_wrapper_create(conn, grp); octstr_destroy(smsc_type); if (ret == -1) { smscconn_destroy(conn); return NULL; } gw_assert(conn->send_msg != NULL); bb_smscconn_ready(conn); return conn; }
static void wrapper_sender(void *arg) { Msg *msg; SMSCConn *conn = arg; SmscWrapper *wrap = conn->data; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); /* send messages to SMSC until our outgoing_list is empty and * no producer anymore (we are set to shutdown) */ while(conn->status != SMSCCONN_DEAD) { if ((msg = gwlist_consume(wrap->outgoing_queue)) == NULL) break; if (octstr_search_char(msg->sms.receiver, ' ', 0) != -1) { /* * multi-send: this should be implemented in corresponding * SMSC protocol, but while we are waiting for that... */ int i; Msg *newmsg; /* split from spaces: in future, split with something more sensible, * this is dangerous... (as space is url-encoded as '+') */ List *nlist = octstr_split_words(msg->sms.receiver); debug("bb.sms", 0, "Handling multi-receiver message"); for(i=0; i < gwlist_len(nlist); i++) { newmsg = msg_duplicate(msg); octstr_destroy(newmsg->sms.receiver); newmsg->sms.receiver = gwlist_get(nlist, i); sms_send(conn, newmsg); } gwlist_destroy(nlist, NULL); msg_destroy(msg); } else sms_send(conn,msg); } /* cleanup, we are now dying */ debug("bb.sms", 0, "SMSCConn %s sender died, waiting for receiver", octstr_get_cstr(conn->name)); conn->why_killed = SMSCCONN_KILLED_SHUTDOWN; if (conn->is_stopped) { gwlist_remove_producer(wrap->stopped); conn->is_stopped = 0; } gwthread_wakeup(wrap->receiver_thread); gwthread_join(wrap->receiver_thread); /* call 'failed' to all messages still in queue */ mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_DEAD; while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } smscwrapper_destroy(wrap); conn->data = NULL; mutex_unlock(conn->flow_mutex); bb_smscconn_killed(); }
static void dlr_sdb_add(struct dlr_entry *dlr) { Octstr *sql; int state; 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(fields->table), octstr_get_cstr(fields->field_smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(fields->field_src), octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_serv), octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_boxc), octstr_get_cstr(fields->field_status), octstr_get_cstr(dlr->smsc), octstr_get_cstr(dlr->timestamp), octstr_get_cstr(dlr->source), octstr_get_cstr(dlr->destination), octstr_get_cstr(dlr->service), octstr_get_cstr(dlr->url), dlr->mask, octstr_get_cstr(dlr->boxc_id), 0); #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, "SDB: error in inserting DLR for DST <%s>", octstr_get_cstr(dlr->destination)); else if (!state) warning(0, "SDB: No dlr inserted for DST <%s>", octstr_get_cstr(dlr->destination)); octstr_destroy(sql); dlr_entry_destroy(dlr); }
SMSCenter *smsc_open(CfgGroup *grp) { SMSCenter *smsc; Octstr *type, *host, *username, *password, *phone, *device; Octstr *preferred_prefix, *allowed_prefix, *denied_prefix; Octstr *alt_chars, *allow_ip; Octstr *sema_smscnua, *sema_homenua, *sema_report; Octstr *sender_prefix; long iwaitreport; long port, receive_port, our_port; long keepalive; long ois_debug; long alt_dcs; int typeno; type = cfg_get(grp, octstr_imm("smsc")); if (type == NULL) { error(0, "Required field 'smsc' missing for smsc group."); return NULL; } if (octstr_compare(type, octstr_imm("cimd")) == 0) typeno = SMSC_TYPE_CIMD; else if (octstr_compare(type, octstr_imm("emi_x25")) == 0) typeno = SMSC_TYPE_EMI_X25; else if (octstr_compare(type, octstr_imm("sema")) == 0) typeno = SMSC_TYPE_SEMA_X28; else if (octstr_compare(type, octstr_imm("ois")) == 0) typeno = SMSC_TYPE_OIS; else { error(0, "Unknown SMSC type '%s'", octstr_get_cstr(type)); octstr_destroy(type); return NULL; } host = cfg_get(grp, octstr_imm("host")); if (cfg_get_integer(&port, grp, octstr_imm("port")) == -1) port = 0; if (cfg_get_integer(&receive_port, grp, octstr_imm("receive-port")) == -1) receive_port = 0; if (cfg_get_integer(&our_port, grp, octstr_imm("our-port")) == -1) our_port = 0; username = cfg_get(grp, octstr_imm("smsc-username")); password = cfg_get(grp, octstr_imm("smsc-password")); phone = cfg_get(grp, octstr_imm("phone")); device = cfg_get(grp, octstr_imm("device")); preferred_prefix = cfg_get(grp, octstr_imm("preferred-prefix")); allowed_prefix = cfg_get(grp, octstr_imm("allowed-prefix")); denied_prefix = cfg_get(grp, octstr_imm("denied-prefix")); alt_chars = cfg_get(grp, octstr_imm("alt-charset")); allow_ip = cfg_get(grp, octstr_imm("connect-allow-ip")); sema_smscnua = cfg_get(grp, octstr_imm("smsc_nua")); sema_homenua = cfg_get(grp, octstr_imm("home_nua")); sema_report = cfg_get(grp, octstr_imm("wait_report")); if (sema_report == NULL) iwaitreport = 1; else octstr_parse_long(&iwaitreport, sema_report, 0, 0); if (cfg_get_integer(&keepalive, grp, octstr_imm("keepalive")) == -1) keepalive = 0; if (cfg_get_integer(&alt_dcs, grp, octstr_imm("alt-dcs")) == -1) alt_dcs = 0; if (alt_dcs > 1) alt_dcs = 1; if (cfg_get_integer(&ois_debug, grp, octstr_imm("ois-debug-level")) == -1) ois_debug = 0; sender_prefix = cfg_get(grp, octstr_imm("sender-prefix")); if (sender_prefix == NULL) sender_prefix = octstr_create("never"); smsc = NULL; switch (typeno) { case SMSC_TYPE_CIMD: if (host == NULL || port == 0 || username == NULL || password == NULL) error(0, "Required field missing for CIMD center."); else smsc = cimd_open(octstr_get_cstr(host), port, octstr_get_cstr(username), octstr_get_cstr(password)); break; case SMSC_TYPE_EMI_X25: if (phone == NULL || device == NULL || username == NULL || password == NULL) error(0, "Required field missing for EMI_X25 center."); else smsc = emi_open(octstr_get_cstr(phone), octstr_get_cstr(device), octstr_get_cstr(username), octstr_get_cstr(password)); break; case SMSC_TYPE_SEMA_X28: if (device == NULL || sema_smscnua == NULL || sema_homenua == NULL) error(0, "Required field missing for SEMA center."); else smsc = sema_open(octstr_get_cstr(sema_smscnua), octstr_get_cstr(sema_homenua), octstr_get_cstr(device), iwaitreport); break; case SMSC_TYPE_OIS: if (host == NULL || port == 0 || receive_port == 0) error(0, "Required field missing for OIS center."); else smsc = ois_open(receive_port, octstr_get_cstr(host), port, ois_debug); break; /* add new SMSCes here */ default: /* Unknown SMSC type */ break; } if (smsc != NULL) { if (cfg_get_integer(&smsc->alt_charset, grp, octstr_imm("alt-charset")) == -1) smsc->alt_charset = 0; if (preferred_prefix == NULL) smsc->preferred_prefix = NULL; else smsc->preferred_prefix = gw_strdup(octstr_get_cstr(preferred_prefix)); if (allowed_prefix == NULL) smsc->allowed_prefix = NULL; else smsc->allowed_prefix = gw_strdup(octstr_get_cstr(allowed_prefix)); if (denied_prefix == NULL) smsc->denied_prefix = NULL; else smsc->denied_prefix = gw_strdup(octstr_get_cstr(denied_prefix)); } octstr_destroy(type); octstr_destroy(host); octstr_destroy(username); octstr_destroy(password); octstr_destroy(phone); octstr_destroy(device); octstr_destroy(preferred_prefix); octstr_destroy(denied_prefix); octstr_destroy(allowed_prefix); octstr_destroy(alt_chars); octstr_destroy(allow_ip); octstr_destroy(sema_smscnua); octstr_destroy(sema_homenua); octstr_destroy(sema_report); octstr_destroy(sender_prefix); return smsc; }
int mime_decompile(Octstr *binary_mime, Octstr **mime) { char *boundary = "kannel_boundary"; ParseContext *context; long mime_parts; long i, j; unsigned long headers_len, data_len; i = mime_parts = headers_len = data_len = 0; debug("wap.wsp.multipart.form.data", 0, "MIMEDEC: begining decoding"); if(binary_mime == NULL || octstr_len(binary_mime) < 1) { warning(0, "MIMEDEC: invalid mime, ending"); return -1; } *mime = octstr_create(""); /* already dumped in deconvert_content debug("mime", 0, "MMSDEC: binary mime dump:"); octstr_dump(binary_mime, 0); */ context = parse_context_create(binary_mime); debug("mime", 0, "MIMEDEC: context created"); mime_parts = parse_get_uintvar(context); debug("mime", 0, "MIMEDEC: mime has %ld multipart entities", mime_parts); if(mime_parts == 0) { debug("mime", 0, "MIMEDEC: mime has none multipart entities, ending"); return 0; } while(parse_octets_left(context) > 0) { Octstr *headers, *data; List *gwlist_headers; i++; octstr_append(*mime, octstr_imm("--")); octstr_append(*mime, octstr_imm(boundary)); octstr_append(*mime, octstr_imm("\n")); headers_len = parse_get_uintvar(context); data_len = parse_get_uintvar(context); debug("mime", 0, "MIMEDEC[%ld]: headers length <0x%02lx>, " "data length <0x%02lx>", i, headers_len, data_len); if((headers = parse_get_octets(context, headers_len)) != NULL) { gwlist_headers = wsp_headers_unpack(headers, 1); for(j=0; j<gwlist_len(gwlist_headers);j++) { octstr_append(*mime, gwlist_get(gwlist_headers, j)); octstr_append(*mime, octstr_imm("\n")); } } else { error(0, "MIMEDEC[%ld]: headers length is out of range, ending", i); return -1; } if((data = parse_get_octets(context, data_len)) != NULL || (i = mime_parts && /* XXX SE-T610 eats last byte, which is generally null */ (data = parse_get_octets(context, data_len - 1)) != NULL)) { debug("mime", 0, "MMSDEC[%ld]: body [%s]", i, octstr_get_cstr(data)); octstr_append(*mime, octstr_imm("\n")); octstr_append(*mime, data); octstr_append(*mime, octstr_imm("\n")); } else { error(0, "MIMEDEC[%ld]: data length is out of range, ending", i); return -1; } } octstr_append(*mime, octstr_imm("--")); octstr_append(*mime, octstr_imm(boundary)); octstr_append(*mime, octstr_imm("--\n")); /* already dumped in deconvert_content debug("mime", 0, "MMSDEC: text mime dump:"); octstr_dump(*mime, 0); */ return 0; }
struct dlr_storage *dlr_init_redis(Cfg *cfg) { CfgGroup *grp; List *grplist; Octstr *redis_host, *redis_pass, *redis_id; long redis_port = 0, redis_database = -1, redis_idle_timeout = -1; Octstr *p = NULL; long pool_size; DBConf *db_conf = NULL; /* * Check for all mandatory directives that specify the field names * of the used Redis key */ if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db")))) panic(0, "DLR: Redis: group 'dlr-db' is not specified!"); if (!(redis_id = cfg_get(grp, octstr_imm("id")))) panic(0, "DLR: Redis: directive 'id' is not specified!"); fields = dlr_db_fields_create(grp); gw_assert(fields != NULL); /* * Escaping special quotes for field/table names */ octstr_replace(fields->table, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_smsc, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_ts, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_src, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_dst, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_serv, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_url, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_mask, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_status, octstr_imm("`"), octstr_imm("``")); octstr_replace(fields->field_boxc, octstr_imm("`"), octstr_imm("``")); /* * Now grab the required information from the 'redis-connection' group * with the redis-id we just obtained. * * We have to loop through all available Redis connection definitions * and search for the one we are looking for. */ grplist = cfg_get_multi_group(cfg, octstr_imm("redis-connection")); while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) { p = cfg_get(grp, octstr_imm("id")); if (p != NULL && octstr_compare(p, redis_id) == 0) { goto found; } if (p != NULL) octstr_destroy(p); } panic(0, "DLR: Redis: connection settings for id '%s' are not specified!", octstr_get_cstr(redis_id)); found: octstr_destroy(p); gwlist_destroy(grplist, NULL); if (cfg_get_integer(&pool_size, grp, octstr_imm("max-connections")) == -1 || pool_size == 0) pool_size = 1; if (!(redis_host = cfg_get(grp, octstr_imm("host")))) panic(0, "DLR: Redis: directive 'host' is not specified!"); if (cfg_get_integer(&redis_port, grp, octstr_imm("port")) == -1) panic(0, "DLR: Redis: directive 'port' is not specified!"); redis_pass = cfg_get(grp, octstr_imm("password")); cfg_get_integer(&redis_database, grp, octstr_imm("database")); cfg_get_integer(&redis_idle_timeout, grp, octstr_imm("idle-timeout")); /* * Ok, ready to connect to Redis */ db_conf = gw_malloc(sizeof(DBConf)); gw_assert(db_conf != NULL); db_conf->redis = gw_malloc(sizeof(RedisConf)); gw_assert(db_conf->redis != NULL); db_conf->redis->host = redis_host; db_conf->redis->port = redis_port; db_conf->redis->password = redis_pass; db_conf->redis->database = redis_database; db_conf->redis->idle_timeout = redis_idle_timeout; pool = dbpool_create(DBPOOL_REDIS, db_conf, pool_size); gw_assert(pool != NULL); /* * Panic on failure to connect. Should we just try to reconnect? */ if (dbpool_conn_count(pool) == 0) panic(0,"DLR: Redis: database pool has no connections!"); octstr_destroy(redis_id); return &handles; }
static int reconnect(SMSCConn *conn) { SmscWrapper *wrap = conn->data; Msg *msg; int ret; int wait = 1; /* disable double-reconnect * NOTE: it is still possible that we do double-connect if * first thread gets through this if-statement and then * execution switches to another thread.. this can be avoided * via double-mutex system, but I do not feel it is worth it, * maybe later --rpr */ if (conn->status == SMSCCONN_RECONNECTING) { mutex_lock(wrap->reconnect_mutex); /* wait here */ mutex_unlock(wrap->reconnect_mutex); return 0; } mutex_lock(wrap->reconnect_mutex); debug("bb.sms", 0, "smsc_wrapper <%s>: reconnect started", octstr_get_cstr(conn->name)); while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); } conn->status = SMSCCONN_RECONNECTING; while(conn->why_killed == SMSCCONN_ALIVE) { ret = smsc_reopen(wrap->smsc); if (ret == 0) { info(0, "Re-open of %s succeeded.", octstr_get_cstr(conn->name)); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; conn->connect_time = time(NULL); mutex_unlock(conn->flow_mutex); bb_smscconn_connected(conn); break; } else if (ret == -2) { error(0, "Re-open of %s failed permanently", octstr_get_cstr(conn->name)); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_DISCONNECTED; mutex_unlock(wrap->reconnect_mutex); mutex_unlock(conn->flow_mutex); return -1; /* permanent failure */ } else { error(0, "Re-open to <%s> failed, retrying after %d minutes...", octstr_get_cstr(conn->name), wait); gwthread_sleep(wait*60.0); wait = wait > 10 ? 10 : wait * 2 + 1; } } mutex_unlock(wrap->reconnect_mutex); return 0; }
int main(int argc, char **argv) { output_t outputti = NORMAL_OUT; FILE *fp = NULL; Octstr *output = NULL; Octstr *filename = NULL; Octstr *wml_text = NULL; Octstr *charset = NULL; Octstr *wml_binary = NULL; int i, ret = 0, opt, file = 0, zero = 0, numstatus = 0, wml_strict = 1; long num = 0; /* You can give an wml text file as an argument './wml_tester main.wml' */ gwlib_init(); while ((opt = getopt(argc, argv, "hsbzrn:f:c:")) != EOF) { switch (opt) { case 'h': help(); exit(0); case 's': if (outputti == NORMAL_OUT) outputti = SOURCE_OUT; else { help(); exit(0); } break; case 'b': if (outputti == NORMAL_OUT) outputti = BINARY_OUT; else { help(); exit(0); } break; case 'z': zero = 1; break; case 'r': wml_strict = 0; break; case 'n': numstatus = octstr_parse_long(&num, octstr_imm(optarg), 0, 0); if (numstatus == -1) { /* Error in the octstr_parse_long */ error(num, "Error in the handling of argument to option n"); help(); panic(0, "Stopping."); } break; case 'f': file = 1; filename = octstr_create(optarg); fp = fopen(optarg, "a"); if (fp == NULL) panic(0, "Couldn't open output file."); break; case 'c': charset = octstr_create(optarg); break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (optind >= argc) { error(0, "Missing arguments."); help(); panic(0, "Stopping."); } if (outputti == BINARY_OUT) log_set_output_level(GW_PANIC); wml_init(wml_strict); while (optind < argc) { wml_text = octstr_read_file(argv[optind]); if (wml_text == NULL) panic(0, "Couldn't read WML source file."); if (zero) set_zero(wml_text); for (i = 0; i <= num; i++) { ret = wml_compile(wml_text, charset, &wml_binary, NULL); if (i < num) octstr_destroy(wml_binary); } optind++; output = octstr_format("wml_compile returned: %d\n\n", ret); if (ret == 0) { if (fp == NULL) fp = stdout; if (outputti != BINARY_OUT) { if (outputti == SOURCE_OUT) { octstr_insert(output, wml_text, octstr_len(output)); octstr_append_char(output, '\n'); } octstr_append(output, octstr_imm( "Here's the binary output: \n\n")); octstr_print(fp, output); } if (file && outputti != BINARY_OUT) { fclose(fp); log_open(octstr_get_cstr(filename), 0, GW_NON_EXCL); octstr_dump(wml_binary, 0); log_close_all(); fp = fopen(octstr_get_cstr(filename), "a"); } else if (outputti != BINARY_OUT) octstr_dump(wml_binary, 0); else octstr_print(fp, wml_binary); if (outputti != BINARY_OUT) { octstr_destroy(output); output = octstr_format("\n And as a text: \n\n"); octstr_print(fp, output); octstr_pretty_print(fp, wml_binary); octstr_destroy(output); output = octstr_format("\n\n"); octstr_print(fp, output); } } octstr_destroy(wml_text); octstr_destroy(output); octstr_destroy(wml_binary); } if (file) { fclose(fp); octstr_destroy(filename); } if (charset != NULL) octstr_destroy(charset); wml_shutdown(); gwlib_shutdown(); return ret; }
/* * Return Msg* if dlr entry found in DB, otherwise NULL. * 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 *msg = NULL; struct dlr_entry *dlr = NULL; if(octstr_len(smsc) == 0) { warning(0, "DLR[%s]: Can't find a dlr without smsc-id", dlr_type()); return NULL; } /* check if we have handler registered */ if (handles == NULL || handles->dlr_get == NULL) return NULL; 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 (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)); return NULL; } #define O_SET(x, val) if (octstr_len(val) > 0) { x = val; val = NULL; } if ((typ & dlr->mask) > 0) { /* its an entry we are interested in */ msg = msg_create(sms); msg->sms.sms_type = report_mo; msg->sms.dlr_mask = typ; O_SET(msg->sms.service, dlr->service); O_SET(msg->sms.smsc_id, dlr->smsc); O_SET(msg->sms.receiver, dlr->destination); O_SET(msg->sms.sender, dlr->source); /* if dlr_url was present, recode it here again */ O_SET(msg->sms.dlr_url, dlr->url); /* add the foreign_id */ msg->sms.foreign_id = octstr_duplicate(ts); /* * insert original message to the data segment * later in the smsc module */ msg->sms.msgdata = NULL; /* * If a boxc_id is available, then instruct bearerbox to * route this msg back to originating smsbox */ O_SET(msg->sms.boxc_id, dlr->boxc_id); time(&msg->sms.time); debug("dlr.dlr", 0, "DLR[%s]: created DLR message for URL <%s>", dlr_type(), (msg->sms.dlr_url?octstr_get_cstr(msg->sms.dlr_url):"")); } else { debug("dlr.dlr", 0, "DLR[%s]: Ignoring DLR message because of mask type=%d dlr->mask=%d", dlr_type(), typ, dlr->mask); /* ok that was a status report but we where not interested in having it */ msg = NULL; } #undef O_SET /* check for end status and if so remove from storage */ 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); } else { 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); } else { warning(0, "DLR[%s]: Storage don't have remove operation defined", dlr_type()); } } /* destroy struct dlr_entry */ dlr_entry_destroy(dlr); return msg; }
static void my_dump(const void *a, long index) { debug("", 0, "dump(%p, %ld) called", a, index); debug("", 0, "value=%s", octstr_get_cstr((Octstr*) a)); }