void cfg_dump(Cfg *cfg) { CfgGroup *grp; List *list; List *names; Octstr *name; debug("gwlib.cfg", 0, "Dumping Cfg %p", (void *) cfg); debug("gwlib.cfg", 0, " filename = <%s>", octstr_get_cstr(cfg->filename)); names = dict_keys(cfg->single_groups); while ((name = gwlist_extract_first(names)) != NULL) { grp = cfg_get_single_group(cfg, name); if (grp != NULL) grp_dump(grp); octstr_destroy(name); } gwlist_destroy(names, NULL); names = dict_keys(cfg->multi_groups); while ((name = gwlist_extract_first(names)) != NULL) { list = cfg_get_multi_group(cfg, name); while ((grp = gwlist_extract_first(list)) != NULL) grp_dump(grp); gwlist_destroy(list, NULL); octstr_destroy(name); } gwlist_destroy(names, NULL); debug("gwlib.cfg", 0, "Dump ends."); }
/* * Parse a line in the format: <name=value name=value ...> * and return a Dict with the name as key and the value as value, * otherwise return NULL if a parsing error occures. */ static Dict *brunet_parse_body(Octstr *body) { Dict *param = NULL; List *words = NULL; long len; Octstr *word; words = octstr_split_words(body); if ((len = gwlist_len(words)) > 0) { param = dict_create(4, (void(*)(void *)) octstr_destroy); while ((word = gwlist_extract_first(words)) != NULL) { List *l = octstr_split(word, octstr_imm("=")); Octstr *key = gwlist_extract_first(l); Octstr *value = gwlist_extract_first(l); if (octstr_len(key)) dict_put(param, key, value); octstr_destroy(key); octstr_destroy(word); gwlist_destroy(l, (void(*)(void *)) octstr_destroy); } } gwlist_destroy(words, (void(*)(void *)) octstr_destroy); return param; }
int urltrans_add_cfg(URLTranslationList *trans, Cfg *cfg) { CfgGroup *grp; List *list; list = cfg_get_multi_group(cfg, octstr_imm("sms-service")); while (list && (grp = gwlist_extract_first(list)) != NULL) { if (urltrans_add_one(trans, grp) == -1) { gwlist_destroy(list, NULL); return -1; } } gwlist_destroy(list, NULL); list = cfg_get_multi_group(cfg, octstr_imm("sendsms-user")); while (list && (grp = gwlist_extract_first(list)) != NULL) { if (urltrans_add_one(trans, grp) == -1) { gwlist_destroy(list, NULL); return -1; } } gwlist_destroy(list, NULL); return 0; }
static long dlr_redis_messages(void) { List *result, *row; DBPoolConn *conn; long msgs = -1; conn = dbpool_conn_consume(pool); if (conn == NULL) return -1; if (dbpool_conn_select(conn, octstr_imm("DBSIZE"), NULL, &result) != 0) { dbpool_conn_produce(conn); return 0; } dbpool_conn_produce(conn); if (gwlist_len(result) > 0) { row = gwlist_extract_first(result); msgs = atol(octstr_get_cstr(gwlist_get(row, 0))); gwlist_destroy(row, octstr_destroy_item); while ((row = gwlist_extract_first(result)) != NULL) gwlist_destroy(row, octstr_destroy_item); } gwlist_destroy(result, NULL); return msgs; }
/* * Add reroute information to the connection data. Where the priority * is in the order: reroute, reroute-smsc-id, reroute-receiver. */ static void init_reroute(SMSCConn *conn, CfgGroup *grp) { Octstr *rule; long i; if (cfg_get_bool(&conn->reroute_dlr, grp, octstr_imm("reroute-dlr")) == -1) conn->reroute_dlr = 0; info(0, "DLR rerouting for smsc id <%s> %s.", octstr_get_cstr(conn->id), (conn->reroute_dlr?"enabled":"disabled")); if (cfg_get_bool(&conn->reroute, grp, octstr_imm("reroute")) != -1) { debug("smscconn",0,"Adding general internal routing for smsc id <%s>", octstr_get_cstr(conn->id)); return; } if ((conn->reroute_to_smsc = cfg_get(grp, octstr_imm("reroute-smsc-id"))) != NULL) { /* reroute all messages to a specific smsc-id */ debug("smscconn",0,"Adding internal routing: smsc id <%s> to smsc id <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(conn->reroute_to_smsc)); return; } if ((rule = cfg_get(grp, octstr_imm("reroute-receiver"))) != NULL) { List *routes; /* create hash disctionary for this smsc-id */ conn->reroute_by_receiver = dict_create(100, (void(*)(void *)) octstr_destroy); routes = octstr_split(rule, octstr_imm(";")); for (i = 0; i < gwlist_len(routes); i++) { Octstr *item = gwlist_get(routes, i); Octstr *smsc, *receiver; List *receivers; /* first word is the smsc-id, all other are the receivers */ receivers = octstr_split(item, octstr_imm(",")); smsc = gwlist_extract_first(receivers); if (smsc) octstr_strip_blanks(smsc); while((receiver = gwlist_extract_first(receivers))) { octstr_strip_blanks(receiver); debug("smscconn",0,"Adding internal routing for smsc id <%s>: " "receiver <%s> to smsc id <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(receiver), octstr_get_cstr(smsc)); if (!dict_put_once(conn->reroute_by_receiver, receiver, octstr_duplicate(smsc))) panic(0, "Could not set internal routing for smsc id <%s>: " "receiver <%s> to smsc id <%s>, because receiver has already routing entry!", octstr_get_cstr(conn->id), octstr_get_cstr(receiver), octstr_get_cstr(smsc)); octstr_destroy(receiver); } octstr_destroy(smsc); gwlist_destroy(receivers, octstr_destroy_item); } octstr_destroy(rule); gwlist_destroy(routes, octstr_destroy_item); } }
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 empty_msg_lists(void) { Msg *msg; #ifndef NO_WAP if (gwlist_len(incoming_wdp) > 0 || gwlist_len(outgoing_wdp) > 0) warning(0, "Remaining WDP: %ld incoming, %ld outgoing", gwlist_len(incoming_wdp), gwlist_len(outgoing_wdp)); info(0, "Total WDP messages: received %ld, sent %ld", counter_value(incoming_wdp_counter), counter_value(outgoing_wdp_counter)); #endif while ((msg = gwlist_extract_first(incoming_wdp)) != NULL) msg_destroy(msg); while ((msg = gwlist_extract_first(outgoing_wdp)) != NULL) msg_destroy(msg); gwlist_destroy(incoming_wdp, NULL); gwlist_destroy(outgoing_wdp, NULL); counter_destroy(incoming_wdp_counter); counter_destroy(outgoing_wdp_counter); #ifndef NO_SMS /* XXX we should record these so that they are not forever lost... */ if (gwlist_len(incoming_sms) > 0 || gwlist_len(outgoing_sms) > 0) debug("bb", 0, "Remaining SMS: %ld incoming, %ld outgoing", gwlist_len(incoming_sms), gwlist_len(outgoing_sms)); info(0, "Total SMS messages: received %ld, dlr %ld, sent %ld, dlr %ld", counter_value(incoming_sms_counter), counter_value(incoming_dlr_counter), counter_value(outgoing_sms_counter), counter_value(outgoing_dlr_counter)); #endif gwlist_destroy(incoming_sms, msg_destroy_item); gwlist_destroy(outgoing_sms, msg_destroy_item); counter_destroy(incoming_sms_counter); counter_destroy(incoming_dlr_counter); counter_destroy(outgoing_sms_counter); counter_destroy(outgoing_dlr_counter); load_destroy(incoming_sms_load); load_destroy(incoming_dlr_load); load_destroy(outgoing_sms_load); load_destroy(outgoing_dlr_load); }
static int shutdown_cb(SMSCConn *conn, int finish_sending) { PrivData *privdata = conn->data; debug("bb.sms", 0, "Shutting down SMSCConn FAKE, %s", finish_sending ? "slow" : "instant"); /* * Documentation claims this would have been done by smscconn.c, * but isn't when this code is being written. */ conn->why_killed = SMSCCONN_KILLED_SHUTDOWN; privdata->shutdown = 1; /* * Separate from why_killed to avoid locking, as * why_killed may be changed from outside? */ if (finish_sending == 0) { Msg *msg; while((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } } gwthread_wakeup(privdata->connection_thread); return 0; }
static long dlr_messages_oracle() { List *result, *row; Octstr *sql; DBPoolConn *conn; long msgs = -1; conn = dbpool_conn_consume(pool); if (conn == NULL) return -1; sql = octstr_format("SELECT count(*) FROM %S", fields->table); #if defined(DLR_TRACE) debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql)); #endif if (dbpool_conn_select(conn, sql, NULL, &result) != 0) { octstr_destroy(sql); dbpool_conn_produce(conn); return -1; } dbpool_conn_produce(conn); octstr_destroy(sql); if (gwlist_len(result) > 0) { row = gwlist_extract_first(result); msgs = strtol(octstr_get_cstr(gwlist_get(row,0)), NULL, 10); gwlist_destroy(row, octstr_destroy_item); } gwlist_destroy(result, NULL); return msgs; }
unsigned int dbpool_decrease(DBPool *p, unsigned int c) { unsigned int i; gw_assert(p != NULL && p->pool != NULL && p->db_ops != NULL && p->db_ops->close != NULL); /* lock dbpool for updates */ gwlist_lock(p->pool); /* * Ensure we don't try to decrease more then available in pool. */ for (i = 0; i < c; i++) { DBPoolConn *pc; /* gwlist_extract_first doesn't block even if no conn here */ pc = gwlist_extract_first(p->pool); /* no conn availible anymore */ if (pc == NULL) break; /* close connections and destroy pool connection */ dbpool_conn_destroy(pc); p->curr_size--; } /* unlock dbpool for updates */ gwlist_unlock(p->pool); return i; }
static void wtp_event_dump(Msg *msg) { WAPEvent *dgram; List *events; long i, n; dgram = wdp_msg2event(msg); if (dgram == NULL) error(0, "dgram is null"); /* pdu = wtp_pdu_unpack(dgram->u.T_DUnitdata_Ind.user_data); if (pdu == NULL) { error(0, "WTP PDU unpacking failed, WAP event is:"); wap_event_dump(dgram); } else { wtp_pdu_dump(pdu, 0); wtp_pdu_destroy(pdu); } */ events = wtp_unpack_wdp_datagram(dgram); n = gwlist_len(events); debug("wap.proxy",0,"datagram contains %ld events", n); i = 1; while (gwlist_len(events) > 0) { WAPEvent *event; event = gwlist_extract_first(events); info(0, "WTP: %ld/%ld event %s.", i, n, wap_event_name(event->type)); if (wtp_event_is_for_responder(event)) /* wtp_resp_dispatch_event(event); */ debug("",0,"datagram is for WTP responder"); else /* wtp_initiator_dispatch_event(event); */ debug("",0,"datagram is for WTP initiator"); wap_event_dump(event); /* switch (event->type) { RcvInvoke: debug("",0,"XXX invoke"); break; RcvResult: debug("",0,"XXX result"); break; default: error(0,"unkown WTP event type while unpacking"); break; } */ i++; } wap_event_destroy(dgram); gwlist_destroy(events, NULL); }
void mms_queue_free_envelope(MmsEnvelope *e) { MmsEnvelopeTo *x; if (e == NULL) return; octstr_destroy(e->msgId); while ((x = gwlist_extract_first(e->to)) != NULL) { octstr_destroy(x->rcpt); gw_free(x); } gwlist_destroy(e->to, NULL); octstr_destroy(e->from); octstr_destroy(e->fromproxy); octstr_destroy(e->mdata); octstr_destroy(e->viaproxy); octstr_destroy(e->token); octstr_destroy(e->subject); octstr_destroy(e->vaspid); octstr_destroy(e->vasid); octstr_destroy(e->url1); octstr_destroy(e->url2); http_destroy_headers(e->hdrs); gw_free(e); }
int udp_start(Cfg *cfg) { CfgGroup *grp; Octstr *iface; List *ifs; int allow_wtls; if (udp_running) return -1; debug("bb.udp", 0, "starting UDP sender/receiver module"); grp = cfg_get_single_group(cfg, octstr_imm("core")); iface = cfg_get(grp, octstr_imm("wdp-interface-name")); if (iface == NULL) { error(0, "Missing wdp-interface-name variable, cannot start UDP"); return -1; } allow_ip = cfg_get(grp, octstr_imm("udp-allow-ip")); deny_ip = cfg_get(grp, octstr_imm("udp-deny-ip")); /* we'll activate WTLS as soon as we have a 'wtls' config group */ grp = cfg_get_single_group(cfg, octstr_imm("wtls")); allow_wtls = grp != NULL ? 1 : 0; udpc_list = gwlist_create(); /* have a list of running systems */ ifs = octstr_split(iface, octstr_imm(";")); octstr_destroy(iface); while (gwlist_len(ifs) > 0) { iface = gwlist_extract_first(ifs); info(0, "Adding interface %s", octstr_get_cstr(iface)); add_service(9200, octstr_get_cstr(iface)); /* wsp */ add_service(9201, octstr_get_cstr(iface)); /* wsp/wtp */ #ifdef HAVE_WTLS_OPENSSL if (allow_wtls) { add_service(9202, octstr_get_cstr(iface)); /* wsp/wtls */ add_service(9203, octstr_get_cstr(iface)); /* wsp/wtp/wtls */ } #else if (allow_wtls) error(0, "These is a 'wtls' group in configuration, but no WTLS support compiled in!"); #endif /* add_service(9204, octstr_get_cstr(interface_name)); * vcard */ /* add_service(9205, octstr_get_cstr(interface_name)); * vcal */ /* add_service(9206, octstr_get_cstr(interface_name)); * vcard/wtls */ /* add_service(9207, octstr_get_cstr(interface_name)); * vcal/wtls */ octstr_destroy(iface); } gwlist_destroy(ifs, NULL); gwlist_add_producer(incoming_wdp); udp_running = 1; return 0; }
static struct dlr_entry* dlr_get_oracle(const Octstr *smsc, const Octstr *ts, const Octstr *dst) { Octstr *sql; DBPoolConn *pconn; List *result = NULL, *row; struct dlr_entry *res = NULL; List *binds = gwlist_create(); pconn = dbpool_conn_consume(pool); if (pconn == NULL) /* should not happens, but sure is sure */ return NULL; sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S=:1 AND %S=:2 AND %S=:3 AND ROWNUM < 2", fields->field_mask, fields->field_serv, fields->field_url, fields->field_src, fields->field_dst, fields->field_boxc, fields->table, fields->field_smsc, fields->field_ts, fields->field_dst); gwlist_append(binds, (Octstr *)smsc); /* :1 */ gwlist_append(binds, (Octstr *)ts); /* :2 */ gwlist_append(binds, (Octstr *)dst); /* :3 */ #if defined(DLR_TRACE) debug("dlr.oracle", 0, "sql: %s", octstr_get_cstr(sql)); #endif if (dbpool_conn_select(pconn, sql, binds, &result) != 0) { octstr_destroy(sql); dbpool_conn_produce(pconn); return NULL; } octstr_destroy(sql); 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 = dlr_entry_create(); gw_assert(res != NULL); res->mask = atoi(LO2CSTR(row,0)); res->service = octstr_create(LO2CSTR(row, 1)); res->url = octstr_create(LO2CSTR(row,2)); res->source = octstr_create(LO2CSTR(row, 3)); res->destination = octstr_create(LO2CSTR(row, 4)); res->boxc_id = octstr_create(LO2CSTR(row, 5)); gwlist_destroy(row, octstr_destroy_item); res->smsc = octstr_duplicate(smsc); } gwlist_destroy(result, NULL); #undef LO2CSTR return res; }
static int add_group(Cfg *cfg, CfgGroup *grp) { Octstr *groupname; Octstr *name; List *names; List *list; groupname = cfg_get(grp, octstr_imm("group")); if (groupname == NULL) { error(0, "Group does not contain variable 'group'."); return -1; } set_group_name(grp, groupname); names = dict_keys(grp->vars); while ((name = gwlist_extract_first(names)) != NULL) { int a = is_allowed_in_group(groupname, name); switch (a) { case 0: error(0, "Group '%s' may not contain field '%s'.", octstr_get_cstr(groupname), octstr_get_cstr(name)); octstr_destroy(name); octstr_destroy(groupname); gwlist_destroy(names, octstr_destroy_item); return -1; break; case -1: error(0, "Group '%s' is no valid group identifier.", octstr_get_cstr(groupname)); octstr_destroy(name); octstr_destroy(groupname); gwlist_destroy(names, octstr_destroy_item); return -1; break; default: octstr_destroy(name); break; } } gwlist_destroy(names, NULL); if (is_single_group(groupname)) { dict_put(cfg->single_groups, groupname, grp); } else { list = dict_get(cfg->multi_groups, groupname); if (list == NULL) { list = gwlist_create(); dict_put(cfg->multi_groups, groupname, list); } gwlist_append(list, grp); } octstr_destroy(groupname); return 0; }
static struct dlr_entry* dlr_get_mssql(const Octstr *smsc, const Octstr *ts, const Octstr *dst) { Octstr *sql, *like; DBPoolConn *pconn; List *result = NULL, *row; struct dlr_entry *res = NULL; pconn = dbpool_conn_consume(pool); if (pconn == NULL) /* should not happens, but sure is sure */ return NULL; if (dst) like = octstr_format("AND %S LIKE '%%%S'", fields->field_dst, dst); else like = octstr_imm(""); sql = octstr_format("SELECT %S, %S, %S, %S, %S, %S FROM %S WHERE %S='%S'" " AND %S='%S' %S", fields->field_mask, fields->field_serv, fields->field_url, fields->field_src, fields->field_dst, fields->field_boxc, fields->table, fields->field_smsc, smsc, fields->field_ts, ts, like); #if defined(DLR_TRACE) debug("dlr.mssql", 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); octstr_destroy(like); 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 = dlr_entry_create(); gw_assert(res != NULL); res->mask = atoi(LO2CSTR(row,0)); res->service = octstr_create(LO2CSTR(row, 1)); res->url = octstr_create(LO2CSTR(row,2)); res->source = octstr_create(LO2CSTR(row, 3)); res->destination = octstr_create(LO2CSTR(row, 4)); res->boxc_id = octstr_create(LO2CSTR(row, 5)); gwlist_destroy(row, octstr_destroy_item); res->smsc = octstr_duplicate(smsc); } gwlist_destroy(result, NULL); #undef LO2CSTR return res; }
void parse_context_destroy(ParseContext *context) { gw_assert(context != NULL); if (context->limit_stack) { while (gwlist_len(context->limit_stack) > 0) gw_free(gwlist_extract_first(context->limit_stack)); gwlist_destroy(context->limit_stack, NULL); } gw_free(context); }
static struct dlr_entry *dlr_pgsql_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst) { struct dlr_entry *res = NULL; Octstr *sql, *like; List *result, *row; if (dst) like = octstr_format("AND \"%S\" LIKE '%%%S'", fields->field_dst, dst); else like = octstr_imm(""); sql = octstr_format("SELECT \"%S\", \"%S\", \"%S\", \"%S\", \"%S\", " "\"%S\" FROM \"%S\" WHERE \"%S\"='%S' AND \"%S\"='%S' %S LIMIT 1;", fields->field_mask, fields->field_serv, fields->field_url, fields->field_src, fields->field_dst, fields->field_boxc, fields->table, fields->field_smsc, smsc, fields->field_ts, ts, like); result = pgsql_select(sql); octstr_destroy(sql); octstr_destroy(like); if (result == NULL || gwlist_len(result) < 1) { debug("dlr.pgsql", 0, "no rows found"); 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; }
/* * Go through the list of threads waiting for us to exit, and tell * them that we're exiting. The joiner_cond entries are registered * by those threads, and will be cleaned up by them. */ static void alert_joiners(void) { struct threadinfo *threadinfo; pthread_cond_t *joiner_cond; threadinfo = getthreadinfo(); if (!threadinfo->joiners) return; while ((joiner_cond = gwlist_extract_first(threadinfo->joiners))) { pthread_cond_broadcast(joiner_cond); } }
static Connection *cgw_open_send_connection(SMSCConn *conn) { PrivData *privdata = conn->data; int wait; Connection *server; Msg *msg; wait = 0; while (!privdata->shutdown) { /* Change status only if the first attempt to form a * connection fails, as it's possible that the SMSC closed the * connection because of idle timeout and a new one will be * created quickly. */ if (wait) { if (conn->status == SMSCCONN_ACTIVE) { mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_RECONNECTING; mutex_unlock(conn->flow_mutex); } while ((msg = gwlist_extract_first(privdata->outgoing_queue))) bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); info(0, "smsc_cgw: waiting for %d minutes before trying to connect again", wait); gwthread_sleep(wait * 60); wait = wait > 5 ? 10 : wait * 2; } else wait = 1; server = conn_open_tcp_with_port(privdata->host, privdata->port, privdata->our_port, conn->our_host); if (privdata->shutdown) { conn_destroy(server); return NULL; } if (server == NULL) { error(0, "smsc_cgw: opening TCP connection to %s failed", octstr_get_cstr(privdata->host)); continue; } if (conn->status != SMSCCONN_ACTIVE) { mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; conn->connect_time = time(NULL); mutex_unlock(conn->flow_mutex); bb_smscconn_connected(conn); } return server; } return NULL; }
/* * this thread listens to incoming_wdp list * and then routs messages to proper wapbox */ static void wdp_to_wapboxes(void *arg) { List *route_info; AddrPar *ap; Boxc *conn; Msg *msg; int i; gwlist_add_producer(flow_threads); gwlist_add_producer(wapbox_list); route_info = gwlist_create(); while(bb_status != BB_DEAD) { gwlist_consume(suspended); /* block here if suspended */ if ((msg = gwlist_consume(incoming_wdp)) == NULL) break; gw_assert(msg_type(msg) == wdp_datagram); conn = route_msg(route_info, msg); if (conn == NULL) { warning(0, "Cannot route message, discard it"); msg_destroy(msg); continue; } gwlist_produce(conn->incoming, msg); } debug("bb", 0, "wdp_to_wapboxes: destroying lists"); while((ap = gwlist_extract_first(route_info)) != NULL) ap_destroy(ap); gw_assert(gwlist_len(route_info) == 0); gwlist_destroy(route_info, NULL); gwlist_lock(wapbox_list); for(i=0; i < gwlist_len(wapbox_list); i++) { conn = gwlist_get(wapbox_list, i); gwlist_remove_producer(conn->incoming); conn->alive = 0; } gwlist_unlock(wapbox_list); gwlist_remove_producer(wapbox_list); gwlist_remove_producer(flow_threads); }
int parse_pop_limit(ParseContext *context) { long *elem; gw_assert(context != NULL); if (context->limit_stack == NULL || gwlist_len(context->limit_stack) == 0) { context->error = 1; return -1; } elem = gwlist_extract_first(context->limit_stack); context->limit = *elem; gw_free(elem); return 0; }
static int mms_queue_size(char *dir) { debug("mms_queue_size",0,"running mss_queue_size"); List *stack = gwlist_create(); Octstr *xdir = NULL; int size = 0; gwlist_append(stack, octstr_create("")); while (NULL != (xdir = gwlist_extract_first(stack))) { size += run_dir_count(dir, octstr_get_cstr(xdir), stack); octstr_destroy(xdir); } gwlist_destroy(stack,octstr_destroy_item); return size; }
static int mms_queue_flush(char *dir) { List *stack = gwlist_create(); Octstr *xdir = NULL; gwlist_append(stack, octstr_create("")); int ret = 0; while (NULL != (xdir = gwlist_extract_first(stack))) { ret += flush_dir(dir, octstr_get_cstr(xdir), stack); octstr_destroy(xdir); } gwlist_destroy(stack,octstr_destroy_item); return ret; }
static int wrapper_shutdown(SMSCConn *conn, int finish_sending) { SmscWrapper *wrap = conn->data; debug("bb.sms", 0, "Shutting down SMSCConn %s, %s", octstr_get_cstr(conn->name), finish_sending ? "slow" : "instant"); if (finish_sending == 0) { Msg *msg; while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } } gwlist_remove_producer(wrap->outgoing_queue); gwthread_wakeup(wrap->sender_thread); gwthread_wakeup(wrap->receiver_thread); return 0; }
static int cgw_send_loop(SMSCConn *conn, Connection *server) { PrivData *privdata = conn->data; struct cgwop *cgwop; Msg *msg; int firsttrn; /* Send messages in queue */ while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) { firsttrn = privdata->nexttrn; while (privdata->sendtime[privdata->nexttrn] != 0) { if (++privdata->nexttrn >= CGW_TRN_MAX) privdata->nexttrn = 0; if (privdata->nexttrn == firsttrn) { /* no available trn */ /* this happens too many messages are sent, and old messages * haven't been acked. In this case, increase size of * CGW_TRN_MAX */ info(0, "cgw: Saturated, increase size of CGW_TRN_MAX!"); gwlist_produce(privdata->outgoing_queue, msg); return 1; /* re-insert, and go check for acks */ } } cgwop = msg_to_cgwop(privdata, msg, privdata->nexttrn); if (cgwop == NULL) { info(0, "cgw: cgwop == NULL"); return 0; } privdata->sendmsg[privdata->nexttrn] = msg; privdata->sendtime[privdata->nexttrn] = time(NULL); if (cgwop_send(server, cgwop) == -1) { cgwop_destroy(cgwop); info(0, "cgw: Unable to send (cgwop_send() == -1)"); return -1; } privdata->unacked++; cgwop_destroy(cgwop); } return 0; }
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor) { long len, i; if (list == NULL) return; if (destructor != NULL) { len = gwlist_len(list); /* Using while(x != NULL) is unreliable, what if someone added NULL values? */ for (i = 0; i < len; i++) destructor(gwlist_extract_first(list)); } mutex_destroy(list->permanent_lock); mutex_destroy(list->single_operation_lock); pthread_cond_destroy(&list->nonempty); gw_free(list->tab); gw_free(list); }
static int receive_reply(HTTPCaller *caller) { void *id; int ret; Octstr *final_url; List *replyh; Octstr *replyb; Octstr *type; Octstr *charset; Octstr *os; id = http_receive_result(caller, &ret, &final_url, &replyh, &replyb); octstr_destroy(final_url); if (id == NULL || ret == -1) { error(0, "http GET failed"); gw_free(id); return -1; } debug("", 0, "Done with request %ld", *(long *) id); gw_free(id); http_header_get_content_type(replyh, &type, &charset); debug("", 0, "Content-type is <%s>, charset is <%s>", octstr_get_cstr(type), octstr_get_cstr(charset)); octstr_destroy(type); octstr_destroy(charset); if (verbose) debug("", 0, "Reply headers:"); while ((os = gwlist_extract_first(replyh)) != NULL) { if (verbose) octstr_dump(os, 1); octstr_destroy(os); } gwlist_destroy(replyh, NULL); if (verbose) { debug("", 0, "Reply body:"); octstr_dump(replyb, 1); } octstr_destroy(replyb); return 0; }
/* * Send IP datagram as it is, segment SMS datagram if necessary. */ static void dispatch_datagram(WAPEvent *dgram) { Msg *msg, *part; List *sms_datagrams; static unsigned long msg_sequence = 0L; /* Used only by this function */ msg = part = NULL; sms_datagrams = NULL; if (dgram == NULL) { error(0, "WDP: dispatch_datagram received empty datagram, ignoring."); } else if (dgram->type != T_DUnitdata_Req) { warning(0, "WDP: dispatch_datagram received event of unexpected type."); wap_event_dump(dgram); } else if (dgram->u.T_DUnitdata_Req.address_type == ADDR_IPV4) { #ifdef HAVE_WTLS_OPENSSL if (dgram->u.T_DUnitdata_Req.addr_tuple->local->port >= WTLS_CONNECTIONLESS_PORT) wtls_dispatch_resp(dgram); else #endif /* HAVE_WTLS_OPENSSL */ { msg = pack_ip_datagram(dgram); write_to_bearerbox(msg); } } else { msg_sequence = counter_increase(sequence_counter) & 0xff; msg = pack_sms_datagram(dgram); sms_datagrams = sms_split(msg, NULL, NULL, NULL, NULL, concatenation, msg_sequence, max_messages, MAX_SMS_OCTETS); debug("wap",0,"WDP (wapbox): delivering %ld segments to bearerbox", gwlist_len(sms_datagrams)); while ((part = gwlist_extract_first(sms_datagrams)) != NULL) { write_to_bearerbox(part); } gwlist_destroy(sms_datagrams, NULL); msg_destroy(msg); } wap_event_destroy(dgram); }
static int oracle_check_conn(void *conn) { Octstr *sql; List *res; int ret; /* TODO Check for appropriate OCI function */ sql = octstr_create("SELECT 1 FROM DUAL"); ret = oracle_select(conn, sql, NULL, &res); if (ret != -1 && gwlist_len(res) > 0) { List *row = gwlist_extract_first(res); gwlist_destroy(row, octstr_destroy_item); } if (ret != -1) gwlist_destroy(res, NULL); octstr_destroy(sql); return ret; }