Example #1
0
static void  dlr_sdb_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
{
    Octstr *sql;
    int	state;

    debug("dlr.sdb", 0, "removing DLR from database");
    if (sdb_conn_type == SDB_POSTGRES) {
        /*
         * Postgres doesn't support limiting delete/update queries,
         * thus we need to use a select subquery.
         * - notice that for uniqueness use of `oid', postgres suggests
         * to do vacuum regularly, even if it's virtually impossible
         * to hit duplicates since oid's are given in a row
         */
        sql = octstr_format("DELETE FROM %s WHERE oid = \
                            (SELECT oid FROM %s WHERE %s='%s' AND %s='%s' LIMIT 1)",
                            octstr_get_cstr(fields->table),
                            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));
    } else {
        sql = octstr_format("DELETE FROM %s WHERE %s='%s' AND %s='%s' %s",
                            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), sdb_get_limit_str());
    }

#if defined(DLR_TRACE)
     debug("dlr.sdb", 0, "SDB: sql: %s", octstr_get_cstr(sql));
#endif

    state = gw_sdb_query(octstr_get_cstr(sql), NULL, NULL);
    octstr_destroy(sql);
    if (state == -1)
        error(0, "SDB: error in deleting DLR");
}
Example #2
0
static struct cgwop *cgwop_create(int op, int trn)
{
    struct cgwop *ret;
    Octstr *trnstr;

    ret = gw_malloc(sizeof(struct cgwop));

    ret->op = op;
    ret->num_fields = 0;
    ret->trn = trn;

    ret->name = gw_malloc(CGWOP_MAXARGS * sizeof(Octstr *));
    ret->value = gw_malloc(CGWOP_MAXARGS * sizeof(Octstr *));

    if (trn != -1)
    {
        trnstr = octstr_create("");
        octstr_append_decimal(trnstr, trn);
        cgwop_add(ret, octstr_imm("client-id"), trnstr);
        octstr_destroy(trnstr);
    }

    return ret;
}
Example #3
0
long smpp_pdu_read_len(Connection *conn)
{
    Octstr *os;
    unsigned char buf[4];    /* The length is 4 octets. */
    long len;

    os = conn_read_fixed(conn, sizeof(buf));
    if (os == NULL)
    	return 0;
    octstr_get_many_chars((char*) buf, os, 0, sizeof(buf));
    octstr_destroy(os);
    len = decode_network_long(buf);
    if (len < MIN_SMPP_PDU_LEN) {
	error(0, "SMPP: PDU length was too small (%ld, minimum is %ld).",
	      len, (long) MIN_SMPP_PDU_LEN);
    	return -1;
    }
    if (len > MAX_SMPP_PDU_LEN) {
	error(0, "SMPP: PDU length was too large (%ld, maximum is %ld).",
	      len, (long) MAX_SMPP_PDU_LEN);
    	return -1;
    }
    return len;
}
Example #4
0
static List *make_reply_headers(WSPMachine *m)
{
    List *headers;
    Octstr *encoding_version;

    /* Add all server wsp level hop-by-hop headers. Currently only 
     * Encoding-Version, as defined by wsp, chapter 8.4.2.70. 
     * What headers belong to which version is defined in appendix A,
     * table 39.. 
    encoding_version = request_version = NULL;
     * Essentially, if the client sends us an Encoding-Version
     * higher than ours (1.3) we send our version number to it,
     * if it is lower, we left version number intact. */
    /* First the case that we have no Encoding-Version header at all. 
     * This case we must assume that the client supports version 1.2
     * or lower. */

    headers = http_create_empty_headers();
    encoding_version = wsp_encoding_version_to_string(m->encoding_version);
    http_header_add(headers, "Encoding-Version", octstr_get_cstr(encoding_version));
    octstr_destroy(encoding_version);

    return headers;
}
Example #5
0
void mms_cfg_destroy(mCfg *cfg)
{
     List *l;
     int i, n;

     gw_assert(cfg);
     
     for (i = 0, l  = dict_keys(cfg->grps), n = gwlist_len(l); i < n; i++) {
	  Octstr *grpname = gwlist_get(l, i);
	  void *val = dict_get(cfg->grps, grpname);
	  if (is_multigroup(grpname)) { /* item is a list. */
	       List *gl = val;	  
	int j, m = gwlist_len(gl);
	       for (j = 0; j < m; j++)
		    mGrp_destroy(gwlist_get(gl, j));
	       gwlist_destroy(gl, NULL);
	  } else 
	       mGrp_destroy(val);	  
     }
     gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
     dict_destroy(cfg->grps);
     octstr_destroy(cfg->file);
     gw_free(cfg);
}
Example #6
0
octstr_t * octstr_load_from_file(const char *path)
{
    octstr_t *s;
    int fd, n;
    char buf[1024000];

    if( (fd = open(path, O_RDONLY)) == -1 ) {
        return NULL;
    }

    s = octstr_create(NULL, 0);
    while( (n = read(fd, buf, 1024000)) > 0 ) {
        octstr_str_append(s, buf, n);
    }

    close(fd);

    if( n < 0 ) {
        octstr_destroy(s);
        return NULL;
    }

    return s;
}
Example #7
0
void wap_map_destroy(void) 
{
    long i;
    struct url_map_struct *entry;

    if (url_map != NULL) {
        for (i = 0; i < gwlist_len(url_map); i++) {
            entry = gwlist_get(url_map, i);
            octstr_destroy(entry->name);
            octstr_destroy(entry->url);
            octstr_destroy(entry->map_url);
            octstr_destroy(entry->send_msisdn_query);
            octstr_destroy(entry->send_msisdn_header);
            octstr_destroy(entry->send_msisdn_format);
            gw_free(entry);
        }
        gwlist_destroy(url_map, NULL);
    }
    url_map = NULL;
}
Example #8
0
/*
 * We try to find an optional header, so a failure to find one is not an 
 * error. Return -1 when error, 0 when header name not found, 1 otherwise.
 * Search only until 'boundary'.
 */
