From 48ed54d1102bd30a5fd08577a088cb7fe04b281f Mon Sep 17 00:00:00 2001 From: bagyenda <> Date: Fri, 9 Sep 2005 13:11:38 +0000 Subject: [PATCH] MMSBox bug fixes --- mbuni/doc/examples/mmsc.conf | 30 +++++ mbuni/mmlib/mms_mm7soap.c | 10 +- mbuni/mmlib/mms_mm7soap.h | 1 + mbuni/mmlib/mms_queue.c | 3 +- mbuni/mmsbox/Makefile | 2 +- mbuni/mmsbox/bearerbox.c | 38 +++--- mbuni/mmsbox/mmsbox.c | 217 +++++++++++++++++++++++++++-------- mbuni/mmsbox/mmsbox_cfg.c | 44 ++++--- mbuni/mmsbox/mmsbox_cfg.h | 3 +- mbuni/mmsc/mmsglobalsender.c | 1 + 10 files changed, 267 insertions(+), 82 deletions(-) diff --git a/mbuni/doc/examples/mmsc.conf b/mbuni/doc/examples/mmsc.conf index 7569c29..8b3e544 100644 --- a/mbuni/doc/examples/mmsc.conf +++ b/mbuni/doc/examples/mmsc.conf @@ -36,6 +36,36 @@ mms-notify-unprovisioned-text = "This is a test" mms-to-email-txt = "This is a multimedia message (HTML suppressed)" mms-to-email-html = "This is a multimedia message powered by Digital Solutions" mms-message-too-large-txt = "You have received a multimedia message from %S that is too large for your phone. Go to xxx to view it" +sendmms-port = 10001 + +group = send-mms-user +username = tester +password = foobar +faked-sender = 100 + +group = mmsc +id = testone +mmsc-url = http://mmsc +incoming-username = user +incoming-password = pass +incoming-port = 10002 +type = soap + +group = mms-service +name = me +post-url = http://localhost/~bagyenda/test2.hei +catch-all = true +http-post-parameters = fx=true&images.=%i&text.=%t +accept-x-mbuni-headers = true +keyword = test + +group = mms-service +name = fullmessage +get-url = http://localhost/~bagyenda/images/apache_pb.gif +# http-post-parameters = fx=true&image=%i&text=%t +accept-x-mbuni-headers = true +keyword = thixs + group = mms-vasp vasp-id = newscorp diff --git a/mbuni/mmlib/mms_mm7soap.c b/mbuni/mmlib/mms_mm7soap.c index cacca86..dcffb28 100644 --- a/mbuni/mmlib/mms_mm7soap.c +++ b/mbuni/mmlib/mms_mm7soap.c @@ -671,7 +671,9 @@ int mm7_get_envelope(MSoapMsg_t *m, *subject = http_header_value(m->envelope, octstr_imm("Subject")); *vasid = http_header_value(m->envelope, octstr_imm("VASID")); - s = http_header_value(m->envelope, octstr_imm("SenderAddress")); + if ((s = http_header_value(m->envelope, octstr_imm("SenderAddress"))) == NULL) + s = http_header_value(m->envelope, octstr_imm("Sender")); + if (s && octstr_get_char(s, 0) == '+') octstr_delete(s, 0, 2); else if (s) { @@ -847,7 +849,8 @@ static MSoapMsg_t *mm7_soap_create(int msgtype, Octstr *otransid) } MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, - Octstr *transid, Octstr *srvcode, + Octstr *transid, Octstr *srvcode, + Octstr *linkedid, int isclientside, char *vaspid, char *vasid) { @@ -877,7 +880,8 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, isclientside ? "ServiceCode" : "MMSRelayServerID", octstr_get_cstr(srvcode)); - http_header_add(m->envelope, "LinkedID", octstr_get_cstr(transid)); + if (linkedid) + http_header_add(m->envelope, "LinkedID", octstr_get_cstr(linkedid)); http_header_add(m->envelope, isclientside ? "SenderAddress" : "Sender", octstr_get_cstr(xfrom)); diff --git a/mbuni/mmlib/mms_mm7soap.h b/mbuni/mmlib/mms_mm7soap.h index 575fd1e..602a476 100644 --- a/mbuni/mmlib/mms_mm7soap.h +++ b/mbuni/mmlib/mms_mm7soap.h @@ -40,6 +40,7 @@ extern void mm7_soap_destroy(MSoapMsg_t *m); /* Convert a message to a SOAP message. */ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, Octstr *transid, Octstr *srvcode, + Octstr *linkedid, int isclientside, char *vaspid, char *vasid); MSoapMsg_t *mm7_make_resp(MSoapMsg_t *mreq, int status, Octstr *msgid); diff --git a/mbuni/mmlib/mms_queue.c b/mbuni/mmlib/mms_queue.c index 8036c64..57ffc31 100644 --- a/mbuni/mmlib/mms_queue.c +++ b/mbuni/mmlib/mms_queue.c @@ -353,7 +353,8 @@ static int writeenvelope(MmsEnvelope *e, int newenv) if (e->msgId) _putline(fd, "I", octstr_get_cstr(e->msgId)); - _putline(fd, "F", octstr_get_cstr(e->from)); + if (e->from) + _putline(fd, "F", octstr_get_cstr(e->from)); if (e->to) n = list_len(e->to); diff --git a/mbuni/mmsbox/Makefile b/mbuni/mmsbox/Makefile index 24ab473..379c955 100644 --- a/mbuni/mmsbox/Makefile +++ b/mbuni/mmsbox/Makefile @@ -82,7 +82,7 @@ AUTOMAKE = ${SHELL} /Users/bagyenda/src/mbuni/missing --run automake-1.9 AWK = gawk CC = gcc CCDEPMODE = depmode=gcc3 -CFLAGS = -I./../mmlib -g -Wall -O2 -DDARWIN=1 -I/sw/include -I/usr/local/include/kannel -DDARWIN=1 -I/sw/include/libxml2 -I/sw/include -I/sw/include +CFLAGS = -I./../mmlib -g -Wall -DDARWIN=1 -I/sw/include -I/usr/local/include/kannel -DDARWIN=1 -I/sw/include/libxml2 -I/sw/include -I/sw/include CPP = gcc -E CPPFLAGS = CXX = g++ diff --git a/mbuni/mmsbox/bearerbox.c b/mbuni/mmsbox/bearerbox.c index 350e148..6e0b1cf 100644 --- a/mbuni/mmsbox/bearerbox.c +++ b/mbuni/mmsbox/bearerbox.c @@ -70,7 +70,8 @@ done: return res; } -static int send_report(Octstr *from, char *report_type, Octstr *status, Octstr *msgid, Octstr *mmc_id) +static int send_report(Octstr *from, char *report_type, Octstr *status, + Octstr *msgid, Octstr *mmc_id) { Octstr *url = mms_dlr_url_get(msgid, report_type, mmc_id); @@ -150,7 +151,9 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) case MM7_TAG_DeliverReq: m = mm7_soap_to_mmsmsg(mreq, from); if (m) { - Octstr *value; + Octstr *value = NULL; + /* Store linked id so we use it in response. */ + Octstr *linkedid = mm7_soap_header_value(mreq, octstr_imm("LinkedID")); int dlr; value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report")); @@ -168,7 +171,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) qf = mms_queue_add(from, to, subject, h->m->id, NULL, - delivert, expiryt, m, NULL, + delivert, expiryt, m, linkedid, NULL, NULL, NULL, NULL, dlr, @@ -177,6 +180,8 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) msgid = mms_maketransid(octstr_get_cstr(qf), octstr_imm(MM_NAME)); mms_log("Received", from, to, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL); + if (linkedid) + octstr_destroy(linkedid); octstr_destroy(value); } else status = 4000; @@ -501,7 +506,9 @@ static void free_clientInfo(MmsHTTPClientInfo *h, int freeh) * are observed! * Don't remove from queue on fail, just leave it to expire. */ -static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgId, +static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, + Octstr *transid, + Octstr *linkedid, char *vasid, MmsMsg *m, Octstr **error) { @@ -521,8 +528,9 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgI list_append(xto, to); - if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, + if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, transid, NULL, + linkedid, 1, octstr_get_cstr(mmc->id), vasid)) == NULL) { *error = octstr_format("Failed to convert Msg[%s] 2 SOAP message!", mms_message_type_to_cstr(mtype)); @@ -534,7 +542,7 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgI goto done1; } - hstatus = mmsbox_http_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph,&rbody); + hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph,&rbody); if (hstatus != HTTP_OK) { *error = octstr_format("Failed to contact MMC[url=%s] => HTTP returned status = %d!", octstr_get_cstr(mmc->mmsc_url), hstatus); @@ -630,7 +638,7 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, body = mms_tobinary(m); - hstatus = mmsbox_http_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); + hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%s] => HTTP returned status = %d !", @@ -664,19 +672,20 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, } -static int mms_sendtommsc(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgid, - char *vasid, - MmsMsg *m, - Octstr *dlr_url, - Octstr *rr_url, - Octstr **err) +static int mms_sendtommsc(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transid, + Octstr *linkedid, + char *vasid, + MmsMsg *m, + Octstr *dlr_url, + Octstr *rr_url, + Octstr **err) { Octstr *id = NULL; mutex_lock(mmc->mutex); { /* Grab a lock on it. */ if (mmc->type == SOAP_MMSC) - id = mm7soap_send(mmc, from, to, msgid, vasid, m, err); + id = mm7soap_send(mmc, from, to, transid, linkedid, vasid, m, err); else if (mmc->type == EAIF_MMSC) id = mm7eaif_send(mmc, from, to, vasid, m, err); else @@ -779,6 +788,7 @@ static int sendMsg(MmsEnvelope *e) res = mms_sendtommsc(mmc, e->from, to->rcpt, e->msgId, + e->token, /* token = linkedid */ e->vasid ? octstr_get_cstr(e->vasid) : NULL, msg, e->url1, e->url2, diff --git a/mbuni/mmsbox/mmsbox.c b/mbuni/mmsbox/mmsbox.c index 9003ea5..c319d4c 100644 --- a/mbuni/mmsbox/mmsbox.c +++ b/mbuni/mmsbox/mmsbox.c @@ -23,9 +23,19 @@ int rstop = 0; static void quit_now(int notused) { + int i, n; + MmscGrp *mmc; rstop = 1; /* Close all MMSC http ports, kill all MMSC threads, kill sendmms port... */ + + if (sendmms_port.port > 0) + http_close_port(sendmms_port.port); + + for (i = 0, n = list_len(mmscs); i < n; i++) + if ((mmc = list_get(mmscs, i)) != NULL && + mmc->incoming.port > 0) + http_close_port(mmc->incoming.port); } static MIMEEntity *find_textpart(MIMEEntity *m) @@ -46,11 +56,9 @@ static MIMEEntity *find_textpart(MIMEEntity *m) int i, n = list_len(m->multiparts); for (i = 0; i < n; i++) if ((res = find_textpart(list_get(m->multiparts, i))) != NULL) - goto done; + goto done2; } done: - if (ctype) - octstr_destroy(ctype); if (res) { /* We got it! Convert charset if needed. */ List *params_h = get_value_parameters(params); @@ -68,10 +76,16 @@ done: octstr_destroy(charset); } +done2: + if (ctype) + octstr_destroy(ctype); + if (params) octstr_destroy(params); return res; } + + /* Gets the keyword, if any, from the text part of the message. * converts charset as needed. */ @@ -92,9 +106,15 @@ static Octstr *get_keyword(MIMEEntity *me) return keyword; } +static int _x_octstr_comp(Octstr *x, Octstr *y) +{ + return (octstr_case_compare(x,y) == 0); +} + static MmsService *get_service(Octstr *keyword, Octstr *mmc_id) { int i, n; + MmsService *catch_all = NULL; for (i = 0, n = list_len(mms_services); i < n; i++) { MmsService *ms = list_get(mms_services,i); @@ -113,11 +133,14 @@ static MmsService *get_service(Octstr *keyword, Octstr *mmc_id) if (keyword == NULL || list_search(ms->keywords, keyword, - (list_item_matches_t *)octstr_case_compare) != NULL) + (list_item_matches_t *)_x_octstr_comp) != NULL) return ms; + + if (ms->isdefault) /* We also find the catch-all for this sender. */ + catch_all = ms; } - return NULL; + return catch_all; } static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm, @@ -130,9 +153,12 @@ static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm, if (pm->type == WHOLE_BINARY && lev == 0) { data = mms_tobinary(msg); ctype = octstr_imm("application/vnd.wap.mms-message"); + } else if (pm->type == NO_PART && lev == 0) { + data = octstr_create(""); /* We'll add value below. */ + goto done; } - if (me->multiparts && list_len(me->multiparts) > 0) { + if (me->multiparts && list_len(me->multiparts) > 0) { /* Don't process multipart. */ for (i = 0, n = list_len(me->multiparts); i < n; i++) add_all_matching_parts(plist, pm, list_get(me->multiparts, i), msg, lev+1); @@ -161,29 +187,63 @@ static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm, data = me->body ? octstr_duplicate(me->body) : octstr_create(""); } -done: - - if (ctype) { +done: + if (data) { MIMEEntity *p = mime_entity_create(); Octstr *cd = octstr_format("form-data; name=\"%S\"", pm->name); - http_header_add(p->headers, "Content-Type", octstr_get_cstr(ctype)); - http_header_add(p->headers, "Content-Disposition", octstr_get_cstr(cd)); + if (ctype) { + /* If name parameter given, pass it as filename. */ + Octstr *c = NULL, *q = NULL; + split_header_value(ctype, &c, &q); + + if (q) { + List *ph = get_value_parameters(q); + Octstr *v = http_header_value(ph, octstr_imm("name")); + + if (v) { + octstr_format_append(cd, "; filename=\"%S\"", v); + http_header_remove_all(ph, "name"); + + octstr_destroy(v); + octstr_destroy(ctype); + v = make_value_parameters(ph); + if (v && octstr_len(v) > 0) + ctype = octstr_format("%S; %S", c, v); + else + ctype = octstr_duplicate(c); + if (v) + octstr_destroy(v); + } + http_destroy_headers(ph); + octstr_destroy(q); + } + + if (c) + octstr_destroy(c); + } + http_header_add(p->headers, "Content-Disposition", octstr_get_cstr(cd)); + if (ctype) /* This header must come after the above it seems. */ + http_header_add(p->headers, "Content-Type", octstr_get_cstr(ctype)); p->body = data; + if (pm->value) /* add value part as needed. */ + octstr_append(p->body, pm->value); + base64_mimeparts(p); list_append(plist->multiparts, p); - octstr_destroy(ctype); octstr_destroy(cd); } + if (xctype) octstr_destroy(xctype); if (params) octstr_destroy(params); - + if (ctype) + octstr_destroy(ctype); } enum _xurltype {FILE_TYPE, URL_TYPE}; @@ -211,7 +271,7 @@ static int fetch_serviceurl(MmsEnvelope *e, case TRANS_TYPE_POST_URL: rh = http_create_empty_headers(); - http_header_add(rh, "User-Agent", MM_NAME "/" GW_VERSION); + http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); /* Put in some useful headers. */ if (e->msgId) http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(e->msgId)); @@ -247,7 +307,7 @@ static int fetch_serviceurl(MmsEnvelope *e, method = HTTP_METHOD_GET; typ = URL_TYPE; - if (mmsbox_http_fetch_content(method, ms->url, rh, body, &rph, &rb) == HTTP_OK) + if (mmsbox_url_fetch_content(method, ms->url, rh, body, &rph, &rb) == HTTP_OK) get_content_type(rph, &ctype, ¶ms); else *err = octstr_format("MMSBox: Failed to fetch content for Service %S, url %S!", @@ -429,19 +489,21 @@ int main(int argc, char *argv[]) signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for nothing*/ - /* Start out-going queue thread. */ - qthread = gwthread_create((gwthread_func_t *)mmsbox_outgoing_queue_runner, &rstop); - /* Start sendmms port */ if (sendmms_port.port > 0) sthread = gwthread_create((gwthread_func_t *)sendmms_func, NULL); + +#if 0 + /* Start out-going queue thread. */ + qthread = gwthread_create((gwthread_func_t *)mmsbox_outgoing_queue_runner, &rstop); +#endif - +#if 1 mms_queue_run(octstr_get_cstr(incoming_qdir), mmsbox_service_dispatch, queue_interval, maxthreads, &rstop); - +#endif /* Wait for the sender thread, then quit. */ gwthread_join(qthread); /* Wait for it to die... */ @@ -451,21 +513,72 @@ int main(int argc, char *argv[]) return 0; } -int mmsbox_http_fetch_content(int method, Octstr *url, List *request_headers, +int mmsbox_url_fetch_content(int method, Octstr *url, List *request_headers, Octstr *body, List **reply_headers, Octstr **reply_body) { - HTTPCaller *c = http_caller_create(); + int status = 0; Octstr *furl = NULL; - http_start_request(c, method, url, request_headers, body, 1, NULL, NULL); + if (octstr_search(url, octstr_imm("data:"), 0) == 0) { + int i = octstr_search_char(url, ',',0); + Octstr *ctype = (i >= 0) ? octstr_copy(url, 5, i-5) : octstr_create("text/plain; charset=us-ascii"); + Octstr *data = (i >= 0) ? octstr_copy(url, i+1, octstr_len(url)) : octstr_duplicate(url); - if (http_receive_result(c, &status, &furl, reply_headers, reply_body) == NULL) - status = -1; + Octstr *n = NULL, *h = NULL; + + if (octstr_len(ctype) == 0) + octstr_append_cstr(ctype, "text/plain; charset=us-ascii"); + split_header_value(ctype, &n, &h); + + if (h) { + List *ph = get_value_parameters(h); + Octstr *v = NULL; + + if (ph && (v = http_header_value(ph, octstr_imm("base64"))) != NULL) { /* has base64 item */ + Octstr *p = NULL; + + octstr_base64_to_binary(data); + http_header_remove_all(ph, "base64"); + + octstr_destroy(ctype); + + if (list_len(ph) > 0) { + p = make_value_parameters(ph); + ctype = octstr_format("%S; %S", + n,p); + octstr_destroy(p); + } else + ctype = octstr_format("%S", n); + } + + if (ph) + http_destroy_headers(ph); + + octstr_destroy(v); + octstr_destroy(h); + } + + if (n) + octstr_destroy(n); + + *reply_body = data; + *reply_headers = http_create_empty_headers(); + http_header_add(*reply_headers, "Content-Type", octstr_get_cstr(ctype)); + + octstr_destroy(ctype); + status = HTTP_OK; + } else { + HTTPCaller *c = http_caller_create(); + http_start_request(c, method, url, request_headers, body, 1, NULL, NULL); + if (http_receive_result(c, &status, &furl, reply_headers, reply_body) == NULL) + status = -1; + http_caller_destroy(c); + } if (furl) octstr_destroy(furl); - http_caller_destroy(c); + return status; } @@ -573,7 +686,10 @@ static Octstr *get_toplevel_url(Octstr *url) static int has_url_scheme(char *url) { char *p = strstr(url, "://"); - + char *q = strstr(url, "data:"); /* data url scheme. */ + + if (q && q == url) + return 1; if (!p) return 0; for (p -= 1; p >= url; p--) @@ -584,13 +700,14 @@ static int has_url_scheme(char *url) static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, Octstr *top_url, - int type, MmsEnvelope *e) + int type, MmsEnvelope *e, Dict *url_map) { Octstr *curl = NULL, *ctype = NULL, *body = NULL; char *src = NULL; int isurl, slash_prefix; MmsService *ms = e->_x; static int cntr; /* For generating cids */ + Octstr *cid = NULL; /* For each node in the smil doc, if it has an src attribute, then: * - if our type of base_url is FILE *and the src attribute does not look @@ -611,11 +728,11 @@ static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, isurl = has_url_scheme(src); slash_prefix = (src[0] == '/'); - if (isurl && strstr(src, "http") != 0) /* Only http and https allowed! */ + if (isurl && strstr(src, "http") != src) /* Only http and https allowed! */ goto done; if (isurl) - ctype = octstr_create(src); + curl = octstr_create(src); else if (slash_prefix) { if (type == URL_TYPE) curl = octstr_format("%S%s", @@ -625,13 +742,19 @@ static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, } else curl = octstr_format("%S/%s",base_url, src); + if ((cid = dict_get(url_map, curl)) != NULL) { /* We've seen it before. */ + xmlSetProp(node, (xmlChar *)"src", (xmlChar *)octstr_get_cstr(cid)); + /* Don't delete cid! */ + goto done; + } + isurl |= (type == URL_TYPE); /* From now on, this flag tells us whether we are fetching a url.*/ if (isurl) { List *rh = http_create_empty_headers(), *rph = NULL; - http_header_add(rh, "User-Agent", MM_NAME "/" GW_VERSION); - if (mmsbox_http_fetch_content(HTTP_METHOD_POST, curl, rh, NULL, &rph, &body) == HTTP_OK) + http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); + if (mmsbox_url_fetch_content(HTTP_METHOD_GET, curl, rh, NULL, &rph, &body) == HTTP_OK) ctype = http_header_value(rph, octstr_imm("Content-Type")); else error(0, "MMSBOX: Failed to load url %s within SMIL content from service %s!", @@ -656,6 +779,8 @@ static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, list_append(res->multiparts, x); + dict_put_once(url_map, curl, octstr_duplicate(attr)); /* Store the cid. */ + xmlSetProp(node, (xmlChar *)"src", (xmlChar *)octstr_get_cstr(attr)); octstr_destroy(attr); @@ -674,14 +799,14 @@ done: /* Traverse the tree doing the above. */ static void add_msg_parts(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, Octstr *top_url, - int type, MmsEnvelope *e) + int type, MmsEnvelope *e, Dict *url_map) { xmlNodePtr n; /* Do all the children recursively, then come back and do parent. */ for (n = node; n; n = n->next) if (n->type != XML_COMMENT_NODE) { - add_msg_part(res, n, base_url, top_url, type, e); - add_msg_parts(res, n->xmlChildrenNode, base_url, top_url, type, e); + add_msg_part(res, n, base_url, top_url, type, e, url_map); + add_msg_parts(res, n->xmlChildrenNode, base_url, top_url, type, e, url_map); } } @@ -719,15 +844,15 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, } /* start with the easy one... */ - if (octstr_case_compare(ctype, octstr_imm("application/vnd.wap.mms-message")) == 0) { + if (octstr_case_compare(ctype, octstr_imm("application/vnd.wap.mms-message")) == 0) m = mms_frombinary(data, from); - goto done; /* all done! */ - } else if (octstr_case_compare(ctype, octstr_imm("application/smil")) == 0) { + else if (octstr_case_compare(ctype, octstr_imm("application/smil")) == 0) { xmlDocPtr smil; xmlChar *buf = NULL; int bsize = 0; - - /* This is the hard bit! */ + Dict *url_map = dict_create(97, (void (*)(void *))octstr_destroy); + + /* This is the hard bit: Fetch each external reference in smil, add it to message! */ http_header_add(me->headers, "Content-Type", "multipart/related; " "type=\"application/smil\"; start=\"\""); @@ -737,11 +862,13 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, *err = octstr_format("MMSBox: Error parsing SMIL response from service[%s], " " msgid %s!", octstr_get_cstr(svc_name), (e && e->msgId) ? octstr_get_cstr(e->msgId) : "(none)"); + dict_destroy(url_map); goto done; } - add_msg_parts(me, smil->xmlChildrenNode, base_url, turl, type, e); + add_msg_parts(me, smil->xmlChildrenNode, base_url, turl, type, e, url_map); + dict_destroy(url_map); /* SMIL has been modified, convert it to text, put it in. */ xmlDocDumpFormatMemory(smil, &buf, &bsize, 1); xmlFreeDoc(smil); @@ -807,11 +934,9 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, http_header_add(me->headers, "From", octstr_get_cstr(from)); for (i = 0, n = list_len(xto); i < n; i++) { - Octstr *v, *h; - http_header_get(xto, i, &h, &v); + Octstr *v; + v = list_get(xto, i); http_header_add(me->headers, "To", octstr_get_cstr(v)); - octstr_destroy(h); - octstr_destroy(v); } if (dlr_url) @@ -826,7 +951,7 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, octstr_destroy(x); } - if (me) + if (me && !m) /* Set m if it hasn't been set yet. */ m = mms_frommime(me); if (!m) { *err = octstr_format("MMSBox: Failed to convert Mms Message from service %s!", diff --git a/mbuni/mmsbox/mmsbox_cfg.c b/mbuni/mmsbox/mmsbox_cfg.c index 0ad156f..3e26077 100644 --- a/mbuni/mmsbox/mmsbox_cfg.c +++ b/mbuni/mmsbox/mmsbox_cfg.c @@ -28,7 +28,8 @@ List *mms_services = NULL; /* list of MMS Services */ List *mmscs = NULL; Octstr *incoming_qdir, *outgoing_qdir, *dlr_dir; long mmsbox_maxsendattempts, mmsbox_send_back_off; -long queue_interval, maxthreads; +long maxthreads = 0; +double queue_interval = -1; Octstr *unified_prefix; struct SendMmsPortInfo sendmms_port; @@ -41,7 +42,8 @@ int mms_load_mmsbox_settings(Cfg *cfg, gwthread_func_t *mmsc_handler_func) int send_port_ssl = 0; List *l; int i, n; - + void *catchall = NULL; + mms_load_core_settings(cgrp); sendmms_users = list_create(); @@ -87,12 +89,15 @@ int mms_load_mmsbox_settings(Cfg *cfg, gwthread_func_t *mmsc_handler_func) if (cfg_get_integer(&maxthreads, grp, octstr_imm("max-send-threads")) == -1) maxthreads = 10; - s = _mms_cfg_getx(grp, octstr_imm("queue-run-interval")); - if (!s || (queue_interval = atof(octstr_get_cstr(s))) <= 0) + s = cfg_get(grp, octstr_imm("queue-run-interval")); + if (s) { + queue_interval = atof(octstr_get_cstr(s)); + octstr_destroy(s); + } + if (queue_interval <= 0) queue_interval = QUEUERUN_INTERVAL; - if (s) - octstr_destroy(s); + unified_prefix = _mms_cfg_getx(grp, octstr_imm("unified-prefix")); @@ -119,7 +124,7 @@ int mms_load_mmsbox_settings(Cfg *cfg, gwthread_func_t *mmsc_handler_func) u->user = _mms_cfg_getx(x, octstr_imm("username")); u->pass = _mms_cfg_getx(x, octstr_imm("password")); - u->faked_sender = _mms_cfg_getx(x, octstr_imm("faked-sender")); + u->faked_sender = cfg_get(x, octstr_imm("faked-sender")); u->dlr_url = _mms_cfg_getx(x, octstr_imm("delivery-report-url")); u->rr_url = _mms_cfg_getx(x, octstr_imm("read-report-url")); list_append(sendmms_users, u); @@ -206,8 +211,15 @@ int mms_load_mmsbox_settings(Cfg *cfg, gwthread_func_t *mmsc_handler_func) else panic(0, "MMSBox: Service [%s] has no url!", octstr_get_cstr(m->name)); - m->faked_sender = _mms_cfg_getx(x, octstr_imm("faked-sender")); - cfg_get_bool(&m->isdefault, x, octstr_imm("catch-all")); + m->faked_sender = cfg_get(x, octstr_imm("faked-sender")); + cfg_get_bool(&m->isdefault, x, octstr_imm("catch-all")); + + if (m->isdefault) { + if (catchall) + warning(0, "MMSBox: Multiple default mms services defined!"); + catchall = m; + } + cfg_get_bool(&m->omitempty, x, octstr_imm("omit-empty")); cfg_get_bool(&m->accept_x_headers, x, octstr_imm("accept-x-mbuni-headers")); cfg_get_bool(&m->assume_plain_text, x, octstr_imm("assume-plain-text")); @@ -258,17 +270,17 @@ int mms_load_mmsbox_settings(Cfg *cfg, gwthread_func_t *mmsc_handler_func) if (octstr_get_char(y, ii+1) == '%') { switch(ch = octstr_get_char(y, ii+2)) { - case 'I': + case 'i': p->type = IMAGE_PART; break; - case 'V': + case 'v': p->type = VIDEO_PART; break; - case 'T': + case 't': p->type = TEXT_PART; break; - case 'S': + case 's': p->type = SMIL_PART; break; - case 'O': + case 'o': p->type = OTHER_PART; break; - case 'A': + case 'a': p->type = ANY_PART; break; case '%': p->type = NO_PART; break; @@ -279,7 +291,7 @@ int mms_load_mmsbox_settings(Cfg *cfg, gwthread_func_t *mmsc_handler_func) p->type = NO_PART; break; } - p->value = octstr_copy(y, ii+2, octstr_len(y)); + p->value = octstr_copy(y, ii+3, octstr_len(y)); } else /* No conversion spec. */ p->value = octstr_copy(y, ii+1, octstr_len(y)); list_append(m->params, p); diff --git a/mbuni/mmsbox/mmsbox_cfg.h b/mbuni/mmsbox/mmsbox_cfg.h index 7e8237a..3c41a19 100644 --- a/mbuni/mmsbox/mmsbox_cfg.h +++ b/mbuni/mmsbox/mmsbox_cfg.h @@ -70,7 +70,8 @@ extern List *mmscs; /* MMSC list. Perhaps turn into a Dict instead? */ extern Octstr *incoming_qdir, *outgoing_qdir, *dlr_dir; extern Octstr *unified_prefix; extern long mmsbox_maxsendattempts, mmsbox_send_back_off; -extern long queue_interval, maxthreads; +extern long maxthreads; +extern double queue_interval; extern struct SendMmsPortInfo { long port; /* Might be ssl-ed. */ Octstr *allow_ip; diff --git a/mbuni/mmsc/mmsglobalsender.c b/mbuni/mmsc/mmsglobalsender.c index be904b6..e3fd909 100644 --- a/mbuni/mmsc/mmsglobalsender.c +++ b/mbuni/mmsc/mmsglobalsender.c @@ -493,6 +493,7 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId, if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, settings->host_alias, + msgId, 0, NULL, NULL)) == NULL) { *error = octstr_format("Failed to convert Msg[%s] 2 SOAP message!", mms_message_type_to_cstr(mtype));