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));