static int pass_optional_header(Octstr **body_part, char *name, List **content_headers,
                                Octstr *boundary)
{
    long content_pos,
         next_header_pos;
    Octstr *osname,
           *osvalue;
    long message_start_pos;

    content_pos = next_header_pos = -1;
    osname = octstr_create(name);
    osvalue = octstr_create("");
    message_start_pos = octstr_search(*body_part, boundary, 0);

    if ((content_pos = octstr_case_nsearch(*body_part, osname, 0, message_start_pos)) < 0) 
        goto noheader;
    if ((next_header_pos = pass_field_value(body_part, &osvalue, 
	     content_pos + octstr_len(osname))) < 0)
        goto error;   
    if ((next_header_pos = 
	     parse_terminator(*body_part, next_header_pos)) == 0)
        goto error;

    drop_separator(&osvalue, &next_header_pos);
    http_header_add(*content_headers, name, octstr_get_cstr(osvalue));
    octstr_delete(*body_part, content_pos, next_header_pos - content_pos);

    octstr_destroy(osname);
    octstr_destroy(osvalue);
    return 1;

error:
    octstr_destroy(osvalue);
    octstr_destroy(osname);
    return -1;

noheader:
    octstr_destroy(osvalue);
    octstr_destroy(osname);
    return 0;
}
Example #9
0
File: smsc.c Project: sivirk/kannel
SMSCenter *smsc_open(CfgGroup *grp)
{
    SMSCenter *smsc;
    Octstr *type, *host, *username, *password, *phone, *device;
    Octstr *preferred_prefix, *allowed_prefix, *denied_prefix;
    Octstr *alt_chars, *allow_ip;
    Octstr *sema_smscnua, *sema_homenua, *sema_report;
    Octstr *sender_prefix;

    long iwaitreport;
    long port, receive_port, our_port;
    long keepalive;
    long ois_debug;
    long alt_dcs;
    int typeno;


    type = cfg_get(grp, octstr_imm("smsc"));
    if (type == NULL) {
	error(0, "Required field 'smsc' missing for smsc group.");
	return NULL;
    }
    if (octstr_compare(type, octstr_imm("cimd")) == 0)
    	typeno = SMSC_TYPE_CIMD;
    else if (octstr_compare(type, octstr_imm("emi_x25")) == 0)
    	typeno = SMSC_TYPE_EMI_X25;
    else if (octstr_compare(type, octstr_imm("sema")) == 0)
    	typeno = SMSC_TYPE_SEMA_X28;
    else if (octstr_compare(type, octstr_imm("ois")) == 0)
    	typeno = SMSC_TYPE_OIS;
    else {
	error(0, "Unknown SMSC type '%s'", octstr_get_cstr(type));
	octstr_destroy(type);
	return NULL;
    }

    host = cfg_get(grp, octstr_imm("host"));
    if (cfg_get_integer(&port, grp, octstr_imm("port")) == -1)
    	port = 0;
    if (cfg_get_integer(&receive_port, grp, octstr_imm("receive-port")) == -1)
    	receive_port = 0;
    if (cfg_get_integer(&our_port, grp, octstr_imm("our-port")) == -1)
    	our_port = 0;
    username = cfg_get(grp, octstr_imm("smsc-username"));
    password = cfg_get(grp, octstr_imm("smsc-password"));
    phone = cfg_get(grp, octstr_imm("phone"));
    device = cfg_get(grp, octstr_imm("device"));
    preferred_prefix = cfg_get(grp, octstr_imm("preferred-prefix"));
    allowed_prefix = cfg_get(grp, octstr_imm("allowed-prefix"));
    denied_prefix = cfg_get(grp, octstr_imm("denied-prefix"));
    alt_chars = cfg_get(grp, octstr_imm("alt-charset"));

    allow_ip = cfg_get(grp, octstr_imm("connect-allow-ip"));

    sema_smscnua = cfg_get(grp, octstr_imm("smsc_nua"));
    sema_homenua = cfg_get(grp, octstr_imm("home_nua"));
    sema_report = cfg_get(grp, octstr_imm("wait_report"));
    if (sema_report == NULL)
    	iwaitreport = 1;
    else
    	octstr_parse_long(&iwaitreport, sema_report, 0, 0);

    if (cfg_get_integer(&keepalive, grp, octstr_imm("keepalive")) == -1)
    	keepalive = 0;

    if (cfg_get_integer(&alt_dcs, grp, octstr_imm("alt-dcs")) == -1)
    	alt_dcs = 0;
    if (alt_dcs > 1)
        alt_dcs = 1;

    if (cfg_get_integer(&ois_debug, grp, octstr_imm("ois-debug-level")) == -1)
    	ois_debug = 0;

    sender_prefix = cfg_get(grp, octstr_imm("sender-prefix"));
    if (sender_prefix == NULL)
        sender_prefix = octstr_create("never");

    smsc = NULL;

    switch (typeno) {
    case SMSC_TYPE_CIMD:
        if (host == NULL || port == 0 || username == NULL || password == NULL)
            error(0, "Required field missing for CIMD center.");
        else
            smsc = cimd_open(octstr_get_cstr(host),
	    	    	     port, 
	    	    	     octstr_get_cstr(username), 
			     octstr_get_cstr(password));
        break;

    case SMSC_TYPE_EMI_X25:
        if (phone == NULL || device == NULL || username == NULL ||
            password == NULL)
            error(0, "Required field missing for EMI_X25 center.");
        else
            smsc = emi_open(octstr_get_cstr(phone), 
	    	    	    octstr_get_cstr(device), 
			    octstr_get_cstr(username), 
			    octstr_get_cstr(password));
        break;

    case SMSC_TYPE_SEMA_X28:
        if (device == NULL || sema_smscnua == NULL || sema_homenua == NULL)
            error(0, "Required field missing for SEMA center.");
        else
            smsc = sema_open(octstr_get_cstr(sema_smscnua), 
	    	    	     octstr_get_cstr(sema_homenua), 
			     octstr_get_cstr(device),
                             iwaitreport);
        break;

    case SMSC_TYPE_OIS:
        if (host == NULL || port == 0 || receive_port == 0)
            error(0, "Required field missing for OIS center.");
        else
            smsc = ois_open(receive_port, 
	    	    	    octstr_get_cstr(host), 
			    port, 
	    	    	    ois_debug);
        break;

        /* add new SMSCes here */

    default: 		/* Unknown SMSC type */
        break;
    }

    if (smsc != NULL) {
	if (cfg_get_integer(&smsc->alt_charset, grp, 
	    	    	    octstr_imm("alt-charset")) == -1)
	    smsc->alt_charset = 0;
    	if (preferred_prefix == NULL)
	    smsc->preferred_prefix = NULL;
	else
	    smsc->preferred_prefix = 
	    	gw_strdup(octstr_get_cstr(preferred_prefix));
    	if (allowed_prefix == NULL)
	    smsc->allowed_prefix = NULL;
	else
	    smsc->allowed_prefix = gw_strdup(octstr_get_cstr(allowed_prefix));
    	if (denied_prefix == NULL)
	    smsc->denied_prefix = NULL;
	else
	    smsc->denied_prefix = gw_strdup(octstr_get_cstr(denied_prefix));
    }

    octstr_destroy(type);
    octstr_destroy(host);
    octstr_destroy(username);
    octstr_destroy(password);
    octstr_destroy(phone);
    octstr_destroy(device);
    octstr_destroy(preferred_prefix);
    octstr_destroy(denied_prefix);
    octstr_destroy(allowed_prefix);
    octstr_destroy(alt_chars);
    octstr_destroy(allow_ip);
    octstr_destroy(sema_smscnua);
    octstr_destroy(sema_homenua);
    octstr_destroy(sema_report);
    octstr_destroy(sender_prefix);
    return smsc;
}
Example #10
0
static Octstr *get_pattern(SMSCConn *conn, Msg *msg, const char *message)
{
    int nextarg, j;
    struct tm tm;
    int num_words;
    List *word_list;
    Octstr *result;
    const char *pattern;
    Octstr *temp, *text, *udh;
    size_t n;
    long i;
 
    text = msg->sms.msgdata ? octstr_duplicate(msg->sms.msgdata) : octstr_create("");
    udh = msg->sms.udhdata ? octstr_duplicate(msg->sms.udhdata) : octstr_create("");
    if ((msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2))
        octstr_binary_to_hex(text, 1);
    else
        octstr_convert_printable(text);
    octstr_binary_to_hex(udh, 1);

    if (octstr_len(text)) {
        word_list = octstr_split_words(text);
        num_words = gwlist_len(word_list);
    } else {
    	word_list = gwlist_create();
        num_words = 0;
    }

    result = octstr_create("");
    pattern = octstr_get_cstr(custom_log_format);

    nextarg = 1;

    while(*pattern != '\0') {
        n = strcspn(pattern, "%");
        octstr_append_data(result, pattern, n);
        pattern += n;
        gw_assert(*pattern == '%' || *pattern == '\0');
        if (*pattern == '\0')
            break;

        pattern++;
        
        switch (*pattern) {
	case 'k':
	    if (num_words <= 0)
                break;
	    octstr_append(result, gwlist_get(word_list, 0));
	    break;

	case 's':
	    if (nextarg >= num_words)
                break;
	    octstr_append(result, gwlist_get(word_list, nextarg));
	    ++nextarg;
	    break;

	case 'S':
	    if (nextarg >= num_words)
                break;
	    temp = gwlist_get(word_list, nextarg);
	    for (i = 0; i < octstr_len(temp); ++i) {
		if (octstr_get_char(temp, i) == '*')
		    octstr_append_char(result, '~');
		else
		    octstr_append_char(result, octstr_get_char(temp, i));
	    }
	    ++nextarg;
	    break;

	case 'r':
	    for (j = nextarg; j < num_words; ++j) {
		if (j != nextarg)
		    octstr_append_char(result, '+');
		octstr_append(result, gwlist_get(word_list, j));
	    }
	    break;
    
	case 'l':
            if (message)
	        octstr_append_cstr(result, message);
	    break;

	case 'P':
            if (msg->sms.receiver)
	        octstr_append(result, msg->sms.receiver);
	    break;

	case 'p':
            if (msg->sms.sender)
	        octstr_append(result, msg->sms.sender);
	    break;

	case 'a':
	    for (j = 0; j < num_words; ++j) {
                if (j > 0)
                    octstr_append_char(result, ' ');
                octstr_append(result, gwlist_get(word_list, j));
            }
            break;

	case 'b':
            if (text)
	        octstr_append(result, text);
	    break;

	case 'L':
	    octstr_append_decimal(result, octstr_len(msg->sms.msgdata));
	    break;

	case 't':
	    tm = gw_gmtime(msg->sms.time);
	    octstr_format_append(result, "%04d-%02d-%02d %02d:%02d:%02d",
				 tm.tm_year + 1900,
				 tm.tm_mon + 1,
				 tm.tm_mday,
				 tm.tm_hour,
				 tm.tm_min,
				 tm.tm_sec);
	    break;

	case 'T':
	    if (msg->sms.time != MSG_PARAM_UNDEFINED)
	        octstr_format_append(result, "%ld", msg->sms.time);
	    break;

	case 'i':
	    if (conn && smscconn_id(conn))
	        octstr_append(result, smscconn_id(conn));
	    else if (conn && smscconn_name(conn))
	        octstr_append(result, smscconn_name(conn));
	    else if (msg->sms.smsc_id)
	        octstr_append(result, msg->sms.smsc_id);
	    break;

	case 'I':
	    if (!uuid_is_null(msg->sms.id)) {
                char id[UUID_STR_LEN + 1];
                uuid_unparse(msg->sms.id, id);
	        octstr_append_cstr(result, id);
            }
	    break;

	case 'n':
	    if (msg->sms.service != NULL)
	        octstr_append(result, msg->sms.service);
	    break;

	case 'd':
	    octstr_append_decimal(result, msg->sms.dlr_mask);
	    break;

	case 'c':
	    octstr_append_decimal(result, msg->sms.coding);
	    break;

	case 'm':
	    octstr_append_decimal(result, msg->sms.mclass);
	    break;

	case 'C':
	    octstr_append_decimal(result, msg->sms.compress);
	    break;

	case 'M':
	    octstr_append_decimal(result, msg->sms.mwi);
	    break;

	case 'u':
	    if (octstr_len(udh)) {
                octstr_append(result, udh);
	    }
	    break;

	case 'U':
	    octstr_append_decimal(result, octstr_len(msg->sms.udhdata));
	    break;

	case 'B':  /* billing identifier/information */
	    if (octstr_len(msg->sms.binfo)) {
                octstr_append(result, msg->sms.binfo);
            }
            break;

	case 'A':  /* account */
	    if (octstr_len(msg->sms.account)) {
                octstr_append(result, msg->sms.account);
            }
            break;

	case 'F': /* the foreign (smsc-provided) message ID */
	    if (msg->sms.foreign_id != NULL)
	        octstr_append(result, msg->sms.foreign_id);
	    break;

        /* XXX add more here if needed */

	case '%':
	    octstr_format_append(result, "%%");
	    break;

	default:
	    warning(0, "Unknown escape code (%%%c) within custom-log-format, skipping!", *pattern);
            octstr_format_append(result, "%%%c", *pattern);
	    break;
        } /* switch(...) */
    
        pattern++;
    } /* for ... */

    gwlist_destroy(word_list, octstr_destroy_item);
    octstr_destroy(text);
    octstr_destroy(udh);

    return result;
}
Example #11
0
struct dlr_storage *dlr_init_sdb(Cfg* cfg)
{
    CfgGroup *grp;
    List *grplist;
    Octstr *sdb_url, *sdb_id;
    Octstr *p = NULL;
    long pool_size;
    DBConf *db_conf = NULL;

    /*
     * check for all mandatory directives that specify the field names
     * of the used table
     */
    if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db"))))
        panic(0, "DLR: SDB: group 'dlr-db' is not specified!");

    if (!(sdb_id = cfg_get(grp, octstr_imm("id"))))
   	    panic(0, "DLR: SDB: directive 'id' is not specified!");

    fields = dlr_db_fields_create(grp);
    gw_assert(fields != NULL);

    /*
     * now grap the required information from the 'mysql-connection' group
     * with the sdb-id we just obtained
     *
     * we have to loop through all available SDB connection definitions
     * and search for the one we are looking for
     */

    grplist = cfg_get_multi_group(cfg, octstr_imm("sdb-connection"));
    while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
        p = cfg_get(grp, octstr_imm("id"));
        if (p != NULL && octstr_compare(p, sdb_id) == 0) {
            goto found;
        }
        if (p != NULL) octstr_destroy(p);
    }
    panic(0, "DLR: SDB: connection settings for id '%s' are not specified!",
          octstr_get_cstr(sdb_id));

found:
    octstr_destroy(p);
    gwlist_destroy(grplist, NULL);

    if (cfg_get_integer(&pool_size, grp, octstr_imm("max-connections")) == -1 || pool_size == 0)
        pool_size = 1;

    if (!(sdb_url = cfg_get(grp, octstr_imm("url"))))
   	    panic(0, "DLR: SDB: directive 'url' is not specified!");

    if (octstr_search(sdb_url, octstr_imm("oracle:"), 0) == 0)
        sdb_conn_type = SDB_ORACLE;
    else if (octstr_search(sdb_url, octstr_imm("mysql:"), 0) == 0) {
        warning(0, "DLR[sdb]: Please use native MySQL support, instead of libsdb.");
        sdb_conn_type = SDB_MYSQL;
    }
    else if (octstr_search(sdb_url, octstr_imm("postgres:"), 0) == 0) {
        sdb_conn_type = SDB_POSTGRES;
    }
    else
        sdb_conn_type = SDB_OTHER;

    /*
     * ok, ready to connect
     */
    info(0,"Connecting to sdb resource <%s>.", octstr_get_cstr(sdb_url));

    db_conf = gw_malloc(sizeof(DBConf));
    gw_assert(db_conf != NULL);

    db_conf->sdb = gw_malloc(sizeof(SDBConf));
    gw_assert(db_conf->sdb != NULL);

    db_conf->sdb->url = sdb_url;

    pool = dbpool_create(DBPOOL_SDB, db_conf, pool_size);
    gw_assert(pool != NULL);

    /*
     * XXX should a failing connect throw panic?!
     */
    if (dbpool_conn_count(pool) == 0)
        panic(0,"DLR: SDB: database pool has no connections!");

    return &handles;
}
Example #12
0
long date_parse_http(Octstr *date)
{
    long pos;
    struct universaltime t;
    Octstr *monthstr = NULL;

    /* First, skip the leading day-of-week string. */
    pos = octstr_search_char(date, ' ', 0);
    if (pos < 0 || pos == octstr_len(date) - 1)
        return -1;
    pos++;  /* Skip the space */

    /* Distinguish between the three acceptable formats */
    if (isdigit(octstr_get_char(date, pos)) &&
        octstr_get_char(date, pos + 2) == ' ') {
        if (octstr_len(date) - pos < (long)strlen("06 Nov 1994 08:49:37 GMT"))
            goto error;
        if (octstr_parse_long(&t.day, date, pos, 10) != pos + 2)
            goto error;
        monthstr = octstr_copy(date, pos + 3, 3);
        if (octstr_parse_long(&t.year, date, pos + 7, 10) != pos + 11)
            goto error;
        if (octstr_parse_long(&t.hour, date, pos + 12, 10) != pos + 14)
            goto error;
        if (octstr_parse_long(&t.minute, date, pos + 15, 10) != pos + 17)
            goto error;
        if (octstr_parse_long(&t.second, date, pos + 18, 10) != pos + 20)
            goto error;
        /* Take the GMT part on faith. */
    } else if (isdigit(octstr_get_char(date, pos)) &&
               octstr_get_char(date, pos + 2) == '-') {
        if (octstr_len(date) - pos < (long)strlen("06-Nov-94 08:49:37 GMT"))
            goto error;
        if (octstr_parse_long(&t.day, date, pos, 10) != pos + 2)
            goto error;
        monthstr = octstr_copy(date, pos + 3, 3);
        if (octstr_parse_long(&t.year, date, pos + 7, 10) != pos + 9)
            goto error;
        if (t.year > 60)
            t.year += 1900;
        else
            t.year += 2000;
        if (octstr_parse_long(&t.hour, date, pos + 10, 10) != pos + 12)
            goto error;
        if (octstr_parse_long(&t.minute, date, pos + 13, 10) != pos + 15)
            goto error;
        if (octstr_parse_long(&t.second, date, pos + 16, 10) != pos + 18)
            goto error;
        /* Take the GMT part on faith. */
    } else {
        if (octstr_len(date) - pos < (long)strlen(" 6 08:49:37 1994"))
            goto error;
        monthstr = octstr_copy(date, pos, 3);
        if (octstr_parse_long(&t.day, date, pos + 4, 10) != pos + 6)
            goto error;
        if (octstr_parse_long(&t.hour, date, pos + 7, 10) != pos + 9)
            goto error;
        if (octstr_parse_long(&t.minute, date, pos + 10, 10) != pos + 12)
            goto error;
        if (octstr_parse_long(&t.second, date, pos + 13, 10) != pos + 15)
            goto error;
        if (octstr_parse_long(&t.year, date, pos + 16, 10) != pos + 20)
            goto error;
    }

    for (t.month = 0; t.month < 12; t.month++) {
        if (octstr_str_compare(monthstr, monthname[t.month]) == 0)
            break;
    }
    if (t.month == 12)
        goto error;

    octstr_destroy(monthstr);
    return date_convert_universal(&t);

error:
    octstr_destroy(monthstr);
    return -1;
}
Example #13
0
static void wrapper_sender(void *arg)
{
    Msg 	*msg;
    SMSCConn 	*conn = arg;
    SmscWrapper *wrap = conn->data;

    /* Make sure we log into our own log-file if defined */
    log_thread_to(conn->log_idx);

    /* send messages to SMSC until our outgoing_list is empty and
     * no producer anymore (we are set to shutdown) */
    while(conn->status != SMSCCONN_DEAD) {

	if ((msg = gwlist_consume(wrap->outgoing_queue)) == NULL)
            break;

        if (octstr_search_char(msg->sms.receiver, ' ', 0) != -1) {
            /*
             * multi-send: this should be implemented in corresponding
             *  SMSC protocol, but while we are waiting for that...
             */
            int i;
	    Msg *newmsg;
            /* split from spaces: in future, split with something more sensible,
             * this is dangerous... (as space is url-encoded as '+')
             */
            List *nlist = octstr_split_words(msg->sms.receiver);

	    debug("bb.sms", 0, "Handling multi-receiver message");

            for(i=0; i < gwlist_len(nlist); i++) {

		newmsg = msg_duplicate(msg);
                octstr_destroy(newmsg->sms.receiver);

                newmsg->sms.receiver = gwlist_get(nlist, i);
                sms_send(conn, newmsg);
            }
            gwlist_destroy(nlist, NULL);
            msg_destroy(msg);
        }
        else
	    sms_send(conn,msg);

    }
    /* cleanup, we are now dying */

    debug("bb.sms", 0, "SMSCConn %s sender died, waiting for receiver",
	  octstr_get_cstr(conn->name));
    
    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;

    if (conn->is_stopped) {
	gwlist_remove_producer(wrap->stopped);
	conn->is_stopped = 0;
    }

    gwthread_wakeup(wrap->receiver_thread);
    gwthread_join(wrap->receiver_thread);

    /* call 'failed' to all messages still in queue */
    
    mutex_lock(conn->flow_mutex);

    conn->status = SMSCCONN_DEAD;

    while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) {
	bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);
    }
    smscwrapper_destroy(wrap);
    conn->data = NULL;
    
    mutex_unlock(conn->flow_mutex);

    bb_smscconn_killed();
}
Example #14
0
struct dlr_storage *dlr_init_redis(Cfg *cfg)
{
    CfgGroup *grp;
    List *grplist;
    Octstr *redis_host, *redis_pass, *redis_id;
    long redis_port = 0, redis_database = -1, redis_idle_timeout = -1;
    Octstr *p = NULL;
    long pool_size;
    DBConf *db_conf = NULL;

