Пример #1
0
/*
 * 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);
    }
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
Octstr *get_column(Octstr *str)
{
    Octstr *ret = octstr_create(octstr_get_cstr(str));
    if (ret != NULL)
        octstr_strip_blanks(ret);
    return ret;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
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);
}
Пример #15
0
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;
}
Пример #16
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;
}
Пример #17
0
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;
}