/* * 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 void check_and_add_field(mCfgGrp *grp, Octstr *field, Octstr *value, int lineno) { if (!valid_in_group(grp->name, field)) mms_info(0, "mms_cfg", NULL, "field `%s' is not expected within group `%s' at line %d in conf file - skipped", octstr_get_cstr(field), octstr_get_cstr(grp->name), lineno); else if (dict_put_once(grp->fields, field, octstr_duplicate(value)) == 0) mms_error(0, "mms_cfg", NULL, "Duplicate field `%s' at line %d in conf file, ignored", octstr_get_cstr(field), lineno); }
/* * Populates the corresponding smsbox_by_foobar dictionary hash tables */ static void init_smsbox_routes(Cfg *cfg) { CfgGroup *grp; List *list, *items; Octstr *boxc_id, *smsc_ids, *shortcuts; int i, j; boxc_id = smsc_ids = shortcuts = NULL; list = cfg_get_multi_group(cfg, octstr_imm("smsbox-route")); /* loop multi-group "smsbox-route" */ while (list && (grp = gwlist_extract_first(list)) != NULL) { if ((boxc_id = cfg_get(grp, octstr_imm("smsbox-id"))) == NULL) { grp_dump(grp); panic(0,"'smsbox-route' group without valid 'smsbox-id' directive!"); } /* * If smsc-id is given, then any message comming from the specified * smsc-id in the list will be routed to this smsbox instance. * If shortcode is given, then any message with receiver number * matching those will be routed to this smsbox instance. * If both are given, then only receiver within shortcode originating * from smsc-id list will be routed to this smsbox instance. So if both * are present then this is a logical AND operation. */ smsc_ids = cfg_get(grp, octstr_imm("smsc-id")); shortcuts = cfg_get(grp, octstr_imm("shortcode")); /* consider now the 3 possibilities: */ if (smsc_ids && !shortcuts) { /* smsc-id only, so all MO traffic */ items = octstr_split(smsc_ids, octstr_imm(";")); for (i = 0; i < gwlist_len(items); i++) { Octstr *item = gwlist_get(items, i); octstr_strip_blanks(item); debug("bb.boxc",0,"Adding smsbox routing to id <%s> for smsc id <%s>", octstr_get_cstr(boxc_id), octstr_get_cstr(item)); if (!dict_put_once(smsbox_by_smsc, item, octstr_duplicate(boxc_id))) panic(0, "Routing for smsc-id <%s> already exists!", octstr_get_cstr(item)); } gwlist_destroy(items, octstr_destroy_item); octstr_destroy(smsc_ids); } else if (!smsc_ids && shortcuts) { /* shortcode only, so these MOs from all smscs */ items = octstr_split(shortcuts, octstr_imm(";")); for (i = 0; i < gwlist_len(items); i++) { Octstr *item = gwlist_get(items, i); octstr_strip_blanks(item); debug("bb.boxc",0,"Adding smsbox routing to id <%s> for receiver no <%s>", octstr_get_cstr(boxc_id), octstr_get_cstr(item)); if (!dict_put_once(smsbox_by_receiver, item, octstr_duplicate(boxc_id))) panic(0, "Routing for receiver no <%s> already exists!", octstr_get_cstr(item)); } gwlist_destroy(items, octstr_destroy_item); octstr_destroy(shortcuts); } else if (smsc_ids && shortcuts) { /* both, so only specified MOs from specified smscs */ items = octstr_split(shortcuts, octstr_imm(";")); for (i = 0; i < gwlist_len(items); i++) { List *subitems; Octstr *item = gwlist_get(items, i); octstr_strip_blanks(item); subitems = octstr_split(smsc_ids, octstr_imm(";")); for (j = 0; j < gwlist_len(subitems); j++) { Octstr *subitem = gwlist_get(subitems, j); octstr_strip_blanks(subitem); debug("bb.boxc",0,"Adding smsbox routing to id <%s> " "for receiver no <%s> and smsc id <%s>", octstr_get_cstr(boxc_id), octstr_get_cstr(item), octstr_get_cstr(subitem)); /* construct the dict key '<shortcode>:<smsc-id>' */ octstr_insert(subitem, item, 0); octstr_insert_char(subitem, octstr_len(item), ':'); if (!dict_put_once(smsbox_by_smsc_receiver, subitem, octstr_duplicate(boxc_id))) panic(0, "Routing for receiver:smsc <%s> already exists!", octstr_get_cstr(subitem)); } gwlist_destroy(subitems, octstr_destroy_item); } gwlist_destroy(items, octstr_destroy_item); octstr_destroy(shortcuts); } octstr_destroy(boxc_id); } gwlist_destroy(list, NULL); }
int smpp_pdu_init(Cfg *cfg) { CfgGroup *grp; List *l; if (initialized) return 0; l = cfg_get_multi_group(cfg, octstr_imm("smpp-tlv")); tlvs = gwlist_create(); tlvs_by_tag = dict_create(1024, (void(*)(void*))dict_destroy); tlvs_by_name = dict_create(1024, (void(*)(void*))dict_destroy); while (l != NULL && (grp = gwlist_extract_first(l)) != NULL) { struct smpp_tlv *tlv; Octstr *tmp, *smsc_id; List *l2; tlv = gw_malloc(sizeof(*tlv)); if ((tlv->name = cfg_get(grp, octstr_imm("name"))) == NULL) { error(0, "SMPP: Unable to get name for smpp-tlv."); smpp_tlv_destroy(tlv); goto failed; } if (cfg_get_integer(&tlv->tag, grp, octstr_imm("tag")) == -1) { error(0, "SMPP: Unable to get tag for smpp-tlv."); smpp_tlv_destroy(tlv); goto failed; } if (cfg_get_integer(&tlv->length, grp, octstr_imm("length")) == -1) { error(0, "SMPP: Unable to get length for smpp-tlv."); smpp_tlv_destroy(tlv); goto failed; } if ((tmp = cfg_get(grp, octstr_imm("type"))) == NULL) { error(0, "SMPP: Unable to get type for smpp-tlv."); smpp_tlv_destroy(tlv); goto failed; } if (octstr_str_case_compare(tmp, "octetstring") == 0) tlv->type = SMPP_TLV_OCTETS; else if (octstr_str_case_compare(tmp, "nulterminated") == 0) tlv->type = SMPP_TLV_NULTERMINATED; else if (octstr_str_case_compare(tmp, "integer") == 0) tlv->type = SMPP_TLV_INTEGER; else { error(0, "SMPP: Unknown type for smpp-tlv: `%s'", octstr_get_cstr(tmp)); octstr_destroy(tmp); smpp_tlv_destroy(tlv); goto failed; } octstr_destroy(tmp); /* put to all TLVs */ gwlist_produce(tlvs, tlv); smsc_id = cfg_get(grp, octstr_imm("smsc-id")); if (smsc_id != NULL) { l2 = octstr_split(smsc_id, octstr_imm(";")); octstr_destroy(smsc_id); } else { l2 = gwlist_create(); gwlist_produce(l2, octstr_create(DEFAULT_SMSC_ID)); } while(l2 != NULL && (smsc_id = gwlist_extract_first(l2)) != NULL) { Dict *tmp_dict; debug("sms.smpp", 0, "adding smpp-tlv for smsc-id=%s", octstr_get_cstr(smsc_id)); tmp_dict = dict_get(tlvs_by_name, smsc_id); if (tmp_dict == NULL) { tmp_dict = dict_create(1024, NULL); dict_put(tlvs_by_name, smsc_id, tmp_dict); } /* put into dict */ if (!dict_put_once(tmp_dict, tlv->name, tlv)) { error(0, "SMPP: Double TLV name %s found.", octstr_get_cstr(tlv->name)); octstr_destroy(smsc_id); goto failed; } tmp_dict = dict_get(tlvs_by_tag, smsc_id); if (tmp_dict == NULL) { tmp_dict = dict_create(1024, NULL); dict_put(tlvs_by_tag, smsc_id, tmp_dict); } tmp = octstr_format("%ld", tlv->tag); if (!dict_put_once(tmp_dict, tmp, tlv)) { error(0, "SMPP: Double TLV tag %s found.", octstr_get_cstr(tmp)); gwlist_destroy(l2, octstr_destroy_item); octstr_destroy(tmp); octstr_destroy(smsc_id); goto failed; } octstr_destroy(tmp); octstr_destroy(smsc_id); } gwlist_destroy(l2, octstr_destroy_item); } gwlist_destroy(l, NULL); initialized = 1; return 0; failed: gwlist_destroy(tlvs, (void(*)(void*))smpp_tlv_destroy); dict_destroy(tlvs_by_tag); dict_destroy(tlvs_by_name); return -1; }
mCfg *mms_cfg_read(Octstr *file) { Octstr *sf; List *lines; int i, n; mCfg *cfg; mCfgGrp *grp = NULL; int skip = 0; gw_assert(file); if ((sf = octstr_read_file(octstr_get_cstr(file))) == NULL) { mms_error(errno, "mms_cfg", NULL, "failed to read config from `%s'", octstr_get_cstr(file)); return NULL; } cfg = gw_malloc(sizeof *cfg); cfg->file = octstr_duplicate(file); cfg->grps = dict_create(7, NULL); cfg->xcfg = NULL; cfg->cfg_funcs = NULL; lines = octstr_split(sf, octstr_imm("\n")); for (i = 0, n = gwlist_len(lines); i < n; i++) { Octstr *current = gwlist_get(lines,i); int pos; octstr_strip_blanks(current); if (octstr_len(current) == 0) { /* end of group. */ grp = NULL; skip = 0; continue; } else if (skip || octstr_get_char(current, 0) == '#') continue; if ((pos = octstr_search_char(current, '=',0)) > 0) { /* a field name. first see if start of grp */ Octstr *field = octstr_copy(current,0,pos); Octstr *value = octstr_copy(current,pos+1,octstr_len(current)); octstr_strip_blanks(field); fixup_value(value, i+1); #if 0 mms_info(0, "mms_cfg", NULL, "field/value: [%s - %s]", octstr_get_cstr(field), octstr_get_cstr(value)); #endif if (octstr_str_case_compare(field, "group") == 0) if (grp == NULL) { /* grp name. */ int ismulti = is_multigroup(value); if (ismulti < 0) { mms_info(0, "mms_cfg", NULL, "Skipping unknown group `%s' at line %d of conf file", octstr_get_cstr(value), i+1); skip = 1; } else { grp = gw_malloc(sizeof *grp); grp->name = octstr_duplicate(value); grp->fields = dict_create(23, (void (*)(void *))octstr_destroy); if (ismulti) { List *l = dict_get(cfg->grps, value); if (l == NULL) { l = gwlist_create(); dict_put(cfg->grps, value, l); } gwlist_append(l, grp); } else if (dict_put_once(cfg->grps, value, grp) == 0) panic(0, "Group `%s' [at line %d] cannot appear more " "than once in config!", octstr_get_cstr(value), i+1); } } else panic(0,"`group' is an illegal field name " "within a group at line %d in config file!", i+1); else if (grp) /* an ordinary field name. */ check_and_add_field(grp, field, value,i+1); else panic(0, "A group must begin with a `group = group_name' " "clause [at line %d in config file]", i+1); octstr_destroy(field); octstr_destroy(value); } else panic(0, "mal-formed entry in conf file at line %d!", i+1); } gwlist_destroy(lines, (gwlist_item_destructor_t *)octstr_destroy); octstr_destroy(sf); /* Now check if config-source is set, use that. */ if ((grp = mms_cfg_get_single(cfg, octstr_imm("config-source"))) != NULL) { Octstr *init = mms_cfg_get(cfg, grp, octstr_imm("config-library-init-param")); cfg->cfg_funcs = _mms_load_module(cfg, grp, "config-library", "cfg_funcs", NULL); if (cfg->cfg_funcs == NULL || cfg->cfg_funcs->read == NULL || (cfg->xcfg = cfg->cfg_funcs->read(init)) == NULL) { mms_error(0, "mms_cfg", NULL, "Failed to load cfg reader library from conf!"); mms_cfg_destroy(cfg); cfg = NULL; } octstr_destroy(init); } return cfg; }