    /*
     * Check for all mandatory directives that specify the field names
     * of the used Redis key
     */
    if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db"))))
        panic(0, "DLR: Redis: group 'dlr-db' is not specified!");

    if (!(redis_id = cfg_get(grp, octstr_imm("id"))))
        panic(0, "DLR: Redis: directive 'id' is not specified!");

    fields = dlr_db_fields_create(grp);
    gw_assert(fields != NULL);

    /*
     * Escaping special quotes for field/table names
     */
    octstr_replace(fields->table, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_smsc, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_ts, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_src, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_dst, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_serv, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_url, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_mask, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_status, octstr_imm("`"), octstr_imm("``"));
    octstr_replace(fields->field_boxc, octstr_imm("`"), octstr_imm("``"));

    /*
     * Now grab the required information from the 'redis-connection' group
     * with the redis-id we just obtained.
     *
     * We have to loop through all available Redis connection definitions
     * and search for the one we are looking for.
     */
    grplist = cfg_get_multi_group(cfg, octstr_imm("redis-connection"));
    while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
        p = cfg_get(grp, octstr_imm("id"));
        if (p != NULL && octstr_compare(p, redis_id) == 0) {
            goto found;
        }
        if (p != NULL)
            octstr_destroy(p);
    }
    panic(0, "DLR: Redis: connection settings for id '%s' are not specified!",
          octstr_get_cstr(redis_id));

found:
    octstr_destroy(p);
    gwlist_destroy(grplist, NULL);

    if (cfg_get_integer(&pool_size, grp, octstr_imm("max-connections")) == -1 || pool_size == 0)
        pool_size = 1;

    if (!(redis_host = cfg_get(grp, octstr_imm("host"))))
   	    panic(0, "DLR: Redis: directive 'host' is not specified!");
    if (cfg_get_integer(&redis_port, grp, octstr_imm("port")) == -1)
   	    panic(0, "DLR: Redis: directive 'port' is not specified!");
    redis_pass = cfg_get(grp, octstr_imm("password"));
    cfg_get_integer(&redis_database, grp, octstr_imm("database"));
    cfg_get_integer(&redis_idle_timeout, grp, octstr_imm("idle-timeout"));

    /*
     * Ok, ready to connect to Redis
     */
    db_conf = gw_malloc(sizeof(DBConf));
    gw_assert(db_conf != NULL);

    db_conf->redis = gw_malloc(sizeof(RedisConf));
    gw_assert(db_conf->redis != NULL);

    db_conf->redis->host = redis_host;
    db_conf->redis->port = redis_port;
    db_conf->redis->password = redis_pass;
    db_conf->redis->database = redis_database;
    db_conf->redis->idle_timeout = redis_idle_timeout;

    pool = dbpool_create(DBPOOL_REDIS, db_conf, pool_size);
    gw_assert(pool != NULL);

    /*
     * Panic on failure to connect. Should we just try to reconnect?
     */
    if (dbpool_conn_count(pool) == 0)
        panic(0,"DLR: Redis: database pool has no connections!");

    octstr_destroy(redis_id);

    return &handles;
}
Example #15
0
static struct dlr_entry *dlr_redis_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
{
    Octstr *key, *sql;
    DBPoolConn *pconn;
    List *binds = gwlist_create();
    List *result = NULL, *row;
    struct dlr_entry *res = NULL;

    pconn = dbpool_conn_consume(pool);
    if (pconn == NULL) {
        error(0, "DLR: REDIS: No connection available");
        gwlist_destroy(binds, NULL);
        dbpool_conn_produce(pconn);
        return NULL;
    }

    /* If the destination address is not NULL, then
     * it has been shortened by the abstractive layer. */
    key = octstr_format((dst ? "%S:?:?:?" : "%S:?:?"), fields->table);

    sql = octstr_format("HMGET %S ? ? ? ? ? ?", key);
    gwlist_append(binds, (Octstr *)smsc); /* key */
    gwlist_append(binds, (Octstr *)ts); /* key */
    if (dst)
        gwlist_append(binds, (Octstr *)dst); /* key */
    gwlist_append(binds, fields->field_mask);
    gwlist_append(binds, fields->field_serv);
    gwlist_append(binds, fields->field_url);
    gwlist_append(binds, fields->field_src);
    gwlist_append(binds, fields->field_dst);
    gwlist_append(binds, fields->field_boxc);

    if (dbpool_conn_select(pconn, sql, binds, &result) != 0) {
        error(0, "DLR: REDIS: Failed to fetch DLR for %s", octstr_get_cstr(key));
        octstr_destroy(sql);
        octstr_destroy(key);
        gwlist_destroy(binds, NULL);
        dbpool_conn_produce(pconn);
        return NULL;
    }

    dbpool_conn_produce(pconn);
    octstr_destroy(sql);
    octstr_destroy(key);
    gwlist_destroy(binds, NULL);

#define LO2CSTR(r, i) octstr_get_cstr(gwlist_get(r, i))

    if (gwlist_len(result) > 0) {
        row = gwlist_extract_first(result);

        /*
         * If we get an empty set back from redis, this is
         * still an array with "" values, representing (nil).
         * If the mask is empty then this can't be a valid
         * set, therefore bail out.
         */
        if (octstr_len(gwlist_get(row, 0)) > 0) {
            res = dlr_entry_create();
            gw_assert(res != NULL);
            res->mask = atoi(octstr_get_cstr(gwlist_get(row, 0)));
            get_octstr_value(&res->service, row, 1);
            get_octstr_value(&res->url, row, 2);
            octstr_url_decode(res->url);
            get_octstr_value(&res->source, row, 3);
            get_octstr_value(&res->destination, row, 4);
            get_octstr_value(&res->boxc_id, row, 5);
            res->smsc = octstr_duplicate(smsc);

            octstr_replace(res->source, octstr_imm("__space__"), octstr_imm(" "));
            octstr_replace(res->destination, octstr_imm("__space__"), octstr_imm(" "));
        }
        gwlist_destroy(row, octstr_destroy_item);
    }
    gwlist_destroy(result, NULL);

#undef LO2CSTR

