Esempio n. 1
0
static Octstr *copy_until_assign(Octstr *os, long *pos) 
{
    long nul;
    Octstr *data;

    nul = octstr_search_char(os, '=', *pos);
    if (nul == -1 && (octstr_len(os) - *pos) > 1) {
        warning(0, "SMASI: Garbage at end of parameter list: %s", octstr_get_cstr(os));
        *pos = octstr_len(os);
        return NULL;
    }
    data = octstr_copy(os, *pos, nul - *pos);
    *pos = nul + 1;
    return data;
}
Esempio n. 2
0
Octstr *parse_get_octets(ParseContext *context, long length)
{
    Octstr *result;

    gw_assert(context != NULL);

    if (context->pos + length > context->limit) {
        context->error = 1;
        return NULL;
    }

    result = octstr_copy(context->data, context->pos, length);
    context->pos += length;
    return result;
}
Esempio n. 3
0
Octstr *parse_get_nul_string(ParseContext *context)
{
    Octstr *result;
    long pos;

    gw_assert(context != NULL);

    pos = octstr_search_char(context->data, 0, context->pos);
    if (pos < 0 || pos >= context->limit) {
        context->error = 1;
        return NULL;
    }

    result = octstr_copy(context->data, context->pos, pos - context->pos);
    context->pos = pos + 1;

    return result;
}
Esempio n. 4
0
static Octstr *decode_type(Octstr *os)
{
    long p1, p2;
    Octstr *temp;

    if ((p2 = octstr_search_char(os, ':', 0)) == -1)
        return NULL;

    if ((p1 = octstr_search_char(os, '!', 0)) != -1 && p1 < p2) {
        p1++;
    } else {
        p1 = 0;
    }

    temp = octstr_copy(os, p1, p2 - p1);

    return temp;
}
Esempio n. 5
0
static Octstr *copy_until_nul(Octstr *os, long *pos, long max_octets)
{
    long nul;
    Octstr *data;

    nul = octstr_search_char(os, '\0', *pos);
    if (nul == -1) {
	warning(0, "SMPP: PDU NULL terminated string has no NULL.");
    	return NULL;
    }
    if (*pos + max_octets < nul) {
	error(0, "SMPP: PDU NULL terminated string longer than allowed.");
    	return NULL;
    }
    data = (nul - *pos > 0) ? octstr_copy(os, *pos, nul - *pos) : NULL;
    *pos = nul + 1;
    return data;
}
Esempio n. 6
0
static int copy_until_nul(const char *field_name, Octstr *os, long *pos, long max_octets, Octstr **data)
{
    long nul;

    *data = NULL;

    nul = octstr_search_char(os, '\0', *pos);
    if (nul == -1) {
        warning(0, "SMPP: PDU NULL terminated string (%s) has no NULL.", field_name);
        return -1;
    }
    if (*pos + max_octets < nul) {
        error(0, "SMPP: PDU NULL terminated string (%s) longer than allowed.", field_name);
        return -1;
    }
    *data = (nul - *pos > 0) ? octstr_copy(os, *pos, nul - *pos) : NULL;
    *pos = nul + 1;
    return 0;
}
Esempio n. 7
0
/*
 * Find the first packet in "in", delete it from "in", and return it as
 * a struct.  Return NULL if "in" contains no packet.  Always delete
 * leading non-packet data from "in".
 */
static struct packet *packet_extract(Octstr *in, SMSCConn *conn)
{
    Octstr *packet;
    int size, i;
    static char s[4][4] = {
        { 0x01, 0x0b, 0x00, 0x00 },
        { 0x01, 0x00, 0x00, 0x00 },
        { 0x00, 0x04, 0x00, 0x00 },
        { 0x00, 0x09, 0x00, 0x00 }
    }; /* msgtype, oper, 0, 0 */
    char known_bytes[4];

    if (octstr_len(in) < 10)
        return NULL;
    octstr_get_many_chars(known_bytes, in, 4, 4);
    /* Find s, and delete everything up to it. */
    /* If packet starts with one of s, it should be good packet */
    for (i = 0; i < 4; i++) {
        if (memcmp(s[i], known_bytes, 4) == 0)
            break;
    }

    if (i >= 4) {
        error(0, "OISD[%s]: wrong packet",
              octstr_get_cstr(conn->id));
        octstr_dump(in, 0);
        return NULL;
    }

    /* Find end of packet */
    size = (octstr_get_char(in, 9) << 8) | octstr_get_char(in, 8);

    if (size + 10 > octstr_len(in))
        return NULL;

    packet = octstr_copy(in, 0, size + 10);
    octstr_delete(in, 0, size + 10);

    return packet_parse(packet);
}
Esempio n. 8
0
static void split_headers(Octstr *headers, List **split)
{
    long start;
    long pos;

    *split = gwlist_create();
    start = 0;
    for (pos = 0; pos < octstr_len(headers); pos++) {
        if (octstr_get_char(headers, pos) == '\n') {
            Octstr *line;

            if (pos == start) {
                /* Skip empty lines */
                start = pos + 1;
                continue;
            }
            line = octstr_copy(headers, start, pos - start);
            start = pos + 1;
            gwlist_append(*split, line);
        }
    }
}
Esempio n. 9
0
static long pass_field_name(Octstr **body_part, Octstr **field_part, 
                            long pos)
{
    int c;
    long start;
    Octstr *name = NULL;

    start = pos;
    while (((c = octstr_get_char(*body_part, pos)) != ':') &&
            pos < octstr_len(*body_part)) {
        ++pos;
    }

    if (pos == octstr_len(*body_part)) {
        return -1;
    }

    name = octstr_copy(*body_part, start, pos - start);
    octstr_append(*field_part, name);

    octstr_destroy(name);
    return pos;
}
Esempio n. 10
0
static long pass_field_value(Octstr **body_part, Octstr **header, 
                             long pos)
{
    int c;
    long start;
    Octstr *field = NULL;

    start = pos;
    while (!is_cr(c = octstr_get_char(*body_part, pos)) &&
             pos < octstr_len(*body_part)) {
        ++pos;
    }
 
    if (pos == octstr_len(*body_part)) {
        return -1;
    }

    field = octstr_copy(*body_part, start, pos - start);
    octstr_append(*header, field);

    octstr_destroy(field);
    return pos;
}
Esempio n. 11
0
static Octstr *get_header_value(Octstr *header) 
{
	Octstr *h = NULL;
	long colon = -1;
	
	if (header == NULL) {
		error(0, "get_header_value: NULL argument");
		return NULL;
	}

	octstr_strip_blanks(header);
	colon = octstr_search_char(header, ':', 0);
	if (colon == -1) {
		error(0, "get_header_value: Malformed header (%s)", octstr_get_cstr (header));
		return NULL;
	} else {
		h = octstr_copy(header, colon + 1, octstr_len(header));
		octstr_strip_blanks(h);
	}

	debug("wap.wsp.http", 0, "get_header_value: Value (%s)", octstr_get_cstr (h));
	return h;
}
Esempio n. 12
0
static Octstr *read_line(FILE *f, Octstr *buf)
{
    Octstr *os;
    char cbuf[8*1024];
    size_t n;
    long pos;
    
    pos = octstr_search_char(buf, '\n', 0);
    while (pos == -1 && (n = fread(cbuf, 1, sizeof(cbuf), f)) > 0) {
	octstr_append_data(buf, cbuf, n);
	pos = octstr_search_char(buf, '\n', 0);
    }

    if (pos == -1) {
    	pos = octstr_len(buf);
	if (pos == 0)
	    return NULL;
    }
    os = octstr_copy(buf, 0, pos);
    octstr_delete(buf, 0, pos + 1);

    return os;
}
Esempio n. 13
0
static Octstr *eat_string_parm(Octstr *packet, int parm, int maxlen) {
	long start, datastart;
	long tab;
	Octstr *result;
	Octstr *parmheader;

    	parmheader = octstr_format("%c%03d:", TAB, parm);
	start = octstr_search(packet, parmheader, 0);
	if (start < 0) {
		octstr_destroy(parmheader);
		return NULL;
	}
	datastart = start + octstr_len(parmheader);

	tab = octstr_search_char(packet, TAB, datastart + 1);
	if (tab < 0) {
		tab = octstr_len(packet);
	}

	result = octstr_copy(packet, datastart, tab - datastart);
	octstr_delete(packet, start, tab - start);
	octstr_destroy(parmheader);
	return result;
}
Esempio n. 14
0
/*
 * Trans being NULL means that we are servicing ppg (doing dlr, but this does not
 * concern us here).
 */
