/* * 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); } }
int ota_compile(Octstr *ota_doc, Octstr *charset, Octstr **ota_binary) { simple_binary_t *otabxml; int ret; xmlDocPtr pDoc; size_t size; char *ota_c_text; *ota_binary = octstr_create(""); otabxml = simple_binary_create(); octstr_strip_blanks(ota_doc); octstr_shrink_blanks(ota_doc); set_charset(ota_doc, charset); size = octstr_len(ota_doc); ota_c_text = octstr_get_cstr(ota_doc); pDoc = xmlParseMemory(ota_c_text, size); ret = 0; if (pDoc) { ret = parse_document(pDoc, charset, &otabxml); simple_binary_output(*ota_binary, otabxml); xmlFreeDoc(pDoc); } else { xmlFreeDoc(pDoc); octstr_destroy(*ota_binary); simple_binary_destroy(otabxml); error(0, "OTA: No document to parse. Probably an error in OTA source"); return -1; } simple_binary_destroy(otabxml); return ret; }
Octstr *html_to_sms(Octstr *html) { long i, len; int c; Octstr *sms; sms = octstr_create(""); len = octstr_len(html); i = 0; while (i < len) { c = octstr_get_char(html, i); switch (c) { case '<': if (html_comment_begins(html, i)) skip_html_comment(html, &i); else skip_html_tag(html, &i); break; case '&': convert_html_entity(sms, html, &i); break; default: octstr_append_char(sms, c); ++i; break; } } octstr_shrink_blanks(sms); octstr_strip_blanks(sms); return sms; }
int si_compile(Octstr *si_doc, Octstr *charset, Octstr **si_binary) { simple_binary_t *sibxml; int ret; xmlDocPtr pDoc; size_t size; char *si_c_text; *si_binary = octstr_create(""); sibxml = simple_binary_create(); octstr_strip_blanks(si_doc); set_charset(si_doc, charset); size = octstr_len(si_doc); si_c_text = octstr_get_cstr(si_doc); pDoc = xmlParseMemory(si_c_text, size); ret = 0; if (pDoc) { ret = parse_document(pDoc, charset, &sibxml); simple_binary_output(*si_binary, sibxml); xmlFreeDoc(pDoc); } else { xmlFreeDoc(pDoc); octstr_destroy(*si_binary); simple_binary_destroy(sibxml); error(0, "SI: No document to parse. Probably an error in SI source"); return -1; } simple_binary_destroy(sibxml); return ret; }
Octstr *get_column(Octstr *str) { Octstr *ret = octstr_create(octstr_get_cstr(str)); if (ret != NULL) octstr_strip_blanks(ret); return ret; }
static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to, MmsMsg *m, Octstr **error, int *retry) { Octstr *ret = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK; List *rh, *ph = NULL; Octstr *body = NULL, *rbody = NULL; Octstr *mms; MIMEEntity *form_data = make_multipart_formdata(); mms_info(0, "MM7", mmc->id, "MMSBox: Send [http] to MMC[%s], msg type [%s], from %s, to %s", mmc ? octstr_get_cstr(mmc->id) : "", mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); mms = mms_tobinary(m); add_multipart_form_field(form_data, "to", "text/plain", NULL, to); add_multipart_form_field(form_data, "from", "text/plain", NULL, from); add_multipart_form_field(form_data, "mms", "application/vnd.wap.mms-message", NULL, mms); rh = mime_entity_headers(form_data); body = mime_entity_body(form_data); hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", mmc->mmsc_url, hstatus); } else { ret = rbody ? octstr_duplicate(rbody) : NULL; if (ret) octstr_strip_blanks(ret); } *retry = (ret == NULL && (http_status_class(hstatus) == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(mms); mime_entity_destroy(form_data); return ret; }
static Octstr *get_header_value(Octstr *header) { Octstr *h = NULL; long colon = -1; if (header == NULL) { error(0, "get_header_value: NULL argument"); return NULL; } octstr_strip_blanks(header); colon = octstr_search_char(header, ':', 0); if (colon == -1) { error(0, "get_header_value: Malformed header (%s)", octstr_get_cstr (header)); return NULL; } else { h = octstr_copy(header, colon + 1, octstr_len(header)); octstr_strip_blanks(h); } debug("wap.wsp.http", 0, "get_header_value: Value (%s)", octstr_get_cstr (h)); return h; }
static Octstr *mms_init_queue_dir(char *qdir, int *error) { Octstr *dir; int i, ret; char fbuf[512], *xqdir; gw_assert(inited); gw_assert(qdir); if (error == NULL) error = &ret; *error = 0; dir = octstr_format("%s%c%s", sdir, DIR_SEP, qdir); octstr_strip_blanks(dir); /* Remove trailing slashes. */ for (i = octstr_len(dir) - 1; i >= 0; i--) if (octstr_get_char(dir, i) != DIR_SEP) break; else octstr_delete(dir, i,1); xqdir = octstr_get_cstr(dir); if ((ret = mkdir(xqdir, S_IRWXU|S_IRWXG)) < 0 && errno != EEXIST) { *error = errno; goto done; } for (i = 0; _TT[i]; i++) { /* initialise the top level only... */ sprintf(fbuf, "%.128s/%c", xqdir, _TT[i]); if (mkdir(fbuf, S_IRWXU|S_IRWXG) < 0 && errno != EEXIST) { *error = errno; goto done; } } done: if (*error == 0) return dir; octstr_destroy(dir); return NULL; }
static void fixup_value(Octstr *value, int lineno) { Octstr *tmp; int i,n; octstr_strip_blanks(value); if (octstr_get_char(value, 0) != '"') return; if (octstr_get_char(value, octstr_len(value) - 1) != '"') mms_error(0, "mms_cfg", NULL, "Missing enclosing '\"' at line %d in conf file", lineno); octstr_delete(value, 0,1); /* strip quotes. */ octstr_delete(value, octstr_len(value) - 1, 1); tmp = octstr_duplicate(value); octstr_delete(value, 0, octstr_len(value)); for (i = 0, n = octstr_len(tmp); i < n; i++) { int ch = octstr_get_char(tmp, i); if (ch != '\\') { octstr_append_char(value, ch); continue; } i++; /* skip forward. */ ch = octstr_get_char(tmp,i); switch(ch) { case '"': case '\\': default: octstr_append_char(value, ch); break; case 'n': octstr_append_char(value, '\n'); break; case 't': octstr_append_char(value, '\t'); break; } } octstr_destroy(tmp); }
static void parse_value(Octstr *value) { Octstr *temp; long len; int c; octstr_strip_blanks(value); len = octstr_len(value); if (octstr_get_char(value, 0) != '"' || octstr_get_char(value, len - 1) != '"') return; octstr_delete(value, len - 1, 1); octstr_delete(value, 0, 1); temp = octstr_duplicate(value); octstr_truncate(value, 0); while (octstr_len(temp) > 0) { c = octstr_get_char(temp, 0); octstr_delete(temp, 0, 1); if (c != '\\' || octstr_len(temp) == 0) octstr_append_char(value, c); else { c = octstr_get_char(temp, 0); octstr_delete(temp, 0, 1); switch (c) { case '\\': case '"': octstr_append_char(value, c); break; default: octstr_append_char(value, '\\'); octstr_append_char(value, c); break; } } } octstr_destroy(temp); }
Octstr *copy_and_clean_address(Octstr *addr) { Octstr *s; int k, i; if (addr == NULL) return NULL; s = octstr_duplicate(addr); octstr_strip_blanks(s); /* Only clean up email addresses for now. */ if ((k = octstr_search_char(s, '@',0)) < 0) goto done; /* Find '<' if any, then find last one and remove everything else. */ i = octstr_search_char(s, '<',0); if (i >= 0) { int j; octstr_delete(s, 0, i+1); /* strip first part off. */ j = octstr_search_char(s, '>',0); if (j >= 0) octstr_delete(s, j, octstr_len(s)); } else { /* remove everything after the domain. */ int n = octstr_len(s); char *p = octstr_get_cstr(s); for (i = k+1; i < n; i++) if (isspace(p[i])) { /* there can't be space in domain, so this marks end of address. */ octstr_delete(s, i, n); break; } } done: if (octstr_len(s) == 0) { octstr_destroy(s); s = NULL; } return s; }
Octstr *find_charset_encoding(Octstr *document) { long gt = 0, enc = 0; Octstr *encoding = NULL, *temp = NULL; enc = octstr_search(document, octstr_imm(" encoding="), 0); gt = octstr_search(document, octstr_imm("?>"), 0); /* in case there is no encoding argument, assume always UTF-8 */ if (enc < 0 || enc + 10 > gt) return NULL; temp = octstr_copy(document, enc + 10, gt - (enc + 10)); octstr_strip_blanks(temp); encoding = octstr_copy(temp, 1, octstr_len(temp) - 2); octstr_destroy(temp); return encoding; }
static int parse_text(xmlNodePtr node, simple_binary_t **sibxml) { Octstr *temp; temp = create_octstr_from_node((char *)node); octstr_shrink_blanks(temp); octstr_strip_blanks(temp); if (octstr_len(temp) == 0) { octstr_destroy(temp); return 0; } parse_inline_string(temp, sibxml); octstr_destroy(temp); return 0; }
/* * 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 main(int argc, char *argv[]) { Octstr *fname, *s; int cfidx; int msize; List *h = NULL; if (argc < 2) return -1; mms_lib_init(); cfidx = get_and_set_debugs(argc, argv, find_own); if (argv[cfidx] == NULL) fname = octstr_imm("mmsc.conf"); else fname = octstr_create(argv[cfidx]); mms_info(0, "mmssend", NULL, "----------------------------------------"); mms_info(0, "mmssend", NULL, " MMSC Message sender runner version %s starting", MMSC_VERSION); /* Load settings. */ settings = mms_load_mmsc_settings(fname, &proxyrelays,1); if (!settings) panic(0, "No global MMSC configuration, or failed to read conf from <%s>!", octstr_get_cstr(fname)); octstr_destroy(fname); if (from == NULL || to == NULL) { mms_error(0, "mmssend", NULL, "Sender and recipient addresses required!\n"); exit(-1); } else { /* fix up 'to' list */ List *l = gwlist_create(); Octstr *x; while ((x = gwlist_extract_first(to)) != NULL) { octstr_strip_blanks(x); _mms_fixup_address(&x, settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL, settings->strip_prefixes, 1); gwlist_append(l, x); } gwlist_destroy(to, NULL); to = l; } /* fix from address. */ _mms_fixup_address(&from, settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL, settings->strip_prefixes, 1); #if 0 mms_start_profile_engine(octstr_get_cstr(settings->ua_profile_cache_dir)); #endif if (data) { /* try and detect if we are looking at plain text (mime-encoded) or binary encoded message. */ int ch = octstr_get_char(data, 0); if (isprint(ch)) { MIMEEntity *mime = mime_octstr_to_entity(data); if (mime) { m = mms_frommime(mime); mime_entity_destroy(mime); } } else m = mms_frombinary_ex(data, from ? from : octstr_imm("anon@anon"), octstr_get_cstr(settings->unified_prefix), settings->strip_prefixes); if (m) mms_msgdump(m,1); msize = octstr_len(data); octstr_destroy(data); } else msize = 0; if (!m) panic(0, "No Message supplied, or failed to decode binary data!"); h = http_create_empty_headers(); http_header_add(h, "X-Mbuni-Tool", "mmssend"); http_header_add(h, "X-Mbuni-CalledFrom", "Terminal"); if (binfo) { mms_info(0, "add.info", NULL, "Adding extra headers billing info `X-Mms-Binfo' :"); http_header_add(h, "X-Mms-Binfo", octstr_get_cstr(binfo)); } s = settings->qfs->mms_queue_add(from, to, NULL, NULL, NULL, time(NULL), time(NULL) + settings->default_msgexpiry, m, NULL, NULL, NULL, NULL, NULL, h, dlr, octstr_get_cstr(settings->global_queuedir), "MM3", settings->host_alias); if (savetommbox) mmbox = mms_mmbox_addmsg(octstr_get_cstr(settings->mmbox_rootdir), octstr_get_cstr(from), m, NULL, octstr_imm("Sent")); mms_log("Received", from, to, msize, s, NULL, NULL, "MM3",NULL,NULL); printf("Queued: %s, mmbox=%s\n", octstr_get_cstr(s), mmbox ? octstr_get_cstr(mmbox) : ""); octstr_destroy(s); http_destroy_headers(h); mms_cleanup_mmsc_settings(settings); mms_lib_shutdown(); return 0; }
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; }
int cfg_read(Cfg *cfg) { CfgLoc *loc; CfgLoc *loc_inc; List *lines; List *expand; List *stack; Octstr *name; Octstr *value; Octstr *filename; CfgGroup *grp; long equals; long lineno; long error_lineno; loc = loc_inc = NULL; /* * expand initial main config file and add it to the recursion * stack to protect against cycling */ if ((lines = expand_file(cfg->filename, 1)) == NULL) { panic(0, "Failed to load main configuration file `%s'. Aborting!", octstr_get_cstr(cfg->filename)); } stack = gwlist_create(); gwlist_insert(stack, 0, octstr_duplicate(cfg->filename)); grp = NULL; lineno = 0; error_lineno = 0; while (error_lineno == 0 && (loc = gwlist_extract_first(lines)) != NULL) { octstr_strip_blanks(loc->line); if (octstr_len(loc->line) == 0) { if (grp != NULL && add_group(cfg, grp) == -1) { error_lineno = loc->line_no; destroy_group(grp); } grp = NULL; } else if (octstr_get_char(loc->line, 0) != '#') { equals = octstr_search_char(loc->line, '=', 0); if (equals == -1) { error(0, "An equals sign ('=') is missing on line %ld of file %s.", loc->line_no, octstr_get_cstr(loc->filename)); error_lineno = loc->line_no; } else /* * check for special config directives, like include or conditional * directives here */ if (octstr_search(loc->line, octstr_imm("include"), 0) != -1) { filename = octstr_copy(loc->line, equals + 1, octstr_len(loc->line)); parse_value(filename); /* check if we are cycling */ if (gwlist_search(stack, filename, octstr_item_match) != NULL) { panic(0, "Recursive include for config file `%s' detected " "(on line %ld of file %s).", octstr_get_cstr(filename), loc->line_no, octstr_get_cstr(loc->filename)); } else { List *files = gwlist_create(); Octstr *file; struct stat filestat; /* check if included file is a directory */ if (lstat(octstr_get_cstr(filename), &filestat) != 0) { error(errno, "lstat failed: couldn't stat `%s'", octstr_get_cstr(filename)); panic(0, "Failed to include `%s' " "(on line %ld of file %s). Aborting!", octstr_get_cstr(filename), loc->line_no, octstr_get_cstr(loc->filename)); } /* * is a directory, create a list with files of * this directory and load all as part of the * whole configuration. */ if (S_ISDIR(filestat.st_mode)) { DIR *dh; struct dirent *diritem; debug("gwlib.cfg", 0, "Loading include dir `%s' " "(on line %ld of file %s).", octstr_get_cstr(filename), loc->line_no, octstr_get_cstr(loc->filename)); dh = opendir(octstr_get_cstr(filename)); while ((diritem = readdir(dh))) { Octstr *fileitem; fileitem = octstr_duplicate(filename); octstr_append_cstr(fileitem, "/"); octstr_append_cstr(fileitem, diritem->d_name); lstat(octstr_get_cstr(fileitem), &filestat); if (!S_ISDIR(filestat.st_mode)) { gwlist_insert(files, 0, fileitem); } else { octstr_destroy(fileitem); } } closedir(dh); } /* is a file, create a list with it */ else { gwlist_insert(files, 0, octstr_duplicate(filename)); } /* include files */ while ((file = gwlist_extract_first(files)) != NULL) { gwlist_insert(stack, 0, octstr_duplicate(file)); debug("gwlib.cfg", 0, "Loading include file `%s' (on line %ld of file %s).", octstr_get_cstr(file), loc->line_no, octstr_get_cstr(loc->filename)); /* * expand the given include file and add it to the current * processed main while loop */ if ((expand = expand_file(file, 0)) != NULL) { while ((loc_inc = gwlist_extract_first(expand)) != NULL) gwlist_insert(lines, 0, loc_inc); } else { panic(0, "Failed to load whole configuration. Aborting!"); } gwlist_destroy(expand, NULL); cfgloc_destroy(loc_inc); octstr_destroy(file); } gwlist_destroy(files, octstr_destroy_item); } octstr_destroy(filename); } /* * this is a "normal" line, so process it accodingly */ else { name = octstr_copy(loc->line, 0, equals); octstr_strip_blanks(name); value = octstr_copy(loc->line, equals + 1, octstr_len(loc->line)); parse_value(value); if (grp == NULL) grp = create_group(); if (grp->configfile != NULL) { octstr_destroy(grp->configfile); grp->configfile = NULL; } grp->configfile = octstr_duplicate(cfg->filename); cfg_set(grp, name, value); octstr_destroy(name); octstr_destroy(value); } } cfgloc_destroy(loc); } if (grp != NULL && add_group(cfg, grp) == -1) { error_lineno = 1; destroy_group(grp); } gwlist_destroy(lines, NULL); gwlist_destroy(stack, octstr_destroy_item); if (error_lineno != 0) { error(0, "Error found on line %ld of file `%s'.", error_lineno, octstr_get_cstr(cfg->filename)); return -1; } return 0; }