    return res;
}
Example #16
0
static void kannel_receive_sms(SMSCConn *conn, HTTPClient *client,
                               List *headers, Octstr *body, List *cgivars)
{
    ConnData *conndata = conn->data;
    Octstr *user, *pass, *from, *to, *text, *udh, *account, *binfo, *charset;
    Octstr *dlrmid, *dlrerr;
    Octstr *tmp_string, *retmsg;
    int	mclass, mwi, coding, validity, deferred, dlrmask;
    List *reply_headers;
    int ret;
	
    mclass = mwi = coding = validity = 
        deferred = dlrmask = SMS_PARAM_UNDEFINED;

    user = http_cgi_variable(cgivars, "username");
    pass = http_cgi_variable(cgivars, "password");
    from = http_cgi_variable(cgivars, "from");
    to = http_cgi_variable(cgivars, "to");
    text = http_cgi_variable(cgivars, "text");
    udh = http_cgi_variable(cgivars, "udh");
    charset = http_cgi_variable(cgivars, "charset");
    account = http_cgi_variable(cgivars, "account");
    binfo = http_cgi_variable(cgivars, "binfo");
    dlrmid = http_cgi_variable(cgivars, "dlr-mid");
    tmp_string = http_cgi_variable(cgivars, "flash");
    if (tmp_string) {
        sscanf(octstr_get_cstr(tmp_string),"%d", &mclass);
    }
    tmp_string = http_cgi_variable(cgivars, "mclass");
    if (tmp_string) {
        sscanf(octstr_get_cstr(tmp_string),"%d", &mclass);
    }
    tmp_string = http_cgi_variable(cgivars, "mwi");
    if (tmp_string) {
        sscanf(octstr_get_cstr(tmp_string),"%d", &mwi);
    }
    tmp_string = http_cgi_variable(cgivars, "coding");
    if (tmp_string) {
        sscanf(octstr_get_cstr(tmp_string),"%d", &coding);
    }
    tmp_string = http_cgi_variable(cgivars, "validity");
    if (tmp_string) {
        sscanf(octstr_get_cstr(tmp_string),"%d", &validity);
    }
    tmp_string = http_cgi_variable(cgivars, "deferred");
    if (tmp_string) {
        sscanf(octstr_get_cstr(tmp_string),"%d", &deferred);
    }
    tmp_string = http_cgi_variable(cgivars, "dlr-mask");
    if (tmp_string) {
        sscanf(octstr_get_cstr(tmp_string),"%d", &dlrmask);
    }
    dlrerr = http_cgi_variable(cgivars, "dlr-err");

    debug("smsc.http.kannel", 0, "HTTP[%s]: Received an HTTP request",
          octstr_get_cstr(conn->id));
    
    if (user == NULL || pass == NULL ||
	    octstr_compare(user, conndata->username) != 0 ||
	    octstr_compare(pass, conndata->password) != 0) {

        error(0, "HTTP[%s]: Authorization failure",
              octstr_get_cstr(conn->id));
        retmsg = octstr_create("Authorization failed for sendsms");
    } else if (dlrmask != 0 && dlrmid != NULL) {
        /* we got a DLR, and we don't require additional values */
        Msg *dlrmsg;
        
        dlrmsg = dlr_find(conn->id,
            dlrmid, /* message id */
            to, /* destination */
            dlrmask, 0);

        if (dlrmsg != NULL) {
            dlrmsg->sms.sms_type = report_mo;
            dlrmsg->sms.msgdata = octstr_duplicate(text);
            dlrmsg->sms.account = octstr_duplicate(conndata->username);

            debug("smsc.http.kannel", 0, "HTTP[%s]: Received DLR for DLR-URL <%s>",
                  octstr_get_cstr(conn->id), octstr_get_cstr(dlrmsg->sms.dlr_url));

            if (dlrerr != NULL) {
                /* pass errorcode as is */
            	if (dlrmsg->sms.meta_data == NULL)
            		dlrmsg->sms.meta_data = octstr_create("");

                meta_data_set_value(dlrmsg->sms.meta_data, METADATA_DLR_GROUP,
                                    octstr_imm(METADATA_DLR_GROUP_ERRORCODE), dlrerr, 1);
            }
            
            ret = bb_smscconn_receive(conn, dlrmsg);
            if (ret == -1)
                retmsg = octstr_create("Not accepted");
            else
                retmsg = octstr_create("Sent.");
        } else {
            error(0,"HTTP[%s]: Got DLR but could not find message or was not interested "
                  "in it id<%s> dst<%s>, type<%d>",
                  octstr_get_cstr(conn->id), octstr_get_cstr(dlrmid),
                  octstr_get_cstr(to), dlrmask);
            retmsg = octstr_create("Unknown DLR, not accepted");
        }                    
    }
    else if (from == NULL || to == NULL || text == NULL) {
	
        error(0, "HTTP[%s]: Insufficient args",
              octstr_get_cstr(conn->id));
        retmsg = octstr_create("Insufficient args, rejected");
    }
    else if (udh != NULL && (octstr_len(udh) != octstr_get_char(udh, 0) + 1)) {
        error(0, "HTTP[%s]: UDH field misformed, rejected",
              octstr_get_cstr(conn->id));
        retmsg = octstr_create("UDH field misformed, rejected");
    }
    else if (udh != NULL && octstr_len(udh) > MAX_SMS_OCTETS) {
        error(0, "HTTP[%s]: UDH field is too long, rejected",
              octstr_get_cstr(conn->id));
        retmsg = octstr_create("UDH field is too long, rejected");
    }
    else {
        /* we got a normal MO SMS */
        Msg *msg;
        msg = msg_create(sms);

        debug("smsc.http.kannel", 0, "HTTP[%s]: Constructing new SMS",
              octstr_get_cstr(conn->id));
	
        msg->sms.service = octstr_duplicate(user);
        msg->sms.sender = octstr_duplicate(from);
        msg->sms.receiver = octstr_duplicate(to);
        msg->sms.msgdata = octstr_duplicate(text);
        msg->sms.udhdata = octstr_duplicate(udh);

        msg->sms.smsc_id = octstr_duplicate(conn->id);
        msg->sms.time = time(NULL);
        msg->sms.mclass = mclass;
        msg->sms.mwi = mwi;
        msg->sms.coding = coding;
        msg->sms.validity = (validity == SMS_PARAM_UNDEFINED ? validity : time(NULL) + validity * 60);
        msg->sms.deferred = (deferred == SMS_PARAM_UNDEFINED ? deferred : time(NULL) + deferred * 60);
        msg->sms.account = octstr_duplicate(account);
        msg->sms.binfo = octstr_duplicate(binfo);

        /* re-encode content if necessary */
        if (sms_charset_processing(charset, msg->sms.msgdata, msg->sms.coding) == -1) {
            error(0, "HTTP[%s]: Charset or body misformed, rejected",
                  octstr_get_cstr(conn->id));
            retmsg = octstr_create("Charset or body misformed, rejected");
        }
        else {

            ret = bb_smscconn_receive(conn, msg);
            if (ret == -1)
                retmsg = octstr_create("Not accepted");
            else
                retmsg = octstr_create("Sent.");
        }
    }

    reply_headers = gwlist_create();
    http_header_add(reply_headers, "Content-Type", "text/plain");
    debug("smsc.http.kannel", 0, "HTTP[%s]: Sending reply",
          octstr_get_cstr(conn->id));
    http_send_reply(client, HTTP_ACCEPTED, reply_headers, retmsg);

    octstr_destroy(retmsg);
    http_destroy_headers(reply_headers);
}
Example #17
0
int smsc_http_create(SMSCConn *conn, CfgGroup *cfg)
{
    ConnData *conndata = NULL;
    Octstr *type;
    int ssl = 0;   /* indicate if SSL-enabled server should be used */
    long max_ps;

    if ((type = cfg_get(cfg, octstr_imm("system-type"))) == NULL) {
        error(0, "HTTP[%s]: 'system-type' missing in smsc 'http' record.",
              octstr_get_cstr(conn->id));
        octstr_destroy(type);
        return -1;
    }

    conndata = gw_malloc(sizeof(ConnData));
    /* reset conndata */
    memset(conndata, 0, sizeof(ConnData));

    conn->data = conndata;
    conndata->http_ref = NULL;
    conndata->data = NULL;

    if (cfg_get_integer(&conndata->port, cfg, octstr_imm("port")) == -1) {
        warning(0, "HTTP[%s]: 'port' not set in smsc 'http' group.",
              octstr_get_cstr(conn->id));
        conndata->port = -1;
    }

    conndata->allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip"));
    conndata->send_url = cfg_get(cfg, octstr_imm("send-url"));
    conndata->username = cfg_get(cfg, octstr_imm("smsc-username"));
    conndata->password = cfg_get(cfg, octstr_imm("smsc-password"));
    conndata->system_id = cfg_get(cfg, octstr_imm("system-id"));
    cfg_get_bool(&conndata->no_sender, cfg, octstr_imm("no-sender"));
    cfg_get_bool(&conndata->no_coding, cfg, octstr_imm("no-coding"));
    cfg_get_bool(&conndata->no_sep, cfg, octstr_imm("no-sep"));
    conndata->proxy = cfg_get(cfg, octstr_imm("system-id"));
    cfg_get_bool(&ssl, cfg, octstr_imm("use-ssl"));
    conndata->dlr_url = cfg_get(cfg, octstr_imm("dlr-url"));
    conndata->alt_charset = cfg_get(cfg, octstr_imm("alt-charset"));

    if (cfg_get_integer(&max_ps, cfg, octstr_imm("max-pending-submits")) == -1 || max_ps < 1)
        max_ps = 10;
    
    conndata->max_pending_sends = semaphore_create(max_ps);

    if (conndata->port <= 0 && conndata->send_url == NULL) {
        error(0, "Sender and receiver disabled. Dummy SMSC not allowed.");
        goto error;
    }
    if (conndata->send_url == NULL)
        panic(0, "HTTP[%s]: Sending not allowed. No 'send-url' specified.",
              octstr_get_cstr(conn->id));

    if (octstr_case_compare(type, octstr_imm("kannel")) == 0) {
        if (conndata->username == NULL || conndata->password == NULL) {
            error(0, "HTTP[%s]: 'username' and 'password' required for Kannel http smsc",
                  octstr_get_cstr(conn->id));
            goto error;
        }
        conndata->callbacks = &smsc_http_kannel_callback;
    } else if (octstr_case_compare(type, octstr_imm("brunet")) == 0) {
        conndata->callbacks = &smsc_http_brunet_callback;
    } else if (octstr_case_compare(type, octstr_imm("xidris")) == 0) {
        conndata->callbacks = &smsc_http_xidris_callback;
    } else if (octstr_case_compare(type, octstr_imm("generic")) == 0) {
        conndata->callbacks = &smsc_http_generic_callback;
    } else if (octstr_case_compare(type, octstr_imm("clickatell")) == 0) {
        conndata->callbacks = &smsc_http_clickatell_callback;
    } else if (octstr_case_compare(type, octstr_imm("wapme")) == 0) {
        conndata->callbacks = &smsc_http_wapme_callback;
    }
    /*
     * ADD NEW HTTP SMSC TYPES HERE
     */
    else {
        error(0, "HTTP[%s]: system-type '%s' unknown smsc 'http' record.",
              octstr_get_cstr(conn->id), octstr_get_cstr(type));
        goto error;
    }

    if (conndata->callbacks != NULL && conndata->callbacks->init != NULL && conndata->callbacks->init(conn, cfg)) {
        error(0, "HTTP[%s]: submodule '%s' init failed.", octstr_get_cstr(conn->id), octstr_get_cstr(type));
        goto error;
    }

    conndata->open_sends = counter_create();
    conndata->msg_to_send = gwlist_create();
    gwlist_add_producer(conndata->msg_to_send);
    conndata->http_ref = http_caller_create();

    conn->name = octstr_format("HTTP%s:%S:%d", (ssl?"S":""), type, conndata->port);

    if (conndata->send_url != NULL) {
        conn->status = SMSCCONN_ACTIVE;
    } else {
        conn->status = SMSCCONN_ACTIVE_RECV;
    }


    conn->connect_time = time(NULL);

    conn->shutdown = httpsmsc_shutdown;
    conn->queued = httpsmsc_queued;
    conn->send_msg = httpsmsc_send;

    conndata->shutdown = 0;

    /* start receiver thread */
    if (conndata->port > 0) {
        if (http_open_port(conndata->port, ssl) == -1)
            goto error;
        if ((conndata->receive_thread = gwthread_create(httpsmsc_receiver, conn)) == -1)
            goto error;
    } else
        conndata->receive_thread = -1;

    /* start sender threads */
    if (conndata->send_url) {
        if ((conndata->send_cb_thread =
	        gwthread_create(httpsmsc_send_cb, conn)) == -1)
	    goto error;
        if ((conndata->sender_thread =
                gwthread_create(httpsmsc_sender, conn)) == -1)
	    goto error;
    }
    else {
        conndata->send_cb_thread = conndata->sender_thread = -1;
    }

    info(0, "HTTP[%s]: Initiated and ready", octstr_get_cstr(conn->id));

    octstr_destroy(type);
    return 0;

error:
    error(0, "HTTP[%s]: Failed to create HTTP SMSC connection",
          octstr_get_cstr(conn->id));

    if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL)
        conndata->callbacks->destroy(conn);
    conn->data = NULL;
    conndata_destroy(conndata);
    conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT;
    conn->status = SMSCCONN_DEAD;
    octstr_destroy(type);
    return -1;
}
Example #18
0
int main(int argc, char **argv)
{
    output_t outputti = NORMAL_OUT;
    FILE *fp = NULL;
    Octstr *output = NULL;
    Octstr *filename = NULL;
    Octstr *wml_text = NULL;
    Octstr *charset = NULL;
    Octstr *wml_binary = NULL;
    int i, ret = 0, opt, file = 0, zero = 0, numstatus = 0, wml_strict = 1;
    long num = 0;

    /* You can give an wml text file as an argument './wml_tester main.wml' */

    gwlib_init();

    while ((opt = getopt(argc, argv, "hsbzrn:f:c:")) != EOF) {
        switch (opt) {
        case 'h':
            help();
            exit(0);
        case 's':
            if (outputti == NORMAL_OUT)
                outputti = SOURCE_OUT;
            else {
                help();
                exit(0);
            }
            break;
        case 'b':
            if (outputti == NORMAL_OUT)
                outputti = BINARY_OUT;
            else {
                help();
                exit(0);
            }
            break;
        case 'z':
            zero = 1;
            break;
        case 'r':
            wml_strict = 0;
            break;
        case 'n':
            numstatus = octstr_parse_long(&num, octstr_imm(optarg), 0, 0);
            if (numstatus == -1) {
                /* Error in the octstr_parse_long */
                error(num, "Error in the handling of argument to option n");
                help();
                panic(0, "Stopping.");
            }
            break;
        case 'f':
            file = 1;
            filename = octstr_create(optarg);
            fp = fopen(optarg, "a");
            if (fp == NULL)
                panic(0, "Couldn't open output file.");
            break;
        case 'c':
            charset = octstr_create(optarg);
            break;
        case '?':
        default:
            error(0, "Invalid option %c", opt);
            help();
            panic(0, "Stopping.");
        }
    }

    if (optind >= argc) {
        error(0, "Missing arguments.");
        help();
        panic(0, "Stopping.");
    }

    if (outputti == BINARY_OUT)
        log_set_output_level(GW_PANIC);
    wml_init(wml_strict);

    while (optind < argc) {
        wml_text = octstr_read_file(argv[optind]);
        if (wml_text == NULL)
            panic(0, "Couldn't read WML source file.");

        if (zero)
            set_zero(wml_text);

        for (i = 0; i <= num; i++) {
            ret = wml_compile(wml_text, charset, &wml_binary, NULL);
            if (i < num)
                octstr_destroy(wml_binary);
        }
        optind++;

        output = octstr_format("wml_compile returned: %d\n\n", ret);

        if (ret == 0) {
            if (fp == NULL)
                fp = stdout;

            if (outputti != BINARY_OUT) {
                if (outputti == SOURCE_OUT) {
                    octstr_insert(output, wml_text, octstr_len(output));
                    octstr_append_char(output, '\n');
                }

                octstr_append(output, octstr_imm(
                                  "Here's the binary output: \n\n"));
                octstr_print(fp, output);
            }

            if (file && outputti != BINARY_OUT) {
                fclose(fp);
                log_open(octstr_get_cstr(filename), 0, GW_NON_EXCL);
                octstr_dump(wml_binary, 0);
                log_close_all();
                fp = fopen(octstr_get_cstr(filename), "a");
            } else if (outputti != BINARY_OUT)
                octstr_dump(wml_binary, 0);
            else
                octstr_print(fp, wml_binary);

            if (outputti != BINARY_OUT) {
                octstr_destroy(output);
                output = octstr_format("\n And as a text: \n\n");
                octstr_print(fp, output);

                octstr_pretty_print(fp, wml_binary);
                octstr_destroy(output);
                output = octstr_format("\n\n");
                octstr_print(fp, output);
            }
        }

        octstr_destroy(wml_text);
        octstr_destroy(output);
        octstr_destroy(wml_binary);
    }

    if (file) {
        fclose(fp);
        octstr_destroy(filename);
    }

    if (charset != NULL)
        octstr_destroy(charset);

    wml_shutdown();
    gwlib_shutdown();

    return ret;
}
Example #19
0
int main(int argc, char **argv)
{
    Octstr *mime_content,
           *pap_content,
           *push_data,
           *rdf_content,
           *boundary,
           *push_content_file = NULL,
           *this_header,
           *pap_osname,
           *data_osname;
    List *content_headers,
         *source_parts;
    char *pap_content_file,
         *push_data_file,
         *rdf_content_file;
    int ret,
        std_out,
        opt,
        d_file,
        c_file;
    FILE *fp1,
         *fp2,
         *fp3;

    gwlib_init();
    std_out = 0;
    d_file = 0;
    c_file = 0;
    data_osname = NULL;
    pap_osname = NULL;

    while ((opt = getopt(argc, argv, "hd:sc:")) != EOF) {
        switch(opt) {
            case 'h':
                help();
                exit(1);
            break;

            case 'd':
	        d_file = 1;
                data_osname = octstr_create(optarg);
            break;

            case 'c':
	        c_file = 1;
                pap_osname = octstr_create(optarg);
            break;

            case 's':
                std_out = 1;
            break;

            case '?':
            default:
                error(0, "Invalid option %c", opt);
                help();
                panic(0, "Stopping");
            break;
        }
    }    

    if (optind >= argc) {
        help();
        panic(0, "missing arguments, stopping");
    }

    if (!c_file)
        pap_content_file = "test/pap.txt";
    else
        pap_content_file = octstr_get_cstr(pap_osname);
    if (!d_file)
        push_data_file = "test/data.txt";
    else
        push_data_file = octstr_get_cstr(data_osname);
    rdf_content_file = "test/rdf.txt";

    mime_content = octstr_read_file(argv[optind]);
    if (mime_content == NULL) {
        octstr_destroy(mime_content);
        error(0, "No MIME source");
        panic(0, "Stopping");
    }

    source_parts = octstr_split(mime_content, octstr_imm("content="));
    if (gwlist_len(source_parts) == 1) {     /* a hack to circumvent a bug */
        error(0, "Badly formatted source:");
        octstr_destroy(mime_content);
        gwlist_destroy(source_parts, octstr_destroy_item);
        panic(0, "Stopping");
    }

    boundary = gwlist_extract_first(source_parts);
    octstr_delete(boundary, 0, octstr_len(octstr_imm("boundary=")));
    if (skip_tail(&boundary, ';') == 0) {
        error(0, "Cannot determine boundary, no delimiter; possible");
        octstr_dump(boundary, 0);
        goto no_parse;
    }
    
    octstr_destroy(mime_content);
    mime_content = gwlist_extract_first(source_parts);
    if (skip_tail(&mime_content, ';') == 0){
        error(0, "Cannot determine mime content, no delimiter");
        octstr_dump(mime_content, 0);
        goto no_parse;
    }
    prepend_crlf(&mime_content);
    add_crs(mime_content);
    append_crlf(mime_content);
    
    ret = mime_parse(boundary, mime_content, &pap_content, &push_data, 
                     &content_headers, &rdf_content);
    if (ret == 0) {
        error(0, "Mime_parse returned 0, cannot continue");
        goto error;
    }

    remove_crs(pap_content);
    if (!std_out) {
        fp1 = fopen(pap_content_file, "a");
        if (fp1 == NULL) {
            error(0, "Cannot open the file for pap control message");
            goto error;
        }
        octstr_print(fp1, pap_content);
        debug("test.mime", 0, "pap control message appended to the file");
        fclose(fp1);
    } else {
        debug("test.mime", 0, "pap control message was");
        octstr_dump(pap_content, 0);
    }

    remove_crs(push_data);
    if (!std_out) {
        fp2 = fopen(push_data_file, "a");
        if (fp2 == NULL) {
            error(0, "Cannot open the push data file");
            goto error;
        }
        push_content_file = octstr_create("");
        octstr_append(push_content_file, octstr_imm("headers="));
        while (gwlist_len(content_headers) > 0) {
            octstr_append(push_content_file, 
                          this_header = gwlist_extract_first(content_headers));
            octstr_format_append(push_content_file, "%c", ' ');
            octstr_destroy(this_header);
        }
        octstr_append(push_content_file, octstr_imm(";\n"));
        octstr_append(push_content_file, octstr_imm("content="));
        octstr_append(push_content_file, push_data);
        octstr_append(push_content_file, octstr_imm(";\n"));
        octstr_print(fp2, push_content_file);
        debug("test.mime", 0, "push content appended to the file");
        fclose(fp2);
    } else {
        debug("test.mime", 0, "Content headers were");
        http_header_dump(content_headers);
        debug("test.mime", 0, "And push content itself");
        octstr_dump(push_data, 0);
    }

    if (rdf_content != NULL)
        remove_crs(rdf_content);
    if (!std_out && rdf_content != NULL) {
        fp3 = NULL;
        if (rdf_content != NULL) {
            fp3 = fopen(rdf_content_file, "a");
            if (fp3 == NULL) {
                error(0, "Cannot open the rdf file");
                goto cerror;
             }
            octstr_print(fp3, rdf_content);
            debug("test.mime", 0, "push caps message appended to the file");
            fclose(fp3);
        }
    } else {
        if (rdf_content != NULL) {
            debug("test.mime", 0, "push caps message was");
            octstr_dump(rdf_content, 0);
        }
    }
    
    octstr_destroy(boundary);
    octstr_destroy(mime_content);
    octstr_destroy(pap_content);
    octstr_destroy(push_data);
    octstr_destroy(rdf_content);
    octstr_destroy(pap_osname);
    octstr_destroy(data_osname);
    http_destroy_headers(content_headers);
    gwlist_destroy(source_parts, octstr_destroy_item);
    octstr_destroy(push_content_file);
    gwlib_shutdown();

    info(0, "MIME data parsed successfully");
    return 0;

no_parse:
    octstr_destroy(mime_content);
    octstr_destroy(pap_osname);
    octstr_destroy(data_osname);
    gwlist_destroy(source_parts, octstr_destroy_item);
    octstr_destroy(boundary);
    gwlib_shutdown();
    panic(0, "Stopping");

error:
    octstr_destroy(mime_content);
    gwlist_destroy(source_parts, octstr_destroy_item);
    octstr_destroy(boundary);
    octstr_destroy(pap_content);
    octstr_destroy(push_data);
    octstr_destroy(pap_osname);
    octstr_destroy(data_osname);
    http_destroy_headers(content_headers);
    octstr_destroy(rdf_content);
    gwlib_shutdown();
    panic(0, "Stopping");

cerror:
    octstr_destroy(mime_content);
    gwlist_destroy(source_parts, octstr_destroy_item);
    octstr_destroy(boundary);
    octstr_destroy(pap_content);
    octstr_destroy(push_data);
    octstr_destroy(push_content_file);
    octstr_destroy(pap_osname);
    octstr_destroy(data_osname);
    http_destroy_headers(content_headers);
    octstr_destroy(rdf_content);
    gwlib_shutdown();
    panic(0, "Stopping");
/* return after panic always required by gcc */
    return 1;
}
Example #20
0
static int store_spool_save(Msg *msg)
{
    char id[UUID_STR_LEN + 1];
    Octstr *id_s;

    /* always set msg id and timestamp */
    if (msg_type(msg) == sms && uuid_is_null(msg->sms.id))
        uuid_generate(msg->sms.id);

    if (msg_type(msg) == sms && msg->sms.time == MSG_PARAM_UNDEFINED)
        time(&msg->sms.time);

    if (spool == NULL)
        return 0;

    /* blocke here if store still not loaded */
    gwlist_consume(loaded);

    switch(msg_type(msg)) {
        case sms:
        {
            Octstr *os = store_msg_pack(msg);
            Octstr *filename, *dir;
            int fd;
            size_t wrc;

            if (os == NULL) {
                error(0, "Could not pack message.");
                return -1;
            }
            uuid_unparse(msg->sms.id, id);
            id_s = octstr_create(id);
            dir = octstr_format("%S/%ld", spool, octstr_hash_key(id_s) % MAX_DIRS);
            octstr_destroy(id_s);
            if (mkdir(octstr_get_cstr(dir), S_IRUSR|S_IWUSR|S_IXUSR) == -1 && errno != EEXIST) {
                error(errno, "Could not create directory `%s'.", octstr_get_cstr(dir));
                octstr_destroy(dir);
                octstr_destroy(os);
                return -1;
            }
            filename = octstr_format("%S/%s", dir, id);
            octstr_destroy(dir);
            if ((fd = open(octstr_get_cstr(filename), O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR)) == -1) {
                error(errno, "Could not open file `%s'.", octstr_get_cstr(filename));
                octstr_destroy(filename);
                octstr_destroy(os);
                return -1;
            }
            for (wrc = 0; wrc < octstr_len(os); ) {
                size_t rc = write(fd, octstr_get_cstr(os) + wrc, octstr_len(os) - wrc);
                if (rc == -1) {
                    /* remove file */
                    error(errno, "Could not write message to `%s'.", octstr_get_cstr(filename));
                    close(fd);
                    if (unlink(octstr_get_cstr(filename)) == -1)
                        error(errno, "Oops, Could not remove failed file `%s'.", octstr_get_cstr(filename));
                    octstr_destroy(os);
                    octstr_destroy(filename);
                    return -1;
                }
                wrc += rc;
            }
            close(fd);
            counter_increase(counter);
            octstr_destroy(filename);
            octstr_destroy(os);
            break;
        }
        case ack:
        {
            Octstr *filename;
            uuid_unparse(msg->ack.id, id);
            id_s = octstr_create(id);
            filename = octstr_format("%S/%ld/%s", spool, octstr_hash_key(id_s) % MAX_DIRS, id);
            octstr_destroy(id_s);
            if (unlink(octstr_get_cstr(filename)) == -1) {
                error(errno, "Could not unlink file `%s'.", octstr_get_cstr(filename));
                octstr_destroy(filename);
                return -1;
            }
            counter_decrease(counter);
            octstr_destroy(filename);
            break;
        }
        default:
            return -1;
    }

    return 0;
}
Example #21
0
SMSCConn *smscconn_create(CfgGroup *grp, int start_as_stopped)
{
    SMSCConn *conn;
    Octstr *smsc_type;
    int ret;
    Octstr *allowed_smsc_id_regex;
    Octstr *denied_smsc_id_regex;
    Octstr *allowed_prefix_regex;
    Octstr *denied_prefix_regex;
    Octstr *preferred_prefix_regex;
    Octstr *tmp;

    if (grp == NULL)
	return NULL;

    conn = gw_malloc(sizeof(*conn));
    memset(conn, 0, sizeof(*conn));

    conn->why_killed = SMSCCONN_ALIVE;
    conn->status = SMSCCONN_CONNECTING;
    conn->connect_time = -1;
    conn->is_stopped = start_as_stopped;

    conn->received = counter_create();
    conn->received_dlr = counter_create();
    conn->sent = counter_create();
    conn->sent_dlr = counter_create();
    conn->failed = counter_create();
    conn->flow_mutex = mutex_create();

    conn->outgoing_sms_load = load_create();
    /* add 60,300,-1 entries */
    load_add_interval(conn->outgoing_sms_load, 60);
    load_add_interval(conn->outgoing_sms_load, 300);
    load_add_interval(conn->outgoing_sms_load, -1);

    conn->incoming_sms_load = load_create();
    /* add 60,300,-1 entries */
    load_add_interval(conn->incoming_sms_load, 60);
    load_add_interval(conn->incoming_sms_load, 300);
    load_add_interval(conn->incoming_sms_load, -1);

    conn->incoming_dlr_load = load_create();
    /* add 60,300,-1 entries to dlr */
    load_add_interval(conn->incoming_dlr_load, 60);
    load_add_interval(conn->incoming_dlr_load, 300);
    load_add_interval(conn->incoming_dlr_load, -1);

    conn->outgoing_dlr_load = load_create();
    /* add 60,300,-1 entries to dlr */
    load_add_interval(conn->outgoing_dlr_load, 60);
    load_add_interval(conn->outgoing_dlr_load, 300);
    load_add_interval(conn->outgoing_dlr_load, -1);


#define GET_OPTIONAL_VAL(x, n) x = cfg_get(grp, octstr_imm(n))
#define SPLIT_OPTIONAL_VAL(x, n) \
        do { \
                Octstr *tmp = cfg_get(grp, octstr_imm(n)); \
                if (tmp) x = octstr_split(tmp, octstr_imm(";")); \
                else x = NULL; \
                octstr_destroy(tmp); \
        }while(0)

    GET_OPTIONAL_VAL(conn->id, "smsc-id");
    SPLIT_OPTIONAL_VAL(conn->allowed_smsc_id, "allowed-smsc-id");
    SPLIT_OPTIONAL_VAL(conn->denied_smsc_id, "denied-smsc-id");
    SPLIT_OPTIONAL_VAL(conn->preferred_smsc_id, "preferred-smsc-id");
    GET_OPTIONAL_VAL(conn->allowed_prefix, "allowed-prefix");
    GET_OPTIONAL_VAL(conn->denied_prefix, "denied-prefix");
    GET_OPTIONAL_VAL(conn->preferred_prefix, "preferred-prefix");
    GET_OPTIONAL_VAL(conn->unified_prefix, "unified-prefix");
    GET_OPTIONAL_VAL(conn->our_host, "our-host");
    GET_OPTIONAL_VAL(conn->log_file, "log-file");
    cfg_get_bool(&conn->alt_dcs, grp, octstr_imm("alt-dcs"));

    GET_OPTIONAL_VAL(allowed_smsc_id_regex, "allowed-smsc-id-regex");
    if (allowed_smsc_id_regex != NULL) 
        if ((conn->allowed_smsc_id_regex = gw_regex_comp(allowed_smsc_id_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_smsc_id_regex));
    GET_OPTIONAL_VAL(denied_smsc_id_regex, "denied-smsc-id-regex");
    if (denied_smsc_id_regex != NULL) 
        if ((conn->denied_smsc_id_regex = gw_regex_comp(denied_smsc_id_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_smsc_id_regex));
    GET_OPTIONAL_VAL(allowed_prefix_regex, "allowed-prefix-regex");
    if (allowed_prefix_regex != NULL) 
        if ((conn->allowed_prefix_regex = gw_regex_comp(allowed_prefix_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_prefix_regex));
    GET_OPTIONAL_VAL(denied_prefix_regex, "denied-prefix-regex");
    if (denied_prefix_regex != NULL) 
        if ((conn->denied_prefix_regex = gw_regex_comp(denied_prefix_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_prefix_regex));
    GET_OPTIONAL_VAL(preferred_prefix_regex, "preferred-prefix-regex");
    if (preferred_prefix_regex != NULL) 
        if ((conn->preferred_prefix_regex = gw_regex_comp(preferred_prefix_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(preferred_prefix_regex));

    if ((tmp = cfg_get(grp, octstr_imm("throughput"))) != NULL) {
        if (octstr_parse_double(&conn->throughput, tmp, 0) == -1)
            conn->throughput = 0;
        octstr_destroy(tmp);
        info(0, "Set throughput to %.3f for smsc id <%s>", conn->throughput, octstr_get_cstr(conn->id));
    }
    /* Sets the admin_id. Equals to connection id if empty */
    GET_OPTIONAL_VAL(conn->admin_id, "smsc-admin-id");
    if (conn->admin_id == NULL)
        conn->admin_id = octstr_duplicate(conn->id);

    /* configure the internal rerouting rules for this smsc id */
    init_reroute(conn, grp);

    if (cfg_get_integer(&conn->log_level, grp, octstr_imm("log-level")) == -1)
        conn->log_level = 0;

    if (cfg_get_integer(&conn->max_sms_octets, grp, octstr_imm("max-sms-octets")) == -1)
        conn->max_sms_octets = MAX_SMS_OCTETS;

    if (cfg_get_bool(&conn->dead_start, grp, octstr_imm("dead-start")) == -1)
        conn->dead_start = 0;	/* default to connect at start-up time */

    /* open a smsc-id specific log-file in exlusive mode */
    if (conn->log_file)
        conn->log_idx = log_open(octstr_get_cstr(conn->log_file), 
                                 conn->log_level, GW_EXCL); 
#undef GET_OPTIONAL_VAL
#undef SPLIT_OPTIONAL_VAL

    if (conn->allowed_smsc_id && conn->denied_smsc_id)
	warning(0, "Both 'allowed-smsc-id' and 'denied-smsc-id' set, deny-list "
		"automatically ignored");
    if (conn->allowed_smsc_id_regex && conn->denied_smsc_id_regex)
        warning(0, "Both 'allowed-smsc-id_regex' and 'denied-smsc-id_regex' set, deny-regex "
                "automatically ignored");

    if (cfg_get_integer(&conn->reconnect_delay, grp,
                        octstr_imm("reconnect-delay")) == -1)
        conn->reconnect_delay = SMSCCONN_RECONNECT_DELAY;

    smsc_type = cfg_get(grp, octstr_imm("smsc"));
    if (smsc_type == NULL) {
        error(0, "Required field 'smsc' missing for smsc group.");
        smscconn_destroy(conn);
        octstr_destroy(smsc_type);
        return NULL;
    }

    if (octstr_compare(smsc_type, octstr_imm("fake")) == 0)
        ret = smsc_fake_create(conn, grp);
    else if (octstr_compare(smsc_type, octstr_imm("cimd2")) == 0)
	ret = smsc_cimd2_create(conn, grp);
    else if (octstr_compare(smsc_type, octstr_imm("emi")) == 0)
	ret = smsc_emi2_create(conn, grp);
    else if (octstr_compare(smsc_type, octstr_imm("http")) == 0)
        ret = smsc_http_create(conn, grp);
    else if (octstr_compare(smsc_type, octstr_imm("smpp")) == 0)
	ret = smsc_smpp_create(conn, grp);
    else if (octstr_compare(smsc_type, octstr_imm("at")) == 0)
	ret = smsc_at2_create(conn,grp);
    else if (octstr_compare(smsc_type, octstr_imm("cgw")) == 0)
        ret = smsc_cgw_create(conn,grp);
    else if (octstr_compare(smsc_type, octstr_imm("smasi")) == 0)
        ret = smsc_smasi_create(conn, grp);
    else if (octstr_compare(smsc_type, octstr_imm("oisd")) == 0)
        ret = smsc_oisd_create(conn, grp);
    else if (octstr_compare(smsc_type, octstr_imm("loopback")) == 0)
        ret = smsc_loopback_create(conn, grp);
#ifdef HAVE_GSOAP
    else if (octstr_compare(smsc_type, octstr_imm("parlayx")) == 0)
    	ret = smsc_soap_parlayx_create(conn, grp);
#endif
    else
        ret = smsc_wrapper_create(conn, grp);

    octstr_destroy(smsc_type);
    if (ret == -1) {
        smscconn_destroy(conn);
        return NULL;
    }
    gw_assert(conn->send_msg != NULL);

    bb_smscconn_ready(conn);

    return conn;
}
Example #22
0
struct dlr_storage *dlr_init_pgsql(Cfg *cfg)
{
    CfgGroup *grp;
    List *grplist;
    Octstr *pgsql_host, *pgsql_user, *pgsql_pass, *pgsql_db, *pgsql_id;
    long pgsql_port = 0;
    Octstr *p = NULL;
    long pool_size;
    DBConf *db_conf = NULL;

    /*
     * check for all mandatory directives that specify the field names
     * of the table used
     */
    if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db"))))
        panic(0, "DLR: PgSQL: group 'dlr-db' is not specified!");

    if (!(pgsql_id = cfg_get(grp, octstr_imm("id"))))
   	    panic(0, "DLR: PgSQL: directive 'id' is not specified!");

    fields = dlr_db_fields_create(grp);
    gw_assert(fields != NULL);

    /*
     * now grap the required information from the 'pgsql-connection' group
     * with the pgsql-id we just obtained
     *
     * we have to loop through all available PostgreSQL connection definitions
     * and search for the one we are looking for
     */

    grplist = cfg_get_multi_group(cfg, octstr_imm("pgsql-connection"));
    while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
        p = cfg_get(grp, octstr_imm("id"));
        if (p != NULL && octstr_compare(p, pgsql_id) == 0) {
            goto found;
        }
        if (p != NULL) 
            octstr_destroy(p);
    }
    panic(0, "DLR: PgSQL: connection settings for id '%s' are not specified!",
          octstr_get_cstr(pgsql_id));

found:
    octstr_destroy(p);
    gwlist_destroy(grplist, NULL);

    if (cfg_get_integer(&pool_size, grp, octstr_imm("max-connections")) == -1 || pool_size == 0)
        pool_size = 1;

    if (!(pgsql_host = cfg_get(grp, octstr_imm("host"))))
   	    panic(0, "DLR: PgSQL: directive 'host' is not specified!");
    if (!(pgsql_user = cfg_get(grp, octstr_imm("username"))))
   	    panic(0, "DLR: PgSQL: directive 'username' is not specified!");
    if (!(pgsql_pass = cfg_get(grp, octstr_imm("password"))))
   	    panic(0, "DLR: PgSQL: directive 'password' is not specified!");
    if (!(pgsql_db = cfg_get(grp, octstr_imm("database"))))
   	    panic(0, "DLR: PgSQL: directive 'database' is not specified!");
    cfg_get_integer(&pgsql_port, grp, octstr_imm("port"));  /* optional */

    /*
     * ok, ready to connect to the database
     */
    db_conf = gw_malloc(sizeof(DBConf));
    gw_assert(db_conf != NULL);

    db_conf->pgsql = gw_malloc(sizeof(PgSQLConf));
    gw_assert(db_conf->pgsql != NULL);

    db_conf->pgsql->host = pgsql_host;
    db_conf->pgsql->port = pgsql_port;
    db_conf->pgsql->username = pgsql_user;
    db_conf->pgsql->password = pgsql_pass;
    db_conf->pgsql->database = pgsql_db;

    pool = dbpool_create(DBPOOL_PGSQL, db_conf, pool_size);
    gw_assert(pool != NULL);

    /*
     * XXX should a failing connect throw panic?!
     */
    if (dbpool_conn_count(pool) == 0)
        panic(0,"DLR: PgSQL: database pool has no connections!");

    octstr_destroy(pgsql_id);

    return &handles;
}
Example #23
0
static void httpd_serve(HTTPClient *client, Octstr *ourl, List *headers,
    	    	    	Octstr *body, List *cgivars)
{
    Octstr *reply, *final_reply, *url;
    char *content_type;
    char *header, *footer;
    int status_type;
    int i;
    long pos;

    reply = final_reply = NULL; /* for compiler please */
    url = octstr_duplicate(ourl);

    /* Set default reply format according to client
     * Accept: header */
    if (http_type_accepted(headers, "text/vnd.wap.wml")) {
	status_type = BBSTATUS_WML;
	content_type = "text/vnd.wap.wml";
    }
    else if (http_type_accepted(headers, "text/html")) {
	status_type = BBSTATUS_HTML;
	content_type = "text/html";
    }
    else if (http_type_accepted(headers, "text/xml")) {
	status_type = BBSTATUS_XML;
	content_type = "text/xml";
    } else {
	status_type = BBSTATUS_TEXT;
	content_type = "text/plain";
    }

    /* kill '/cgi-bin' prefix */
    pos = octstr_search(url, octstr_imm("/cgi-bin/"), 0);
    if (pos != -1)
        octstr_delete(url, pos, 9);
    else if (octstr_get_char(url, 0) == '/')
        octstr_delete(url, 0, 1);

    /* look for type and kill it */
    pos = octstr_search_char(url, '.', 0);
    if (pos != -1) {
        Octstr *tmp = octstr_copy(url, pos+1, octstr_len(url) - pos - 1);
        octstr_delete(url, pos, octstr_len(url) - pos);

        if (octstr_str_compare(tmp, "txt") == 0)
            status_type = BBSTATUS_TEXT;
        else if (octstr_str_compare(tmp, "html") == 0)
            status_type = BBSTATUS_HTML;
        else if (octstr_str_compare(tmp, "xml") == 0)
            status_type = BBSTATUS_XML;
        else if (octstr_str_compare(tmp, "wml") == 0)
            status_type = BBSTATUS_WML;

        octstr_destroy(tmp);
    }

    for (i=0; httpd_commands[i].command != NULL; i++) {
        if (octstr_str_compare(url, httpd_commands[i].command) == 0) {
            reply = httpd_commands[i].function(cgivars, status_type);
            break;
        }
    }

    /* check if command found */
    if (httpd_commands[i].command == NULL) {
        char *lb = bb_status_linebreak(status_type);
	reply = octstr_format("Unknown command `%S'.%sPossible commands are:%s",
            ourl, lb, lb);
        for (i=0; httpd_commands[i].command != NULL; i++)
            octstr_format_append(reply, "%s%s", httpd_commands[i].command, lb);
    }

    gw_assert(reply != NULL);

    if (status_type == BBSTATUS_HTML) {
	header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n"
 	    "<html>\n<title>" GW_NAME "</title>\n<body>\n<p>";
	footer = "</p>\n</body></html>\n";
	content_type = "text/html";
    } else if (status_type == BBSTATUS_WML) {
	header = "<?xml version=\"1.0\"?>\n"
            "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" "
            "\"http://www.wapforum.org/DTD/wml_1.1.xml\">\n"
            "\n<wml>\n <card>\n  <p>";
	footer = "  </p>\n </card>\n</wml>\n";
	content_type = "text/vnd.wap.wml";
    } else if (status_type == BBSTATUS_XML) {
	header = "<?xml version=\"1.0\"?>\n"
            "<gateway>\n";
        footer = "</gateway>\n";
    } else {
	header = "";
	footer = "";
	content_type = "text/plain";
    }
    final_reply = octstr_create(header);
    octstr_append(final_reply, reply);
    octstr_append_cstr(final_reply, footer);
    
    /* debug("bb.http", 0, "Result: '%s'", octstr_get_cstr(final_reply));
     */
    http_destroy_headers(headers);
    headers = list_create();
    http_header_add(headers, "Content-Type", content_type);

    http_send_reply(client, HTTP_OK, headers, final_reply);

    octstr_destroy(url);
    octstr_destroy(ourl);
    octstr_destroy(body);
    octstr_destroy(reply);
    octstr_destroy(final_reply);
    http_destroy_headers(headers);
    http_destroy_cgiargs(cgivars);
}
Example #24
0
int main(int argc, char **argv)
{
    struct sigaction act;
    int port;
    int opt;
    double run_time;
    char *log_file;
    char *config_file;

    gwlib_init();

    act.sa_handler = handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGTERM, &act, NULL);
    sigaction(SIGINT, &act, NULL);

    port = 2345;
    smsc_system_id = octstr_create("kannel_smpp");
    smsc_source_addr = octstr_create("123456");
    message_id_counter = counter_create();
    bearerbox_host = octstr_create("127.0.0.1");
    port_for_smsbox = 13001;
    max_to_esme = 1;
    num_to_esme = counter_create();
    num_from_esme = counter_create();
    num_to_bearerbox = counter_create();
    num_from_bearerbox = counter_create();
    log_file = config_file = NULL;

    while ((opt = getopt(argc, argv, "hv:p:m:l:c:")) != EOF) {
	switch (opt) {
	case 'v':
	    log_set_output_level(atoi(optarg));
	    break;

	case 'h':
	    help();
	    exit(0);

	case 'm':
	    max_to_esme = atoi(optarg);
	    break;

	case 'p':
	    port = atoi(optarg);
	    break;

	case 'l':
        log_file = optarg;
        break;
    
    case 'c':
        config_file = optarg;
        break;

	case '?':
	default:
	    error(0, "Invalid option %c", opt);
	    help();
	    panic(0, "Stopping.");
	}
    }

    if (log_file != NULL)
    	log_open(log_file, GW_DEBUG, GW_NON_EXCL);

    if (config_file != NULL) {
        Cfg *cfg;
        Octstr *tmp = octstr_create(config_file);
        
        cfg = cfg_create(tmp);
        octstr_destroy(tmp);
        if (cfg_read(cfg) == -1)
            panic(0, "Errors in config file.");
        smpp_pdu_init(cfg);
        cfg_destroy(cfg);
    }
            
    info(0, "Starting drive_smpp test.");
    gwthread_create(accept_thread, &port);
    gwthread_join_all();
    debug("test.smpp", 0, "Program exiting normally.");

    run_time = difftime(last_from_esme, first_to_esme);

    info(0, "Number of messages sent to ESME: %ld",
    	 counter_value(num_to_esme));
    info(0, "Number of messages sent to smsbox: %ld",
    	 counter_value(num_from_bearerbox));
    info(0, "Number of messages sent to bearerbox: %ld",
    	 counter_value(num_to_bearerbox));
    info(0, "Number of messages sent to SMSC: %ld",
    	 counter_value(num_from_esme));
    info(0, "Time: %.0f secs", run_time);
    info(0, "Time until all sent to ESME: %.0f secs", 
    	 difftime(last_to_esme, start_time));
    info(0, "Time from first from bb to last to bb: %.0f secs", 
    	 difftime(last_to_bb, first_from_bb));
    info(0, "Time until all sent to SMSC: %.0f secs", 
    	 difftime(last_from_esme, start_time));
    info(0, "SMPP messages SMSC to ESME: %.1f msgs/sec",
    	 counter_value(num_to_esme) / run_time);
    info(0, "SMPP messages ESME to SMSC: %.1f msgs/sec",
    	 counter_value(num_from_esme) / run_time);

    octstr_destroy(smsc_system_id);
    octstr_destroy(smsc_source_addr);
    octstr_destroy(bearerbox_host);
    counter_destroy(num_to_esme);
    counter_destroy(num_from_esme);
    counter_destroy(num_to_bearerbox);
    counter_destroy(num_from_bearerbox);
    counter_destroy(message_id_counter);

    gwlib_shutdown();
    return 0;
}
Example #25
0
int main(int argc, char **argv)
{
    int opt;
    unsigned long sended = 0;
    Octstr *cf, *rf;

    gwlib_init();

    bb_host = octstr_create("localhost");
    bb_port = 13001;
    bb_ssl = 0;
        
    while ((opt = getopt(argc, argv, "hv:b:p:si:n:a:f:D:u:d:r:")) != EOF) {
        switch (opt) {
            case 'v':
                log_set_output_level(atoi(optarg));
                break;
            case 'b':
                octstr_destroy(bb_host);
                bb_host = octstr_create(optarg);
                break;
            case 'p':
                bb_port = atoi(optarg);
                break;
            case 's':
                bb_ssl = 1;
                break;
            case 'i':
                smsbox_id = octstr_create(optarg);
                break;
            case 'n':
                service = octstr_create(optarg);
                break;
            case 'a':
                account = octstr_create(optarg);
                break;
            case 'f':
                from = octstr_create(optarg);
                break;
            case 'D':
                dlr_mask = atoi(optarg);
                break;
            case 'u':
                dlr_url = octstr_create(optarg);
                break;
            case 'd':
                delay = atof(optarg);
                break;
            case 'r':
                smsc_id = octstr_create(optarg);
                break;
            case '?':
            default:
                error(0, "Invalid option %c", opt);
                help();
                panic(0, "Stopping.");
        }
    }
    
    if (optind == argc || argc-optind < 2) {
        help();
        exit(1);
    }

    /* check some mandatory elements */
    if (from == NULL)
        panic(0,"Sender address not specified. Use option -f to specify sender address.");

    if ((DLR_IS_ENABLED(dlr_mask) && dlr_url == NULL) || (!DLR_IS_ENABLED(dlr_mask) && dlr_url != NULL))
        panic(0,"dlr-url address OR dlr-mask not specified. Use option -D or -u to specify dlr values");

    rf = octstr_create(argv[argc-1]);
    cf = octstr_create(argv[argc-2]);

    report_versions("mtbatch");
    write_pid_file();
 
    init_batch(cf, rf);

    connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL /* bb_our_host */);
    identify_to_bearerbox();
    gwthread_create(read_messages_from_bearerbox, NULL);

    sended = run_batch();

    /* avoid exiting before sending all msgs */
    while(sended > counter_value(counter)) {
         gwthread_sleep(0.1);
    }

    program_status = shutting_down;
    gwthread_join_all();

    octstr_destroy(bb_host);
    octstr_destroy(smsbox_id);
    octstr_destroy(content);
    octstr_destroy(service);
    octstr_destroy(account);
    octstr_destroy(dlr_url);
    octstr_destroy(smsc_id);
    counter_destroy(counter);
    gwlist_destroy(lines, octstr_destroy_item); 
   
    gwlib_shutdown();

    return 0;
}
Example #26
0
/*
 * Thread to listen to HTTP requests from SMSC entity
 */
static void httpsmsc_receiver(void *arg)
{
    SMSCConn *conn = arg;
    ConnData *conndata = conn->data;
    HTTPClient *client;
    Octstr *ip, *url, *body;
    List *headers, *cgivars;

    /* Make sure we log into our own log-file if defined */
    log_thread_to(conn->log_idx);

    while (conndata->shutdown == 0) {
        /* reset */
        ip = url = body = NULL;
        headers = cgivars = NULL;

        /* XXX if conn->is_stopped, do not receive new messages.. */

        client = http_accept_request(conndata->port, &ip, &url,
                                     &headers, &body, &cgivars);
        if (client == NULL)
            break;

        if (cgivars != NULL) {
        	octstr_append_char(url, '?');
        	http_cgivar_dump_into(cgivars, url);
        }

        debug("smsc.http", 0, "HTTP[%s]: Got request `%s'",
              octstr_get_cstr(conn->id), octstr_get_cstr(url));

        if (connect_denied(conndata->allow_ip, ip)) {
            info(0, "HTTP[%s]: Connection `%s' tried from denied "
                    "host %s, ignored", octstr_get_cstr(conn->id),
                    octstr_get_cstr(url), octstr_get_cstr(ip));
            http_close_client(client);
        } else
            conndata->callbacks->receive_sms(conn, client, headers, body, cgivars);

        debug("smsc.http", 0, "HTTP[%s]: Destroying client information",
              octstr_get_cstr(conn->id));
        octstr_destroy(url);
        octstr_destroy(ip);
        octstr_destroy(body);
        http_destroy_headers(headers);
        http_destroy_cgiargs(cgivars);
    }
    debug("smsc.http", 0, "HTTP[%s]: httpsmsc_receiver dying",
          octstr_get_cstr(conn->id));

    conndata->shutdown = 1;
    http_close_port(conndata->port);

    /* unblock http_receive_result() if there are no open sends */
    if (counter_value(conndata->open_sends) == 0)
        http_caller_signal_shutdown(conndata->http_ref);

    if (conndata->sender_thread != -1) {
        gwthread_wakeup(conndata->sender_thread);
        gwthread_join(conndata->sender_thread);
    }
    if (conndata->send_cb_thread != -1) {
        gwthread_wakeup(conndata->send_cb_thread);
        gwthread_join(conndata->send_cb_thread);
    }

    mutex_lock(conn->flow_mutex);
    conn->status = SMSCCONN_DEAD;
    mutex_unlock(conn->flow_mutex);

    if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL)
        conndata->callbacks->destroy(conn);
    conn->data = NULL;
    conndata_destroy(conndata);
    bb_smscconn_killed();
}
Example #27
0
void bb_alog_shutdown(void)
{
    octstr_destroy(custom_log_format);
    custom_log_format = NULL;
}
Example #28
0
/*
 * Thread to handle finished sendings
 */
static void httpsmsc_send_cb(void *arg)
{
    SMSCConn *conn = arg;
    ConnData *conndata = conn->data;
    Msg *msg;
    int status;
    List *headers;
    Octstr *final_url, *body;

    /* Make sure we log into our own log-file if defined */
    log_thread_to(conn->log_idx);

    while(conndata->shutdown == 0 || counter_value(conndata->open_sends)) {

        msg = http_receive_result(conndata->http_ref, &status,
                                  &final_url, &headers, &body);

        if (msg == NULL)
            break;  /* they told us to die, by unlocking */

        counter_decrease(conndata->open_sends);
        if (conndata->max_pending_sends)
            semaphore_up(conndata->max_pending_sends);

        /* Handle various states here. */

        /* request failed and we are not in shutdown mode */
        if (status == -1 && conndata->shutdown == 0) {
            error(0, "HTTP[%s]: Couldn't connect to SMS center."
                     "(retrying in %ld seconds) %ld.",
                     octstr_get_cstr(conn->id), conn->reconnect_delay, counter_value(conndata->open_sends));
            mutex_lock(conn->flow_mutex);
            conn->status = SMSCCONN_RECONNECTING;
            mutex_unlock(conn->flow_mutex);
            /* XXX how should we know whether it's temp. error ?? */
            bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL);
            /*
             * Just sleep reconnect delay and set conn to ACTIVE again;
             * otherwise if no pending request are here, we leave conn in
             * RECONNECTING state for ever and no routing (trials) take place.
             */
            if (counter_value(conndata->open_sends) == 0) {
                gwthread_sleep(conn->reconnect_delay);
                /* and now enable routing again */
                mutex_lock(conn->flow_mutex);
                conn->status = SMSCCONN_ACTIVE;
                time(&conn->connect_time);
                mutex_unlock(conn->flow_mutex);
                /* tell bearerbox core that we are connected again */
                bb_smscconn_connected(conn);
            }
            continue;
        }
        /* request failed and we *are* in shutdown mode, drop the message */
        else if (status == -1 && conndata->shutdown == 1) {
            bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);
        }
        /* request succeeded */
        else {
            /* we received a response, so this link is considered online again */
            if (conn->status != SMSCCONN_ACTIVE) {
                mutex_lock(conn->flow_mutex);
                conn->status = SMSCCONN_ACTIVE;
                time(&conn->connect_time);
                mutex_unlock(conn->flow_mutex);
                /* tell bearerbox core that we are connected again */
                bb_smscconn_connected(conn);
            }
            conndata->callbacks->parse_reply(conn, msg, status, headers, body);
        }

        http_destroy_headers(headers);
        octstr_destroy(final_url);
        octstr_destroy(body);
    }
    debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying",
          octstr_get_cstr(conn->id));
    conndata->shutdown = 1;

    if (counter_value(conndata->open_sends)) {
        warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.",
                octstr_get_cstr(conn->id), counter_value(conndata->open_sends));
    }
}
Example #29
0
Octstr *smpp_pdu_pack(SMPP_PDU *pdu)
{
    Octstr *os;
    Octstr *temp;

    os = octstr_create("");

    gw_assert(pdu != NULL);

    /*
     * Fix lengths of octet string fields.
     */
    switch (pdu->type) {
    #define OPTIONAL_BEGIN
    #define TLV_INTEGER(name, octets)
    #define TLV_NULTERMINATED(name, max_len)
    #define TLV_OCTETS(name, min_len, max_len)
    #define OPTIONAL_END
    #define INTEGER(name, octets) p = *(&p);
    #define NULTERMINATED(name, max_octets) p = *(&p);
    #define OCTETS(name, field_giving_octets) \
    	p->field_giving_octets = octstr_len(p->name);
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smpp_pdu.def"
    default:
    	error(0, "Unknown SMPP_PDU type, internal error while packing.");
    }

    switch (pdu->type) {
    #define TL(name, octets) \
        append_encoded_integer(os, SMPP_##name, 2); \
        append_encoded_integer(os, octets, 2);
    #define OPTIONAL_BEGIN
    #define TLV_INTEGER(name, octets) \
        if (p->name != -1) { \
            TL(name, octets); \
            INTEGER(name, octets) \
        }
    #define TLV_NULTERMINATED(name, max_len) \
        if (p->name != NULL) { \
            TL(name, (octstr_len(p->name) > max_len ? max_len : octstr_len(p->name))); \
            NULTERMINATED(name, max_len) \
        }
    #define TLV_OCTETS(name, min_len, max_len) \
        if (p->name != NULL) { \
            unsigned long len = octstr_len(p->name); \
            if (len > max_len || len < min_len) { \
                error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \
                    #name, len, min_len, max_len);\
            } else { \
                TL(name, len); \
                octstr_append(os, p->name); \
            } \
        }
    #define OPTIONAL_END
    #define INTEGER(name, octets) \
    	append_encoded_integer(os, p->name, octets);
    #define NULTERMINATED(name, max_octets) \
        if (p->name != NULL) { \
            if (octstr_len(p->name) >= max_octets) { \
                warning(0, "SMPP: PDU element <%s> too long " \
                        "(length is %ld, should be %d)", \
                        #name, octstr_len(p->name), max_octets-1); \
                temp = octstr_copy(p->name, 0, max_octets-1); \
            } else \
                temp = octstr_duplicate(p->name); \
            octstr_append(os, temp); \
            octstr_destroy(temp); \
        } \
        octstr_append_char(os, '\0');
    #define OCTETS(name, field_giving_octets) \
        if (p->name) octstr_append(os, p->name);
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smpp_pdu.def"
    default:
    	error(0, "Unknown SMPP_PDU type, internal error while packing.");
    }

    temp = octstr_create("");
    append_encoded_integer(temp, octstr_len(os) + 4, 4);
    octstr_insert(os, temp, 0);
    octstr_destroy(temp);

    return os;
}
Example #30
0
static int kannel_send_sms(SMSCConn *conn, Msg *sms)
{
    ConnData *conndata = conn->data;
    Octstr *url;
    List *headers;

    if (!conndata->no_sep) {
        url = octstr_format("%S?"
			    "username=%E&password=%E&to=%E&text=%E",
			     conndata->send_url,
			     conndata->username, conndata->password,
			     sms->sms.receiver, sms->sms.msgdata);
    } else {
        Octstr *msgdata = octstr_duplicate(sms->sms.msgdata);
        
        octstr_binary_to_hex(msgdata, HEX_NOT_UPPERCASE);
        url = octstr_format("%S?"
			    "username=%E&password=%E&to=%E&text=%S",
			     conndata->send_url,
			     conndata->username, conndata->password,
			     sms->sms.receiver, msgdata);
        octstr_destroy(msgdata);
    }   

    if (octstr_len(sms->sms.udhdata)) {
        if (!conndata->no_sep) {
            octstr_format_append(url, "&udh=%E", sms->sms.udhdata);
        } else {
            Octstr *udhdata = octstr_duplicate(sms->sms.udhdata);
            
            octstr_binary_to_hex(udhdata, HEX_NOT_UPPERCASE);
            octstr_format_append(url, "&udh=%S", udhdata);
            octstr_destroy(udhdata);
        }
    }

    if (!conndata->no_sender)
        octstr_format_append(url, "&from=%E", sms->sms.sender);
    if (sms->sms.mclass != MC_UNDEF)
        octstr_format_append(url, "&mclass=%d", sms->sms.mclass);
    if (!conndata->no_coding && sms->sms.coding != DC_UNDEF)
        octstr_format_append(url, "&coding=%d", sms->sms.coding);

    /* Obey that smsbox's sendsms HTTP interface is still expecting 
     * WINDOWS-1252 as default charset, while all other internal parts
     * use UTF-8 as internal encoding. This means, when we pass a SMS
     * into a next Kannel instance, we need to let the smsbox know which
     * charset we have in use.
     * XXX TODO: change smsbox interface to use UTF-8 as default
     * in next major release. */
    if (sms->sms.coding == DC_7BIT)
        octstr_append_cstr(url, "&charset=UTF-8");
    else if (sms->sms.coding == DC_UCS2)
        octstr_append_cstr(url, "&charset=UTF-16BE");

    if (sms->sms.mwi != MWI_UNDEF)
        octstr_format_append(url, "&mwi=%d", sms->sms.mwi);
    if (sms->sms.account) /* prepend account with local username */
        octstr_format_append(url, "&account=%E:%E", sms->sms.service, sms->sms.account);
    if (sms->sms.binfo) /* prepend billing info */
        octstr_format_append(url, "&binfo=%S", sms->sms.binfo);
    if (sms->sms.smsc_id) /* proxy the smsc-id to the next instance */
        octstr_format_append(url, "&smsc=%S", sms->sms.smsc_id);
	if (conndata->dlr_url) {
		char id[UUID_STR_LEN + 1];
		Octstr *mid;

		/* create Octstr from UUID */
		uuid_unparse(sms->sms.id, id);
		mid = octstr_create(id);

		octstr_format_append(url, "&dlr-url=%E", conndata->dlr_url);

		/* encapsulate the original DLR-URL, escape code for DLR mask
		 * and message id */
		octstr_format_append(url, "%E%E%E%E%E",
			octstr_imm("&dlr-url="), sms->sms.dlr_url != NULL ? sms->sms.dlr_url : octstr_imm(""),
			octstr_imm("&dlr-mask=%d"),
			octstr_imm("&dlr-mid="), mid);

		octstr_destroy(mid);
	} else if (sms->sms.dlr_url != NULL)
		octstr_format_append(url, "&dlr-url=%E", sms->sms.dlr_url);
    if (sms->sms.dlr_mask != DLR_UNDEFINED && sms->sms.dlr_mask != DLR_NOTHING)
        octstr_format_append(url, "&dlr-mask=%d", sms->sms.dlr_mask);

    if (sms->sms.validity != SMS_PARAM_UNDEFINED)
    	octstr_format_append(url, "&validity=%ld", (sms->sms.validity - time(NULL)) / 60);
    if (sms->sms.deferred != SMS_PARAM_UNDEFINED)
    	octstr_format_append(url, "&deferred=%ld", (sms->sms.deferred - time(NULL)) / 60);

    headers = gwlist_create();
    debug("smsc.http.kannel", 0, "HTTP[%s]: Start request",
          octstr_get_cstr(conn->id));
    http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers, 
                       NULL, 0, sms, NULL);

    octstr_destroy(url);
    http_destroy_headers(headers);

    return 0;
}