Octstr *urltrans_get_pattern(URLTranslation *t, Msg *request)
{
    Octstr *enc;
    int nextarg, j;
    struct tm tm;
    int num_words;
    List *word_list;
    Octstr *result, *pattern;
    long pattern_len;
    long pos;
    int c;
    long i;
    Octstr *temp;
    Octstr *url, *reply; /* For and If delivery report */

    url = reply = NULL;
    
    if (request->sms.sms_type != report_mo && t->type == TRANSTYPE_SENDSMS)
        return octstr_create("");

    if (request->sms.msgdata) {
        word_list = octstr_split_words(request->sms.msgdata);
        num_words = list_len(word_list);
    } else {
    	word_list = list_create();
        num_words = 0;
    }

    result = octstr_create("");

    /* check if this is a delivery report message or not */
    if (request->sms.sms_type != report_mo) {
        pattern = t->pattern;
    } else {

        /* this is a DLR message */
        reply = octstr_duplicate(request->sms.msgdata);
        url = octstr_duplicate(request->sms.dlr_url);

        pattern = url;
        if (octstr_len(pattern) == 0) {
            if (t && octstr_len(t->dlr_url)) {
                pattern = t->dlr_url;
            } else {
                list_destroy(word_list, octstr_destroy_item);
                return octstr_create("");
            }
        }
    }

    pattern_len = octstr_len(pattern);
    nextarg = 1;
    pos = 0;
    for (;;) {
        while (pos < pattern_len) {
            c = octstr_get_char(pattern, pos);
            if (c == '%' && pos + 1 < pattern_len)
                break;
            octstr_append_char(result, c);
            ++pos;
        }

        if (pos == pattern_len)
            break;

    switch (octstr_get_char(pattern, pos + 1)) {
	case 'k':
	    if (num_words <= 0)
		break;
	    enc = octstr_duplicate(list_get(word_list, 0));
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 's':
	    if (nextarg >= num_words)
		break;
	    enc = octstr_duplicate(list_get(word_list, nextarg));
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    ++nextarg;
	    break;

	case 'S':
	    if (nextarg >= num_words)
		break;
	    temp = list_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) {
		enc = octstr_duplicate(list_get(word_list, j));
		octstr_url_encode(enc);
		if (j != nextarg)
		    octstr_append_char(result, '+');
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;
    
	/* NOTE: the sender and receiver is already switched in
	 *    message, so that's why we must use 'sender' when
	 *    we want original receiver and vice versa
	 */
	case 'P':
	    enc = octstr_duplicate(request->sms.sender);
    	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'p':
	    enc = octstr_duplicate(request->sms.receiver);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'Q':
	    if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {
		enc = octstr_copy(request->sms.sender, 2, 
		    	    	  octstr_len(request->sms.sender));
		octstr_url_encode(enc);
		octstr_format_append(result, "%%2B%S", enc);
		octstr_destroy(enc);
	    } else {
		enc = octstr_duplicate(request->sms.sender);
    	    	octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

	case 'q':
	    if (strncmp(octstr_get_cstr(request->sms.receiver),"00",2)==0) {
		enc = octstr_copy(request->sms.receiver, 2, 
		    	    	  octstr_len(request->sms.receiver));
		octstr_url_encode(enc);
		octstr_format_append(result, "%%2B%S", enc);
		octstr_destroy(enc);
	    } else {
		enc = octstr_duplicate(request->sms.receiver);
		octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

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

	case 'b':
	    enc = octstr_duplicate(request->sms.msgdata);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 't':
	    tm = gw_gmtime(request->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 (request->sms.time == MSG_PARAM_UNDEFINED)
		break;
	    octstr_format_append(result, "%ld", request->sms.time);
	    break;

	case 'i':
	    if (request->sms.smsc_id == NULL)
		break;
	    enc = octstr_duplicate(request->sms.smsc_id);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

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

	case 'n':
	    if (request->sms.service == NULL)
		break;
	    enc = octstr_duplicate(request->sms.service);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'd':
	    enc = octstr_create("");
	    octstr_append_decimal(enc, request->sms.dlr_mask);
	    octstr_url_encode(enc);
	    octstr_append(result, enc);
	    octstr_destroy(enc);
	    break;

	case 'A':
	    if (reply) {
		enc = octstr_duplicate(reply);
		octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

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

	case 'C':
	    if(octstr_len(request->sms.charset)) {
		octstr_append(result, request->sms.charset);
	    } else {
		switch (request->sms.coding) {
		    case DC_UNDEF:
		    case DC_7BIT:
			octstr_append(result, octstr_imm("ISO-8859-1"));
			break;
		    case DC_8BIT:
			octstr_append(result, octstr_imm("8-BIT"));
			break;
		    case DC_UCS2:
			octstr_append(result, octstr_imm("UTF16-BE"));
			break;
		}
	    }
	    break;

	case 'u':
	    if(octstr_len(request->sms.udhdata)) {
		enc = octstr_duplicate(request->sms.udhdata);
		octstr_url_encode(enc);
		octstr_append(result, enc);
		octstr_destroy(enc);
	    }
	    break;

	case 'B':  /* billing identifier/information */
	    if (octstr_len(request->sms.binfo)) {
            enc = octstr_duplicate(request->sms.binfo);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;
	
    case 'o':  /* account information (may be operator id for aggregators */
	    if (octstr_len(request->sms.account)) {
            enc = octstr_duplicate(request->sms.account);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

	/* XXX sms.parameters not present in here:
	 *   * pid - will we receive this ? 
	 *   * mwi,mclass - will we receive these bits from smsc ?
	 *   * alt-dcs - shouldn't be required unless we want to inform 
	 *               which alt-dcs external server should use back
	 *   * compress - if we use compression, probably kannel would 
	 *                decompress and reset this to 0. not required
	 *   * validity, deferred, rpi - we don't receive these from smsc
	 *   * username, password, dlr-url, account - nonsense to send
	 */

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

	default:
	    octstr_format_append(result, "%%%c",
	    	    	    	 octstr_get_char(pattern, pos + 1));
	    break;
	}

	pos += 2;
    }
    /*
     * this SHOULD be done in smsbox, not here, but well,
     * much easier to do here
     */
    if (t && (t->type == TRANSTYPE_POST_URL || t->type == TRANSTYPE_POST_XML)
		    && t->strip_keyword)
	strip_keyword(request);

    octstr_destroy(url);
    octstr_destroy(reply);

    list_destroy(word_list, octstr_destroy_item);
    return result;
}
Esempio n. 15
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);
}
Esempio n. 16
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;
}
Esempio n. 17
0
Octstr *urltrans_fill_escape_codes(Octstr *pattern, Msg *request)
{
    Octstr *enc;
    Octstr *meta_group, *meta_param;
    int nextarg, j;
    struct tm tm;
    int num_words;
    List *word_list;
    Octstr *result;
    long pattern_len;
    long pos;
    int c;
    long i, k;
    Octstr *temp;

    result = octstr_create("");

    if (request->sms.msgdata) {
        word_list = octstr_split_words(request->sms.msgdata);
        num_words = gwlist_len(word_list);
    } else {
        word_list = gwlist_create();
        num_words = 0;
    }
    
    pattern_len = octstr_len(pattern);
    nextarg = 1;
    pos = 0;
    for (;;) {
        while (pos < pattern_len) {
            c = octstr_get_char(pattern, pos);
            if (c == '%' && pos + 1 < pattern_len)
                break;
            octstr_append_char(result, c);
            ++pos;
        }

        if (pos == pattern_len)
            break;

    switch (octstr_get_char(pattern, pos + 1)) {
    case 'a':
        for (j = 0; j < num_words; ++j) {
        enc = octstr_duplicate(gwlist_get(word_list, j));
        octstr_url_encode(enc);
        if (j > 0)
            octstr_append_char(result, '+');
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'A':
        if (request->sms.msgdata) {
        enc = octstr_duplicate(request->sms.msgdata);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'b':
        enc = octstr_duplicate(request->sms.msgdata);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'B':  /* billing identifier/information */
        if (octstr_len(request->sms.binfo)) {
            enc = octstr_duplicate(request->sms.binfo);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

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

    case 'C':
        if (octstr_len(request->sms.charset)) {
            octstr_append(result, request->sms.charset);
        } else {
            switch (request->sms.coding) {
            case DC_UNDEF:
            case DC_7BIT:
                octstr_append(result, octstr_imm("UTF-8"));
                break;
            case DC_8BIT:
                octstr_append(result, octstr_imm("8-BIT"));
                break;
            case DC_UCS2:
                octstr_append(result, octstr_imm("UTF-16BE"));
                break;
            }
        }
        break;

    case 'd':
        enc = octstr_create("");
        octstr_append_decimal(enc, request->sms.dlr_mask);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'D': /* meta_data */
        if (octstr_len(request->sms.meta_data)) {
            enc = octstr_duplicate(request->sms.meta_data);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 'f':  /* smsc number*/
        if (octstr_len(request->sms.smsc_number)) {
            enc = octstr_duplicate(request->sms.smsc_number);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 'F':
        if (request->sms.foreign_id == NULL)
            break;
        enc = octstr_duplicate(request->sms.foreign_id);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'i':
        if (request->sms.smsc_id == NULL)
        break;
        enc = octstr_duplicate(request->sms.smsc_id);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

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

    case 'k':
        if (num_words <= 0)
        break;
        enc = octstr_duplicate(gwlist_get(word_list, 0));
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'm':  /* mclass - message class */
        enc = octstr_create("");
        octstr_append_decimal(enc, request->sms.mclass);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'M':  /* mwi - message waiting indicator */
        enc = octstr_create("");
        octstr_append_decimal(enc, request->sms.mwi);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'n':
        if (request->sms.service == NULL)
        break;
        enc = octstr_duplicate(request->sms.service);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'o':  /* account information (may be operator id for aggregators */
        if (octstr_len(request->sms.account)) {
            enc = octstr_duplicate(request->sms.account);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 'O':  /* DCS */
    {
        int dcs;
        dcs = fields_to_dcs(request, request->sms.alt_dcs);
        octstr_format_append(result, "%02d", dcs);
        break;
    }

    /* NOTE: the sender and receiver is already switched in
     *    message, so that's why we must use 'sender' when
     *    we want original receiver and vice versa
     */
    case 'P':
        enc = octstr_duplicate(request->sms.sender);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'p':
        enc = octstr_duplicate(request->sms.receiver);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        break;

    case 'q':
        if (strncmp(octstr_get_cstr(request->sms.receiver),"00",2)==0) {
        enc = octstr_copy(request->sms.receiver, 2, 
                          octstr_len(request->sms.receiver));
        octstr_url_encode(enc);
        octstr_format_append(result, "%%2B%S", enc);
        octstr_destroy(enc);
        } else {
        enc = octstr_duplicate(request->sms.receiver);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'Q':
        if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {
        enc = octstr_copy(request->sms.sender, 2, 
                          octstr_len(request->sms.sender));
        octstr_url_encode(enc);
        octstr_format_append(result, "%%2B%S", enc);
        octstr_destroy(enc);
        } else {
        enc = octstr_duplicate(request->sms.sender);
                octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'r':
        for (j = nextarg; j < num_words; ++j) {
        enc = octstr_duplicate(gwlist_get(word_list, j));
        octstr_url_encode(enc);
        if (j != nextarg)
            octstr_append_char(result, '+');
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'R': /* dlr_url */
        if (octstr_len(request->sms.dlr_url)) {
            enc = octstr_duplicate(request->sms.dlr_url);
            octstr_url_encode(enc);
            octstr_append(result, enc);
            octstr_destroy(enc);
        }
        break;

    case 's':
        if (nextarg >= num_words)
        	break;
        enc = octstr_duplicate(gwlist_get(word_list, nextarg));
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        ++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 't':
        tm = gw_gmtime(request->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 (request->sms.time == MSG_PARAM_UNDEFINED)
        break;
        octstr_format_append(result, "%ld", request->sms.time);
        break;

    case 'u':
        if(octstr_len(request->sms.udhdata)) {
        enc = octstr_duplicate(request->sms.udhdata);
        octstr_url_encode(enc);
        octstr_append(result, enc);
        octstr_destroy(enc);
        }
        break;

    case 'v':
        if (request->sms.validity != MSG_PARAM_UNDEFINED) {
            octstr_format_append(result, "%ld", (request->sms.validity - time(NULL)) / 60);
        }
        break;

    case 'V':
        if (request->sms.deferred != MSG_PARAM_UNDEFINED) {
            octstr_format_append(result, "%ld", (request->sms.deferred - time(NULL)) / 60);
        }
        break;
    
    /*
     * This allows to pass meta-data individual parameters into urls.
     * The syntax is as follows: %#group#parameter#
     * For example: %#smpp#my_param# would be replaced with the value
     * 'my_param' from the group 'smpp' coming inside the meta_data field.
     */
    case '#':
        /* ASCII 0x23 == '#' */
        k = octstr_search_char(pattern, 0x23, pos + 2);
        if (k >= 0) {
            pos += 2;
            meta_group = octstr_copy(pattern, pos, (k-pos));
            pos = k + 1;
            k = octstr_search_char(pattern, 0x23, pos);
            if (k >= 0) {
                meta_param = octstr_copy(pattern, pos, (k-pos));
                pos = k - 1;
                if (request->sms.meta_data != NULL) {
                    enc = meta_data_get_value(request->sms.meta_data,
                            octstr_get_cstr(meta_group), meta_param);
                    octstr_url_encode(enc);
                    octstr_append(result, enc);
                    octstr_destroy(enc);
                }
                octstr_destroy(meta_param);
            } else {
                pos++;
            }
            octstr_destroy(meta_group);
        }
        break;

    /* XXX sms.parameters not present in here:
     *   * pid - will we receive this ? 
     *   * alt-dcs - shouldn't be required unless we want to inform 
     *               which alt-dcs external server should use back
     *   * compress - if we use compression, probably kannel would 
     *                decompress and reset this to 0. not required
     *   * rpi - we don't receive these from smsc
     *   * username, password, dlr-url, account - nonsense to send
     */
    case '%':
        octstr_format_append(result, "%%");
        break;

    default:
        octstr_format_append(result, "%%%c",
                             octstr_get_char(pattern, pos + 1));
        break;
    }

    pos += 2;
    }
    
    gwlist_destroy(word_list, octstr_destroy_item);    

    return result;    
}
Esempio n. 18
0
/*
 * Split os2 from os1, boundary being boundary_pos.
 */
static void octstr_split_by_pos(Octstr **os1, Octstr **os2, 
                                long boundary_pos)
{
    *os2 = octstr_copy(*os1, 0, boundary_pos);
    octstr_delete(*os1, 0, boundary_pos);
}
Esempio n. 19
0
mCfg *mms_cfg_read(Octstr *file)
{
     Octstr *sf;
     List *lines;
     int i, n;
     mCfg *cfg;
     mCfgGrp *grp = NULL;
     int skip = 0;
     
     gw_assert(file);

     if ((sf = octstr_read_file(octstr_get_cstr(file))) == NULL) {
	  mms_error(errno, "mms_cfg", NULL, "failed to read config from `%s'", octstr_get_cstr(file));
	  return NULL;
     }

     cfg = gw_malloc(sizeof *cfg);
     cfg->file = octstr_duplicate(file);
     cfg->grps = dict_create(7, NULL);

     cfg->xcfg = NULL;
     cfg->cfg_funcs = NULL;
     
     lines = octstr_split(sf, octstr_imm("\n"));    
     for (i = 0, n = gwlist_len(lines); i < n; i++) {
	  Octstr *current = gwlist_get(lines,i);
	  int pos;
	  
	  octstr_strip_blanks(current);
	  
	  if (octstr_len(current) == 0) { /* end of group. */
	       grp = NULL;
	       skip = 0;
	       continue;
	  } else if (skip || octstr_get_char(current, 0) == '#') 
	       continue; 
	  	  
	  if ((pos = octstr_search_char(current, '=',0)) > 0) {
	       /* a field name. first see if start of grp */
	       Octstr *field = octstr_copy(current,0,pos);
	       Octstr *value = octstr_copy(current,pos+1,octstr_len(current));
	       
	       octstr_strip_blanks(field);
	       fixup_value(value, i+1);
#if 0
	       mms_info(0, "mms_cfg", NULL, "field/value: [%s - %s]", octstr_get_cstr(field), 
		    octstr_get_cstr(value));
#endif

	       if (octstr_str_case_compare(field, "group") == 0) 
		    if (grp == NULL) { /* grp name. */		    
			 int ismulti = is_multigroup(value);
			 
			 if (ismulti < 0) {
			      mms_info(0, "mms_cfg", NULL, "Skipping unknown group `%s' at line %d of conf file", 
				   octstr_get_cstr(value), i+1);
			      skip = 1;
			 } else {
			      grp = gw_malloc(sizeof *grp);
			      grp->name = octstr_duplicate(value);
			      grp->fields = dict_create(23, (void (*)(void *))octstr_destroy);
			      
			      if (ismulti) {
				   List *l = dict_get(cfg->grps, value);
				   
				   if (l == NULL) { 
					l = gwlist_create();
					dict_put(cfg->grps, value, l);			      
				   }
				   gwlist_append(l, grp);			 
			      } else if (dict_put_once(cfg->grps, value, grp) == 0)
				   panic(0, "Group `%s' [at line %d] cannot appear more "
					 "than once in config!",
					 octstr_get_cstr(value), i+1);
			 }
		    } else
			 panic(0,"`group' is an illegal field name "
			       "within a group at line %d in config file!",
			       i+1);
	       else  if (grp) /* an ordinary field name. */
		    check_and_add_field(grp, field, value,i+1);
	       else 
		    panic(0, "A group must begin with a `group = group_name' "
			  "clause [at line %d in config file]", i+1);			      	       
	       
	       octstr_destroy(field);
	       octstr_destroy(value);
	  } else
	       panic(0, "mal-formed entry in conf file at line %d!", i+1);
     }

     gwlist_destroy(lines, (gwlist_item_destructor_t *)octstr_destroy);
     octstr_destroy(sf);

     /* Now check if config-source is set, use that. */
     if ((grp = mms_cfg_get_single(cfg, octstr_imm("config-source"))) != NULL) {
	  Octstr *init = mms_cfg_get(cfg, grp, octstr_imm("config-library-init-param"));
	  cfg->cfg_funcs = _mms_load_module(cfg, grp, "config-library", "cfg_funcs", NULL);
	  
	  if (cfg->cfg_funcs == NULL ||
	      cfg->cfg_funcs->read == NULL ||
	      (cfg->xcfg = cfg->cfg_funcs->read(init)) == NULL) {
	       mms_error(0, "mms_cfg", NULL, "Failed to load cfg reader library from conf!");
	       mms_cfg_destroy(cfg);
	       cfg = NULL;
	  }
	  
	  octstr_destroy(init);	  
     }
     
     return cfg;
}
Esempio n. 20
0
int cfg_read(Cfg *cfg) 
{ 
    CfgLoc *loc; 
    CfgLoc *loc_inc; 
    List *lines;
    List *expand; 
    List *stack; 
    Octstr *name;
    Octstr *value;
    Octstr *filename; 
    CfgGroup *grp;
    long equals;
    long lineno;
    long error_lineno;
    
    loc = loc_inc = NULL;

    /* 
     * expand initial main config file and add it to the recursion 
     * stack to protect against cycling 
     */ 
    if ((lines = expand_file(cfg->filename, 1)) == NULL) { 
        panic(0, "Failed to load main configuration file `%s'. Aborting!", 
              octstr_get_cstr(cfg->filename)); 
    } 
    stack = gwlist_create(); 
    gwlist_insert(stack, 0, octstr_duplicate(cfg->filename)); 

    grp = NULL;
    lineno = 0;
    error_lineno = 0;
    while (error_lineno == 0 && (loc = gwlist_extract_first(lines)) != NULL) { 
        octstr_strip_blanks(loc->line); 
        if (octstr_len(loc->line) == 0) { 
            if (grp != NULL && add_group(cfg, grp) == -1) { 
                error_lineno = loc->line_no; 
                destroy_group(grp); 
            } 
            grp = NULL; 
        } else if (octstr_get_char(loc->line, 0) != '#') { 
            equals = octstr_search_char(loc->line, '=', 0); 
            if (equals == -1) { 
                error(0, "An equals sign ('=') is missing on line %ld of file %s.", 
                      loc->line_no, octstr_get_cstr(loc->filename)); 
                error_lineno = loc->line_no; 
            } else  
             
            /* 
             * check for special config directives, like include or conditional 
             * directives here 
             */ 
            if (octstr_search(loc->line, octstr_imm("include"), 0) != -1) { 
                filename = octstr_copy(loc->line, equals + 1, octstr_len(loc->line)); 
                parse_value(filename); 
 
                /* check if we are cycling */ 
                if (gwlist_search(stack, filename, octstr_item_match) != NULL) { 
                    panic(0, "Recursive include for config file `%s' detected " 
                             "(on line %ld of file %s).", 
                          octstr_get_cstr(filename), loc->line_no,  
                          octstr_get_cstr(loc->filename)); 
                } else {     
                    List *files = gwlist_create();
                    Octstr *file;
                    struct stat filestat;

                    /* check if included file is a directory */
                    if (lstat(octstr_get_cstr(filename), &filestat) != 0) {
                        error(errno, "lstat failed: couldn't stat `%s'", 
                              octstr_get_cstr(filename));
                        panic(0, "Failed to include `%s' "
                              "(on line %ld of file %s). Aborting!",  
                              octstr_get_cstr(filename), loc->line_no,  
                              octstr_get_cstr(loc->filename)); 
                    }
                    
                    /* 
                     * is a directory, create a list with files of
                     * this directory and load all as part of the
                     * whole configuration.
                     */
                    if (S_ISDIR(filestat.st_mode)) {
                        DIR *dh;
                        struct dirent *diritem;

                        debug("gwlib.cfg", 0, "Loading include dir `%s' "
                              "(on line %ld of file %s).",  
                              octstr_get_cstr(filename), loc->line_no,  
                              octstr_get_cstr(loc->filename)); 

                        dh = opendir(octstr_get_cstr(filename));
                        while ((diritem = readdir(dh))) {
                            Octstr *fileitem;

                            fileitem = octstr_duplicate(filename);
                            octstr_append_cstr(fileitem, "/");
                            octstr_append_cstr(fileitem, diritem->d_name);

                            lstat(octstr_get_cstr(fileitem), &filestat);
                            if (!S_ISDIR(filestat.st_mode)) {
                                gwlist_insert(files, 0, fileitem);
                            } else {
                            	octstr_destroy(fileitem);
                            }
                        }
                        closedir(dh);
                    } 
		    
                    /* is a file, create a list with it */
                    else {
                        gwlist_insert(files, 0, octstr_duplicate(filename));
                    }

                    /* include files */
                    while ((file = gwlist_extract_first(files)) != NULL) {

                        gwlist_insert(stack, 0, octstr_duplicate(file)); 
                        debug("gwlib.cfg", 0, "Loading include file `%s' (on line %ld of file %s).",  
                              octstr_get_cstr(file), loc->line_no,  
                              octstr_get_cstr(loc->filename)); 

                        /*  
                         * expand the given include file and add it to the current 
                         * processed main while loop 
                         */ 
                        if ((expand = expand_file(file, 0)) != NULL) {
                            while ((loc_inc = gwlist_extract_first(expand)) != NULL) 
                                gwlist_insert(lines, 0, loc_inc); 
                        } else { 
                            panic(0, "Failed to load whole configuration. Aborting!"); 
                        } 
                 
                        gwlist_destroy(expand, NULL); 
                        cfgloc_destroy(loc_inc);
                        octstr_destroy(file);
                    }
                    gwlist_destroy(files, octstr_destroy_item);
                } 
                octstr_destroy(filename); 
            }  
             
            /* 
             * this is a "normal" line, so process it accodingly 
             */ 
            else  { 
                name = octstr_copy(loc->line, 0, equals); 
                octstr_strip_blanks(name); 
                value = octstr_copy(loc->line, equals + 1, octstr_len(loc->line)); 
                parse_value(value); 
 
    	    	if (grp == NULL)
                    grp = create_group(); 
                 
                if (grp->configfile != NULL) {
                    octstr_destroy(grp->configfile); 
                    grp->configfile = NULL;
                }
                grp->configfile = octstr_duplicate(cfg->filename); 

                cfg_set(grp, name, value); 
                octstr_destroy(name); 
                octstr_destroy(value); 
            } 
        } 

        cfgloc_destroy(loc); 
    }

    if (grp != NULL && add_group(cfg, grp) == -1) {
        error_lineno = 1; 
        destroy_group(grp); 
    }

    gwlist_destroy(lines, NULL); 
    gwlist_destroy(stack, octstr_destroy_item); 

    if (error_lineno != 0) {
        error(0, "Error found on line %ld of file `%s'.",  
	          error_lineno, octstr_get_cstr(cfg->filename)); 
        return -1; 
    }

    return 0;
}
Esempio n. 21
0
static int sendNotify(MmsEnvelope *e)
{
     Octstr *to;
     MmsMsg *msg, *smsg = NULL;
     MmsEnvelopeTo *xto = gwlist_get(e->to, 0);
     Octstr *err = NULL;
     time_t tnow = time(NULL);
     int j, k, len;
     Octstr *phonenum = NULL, *rcpt_ip = NULL, *msgId, *from, *fromproxy;
     int mtype, msize;
     int res = MMS_SEND_OK, dlr;
     time_t expiryt;
     char *prov_notify_event = NULL;
     char *rtype = NULL;

          
     if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */	  
	  e->sendt = e->expiryt + 3600*24*30*12;
	  info(0, "MM1: Message [ID: %s] fetched/touched at least once. Skipping",
	       e->xqfname);
	  return settings->qfs->mms_queue_update(e);
     }

     if (!xto) {
	  error(0, "mobilesender: Queue entry %s with no recipients!", 
		e->xqfname);
	  return 0;
     }

     msg = settings->qfs->mms_queue_getdata(e);
     to = octstr_duplicate(xto->rcpt);
     expiryt = e->expiryt;
     msgId = e->msgId ? octstr_duplicate(e->msgId) : NULL;
     from = octstr_duplicate(e->from);
     fromproxy = e->fromproxy ? octstr_duplicate(e->fromproxy) : NULL;
     msize = e->msize;
     dlr = e->dlr;

     if (e->expiryt != 0 &&  /* Handle message expiry. */
	 e->expiryt < tnow) {
	  err = octstr_format("MMSC error: Message expired while sending to %S!", to);
	  res = MMS_SEND_ERROR_FATAL;
	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     } else if (e->attempts >= settings->maxsendattempts) {
	  err = octstr_format("MMSC error: Failed to deliver to %S after %ld attempts!", 
			      to, e->attempts);
	  res = MMS_SEND_ERROR_FATAL;

	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     }
     
     j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0);
     k = octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0);
     len = octstr_len(to);
     
     if (j > 0 && j - 1 +  sizeof "/TYPE=PLMN" == len) { /* A proper number. */
	  phonenum = octstr_copy(to, 0, j);
#if 0
	  normalize_number(octstr_get_cstr(settings->unified_prefix), &phonenum);
#else
	  mms_normalize_phonenum(&phonenum, 
				 octstr_get_cstr(settings->unified_prefix), 
				 settings->strip_prefixes);	  
#endif
     }     else if (k > 0 && k + sizeof "/TYPE=IPv" == len) 
	  rcpt_ip = octstr_copy(to, 0, k);
     else {
	  /* We only handle phone numbers here. */
	  err = octstr_format("Unexpected recipient %s in MT queue!", octstr_get_cstr(to));	  
	  res = MMS_SEND_ERROR_FATAL;	  
	  goto done;
     }
     
     mtype = mms_messagetype(msg);     
     
     /* For phone, getting here means the message can be delivered. So: 
      * - Check whether the recipient is provisioned, if not, wait (script called will queue creation req)
      * - If the recipient can't take MMS, then send SMS.
      */
     
     /* We handle two types of requests: send and delivery/read notifications. 
      * other types of messages cannot possibly be in this queue!
      */
     
     if (mtype == MMS_MSGTYPE_SEND_REQ ||
	 mtype == MMS_MSGTYPE_RETRIEVE_CONF) {
	  Octstr *url, *transid;
	  
	  if (phonenum) {
	       int send_ind = mms_ind_send(settings->prov_getstatus, phonenum);
	       
	       if (send_ind < 0 && 
		   settings->notify_unprovisioned)
		    send_ind = 0;

	       if (send_ind < 0) { /* That is, recipient is not (yet) provisioned. */
		    res = MMS_SEND_ERROR_TRANSIENT;
		    err = octstr_format("%S is not provisioned for MMS reception, delivery deferred!", 
					phonenum);
		    
		    /* Do not increase delivery attempts counter. */
		    e->lasttry = tnow;		    
		    e->sendt = e->lasttry + settings->send_back_off * (1 + e->attempts);
		    
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; /* Queue entry gone. */	
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    		    
		    goto done;
	       } else if (send_ind == 0) { /*  provisioned but does not support */		    
		    Octstr *s = octstr_format(octstr_get_cstr(settings->mms_notify_txt),
					      from);
		    if (settings->notify_unprovisioned && s && octstr_len(s) > 0) { /* Only send if the string was set. */
			 List *pheaders;					    
			 Octstr *sto = octstr_duplicate(phonenum);
			 
			 octstr_url_encode(s);
			 octstr_url_encode(sto);
			 
			 url = octstr_format("%S&text=%S&to=%S",settings->sendsms_url,s, sto);
			 pheaders = http_create_empty_headers();
			 http_header_add(pheaders, "Connection", "close");
			 http_header_add(pheaders, "User-Agent", MM_NAME "/" VERSION);      
			 
			 http_start_request(httpcaller, HTTP_METHOD_GET, url, 
					    pheaders, NULL, 0, &edummy, NULL);			 			 
			 http_destroy_headers(pheaders);
			 octstr_destroy(url);
			 octstr_destroy(sto);		   		 
		    } else if (s)
			 octstr_destroy(s);	
		    res = MMS_SEND_OK;
		    err = octstr_imm("No MMS Ind support, sent SMS instead");
		    
		    xto->process = 0; /* No more processing. */
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; 
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    
		    goto done;

	       }	       
	  }
	  
	  /* To get here means we can send Ind. */
	  url = mms_makefetchurl(e->xqfname, e->token, MMS_LOC_MQUEUE,
				 phonenum ? phonenum : to,
				 settings);
	  info(0, "Preparing to notify client to fetch message at URL: %s",
	       octstr_get_cstr(url));
	  transid = mms_maketransid(e->xqfname, settings->host_alias);	  
	  
	  smsg = mms_notification(msg, e->msize, url, transid, 
				  e->expiryt ? e->expiryt :
				  tnow + settings->default_msgexpiry,
				  settings->optimize_notification_size);
	  octstr_destroy(transid);
	  octstr_destroy(url);
     } else if (mtype == MMS_MSGTYPE_DELIVERY_IND ||
		mtype == MMS_MSGTYPE_READ_ORIG_IND) 
	  smsg = msg;
     else {
	  error(0, "Unexpected message type %s for %s found in MT queue!", 
		mms_message_type_to_cstr(mtype), octstr_get_cstr(to));
	  res = MMS_SEND_ERROR_FATAL;
	  goto done;
     }
     
     if (smsg)
	  start_push(phonenum ? phonenum : rcpt_ip, 
		     phonenum ? 1 : 0, 
		     e, smsg); /* Send the message. 
				* Don't touch 'e' after this point!
				* It may be freed by receive thread. 
				*/
     
     if (smsg != msg && smsg)
	  mms_destroy(smsg);
    
 done:
     if (err != NULL && 
	 res != MMS_SEND_ERROR_TRANSIENT) { /* If there was a report request and this is a legit error
					     *  queue it. 
					     */
	  
	  if (dlr) {	       
	       MmsMsg *m = mms_deliveryreport(msgId, to, tnow, 
					      rtype ? octstr_imm(rtype) : 
					      octstr_imm("Indeterminate"));
	       
	       List *l = gwlist_create();
	       Octstr *res;
	       gwlist_append(l, from);
	       
	       /* Add to queue, switch via proxy to be from proxy. */
	       res = settings->qfs->mms_queue_add(to ? to : settings->system_user, l,  err, 
						  NULL, fromproxy,  
						  tnow, tnow+settings->default_msgexpiry, m, NULL, 
						  NULL, NULL,
						  NULL, NULL,
						  NULL,
						  0,
						  octstr_get_cstr(settings->mm1_queuedir), 
						  "MM2",
						  settings->host_alias);
	       gwlist_destroy(l, NULL);
	       mms_destroy(m);
	       octstr_destroy(res);
	  }
	  
     }
     
     /* Write to log */
     info(0, "%s Mobile Queue MMS Send Notify: From=%s, to=%s, msgsize=%d, reason=%s", 
	  SEND_ERROR_STR(res),
	  octstr_get_cstr(from), octstr_get_cstr(to), msize,
	  err ? octstr_get_cstr(err) : "");
     
     
     if (res == MMS_SEND_ERROR_FATAL) {
	  xto->process = 0;  /* No more attempts to deliver, delete this. */	       
	  if (settings->qfs->mms_queue_update(e) == 1) 
	       e = NULL; /* Queue entry gone. */	
	  else 	  
	       settings->qfs->mms_queue_free_env(e);
     }    /* Else queue will be updated/freed elsewhere. */
     
     
     if (prov_notify_event)
	  notify_prov_server(octstr_get_cstr(settings->prov_notify), 
			     to ? octstr_get_cstr(to) : "unknown", 
			     prov_notify_event, 
			     rtype ? rtype : "",
			     e ? e->msgId : NULL, NULL, NULL);

     if (msg) mms_destroy(msg);       

     octstr_destroy(phonenum);
     
     octstr_destroy(rcpt_ip);
     octstr_destroy(to);
     octstr_destroy(msgId);
     octstr_destroy(fromproxy);
     octstr_destroy(from);
     octstr_destroy(err);

     return 1;
}
Esempio n. 22
0
static int sendMsg(MmsEnvelope *e)
{
     MmsMsg *msg = NULL;
     int i, n;     
     Octstr *otransid = e->hdrs ? http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL;

     if ((msg = qfs->mms_queue_getdata(e)) == NULL)  {
	  mms_error(0,  "MM7", NULL, "MMSBox queue error: Failed to load message for queue id [%s]!", e->xqfname);
	  goto done2;
     }
     
     for (i = 0, n = gwlist_len(e->to); i<n; i++) {
	  int res = MMS_SEND_OK;
	  MmsEnvelopeTo *to = gwlist_get(e->to, i);
	  Octstr *err = NULL;
	  time_t tnow = time(NULL);
	  MmscGrp *mmc = NULL;
	  Octstr *new_msgid = NULL;
	  List *errl = NULL;
	  int is_email = 0;

	  if (!to || !to->process)
	       continue;
	  
	  if (e->expiryt != 0 &&  /* Handle message expiry. */
	      e->expiryt < tnow) {
               err = octstr_format("MMSC error: Message expired while sending to %S!", to->rcpt);
               res = MMS_SEND_ERROR_FATAL;
	       
               goto done;
          } else if (e->attempts >= maxsendattempts) {
               err = octstr_format("MMSBox error: Failed to deliver to "
				   "%S after %ld attempts. (max attempts allowed is %ld)!", 
                                   to->rcpt, e->attempts, 
                                   maxsendattempts);
               res = MMS_SEND_ERROR_FATAL;
               goto done;
          }

	  is_email = (octstr_search_char(to->rcpt, '@', 0) > 0);
	  
	  if ((mmc = get_handler_mmc(e->viaproxy, to->rcpt, e->from)) == NULL && !is_email) {
               err = octstr_format("MMSBox error: Failed to deliver to "
				   "%S. Don't know how to route!", 
                                   to->rcpt);
               res = MMS_SEND_ERROR_TRANSIENT;
	       goto done;
	  }
	  
	  if (is_email) {
               int j = octstr_case_search(e->from, octstr_imm("/TYPE=PLMN"), 0);
               int k = octstr_case_search(e->from, octstr_imm("/TYPE=IPv"), 0);
               int len = octstr_len(e->from);
               Octstr *pfrom;
	       
               
               if (j > 0 && j - 1 +  sizeof "/TYPE=PLMN" == len) 
                    pfrom = octstr_copy(e->from, 0, j);
               else if (k > 0 && k + sizeof "/TYPE=IPv" == len) 
                    pfrom = octstr_copy(e->from, 0, k);
               else
                    pfrom = octstr_duplicate(e->from);

               if (octstr_search_char(e->from, '@', 0) < 0)
                    octstr_format_append(pfrom,"@%S", myhostname);
	       
	       res = mms_sendtoemail(pfrom, to->rcpt, 
				     e->subject ? e->subject : octstr_imm(""),
				     e->msgId, msg, 0, &err, octstr_get_cstr(sendmail_cmd),
				     myhostname, 0, 0, 
				     "", 
				     "", 0, 
				     e->xqfname, 
				     e->hdrs);
	       octstr_destroy(pfrom);
	  } else {
	       res = mms_sendtommsc(mmc, e, 
				    to->rcpt, 
				    otransid,
				    msg, 
				    &new_msgid,
				    &errl);
	       if (errl)
		    err = http_header_value(errl, octstr_imm("X-Mbuni-Error"));
	  }
	  if (mmc) {
	       if (res == MMS_SEND_OK)
		    mmc->mt_pdus++;
	       else
		    mmc->mt_errors++;	  
	       mmc->last_pdu = time(NULL);
	       return_mmsc_conn(mmc); /* important. */
	  }
     done:
	  if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
	       to->process = 0;
	       
	       if (e->msgtype == MMS_MSGTYPE_SEND_REQ ||
		   e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */
		    queue_dlr(mmc, e->from, to->rcpt, new_msgid, octstr_imm("Forwarded"), "MM7-Out", errl);
	  } else if (res == MMS_SEND_ERROR_FATAL && mmc) {
	       if (e->msgtype == MMS_MSGTYPE_SEND_REQ ||
		   e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */		    
		    queue_dlr(mmc, e->from, to->rcpt, e->msgId, 			
			      (e->expiryt != 0 && e->expiryt < tnow) ? 
			 octstr_imm("Expired") : octstr_imm("Rejected"), 
			      "MM7-Out", errl);
	  }
	  if (res == MMS_SEND_ERROR_FATAL)
	       to->process = 0; /* No more attempts. */        


	  /* handle CDR */
	  if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED || res == MMS_SEND_ERROR_FATAL) {
	       Octstr *mclass = mms_get_header_value(msg, octstr_imm("X-Mms-Message-Class"));
	       Octstr *prio = mms_get_header_value(msg, octstr_imm("X-Mms-Priority"));
	       Octstr *mstatus  = mms_get_header_value(msg, octstr_imm("X-Mms-Status"));
	       
	       /* Do CDR */
	       cdrfs->logcdr(e->created, 
			     octstr_get_cstr(e->from),
			     octstr_get_cstr(to->rcpt),
			     octstr_get_cstr(e->msgId),
			     mmc ? octstr_get_cstr(mmc->id) : NULL, /* Should we touch mmc here? XXX */ 
			     e->src_interface, 
			     "MM7",
			     e->msize, 
			     (char *)mms_message_type_to_cstr(e->msgtype),
			     
			     prio ? octstr_get_cstr(prio) : NULL,
			     mclass ? octstr_get_cstr(mclass) : NULL,
			     res == MMS_SEND_ERROR_FATAL ? "dropped" : (mstatus ? octstr_get_cstr(mstatus) : "sent"),
			     e->dlr,
			     0);
	       
	       octstr_destroy(mclass);
	       octstr_destroy(prio);
	       octstr_destroy(mstatus);	       
	  }

	  if (err == NULL)
	       mms_info(0, "MM7", NULL, "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: msgid=[%s]", 
			SEND_ERROR_STR(res),
			octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), e->msize,
			new_msgid ? octstr_get_cstr(new_msgid) : "N/A");
	  else 
	       mms_error_ex("MT", 0, 
			    "MM7", NULL, 
			    "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: %s", 
			    SEND_ERROR_STR(res),
			    octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), e->msize, octstr_get_cstr(err));
	  
	  octstr_destroy(new_msgid);
	  octstr_destroy(err);
	  http_destroy_headers(errl);
	  
	  e->lasttry = tnow;
          if (qfs->mms_queue_update(e) == 1) { 
               e = NULL;
               break; /* Queue entry gone. */             
          }
     }

done2:
     mms_destroy(msg);     
     octstr_destroy(otransid);
     
     if (e) { /* Update the queue if it is still valid (e.g. recipients not handled) 
	       * XXX can this happen here??... 
	       */
	  e->lasttry = time(NULL);
	  e->attempts++;  /* Update count of number of delivery attempts. */   
	  e->sendt = e->lasttry + mmsbox_send_back_off * e->attempts;
	  
	  if (qfs->mms_queue_update(e) != 1)
	       qfs->mms_queue_free_env(e);
     }

     
     return 1; /* always delete queue entry. */
}
Esempio n. 23
0
static void msg_to_bb(SMSCConn *conn, Octstr *line)
{
    long p, p2;
    Msg *msg;
    Octstr *type = NULL; /* might be destroyed after error before created */

    msg = msg_create(sms);
    p = octstr_search_char(line, ' ', 0);
    if (p == -1)
        goto error;
    msg->sms.sender = octstr_copy(line, 0, p);
    p2 = octstr_search_char(line, ' ', p + 1);
    if (p2 == -1)
        goto error;
    msg->sms.receiver = octstr_copy(line, p + 1, p2 - p - 1);
    p = octstr_search_char(line, ' ', p2 + 1);
    if (p == -1)
        goto error;
    type = octstr_copy(line, p2 + 1, p - p2 - 1);
    if (!octstr_compare(type, octstr_imm("text"))) {
        msg->sms.msgdata = octstr_copy(line, p + 1, LONG_MAX);
        msg->sms.coding = DC_7BIT;
    }
    else if (!octstr_compare(type, octstr_imm("data"))) {
        msg->sms.msgdata = octstr_copy(line, p + 1, LONG_MAX);
        msg->sms.coding = DC_8BIT;
        if (octstr_url_decode(msg->sms.msgdata) == -1)
            warning(0, "smsc_fake: urlcoded data from client looks malformed");
    }
    else if (!octstr_compare(type, octstr_imm("route"))) {
        p2 = octstr_search_char(line, ' ', p + 1);
        if (p2 == -1)
            goto error;
        msg->sms.boxc_id = octstr_copy(line, p + 1, p2 - p - 1);
        msg->sms.msgdata = octstr_copy(line, p2 + 1, LONG_MAX);
    }
    else if (!octstr_compare(type, octstr_imm("udh"))) {
        p2 = octstr_search_char(line, ' ', p + 1);
        if (p2 == -1)
            goto error;
        msg->sms.udhdata = octstr_copy(line, p + 1, p2 - p - 1);
        msg->sms.msgdata = octstr_copy(line, p2 + 1, LONG_MAX);
        if (msg->sms.coding == DC_UNDEF)
            msg->sms.coding = DC_8BIT;
        if (octstr_url_decode(msg->sms.msgdata) == -1 ||
            octstr_url_decode(msg->sms.udhdata) == -1)
            warning(0, "smsc_fake: urlcoded data from client looks malformed");
    }
    else if (!octstr_compare(type, octstr_imm("dlr-mask"))) {
        Octstr *tmp;
        p2 = octstr_search_char(line, ' ', p + 1);
        if (p2 == -1)
            goto error;
        tmp = octstr_copy(line, p + 1, p2 - p - 1);
        msg->sms.dlr_mask = atoi(octstr_get_cstr(tmp));
        octstr_destroy(tmp);
        msg->sms.msgdata = octstr_copy(line, p2 + 1, LONG_MAX);
    }
    else
        goto error;
    octstr_destroy(line);
    octstr_destroy(type);
    time(&msg->sms.time);
    msg->sms.smsc_id = octstr_duplicate(conn->id);

    debug("bb.sms", 0, "smsc_fake: new message received");
    /* msg_dump(msg, 0); */
    bb_smscconn_receive(conn, msg);
    return;
error:
    warning(0, "smsc_fake: invalid message syntax from client, ignored");
    msg_destroy(msg);
    octstr_destroy(line);
    octstr_destroy(type);
    return;
}
Esempio n. 24
0
struct cgwop *cgw_read_op(PrivData *privdata, SMSCConn *conn, Connection *server, time_t timeout)
{
    Octstr *line, *name, *value;
    int finished = 0;
    int c = 0;
    struct cgwop *cgwop = NULL;

    int op = CGW_OP_NOP;

    if ((line = conn_read_line(server)) == NULL) 
        return NULL;     /* don't block */

    do
    {
        while (line == NULL)
            line = conn_read_line(server);     /* wait for more data */

        c = octstr_search_char(line, ':', 0);
        if (c != -1) {
            name = octstr_copy(line, 0, c);
            value = octstr_copy(line, c + 1, octstr_len(line) - (c + 1));

            if (octstr_compare(name, octstr_imm("hello")) == 0) {
                /* A connection is started by CGW by sending a 
		 * "hello: Provider Server..." line. */

                cgwop = cgwop_create(CGW_OP_HELLO, 0);
                cgwop_add(cgwop, octstr_imm("hello"), value);

                octstr_destroy(name);
                octstr_destroy(value);
                octstr_destroy(line);

                return cgwop;
            }

            if (octstr_compare(name, octstr_imm("op")) == 0) {
                /* check different ops */
                if (octstr_compare(value, octstr_imm("msg")) == 0)
                    op = CGW_OP_MSG;
                else
                    if (octstr_compare(value, octstr_imm("ok")) == 0)
                        op = CGW_OP_OK;
                    else
                        if (octstr_compare(value, octstr_imm("delivery")) == 0)
                            op = CGW_OP_DELIVERY;
                        else
                            if (octstr_compare(value, octstr_imm("err")) == 0)
                                op = CGW_OP_ERR;
                            else
                                if (octstr_compare(value, octstr_imm("status")) == 0)
                                    op = CGW_OP_STATUS;
                                else
                                    info(0, "CGW: Received unknown op: %s", octstr_get_cstr(value));

                if (cgwop == NULL)
                    cgwop = cgwop_create(op, 0);
                else
                    info(0, "cgw: cgwop != null");
            }

            if (op != CGW_OP_NOP) {
                /* All commands have to be inside an op:xx ... end:xx statement */

                if (octstr_compare(name, octstr_imm("end")) == 0) { /* found end of op */
                    finished = 1;
                } else {
                    /* store in name/value fields in cgwop */
                    if (cgwop != NULL) {
                        cgwop_add(cgwop, name, value);
                    }
                }
            }
            octstr_destroy(name);
            octstr_destroy(value);
            octstr_destroy(line);

            if (!finished) line = conn_read_line(server);
        } else {
            info(0, "cgw: Received invalid input: %s", octstr_get_cstr(line));
            octstr_destroy(line);
            finished = 1;
        }

    } while (!finished);

    return cgwop;
}