1
0
Fork 0

Mbuni updated to Kannel 1.4.1 -- initial stab

This commit is contained in:
bagyenda 2006-10-12 15:21:46 +00:00
parent 26cf73882b
commit c3feca09ff
25 changed files with 1161 additions and 1921 deletions

View File

@ -1,3 +1,3 @@
SUBDIRS = autotools doc misc-patches mmlib mmsc mmsbox SUBDIRS = autotools doc mmlib mmsc mmsbox
EXTRA_DIST = GnuLICENSE KannelLICENSE bootstrap Notes todo EXTRA_DIST = GnuLICENSE KannelLICENSE bootstrap Notes todo

View File

@ -1,6 +1,6 @@
dnl Mbuni - Open Source MMS Gateway dnl Mbuni - Open Source MMS Gateway
dnl dnl
dnl Copyright (C) 2003 - 2005, Digital Solutions Ltd. - http://www.dsmagic.com dnl Copyright (C) 2003 - 2006, Digital Solutions Ltd. - http://www.dsmagic.com
dnl dnl
dnl Paul Bagyenda <bagyenda@dsmagic.com> dnl Paul Bagyenda <bagyenda@dsmagic.com>
dnl dnl
@ -252,7 +252,7 @@ AC_CHECK_LIB([wap], [wsp_headers_pack], [], AC_MSG_ERROR([Kannel WAP lib is requ
dnl May be we need to check for media conversion tools (imagemagick, etc)? dnl May be we need to check for media conversion tools (imagemagick, etc)?
AC_CONFIG_FILES([Makefile autotools/Makefile doc/Makefile doc/examples/Makefile doc/images/Makefile misc-patches/Makefile mmlib/Makefile mmsc/Makefile mmsbox/Makefile]) AC_CONFIG_FILES([Makefile autotools/Makefile doc/Makefile doc/examples/Makefile doc/images/Makefile mmlib/Makefile mmsc/Makefile mmsbox/Makefile])
AC_OUTPUT AC_OUTPUT
@ -260,7 +260,7 @@ cat<<X
License: License:
Mbuni - Open Source MMS Gateway - http://www.mbuni.org/ Mbuni - Open Source MMS Gateway - http://www.mbuni.org/
Copyright (C) 2003 - 2005, Digital Solutions Ltd. - http://www.dsmagic.com Copyright (C) 2003 - 2006, Digital Solutions Ltd. - http://www.dsmagic.com
This program is free software, distributed under the terms of This program is free software, distributed under the terms of
the GNU General Public License, with a few exceptions granted (see LICENSE) the GNU General Public License, with a few exceptions granted (see LICENSE)

View File

@ -53,7 +53,7 @@ This document describes the installation and usage of the MMS Gateway.
<LI><A HREF="#Section_.1.1.3">Requirements</A></LI> <LI><A HREF="#Section_.1.1.3">Requirements</A></LI>
</UL></LI> </UL></LI>
<LI><A HREF="#Section_.1.2">Chapter 2: Installing The Gateway</A><UL> <LI><A HREF="#Section_.1.2">Chapter 2: Installing The Gateway</A><UL>
<LI><A HREF="#Section_.1.2.1">Patching and Installing Kannel</A></LI> <LI><A HREF="#Section_.1.2.1">Installing Kannel</A></LI>
<LI><A HREF="#Section_.1.2.2">Installing Mbuni MMS Gateway</A></LI> <LI><A HREF="#Section_.1.2.2">Installing Mbuni MMS Gateway</A></LI>
<LI><A HREF="#Section_.1.2.3">Installing Required Components</A></LI> <LI><A HREF="#Section_.1.2.3">Installing Required Components</A></LI>
</UL></LI> </UL></LI>
@ -364,16 +364,16 @@ less power.
<H3><!--TableOfContentsAnchor:Begin--><A NAME="Section_.1.2"></A><!--TableOfContentsAnchor:End-->Chapter 2: Installing The Gateway</H3> <H3><!--TableOfContentsAnchor:Begin--><A NAME="Section_.1.2"></A><!--TableOfContentsAnchor:End-->Chapter 2: Installing The Gateway</H3>
<p>This section <p>This section
explains the steps required to install the gateway. If you are explains the steps required to install the gateway. <strong>If you are
installing from a binary distribution, you may safely skip to <a installing from a binary distribution, you may safely skip to <a
href="#required_comps">here</a>. href="#required_comps">here</a></strong>.
</p> </p>
<p> <p>
In brief, to install Mbuni, you need to: In brief, to install Mbuni, you need to:
<ul> <ul>
<li>Download and install required packages (such as libXML, libiconv) <li>Download and install required packages (such as libXML, libiconv)
<li>Download, patch and install Kannel v1.4.0 <li>Download and install Kannel v1.4.1
<li>Download and install Mbuni <li>Download and install Mbuni
<li>Download, patch and install the AMR encoder/decoder <li>Download, patch and install the AMR encoder/decoder
<li>Download and install additional <a href="#required">requried</a> packages <li>Download and install additional <a href="#required">requried</a> packages
@ -387,11 +387,11 @@ href="http://www.mbuni.org/downloads.shtml">download area</a> of the website
<H4><!--TableOfContentsAnchor:Begin--><A NAME="Section_.1.2.1"></A><!--TableOfContentsAnchor:End-->Patching and Installing Kannel</H4> <H4><!--TableOfContentsAnchor:Begin--><A NAME="Section_.1.2.1"></A><!--TableOfContentsAnchor:End-->Installing Kannel</H4>
<p>In order to compile the software, you <p>In order to compile the software, you
will first need to download, patch, compile and install Kannel v1.4.0 from <a will first need to download and install Kannel v1.4.1 from <a
href="http://www.kannel.org/download/1.4.0/gateway-1.4.0.tar.bz2">kannel.org</a>:</p> href="http://www.kannel.org/download/1.4.1/gateway-1.4.1.tar.bz2">kannel.org</a>:</p>
@ -399,26 +399,9 @@ href="http://www.kannel.org/download/1.4.0/gateway-1.4.0.tar.bz2">kannel.org</a>
source files using a command like:</p> source files using a command like:</p>
<p><tt>bzip2 -cd <p><tt>bzip2 -cd
gateway-1.4.0.tar.bz2 | tar xf -</tt></p> gateway-1.4.1.tar.bz2 | tar xf -</tt></p>
<p>The kannel
sources need to be patched for Mbuni using the supplied patch file from
the Mbuni downloads section given above.
</p>
<p><tt>mbuni-kannel-patch-full</tt> contains important updates to Kannel 1.4.0 that are now part of Kannel CVS.
(Mbuni still depends on the v1.4.0 release version.)
</p>
<p>Apply the patch as follows:</p>
<p ><tt>cd gateway-1.4.0</tt>
<br>
<tt>patch -p1 &lt; ../mbuni-kannel-patch-full</tt>
</p>
<p >Then proceed to <p >Then proceed to
compile and install Kannel normally:</p> compile and install Kannel normally:</p>

View File

@ -1 +0,0 @@
EXTRA_DIST = mbuni-kannel-patch-full

File diff suppressed because it is too large Load Diff

View File

@ -140,8 +140,8 @@ mCfg *mms_cfg_read(Octstr *file)
cfg->grps = dict_create(7, NULL); cfg->grps = dict_create(7, NULL);
lines = octstr_split(sf, octstr_imm("\n")); lines = octstr_split(sf, octstr_imm("\n"));
for (i = 0, n = list_len(lines); i < n; i++) { for (i = 0, n = gwlist_len(lines); i < n; i++) {
Octstr *current = list_get(lines,i); Octstr *current = gwlist_get(lines,i);
int pos; int pos;
octstr_strip_blanks(current); octstr_strip_blanks(current);
@ -182,10 +182,10 @@ mCfg *mms_cfg_read(Octstr *file)
List *l = dict_get(cfg->grps, value); List *l = dict_get(cfg->grps, value);
if (l == NULL) { if (l == NULL) {
l = list_create(); l = gwlist_create();
dict_put(cfg->grps, value, l); dict_put(cfg->grps, value, l);
} }
list_append(l, grp); gwlist_append(l, grp);
} else if (dict_put_once(cfg->grps, value, grp) == 0) } else if (dict_put_once(cfg->grps, value, grp) == 0)
panic(0, "Group `%s' [at line %d] cannot appear more " panic(0, "Group `%s' [at line %d] cannot appear more "
"than once in config!", "than once in config!",
@ -207,7 +207,7 @@ mCfg *mms_cfg_read(Octstr *file)
panic(0, "mal-formed entry in conf file at line %d!", i+1); panic(0, "mal-formed entry in conf file at line %d!", i+1);
} }
list_destroy(lines, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(lines, (gwlist_item_destructor_t *)octstr_destroy);
octstr_destroy(sf); octstr_destroy(sf);
return cfg; return cfg;
} }
@ -226,18 +226,18 @@ void mms_cfg_destroy(mCfg *cfg)
gw_assert(cfg); gw_assert(cfg);
for (i = 0, l = dict_keys(cfg->grps), n = list_len(l); i < n; i++) { for (i = 0, l = dict_keys(cfg->grps), n = gwlist_len(l); i < n; i++) {
Octstr *grpname = list_get(l, i); Octstr *grpname = gwlist_get(l, i);
void *val = dict_get(cfg->grps, grpname); void *val = dict_get(cfg->grps, grpname);
if (is_multigroup(grpname)) { if (is_multigroup(grpname)) {
List *gl = val; List *gl = val;
int j, m = list_len(gl); int j, m = gwlist_len(gl);
for (j = 0; j < m; j++) for (j = 0; j < m; j++)
mGrp_destroy(list_get(gl, j)); mGrp_destroy(gwlist_get(gl, j));
} else } else
mGrp_destroy(val); mGrp_destroy(val);
} }
list_destroy(l, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
dict_destroy(cfg->grps); dict_destroy(cfg->grps);
octstr_destroy(cfg->file); octstr_destroy(cfg->file);
gw_free(cfg); gw_free(cfg);
@ -262,8 +262,8 @@ List *mms_cfg_get_multi(mCfg *cfg, Octstr *name)
r = dict_get(cfg->grps, name); r = dict_get(cfg->grps, name);
if (r) if (r)
for (i = 0, l = list_create(); i < list_len(r); i++) for (i = 0, l = gwlist_create(); i < gwlist_len(r); i++)
list_append(l, list_get(r,i)); gwlist_append(l, gwlist_get(r,i));
return l; return l;
} }

View File

@ -101,7 +101,7 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent)
/* look at each node in turn, extract meaning. /* look at each node in turn, extract meaning.
* we ignore some tags: senderidentification, etc because we don't need them. * we ignore some tags: senderidentification, etc because we don't need them.
* we are also not strict on syntax (when receiving): we will be on sending! * we are also not strict on syntax (when receiving): we will be on sending!
*/ */
hname = (char *)node->name; hname = (char *)node->name;
@ -228,31 +228,26 @@ static int parse_headers(xmlNodePtr start, List *h, int sigparent)
MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body) MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
{ {
MIMEEntity *mime = mime_http_to_entity(headers, body); MIMEEntity *mime = mime_http_to_entity(headers, body), *start = NULL;
Octstr *xml = NULL, *cloc; Octstr *xml = NULL, *cloc;
xmlDocPtr doc; xmlDocPtr doc;
MIMEEntity *msg = NULL; MIMEEntity *msg = NULL;
List *h; List *h;
int s = -1; int s = -1;
MSoapMsg_t *smsg = NULL; MSoapMsg_t *smsg = NULL;
if (!mime) if (!mime)
return NULL; return NULL;
/* Find the start element: /* Find the start element:
* - either the mime entity is multipart and has start param ... * - either the mime entity is multipart and has start param (or implicitly first element) ...
* - or entity is multipart and start element is (implicitly) first element
* - or entity is not multipart, so body is xml * - or entity is not multipart, so body is xml
*/ */
if (mime->start) if ((start = mime_multipart_start_elem(mime)) != NULL)
xml = mime->start->body; xml = mime_entity_body(start);
else if (mime->multiparts && list_len(mime->multiparts) > 0) { else
MIMEEntity *x = list_get(mime->multiparts,0); xml = mime_entity_body(mime);
xml = x->body;
} else
xml = mime->body;
/* Don't free 'xml'! It is part of mime object. */
if (!xml) if (!xml)
goto done; goto done;
#if 1 #if 1
@ -277,24 +272,26 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
MIMEEntity *c = NULL; MIMEEntity *c = NULL;
int i, n; int i, n;
char *loc = octstr_get_cstr(cloc) + 4; /* skip 'cid:' part. */ char *loc = octstr_get_cstr(cloc) + 4; /* skip 'cid:' part. */
for (i = 0, n = list_len(mime->multiparts); i<n; i++) { for (i = 0, n = mime_entity_num_parts(mime); i<n; i++) {
MIMEEntity *x = list_get(mime->multiparts, i); MIMEEntity *x = mime_entity_get_part(mime, i);
Octstr *y = x ? http_header_value(x->headers, octstr_imm("Content-ID")) : NULL; List *headers = _x_mime_entity_headers(x);
Octstr *y = headers ? http_header_value(headers, octstr_imm("Content-ID")) : NULL;
char *cid = (y && octstr_get_char(y, 0) == '<') ? octstr_get_cstr(y) + 1 : (y ? octstr_get_cstr(y) : ""); char *cid = (y && octstr_get_char(y, 0) == '<') ? octstr_get_cstr(y) + 1 : (y ? octstr_get_cstr(y) : "");
int cid_len = (y && octstr_get_char(y, 0) == '<') ? octstr_len(y) - 2 : (y ? octstr_len(y) : 0); int cid_len = (y && octstr_get_char(y, 0) == '<') ? octstr_len(y) - 2 : (y ? octstr_len(y) : 0);
if (y && strncmp(loc, cid, cid_len) == 0) if (y && strncmp(loc, cid, cid_len) == 0)
c = x; c = mime_entity_duplicate(x);
if (y) if (y)
octstr_destroy(y); octstr_destroy(y);
http_destroy_headers(headers);
mime_entity_destroy(x);
if (c) if (c)
break; break;
} }
if (c) if (c)
msg = mime_entity_duplicate(c); msg = c; /* this is already a copy. */
octstr_destroy(cloc); octstr_destroy(cloc);
} }
smsg = gw_malloc(sizeof *smsg); smsg = gw_malloc(sizeof *smsg);
@ -304,6 +301,10 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
done: done:
if (mime) if (mime)
mime_entity_destroy(mime); mime_entity_destroy(mime);
if (start)
mime_entity_destroy(start);
if (xml)
octstr_destroy(xml);
return smsg; return smsg;
} }
@ -333,7 +334,7 @@ static void output_rcpt(char *hdr, List *hdrs, Octstr *p)
char x[32]; char x[32];
int i, n; int i, n;
for (i = 0, n = list_len(l), x[0]=0; i < n; i++) { for (i = 0, n = gwlist_len(l), x[0]=0; i < n; i++) {
Octstr *h = NULL, *v = NULL; Octstr *h = NULL, *v = NULL;
http_header_get(l, i, &h, &v); http_header_get(l, i, &h, &v);
@ -450,7 +451,7 @@ Octstr *headers_to_soapxml(List *hdrs)
/* cycle through rest of headers. */ /* cycle through rest of headers. */
for (i = 0, n = list_len(hdrs); i < n; i++) { for (i = 0, n = gwlist_len(hdrs); i < n; i++) {
Octstr *h = NULL, *v = NULL; Octstr *h = NULL, *v = NULL;
char *zz; char *zz;
int tag; int tag;
@ -568,8 +569,9 @@ Octstr *headers_to_soapxml(List *hdrs)
int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body) int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
{ {
MIMEEntity *mime; MIMEEntity *mime;
Octstr *ctype; Octstr *ctype, *s;
List *headers;
mime = mime_entity_create(); mime = mime_entity_create();
if (m->msg) { if (m->msg) {
@ -585,21 +587,31 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
'a' + random() % 26); 'a' + random() % 26);
MIMEEntity *xml = mime_entity_create(); MIMEEntity *xml = mime_entity_create();
List *hh = http_header_duplicate(m->envelope); List *hh = http_header_duplicate(m->envelope);
List *hx;
/* Replace in envelope. */ /* Replace in envelope. */
http_header_remove_all(hh, "Content"); http_header_remove_all(hh, "Content");
http_header_add(hh, "Content", octstr_get_cstr(cloc)); http_header_add(hh, "Content", octstr_get_cstr(cloc));
/* Replace content location in msg part. */ /* Replace content location in msg part. */
http_header_remove_all(c->headers, "Content-ID"); hx = _x_mime_entity_headers(c);
http_header_add(c->headers, "Content-ID", octstr_get_cstr(cloc_str)); http_header_remove_all(hx, "Content-ID");
http_header_add(hx, "Content-ID", octstr_get_cstr(cloc_str));
http_header_add(xml->headers, "Content-Type", "\"text/xml\""); mime_replace_headers(c, hx);
http_header_add(xml->headers, "Content-ID", octstr_get_cstr(envloc)); http_destroy_headers(hx);
xml->body = headers_to_soapxml(hh);
list_append(mime->multiparts, xml); hx = http_create_empty_headers();
list_append(mime->multiparts, c); http_header_add(hx, "Content-Type", "\"text/xml\"");
http_header_add(hx, "Content-ID", octstr_get_cstr(envloc));
mime_replace_headers(xml, hx);
http_destroy_headers(hx);
s = headers_to_soapxml(hh);
mime_entity_set_body(xml, s);
octstr_destroy(s);
mime_entity_add_part(mime, xml);
mime_entity_add_part(mime, c);
http_destroy_headers(hh); http_destroy_headers(hh);
@ -608,16 +620,25 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
octstr_destroy(envloc); octstr_destroy(envloc);
octstr_destroy(cloc); octstr_destroy(cloc);
octstr_destroy(cloc_str); octstr_destroy(cloc_str);
mime_entity_destroy(xml);
mime_entity_destroy(c);
} else { } else {
ctype = octstr_imm("\"text/xml\""); ctype = octstr_imm("\"text/xml\"");
mime->body = headers_to_soapxml(m->envelope); s = headers_to_soapxml(m->envelope);
mime_entity_set_body(mime,s);
octstr_destroy(s);
} }
http_header_add(mime->headers, "Content-Type", octstr_get_cstr(ctype)); headers = http_create_empty_headers();
http_header_add(mime->headers, "SOAPAction", "\"some-url\""); http_header_add(headers, "Content-Type", octstr_get_cstr(ctype));
http_header_add(headers, "SOAPAction", "\"some-url\"");
mime_entity_body_and_headers(mime, body, hdrs); mime_replace_headers(mime, headers);
http_destroy_headers(headers);
*body = mime_entity_body(mime);
*hdrs = _x_mime_entity_headers(mime);
mime_entity_destroy(mime); mime_entity_destroy(mime);
@ -645,14 +666,14 @@ static int get_rcptvalues(List *to, List *headers, char *hname)
l = http_header_find_all(headers, hname); l = http_header_find_all(headers, hname);
for (i = 0, n = (l) ? list_len(l) : 0; i < n; i++) { for (i = 0, n = (l) ? gwlist_len(l) : 0; i < n; i++) {
Octstr *h, *v; Octstr *h, *v;
int ch; int ch;
http_header_get(l, i, &h, &v); http_header_get(l, i, &h, &v);
ch = octstr_get_char(v, 0); ch = octstr_get_char(v, 0);
if (ch == '+') if (ch == '+')
list_append(to, octstr_copy(v, 2, octstr_len(v))); gwlist_append(to, octstr_copy(v, 2, octstr_len(v)));
octstr_destroy(h); octstr_destroy(h);
octstr_destroy(v); octstr_destroy(v);
} }
@ -670,7 +691,7 @@ int mm7_get_envelope(MSoapMsg_t *m,
Octstr *s; Octstr *s;
if (*to == NULL) if (*to == NULL)
*to = list_create(); *to = gwlist_create();
get_rcptvalues(*to, m->envelope, "To"); get_rcptvalues(*to, m->envelope, "To");
get_rcptvalues(*to, m->envelope, "Cc"); get_rcptvalues(*to, m->envelope, "Cc");
@ -730,7 +751,7 @@ MmsMsg *mm7_soap_to_mmsmsg(MSoapMsg_t *m, Octstr *from)
if (!msg) if (!msg)
break; break;
mms_remove_headers(msg, "Content-ID"); /* not necessary, but... */
/* Put in some headers... */ /* Put in some headers... */
if (from) if (from)
mms_replace_header_value(msg, "From", octstr_get_cstr(from)); mms_replace_header_value(msg, "From", octstr_get_cstr(from));
@ -784,15 +805,15 @@ MmsMsg *mm7_soap_to_mmsmsg(MSoapMsg_t *m, Octstr *from)
} }
/* Put in recipient list. XXX - really?? */ /* Put in recipient list. XXX - really?? */
l = list_create(); l = gwlist_create();
get_rcptvalues(l, m->envelope, "To"); get_rcptvalues(l, m->envelope, "To");
mms_replace_header_values(msg, "To", l); mms_replace_header_values(msg, "To", l);
list_destroy(l, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
l = list_create(); l = gwlist_create();
get_rcptvalues(l, m->envelope, "Cc"); get_rcptvalues(l, m->envelope, "Cc");
mms_replace_header_values(msg, "Cc", l); mms_replace_header_values(msg, "Cc", l);
list_destroy(l, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
/* XXX - we ignore reply charging, etc. */ /* XXX - we ignore reply charging, etc. */
break; break;
@ -877,7 +898,8 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
Octstr *s; Octstr *s;
int i, n; int i, n;
Octstr *xfrom; Octstr *xfrom;
List *headers;
xfrom = octstr_format("+ %S", from ? from : octstr_imm("anon@anon")); xfrom = octstr_format("+ %S", from ? from : octstr_imm("anon@anon"));
switch(mtype) { switch(mtype) {
case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_SEND_REQ:
@ -886,8 +908,8 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
transid); transid);
m->msg = mms_tomime(msg,1); m->msg = mms_tomime(msg,1);
for (i = 0, n = xto ? list_len(xto) : 0; i < n; i++) { /* Add recipients. */ for (i = 0, n = xto ? gwlist_len(xto) : 0; i < n; i++) { /* Add recipients. */
Octstr *xx = octstr_format("+ %S", list_get(xto, i)); Octstr *xx = octstr_format("+ %S", gwlist_get(xto, i));
http_header_add(m->envelope, "To", http_header_add(m->envelope, "To",
octstr_get_cstr(xx)); octstr_get_cstr(xx));
octstr_destroy(xx); octstr_destroy(xx);
@ -952,13 +974,16 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
} }
/* Should we bother to strip message part of headers??? */ /* Should we bother to strip message part of headers??? */
http_header_remove_all(m->msg->headers, "Subject"); headers = _x_mime_entity_headers(m->msg);
http_header_remove_all(m->msg->headers, "X-Mms-Message-Type"); http_header_remove_all(headers, "Subject");
http_header_remove_all(m->msg->headers, "X-Mms-Message-Version"); http_header_remove_all(headers, "X-Mms-Message-Type");
http_header_remove_all(m->msg->headers, "From"); http_header_remove_all(headers, "X-Mms-Message-Version");
http_header_remove_all(m->msg->headers, "To"); http_header_remove_all(headers, "From");
http_header_remove_all(m->msg->headers, "Cc"); http_header_remove_all(headers, "To");
http_header_remove_all(m->msg->headers, "Bcc"); http_header_remove_all(headers, "Cc");
http_header_remove_all(headers, "Bcc");
mime_replace_headers(m->msg, headers);
http_destroy_headers(headers);
break; break;
case MMS_MSGTYPE_READ_ORIG_IND: case MMS_MSGTYPE_READ_ORIG_IND:
case MMS_MSGTYPE_DELIVERY_IND: case MMS_MSGTYPE_DELIVERY_IND:
@ -968,8 +993,8 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
http_header_add(m->envelope, "Sender", octstr_get_cstr(xfrom)); http_header_add(m->envelope, "Sender", octstr_get_cstr(xfrom));
if (xto && list_len(xto) > 0) { if (xto && gwlist_len(xto) > 0) {
Octstr *xx = octstr_format("+ %S", list_get(xto, 0)); Octstr *xx = octstr_format("+ %S", gwlist_get(xto, 0));
http_header_add(m->envelope, "To", http_header_add(m->envelope, "To",
octstr_get_cstr(xx)); octstr_get_cstr(xx));
octstr_destroy(xx); octstr_destroy(xx);

View File

@ -215,8 +215,8 @@ static Octstr *linearise_string_list(List *l, char *sep)
Octstr *s = octstr_create(""); Octstr *s = octstr_create("");
for (i = 0, n = list_len(l); i < n; i++) { for (i = 0, n = gwlist_len(l); i < n; i++) {
Octstr *p = list_get(l,i); Octstr *p = gwlist_get(l,i);
if (p) if (p)
octstr_format_append(s, "%s%S", (i == 0) ? "" : sep, p); octstr_format_append(s, "%s%S", (i == 0) ? "" : sep, p);
} }
@ -227,10 +227,10 @@ static List *parse_string_list(char *buf)
{ {
int i = 0; int i = 0;
char sbuf[128], *p = buf; char sbuf[128], *p = buf;
List *l = list_create(); List *l = gwlist_create();
while (sscanf(p, "%s%n", sbuf, &i) > 0) { while (sscanf(p, "%s%n", sbuf, &i) > 0) {
list_append(l, octstr_create(sbuf)); gwlist_append(l, octstr_create(sbuf));
p += i; p += i;
} }
@ -341,19 +341,19 @@ static int update_mmbox_index(int fd, char *mmbox_dir, int cmd,
static List *make_mm_flags(List *oflags, List *flag_cmds) static List *make_mm_flags(List *oflags, List *flag_cmds)
{ {
List *l = oflags ? oflags : list_create(); List *l = oflags ? oflags : gwlist_create();
int i, n; int i, n;
for (i = 0, n = list_len(l); i < n; i++) { /* cleanup list. */ for (i = 0, n = gwlist_len(l); i < n; i++) { /* cleanup list. */
Octstr *x = list_get(l,i); Octstr *x = gwlist_get(l,i);
int ch = octstr_get_char(x, 0); int ch = octstr_get_char(x, 0);
if (ch == '+' || ch == '-' || ch == '/') if (ch == '+' || ch == '-' || ch == '/')
octstr_delete(x,0,1); octstr_delete(x,0,1);
} }
for (i = 0, n = (flag_cmds ? list_len(flag_cmds) : 0); i<n; i++) { for (i = 0, n = (flag_cmds ? gwlist_len(flag_cmds) : 0); i<n; i++) {
Octstr *x = list_get(flag_cmds,i); Octstr *x = gwlist_get(flag_cmds,i);
int ch = octstr_get_char(x, 0); int ch = octstr_get_char(x, 0);
char *s = octstr_get_cstr(x); char *s = octstr_get_cstr(x);
int j, m, cmd; int j, m, cmd;
@ -365,17 +365,17 @@ static List *make_mm_flags(List *oflags, List *flag_cmds)
cmd = '+'; cmd = '+';
/* Find it in original. If existent, remove it. */ /* Find it in original. If existent, remove it. */
for (j = 0, m = list_len(l); j < m; j++) for (j = 0, m = gwlist_len(l); j < m; j++)
if (octstr_str_compare(list_get(l,j),s) == 0) { if (octstr_str_compare(gwlist_get(l,j),s) == 0) {
Octstr *y = list_get(l,j); Octstr *y = gwlist_get(l,j);
list_delete(l,j,1); gwlist_delete(l,j,1);
octstr_destroy(y); octstr_destroy(y);
j--; j--;
m--; m--;
} }
if (cmd == '+' || cmd == '/') if (cmd == '+' || cmd == '/')
list_append(l, octstr_create(s)); gwlist_append(l, octstr_create(s));
} }
@ -444,7 +444,7 @@ Octstr *mms_mmbox_addmsg(char *mmbox_root, char *user, MmsMsg *msg, List *flag_c
if (state) if (state)
octstr_destroy(state); octstr_destroy(state);
if (flags) if (flags)
list_destroy(flags, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy);
return sdf; return sdf;
} }
@ -546,7 +546,7 @@ int mms_mmbox_modmsg(char *mmbox_root, char *user, Octstr *msgref,
if (nstate) if (nstate)
octstr_destroy(nstate); octstr_destroy(nstate);
if (flags) if (flags)
list_destroy(flags, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy);
if (m) if (m)
mms_destroy(m); mms_destroy(m);
return res; return res;
@ -604,8 +604,8 @@ static int string_in_list(Octstr *s, List *l)
{ {
int i, n; int i, n;
for (i = 0, n = list_len(l); i<n; i++) { for (i = 0, n = gwlist_len(l); i<n; i++) {
Octstr *x = list_get(l,i); Octstr *x = gwlist_get(l,i);
char *p = octstr_get_cstr(x); char *p = octstr_get_cstr(x);
if (p[0] == '+' || if (p[0] == '+' ||
@ -662,42 +662,42 @@ List *mms_mmbox_search(char *mmbox_root, char *user,
flags = make_mm_flags(NULL, flag_cmds); flags = make_mm_flags(NULL, flag_cmds);
ct = 1; ct = 1;
dflist = list_create(); dflist = gwlist_create();
while (fgets(linbuf, sizeof linbuf, fp) != NULL) { while (fgets(linbuf, sizeof linbuf, fp) != NULL) {
char idx[128], xstate[32]; char idx[128], xstate[32];
List *xflags = NULL; List *xflags = NULL;
int i, size; int i, size;
int match = (!state && (!msgrefs || list_len(msgrefs) == 0) && (!xflags || list_len(xflags) == 0)); int match = (!state && (!msgrefs || gwlist_len(msgrefs) == 0) && (!xflags || gwlist_len(xflags) == 0));
sscanf(linbuf, "%s %s %d%n", idx, xstate, &size, &i); sscanf(linbuf, "%s %s %d%n", idx, xstate, &size, &i);
/* search: by id list if given, by states if given, by flags if given */ /* search: by id list if given, by states if given, by flags if given */
if (!match && state && list_search(state, xstate, if (!match && state && gwlist_search(state, xstate,
(list_item_matches_t *)_x_octstr_str_compare) != NULL) (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL)
match = 1; match = 1;
/* For the rest we only match if nothing else matched. Save time */ /* For the rest we only match if nothing else matched. Save time */
replace_slash(idx); replace_slash(idx);
if (!match && msgrefs && if (!match && msgrefs &&
list_search(msgrefs, idx, gwlist_search(msgrefs, idx,
(list_item_matches_t *)_x_octstr_str_compare) != NULL) (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL)
match = 1; match = 1;
if (!match && if (!match &&
flag_cmds && flag_cmds &&
((xflags = parse_string_list(linbuf + i)) != NULL && ((xflags = parse_string_list(linbuf + i)) != NULL &&
list_search(xflags, flags, (list_item_matches_t *)string_in_list) != NULL)) gwlist_search(xflags, flags, (gwlist_item_matches_t *)string_in_list) != NULL))
match = 1; match = 1;
if (match && ct >= start && list_len(dflist) <= limit) { if (match && ct >= start && gwlist_len(dflist) <= limit) {
Octstr *x = octstr_create(idx); Octstr *x = octstr_create(idx);
/* octstr_replace(x, octstr_imm("/"), octstr_imm("-")); */ /* octstr_replace(x, octstr_imm("/"), octstr_imm("-")); */
list_append(dflist, x); gwlist_append(dflist, x);
} }
ct++; ct++;
if (xflags) if (xflags)
list_destroy(xflags, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy);
} }
done: done:
@ -710,7 +710,7 @@ List *mms_mmbox_search(char *mmbox_root, char *user,
close(ifd); close(ifd);
if (flags) if (flags)
list_destroy(flags, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy);
if (home) if (home)
octstr_destroy(home); octstr_destroy(home);

View File

@ -31,10 +31,11 @@ struct MmsMsg {
#define SIZHINT 47 #define SIZHINT 47
static void mm_destroy(MIMEEntity *mx);
static int encode_msgheaders(Octstr *os, List *hdrs); static int encode_msgheaders(Octstr *os, List *hdrs);
static int decode_msgheaders(ParseContext *context, List *hdr, Octstr *from, int stop_on_ctype); static int decode_msgheaders(ParseContext *context, List *hdr, Octstr *from, int stop_on_ctype);
static inline void pack_short_integer(Octstr *s, int ch) static inline void pack_short_integer(Octstr *s, int ch)
{ {
unsigned long c = ((unsigned)ch)&0x7f; unsigned long c = ((unsigned)ch)&0x7f;
@ -90,13 +91,13 @@ static int decode_multipart(ParseContext *context, List *body)
for (i = 0; i<n && parse_octets_left(context) > 0 ; i++) { for (i = 0; i<n && parse_octets_left(context) > 0 ; i++) {
int dlen, hlen; int dlen, hlen;
MIMEEntity *x = gw_malloc(sizeof *x); MIMEEntity *x = mime_entity_create();
List *headers;
Octstr *hs; Octstr *hs;
Octstr *content; Octstr *content;
Octstr *content_type; Octstr *content_type;
memset(x, 0,sizeof *x);
hlen = parse_get_uintvar(context); hlen = parse_get_uintvar(context);
dlen = parse_get_uintvar(context); dlen = parse_get_uintvar(context);
@ -105,23 +106,32 @@ static int decode_multipart(ParseContext *context, List *body)
hs = parse_get_octets(context, parse_octets_left(context)); hs = parse_get_octets(context, parse_octets_left(context));
x->headers = wsp_headers_unpack(hs, 1); headers = wsp_headers_unpack(hs, 1);
octstr_destroy(hs); octstr_destroy(hs);
strip_boundary_element(headers,NULL);
mime_replace_headers(x, headers);
parse_skip_to_limit(context); parse_skip_to_limit(context);
parse_pop_limit(context); parse_pop_limit(context);
content_type = http_header_value(x->headers, octstr_imm("Content-Type")); content_type = http_header_value(headers, octstr_imm("Content-Type"));
content = parse_get_octets(context, dlen); content = parse_get_octets(context, dlen);
http_destroy_headers(headers);
if (!content || !content_type) { if (!content || !content_type) {
int pleft = parse_octets_left(context); int pleft = parse_octets_left(context);
warning(0, "Parse error reading mime body [hlen=%d, dlen=%d, left=%d]!",hlen,dlen, pleft); warning(0, "Parse error reading mime body [hlen=%d, dlen=%d, left=%d]!",
hlen,dlen, pleft);
mime_entity_destroy(x); mime_entity_destroy(x);
if (content_type) octstr_destroy(content_type); if (content_type)
octstr_destroy(content_type);
if (content)
octstr_destroy(content);
return -1; return -1;
} }
if (octstr_case_compare(content_type, if (octstr_case_compare(content_type,
octstr_imm("application/vnd.wap.multipart.related")) == 0 || octstr_imm("application/vnd.wap.multipart.related")) == 0 ||
octstr_case_compare(content_type, octstr_case_compare(content_type,
@ -129,46 +139,65 @@ static int decode_multipart(ParseContext *context, List *body)
octstr_case_compare(content_type, octstr_case_compare(content_type,
octstr_imm("application/vnd.wap.multipart.mixed")) == 0) { /* Body is multipart. */ octstr_imm("application/vnd.wap.multipart.mixed")) == 0) { /* Body is multipart. */
ParseContext *p = parse_context_create(content); ParseContext *p = parse_context_create(content);
int res; List *ml = gwlist_create();
List *ml = x->multiparts = list_create(); int res = decode_multipart(p, ml);
res = decode_multipart(p, x->multiparts);
octstr_destroy(content);
parse_context_destroy(p);
parse_context_destroy(p);
if (res == 0) {
/* Put body parts into mime object. */
int j, m = gwlist_len(ml);
for (j = 0; j < m; j++)
mime_entity_add_part(x, gwlist_get(ml,i));
}
gwlist_destroy(ml, (gwlist_item_destructor_t *)mime_entity_destroy);
if (res < 0) { if (res < 0) {
list_destroy(ml, (list_item_destructor_t *)mime_entity_destroy); if (content_type)
octstr_destroy(content_type);
if (content)
octstr_destroy(content);
return -1; return -1;
} }
} else } else
x->body = content; mime_entity_set_body(x,content);
octstr_destroy(content);
octstr_destroy(content_type); octstr_destroy(content_type);
gwlist_append(body, x);
list_append(body, x);
} }
return 0; return 0;
} }
static int encode_multipart(Octstr *os, List *body) static int encode_multipart(Octstr *os, List *body)
{ {
int i, n; int i, j, n, m;
n = list_len(body); n = gwlist_len(body);
octstr_append_uintvar(os, n); octstr_append_uintvar(os, n);
i = 0; i = 0;
while (i<n) { while (i<n) {
Octstr *mhdr, *mbody = octstr_create(""); Octstr *mhdr, *mbody = octstr_create("");
MIMEEntity *x = list_get(body, i); MIMEEntity *x = gwlist_get(body, i);
List *headers = _x_mime_entity_headers(x);
Octstr *s;
strip_boundary_element(headers,NULL);
mhdr = wsp_headers_pack(headers, 1, WSP_1_3);
http_destroy_headers(headers);
mhdr = wsp_headers_pack(x->headers, 1, WSP_1_3); if ((m = mime_entity_num_parts(x)) > 0) { /* This is a multi-part,
* go down further.
if (x->multiparts && */
list_len(x->multiparts) > 0) /* This is a multi-part, go down further. */ List *l = gwlist_create();
encode_multipart(mbody, x->multiparts);
else if (x->body) for (j = 0; j < m; j++)
octstr_append(mbody, x->body); gwlist_append(l, mime_entity_get_part(x, j));
encode_multipart(mbody, l);
gwlist_destroy(l, (gwlist_item_destructor_t *)mime_entity_destroy);
} else if ((s = mime_entity_body(x)) != NULL) {
octstr_append(mbody, s);
octstr_destroy(s);
}
octstr_append_uintvar(os, octstr_len(mhdr)); octstr_append_uintvar(os, octstr_len(mhdr));
octstr_append_uintvar(os, octstr_len(mbody)); octstr_append_uintvar(os, octstr_len(mbody));
@ -188,7 +217,7 @@ static int decode_msgbody(ParseContext *context, MmsMsg *msg)
{ {
int res = 0; int res = 0;
if (msg->ismultipart) { if (msg->ismultipart) {
msg->body.l = list_create(); msg->body.l = gwlist_create();
res = decode_multipart(context, msg->body.l); res = decode_multipart(context, msg->body.l);
} else } else
msg->body.s = parse_get_rest(context); msg->body.s = parse_get_rest(context);
@ -863,7 +892,7 @@ static void mms_pack_well_known_field(Octstr *os, int field_type, Octstr *value)
params = get_value_parameters(cpar); params = get_value_parameters(cpar);
wsp_pack_text(encoded, cv); wsp_pack_text(encoded, cv);
n = list_len(params); n = gwlist_len(params);
for (i = 0; i<n; i++) { for (i = 0; i<n; i++) {
Octstr *h, *v; Octstr *h, *v;
@ -903,10 +932,11 @@ static void mms_pack_well_known_field(Octstr *os, int field_type, Octstr *value)
static int encode_msgheaders(Octstr *os, List *hdrs) static int encode_msgheaders(Octstr *os, List *hdrs)
{ {
int fcont = 1; int fcont = 1;
int i, l = list_len(hdrs), mtype; int i, l = gwlist_len(hdrs), mtype;
Octstr *msgtype = NULL, *transid = NULL, *version = NULL, *ctype; Octstr *msgtype = NULL, *transid = NULL, *version = NULL, *ctype;
strip_boundary_element(hdrs,NULL);
/* First ensure that top headers are in place. */ /* First ensure that top headers are in place. */
version = http_header_value(hdrs, version = http_header_value(hdrs,
@ -987,7 +1017,7 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION); http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
} else if (octstr_str_compare(ver, "1.2") <= 0) } else if (octstr_str_compare(ver, "1.2") <= 0)
m->enc = MS_1_2; m->enc = MS_1_2;
http_header_remove_all(m->headers, "MIME-Version");
if (m->message_type == MMS_MSGTYPE_SEND_REQ || if (m->message_type == MMS_MSGTYPE_SEND_REQ ||
m->message_type == MMS_MSGTYPE_RETRIEVE_CONF) { m->message_type == MMS_MSGTYPE_RETRIEVE_CONF) {
Octstr *s = NULL; Octstr *s = NULL;
@ -1030,7 +1060,8 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
} else } else
octstr_destroy(s); octstr_destroy(s);
} }
strip_boundary_element(m->headers, NULL); /* remove top-level boundary element if any. */
return 0; return 0;
} }
@ -1053,11 +1084,11 @@ MmsMsg *mms_frombinary(Octstr *msg, Octstr *from)
p = parse_context_create(msg); p = parse_context_create(msg);
mms_strings_init(); /* Just in case. */ mms_strings_init(); /* Just in case. */
_m.headers = list_create(); _m.headers = gwlist_create();
decode_msgheaders(p, _m.headers, from, 1); decode_msgheaders(p, _m.headers, from, 1);
if (_m.headers == NULL || if (_m.headers == NULL ||
list_len(_m.headers) == 0) gwlist_len(_m.headers) == 0)
goto done; goto done;
/* Get the message type and also set flag for whether multipart.*/ /* Get the message type and also set flag for whether multipart.*/
@ -1094,7 +1125,7 @@ MmsMsg *mms_frombinary(Octstr *msg, Octstr *from)
MmsMsg *msg = &_m; MmsMsg *msg = &_m;
if (msg->ismultipart && msg->body.l) if (msg->ismultipart && msg->body.l)
list_destroy(msg->body.l, (list_item_destructor_t *)mm_destroy); gwlist_destroy(msg->body.l, (gwlist_item_destructor_t *)mime_entity_destroy);
else if (msg->body.s) else if (msg->body.s)
octstr_destroy(msg->body.s); octstr_destroy(msg->body.s);
@ -1108,17 +1139,29 @@ MmsMsg *mms_frombinary(Octstr *msg, Octstr *from)
static void _x_mime_entity_dump(MIMEEntity *x, int level, int headers_only) static void _x_mime_entity_dump(MIMEEntity *x, int level, int headers_only)
{ {
int i, n, ism; int i,m, ism;
List *h;
ism = (x->multiparts && list_len(x->multiparts) > 0) ? 1 : 0; Octstr *body;
debug("part.dump", 0, "%sMultipart -> ", ism ? "" : "Not ");
http_header_dump(x->headers);
ism = ((m = mime_entity_num_parts(x)) > 0);
debug("part.dump", 0, "%sMultipart -> ", ism ? "" : "Not ");
h = _x_mime_entity_headers(x);
strip_boundary_element(h,NULL);
http_header_dump(h);
http_destroy_headers(h);
if (ism) if (ism)
for (i = 0, n = list_len(x->multiparts); i<n; i++) for (i = 0; i<m; i++) {
_x_mime_entity_dump(list_get(x->multiparts, i), level+1, headers_only); MIMEEntity *xm = mime_entity_get_part(x, i);
else if (x->body && !headers_only) _x_mime_entity_dump(xm, level+1, headers_only);
octstr_dump(x->body, level); mime_entity_destroy(xm);
}
else if ((body = mime_entity_body(x)) != NULL) {
if (!headers_only)
octstr_dump(body, level);
octstr_destroy(body);
}
} }
void mms_msgdump(MmsMsg *m, int headers_only) void mms_msgdump(MmsMsg *m, int headers_only)
@ -1131,17 +1174,17 @@ void mms_msgdump(MmsMsg *m, int headers_only)
debug("mms.dump", 0, "Dumping MMS message body (%s) [%ld parts] --> ", debug("mms.dump", 0, "Dumping MMS message body (%s) [%ld parts] --> ",
m->ismultipart ? "mulitpart" : "not multipart", m->ismultipart ? "mulitpart" : "not multipart",
m->ismultipart ? list_len(m->body.l) : 0); m->ismultipart ? gwlist_len(m->body.l) : 0);
if (m->ismultipart) if (m->ismultipart)
for (i = 0, n = list_len(m->body.l); i< n; i++) { for (i = 0, n = gwlist_len(m->body.l); i< n; i++) {
MIMEEntity *x = list_get(m->body.l, i); MIMEEntity *x = gwlist_get(m->body.l, i);
debug("mms.dump", 0, "--->Message part: %d --->", i); debug("mms.dump", 0, "--->Message part: %d --->", i);
_x_mime_entity_dump(x,0,headers_only); _x_mime_entity_dump(x,0,headers_only);
} }
else if (!headers_only) else if (!headers_only)
octstr_dump(m->body.s, 0); octstr_dump(m->body.s, 0);
} }
@ -1171,8 +1214,9 @@ static void convert_mime_msg(MIMEEntity *m)
int i, n; int i, n;
Octstr *content_type, *params; Octstr *content_type, *params;
char *s = NULL; char *s = NULL;
List *h = _x_mime_entity_headers(m);
get_content_type(m->headers, &content_type, &params);
get_content_type(h, &content_type, &params);
if (content_type) { if (content_type) {
if (octstr_str_compare(content_type, if (octstr_str_compare(content_type,
@ -1187,24 +1231,25 @@ static void convert_mime_msg(MIMEEntity *m)
octstr_destroy(content_type); octstr_destroy(content_type);
} }
if (s) { if (s) {
Octstr *value; Octstr *value = (params && octstr_len(params) > 0) ?
octstr_format("%s; %S", s, params) : octstr_create(s);
value = (params && octstr_len(params) > 0) ?
octstr_format("%s; %S", s, params) : octstr_create(s);
http_header_remove_all(m->headers, "Content-Type");
http_header_add(m->headers, "Content-Type", octstr_get_cstr(value));
http_header_remove_all(h, "Content-Type");
http_header_add(h, "Content-Type", octstr_get_cstr(value));
mime_replace_headers(m,h);
octstr_destroy(value); octstr_destroy(value);
} }
if (h)
http_destroy_headers(h);
if (params) if (params)
octstr_destroy(params); octstr_destroy(params);
if (m->multiparts) if ((n = mime_entity_num_parts(m)) > 0)
for (i = 0, n = list_len(m->multiparts); i < n; i++) for (i = 0; i < n; i++) {
convert_mime_msg(list_get(m->multiparts, i)); MIMEEntity *x = mime_entity_get_part(m, i);
convert_mime_msg(x);
mime_entity_replace_part(m, i, x);
}
} }
static void unconvert_mime_msg(MIMEEntity *m) static void unconvert_mime_msg(MIMEEntity *m)
@ -1212,8 +1257,9 @@ static void unconvert_mime_msg(MIMEEntity *m)
int i, n; int i, n;
Octstr *content_type, *params; Octstr *content_type, *params;
char *s = NULL; char *s = NULL;
List *h = _x_mime_entity_headers(m);
get_content_type(m->headers, &content_type, &params); get_content_type(h, &content_type, &params);
if (content_type) { if (content_type) {
if (octstr_case_compare(content_type, if (octstr_case_compare(content_type,
@ -1227,35 +1273,21 @@ static void unconvert_mime_msg(MIMEEntity *m)
s = "application/vnd.wap.multipart.mixed"; s = "application/vnd.wap.multipart.mixed";
octstr_destroy(content_type); octstr_destroy(content_type);
} }
if (s) {
Octstr *value;
if (params) {
List *h = get_value_parameters(params);
Octstr *ps;
http_header_remove_all(h,"boundary"); /* We don't need the boundary param if it is there. */
ps = make_value_parameters(h);
value = octstr_format("%s%s%S", s,
(ps && octstr_len(ps) > 0) ? "; " : "",
ps);
octstr_destroy(ps);
http_destroy_headers(h);
} else
value = octstr_create(s);
http_header_remove_all(m->headers, "Content-Type");
http_header_add(m->headers, "Content-Type", octstr_get_cstr(value));
octstr_destroy(value); if (s)
} strip_boundary_element(h,s);
mime_replace_headers(m, h);
http_destroy_headers(h);
if (params) if (params)
octstr_destroy(params); octstr_destroy(params);
if (m->multiparts && list_len(m->multiparts) > 0) if ((n = mime_entity_num_parts(m)) > 0)
for (i = 0, n = list_len(m->multiparts); i < n; i++) for (i = 0; i < n; i++) {
unconvert_mime_msg(list_get(m->multiparts, i)); MIMEEntity *x = mime_entity_get_part(m, i);
unconvert_mime_msg(x);
mime_entity_replace_part(m, i, x);
}
} }
@ -1267,20 +1299,15 @@ MIMEEntity *mms_tomime(MmsMsg *msg, int base64)
if (!msg) if (!msg)
return NULL; return NULL;
m = gw_malloc(sizeof *m); m = mime_entity_create();
memset(m, 0, sizeof *m); mime_replace_headers(m, msg->headers);
m->body = NULL;
m->multiparts = NULL;
m->start = NULL;
m->headers = http_header_duplicate(msg->headers);
if (!msg->ismultipart) if (!msg->ismultipart)
m->body = msg->body.s ? octstr_duplicate(msg->body.s) : NULL; mime_entity_set_body(m, msg->body.s);
else { else {
m->multiparts = list_create(); for (i = 0, n = gwlist_len(msg->body.l); i < n; i++) {
for (i = 0, n = list_len(msg->body.l); i < n; i++) { MIMEEntity *mx = gwlist_get(msg->body.l, i);
MIMEEntity *mx = mime_entity_duplicate(list_get(msg->body.l, i)); mime_entity_add_part(m, mx);
list_append(m->multiparts, mx);
} }
} }
convert_mime_msg(m); convert_mime_msg(m);
@ -1294,29 +1321,34 @@ MmsMsg *mms_frommime(MIMEEntity *mime)
MmsMsg *m; MmsMsg *m;
Octstr *s; Octstr *s;
MIMEEntity *mx; MIMEEntity *mx;
int n;
if (!mime) if (!mime)
return NULL; return NULL;
m = gw_malloc(sizeof *m); m = gw_malloc(sizeof *m);
memset(m, 0, sizeof *m); memset(m, 0, sizeof *m);
n = mime_entity_num_parts(mime);
mx = mime_entity_duplicate(mime); mx = mime_entity_duplicate(mime);
unconvert_mime_msg(mx); /* Fix-up content type issues. */ unconvert_mime_msg(mx); /* Fix-up content type issues. */
unpack_mimeheaders(mx); unpack_mimeheaders(mx);
unbase64_mimeparts(mx); unbase64_mimeparts(mx);
m->headers = mx->headers; m->headers = _x_mime_entity_headers(mx);
if (n > 0) {
if (mx->multiparts && list_len(mx->multiparts) > 0) { int i;
m->ismultipart = 1; m->ismultipart = 1;
m->body.l = mx->multiparts; m->body.l = gwlist_create();
for (i = 0; i < n; i++)
gwlist_append(m->body.l, mime_entity_get_part(mx, i));
} else { } else {
m->ismultipart = 0; m->ismultipart = 0;
m->body.s = mx->body ? mx->body : octstr_imm(""); m->body.s = mime_entity_body(mx);
} }
mime_entity_destroy(mx); /* Because all its bits are used above. XXX not very clean! */
gw_free(mx); /* Because all its bits are used above. XXX not very clean! */
/* Now check for important headers. If missing, put them in */ /* Now check for important headers. If missing, put them in */
m->msgId = http_header_value(m->headers, octstr_imm("Message-ID")); m->msgId = http_header_value(m->headers, octstr_imm("Message-ID"));
@ -1385,15 +1417,6 @@ MmsMsg *mms_frommime(MIMEEntity *mime)
return NULL; return NULL;
} }
static void mm_destroy(MIMEEntity *mx)
{
http_destroy_headers(mx->headers);
if (mx->body)
octstr_destroy(mx->body);
else if (mx->multiparts)
list_destroy(mx->multiparts, (list_item_destructor_t *)mm_destroy);
gw_free(mx);
}
void mms_destroy(MmsMsg *msg) void mms_destroy(MmsMsg *msg)
{ {
@ -1401,7 +1424,7 @@ void mms_destroy(MmsMsg *msg)
if (!msg) if (!msg)
return; return;
if (msg->ismultipart) if (msg->ismultipart)
list_destroy(msg->body.l, (list_item_destructor_t *)mm_destroy); gwlist_destroy(msg->body.l, (gwlist_item_destructor_t *)mime_entity_destroy);
else if (msg->body.s) else if (msg->body.s)
octstr_destroy(msg->body.s); octstr_destroy(msg->body.s);
http_destroy_headers(msg->headers); http_destroy_headers(msg->headers);
@ -1596,11 +1619,11 @@ MmsMsg *mms_retrieveconf(MmsMsg *msg, Octstr *transactionid,
else else
/* Body is a list of MIMEEntities, so recreate it. */ /* Body is a list of MIMEEntities, so recreate it. */
for (m->body.l = list_create(), i = 0, for (m->body.l = gwlist_create(), i = 0,
n = list_len(msg->body.l); n = gwlist_len(msg->body.l);
i<n; i++) i<n; i++)
list_append(m->body.l, gwlist_append(m->body.l,
mime_entity_duplicate(list_get(msg->body.l, i))); mime_entity_duplicate(gwlist_get(msg->body.l, i)));
/* Remove some headers that may not be permitted. */ /* Remove some headers that may not be permitted. */
mms_remove_headers(m, "X-Mms-Expiry"); mms_remove_headers(m, "X-Mms-Expiry");
mms_remove_headers(m, "X-Mms-Delivery-Time"); mms_remove_headers(m, "X-Mms-Delivery-Time");
@ -1694,8 +1717,8 @@ int mms_replace_header_values(MmsMsg *msg, char *hname, List *value)
gw_assert(msg); gw_assert(msg);
http_header_remove_all(msg->headers, hname); http_header_remove_all(msg->headers, hname);
for (i = 0; i < list_len(value); i++) { for (i = 0; i < gwlist_len(value); i++) {
Octstr *x = list_get(value, i); Octstr *x = gwlist_get(value, i);
http_header_add(msg->headers, hname, octstr_get_cstr(x)); http_header_add(msg->headers, hname, octstr_get_cstr(x));
} }
return 0; return 0;
@ -1716,14 +1739,14 @@ List *mms_get_header_values(MmsMsg *msg, Octstr *header)
int i; int i;
gw_assert(msg); gw_assert(msg);
l = list_create(); l = gwlist_create();
h = http_header_find_all(msg->headers, octstr_get_cstr(header)); h = http_header_find_all(msg->headers, octstr_get_cstr(header));
for (i = 0; i < list_len(h); i++) { for (i = 0; i < gwlist_len(h); i++) {
Octstr *hname, *value; Octstr *hname, *value;
http_header_get(h, i, &hname, &value); http_header_get(h, i, &hname, &value);
list_append(l, value); gwlist_append(l, value);
octstr_destroy(hname); octstr_destroy(hname);
} }
http_destroy_headers(h); http_destroy_headers(h);
@ -1836,8 +1859,8 @@ static int mms_convert_to_mboxdescr(MmsMsg *mm, Octstr *cloc, List *reqhdrs,
http_header_add(mh, "X-Mms-Content-Location", octstr_get_cstr(cloc)); http_header_add(mh, "X-Mms-Content-Location", octstr_get_cstr(cloc));
/* Add only those headers requested. */ /* Add only those headers requested. */
for (i = 0, n = list_len(reqhdrs); i < n; i++) { for (i = 0, n = gwlist_len(reqhdrs); i < n; i++) {
Octstr *header = list_get(reqhdrs,i); Octstr *header = gwlist_get(reqhdrs,i);
List *h = http_header_find_all(mm->headers, octstr_get_cstr(header)); List *h = http_header_find_all(mm->headers, octstr_get_cstr(header));
int j; int j;
@ -1853,7 +1876,7 @@ static int mms_convert_to_mboxdescr(MmsMsg *mm, Octstr *cloc, List *reqhdrs,
} else if (octstr_case_compare(header, octstr_imm("Message-ID")) == 0) } else if (octstr_case_compare(header, octstr_imm("Message-ID")) == 0)
hasmsgid = 1; hasmsgid = 1;
for (j = 0; j < list_len(h); j++) { for (j = 0; j < gwlist_len(h); j++) {
Octstr *hname, *value; Octstr *hname, *value;
http_header_get(h, j, &hname, &value); http_header_get(h, j, &hname, &value);
octstr_destroy(hname); octstr_destroy(hname);
@ -1892,7 +1915,7 @@ static int mms_convert_to_mboxdescr(MmsMsg *mm, Octstr *cloc, List *reqhdrs,
if (!addcontent) { if (!addcontent) {
if (mm->ismultipart) if (mm->ismultipart)
list_destroy(mm->body.l, (list_item_destructor_t *)mm_destroy); gwlist_destroy(mm->body.l, (gwlist_item_destructor_t *)mime_entity_destroy);
else if (mm->body.s) else if (mm->body.s)
octstr_destroy(mm->body.s); octstr_destroy(mm->body.s);
mm->body.s = NULL; mm->body.s = NULL;
@ -1956,15 +1979,15 @@ MmsMsg *mms_viewconf(char *transid,
msize = mms_msgsize(m); msize = mms_msgsize(m);
n = list_len(msgrefs); n = gwlist_len(msgrefs);
msgcount = 0; msgcount = 0;
m->ismultipart = 1; m->ismultipart = 1;
m->body.l = list_create(); m->body.l = gwlist_create();
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
unsigned long tmsize; unsigned long tmsize;
Octstr *msgref = list_get(msgrefs,i); Octstr *msgref = gwlist_get(msgrefs,i);
Octstr *msgloc = list_get(msglocs, i); Octstr *msgloc = gwlist_get(msglocs, i);
MmsMsg *mm = getmsg(p1, p2, msgref, &tmsize); MmsMsg *mm = getmsg(p1, p2, msgref, &tmsize);
Octstr *ms; Octstr *ms;
@ -1976,12 +1999,16 @@ MmsMsg *mms_viewconf(char *transid,
ms = mms_tobinary(mm); ms = mms_tobinary(mm);
if (octstr_len(ms) + msize <= maxsize) { if (octstr_len(ms) + msize <= maxsize) {
MIMEEntity *mtmp = mime_entity_create(); MIMEEntity *mtmp = mime_entity_create();
List *h = _x_mime_entity_headers(mtmp);
http_header_add(mtmp->headers, "Content-Type", http_header_add(h, "Content-Type",
"application/vnd.wap.mms-message"); "application/vnd.wap.mms-message");
mtmp->body = ms; mime_replace_headers(mtmp, h);
mime_entity_set_body(mtmp, ms);
http_destroy_headers(h);
list_append(m->body.l, mtmp); gwlist_append(m->body.l, mtmp);
msgcount++; msgcount++;
msize += octstr_len(ms); msize += octstr_len(ms);
} else { } else {
@ -1994,13 +2021,13 @@ MmsMsg *mms_viewconf(char *transid,
loop:(void)0; loop:(void)0;
} }
if (list_len(m->body.l) > 0) { if (gwlist_len(m->body.l) > 0) {
char x[32]; char x[32];
sprintf(x, "%d", (int)list_len(m->body.l)); sprintf(x, "%d", (int)gwlist_len(m->body.l));
mms_replace_header_value(m, "X-Mms-Message-Count", x); mms_replace_header_value(m, "X-Mms-Message-Count", x);
mms_replace_header_value(m, "Content-Type", "application/vnd.wap.multipart.mixed"); mms_replace_header_value(m, "Content-Type", "application/vnd.wap.multipart.mixed");
} else { } else {
list_destroy(m->body.l,NULL); gwlist_destroy(m->body.l,NULL);
m->body.s = NULL; m->body.s = NULL;
m->ismultipart = 0; m->ismultipart = 0;
} }
@ -2014,11 +2041,11 @@ void *mms_msgbody(MmsMsg *msg)
return NULL; return NULL;
if (msg->ismultipart) { if (msg->ismultipart) {
List *l = list_create(); List *l = gwlist_create();
int i; int i;
for (i = 0; i < list_len(msg->body.l); i++) for (i = 0; i < gwlist_len(msg->body.l); i++)
list_append(l, mime_entity_duplicate(list_get(msg->body.l,i))); gwlist_append(l, mime_entity_duplicate(gwlist_get(msg->body.l,i)));
return l; return l;
} else } else
return octstr_duplicate(msg->body.s); return octstr_duplicate(msg->body.s);
@ -2030,7 +2057,7 @@ int mms_clearbody(MmsMsg *msg)
return -1; return -1;
if (msg->ismultipart) if (msg->ismultipart)
list_destroy(msg->body.l, (list_item_destructor_t *)mm_destroy); gwlist_destroy(msg->body.l, (gwlist_item_destructor_t *)mime_entity_destroy);
else if (msg->body.s) else if (msg->body.s)
octstr_destroy(msg->body.s); octstr_destroy(msg->body.s);
msg->body.s = NULL; msg->body.s = NULL;

View File

@ -151,13 +151,13 @@ MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldbloc
int okfile = 0; int okfile = 0;
char subdir[64]; char subdir[64];
char realqf[QFNAMEMAX]; char realqf[QFNAMEMAX];
char *xqf = NULL; char xqf[QFNAMEMAX+64];
get_subdir(qf, subdir, realqf); /* break it down... */ get_subdir(qf, subdir, realqf); /* break it down... */
fname = octstr_format( "%.128s/%s%s", mms_queuedir, subdir, realqf); fname = octstr_format( "%.128s/%s%s", mms_queuedir, subdir, realqf);
xqf = octstr_get_cstr(fname); strncpy(xqf, octstr_get_cstr(fname), sizeof xqf);
if ((fd = open(octstr_get_cstr(fname), O_RDONLY)) < 0) { if ((fd = open(octstr_get_cstr(fname), O_RDONLY)) < 0) {
octstr_destroy(fname); octstr_destroy(fname);
@ -171,7 +171,7 @@ MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldbloc
e = gw_malloc(sizeof *e); e = gw_malloc(sizeof *e);
memset(e, 0, sizeof *e); /* Clear it all .*/ memset(e, 0, sizeof *e); /* Clear it all .*/
e->to = list_create(); e->to = gwlist_create();
e->qf.fd = fd; e->qf.fd = fd;
strncpy(e->qf.name, realqf, sizeof e->qf.name); strncpy(e->qf.name, realqf, sizeof e->qf.name);
strncpy(e->qf.subdir, subdir, sizeof e->qf.subdir); strncpy(e->qf.subdir, subdir, sizeof e->qf.subdir);
@ -226,7 +226,7 @@ MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldbloc
to = gw_malloc(sizeof *to); to = gw_malloc(sizeof *to);
to->rcpt = t; to->rcpt = t;
to->process = 1; to->process = 1;
list_append(e->to, to); gwlist_append(e->to, to);
break; break;
case 'C': case 'C':
e->created = atol(res); e->created = atol(res);
@ -379,19 +379,19 @@ static int writeenvelope(MmsEnvelope *e, int newenv)
_putline(fd, "F", octstr_get_cstr(e->from)); _putline(fd, "F", octstr_get_cstr(e->from));
if (e->to) if (e->to)
n = list_len(e->to); n = gwlist_len(e->to);
else else
n = 0; n = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
MmsEnvelopeTo *to = list_get(e->to, i); MmsEnvelopeTo *to = gwlist_get(e->to, i);
if (to->process) if (to->process)
_putline(fd, "R", octstr_get_cstr(to->rcpt)); _putline(fd, "R", octstr_get_cstr(to->rcpt));
} }
/* Output headers if any. */ /* Output headers if any. */
n = (e->hdrs) ? list_len(e->hdrs) : 0; n = (e->hdrs) ? gwlist_len(e->hdrs) : 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
Octstr *h = NULL, *v = NULL; Octstr *h = NULL, *v = NULL;
@ -666,7 +666,7 @@ Octstr *mms_queue_add(Octstr *from, List *to,
char qf[QFNAMEMAX], subdir[64]; char qf[QFNAMEMAX], subdir[64];
int fd, i, n; int fd, i, n;
MmsEnvelope *e; MmsEnvelope *e;
Octstr *msgid, *s = NULL, *r = NULL; Octstr *msgid, *r = NULL;
Octstr *ms, *res = NULL, *xfrom = NULL; Octstr *ms, *res = NULL, *xfrom = NULL;
int mtype; int mtype;
fd = mkqf(qf, subdir, directory); fd = mkqf(qf, subdir, directory);
@ -710,7 +710,7 @@ Octstr *mms_queue_add(Octstr *from, List *to,
e->fromproxy = fromproxy; e->fromproxy = fromproxy;
e->viaproxy = viaproxy; e->viaproxy = viaproxy;
e->subject = subject; e->subject = subject;
e->to = list_create(); e->to = gwlist_create();
e->msize = octstr_len(ms); e->msize = octstr_len(ms);
e->msgId = msgid; e->msgId = msgid;
e->token = token; e->token = token;
@ -723,22 +723,16 @@ Octstr *mms_queue_add(Octstr *from, List *to,
e->dlr = dlr; e->dlr = dlr;
e->bill.billed = 0; e->bill.billed = 0;
/* Insert message ID into message if it is missing. */
if (mms_messagetype(m) == MMS_MSGTYPE_SEND_REQ &&
(s = mms_get_header_value(m, octstr_imm("Message-ID"))) == NULL)
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid));
else if (s)
octstr_destroy(s);
for (i = 0, n = to ? list_len(to) : 0; i<n; i++) for (i = 0, n = to ? gwlist_len(to) : 0; i<n; i++)
if ((r = list_get(to, i)) != NULL && if ((r = gwlist_get(to, i)) != NULL &&
(r = copy_and_clean_address(r)) != NULL) { (r = copy_and_clean_address(r)) != NULL) {
MmsEnvelopeTo *t = gw_malloc(sizeof *t); MmsEnvelopeTo *t = gw_malloc(sizeof *t);
t->rcpt = r; t->rcpt = r;
t->process = 1; t->process = 1;
list_append(e->to, t); gwlist_append(e->to, t);
} }
/* Write queue data. */ /* Write queue data. */
@ -763,12 +757,12 @@ Octstr *mms_queue_add(Octstr *from, List *to,
done: done:
/* Free the envelope stuff since we do not need it any more, then free 'e' */ /* Free the envelope stuff since we do not need it any more, then free 'e' */
for (i = 0, n = list_len(e->to); i<n; i++) { for (i = 0, n = gwlist_len(e->to); i<n; i++) {
MmsEnvelopeTo *to = list_get(e->to, i); MmsEnvelopeTo *to = gwlist_get(e->to, i);
octstr_destroy(to->rcpt); octstr_destroy(to->rcpt);
gw_free(to); gw_free(to);
} }
list_destroy(e->to, NULL); gwlist_destroy(e->to, NULL);
gw_free(e); /* Free struct only, caller responsible for arguments. */ gw_free(e); /* Free struct only, caller responsible for arguments. */
@ -788,13 +782,13 @@ static int free_envelope(MmsEnvelope *e, int removefromqueue)
if (e->msgId) if (e->msgId)
octstr_destroy(e->msgId); octstr_destroy(e->msgId);
for (i = 0, n = list_len(e->to); i < n; i++) { for (i = 0, n = gwlist_len(e->to); i < n; i++) {
MmsEnvelopeTo *x = list_get(e->to, i); MmsEnvelopeTo *x = gwlist_get(e->to, i);
octstr_destroy(x->rcpt); octstr_destroy(x->rcpt);
gw_free(x); gw_free(x);
} }
list_destroy(e->to, NULL); gwlist_destroy(e->to, NULL);
if (e->from) if (e->from)
octstr_destroy(e->from); octstr_destroy(e->from);
@ -849,14 +843,16 @@ int mms_queue_free_env(MmsEnvelope *e)
} }
int mms_queue_update(MmsEnvelope *e) int mms_queue_update(MmsEnvelope *e)
{ {
int i, n = (e && e->to) ? list_len(e->to) : 0; int i, n = (e && e->to) ? gwlist_len(e->to) : 0;
int hasrcpt = 0; int hasrcpt = 0;
MmsEnvelopeTo *x; MmsEnvelopeTo *x;
if (!e) return -1; if (!e) return -1;
/* FIX: Don't allow expiry to be <= 0 */
if (e->expiryt <= 0)
e->expiryt = time(NULL) + DEFAULT_EXPIRE;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
if ((x = list_get(e->to, i)) != NULL && if ((x = gwlist_get(e->to, i)) != NULL &&
x->process) { x->process) {
hasrcpt = 1; hasrcpt = 1;
break; break;
@ -941,15 +937,16 @@ static void tdeliver(struct Qthread_t *qt)
{ {
MmsEnvelope *e; MmsEnvelope *e;
while ((e = list_consume(qt->l)) != NULL) { while ((e = gwlist_consume(qt->l)) != NULL) {
int res = qt->deliver(e); /* If it is on the queue, it has to be delivered. */ int res;
res = qt->deliver(e); /* If it is on the queue, it has to be delivered. */
if (res != 1) /* Then delete as it wasn't deleted. */ if (res != 1) /* Then delete as it wasn't deleted. */
free_envelope(e, 0); free_envelope(e, 0);
} }
/* Consume failed, time to go away. */ /* Consume failed, time to go away. */
if (qt->l) if (qt->l)
list_destroy(qt->l, NULL); gwlist_destroy(qt->l, NULL);
qt->l = NULL; /* Signal that we are gone. */ qt->l = NULL; /* Signal that we are gone. */
} }
@ -963,7 +960,7 @@ static int run_dir(char *topdir, char *dir, struct Qthread_t *tlist, int num_thr
{ {
DIR *dirp; DIR *dirp;
struct dirent *dp; struct dirent *dp;
time_t tnow = time(NULL);
Octstr *tdir = octstr_format("%s/%s", topdir, dir); Octstr *tdir = octstr_format("%s/%s", topdir, dir);
char *xdir = octstr_get_cstr(tdir); char *xdir = octstr_get_cstr(tdir);
int ret = 0; int ret = 0;
@ -981,7 +978,8 @@ static int run_dir(char *topdir, char *dir, struct Qthread_t *tlist, int num_thr
struct stat st; struct stat st;
Octstr *xfname = octstr_format("%s%s", xdir, dp->d_name); Octstr *xfname = octstr_format("%s%s", xdir, dp->d_name);
int sres = stat(octstr_get_cstr(xfname), &st); int sres = stat(octstr_get_cstr(xfname), &st);
time_t tnow = time(NULL);
octstr_destroy(xfname); octstr_destroy(xfname);
if (sres == 0 && S_ISREG(st.st_mode) && if (sres == 0 && S_ISREG(st.st_mode) &&
@ -1000,9 +998,9 @@ static int run_dir(char *topdir, char *dir, struct Qthread_t *tlist, int num_thr
int j = *i; /* This is the next thread to use. Checking for cycles. */ int j = *i; /* This is the next thread to use. Checking for cycles. */
do { do {
if (tlist[*i].l) { if (tlist[*i].l) {
debug("queuerun", 0, "Queued to thread %d for %s%s", debug("queuerun", 0, "Queued to thread %d for %s%s, sendt=%d, tnow=%d",
*i, xdir, dp->d_name); *i, xdir, dp->d_name, (int)e->sendt, (int)tnow);
list_produce(tlist[*i].l, e); gwlist_produce(tlist[*i].l, e);
queued = 1; queued = 1;
} }
*i = (*i+1)%num_threads; *i = (*i+1)%num_threads;
@ -1022,7 +1020,7 @@ static int run_dir(char *topdir, char *dir, struct Qthread_t *tlist, int num_thr
strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, ".") != 0 &&
strcmp(dp->d_name, "..") != 0) { strcmp(dp->d_name, "..") != 0) {
Octstr *newdir = octstr_format("%s%s/", dir, dp->d_name); Octstr *newdir = octstr_format("%s%s/", dir, dp->d_name);
list_append(stack, newdir); /* push it... */ gwlist_append(stack, newdir); /* push it... */
} }
} }
if (dirp) closedir(dirp); if (dirp) closedir(dirp);
@ -1038,15 +1036,15 @@ void mms_queue_run(char *dir,
{ {
struct Qthread_t *tlist; struct Qthread_t *tlist;
int i, qstop = 0; int i, qstop = 0;
List *stack = list_create(); List *stack = gwlist_create();
gw_assert(num_threads>0); gw_assert(num_threads>0);
tlist = gw_malloc(num_threads*sizeof tlist[0]); tlist = gw_malloc(num_threads*sizeof tlist[0]);
for (i = 0; i<num_threads; i++) { /* Create threads for sending. */ for (i = 0; i<num_threads; i++) { /* Create threads for sending. */
tlist[i].l = list_create(); tlist[i].l = gwlist_create();
list_add_producer(tlist[i].l); gwlist_add_producer(tlist[i].l);
tlist[i].deliver = deliver; tlist[i].deliver = deliver;
gwthread_create((gwthread_func_t *)tdeliver, &tlist[i]); gwthread_create((gwthread_func_t *)tdeliver, &tlist[i]);
} }
@ -1056,10 +1054,10 @@ void mms_queue_run(char *dir,
i = 0; /* For stepping through above array. */ i = 0; /* For stepping through above array. */
do { do {
Octstr *xdir = NULL; Octstr *xdir = NULL;
list_append(stack, octstr_create("")); /* Put initial dir on there. */ gwlist_append(stack, octstr_create("")); /* Put initial dir on there. */
while (!*rstop && while (!*rstop &&
(xdir = list_extract_first(stack)) != NULL) { (xdir = gwlist_extract_first(stack)) != NULL) {
int ret = run_dir(dir, octstr_get_cstr(xdir), tlist, num_threads, &i, stack); int ret = run_dir(dir, octstr_get_cstr(xdir), tlist, num_threads, &i, stack);
octstr_destroy(xdir); octstr_destroy(xdir);
xdir = NULL; xdir = NULL;
@ -1080,15 +1078,15 @@ void mms_queue_run(char *dir,
/* We are out of the queue, time to go away. */ /* We are out of the queue, time to go away. */
for (i = 0; i<num_threads; i++) for (i = 0; i<num_threads; i++)
if (tlist[i].l) if (tlist[i].l)
list_remove_producer(tlist[i].l); gwlist_remove_producer(tlist[i].l);
gwthread_join_every((gwthread_func_t *)tdeliver); /* Wait for them all to terminate. */ gwthread_join_every((gwthread_func_t *)tdeliver); /* Wait for them all to terminate. */
for (i = 0; i<num_threads; i++) for (i = 0; i<num_threads; i++)
if (tlist[i].l) if (tlist[i].l)
list_destroy(tlist[i].l,NULL); /* Final destroy if needed. */ gwlist_destroy(tlist[i].l,NULL); /* Final destroy if needed. */
gw_free(tlist); gw_free(tlist);
list_destroy(stack, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(stack, (gwlist_item_destructor_t *)octstr_destroy);
return; return;
} }

View File

@ -56,21 +56,21 @@ static unsigned long hash_key(Octstr *s)
static void destroy_uaprof(MmsUaProfile *prof) static void destroy_uaprof(MmsUaProfile *prof)
{ {
if (prof->versions) if (prof->versions)
list_destroy(prof->versions, gwlist_destroy(prof->versions,
(list_item_destructor_t *)octstr_destroy); (gwlist_item_destructor_t *)octstr_destroy);
if (prof->ccppaccept.content) { if (prof->ccppaccept.content) {
list_destroy(prof->ccppaccept.content, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(prof->ccppaccept.content, (gwlist_item_destructor_t *)octstr_destroy);
list_destroy(prof->ccppaccept._hash, NULL); gwlist_destroy(prof->ccppaccept._hash, NULL);
} }
if (prof->ccppaccept.charset) { if (prof->ccppaccept.charset) {
list_destroy(prof->ccppaccept.charset, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(prof->ccppaccept.charset, (gwlist_item_destructor_t *)octstr_destroy);
list_destroy(prof->ccppaccept._chash, NULL); gwlist_destroy(prof->ccppaccept._chash, NULL);
} if (prof->ccppaccept.lang) } if (prof->ccppaccept.lang)
list_destroy(prof->ccppaccept.lang, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(prof->ccppaccept.lang, (gwlist_item_destructor_t *)octstr_destroy);
if (prof->ccppaccept.enc) if (prof->ccppaccept.enc)
list_destroy(prof->ccppaccept.enc, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(prof->ccppaccept.enc, (gwlist_item_destructor_t *)octstr_destroy);
gw_free(prof); gw_free(prof);
} }
@ -88,37 +88,37 @@ static void dump_profile(MmsUaProfile *prof, Octstr *name)
s = octstr_create(""); s = octstr_create("");
if (prof->ccppaccept.content) if (prof->ccppaccept.content)
for (i=0; i<list_len(prof->ccppaccept.content); i++) for (i=0; i<gwlist_len(prof->ccppaccept.content); i++)
octstr_format_append(s, "%S, ", list_get(prof->ccppaccept.content,i)); octstr_format_append(s, "%S, ", gwlist_get(prof->ccppaccept.content,i));
debug("mms.uaprof", 0, "Accept content: %s", octstr_get_cstr(s)); debug("mms.uaprof", 0, "Accept content: %s", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
s = octstr_create(""); s = octstr_create("");
if (prof->ccppaccept.enc) if (prof->ccppaccept.enc)
for (i=0; i<list_len(prof->ccppaccept.enc); i++) for (i=0; i<gwlist_len(prof->ccppaccept.enc); i++)
octstr_format_append(s, "%S, ", list_get(prof->ccppaccept.enc,i)); octstr_format_append(s, "%S, ", gwlist_get(prof->ccppaccept.enc,i));
debug("mms.uaprof", 0, "Accept encodings: %s", octstr_get_cstr(s)); debug("mms.uaprof", 0, "Accept encodings: %s", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
s = octstr_create(""); s = octstr_create("");
if (prof->ccppaccept.lang) if (prof->ccppaccept.lang)
for (i=0; i<list_len(prof->ccppaccept.lang); i++) for (i=0; i<gwlist_len(prof->ccppaccept.lang); i++)
octstr_format_append(s, "%S, ", list_get(prof->ccppaccept.lang,i)); octstr_format_append(s, "%S, ", gwlist_get(prof->ccppaccept.lang,i));
debug("mms.uaprof", 0, "Accept language: %s", octstr_get_cstr(s)); debug("mms.uaprof", 0, "Accept language: %s", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
s = octstr_create(""); s = octstr_create("");
if (prof->ccppaccept.charset) if (prof->ccppaccept.charset)
for (i=0; i<list_len(prof->ccppaccept.charset); i++) for (i=0; i<gwlist_len(prof->ccppaccept.charset); i++)
octstr_format_append(s, "%S, ", list_get(prof->ccppaccept.charset,i)); octstr_format_append(s, "%S, ", gwlist_get(prof->ccppaccept.charset,i));
debug("mms.uaprof", 0, "Accept charset: %s", octstr_get_cstr(s)); debug("mms.uaprof", 0, "Accept charset: %s", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
s = octstr_create(""); s = octstr_create("");
if (prof->versions) if (prof->versions)
for (i=0; i<list_len(prof->versions); i++) for (i=0; i<gwlist_len(prof->versions); i++)
octstr_format_append(s, "%S, ", list_get(prof->versions,i)); octstr_format_append(s, "%S, ", gwlist_get(prof->versions,i));
debug("mms.uaprof", 0, "Mms Version: %s", octstr_get_cstr(s)); debug("mms.uaprof", 0, "Mms Version: %s", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
@ -192,19 +192,19 @@ MmsUaProfile *mms_make_ua_profile(List *req_headers)
prof->maxres.x = 640; prof->maxres.x = 640;
prof->maxres.y = 480; prof->maxres.y = 480;
prof->maxmsgsize = 100*1024; prof->maxmsgsize = 100*1024;
prof->versions = list_create(); prof->versions = gwlist_create();
list_append(prof->versions, octstr_imm("1.0")); /* Assume 1.0 for now. */ gwlist_append(prof->versions, octstr_imm("1.0")); /* Assume 1.0 for now. */
/* Get accepted charsets. */ /* Get accepted charsets. */
s = http_header_value(req_headers, octstr_imm("Accept-Charset")); s = http_header_value(req_headers, octstr_imm("Accept-Charset"));
if (s && (l = http_header_split_value(s)) != NULL) { if (s && (l = http_header_split_value(s)) != NULL) {
prof->ccppaccept.charset = l; prof->ccppaccept.charset = l;
prof->ccppaccept._chash = list_create(); prof->ccppaccept._chash = gwlist_create();
for (i = 0, n = list_len(l); i<n; i++) for (i = 0, n = gwlist_len(l); i<n; i++)
list_append(prof->ccppaccept._chash, (void *)hash_key(list_get(l, i))); gwlist_append(prof->ccppaccept._chash, (void *)hash_key(gwlist_get(l, i)));
} }
if (s) octstr_destroy(s); if (s) octstr_destroy(s);
@ -229,16 +229,16 @@ MmsUaProfile *mms_make_ua_profile(List *req_headers)
s = http_header_value(req_headers, octstr_imm("Accept")); s = http_header_value(req_headers, octstr_imm("Accept"));
if (s && (l = http_header_split_value(s)) != NULL) { if (s && (l = http_header_split_value(s)) != NULL) {
prof->ccppaccept.content = l; prof->ccppaccept.content = l;
prof->ccppaccept._hash = list_create(); prof->ccppaccept._hash = gwlist_create();
for (i = 0, n = l ? list_len(l) : 0; i<n; i++) { for (i = 0, n = l ? gwlist_len(l) : 0; i<n; i++) {
Octstr *x = list_get(l, i); Octstr *x = gwlist_get(l, i);
if (octstr_str_compare(x, "*/*") == 0) if (octstr_str_compare(x, "*/*") == 0)
prof->ccppaccept.all = 1; prof->ccppaccept.all = 1;
else if (octstr_case_compare(x, octstr_imm(PRES_TYPE)) == 0) else if (octstr_case_compare(x, octstr_imm(PRES_TYPE)) == 0)
prof->ccppaccept.presentation = 1; prof->ccppaccept.presentation = 1;
list_append(prof->ccppaccept._hash, (void *)hash_key(x)); gwlist_append(prof->ccppaccept._hash, (void *)hash_key(x));
} }
} }
@ -295,12 +295,12 @@ static MmsUaProfile *parse_uaprofile(Octstr *xml)
/* If there is a Bag, get the list. */ /* If there is a Bag, get the list. */
if ((rdfnode = find_node(xnode->xmlChildrenNode, "Bag", NULL,0,1)) != NULL) { if ((rdfnode = find_node(xnode->xmlChildrenNode, "Bag", NULL,0,1)) != NULL) {
l = list_create(); l = gwlist_create();
for (lnode = rdfnode->xmlChildrenNode; lnode; lnode = lnode->next) for (lnode = rdfnode->xmlChildrenNode; lnode; lnode = lnode->next)
if (xmlStrcasecmp(lnode->name, (const xmlChar *)"li") == 0) { if (xmlStrcasecmp(lnode->name, (const xmlChar *)"li") == 0) {
unsigned char *t = xmlNodeListGetString(doc, lnode->xmlChildrenNode,1); unsigned char *t = xmlNodeListGetString(doc, lnode->xmlChildrenNode,1);
if (t) { if (t) {
list_append(l, octstr_create((char *)t)); gwlist_append(l, octstr_create((char *)t));
xmlFree(t); xmlFree(t);
} }
} }
@ -315,32 +315,32 @@ static MmsUaProfile *parse_uaprofile(Octstr *xml)
xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept-CharSet") == 0) {/* Cranky old ones! */ xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept-CharSet") == 0) {/* Cranky old ones! */
int i, n; int i, n;
prof->ccppaccept.charset = l; prof->ccppaccept.charset = l;
prof->ccppaccept._chash = list_create(); prof->ccppaccept._chash = gwlist_create();
for (i = 0, n = list_len(l); i<n; i++) for (i = 0, n = gwlist_len(l); i<n; i++)
list_append(prof->ccppaccept._chash, (void *)hash_key(list_get(l, i))); gwlist_append(prof->ccppaccept._chash, (void *)hash_key(gwlist_get(l, i)));
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptLanguage") == 0) } else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptLanguage") == 0)
prof->ccppaccept.lang = l; prof->ccppaccept.lang = l;
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptEncoding") == 0) else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptEncoding") == 0)
prof->ccppaccept.enc = l; prof->ccppaccept.enc = l;
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsVersion") == 0) { else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsVersion") == 0) {
if (!l && childtext) { /* SonyEriccson uses old format! */ if (!l && childtext) { /* SonyEriccson uses old format! */
l = list_create(); l = gwlist_create();
list_append(l, octstr_create((char *)childtext)); gwlist_append(l, octstr_create((char *)childtext));
} }
prof->versions = l; prof->versions = l;
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept") == 0) { } else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept") == 0) {
int i, n; int i, n;
prof->ccppaccept.content = l; prof->ccppaccept.content = l;
prof->ccppaccept._hash = list_create(); prof->ccppaccept._hash = gwlist_create();
for (i = 0, n = l ? list_len(l) : 0; i<n; i++) { for (i = 0, n = l ? gwlist_len(l) : 0; i<n; i++) {
Octstr *x = list_get(l, i); Octstr *x = gwlist_get(l, i);
if (octstr_str_compare(x, "*/*") == 0) if (octstr_str_compare(x, "*/*") == 0)
prof->ccppaccept.all = 1; prof->ccppaccept.all = 1;
else if (octstr_case_compare(x, octstr_imm(PRES_TYPE)) == 0) else if (octstr_case_compare(x, octstr_imm(PRES_TYPE)) == 0)
prof->ccppaccept.presentation = 1; prof->ccppaccept.presentation = 1;
list_append(prof->ccppaccept._hash, (void *)hash_key(x)); gwlist_append(prof->ccppaccept._hash, (void *)hash_key(x));
} }
} }
if (childtext) xmlFree(childtext); if (childtext) xmlFree(childtext);
@ -439,7 +439,7 @@ static MmsUaProfile *profile_fetch(Octstr *profile_url)
http_header_add(h, "User-Agent", MM_NAME "/" MMSC_VERSION); http_header_add(h, "User-Agent", MM_NAME "/" MMSC_VERSION);
status = http_get_real(HTTP_METHOD_GET, profile_url, h, &final_url, &rh, &body); status = http_get_real(HTTP_METHOD_GET, profile_url, h, &final_url, &rh, &body);
if (status == HTTP_OK) { if (http_status_class(status) == HTTP_STATUS_SUCCESSFUL) {
prof = parse_uaprofile(body); prof = parse_uaprofile(body);
debug("mms.uaprof", 0, "Fetcher got %s", octstr_get_cstr(profile_url)); debug("mms.uaprof", 0, "Fetcher got %s", octstr_get_cstr(profile_url));
@ -591,12 +591,19 @@ static void init_format_table(void)
/* Removes an object by making it text/plain. For now not configurable. */ /* Removes an object by making it text/plain. For now not configurable. */
static void remove_object(MIMEEntity *m, Octstr *ctype) static void remove_object(MIMEEntity *m, Octstr *ctype)
{ {
http_header_remove_all(m->headers, "Content-Type"); List *h = _x_mime_entity_headers(m);
Octstr *s = octstr_format("Unsupported object (content type %S) removed", ctype);
http_header_add(m->headers, "Content-Type", "text/plain");
octstr_destroy(m->body); http_header_remove_all(h, "Content-Type");
m->body = octstr_format("Unsupported object (content type %S) removed", ctype); http_header_add(h, "Content-Type", "text/plain");
mime_replace_headers(m, h);
http_destroy_headers(h);
while (mime_entity_num_parts(m) > 0) /* Delete all parts, if any. */
mime_entity_remove_part(m, 0);
mime_entity_set_body(m, s);
octstr_destroy(s);
} }
static void mktmpfname(char fname[]) static void mktmpfname(char fname[])
@ -627,7 +634,7 @@ static Octstr *mknewname(Octstr *oldname, char *ext)
static void replace_ctype(List *headers, char *newcontent_type, List *params_h) static void replace_ctype(List *headers, char *newcontent_type, List *params_h)
{ {
Octstr *ct; Octstr *ct;
if (list_len(params_h) > 0) { if (gwlist_len(params_h) > 0) {
Octstr *tmp = make_value_parameters(params_h); Octstr *tmp = make_value_parameters(params_h);
ct = octstr_format("%s; %S", newcontent_type, tmp); ct = octstr_format("%s; %S", newcontent_type, tmp);
octstr_destroy(tmp); octstr_destroy(tmp);
@ -645,10 +652,11 @@ static void replace_body(MIMEEntity *msg, Octstr *newbody, List *params_h,
{ {
Octstr *part_name; Octstr *part_name;
Octstr *new_partname = NULL; Octstr *new_partname = NULL;
List *h = _x_mime_entity_headers(msg);
octstr_destroy(msg->body); /* Replace the body. */
msg->body = newbody; mime_entity_set_body(msg, newbody); /* Replace the body. */
octstr_destroy(newbody);
if ((part_name = http_header_value(params_h, octstr_imm("name"))) != NULL) { if ((part_name = http_header_value(params_h, octstr_imm("name"))) != NULL) {
Octstr *tmp = mknewname(part_name, file_ext); Octstr *tmp = mknewname(part_name, file_ext);
http_header_remove_all(params_h, "name"); http_header_remove_all(params_h, "name");
@ -658,15 +666,16 @@ static void replace_body(MIMEEntity *msg, Octstr *newbody, List *params_h,
new_partname = tmp; new_partname = tmp;
} }
replace_ctype(msg->headers, newcontent_type, params_h); replace_ctype(h, newcontent_type, params_h);
if (add_disposition_header) { if (add_disposition_header) {
Octstr *tmp = octstr_format("inline; filename=\"%S\"", Octstr *tmp = octstr_format("inline; filename=\"%S\"",
new_partname ? new_partname : octstr_imm("any")); new_partname ? new_partname : octstr_imm("any"));
http_header_add(msg->headers, "Content-Disposition", octstr_get_cstr(tmp)); http_header_add(h, "Content-Disposition", octstr_get_cstr(tmp));
octstr_destroy(tmp); octstr_destroy(tmp);
} }
mime_replace_headers(msg,h);
http_destroy_headers(h);
if (new_partname) octstr_destroy(new_partname); if (new_partname) octstr_destroy(new_partname);
} }
@ -688,45 +697,51 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
FILE *pf; FILE *pf;
char tmpf[40], tmpf2[40]; char tmpf[40], tmpf2[40];
Octstr *cmd = NULL; Octstr *cmd = NULL;
List *h = NULL;
if (!msg) return 0; if (!msg) return 0;
tmpf[0] = tmpf2[0] = 0; /* Clear .*/ tmpf[0] = tmpf2[0] = 0; /* Clear .*/
/* Get the content type, hash it. */ /* Get the content type, hash it. */
h = _x_mime_entity_headers(msg);
get_content_type(msg->headers, &content_type, &params); get_content_type(h, &content_type, &params);
params_h = get_value_parameters(params); params_h = get_value_parameters(params);
#if 0 #if 0
debug("MMS uaprof:", 0, " content_type = ### %s & %s: Header dump follows:", debug("MMS uaprof:", 0, " content_type = ### %s & %s: Header dump follows:",
octstr_get_cstr(content_type), params ? octstr_get_cstr(params) : "NULL"); octstr_get_cstr(content_type), params ? octstr_get_cstr(params) : "NULL");
http_header_dump(params_h); http_header_dump(params_h);
#endif #endif
if (msg->multiparts && list_len(msg->multiparts) > 0) { if ((n = mime_entity_num_parts(msg)) > 0) {
Octstr *startp = http_header_value(params_h, octstr_imm("start")); Octstr *startp = http_header_value(params_h, octstr_imm("start"));
int sflag = 0; int sflag = 0;
for (i = 0, n = list_len(msg->multiparts); i<n; i++) { for (i = 0; i<n; i++) {
MIMEEntity *x = list_get(msg->multiparts,i); MIMEEntity *x = mime_entity_get_part(msg,i);
Octstr *cid = http_header_value(x->headers, octstr_imm("Content-ID")); List *hx = _x_mime_entity_headers(x);
Octstr *cid = _x_get_content_id(hx);
int sup; int sup;
debug("MMS uaprof: cid =###", 0, "%s", cid ? octstr_get_cstr(cid) : "NULL"); debug("MMS uaprof: cid =###", 0, "%s", cid ? octstr_get_cstr(cid) : "NULL");
sup = modify_msg(x, prof); sup = modify_msg(x, prof);
if (!sup && /* not supported and is the presentation part, set flag */ if (!sup && /* not supported and is the presentation part, set flag */
cid && octstr_compare(cid, startp) == 0) cid && octstr_compare(cid, startp) == 0)
sflag = 1; sflag = 1;
if (cid) octstr_destroy(cid); if (cid) octstr_destroy(cid);
mime_entity_replace_part(msg, i, x); /* Put back changed one */
http_destroy_headers(hx);
mime_entity_destroy(x);
} }
/* If no start param but content type is other than multipart/mixed OR /* If no start param but content type is other than multipart/mixed OR
* There is a start param but presentation type is not supported, * There is a start param but presentation type is not supported,
* Or presentations are not supported. * Or presentations are not supported.
*/ */
if (sflag || if (sflag ||
(!startp && (!startp &&
octstr_case_compare(content_type, octstr_imm("multipart/related")) == 0) || octstr_case_compare(content_type, octstr_imm("multipart/related")) == 0) ||
@ -734,15 +749,15 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
/* MMS conformance guide says: If presentation part is removed or unsupported, /* MMS conformance guide says: If presentation part is removed or unsupported,
* then change content type to multipart/mixed * then change content type to multipart/mixed
*/ */
http_header_remove_all(params_h, "start"); http_header_remove_all(params_h, "start");
http_header_remove_all(params_h, "type"); http_header_remove_all(params_h, "type");
replace_ctype(msg->headers, "multipart/mixed", params_h); replace_ctype(h, "multipart/mixed", params_h);
} }
if (startp) octstr_destroy(startp); if (startp) octstr_destroy(startp);
supported = 1; supported = 1;
goto done; goto done;
} }
@ -769,21 +784,21 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
charset = octstr_imm(DEFAULT_CHARSET); charset = octstr_imm(DEFAULT_CHARSET);
} }
n = prof->ccppaccept.charset ? list_len(prof->ccppaccept.charset) : 0; n = prof->ccppaccept.charset ? gwlist_len(prof->ccppaccept.charset) : 0;
/* Is this character set supported? If so do nothing. */ /* Is this character set supported? If so do nothing. */
for (i = 0; i<n; i++) for (i = 0; i<n; i++)
if (octstr_case_compare(list_get(prof->ccppaccept.charset,i), charset) == 0) { if (octstr_case_compare(gwlist_get(prof->ccppaccept.charset,i), charset) == 0) {
csupport = 1; csupport = 1;
break; break;
} }
if (!csupport) if (!csupport)
for (i = 0; i<n; i++) { for (i = 0; i<n; i++) {
Octstr *ncharset = list_get(prof->ccppaccept.charset,i); /* Don't free this! */ Octstr *ncharset = gwlist_get(prof->ccppaccept.charset,i); /* Don't free this! */
Octstr *ct; Octstr *ct;
Octstr *s = mime_entity_body(msg);
if (charset_convert(msg->body, octstr_get_cstr(charset), if (charset_convert(s, octstr_get_cstr(charset),
octstr_get_cstr(ncharset)) != -1) { /* using libiconv...*/ octstr_get_cstr(ncharset)) != -1) { /* using libiconv...*/
Octstr *tmp; Octstr *tmp;
@ -793,12 +808,14 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
ct = octstr_format("%S; %S", content_type, tmp); ct = octstr_format("%S; %S", content_type, tmp);
octstr_destroy(tmp); octstr_destroy(tmp);
http_header_remove_all(msg->headers, "Content-Type"); http_header_remove_all(h, "Content-Type");
http_header_add(msg->headers, "Content-Type", octstr_get_cstr(ct)); http_header_add(h, "Content-Type", octstr_get_cstr(ct));
octstr_destroy(ct); octstr_destroy(ct);
mime_entity_set_body(msg,s); /* replace with new body. */
break; /* We succeeded in converting it so we shd go away. */ break; /* We succeeded in converting it so we shd go away. */
} } else
octstr_destroy(s);
} }
octstr_destroy(charset); octstr_destroy(charset);
@ -811,10 +828,10 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
if (prof->ccppaccept.all) /* Check if it accepts all content types. */ if (prof->ccppaccept.all) /* Check if it accepts all content types. */
supported = 1; supported = 1;
else else
for (i = 0, n = prof->ccppaccept.content ? list_len(prof->ccppaccept.content) : 0; for (i = 0, n = prof->ccppaccept.content ? gwlist_len(prof->ccppaccept.content) : 0;
i<n; i++) i<n; i++)
if ((unsigned long)list_get(prof->ccppaccept._hash,i) == chash && if ((unsigned long)gwlist_get(prof->ccppaccept._hash,i) == chash &&
octstr_case_compare(list_get(prof->ccppaccept.content,i),content_type) == 0) { octstr_case_compare(gwlist_get(prof->ccppaccept.content,i),content_type) == 0) {
supported = 1; supported = 1;
break; break;
} }
@ -847,10 +864,10 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
oindex = -1; oindex = -1;
for (i = 0; i < NELEMS(cformats); i++) for (i = 0; i < NELEMS(cformats); i++)
if (cformats[i].fromstandard_cmd) /* Check only ones we can convert from. */ if (cformats[i].fromstandard_cmd) /* Check only ones we can convert from. */
for (j = 0, m = list_len(prof->ccppaccept.content); j<m; j++) for (j = 0, m = gwlist_len(prof->ccppaccept.content); j<m; j++)
if ((unsigned long)list_get(prof->ccppaccept._hash,j) == cformats[i].chash && if ((unsigned long)gwlist_get(prof->ccppaccept._hash,j) == cformats[i].chash &&
cformats[i].t == type && /* Convert to like type ! */ cformats[i].t == type && /* Convert to like type ! */
octstr_case_compare(list_get(prof->ccppaccept.content,j), octstr_case_compare(gwlist_get(prof->ccppaccept.content,j),
octstr_imm(cformats[i].content_type)) == 0){ octstr_imm(cformats[i].content_type)) == 0){
oindex = i; oindex = i;
i = NELEMS(cformats); /* So the other loop breaks too. */ i = NELEMS(cformats); /* So the other loop breaks too. */
@ -858,18 +875,16 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
} }
if (iindex < 0 || oindex < 0) { /* We don't know how to convert this one fully, so... */ if (iindex < 0 || oindex < 0) /* We don't know how to convert this one fully, so... */
if (!supported) goto done2; /* go away, don't even replace headers. */
remove_object(msg, content_type);
goto done;
}
/* Whatever we have (audio or image) we know how to convert it fully, so ... */ /* Whatever we have (audio or image) we know how to convert it fully, so ... */
mktmpfname(tmpf); mktmpfname(tmpf);
if (type == TIMAGE) { if (type == TIMAGE) {
FILE *pf; FILE *pf;
long x = 640, y = 480; long x = 640, y = 480;
Octstr *icmd; Octstr *icmd, *s;
char *selector; char *selector;
mktmpfname(tmpf2); mktmpfname(tmpf2);
@ -877,9 +892,11 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
if (!pf) if (!pf)
goto done; goto done;
n = octstr_print(pf, msg->body); s = mime_entity_body(msg);
n = octstr_print(pf, s);
m = fclose(pf); m = fclose(pf);
octstr_destroy(s);
if (n < 0 || m != 0) if (n < 0 || m != 0)
goto done; /* error .*/ goto done; /* error .*/
@ -918,7 +935,7 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
cformats[oindex].file_ext, tmpf); cformats[oindex].file_ext, tmpf);
octstr_destroy(icmd); octstr_destroy(icmd);
} else } else
cmd = octstr_format("cat %S | " IMGCONVERTCMD, cmd = octstr_format("cat %s | " IMGCONVERTCMD,
tmpf2, cformats[iindex].file_ext, selector, tmpf2, cformats[iindex].file_ext, selector,
cformats[oindex].file_ext, tmpf); cformats[oindex].file_ext, tmpf);
@ -935,29 +952,35 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
if (!pf) if (!pf)
goto done; goto done;
if (send_data) /* If this is not set then write the content... */ if (send_data) { /* If this is not set then write the content... */
n = octstr_print(pf, msg->body); Octstr *sx = mime_entity_body(msg);
else n = octstr_print(pf, sx);
octstr_destroy(sx);
} else
n = 0; n = 0;
m = pclose(pf); m = pclose(pf);
if (n < 0 || m != 0) if (n < 0 || m != 0)
goto done; /* Error -- finish up. */ goto done; /* Error -- finish up. */
s = octstr_read_file(tmpf); if ((s = octstr_read_file(tmpf)) != NULL) {
if (s)
replace_body(msg, s, params_h, replace_body(msg, s, params_h,
cformats[oindex].content_type, cformats[oindex].content_type,
cformats[oindex].file_ext,0); cformats[oindex].file_ext,0);
else supported = 1;
goto done2; /* we are done, don't even change headers. */
} else /* failed to convert, hence unsupported. */
goto done; goto done;
supported = 1; /* Means we have sorted it out. */
done: done:
if (h)
mime_replace_headers(msg,h);
done2:
if (!supported) if (!supported)
remove_object(msg, content_type); remove_object(msg, content_type);
if (h)
http_destroy_headers(h);
if (content_type) if (content_type)
octstr_destroy(content_type); octstr_destroy(content_type);
if (params) if (params)
@ -1023,66 +1046,71 @@ static int format_special(MIMEEntity *m,
char tmpf[40]; char tmpf[40];
Octstr *cmd = NULL; Octstr *cmd = NULL;
List *params_h; List *params_h;
List *headers;
tmpf[0] = 0; tmpf[0] = 0;
get_content_type(m->headers, &content_type, &params); headers = _x_mime_entity_headers(m);
get_content_type(headers, &content_type, &params);
params_h = get_value_parameters(params); params_h = get_value_parameters(params);
if (m->multiparts && list_len(m->multiparts) > 0) { if ((n = mime_entity_num_parts(m)) > 0) {
MIMEEntity *pres = NULL;
int presindex = -1; int presindex = -1;
Octstr *presbody; Octstr *presbody;
Octstr *start = http_header_value(params_h, octstr_imm("start")); Octstr *start = http_header_value(params_h, octstr_imm("start"));
for (i = 0, n = list_len(m->multiparts); i<n; i++) {/* format sub-parts, for (i = 0; i<n; i++) {/* format sub-parts, find presentation part too */
* find presentation part too MIMEEntity *x = mime_entity_get_part(m,i);
*/
MIMEEntity *x = list_get(m->multiparts,i);
Octstr *ctype = NULL, *charset = NULL; Octstr *ctype = NULL, *charset = NULL;
Octstr *cid = http_header_value(x->headers, octstr_imm("Content-ID")); List *hx = _x_mime_entity_headers(x);
Octstr *cid = _x_get_content_id(hx);
http_header_get_content_type(x->headers, &ctype, &charset); http_header_get_content_type(hx, &ctype, &charset);
/* Find presentation part: If we have start param, and it matches /* Find presentation part: If we have start param, and it matches
* this one, and this one is SMIL, then... * this one, and this one is SMIL, then...
*/ */
if (start && cid && octstr_compare(cid, start) == 0 && if (start && cid && octstr_compare(cid, start) == 0 &&
octstr_case_compare(ctype, octstr_imm(PRES_TYPE)) == 0) { octstr_case_compare(ctype, octstr_imm(PRES_TYPE)) == 0)
pres = x;
presindex = i; presindex = i;
}
if (ctype) octstr_destroy(ctype); if (ctype) octstr_destroy(ctype);
if (charset) octstr_destroy(charset); if (charset) octstr_destroy(charset);
if (cid) octstr_destroy(cid); if (cid) octstr_destroy(cid);
format_special(x, trans_smil, txtmsg, htmlmsg, counter); format_special(x, trans_smil, txtmsg, htmlmsg, counter);
mime_entity_replace_part(m, i, x);
http_destroy_headers(hx);
mime_entity_destroy(x);
} }
if (start) octstr_destroy(start); if (start) octstr_destroy(start);
if (trans_smil && pres) { /* Reformat. */ if (trans_smil && presindex >= 0) { /* Reformat. */
MIMEEntity *x; MIMEEntity *x, *pres;
Octstr *btxt = octstr_create(""); Octstr *btxt = octstr_create("");
List *h = NULL, *h2 = NULL;
Octstr *tmp;
/* Remove type & start param from top level. */ /* Remove type & start param from top level. */
http_header_remove_all(params_h, "type"); http_header_remove_all(params_h, "type");
http_header_remove_all(params_h, "start"); replace_ctype(headers, "multipart/related", params_h);
replace_ctype(m->headers, "multipart/related", params_h);
/* Put content ids on all siblings, and build html. */ /* Put content ids on all siblings, and build html. */
for (i = 0, n = list_len(m->multiparts); i<n; i++) { for (i = 0, n = mime_entity_num_parts(m); i<n; i++) {
MIMEEntity *x = list_get(m->multiparts,i); MIMEEntity *x = mime_entity_get_part(m,i);
List *hx = NULL;
Octstr *cid, *pname; Octstr *cid, *pname;
Octstr *ctype = NULL, *cparams = NULL; Octstr *ctype = NULL, *cparams = NULL;
Octstr *y, *loc, *cidurl; Octstr *y, *loc, *cidurl;
List *cparamsl; List *cparamsl;
if (x == pres) continue; /* Skip the presentation param. */ if (i == presindex) continue; /* Skip the presentation param. */
cid = http_header_value(x->headers, octstr_imm("Content-ID")); hx = _x_mime_entity_headers(x);
cid = _x_get_content_id(hx);
if (cid == NULL) { if (cid == NULL) {
time_t t = time(NULL); time_t t = time(NULL);
char ch[2]; char ch[2];
@ -1091,17 +1119,23 @@ static int format_special(MIMEEntity *m,
ch[1] = 0; ch[1] = 0;
cid = octstr_format("<item-%s-%d-%d>", ch, *counter, (t%99989)); cid = octstr_format("<item-%s-%d-%d>", ch, *counter, (t%99989));
http_header_add(x->headers, "Content-ID", octstr_get_cstr(cid)); http_header_add(hx, "Content-ID", octstr_get_cstr(cid));
++*counter; ++*counter;
} else if (octstr_get_char(cid, 0) != '<') { /* fix up for badly behaved clients. */
octstr_insert_char(cid, 0, '<');
octstr_append_char(cid, '>');
http_header_remove_all(hx, "Content-ID");
http_header_add(hx, "Content-ID", octstr_get_cstr(cid));
} }
y = octstr_copy(cid, 1, octstr_len(cid) - 2); y = octstr_copy(cid, 1, octstr_len(cid) - 2);
loc = http_header_value(x->headers, octstr_imm("Content-Location")); loc = http_header_value(hx, octstr_imm("Content-Location"));
cidurl = octstr_duplicate(y); cidurl = octstr_duplicate(y);
octstr_url_encode(cidurl); octstr_url_encode(cidurl);
get_content_type(x->headers, &ctype, &cparams); /* Get type of object. */ get_content_type(hx, &ctype, &cparams); /* Get type of object. */
if (cparams) { /* Get its name. */ if (cparams) { /* Get its name. */
if ((cparamsl = get_value_parameters(cparams)) != NULL) { if ((cparamsl = get_value_parameters(cparams)) != NULL) {
@ -1116,10 +1150,12 @@ static int format_special(MIMEEntity *m,
if (octstr_case_search(ctype, octstr_imm("image/"), 0) == 0) if (octstr_case_search(ctype, octstr_imm("image/"), 0) == 0)
octstr_format_append(btxt, octstr_format_append(btxt,
"\n<img src=\"cid:%S\" border=0 alt=\"%S\"><br><br>\n", "\n<img src=\"cid:%S\" border=0 alt=\"%S\"><br><br>\n",
cidurl, pname); cidurl, pname ? pname : octstr_imm("image"));
else if (octstr_case_search(ctype, octstr_imm("text/"), 0) == 0) else if (octstr_case_search(ctype, octstr_imm("text/"), 0) == 0) {
octstr_format_append(btxt, "%S<br><br>\n", Octstr *s = mime_entity_body(x);
x->body ? x->body : octstr_imm("")); octstr_format_append(btxt, "%S<br><br>\n", s);
octstr_destroy(s);
}
#if 0 #if 0
else if (octstr_case_search(ctype, octstr_imm("audio/"), 0) == 0) else if (octstr_case_search(ctype, octstr_imm("audio/"), 0) == 0)
octstr_format_append(btxt, octstr_format_append(btxt,
@ -1129,10 +1165,16 @@ static int format_special(MIMEEntity *m,
else else
octstr_format_append(btxt, octstr_format_append(btxt,
"<a type=\"%S\" href=\"cid:%S\">%S</a><br><br>\n", "<a type=\"%S\" href=\"cid:%S\">%S</a><br><br>\n",
ctype, cidurl, pname); ctype, cidurl, pname ? pname : octstr_imm(""));
http_header_remove_all(hx, "Content-Location");
mime_replace_headers(x, hx); /* put back headers, replace part in main...*/
mime_entity_replace_part(m, i, x);
http_destroy_headers(hx);
mime_entity_destroy(x);
http_header_remove_all(x->headers, "Content-Location");
if (y) octstr_destroy(y); if (y) octstr_destroy(y);
if (loc) octstr_destroy(loc); if (loc) octstr_destroy(loc);
if (ctype) octstr_destroy(ctype); if (ctype) octstr_destroy(ctype);
@ -1142,50 +1184,69 @@ static int format_special(MIMEEntity *m,
octstr_destroy(cid); octstr_destroy(cid);
} }
pres = mime_entity_get_part(m,presindex);
presbody = mime_entity_body(pres);
h = _x_mime_entity_headers(pres);
http_header_remove_all(pres->headers, "Content-Type"); http_header_remove_all(h, "Content-Type");
http_header_add(pres->headers, "Content-Type", "multipart/alternative"); http_header_add(h, "Content-Type", "multipart/alternative");
presbody = pres->body; mime_replace_headers(pres,h);
pres->body = NULL; http_destroy_headers(h);
if (!pres->multiparts)
pres->multiparts = list_create();
/* first the text part ... */ /* first the text part ... */
x = mime_entity_create(); x = mime_entity_create();
http_header_add(x->headers, "Content-Type", "text/plain"); h2 = http_create_empty_headers();
x->body = octstr_create(txtmsg ? txtmsg : ""); http_header_add(h2, "Content-Type", "text/plain");
list_append(pres->multiparts, x); tmp = octstr_create(txtmsg ? txtmsg : "");
mime_replace_headers(x, h2);
mime_entity_set_body(x,tmp);
mime_entity_add_part(pres, x);
http_destroy_headers(h2);
octstr_destroy(tmp);
mime_entity_destroy(x);
/* Lets also leave the pres part in there, just in case somebody knows how to handle it... */ /* Lets also leave the pres part in there, just in case somebody knows how to handle it... */
x = mime_entity_create(); x = mime_entity_create();
http_header_add(x->headers, "Content-Type", PRES_TYPE); h2 = http_create_empty_headers();
x->body = presbody; http_header_add(h2, "Content-Type", PRES_TYPE);
list_append(pres->multiparts, x); mime_replace_headers(x, h2);
mime_entity_set_body(x, presbody);
mime_entity_add_part(pres, x);
http_destroy_headers(h2);
mime_entity_destroy(x);
/* then the html part. */ /* then the html part. */
x = mime_entity_create(); x = mime_entity_create();
http_header_add(x->headers, "Content-Type", "text/html"); h2 = http_create_empty_headers();
x->body = octstr_format("<html><body><center>%s<hr><br>%S<hr></center></body></html>\n", http_header_add(h2, "Content-Type", "text/html");
tmp = octstr_format("<html><body><center>%s<hr><br>%S<hr></center></body></html>\n",
htmlmsg ? htmlmsg : "", btxt); htmlmsg ? htmlmsg : "", btxt);
list_append(pres->multiparts, x);
list_delete(m->multiparts, presindex, 1); /* Put it at the beginning. */
list_insert(m->multiparts, 0, pres);
#if 0
http_header_remove_all(pres->headers, "Content-ID"); /* Not needed anymore. */
#endif
octstr_destroy(btxt);
mime_replace_headers(x, h2);
mime_entity_set_body(x,tmp);
mime_entity_add_part(pres, x);
http_destroy_headers(h2);
octstr_destroy(tmp);
mime_entity_destroy(x);
mime_entity_replace_part(m, presindex, pres);
mime_entity_destroy(pres);
octstr_destroy(btxt);
} }
goto done; goto done;
} }
if (octstr_case_search(content_type, octstr_imm("image/"), 0) == 0) if (octstr_case_search(content_type, octstr_imm("image/"), 0) == 0)
type = TIMAGE; type = TIMAGE;
else if (octstr_case_search(content_type, octstr_imm("audio/"), 0) == 0) else if (octstr_case_search(content_type, octstr_imm("audio/"), 0) == 0)
@ -1232,15 +1293,17 @@ static int format_special(MIMEEntity *m,
pf = popen(octstr_get_cstr(cmd), "w"); pf = popen(octstr_get_cstr(cmd), "w");
if (!pf) if (!pf)
goto done; goto done;
n = octstr_print(pf, m->body); s = mime_entity_body(m);
n = octstr_print(pf, s);
octstr_destroy(s);
o = pclose(pf); o = pclose(pf);
if (n < 0 || o != 0) if (n < 0 || o != 0)
goto done; /* Error -- finish up. */ goto done; /* Error -- finish up. */
s = octstr_read_file(tmpf); if ((s = octstr_read_file(tmpf)) != NULL)
if (s)
replace_body(m, s, params_h, replace_body(m, s, params_h,
cformats[ipref].content_type, cformats[ipref].content_type,
cformats[ipref].file_ext,1); cformats[ipref].file_ext,1);
@ -1249,6 +1312,7 @@ static int format_special(MIMEEntity *m,
} else if (type == TTEXT) {/* change to default charset. */ } else if (type == TTEXT) {/* change to default charset. */
Octstr *charset = http_header_value(params_h, octstr_imm("charset")); Octstr *charset = http_header_value(params_h, octstr_imm("charset"));
Octstr *s;
if (charset == NULL || if (charset == NULL ||
octstr_case_compare(charset, octstr_imm("unknown")) == 0 || octstr_case_compare(charset, octstr_imm("unknown")) == 0 ||
octstr_case_compare(charset, octstr_imm(DEFAULT_CHARSET)) == 0) { octstr_case_compare(charset, octstr_imm(DEFAULT_CHARSET)) == 0) {
@ -1256,7 +1320,8 @@ static int format_special(MIMEEntity *m,
goto done; /* Nothing more to do here. */ goto done; /* Nothing more to do here. */
} }
if (charset_convert(m->body, octstr_get_cstr(charset), s = mime_entity_body(m);
if (charset_convert(s, octstr_get_cstr(charset),
DEFAULT_CHARSET) != -1) { /* using libiconv...*/ DEFAULT_CHARSET) != -1) { /* using libiconv...*/
Octstr *tmp, *ct; Octstr *tmp, *ct;
@ -1266,18 +1331,20 @@ static int format_special(MIMEEntity *m,
ct = octstr_format("%S; %S", content_type, tmp); ct = octstr_format("%S; %S", content_type, tmp);
octstr_destroy(tmp); octstr_destroy(tmp);
http_header_remove_all(m->headers, "Content-Type"); http_header_remove_all(headers, "Content-Type");
http_header_add(m->headers, "Content-Type", octstr_get_cstr(ct)); http_header_add(headers, "Content-Type", octstr_get_cstr(ct));
octstr_destroy(ct); octstr_destroy(ct);
mime_entity_set_body(m, s);
} /* Else goto done. */ } /* Else goto done. */
octstr_destroy(s);
} /* Else do nothing. */ } /* Else do nothing. */
done: done:
if (headers) {
mime_replace_headers(m, headers);
http_destroy_headers(headers);
}
if (content_type) if (content_type)
octstr_destroy(content_type); octstr_destroy(content_type);
if (params_h) if (params_h)
@ -1296,7 +1363,7 @@ int mms_format_special(MmsMsg *inmsg,
char *txtmsg, char *txtmsg,
char *htmlmsg, MIMEEntity **outmsg) char *htmlmsg, MIMEEntity **outmsg)
{ {
MIMEEntity *m = mms_tomime(inmsg,0); MIMEEntity *m = mms_tomime(inmsg,0);
int ct = 0; int ct = 0;
if (!m) if (!m)

View File

@ -70,17 +70,20 @@ int mms_load_core_settings(mCfgGrp *cgrp)
octstr_imm("http-proxy-password")); octstr_imm("http-proxy-password"));
List *exceptions = mms_cfg_get_list(cgrp, List *exceptions = mms_cfg_get_list(cgrp,
octstr_imm("http-proxy-exceptions")); octstr_imm("http-proxy-exceptions"));
Octstr *except_regex = mms_cfg_get(cgrp,
octstr_imm("http-proxy-exceptions-regex"));
long http_proxy_port = -1; long http_proxy_port = -1;
mms_cfg_get_int(cgrp, octstr_imm("http-proxy-port"), &http_proxy_port); mms_cfg_get_int(cgrp, octstr_imm("http-proxy-port"), &http_proxy_port);
if (http_proxy_port > 0) if (http_proxy_port > 0)
http_use_proxy(http_proxy_host, http_proxy_port, http_use_proxy(http_proxy_host, http_proxy_port,
exceptions, username, password); exceptions, username, password, except_regex);
octstr_destroy(http_proxy_host); octstr_destroy(http_proxy_host);
octstr_destroy(username); octstr_destroy(username);
octstr_destroy(password); octstr_destroy(password);
list_destroy(exceptions, octstr_destroy_item); octstr_destroy(except_regex);
gwlist_destroy(exceptions, octstr_destroy_item);
} }
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
@ -283,7 +286,7 @@ static int needs_quotes(Octstr *s)
for (i = 0, n = octstr_len(s); i<n; i++) { for (i = 0, n = octstr_len(s); i<n; i++) {
int ch = octstr_get_char(s,i); int ch = octstr_get_char(s,i);
if (isspace(ch) || ispunct(ch)) if (isspace(ch) || ch == '=' || ch == ';' || ch == '<' || ch == '>')
return 1; return 1;
} }
return 0; return 0;
@ -294,7 +297,7 @@ Octstr *make_value_parameters(List *params)
Octstr *s = octstr_create(""), *name, *value; Octstr *s = octstr_create(""), *name, *value;
int i, n; int i, n;
for (i = 0, n = params ? list_len(params) : 0; i<n; i++) { for (i = 0, n = params ? gwlist_len(params) : 0; i<n; i++) {
int space; int space;
http_header_get(params, i, &name, &value); http_header_get(params, i, &name, &value);
space = needs_quotes(value); space = needs_quotes(value);
@ -318,15 +321,16 @@ void unpack_mimeheaders(MIMEEntity *mm)
{ {
int i, n; int i, n;
List *h = http_create_empty_headers(); List *h = http_create_empty_headers();
List *headers = _x_mime_entity_headers(mm);
for (i = 0, n = list_len(mm->headers); i<n; i++) {
for (i = 0, n = gwlist_len(headers); i<n; i++) {
Octstr *header = NULL, *value = NULL; Octstr *header = NULL, *value = NULL;
List *l = NULL; List *l = NULL;
int j, m; int j, m;
int skip; int skip;
http_header_get(mm->headers, i, &header, &value); http_header_get(headers, i, &header, &value);
if (header == NULL || if (header == NULL ||
octstr_str_compare(header, "X-Unknown") == 0 || octstr_str_compare(header, "X-Unknown") == 0 ||
@ -342,23 +346,25 @@ void unpack_mimeheaders(MIMEEntity *mm)
/* XXX This may not be safe. Need to skip over quotes. */ /* XXX This may not be safe. Need to skip over quotes. */
if (!skip && octstr_search_char(value, ',', 0) > 0 && if (!skip && octstr_search_char(value, ',', 0) > 0 &&
(l = http_header_split_value(value)) != NULL && (l = http_header_split_value(value)) != NULL &&
list_len(l) > 1) gwlist_len(l) > 1)
for (j = 0, m = list_len(l); j<m; j++) for (j = 0, m = gwlist_len(l); j<m; j++)
http_header_add(h, octstr_get_cstr(header), http_header_add(h, octstr_get_cstr(header),
octstr_get_cstr(list_get(l, j))); octstr_get_cstr(gwlist_get(l, j)));
else else
http_header_add(h, octstr_get_cstr(header), http_header_add(h, octstr_get_cstr(header),
octstr_get_cstr(value)); octstr_get_cstr(value));
if (l) list_destroy(l, (list_item_destructor_t *)octstr_destroy); if (l) gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
loop: loop:
if (header) octstr_destroy(header); if (header) octstr_destroy(header);
if (value) octstr_destroy(value); if (value) octstr_destroy(value);
} }
http_destroy_headers(mm->headers); mime_replace_headers(mm, h);
mm->headers = h; http_destroy_headers(headers);
http_destroy_headers(h);
} }
@ -366,26 +372,36 @@ void unpack_mimeheaders(MIMEEntity *mm)
void unbase64_mimeparts(MIMEEntity *m) void unbase64_mimeparts(MIMEEntity *m)
{ {
int i, n; int i, n;
if (m->multiparts && list_len(m->multiparts) > 0) if ((n = mime_entity_num_parts(m)) > 0)
for (i = 0, n = list_len(m->multiparts); i<n; i++) for (i = 0; i<n; i++) {
unbase64_mimeparts(list_get(m->multiparts, i)); MIMEEntity *x = mime_entity_get_part(m, i);
unbase64_mimeparts(x);
mime_entity_replace_part(m, i, x);
mime_entity_destroy(x);
}
else { /* A non-multipart message .*/ else { /* A non-multipart message .*/
Octstr *ctype = http_header_value(m->headers, octstr_imm("Content-Type")); List *headers = _x_mime_entity_headers(m);
Octstr *te = http_header_value(m->headers, octstr_imm("Content-Transfer-Encoding")); Octstr *ctype = http_header_value(headers, octstr_imm("Content-Type"));
Octstr *te = http_header_value(headers, octstr_imm("Content-Transfer-Encoding"));
if (ctype && te && if (ctype && te &&
octstr_case_compare(te,octstr_imm("base64")) == 0) octstr_case_compare(te,octstr_imm("base64")) == 0) {
octstr_base64_to_binary(m->body); Octstr *s = mime_entity_body(m);
octstr_base64_to_binary(s);
mime_entity_set_body(m, s);
octstr_destroy(s);
}
http_header_remove_all(headers, "Content-Transfer-Encoding"); /* Remove it in all cases (?).*/
mime_replace_headers(m, headers);
http_header_remove_all(m->headers, "Content-Transfer-Encoding"); /* Remove it in all cases (?).*/
/* XXX may be we should deal with other transfer encodings here as well... */ /* XXX may be we should deal with other transfer encodings here as well... */
if (ctype) if (ctype)
octstr_destroy(ctype); octstr_destroy(ctype);
if (te) if (te)
octstr_destroy(te); octstr_destroy(te);
http_destroy_headers(headers);
} }
} }
@ -400,31 +416,35 @@ void base64_mimeparts(MIMEEntity *m)
{ {
int i, n; int i, n;
if (m->multiparts && list_len(m->multiparts) > 0) if ((n = mime_entity_num_parts(m)) > 0)
for (i = 0, n = list_len(m->multiparts); i<n; i++) for (i = 0; i<n; i++) {
base64_mimeparts(list_get(m->multiparts, i)); MIMEEntity *x = mime_entity_get_part(m, i);
base64_mimeparts(x);
mime_entity_replace_part(m, i, x);
mime_entity_destroy(x);
}
else { /* A non-multipart message .*/ else { /* A non-multipart message .*/
Octstr *ctype = http_header_value(m->headers, octstr_imm("Content-Type")); List *headers = _x_mime_entity_headers(m);
Octstr *te = http_header_value(m->headers, octstr_imm("Content-Transfer-Encoding")); Octstr *ctype = http_header_value(headers, octstr_imm("Content-Type"));
Octstr *te = http_header_value(headers, octstr_imm("Content-Transfer-Encoding"));
if (ctype && !te Octstr *body = mime_entity_body(m);
#if 1 if (ctype && !te &&
&& (body && octstr_check_range(body, 0, octstr_len(body), _mms_gw_isprint) == 0)) {
(m->body && octstr_check_range(m->body, 0, octstr_len(m->body), _mms_gw_isprint) == 0) octstr_binary_to_base64(body);
#endif
) { http_header_add(headers, "Content-Transfer-Encoding", "base64");
octstr_binary_to_base64(m->body); mime_entity_set_body(m, body);
http_header_add(m->headers, "Content-Transfer-Encoding", "base64"); mime_replace_headers(m, headers);
} }
if (ctype) if (ctype)
octstr_destroy(ctype); octstr_destroy(ctype);
if (te) if (te)
octstr_destroy(te); octstr_destroy(te);
octstr_destroy(body);
http_destroy_headers(headers);
} }
} }
static void addmmscname(Octstr *s, Octstr *myhostname) static void addmmscname(Octstr *s, Octstr *myhostname)
{ {
int j; int j;
@ -448,23 +468,24 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
Octstr *s; Octstr *s;
FILE *f; FILE *f;
int ret = MMS_SEND_OK, i; int ret = MMS_SEND_OK, i;
Octstr *cmd = octstr_create(""); Octstr *cmd = octstr_create("");
List *headers = mime_entity_headers(m); /* we don't want the mime version header removed. */
if (append_hostname) { /* Add our hostname to all phone numbers. */ if (append_hostname) { /* Add our hostname to all phone numbers. */
int i, n; int i, n;
List *l = http_create_empty_headers(); List *l = http_create_empty_headers();
Octstr *xfrom = http_header_value(m->headers, octstr_imm("From")); Octstr *xfrom = http_header_value(headers, octstr_imm("From"));
List *lto = http_header_find_all(m->headers, "To"); List *lto = http_header_find_all(headers, "To");
List *lcc = http_header_find_all(m->headers, "Cc"); List *lcc = http_header_find_all(headers, "Cc");
if (xfrom) { if (xfrom) {
addmmscname(xfrom, myhostname); addmmscname(xfrom, myhostname);
http_header_add(l, "From", octstr_get_cstr(xfrom)); http_header_add(l, "From", octstr_get_cstr(xfrom));
octstr_destroy(xfrom); octstr_destroy(xfrom);
} }
http_header_remove_all(m->headers, "From"); http_header_remove_all(headers, "From");
for (i = 0, n = list_len(lto); i < n; i++) { for (i = 0, n = gwlist_len(lto); i < n; i++) {
Octstr *name, *value; Octstr *name, *value;
http_header_get(lto, i, &name, &value); http_header_get(lto, i, &name, &value);
@ -481,9 +502,9 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
} }
http_destroy_headers(lto); http_destroy_headers(lto);
http_header_remove_all(m->headers, "To"); http_header_remove_all(headers, "To");
for (i = 0, n = list_len(lcc); i < n; i++) { for (i = 0, n = gwlist_len(lcc); i < n; i++) {
Octstr *name, *value; Octstr *name, *value;
http_header_get(lcc, i, &name, &value); http_header_get(lcc, i, &name, &value);
@ -500,14 +521,15 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
} }
http_destroy_headers(lcc); http_destroy_headers(lcc);
http_header_remove_all(m->headers, "Cc"); http_header_remove_all(headers, "Cc");
http_append_headers(m->headers, l); /* combine old with new. */ http_append_headers(headers, l); /* combine old with new. */
http_destroy_headers(l); http_destroy_headers(l);
} }
/* Pack headers, get string rep of mime entity. */ /* Pack headers, get string rep of mime entity. */
http_header_pack(m->headers); http_header_pack(headers);
mime_replace_headers(m, headers);
s = mime_entity_to_octstr(m); s = mime_entity_to_octstr(m);
/* /*
@ -601,6 +623,7 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
ret = MMS_SEND_OK; ret = MMS_SEND_OK;
done: done:
http_destroy_headers(headers);
octstr_destroy(cmd); octstr_destroy(cmd);
octstr_destroy(s); octstr_destroy(s);
return ret; return ret;
@ -618,7 +641,7 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
{ {
MIMEEntity *m = NULL; MIMEEntity *m = NULL;
List *headers = NULL;
List *newhdrs = http_create_empty_headers(); List *newhdrs = http_create_empty_headers();
int ret; int ret;
@ -629,7 +652,7 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
} }
if (!trans_msg) if (!trans_msg)
m = mms_tomime(msg,0); m = mms_tomime(msg,0);
else else
if ((ret = mms_format_special(msg, trans_smil, txt, html, &m)) < 0 || if ((ret = mms_format_special(msg, trans_smil, txt, html, &m)) < 0 ||
m == NULL) { m == NULL) {
@ -648,10 +671,12 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
http_header_add(newhdrs, "MIME-Version", "1.0"); http_header_add(newhdrs, "MIME-Version", "1.0");
http_header_combine(newhdrs, m->headers); headers = _x_mime_entity_headers(m);
http_destroy_headers(m->headers); http_header_combine(headers, newhdrs);
m->headers = newhdrs; mime_replace_headers(m, headers);
http_destroy_headers(headers);
http_destroy_headers(newhdrs);
ret = send2email(to, from, subject, msgid, m, append_hostname, error, sendmail_cmd, myhostname); ret = send2email(to, from, subject, msgid, m, append_hostname, error, sendmail_cmd, myhostname);
mime_entity_destroy(m); mime_entity_destroy(m);
@ -667,15 +692,15 @@ void mms_log2(char *logmsg, Octstr *from, Octstr *to,
{ {
List *l; List *l;
if (to) { if (to) {
l = list_create(); l = gwlist_create();
list_append(l, to); gwlist_append(l, to);
} else } else
l = NULL; l = NULL;
mms_log(logmsg, from,l,msize,msgid,acct,viaproxy,interface,ua,mmboxloc); mms_log(logmsg, from,l,msize,msgid,acct,viaproxy,interface,ua,mmboxloc);
if (l) if (l)
list_destroy(l, NULL); gwlist_destroy(l, NULL);
} }
void mms_log(char *logmsg, Octstr *from, List *to, void mms_log(char *logmsg, Octstr *from, List *to,
@ -685,13 +710,13 @@ void mms_log(char *logmsg, Octstr *from, List *to,
char *interface, Octstr *ua, Octstr *mmboxloc) char *interface, Octstr *ua, Octstr *mmboxloc)
{ {
Octstr *xto = octstr_create(""); Octstr *xto = octstr_create("");
int i, n = to ? list_len(to) : 0; int i, n = to ? gwlist_len(to) : 0;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
octstr_format_append(xto, octstr_format_append(xto,
"%s%S", "%s%S",
(i == 0) ? "" : ", ", (i == 0) ? "" : ", ",
list_get(to,i)); gwlist_get(to,i));
alog("%s MMS [INT:%s] [ACT:%s] [MMSC:%s] [from:%s] [to:%s] [msgid:%s] [size=%d] [UA:%s] [MMBox:%s]", alog("%s MMS [INT:%s] [ACT:%s] [MMSC:%s] [from:%s] [to:%s] [msgid:%s] [size=%d] [UA:%s] [MMBox:%s]",
logmsg, interface, logmsg, interface,
@ -758,28 +783,6 @@ int mm_lockfile(int fd, char *fname, int shouldblock)
return 0; return 0;
} }
MIMEEntity *mime_entity_duplicate(MIMEEntity *m)
{
MIMEEntity *mx = gw_malloc(sizeof *mx);
mx->headers = http_header_duplicate(m->headers);
if (m->multiparts && list_len(m->multiparts) > 0) {
int i, n;
mx->multiparts = list_create();
for (i = 0, n = list_len(m->multiparts); i < n; i++) {
MIMEEntity *x = mime_entity_duplicate(list_get(m->multiparts, i));
list_append(mx->multiparts, x);
}
mx->body = NULL;
} else {
mx->body = m->body ? octstr_duplicate(m->body) : NULL;
mx->multiparts = NULL;
}
mx->start = NULL;
return mx;
}
void mms_collect_envdata_from_msgheaders(List *mh, List **xto, void mms_collect_envdata_from_msgheaders(List *mh, List **xto,
Octstr **subject, Octstr **subject,
Octstr **otransid, time_t *expiryt, Octstr **otransid, time_t *expiryt,
@ -790,10 +793,10 @@ void mms_collect_envdata_from_msgheaders(List *mh, List **xto,
List *l = http_header_find_all(mh, "To"); List *l = http_header_find_all(mh, "To");
if (l) { if (l) {
int i, n; int i, n;
for (i = 0, n = list_len(l); i<n; i++) { for (i = 0, n = gwlist_len(l); i<n; i++) {
Octstr *name, *value; Octstr *name, *value;
http_header_get(l, i, &name, &value); http_header_get(l, i, &name, &value);
list_append(*xto, value); gwlist_append(*xto, value);
octstr_destroy(name); octstr_destroy(name);
} }
@ -803,10 +806,10 @@ void mms_collect_envdata_from_msgheaders(List *mh, List **xto,
l = http_header_find_all(mh, "Cc"); l = http_header_find_all(mh, "Cc");
if (l) { if (l) {
int i, n; int i, n;
for (i = 0, n = list_len(l); i<n; i++) { for (i = 0, n = gwlist_len(l); i<n; i++) {
Octstr *name, *value; Octstr *name, *value;
http_header_get(l, i, &name, &value); http_header_get(l, i, &name, &value);
list_append(*xto, value); gwlist_append(*xto, value);
octstr_destroy(name); octstr_destroy(name);
} }
@ -818,10 +821,10 @@ void mms_collect_envdata_from_msgheaders(List *mh, List **xto,
if (l) { if (l) {
int i, n; int i, n;
for (i = 0, n = list_len(l); i<n; i++) { for (i = 0, n = gwlist_len(l); i<n; i++) {
Octstr *name, *value; Octstr *name, *value;
http_header_get(l, i, &name, &value); http_header_get(l, i, &name, &value);
list_append(*xto, value); gwlist_append(*xto, value);
octstr_destroy(name); octstr_destroy(name);
} }
@ -915,9 +918,9 @@ int is_allowed_host(Octstr *host, Octstr *host_list)
l = octstr_split(host_list, octstr_imm(";")); l = octstr_split(host_list, octstr_imm(";"));
ret = (list_search(l, host, comp_fn) != NULL) ? 1 : 0; ret = (gwlist_search(l, host, comp_fn) != NULL) ? 1 : 0;
list_destroy(l, (void *)octstr_destroy); gwlist_destroy(l, (void *)octstr_destroy);
return ret; return ret;
} }
@ -956,10 +959,10 @@ int parse_cgivars(List *request_headers, Octstr *request_body,
http_header_get_content_type(request_headers, &ctype, &charset); http_header_get_content_type(request_headers, &ctype, &charset);
if (*cgivars == NULL) if (*cgivars == NULL)
*cgivars = list_create(); *cgivars = gwlist_create();
if (*cgivar_ctypes == NULL) if (*cgivar_ctypes == NULL)
*cgivar_ctypes = list_create(); *cgivar_ctypes = gwlist_create();
if (!ctype) { if (!ctype) {
warning(0, "MMS: Parse CGI Vars: Missing Content Type!"); warning(0, "MMS: Parse CGI Vars: Missing Content Type!");
@ -972,16 +975,16 @@ int parse_cgivars(List *request_headers, Octstr *request_body,
List *l = octstr_split(request_body, octstr_imm("&")); List *l = octstr_split(request_body, octstr_imm("&"));
Octstr *v; Octstr *v;
while ((v = list_extract_first(l)) != NULL) { while ((v = gwlist_extract_first(l)) != NULL) {
List *r = octstr_split(v, octstr_imm("=")); List *r = octstr_split(v, octstr_imm("="));
if (list_len(r) == 0) if (gwlist_len(r) == 0)
warning(0, "MMS: Parse CGI Vars: Missing CGI var name/value in POST data: %s", warning(0, "MMS: Parse CGI Vars: Missing CGI var name/value in POST data: %s",
octstr_get_cstr(request_body)); octstr_get_cstr(request_body));
else { else {
HTTPCGIVar *x = gw_malloc(sizeof *x); HTTPCGIVar *x = gw_malloc(sizeof *x);
x->name = list_extract_first(r); x->name = gwlist_extract_first(r);
x->value = list_extract_first(r); x->value = gwlist_extract_first(r);
if (!x->value) if (!x->value)
x->value = octstr_imm(""); x->value = octstr_imm("");
@ -991,12 +994,12 @@ int parse_cgivars(List *request_headers, Octstr *request_body,
octstr_url_decode(x->name); octstr_url_decode(x->name);
octstr_url_decode(x->value); octstr_url_decode(x->value);
list_append(*cgivars, x); gwlist_append(*cgivars, x);
} }
octstr_destroy(v); octstr_destroy(v);
list_destroy(r, octstr_destroy_item); gwlist_destroy(r, octstr_destroy_item);
} }
list_destroy(l, NULL); gwlist_destroy(l, NULL);
} else if (octstr_case_compare(ctype, octstr_imm("multipart/form-data")) == 0) { } else if (octstr_case_compare(ctype, octstr_imm("multipart/form-data")) == 0) {
/* multi-part form data */ /* multi-part form data */
MIMEEntity *m = mime_http_to_entity(request_headers, request_body); MIMEEntity *m = mime_http_to_entity(request_headers, request_body);
@ -1009,33 +1012,36 @@ int parse_cgivars(List *request_headers, Octstr *request_body,
goto done; goto done;
} }
/* Go through body parts, pick out what we need. */ /* Go through body parts, pick out what we need. */
for (i = 0, n = list_len(m->multiparts); i < n; i++) { for (i = 0, n = mime_entity_num_parts(m); i < n; i++) {
MIMEEntity *mp = list_get(m->multiparts, i); MIMEEntity *mp = mime_entity_get_part(m, i);
Octstr *ct = http_header_value(mp->headers, List *headers = _x_mime_entity_headers(mp);
Octstr *body = mime_entity_body(mp);
Octstr *ct = http_header_value(headers,
octstr_imm("Content-Type")); octstr_imm("Content-Type"));
Octstr *cd = http_header_value(mp->headers, Octstr *cd = http_header_value(headers,
octstr_imm("Content-Disposition")); octstr_imm("Content-Disposition"));
Octstr *name = http_get_header_parameter(cd, octstr_imm("name")); Octstr *name = http_get_header_parameter(cd, octstr_imm("name"));
if (name) { if (name) {
HTTPCGIVar *x = gw_malloc(sizeof *x); HTTPCGIVar *x = gw_malloc(sizeof *x);
/* Strip quotes */ /* Strip quotes */
if (octstr_get_char(name, 0) == '"') { if (octstr_get_char(name, 0) == '"') {
octstr_delete(name, 0, 1); octstr_delete(name, 0, 1);
octstr_truncate(name, octstr_len(name) - 1); octstr_truncate(name, octstr_len(name) - 1);
} }
x->name = octstr_duplicate(name);
x->value = octstr_duplicate(mp->body);
list_append(*cgivars, x); x->name = octstr_duplicate(name);
x->value = octstr_duplicate(body);
gwlist_append(*cgivars, x);
if (ct) { /* If the content type is set, use it. */ if (ct) { /* If the content type is set, use it. */
x = gw_malloc(sizeof *x); x = gw_malloc(sizeof *x);
x->name = octstr_duplicate(name); x->name = octstr_duplicate(name);
x->value = octstr_duplicate(ct); x->value = octstr_duplicate(ct);
list_append(*cgivar_ctypes, x); gwlist_append(*cgivar_ctypes, x);
} }
octstr_destroy(name); octstr_destroy(name);
} }
@ -1044,6 +1050,9 @@ int parse_cgivars(List *request_headers, Octstr *request_body,
if (cd) if (cd)
octstr_destroy(cd); octstr_destroy(cd);
octstr_destroy(body);
http_destroy_headers(headers);
mime_entity_destroy(mp);
} }
mime_entity_destroy(m); mime_entity_destroy(m);
@ -1056,3 +1065,66 @@ done:
octstr_destroy(charset); octstr_destroy(charset);
return ret; return ret;
} }
/* We need this because of boundary element adding bug in gwlib/mime.c */
List *_x_mime_entity_headers(MIMEEntity *m)
{
List *h = mime_entity_headers(m);
http_header_remove_all(h, "MIME-Version");
/* also remove boundary element -- it was added erroneously */
if (mime_entity_num_parts(m) == 0)
strip_boundary_element(h,NULL);
mime_replace_headers(m, h);
return h;
}
/* get content-ID header, fix: WAP decoder may leave " at beginning */
Octstr *_x_get_content_id(List *headers)
{
Octstr *cid = http_header_value(headers, octstr_imm("Content-ID"));
if (cid)
if (octstr_get_char(cid, 0) == '"' &&
octstr_get_char(cid, octstr_len(cid) - 1) != '"')
octstr_delete(cid, 0,1);
return cid;
}
/* Utility: Take a header list, remove any boundary parameter from the content-type
* element. We don't want this in the WSP packed content.
*/
void strip_boundary_element(List *headers, char *s)
{
Octstr *ctype = NULL, *params = NULL;
Octstr *value;
gw_assert(headers);
get_content_type(headers, &ctype, &params);
if (s) {/* we are replacing the content type as well as stripping */
if (ctype)
octstr_destroy(ctype);
ctype = octstr_create(s);
}
if (params) {
List *h = get_value_parameters(params);
Octstr *ps;
http_header_remove_all(h,"boundary"); /* We don't need the boundary param if it is there. */
ps = make_value_parameters(h);
value = octstr_format("%S%s%S", ctype,
(ps && octstr_len(ps) > 0) ? "; " : "",
ps);
octstr_destroy(ps);
http_destroy_headers(h);
} else
value = ctype;
http_header_remove_all(headers, "Content-Type");
http_header_add(headers, "Content-Type", octstr_get_cstr(value));
if (ctype != value)
octstr_destroy(ctype);
octstr_destroy(value);
}

View File

@ -111,8 +111,6 @@ void mms_log2(char *logmsg, Octstr *from, Octstr *to,
*/ */
int mm_lockfile(int fd, char *fname, int shouldblock); int mm_lockfile(int fd, char *fname, int shouldblock);
/* This should be elsewhere, but it isn't, so we do it here... */
extern MIMEEntity *mime_entity_duplicate(MIMEEntity *m);
/* Returns true if the character is printable or space */ /* Returns true if the character is printable or space */
int _mms_gw_isprint(int c); int _mms_gw_isprint(int c);
@ -150,6 +148,16 @@ void escape_shell_chars(Octstr *str);
*/ */
int parse_cgivars(List *request_headers, Octstr *request_body, int parse_cgivars(List *request_headers, Octstr *request_body,
List **cgivars, List **cgivar_ctypes); List **cgivars, List **cgivar_ctypes);
/* Helper function: The gwlib func adds an additional MIME-Version header which is not ideal! */
List *_x_mime_entity_headers(MIMEEntity *m);
/* get content-ID header, fix: WAP decoder may leave " at beginning */
Octstr *_x_get_content_id(List *headers);
/* Remove the boundary element from a list of headers. */
void strip_boundary_element(List *headers, char *s);
#define MAXQTRIES 100 #define MAXQTRIES 100
#define BACKOFF_FACTOR 5*60 /* In seconds */ #define BACKOFF_FACTOR 5*60 /* In seconds */
#define QUEUERUN_INTERVAL 1*60 /* 1 minutes. */ #define QUEUERUN_INTERVAL 1*60 /* 1 minutes. */

View File

@ -265,7 +265,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
mm7_soap_destroy(mreq); mm7_soap_destroy(mreq);
if (to) if (to)
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
} }
@ -277,7 +277,7 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
List *rh = http_create_empty_headers(); List *rh = http_create_empty_headers();
Octstr *reply_body = NULL, *value, *value2; Octstr *reply_body = NULL, *value, *value2;
List *to = list_create(), *hto = NULL; List *to = gwlist_create(), *hto = NULL;
Octstr *subject = NULL, *otransid = NULL, *msgid = NULL; Octstr *subject = NULL, *otransid = NULL, *msgid = NULL;
Octstr *hfrom = NULL; Octstr *hfrom = NULL;
time_t expiryt = -1, deliveryt = -1; time_t expiryt = -1, deliveryt = -1;
@ -312,13 +312,13 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL && if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL &&
list_len(hto) > 0) { /* To address is in headers. */ gwlist_len(hto) > 0) { /* To address is in headers. */
int i, n; int i, n;
if (to) if (to)
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
to = list_create(); to = gwlist_create();
for (i = 0, n = list_len(hto); i < n; i++) { for (i = 0, n = gwlist_len(hto); i < n; i++) {
Octstr *h = NULL, *v = NULL; Octstr *h = NULL, *v = NULL;
List *l; List *l;
int j, m; int j, m;
@ -326,10 +326,10 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
http_header_get(hto,i, &h, &v); http_header_get(hto,i, &h, &v);
l = http_header_split_value(v); l = http_header_split_value(v);
for (j = 0, m = list_len(l); j < m; j++) for (j = 0, m = gwlist_len(l); j < m; j++)
list_append(to, list_get(l, j)); gwlist_append(to, gwlist_get(l, j));
list_destroy(l, NULL); gwlist_destroy(l, NULL);
if (h) octstr_destroy(h); if (h) octstr_destroy(h);
if (v) octstr_destroy(v); if (v) octstr_destroy(v);
} }
@ -419,7 +419,7 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
if (hto) if (hto)
http_destroy_headers(hto); http_destroy_headers(hto);
if (to) if (to)
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
if (hfrom) if (hfrom)
octstr_destroy(hfrom); octstr_destroy(hfrom);
if (subject) if (subject)
@ -531,7 +531,7 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
Octstr *ret = NULL; Octstr *ret = NULL;
int mtype = mms_messagetype(m); int mtype = mms_messagetype(m);
int hstatus = HTTP_OK, tstatus; int hstatus = HTTP_OK, tstatus;
List *xto = list_create(); List *xto = gwlist_create();
MSoapMsg_t *mreq = NULL, *mresp = NULL; MSoapMsg_t *mreq = NULL, *mresp = NULL;
List *rh = NULL, *ph = NULL; List *rh = NULL, *ph = NULL;
Octstr *body = NULL, *rbody = NULL, *url = NULL; Octstr *body = NULL, *rbody = NULL, *url = NULL;
@ -542,7 +542,7 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
mms_message_type_to_cstr(mtype), mms_message_type_to_cstr(mtype),
octstr_get_cstr(from), octstr_get_cstr(to)); octstr_get_cstr(from), octstr_get_cstr(to));
list_append(xto, to); gwlist_append(xto, to);
if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, transid, if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, transid,
service_code, service_code,
@ -562,7 +562,7 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
http_header_combine(rh, hdrs); /* If specified, then update and pass on. */ http_header_combine(rh, hdrs); /* If specified, then update and pass on. */
hstatus = mmsbox_url_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) { if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
*error = octstr_format("Failed to contact MMC[url=%s] => HTTP returned status = %d!", *error = octstr_format("Failed to contact MMC[url=%s] => HTTP returned status = %d!",
octstr_get_cstr(mmc->mmsc_url), hstatus); octstr_get_cstr(mmc->mmsc_url), hstatus);
goto done1; goto done1;
@ -628,7 +628,7 @@ done1:
if (url) if (url)
octstr_destroy(url); octstr_destroy(url);
list_destroy(xto, NULL); gwlist_destroy(xto, NULL);
return ret; return ret;
} }
@ -778,14 +778,14 @@ static MmscGrp *get_handler_mmc(Octstr *id, Octstr *to)
Octstr *phonenum = NULL; Octstr *phonenum = NULL;
if (id) if (id)
for (i = 0, n = list_len(mmscs); i < n; i++) for (i = 0, n = gwlist_len(mmscs); i < n; i++)
if ((mmc = list_get(mmscs, i)) != NULL && if ((mmc = gwlist_get(mmscs, i)) != NULL &&
mmc->id && octstr_compare(mmc->id, id) == 0) mmc->id && octstr_compare(mmc->id, id) == 0)
return mmc; return mmc;
if (octstr_search_char(to, '@', 0) > 0 || if (octstr_search_char(to, '@', 0) > 0 ||
octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0) > 0) /* For emails, or ip take first mmsc. */ octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0) > 0) /* For emails, or ip take first mmsc. */
return list_get(mmscs, 0); return gwlist_get(mmscs, 0);
j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0); j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0);
@ -796,8 +796,8 @@ static MmscGrp *get_handler_mmc(Octstr *id, Octstr *to)
normalize_number(octstr_get_cstr(unified_prefix), &phonenum); normalize_number(octstr_get_cstr(unified_prefix), &phonenum);
for (i = 0, n = list_len(mmscs); i < n; i++) for (i = 0, n = gwlist_len(mmscs); i < n; i++)
if ((mmc = list_get(mmscs, i)) != NULL && if ((mmc = gwlist_get(mmscs, i)) != NULL &&
(mmc->allowed_prefix == NULL || (mmc->allowed_prefix == NULL ||
does_prefix_match(mmc->allowed_prefix, phonenum)) && does_prefix_match(mmc->allowed_prefix, phonenum)) &&
(mmc->denied_prefix == NULL || (mmc->denied_prefix == NULL ||
@ -816,9 +816,9 @@ static int sendMsg(MmsEnvelope *e)
msg = mms_queue_getdata(e); msg = mms_queue_getdata(e);
for (i = 0, n = list_len(e->to); i<n; i++) { for (i = 0, n = gwlist_len(e->to); i<n; i++) {
int res = MMS_SEND_OK; int res = MMS_SEND_OK;
MmsEnvelopeTo *to = list_get(e->to, i); MmsEnvelopeTo *to = gwlist_get(e->to, i);
Octstr *err = NULL; Octstr *err = NULL;
time_t tnow = time(NULL); time_t tnow = time(NULL);
MmscGrp *mmc = NULL; MmscGrp *mmc = NULL;

View File

@ -34,46 +34,57 @@ static void quit_now(int notused)
if (sendmms_port.port > 0) if (sendmms_port.port > 0)
http_close_port(sendmms_port.port); http_close_port(sendmms_port.port);
for (i = 0, n = list_len(mmscs); i < n; i++) for (i = 0, n = gwlist_len(mmscs); i < n; i++)
if ((mmc = list_get(mmscs, i)) != NULL && if ((mmc = gwlist_get(mmscs, i)) != NULL &&
mmc->incoming.port > 0) mmc->incoming.port > 0)
http_close_port(mmc->incoming.port); http_close_port(mmc->incoming.port);
} }
/* Finds text part, returns copy. */
static MIMEEntity *find_textpart(MIMEEntity *m) static MIMEEntity *find_textpart(MIMEEntity *m)
{ {
Octstr *ctype = NULL, *params = NULL; Octstr *ctype = NULL, *params = NULL;
MIMEEntity *res = NULL; MIMEEntity *res = NULL;
List *headers;
int i, n;
if (!m) return NULL; if (!m) return NULL;
get_content_type(m->headers, &ctype, &params); headers = _x_mime_entity_headers(m);
get_content_type(headers, &ctype, &params);
http_destroy_headers(headers);
if (ctype && octstr_str_compare(ctype, "text/plain") == 0) { if (ctype && octstr_str_compare(ctype, "text/plain") == 0) {
res = m; res = mime_entity_duplicate(m);
goto done; goto done;
} }
if (m->multiparts) { if ((n = mime_entity_num_parts(m)) > 0) {
int i, n = list_len(m->multiparts); for (i = 0; i < n; i++) {
for (i = 0; i < n; i++) MIMEEntity *x = mime_entity_get_part(m, i);
if ((res = find_textpart(list_get(m->multiparts, i))) != NULL) res = find_textpart(x);
mime_entity_destroy(x);
if (res != NULL)
goto done2; goto done2;
}
} }
done: done:
if (res) { /* We got it! Convert charset if needed. */ if (res) { /* We got it! Convert charset if needed. */
List *params_h = get_value_parameters(params); List *params_h = get_value_parameters(params);
Octstr *charset = http_header_value(params_h, octstr_imm("charset")); Octstr *charset = http_header_value(params_h, octstr_imm("charset"));
Octstr *body = mime_entity_body(res);
if (charset == NULL || if (charset == NULL ||
octstr_str_compare(charset, "unknown") == 0) { octstr_str_compare(charset, "unknown") == 0) {
if (charset) octstr_destroy(charset); if (charset) octstr_destroy(charset);
charset = octstr_imm(DEFAULT_CHARSET); charset = octstr_imm(DEFAULT_CHARSET);
} }
if (octstr_case_compare(charset, octstr_imm(DEFAULT_CHARSET)) != 0) if (octstr_case_compare(charset, octstr_imm(DEFAULT_CHARSET)) != 0) {
charset_convert(m->body, DEFAULT_CHARSET, octstr_get_cstr(charset)); /* XXX error ignored? */ charset_convert(body, DEFAULT_CHARSET, octstr_get_cstr(charset)); /* XXX error ignored? */
mime_entity_set_body(res, body);
}
octstr_destroy(body);
http_destroy_headers(params_h); http_destroy_headers(params_h);
octstr_destroy(charset); octstr_destroy(charset);
} }
@ -95,16 +106,20 @@ static Octstr *get_keyword(MIMEEntity *me)
{ {
MIMEEntity *t = find_textpart(me); MIMEEntity *t = find_textpart(me);
Octstr *txt = t ? t->body : NULL; Octstr *txt = t ? mime_entity_body(t) : NULL;
List *l = t ? octstr_split_words(txt) : NULL; List *l = t ? octstr_split_words(txt) : NULL;
Octstr *keyword = l ? list_get(l, 0) : NULL; Octstr *keyword = l ? gwlist_get(l, 0) : NULL;
if (keyword) if (keyword)
keyword = octstr_duplicate(keyword); keyword = octstr_duplicate(keyword);
if (l) if (l)
list_destroy(l, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
if (txt)
octstr_destroy(txt);
if (t)
mime_entity_destroy(t);
return keyword; return keyword;
} }
@ -118,24 +133,24 @@ static MmsService *get_service(Octstr *keyword, Octstr *mmc_id)
int i, n; int i, n;
MmsService *catch_all = NULL; MmsService *catch_all = NULL;
for (i = 0, n = list_len(mms_services); i < n; i++) { for (i = 0, n = gwlist_len(mms_services); i < n; i++) {
MmsService *ms = list_get(mms_services,i); MmsService *ms = gwlist_get(mms_services,i);
/* Check that mmc_id is allowed: /* Check that mmc_id is allowed:
* denied list is not null and we are on it, or allowed list is not null and we * denied list is not null and we are on it, or allowed list is not null and we
* are *not* on it. * are *not* on it.
*/ */
if (ms->denied_mmscs && if (ms->denied_mmscs &&
list_search(ms->denied_mmscs, mmc_id, (list_item_matches_t *)octstr_compare) != NULL) gwlist_search(ms->denied_mmscs, mmc_id, (gwlist_item_matches_t *)octstr_compare) != NULL)
continue; continue;
if (ms->allowed_mmscs && if (ms->allowed_mmscs &&
list_search(ms->allowed_mmscs, mmc_id, (list_item_matches_t *)octstr_compare) == NULL) gwlist_search(ms->allowed_mmscs, mmc_id, (gwlist_item_matches_t *)octstr_compare) == NULL)
continue; continue;
if (keyword == NULL || if (keyword == NULL ||
list_search(ms->keywords, keyword, gwlist_search(ms->keywords, keyword,
(list_item_matches_t *)_x_octstr_comp) != NULL) (gwlist_item_matches_t *)_x_octstr_comp) != NULL)
return ms; return ms;
if (ms->isdefault) /* We also find the catch-all for this sender. */ if (ms->isdefault) /* We also find the catch-all for this sender. */
@ -149,9 +164,11 @@ static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm,
MIMEEntity *me, MmsMsg *msg, int lev, int count) MIMEEntity *me, MmsMsg *msg, int lev, int count)
{ {
int i, n; int i, n;
List *headers = NULL;
Octstr *data = NULL, *ctype = NULL, *xctype = NULL, *params = NULL; Octstr *data = NULL, *ctype = NULL, *xctype = NULL, *params = NULL;
Octstr *s;
headers = _x_mime_entity_headers(me);
if (pm->type == WHOLE_BINARY && lev == 0) { if (pm->type == WHOLE_BINARY && lev == 0) {
data = mms_tobinary(msg); data = mms_tobinary(msg);
ctype = octstr_imm("application/vnd.wap.mms-message"); ctype = octstr_imm("application/vnd.wap.mms-message");
@ -160,14 +177,16 @@ static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm,
goto done; goto done;
} }
if (me->multiparts && list_len(me->multiparts) > 0) { /* Don't process multipart. */ if ((n = mime_entity_num_parts(me)) > 0) { /* Recurse over multi-parts. */
for (i = 0, n = list_len(me->multiparts); i < n; i++) for (i = 0; i < n; i++) {
add_all_matching_parts(plist, pm, MIMEEntity *x = mime_entity_get_part(me,i);
list_get(me->multiparts, i), msg, lev+1,i); add_all_matching_parts(plist, pm, x, msg, lev+1,i);
mime_entity_destroy(x);
}
goto done; goto done;
} }
get_content_type(me->headers, &xctype, &params); get_content_type(headers, &xctype, &params);
#define BEGINSWITH(s, prefix) (octstr_case_search(s, octstr_imm(prefix),0) == 0) #define BEGINSWITH(s, prefix) (octstr_case_search(s, octstr_imm(prefix),0) == 0)
#define TYPE_MATCH(typ, prefix) ((pm->type) == (typ) && \ #define TYPE_MATCH(typ, prefix) ((pm->type) == (typ) && \
@ -186,19 +205,20 @@ static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm,
!BEGINSWITH(xctype, "image/") && !BEGINSWITH(xctype, "image/") &&
!BEGINSWITH(xctype, "application/smil")))) { !BEGINSWITH(xctype, "application/smil")))) {
ctype = http_header_value(me->headers, octstr_imm("Content-Type")); ctype = http_header_value(headers, octstr_imm("Content-Type"));
data = me->body ? octstr_duplicate(me->body) : octstr_create(""); data = mime_entity_body(me);
} }
done: done:
if (data) { if (data) {
MIMEEntity *p = mime_entity_create(); MIMEEntity *p = mime_entity_create();
Octstr *cd = octstr_format("form-data; name=\"%S\"", pm->name); Octstr *cd = octstr_format("form-data; name=\"%S\"", pm->name);
List *xh;
if (ctype) { if (ctype) {
/* If Content-Location header or name (content-type) parameter given, pass it as filename. */ /* If Content-Location header or name (content-type) parameter given, pass it as filename. */
Octstr *c = NULL, *q = NULL; Octstr *c = NULL, *q = NULL;
Octstr *cloc = http_header_value(me->headers, Octstr *cloc = http_header_value(headers,
octstr_imm("Content-Location")); octstr_imm("Content-Location"));
split_header_value(ctype, &c, &q); split_header_value(ctype, &c, &q);
@ -234,18 +254,25 @@ done:
if (cloc) if (cloc)
octstr_destroy(cloc); octstr_destroy(cloc);
} }
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;
xh = http_create_empty_headers();
http_header_add(xh, "Content-Disposition", octstr_get_cstr(cd));
if (ctype) /* This header must come after the above it seems. */
http_header_add(xh, "Content-Type", octstr_get_cstr(ctype));
mime_replace_headers(p, xh);
http_destroy_headers(xh);
s = octstr_duplicate(data); /* data for the parameter */
if (pm->value) /* add value part as needed. */ if (pm->value) /* add value part as needed. */
octstr_append(p->body, pm->value); octstr_append(s, pm->value);
mime_entity_set_body(p, s);
octstr_destroy(s);
#if 0 #if 0
base64_mimeparts(p); base64_mimeparts(p);
#endif #endif
list_append(plist->multiparts, p); mime_entity_add_part(plist, p); /* add it to list so far. */
mime_entity_destroy(p);
octstr_destroy(cd); octstr_destroy(cd);
@ -257,6 +284,11 @@ done:
octstr_destroy(params); octstr_destroy(params);
if (ctype) if (ctype)
octstr_destroy(ctype); octstr_destroy(ctype);
if (data)
octstr_destroy(data);
if (headers)
http_destroy_headers(headers);
} }
enum _xurltype {FILE_TYPE, URL_TYPE}; enum _xurltype {FILE_TYPE, URL_TYPE};
@ -297,8 +329,8 @@ static int fetch_serviceurl(MmsEnvelope *e,
if (e->subject) if (e->subject)
http_header_add(rh, "X-Mbuni-Subject", octstr_get_cstr(e->subject)); http_header_add(rh, "X-Mbuni-Subject", octstr_get_cstr(e->subject));
for (i = 0, n = list_len(e->to); i < n; i++) { for (i = 0, n = gwlist_len(e->to); i < n; i++) {
MmsEnvelopeTo *r = list_get(e->to, i); MmsEnvelopeTo *r = gwlist_get(e->to, i);
if (r && r->rcpt) if (r && r->rcpt)
http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(r->rcpt)); http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(r->rcpt));
} }
@ -306,15 +338,17 @@ static int fetch_serviceurl(MmsEnvelope *e,
MIMEEntity *x = mime_entity_create(); MIMEEntity *x = mime_entity_create();
http_header_add(rh, "Content-Type", "multipart/form-data"); http_header_add(rh, "Content-Type", "multipart/form-data");
mime_replace_headers(x, rh);
http_destroy_headers(rh);
http_destroy_headers(x->headers); for (i = 0, n = gwlist_len(ms->params); i < n; i++) {
x->headers = rh; MmsServiceUrlParam *p = gwlist_get(ms->params, i);
for (i = 0, n = list_len(ms->params); i < n; i++) {
MmsServiceUrlParam *p = list_get(ms->params, i);
add_all_matching_parts(x, p, msg, m, 0, i); add_all_matching_parts(x, p, msg, m, 0, i);
} }
mime_entity_body_and_headers(x, &body, &rh); body = mime_entity_body(x);
rh = _x_mime_entity_headers(x);
mime_entity_destroy(x); mime_entity_destroy(x);
method = HTTP_METHOD_POST; method = HTTP_METHOD_POST;
@ -461,8 +495,8 @@ done:
octstr_destroy(err); octstr_destroy(err);
} }
if (res == -1 || res == 0) /* Fatal error, or success delete queue entry. */ if (res == -1 || res == 0) /* Fatal error, or success delete queue entry. */
for (i = 0, n = list_len(e->to); i < n; i++) { for (i = 0, n = gwlist_len(e->to); i < n; i++) {
MmsEnvelopeTo *r = list_get(e->to,i); MmsEnvelopeTo *r = gwlist_get(e->to,i);
if (r) if (r)
r->process = 0; r->process = 0;
} }
@ -576,7 +610,7 @@ int mmsbox_url_fetch_content(int method, Octstr *url, List *request_headers,
octstr_destroy(ctype); octstr_destroy(ctype);
if (list_len(ph) > 0) { if (gwlist_len(ph) > 0) {
p = make_value_parameters(ph); p = make_value_parameters(ph);
ctype = octstr_format("%S; %S", ctype = octstr_format("%S; %S",
n,p); n,p);
@ -604,7 +638,7 @@ int mmsbox_url_fetch_content(int method, Octstr *url, List *request_headers,
} else { } else {
HTTPCaller *c = http_caller_create(); HTTPCaller *c = http_caller_create();
http_start_request(c, method, url, request_headers, body, 1, NULL, NULL); http_start_request(c, method, url, request_headers, body, 1, NULL, NULL);
if (http_receive_result(c, &status, &furl, reply_headers, reply_body) == NULL) if (http_receive_result_real(c, &status, &furl, reply_headers, reply_body,1) == NULL)
status = -1; status = -1;
http_caller_destroy(c); http_caller_destroy(c);
} }
@ -805,12 +839,16 @@ static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url,
char *p = octstr_get_cstr(attr) + 4; char *p = octstr_get_cstr(attr) + 4;
Octstr *cid_header_val = octstr_format("<%s>", p); Octstr *cid_header_val = octstr_format("<%s>", p);
MIMEEntity *x = mime_entity_create(); MIMEEntity *x = mime_entity_create();
List *headers = http_create_empty_headers();
http_header_add(headers, "Content-Type", octstr_get_cstr(ctype));
http_header_add(headers, "Content-ID", octstr_get_cstr(cid_header_val));
mime_replace_headers(x, headers);
mime_entity_set_body(x, body);
http_header_add(x->headers, "Content-Type", octstr_get_cstr(ctype));
http_header_add(x->headers, "Content-ID", octstr_get_cstr(cid_header_val));
x->body = body;
list_append(res->multiparts, x); mime_entity_add_part(res, x);
mime_entity_destroy(x);
dict_put_once(url_map, curl, octstr_duplicate(attr)); /* Store the cid. */ dict_put_once(url_map, curl, octstr_duplicate(attr)); /* Store the cid. */
@ -818,6 +856,7 @@ static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url,
octstr_destroy(attr); octstr_destroy(attr);
octstr_destroy(cid_header_val); octstr_destroy(cid_header_val);
http_destroy_headers(headers);
} }
done: done:
@ -825,6 +864,8 @@ done:
octstr_destroy(curl); octstr_destroy(curl);
if (ctype) if (ctype)
octstr_destroy(ctype); octstr_destroy(ctype);
if (body)
octstr_destroy(body);
xmlFree(src); xmlFree(src);
return 0; return 0;
} }
@ -854,11 +895,12 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
Octstr *dlr_url = NULL, *rr_url = NULL, *mmc = NULL, *xservice_code = NULL; Octstr *dlr_url = NULL, *rr_url = NULL, *mmc = NULL, *xservice_code = NULL;
MmsMsg *m = NULL; MmsMsg *m = NULL;
MIMEEntity *me = mime_entity_create(); MIMEEntity *me = mime_entity_create();
List *hdrs = NULL; List *hdrs = NULL, *xheaders = NULL;
time_t expiryt = time(NULL) + DEFAULT_EXPIRE; time_t expiryt = time(NULL) + DEFAULT_EXPIRE;
Octstr *x; Octstr *x;
List *xto = list_create(); List *xto = gwlist_create();
int i, n, res = -1; int i, n, res = -1;
gw_assert(svc_name); gw_assert(svc_name);
@ -871,7 +913,7 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
(void)0; /* all done above. */ (void)0; /* all done above. */
else { else {
/* get first recipient, set that as sender. */ /* get first recipient, set that as sender. */
MmsEnvelopeTo *r = (e) ? list_get(e->to, 0) : NULL; MmsEnvelopeTo *r = (e) ? gwlist_get(e->to, 0) : NULL;
if (r) if (r)
from = octstr_duplicate(r->rcpt); from = octstr_duplicate(r->rcpt);
else else
@ -895,11 +937,14 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
xmlChar *buf = NULL; xmlChar *buf = NULL;
int bsize = 0; int bsize = 0;
Dict *url_map = dict_create(97, (void (*)(void *))octstr_destroy); Dict *url_map = dict_create(97, (void (*)(void *))octstr_destroy);
List *xh = http_create_empty_headers();
/* This is the hard bit: Fetch each external reference in smil, add it to message! */ /* This is the hard bit: Fetch each external reference in smil, add it to message! */
http_header_add(me->headers, "Content-Type", "multipart/related; " http_header_add(xh, "Content-Type", "multipart/related; "
"type=\"application/smil\"; start=\"<presentation>\""); "type=\"application/smil\"; start=\"<presentation>\"");
mime_replace_headers(me,xh);
http_destroy_headers(xh);
/* Parse the smil as XML. */ /* Parse the smil as XML. */
smil = xmlParseMemory(octstr_get_cstr(data), octstr_len(data)); smil = xmlParseMemory(octstr_get_cstr(data), octstr_len(data));
if (!smil || !smil->xmlChildrenNode) { if (!smil || !smil->xmlChildrenNode) {
@ -918,12 +963,22 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
xmlFreeDoc(smil); xmlFreeDoc(smil);
if (buf) { if (buf) {
MIMEEntity *sm = mime_entity_create(); MIMEEntity *sm = mime_entity_create();
List *xh = http_create_empty_headers();
http_header_add(sm->headers, "Content-Type", "application/smil"); Octstr *s;
http_header_add(sm->headers, "Content-ID", "<presentation>");
sm->body = octstr_create_from_data((char *)buf, bsize); http_header_add(xh, "Content-Type", "application/smil");
list_append(me->multiparts, sm); http_header_add(xh, "Content-ID", "<presentation>"); /* identify it as start element. */
me->start = sm; s = octstr_create_from_data((char *)buf, bsize);
mime_replace_headers(sm, xh);
mime_entity_set_body(sm, s);
mime_entity_add_part(me, sm);
mime_entity_destroy(sm);
http_destroy_headers(xh);
octstr_destroy(s);
xmlFree(buf); xmlFree(buf);
} else { } else {
*err = octstr_format("MMSBox: Error writing converted SMIL " *err = octstr_format("MMSBox: Error writing converted SMIL "
@ -934,8 +989,12 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
goto done; goto done;
} }
} else { /* all others, make the message as-is and hope for the best! */ } else { /* all others, make the message as-is and hope for the best! */
http_header_add(me->headers, "Content-Type", octstr_get_cstr(ctype)); List *xh = http_create_empty_headers();
me->body = octstr_duplicate(data); http_header_add(xh, "Content-Type", octstr_get_cstr(ctype));
mime_replace_headers(me, xh);
http_destroy_headers(xh);
mime_entity_set_body(me, data);
} }
/* Get headers needed, if we are allowed to do so. */ /* Get headers needed, if we are allowed to do so. */
@ -949,7 +1008,7 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
if ((l = http_header_find_all(reply_headers, "X-Mbuni-To")) != NULL) { if ((l = http_header_find_all(reply_headers, "X-Mbuni-To")) != NULL) {
int i, n; int i, n;
for (i = 0, n = list_len(l); i<n; i++) { for (i = 0, n = gwlist_len(l); i<n; i++) {
Octstr *h = NULL, *v = NULL; Octstr *h = NULL, *v = NULL;
List *hv = NULL; List *hv = NULL;
int j; int j;
@ -957,15 +1016,15 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
hv = http_header_split_value(v); hv = http_header_split_value(v);
for (j = 0; j < list_len(hv); j++) { for (j = 0; j < gwlist_len(hv); j++) {
Octstr *v = list_get(hv, j); Octstr *v = gwlist_get(hv, j);
/* Fix the address. */ /* Fix the address. */
_mms_fixup_address(v); _mms_fixup_address(v);
list_append(xto, v); gwlist_append(xto, v);
} }
octstr_destroy(v); octstr_destroy(v);
octstr_destroy(h); octstr_destroy(h);
list_destroy(hv, NULL); /* Don't kill strings since we added them to xto above! */ gwlist_destroy(hv, NULL); /* Don't kill strings since we added them to xto above! */
} }
http_destroy_headers(l); http_destroy_headers(l);
} }
@ -975,8 +1034,8 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
mmc = http_header_value(reply_headers, octstr_imm("X-Mbuni-MMSC")); mmc = http_header_value(reply_headers, octstr_imm("X-Mbuni-MMSC"));
} }
if (list_len(xto) == 0 && e && e->from) if (gwlist_len(xto) == 0 && e && e->from)
list_append(xto, octstr_duplicate(e->from)); gwlist_append(xto, octstr_duplicate(e->from));
if (!subject && e && e->subject) if (!subject && e && e->subject)
subject = octstr_duplicate(e->subject); subject = octstr_duplicate(e->subject);
@ -985,25 +1044,28 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
mmc = e->fromproxy; mmc = e->fromproxy;
/* Add some nice headers. */ /* Add some nice headers. */
http_header_add(me->headers, "From", octstr_get_cstr(from)); xheaders = _x_mime_entity_headers(me);
http_header_add(xheaders, "From", octstr_get_cstr(from));
for (i = 0, n = list_len(xto); i < n; i++) { for (i = 0, n = gwlist_len(xto); i < n; i++) {
Octstr *v; Octstr *v;
v = list_get(xto, i); v = gwlist_get(xto, i);
http_header_add(me->headers, "To", octstr_get_cstr(v)); http_header_add(xheaders, "To", octstr_get_cstr(v));
} }
if (dlr_url) if (dlr_url)
http_header_add(me->headers, "X-Mms-Delivery-Report", "Yes"); http_header_add(xheaders, "X-Mms-Delivery-Report", "Yes");
if (rr_url) if (rr_url)
http_header_add(me->headers, "X-Mms-Read-Report", "Yes"); http_header_add(xheaders, "X-Mms-Read-Report", "Yes");
if (subject) if (subject)
http_header_add(me->headers, "Subject", octstr_get_cstr(subject)); http_header_add(xheaders, "Subject", octstr_get_cstr(subject));
if (expiryt > 0) { if (expiryt > 0) {
Octstr *x = date_format_http(expiryt); Octstr *x = date_format_http(expiryt);
http_header_add(me->headers, "X-Mms-Expiry", octstr_get_cstr(x)); http_header_add(xheaders, "X-Mms-Expiry", octstr_get_cstr(x));
octstr_destroy(x); octstr_destroy(x);
} }
mime_replace_headers(me, xheaders);
http_destroy_headers(xheaders);
if (me && !m) /* Set m if it hasn't been set yet. */ if (me && !m) /* Set m if it hasn't been set yet. */
m = mms_frommime(me); m = mms_frommime(me);
@ -1014,7 +1076,7 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
} }
if (passthro_headers && reply_headers) { /* if user wants passthro headers, get them and add them. */ if (passthro_headers && reply_headers) { /* if user wants passthro headers, get them and add them. */
int n = list_len(reply_headers); int n = gwlist_len(reply_headers);
int i; int i;
hdrs = http_create_empty_headers(); hdrs = http_create_empty_headers();
@ -1028,8 +1090,8 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
/* Check for this header in /* Check for this header in
* pass thro list. * pass thro list.
*/ */
for (j = 0; j < list_len(passthro_headers); j++) for (j = 0; j < gwlist_len(passthro_headers); j++)
if (octstr_case_compare(h, list_get(passthro_headers, j)) == 0) { if (octstr_case_compare(h, gwlist_get(passthro_headers, j)) == 0) {
http_header_add(hdrs, octstr_get_cstr(h), octstr_get_cstr(v)); http_header_add(hdrs, octstr_get_cstr(h), octstr_get_cstr(v));
break; break;
} }
@ -1074,7 +1136,7 @@ done:
if (m) if (m)
mms_destroy(m); mms_destroy(m);
if (xto) if (xto)
list_destroy(xto, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(xto, (gwlist_item_destructor_t *)octstr_destroy);
if (hdrs) if (hdrs)
http_destroy_headers(hdrs); http_destroy_headers(hdrs);
@ -1091,8 +1153,8 @@ static SendMmsUser *auth_user(Octstr *user, Octstr *pass)
if (!user || !pass) if (!user || !pass)
return NULL; return NULL;
for (i = 0, n = list_len(sendmms_users); i < n; i++) for (i = 0, n = gwlist_len(sendmms_users); i < n; i++)
if ((u = list_get(sendmms_users, i)) != NULL && if ((u = gwlist_get(sendmms_users, i)) != NULL &&
octstr_compare(u->user, user) == 0 && octstr_compare(u->user, user) == 0 &&
octstr_compare(u->pass, pass) == 0) octstr_compare(u->pass, pass) == 0)
return u; return u;
@ -1185,11 +1247,11 @@ static void sendmms_func(void *unused)
rb = octstr_imm("Missing Sender address"); rb = octstr_imm("Missing Sender address");
if (lto) { if (lto) {
for (i = 0, n = list_len(lto); i < n; i++) { for (i = 0, n = gwlist_len(lto); i < n; i++) {
Octstr *x = list_get(lto, i); Octstr *x = gwlist_get(lto, i);
http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(x)); http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(x));
} }
list_destroy(lto, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(lto, (gwlist_item_destructor_t *)octstr_destroy);
} }
if (dlr_url) if (dlr_url)
http_header_add(rh, "X-Mbuni-DLR-Url", octstr_get_cstr(dlr_url)); http_header_add(rh, "X-Mbuni-DLR-Url", octstr_get_cstr(dlr_url));

View File

@ -49,9 +49,9 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
mms_load_core_settings(cgrp); mms_load_core_settings(cgrp);
sendmms_users = list_create(); sendmms_users = gwlist_create();
mms_services = list_create(); mms_services = gwlist_create();
mmscs = list_create(); mmscs = gwlist_create();
gdir = mms_cfg_get(grp, octstr_imm("storage-directory")); gdir = mms_cfg_get(grp, octstr_imm("storage-directory"));
@ -119,8 +119,8 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
/* Now get sendmms users. */ /* Now get sendmms users. */
l = mms_cfg_get_multi(cfg, octstr_imm("send-mms-user")); l = mms_cfg_get_multi(cfg, octstr_imm("send-mms-user"));
for (i = 0, n = list_len(l); i < n; i++) { for (i = 0, n = gwlist_len(l); i < n; i++) {
mCfgGrp *x = list_get(l, i); mCfgGrp *x = gwlist_get(l, i);
SendMmsUser *u = gw_malloc(sizeof *u); SendMmsUser *u = gw_malloc(sizeof *u);
memset(u, 0, sizeof *u); memset(u, 0, sizeof *u);
@ -130,14 +130,14 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
u->faked_sender = mms_cfg_get(x, octstr_imm("faked-sender")); u->faked_sender = mms_cfg_get(x, octstr_imm("faked-sender"));
u->dlr_url = _mms_cfg_getx(x, octstr_imm("delivery-report-url")); u->dlr_url = _mms_cfg_getx(x, octstr_imm("delivery-report-url"));
u->rr_url = _mms_cfg_getx(x, octstr_imm("read-report-url")); u->rr_url = _mms_cfg_getx(x, octstr_imm("read-report-url"));
list_append(sendmms_users, u); gwlist_append(sendmms_users, u);
} }
list_destroy(l, NULL); gwlist_destroy(l, NULL);
/* Get mmsc list. */ /* Get mmsc list. */
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc")); l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
for (i = 0, n = list_len(l); i < n; i++) { for (i = 0, n = gwlist_len(l); i < n; i++) {
mCfgGrp *x = list_get(l, i); mCfgGrp *x = gwlist_get(l, i);
MmscGrp *m = gw_malloc(sizeof *m); MmscGrp *m = gw_malloc(sizeof *m);
int ssl = 0; int ssl = 0;
Octstr *type; Octstr *type;
@ -189,14 +189,14 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
m->threadid = -1; m->threadid = -1;
m->mutex = mutex_create(); m->mutex = mutex_create();
list_append(mmscs, m); gwlist_append(mmscs, m);
} }
list_destroy(l, NULL); gwlist_destroy(l, NULL);
l = mms_cfg_get_multi(cfg, octstr_imm("mms-service")); l = mms_cfg_get_multi(cfg, octstr_imm("mms-service"));
for (i = 0, n = list_len(l); i < n; i++) { for (i = 0, n = gwlist_len(l); i < n; i++) {
mCfgGrp *x = list_get(l, i); mCfgGrp *x = gwlist_get(l, i);
MmsService *m = gw_malloc(sizeof *m); MmsService *m = gw_malloc(sizeof *m);
Octstr *s; Octstr *s;
@ -254,23 +254,23 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
m->keywords = octstr_split(s, octstr_imm(";")); m->keywords = octstr_split(s, octstr_imm(";"));
octstr_destroy(s); octstr_destroy(s);
} else } else
m->keywords = list_create(); m->keywords = gwlist_create();
s = mms_cfg_get(x, octstr_imm("keyword")); s = mms_cfg_get(x, octstr_imm("keyword"));
if (!s) if (!s)
panic(0, "MMSBox: Service [%s] has no keyword!", octstr_get_cstr(m->name)); panic(0, "MMSBox: Service [%s] has no keyword!", octstr_get_cstr(m->name));
else else
list_append(m->keywords, s); gwlist_append(m->keywords, s);
if ((s = mms_cfg_get(x, octstr_imm("http-post-parameters"))) != NULL) { if ((s = mms_cfg_get(x, octstr_imm("http-post-parameters"))) != NULL) {
List *r = octstr_split(s, octstr_imm("&")); List *r = octstr_split(s, octstr_imm("&"));
int i, n; int i, n;
m->params = list_create(); m->params = gwlist_create();
if (m->type != TRANS_TYPE_POST_URL) if (m->type != TRANS_TYPE_POST_URL)
warning(0, "MMSBox: Service [%s] specifies HTTP Post parameters " warning(0, "MMSBox: Service [%s] specifies HTTP Post parameters "
"without specifying post-url type/url!", octstr_get_cstr(m->name)); "without specifying post-url type/url!", octstr_get_cstr(m->name));
for (i = 0, n = list_len(r); i < n; i++) { for (i = 0, n = gwlist_len(r); i < n; i++) {
Octstr *y = list_get(r, i); Octstr *y = gwlist_get(r, i);
int ii = octstr_search_char(y, '=', 0); int ii = octstr_search_char(y, '=', 0);
if (ii < 0) if (ii < 0)
ii = octstr_len(y); ii = octstr_len(y);
@ -311,21 +311,21 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
p->value = octstr_copy(y, ii+3, octstr_len(y)); p->value = octstr_copy(y, ii+3, octstr_len(y));
} else /* No conversion spec. */ } else /* No conversion spec. */
p->value = octstr_copy(y, ii+1, octstr_len(y)); p->value = octstr_copy(y, ii+1, octstr_len(y));
list_append(m->params, p); gwlist_append(m->params, p);
} else } else
warning(0, "MMSBox: Missing http-post-parameter name? Service [%s]!", warning(0, "MMSBox: Missing http-post-parameter name? Service [%s]!",
octstr_get_cstr(m->name)); octstr_get_cstr(m->name));
} }
list_destroy(r, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(r, (gwlist_item_destructor_t *)octstr_destroy);
octstr_destroy(s); octstr_destroy(s);
} else } else
m->params = NULL; m->params = NULL;
m->service_code = mms_cfg_get(x, octstr_imm("service-code")); m->service_code = mms_cfg_get(x, octstr_imm("service-code"));
list_append(mms_services, m); gwlist_append(mms_services, m);
} }
list_destroy(l, NULL); gwlist_destroy(l, NULL);
return 0; return 0;
} }

View File

@ -39,9 +39,9 @@ static int mms_billmsg(Octstr *from, List *to, unsigned long msg_size, Octstr *v
if (script == NULL || octstr_len(script) == 0) if (script == NULL || octstr_len(script) == 0)
return 0; return 0;
for (i=0;i<list_len(to);i++) { for (i=0;i<gwlist_len(to);i++) {
Octstr *s; Octstr *s;
s = octstr_format("%s '%s' '%s'", octstr_get_cstr(script), octstr_get_cstr(from), octstr_get_cstr(list_get(to, i))); s = octstr_format("%s '%s' '%s'", octstr_get_cstr(script), octstr_get_cstr(from), octstr_get_cstr(gwlist_get(to, i)));
if (s) { if (s) {
int ret = system(octstr_get_cstr(s)); int ret = system(octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);

View File

@ -21,7 +21,7 @@ Octstr *script;
static int mms_detokenizer_init(char *settings) static int mms_detokenizer_init(char *settings)
{ {
script = octstr_create(settings); script = octstr_create(settings);
info(0, "Detokenizer script set to \"%s\"", settings); info(0, "Detokenizer script set to \"%s\"", settings);
return 0; return 0;
} }

View File

@ -37,9 +37,9 @@ static Octstr *mms_resolve(Octstr * phonenum, void *module_data, void *settings_
if (does_prefix_match(settings->local_prefix, phonenum)) { if (does_prefix_match(settings->local_prefix, phonenum)) {
return settings->hostname ? octstr_duplicate(settings->hostname) : NULL; return settings->hostname ? octstr_duplicate(settings->hostname) : NULL;
} else if (proxyrelays && list_len(proxyrelays) > 0) /* Step through proxies. */ } else if (proxyrelays && gwlist_len(proxyrelays) > 0) /* Step through proxies. */
for (j = 0, m = list_len(proxyrelays); j < m; j++) { for (j = 0, m = gwlist_len(proxyrelays); j < m; j++) {
MmsProxyRelay *mp = list_get(proxyrelays, j); MmsProxyRelay *mp = gwlist_get(proxyrelays, j);
if (does_prefix_match(mp->allowed_prefix, phonenum) && if (does_prefix_match(mp->allowed_prefix, phonenum) &&
!does_prefix_match(mp->denied_prefix, phonenum)) { !does_prefix_match(mp->denied_prefix, phonenum)) {
return octstr_duplicate(mp->host); return octstr_duplicate(mp->host);

View File

@ -274,9 +274,9 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
/* Now load the VASP list. */ /* Now load the VASP list. */
l = mms_cfg_get_multi(cfg, octstr_imm("mms-vasp")); l = mms_cfg_get_multi(cfg, octstr_imm("mms-vasp"));
m->vasp_list = list_create(); m->vasp_list = gwlist_create();
for (i=0, n=list_len(l); i<n; i++) { for (i=0, n=gwlist_len(l); i<n; i++) {
mCfgGrp *grp = list_get(l, i); mCfgGrp *grp = gwlist_get(l, i);
MmsVasp *mv = gw_malloc(sizeof *mv); MmsVasp *mv = gw_malloc(sizeof *mv);
Octstr *s; Octstr *s;
int ibool = 0; int ibool = 0;
@ -313,9 +313,9 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
warning(0, "mms-to-mobile copy handler VASP specified more than once! Only last config taken."); warning(0, "mms-to-mobile copy handler VASP specified more than once! Only last config taken.");
m->mms2mobile = mv; m->mms2mobile = mv;
} }
list_append(m->vasp_list, mv); gwlist_append(m->vasp_list, mv);
} }
list_destroy(l, NULL); gwlist_destroy(l, NULL);
return m; return m;
} }
@ -323,10 +323,10 @@ List *mms_proxy_relays(mCfg *cfg)
{ {
List *gl = mms_cfg_get_multi(cfg, octstr_imm("mmsproxy")); List *gl = mms_cfg_get_multi(cfg, octstr_imm("mmsproxy"));
int i, n; int i, n;
List *l = list_create(); List *l = gwlist_create();
for (i = 0, n = list_len(gl); i < n; i++) { for (i = 0, n = gwlist_len(gl); i < n; i++) {
mCfgGrp *grp = list_get(gl, i); mCfgGrp *grp = gwlist_get(gl, i);
MmsProxyRelay *m = gw_malloc(sizeof *m); MmsProxyRelay *m = gw_malloc(sizeof *m);
m->host = _mms_cfg_getx(grp, octstr_imm("host")); m->host = _mms_cfg_getx(grp, octstr_imm("host"));
@ -334,10 +334,10 @@ List *mms_proxy_relays(mCfg *cfg)
m->allowed_prefix = _mms_cfg_getx(grp, octstr_imm("allowed-prefix")); m->allowed_prefix = _mms_cfg_getx(grp, octstr_imm("allowed-prefix"));
m->denied_prefix = _mms_cfg_getx(grp, octstr_imm("denied-prefix")); m->denied_prefix = _mms_cfg_getx(grp, octstr_imm("denied-prefix"));
list_append(l, m); gwlist_append(l, m);
} }
list_destroy(gl, NULL); gwlist_destroy(gl, NULL);
return l; return l;
} }
@ -405,13 +405,13 @@ Octstr *mms_find_sender_msisdn(Octstr *send_url,
requestip_header); requestip_header);
if (xip == NULL) if (xip == NULL)
xip = ip ? octstr_duplicate(ip) : NULL; xip = ip ? octstr_duplicate(ip) : NULL;
if (detokenizerfuncs && ((l && list_len(l) > 1) || xip)) if (detokenizerfuncs && ((l && gwlist_len(l) > 1) || xip))
phonenum = detokenizerfuncs->mms_detokenize((l && list_len(l) > 1) ? phonenum = detokenizerfuncs->mms_detokenize((l && gwlist_len(l) > 1) ?
list_get(l, list_len(l) - 1) : gwlist_get(l, gwlist_len(l) - 1) :
send_url, send_url,
xip); xip);
if (l) if (l)
list_destroy(l, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
if (xip) if (xip)
octstr_destroy(xip); octstr_destroy(xip);
} }

View File

@ -40,7 +40,8 @@ int main(int argc, char *argv[])
Octstr *email; Octstr *email;
Octstr *home_mmsc = NULL; Octstr *home_mmsc = NULL;
List *headers;
mms_lib_init(); mms_lib_init();
srandom(time(NULL)); srandom(time(NULL));
@ -115,9 +116,12 @@ int main(int argc, char *argv[])
unpack_mimeheaders(mm); unpack_mimeheaders(mm);
/* Delete some headers... */ /* Delete some headers... */
http_header_remove_all(mm->headers, "Received"); headers = _x_mime_entity_headers(mm);
http_header_remove_all(mm->headers, "X-MimeOLE"); http_header_remove_all(headers, "Received");
http_header_remove_all(mm->headers, "X-Mailer"); http_header_remove_all(headers, "X-MimeOLE");
http_header_remove_all(headers, "X-Mailer");
mime_replace_headers(mm, headers);
http_destroy_headers(headers);
/* Now convert from mime to MMS message. */ /* Now convert from mime to MMS message. */
msg = mms_frommime(mm); msg = mms_frommime(mm);
@ -133,8 +137,9 @@ int main(int argc, char *argv[])
case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_SEND_REQ:
if (ttype != TPLMN) if (ttype != TPLMN)
error(0, "Not allowed to send to non-phone recipient, to=%s!", octstr_get_cstr(xto)); error(0, "Not allowed to send to non-phone recipient, to=%s!", octstr_get_cstr(xto));
else { else {
List *lto = list_create(); List *lto = gwlist_create();
Octstr *qf; Octstr *qf;
Octstr *msgid = mms_get_header_value(msg, octstr_imm("Message-ID")); Octstr *msgid = mms_get_header_value(msg, octstr_imm("Message-ID"));
Octstr *transid = mms_get_header_value(msg, octstr_imm("X-Mms-Transaction-ID")); Octstr *transid = mms_get_header_value(msg, octstr_imm("X-Mms-Transaction-ID"));
@ -145,7 +150,7 @@ int main(int argc, char *argv[])
int dlr; int dlr;
octstr_format_append(xto, "/TYPE=PLMN"); octstr_format_append(xto, "/TYPE=PLMN");
list_append(lto, xto); gwlist_append(lto, xto);
if (dreport && if (dreport &&
octstr_case_compare(dreport, octstr_imm("Yes")) == 0) octstr_case_compare(dreport, octstr_imm("Yes")) == 0)
@ -180,8 +185,8 @@ int main(int argc, char *argv[])
0,MS_1_1); 0,MS_1_1);
rto = octstr_format("system-user@%S", xproxy); rto = octstr_format("system-user@%S", xproxy);
xlto = list_create(); xlto = gwlist_create();
list_append(xlto, rto); gwlist_append(xlto, rto);
qf = mms_queue_add(settings->system_user, xlto, NULL, qf = mms_queue_add(settings->system_user, xlto, NULL,
xproxy, NULL, xproxy, NULL,
@ -194,7 +199,7 @@ int main(int argc, char *argv[])
octstr_get_cstr(settings->global_queuedir), octstr_get_cstr(settings->global_queuedir),
settings->host_alias); settings->host_alias);
list_destroy(xlto, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(xlto, (gwlist_item_destructor_t *)octstr_destroy);
mms_destroy(mresp); mms_destroy(mresp);
octstr_destroy(qf); octstr_destroy(qf);
} }
@ -202,7 +207,7 @@ int main(int argc, char *argv[])
mms_log("Received", xfrom, lto, mms_log("Received", xfrom, lto,
-1, msgid, NULL, xproxy, xproxy ? "MM4" : "MM3", NULL,NULL); -1, msgid, NULL, xproxy, xproxy ? "MM4" : "MM3", NULL,NULL);
list_destroy(lto,NULL); gwlist_destroy(lto,NULL);
octstr_destroy(transid); octstr_destroy(transid);
octstr_destroy(msgid); octstr_destroy(msgid);
if (dreport) if (dreport)
@ -229,8 +234,8 @@ int main(int argc, char *argv[])
MmsEnvelopeTo *t; MmsEnvelopeTo *t;
int i, n; int i, n;
for (i = 0, n = list_len(e->to); i<n; i++) for (i = 0, n = gwlist_len(e->to); i<n; i++)
if ((t = list_get(e->to, i)) != NULL) if ((t = gwlist_get(e->to, i)) != NULL)
t->process = 0; /* Should make it go away. */ t->process = 0; /* Should make it go away. */
mms_queue_update(e); mms_queue_update(e);
info(0, "Email2MMS received send conf from proxy %s to %s from %s => %s", info(0, "Email2MMS received send conf from proxy %s to %s from %s => %s",
@ -248,12 +253,12 @@ int main(int argc, char *argv[])
if (ttype != TPLMN) /* We only send to phones from this interface */ if (ttype != TPLMN) /* We only send to phones from this interface */
error(0, "Not allowed to send to %s!", octstr_get_cstr(xto)); error(0, "Not allowed to send to %s!", octstr_get_cstr(xto));
else { else {
List *lto = list_create(); List *lto = gwlist_create();
Octstr *qf; Octstr *qf;
octstr_format_append(xto, "/TYPE=PLMN"); octstr_format_append(xto, "/TYPE=PLMN");
list_append(lto, xto); gwlist_append(lto, xto);
qf = mms_queue_add(xfrom, lto, NULL, qf = mms_queue_add(xfrom, lto, NULL,
xproxy, NULL, xproxy, NULL,
0, time(NULL) + settings->default_msgexpiry, msg, NULL, 0, time(NULL) + settings->default_msgexpiry, msg, NULL,
@ -263,7 +268,7 @@ int main(int argc, char *argv[])
0, 0,
octstr_get_cstr(settings->global_queuedir), octstr_get_cstr(settings->global_queuedir),
settings->host_alias); settings->host_alias);
list_destroy(lto, NULL); gwlist_destroy(lto, NULL);
if (qf) { if (qf) {
info(0, "Email2MMS Queued DLR from proxy %s to %s from %s => %s", info(0, "Email2MMS Queued DLR from proxy %s to %s from %s => %s",
octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom), octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom),
@ -272,7 +277,7 @@ int main(int argc, char *argv[])
octstr_destroy(qf); octstr_destroy(qf);
} }
list_destroy(lto, NULL); gwlist_destroy(lto, NULL);
} }
break; break;
@ -285,11 +290,11 @@ int main(int argc, char *argv[])
if (ttype != TPLMN) /* We only send to phones from this interface */ if (ttype != TPLMN) /* We only send to phones from this interface */
error(0, "Not allowed to send to %s!", octstr_get_cstr(xto)); error(0, "Not allowed to send to %s!", octstr_get_cstr(xto));
else { else {
List *lto = list_create(); List *lto = gwlist_create();
Octstr *qf; Octstr *qf;
octstr_format_append(xto, "/TYPE=PLMN"); octstr_format_append(xto, "/TYPE=PLMN");
list_append(lto, xto); gwlist_append(lto, xto);
qf = mms_queue_add(xfrom, lto, NULL, qf = mms_queue_add(xfrom, lto, NULL,
xproxy, NULL, xproxy, NULL,
0, time(NULL) + settings->default_msgexpiry, msg, NULL, 0, time(NULL) + settings->default_msgexpiry, msg, NULL,
@ -299,7 +304,7 @@ int main(int argc, char *argv[])
0, 0,
octstr_get_cstr(settings->global_queuedir), octstr_get_cstr(settings->global_queuedir),
settings->host_alias); settings->host_alias);
list_destroy(lto, NULL); gwlist_destroy(lto, NULL);
if (qf) { if (qf) {
info(0, "Email2MMS Queued read report from proxy %s to %s from %s => %s", info(0, "Email2MMS Queued read report from proxy %s to %s from %s => %s",
octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom), octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom),
@ -309,7 +314,7 @@ int main(int argc, char *argv[])
} }
list_destroy(lto, NULL); gwlist_destroy(lto, NULL);
} }
default: default:
{ {

View File

@ -72,27 +72,27 @@ static int sendMsg(MmsEnvelope *e)
if (e->msgtype == MMS_MSGTYPE_SEND_REQ && if (e->msgtype == MMS_MSGTYPE_SEND_REQ &&
!e->bill.billed) { /* Attempt to bill if not already billed */ !e->bill.billed) { /* Attempt to bill if not already billed */
List *l = list_create(); List *l = gwlist_create();
double amt; double amt;
for (i = 0, n = list_len(e->to); i < n; i++) { for (i = 0, n = gwlist_len(e->to); i < n; i++) {
MmsEnvelopeTo *to = list_get(e->to, i); MmsEnvelopeTo *to = gwlist_get(e->to, i);
list_append(l, to->rcpt); gwlist_append(l, to->rcpt);
} }
amt = settings->mms_billfuncs->mms_billmsg(e->from, l, amt = settings->mms_billfuncs->mms_billmsg(e->from, l,
e->msize, e->msize,
e->vaspid, e->vaspid,
settings->mms_bill_module_data); settings->mms_bill_module_data);
list_destroy(l, NULL); gwlist_destroy(l, NULL);
info(0, "Global Queue MMS Bill: From %s, to_count=%ld, msgid=%s, msgsize=%ld: returned=%.2f", info(0, "Global Queue MMS Bill: From %s, to_count=%ld, msgid=%s, msgsize=%ld: returned=%.2f",
octstr_get_cstr(e->from), list_len(e->to), e->msgId ? octstr_get_cstr(e->msgId) : "", octstr_get_cstr(e->from), gwlist_len(e->to), e->msgId ? octstr_get_cstr(e->msgId) : "",
e->msize, amt); e->msize, amt);
if (amt == -1) { /* Delete message. */ if (amt == -1) { /* Delete message. */
for (i = 0, n = list_len(e->to); i < n; i++) { for (i = 0, n = gwlist_len(e->to); i < n; i++) {
MmsEnvelopeTo *to = list_get(e->to, i); MmsEnvelopeTo *to = gwlist_get(e->to, i);
to->process = 0; to->process = 0;
} }
} else if (amt >= 0) { } else if (amt >= 0) {
@ -117,10 +117,10 @@ static int sendMsg(MmsEnvelope *e)
#endif #endif
for (i = 0, n = list_len(e->to); i < n; i++) { for (i = 0, n = gwlist_len(e->to); i < n; i++) {
Octstr *err = NULL; Octstr *err = NULL;
int res = MMS_SEND_OK, m; int res = MMS_SEND_OK, m;
MmsEnvelopeTo *to = list_get(e->to, i); MmsEnvelopeTo *to = gwlist_get(e->to, i);
time_t tnow = time(NULL); time_t tnow = time(NULL);
@ -208,8 +208,8 @@ static int sendMsg(MmsEnvelope *e)
} }
/* Search VASP list, see what you can find... */ /* Search VASP list, see what you can find... */
for (j = 0, m = list_len(settings->vasp_list); j < m; j++) for (j = 0, m = gwlist_len(settings->vasp_list); j < m; j++)
if ((vasp = list_get(settings->vasp_list, j)) != NULL && if ((vasp = gwlist_get(settings->vasp_list, j)) != NULL &&
_x_octstr_int_compare(vasp->short_code, phonenum) == 0) { _x_octstr_int_compare(vasp->short_code, phonenum) == 0) {
res = mms_sendtovasp(vasp, e->from, to->rcpt, res = mms_sendtovasp(vasp, e->from, to->rcpt,
e->msgId, e->msgId,
@ -251,9 +251,9 @@ static int sendMsg(MmsEnvelope *e)
e->msgId, e->expiryt, msg, e->dlr, e->msgId, e->expiryt, msg, e->dlr,
&err); &err);
sent = 1; sent = 1;
} else if (proxyrelays && list_len(proxyrelays) > 0) /* Step through proxies. */ } else if (proxyrelays && gwlist_len(proxyrelays) > 0) /* Step through proxies. */
for (j = 0, m = list_len(proxyrelays); j<m; j++) { for (j = 0, m = gwlist_len(proxyrelays); j<m; j++) {
MmsProxyRelay *mp = list_get(proxyrelays, j); MmsProxyRelay *mp = gwlist_get(proxyrelays, j);
if (!octstr_compare(mp->host, mmsc)) { if (!octstr_compare(mp->host, mmsc)) {
res = mms_sendtoproxy(e->from, to->rcpt, res = mms_sendtoproxy(e->from, to->rcpt,
@ -287,9 +287,9 @@ static int sendMsg(MmsEnvelope *e)
octstr_imm("Expired") : octstr_imm("Rejected")); octstr_imm("Expired") : octstr_imm("Rejected"));
List *l = list_create(); List *l = gwlist_create();
list_append(l, octstr_duplicate(e->from)); gwlist_append(l, octstr_duplicate(e->from));
/* Add to queue, switch via proxy to be from proxy. */ /* Add to queue, switch via proxy to be from proxy. */
qfs = mms_queue_add(settings->system_user, l, qfs = mms_queue_add(settings->system_user, l,
@ -302,7 +302,7 @@ static int sendMsg(MmsEnvelope *e)
qdir, qdir,
settings->host_alias); settings->host_alias);
octstr_destroy(qfs); octstr_destroy(qfs);
list_destroy(l, NULL); gwlist_destroy(l, NULL);
mms_destroy(m); mms_destroy(m);
} }
@ -327,7 +327,7 @@ static int sendMsg(MmsEnvelope *e)
strncpy(cdr->vaspid, e->vaspid ? octstr_get_cstr(e->vaspid) : "", sizeof cdr->vaspid); strncpy(cdr->vaspid, e->vaspid ? octstr_get_cstr(e->vaspid) : "", sizeof cdr->vaspid);
cdr->msg_size = e->msize; cdr->msg_size = e->msize;
list_produce(cdr_list, cdr); /* Put it on list so sending thread sends it. */ gwlist_produce(cdr_list, cdr); /* Put it on list so sending thread sends it. */
} }
/* Update queue entry so that we know which ones have been processed. */ /* Update queue entry so that we know which ones have been processed. */
@ -358,7 +358,7 @@ static void cdr_thread(void *unused)
{ {
MmsCdrStruct *cdr; MmsCdrStruct *cdr;
while ((cdr = list_consume(cdr_list)) != NULL) { while ((cdr = gwlist_consume(cdr_list)) != NULL) {
settings->mms_billfuncs->mms_logcdr(cdr); settings->mms_billfuncs->mms_logcdr(cdr);
/* We should probably write to log here... */ /* We should probably write to log here... */
gw_free(cdr); gw_free(cdr);
@ -377,15 +377,15 @@ void mbuni_global_queue_runner(int *rstop)
/* Start the thread for CDR */ /* Start the thread for CDR */
cdr_list = list_create(); cdr_list = gwlist_create();
list_add_producer(cdr_list); gwlist_add_producer(cdr_list);
gwthread_create(cdr_thread, NULL); gwthread_create(cdr_thread, NULL);
mms_queue_run(qdir, sendMsg, settings->queue_interval, settings->maxthreads, rstop); mms_queue_run(qdir, sendMsg, settings->queue_interval, settings->maxthreads, rstop);
/* When it ends, wait a little for other stuff to stop... */ /* When it ends, wait a little for other stuff to stop... */
sleep(2); sleep(2);
list_remove_producer(cdr_list); /* Stop CDR thread. */ gwlist_remove_producer(cdr_list); /* Stop CDR thread. */
return; return;
} }
@ -421,10 +421,10 @@ int mms_sendtomobile(Octstr *from, Octstr *to,
{ {
Octstr *ret, *x; Octstr *ret, *x;
List *l = list_create(); List *l = gwlist_create();
char tokenstr[128]; char tokenstr[128];
list_append(l, to); gwlist_append(l, to);
/* We generate a special token that will be added to message ID to make /* We generate a special token that will be added to message ID to make
* stealing messages a bit harder. * stealing messages a bit harder.
@ -443,7 +443,7 @@ int mms_sendtomobile(Octstr *from, Octstr *to,
settings->host_alias); settings->host_alias);
octstr_destroy(x); octstr_destroy(x);
list_destroy(l, NULL); gwlist_destroy(l, NULL);
octstr_destroy(ret); octstr_destroy(ret);
if (ret == NULL) if (ret == NULL)
return MMS_SEND_ERROR_TRANSIENT; return MMS_SEND_ERROR_TRANSIENT;
@ -474,16 +474,16 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to,
} }
if (mms_messagetype(msg) == MMS_MSGTYPE_SEND_REQ) { /* Only queue these ones for future response. */ if (mms_messagetype(msg) == MMS_MSGTYPE_SEND_REQ) { /* Only queue these ones for future response. */
List *l = list_create(); List *l = gwlist_create();
Octstr *ret; Octstr *ret;
list_append(l, to); gwlist_append(l, to);
ret = mms_queue_add(from, l, subject, NULL, proxy, 0, expires, msg,NULL, ret = mms_queue_add(from, l, subject, NULL, proxy, 0, expires, msg,NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL,
dlr, mm4_qdir, dlr, mm4_qdir,
settings->host_alias); settings->host_alias);
list_destroy(l, NULL); gwlist_destroy(l, NULL);
if (ret == NULL) { if (ret == NULL) {
*error = octstr_format("MM4: Failed to queue message to %S for future tracking. ", to); *error = octstr_format("MM4: Failed to queue message to %S for future tracking. ", to);
@ -524,7 +524,7 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
int ret = MMS_SEND_ERROR_TRANSIENT; int ret = MMS_SEND_ERROR_TRANSIENT;
int mtype = mms_messagetype(m); int mtype = mms_messagetype(m);
int hstatus = HTTP_OK, tstatus; int hstatus = HTTP_OK, tstatus;
List *xto = list_create(); List *xto = gwlist_create();
MSoapMsg_t *mreq = NULL, *mresp = NULL; MSoapMsg_t *mreq = NULL, *mresp = NULL;
List *rh = NULL, *ph = NULL; List *rh = NULL, *ph = NULL;
Octstr *body = NULL, *rbody = NULL, *url = NULL; Octstr *body = NULL, *rbody = NULL, *url = NULL;
@ -536,7 +536,7 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
vasp ? octstr_get_cstr(vasp->id) : "", vasp ? octstr_get_cstr(vasp->id) : "",
mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to));
list_append(xto, to); gwlist_append(xto, to);
if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, settings->host_alias, if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, settings->host_alias,
@ -554,8 +554,8 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
http_start_request(caller, HTTP_METHOD_POST, vasp->vasp_url, rh, body, 1, NULL, NULL); http_start_request(caller, HTTP_METHOD_POST, vasp->vasp_url, rh, body, 1, NULL, NULL);
if ((xx = http_receive_result(caller, &hstatus, &url, &ph, &rbody)) == NULL || if ((xx = http_receive_result_real(caller, &hstatus, &url, &ph, &rbody,1)) == NULL ||
hstatus != HTTP_OK) { http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
*error = octstr_format("Failed to contact VASP[url=%s] => HTTP returned status = %d, id=%s !", *error = octstr_format("Failed to contact VASP[url=%s] => HTTP returned status = %d, id=%s !",
octstr_get_cstr(vasp->vasp_url), hstatus, xx ? "Ok" : "not OK"); octstr_get_cstr(vasp->vasp_url), hstatus, xx ? "Ok" : "not OK");
goto done1; goto done1;
@ -612,7 +612,7 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
if (url) if (url)
octstr_destroy(url); octstr_destroy(url);
http_caller_destroy(caller); http_caller_destroy(caller);
list_destroy(xto, NULL); gwlist_destroy(xto, NULL);
return ret; return ret;
} }
@ -656,7 +656,7 @@ static int mm7eaif_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgid,
body = mms_tobinary(m); body = mms_tobinary(m);
http_start_request(caller, HTTP_METHOD_POST, vasp->vasp_url, rh, body, 1, NULL, NULL); http_start_request(caller, HTTP_METHOD_POST, vasp->vasp_url, rh, body, 1, NULL, NULL);
if ((xx = http_receive_result(caller, &hstatus, &url, &ph, &rbody)) == NULL || if ((xx = http_receive_result_real(caller, &hstatus, &url, &ph, &rbody,1)) == NULL ||
http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
*error = octstr_format("Failed to contact VASP[url=%s] => HTTP returned status = %d, id=%s !", *error = octstr_format("Failed to contact VASP[url=%s] => HTTP returned status = %d, id=%s !",
octstr_get_cstr(vasp->vasp_url), hstatus, xx ? "Ok" : "not OK"); octstr_get_cstr(vasp->vasp_url), hstatus, xx ? "Ok" : "not OK");

View File

@ -125,7 +125,7 @@ static void start_push(Octstr *rcpt_to, int isphonenum, MmsEnvelope *e, MmsMsg *
int sock = udp_client_socket(); int sock = udp_client_socket();
if (sock > 0) { if (sock > 0) {
MmsEnvelopeTo *xto = list_get(e->to,0); MmsEnvelopeTo *xto = gwlist_get(e->to,0);
octstr_append(pduhdr, s); octstr_append(pduhdr, s);
#if 0 #if 0
octstr_dump(pduhdr, 0); octstr_dump(pduhdr, 0);
@ -161,8 +161,8 @@ static int receive_push_reply(HTTPCaller *caller)
http_status = HTTP_UNAUTHORIZED; http_status = HTTP_UNAUTHORIZED;
while ((env = http_receive_result(caller, &http_status, &final_url, &reply_headers, while ((env = http_receive_result_real(caller, &http_status, &final_url, &reply_headers,
&reply_body)) != NULL) { &reply_body,1)) != NULL) {
MmsEnvelopeTo *xto = NULL; MmsEnvelopeTo *xto = NULL;
Octstr *to = NULL; Octstr *to = NULL;
@ -173,7 +173,7 @@ static int receive_push_reply(HTTPCaller *caller)
if (env == &edummy) /* Skip this one it is a dummy. */ if (env == &edummy) /* Skip this one it is a dummy. */
goto push_free_env; goto push_free_env;
xto = list_get(env->to, 0); xto = gwlist_get(env->to, 0);
if (xto) if (xto)
to = xto->rcpt; to = xto->rcpt;
else { else {
@ -228,7 +228,7 @@ static int sendNotify(MmsEnvelope *e)
{ {
Octstr *to; Octstr *to;
MmsMsg *msg, *smsg = NULL; MmsMsg *msg, *smsg = NULL;
MmsEnvelopeTo *xto = list_get(e->to, 0); MmsEnvelopeTo *xto = gwlist_get(e->to, 0);
Octstr *err = NULL; Octstr *err = NULL;
time_t tnow = time(NULL); time_t tnow = time(NULL);
int j, k, len; int j, k, len;
@ -240,8 +240,10 @@ static int sendNotify(MmsEnvelope *e)
char *rtype = NULL; char *rtype = NULL;
if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */ if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */
e->sendt = e->expiryt + 3600*24*30*12; e->sendt = e->expiryt + 3600*24*30*12;
info(0, "MM1: Message [ID: %s] fetched/touched at least once. Skipping",
e->xqfname);
return mms_queue_update(e); return mms_queue_update(e);
} }
@ -408,9 +410,9 @@ static int sendNotify(MmsEnvelope *e)
rtype ? octstr_imm(rtype) : rtype ? octstr_imm(rtype) :
octstr_imm("Indeterminate")); octstr_imm("Indeterminate"));
List *l = list_create(); List *l = gwlist_create();
Octstr *res; Octstr *res;
list_append(l, from); gwlist_append(l, from);
/* Add to queue, switch via proxy to be from proxy. */ /* Add to queue, switch via proxy to be from proxy. */
res = mms_queue_add(settings->system_user, l, err, res = mms_queue_add(settings->system_user, l, err,
@ -422,7 +424,7 @@ static int sendNotify(MmsEnvelope *e)
0, 0,
octstr_get_cstr(settings->mm1_queuedir), octstr_get_cstr(settings->mm1_queuedir),
settings->host_alias); settings->host_alias);
list_destroy(l, NULL); gwlist_destroy(l, NULL);
mms_destroy(m); mms_destroy(m);
octstr_destroy(res); octstr_destroy(res);
} }

View File

@ -128,15 +128,25 @@ int main(int argc, char *argv[])
h.vasp = NULL; h.vasp = NULL;
h.profile_url = NULL; h.profile_url = NULL;
h.ua = http_header_value(h.headers, octstr_imm("User-Agent")); h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
http_header_dump(h.headers);
/* Get the profile URL and store it. Has effect of fetching if missing. */ /* Get the profile URL and store it. Has effect of fetching if missing. */
if ((h.profile_url = http_header_value(h.headers, if ((h.profile_url = http_header_value(h.headers,
octstr_imm("X-Wap-Profile"))) == NULL) octstr_imm("X-Wap-Profile"))) == NULL)
h.profile_url = http_header_value(h.headers, octstr_imm("Profile")); h.profile_url = http_header_value(h.headers, octstr_imm("Profile"));
if (h.profile_url) if (h.profile_url) {
/* If quoted, get first quoted string */
if (octstr_get_char(h.profile_url, 0) == '"') {
int x;
octstr_delete(h.profile_url, 0, 1);
x = octstr_search_char(h.profile_url, '"', 0);
if (x >= 0)
octstr_delete(h.profile_url, x, octstr_len(h.profile_url));
}
octstr_strip_nonalphanums(h.profile_url); octstr_strip_nonalphanums(h.profile_url);
}
/* Get the sender address. */ /* Get the sender address. */
h.base_client_addr = mms_find_sender_msisdn(h.url, h.base_client_addr = mms_find_sender_msisdn(h.url,
h.ip, h.ip,
@ -482,7 +492,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
Octstr *qf; Octstr *qf;
List *mh = mms_message_headers(m); List *mh = mms_message_headers(m);
Octstr *from = h->client_addr ? octstr_duplicate(h->client_addr) : NULL; Octstr *from = h->client_addr ? octstr_duplicate(h->client_addr) : NULL;
List *to = list_create(); List *to = gwlist_create();
Octstr *subject = NULL; Octstr *subject = NULL;
time_t expiryt, deliveryt; time_t expiryt, deliveryt;
@ -597,7 +607,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
octstr_destroy(subject); octstr_destroy(subject);
if (mh) if (mh)
http_destroy_headers(mh); http_destroy_headers(mh);
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
notify_cmd = "sent"; notify_cmd = "sent";
reply_body = mms_tobinary(mresp); reply_body = mms_tobinary(mresp);
@ -608,7 +618,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
Octstr *qf = NULL, *token = NULL; Octstr *qf = NULL, *token = NULL;
List *mh = mms_message_headers(m); List *mh = mms_message_headers(m);
Octstr *from = h->client_addr ? octstr_duplicate(h->client_addr) : NULL; Octstr *from = h->client_addr ? octstr_duplicate(h->client_addr) : NULL;
List *to = list_create(); List *to = gwlist_create();
Octstr *subject; Octstr *subject;
time_t expiryt, deliveryt; time_t expiryt, deliveryt;
MmsMsg *mfwd = NULL; MmsMsg *mfwd = NULL;
@ -823,8 +833,8 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
MmsMsg *mrep = mms_deliveryreport(pmsgid, h->client_addr, time(NULL), octstr_imm("Forwarded")); MmsMsg *mrep = mms_deliveryreport(pmsgid, h->client_addr, time(NULL), octstr_imm("Forwarded"));
Octstr *x; Octstr *x;
List *l = list_create(); List *l = gwlist_create();
list_append(l, pfrom); gwlist_append(l, pfrom);
x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, 0, x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, 0,
time(NULL) + settings->default_msgexpiry, time(NULL) + settings->default_msgexpiry,
@ -838,7 +848,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (x) if (x)
octstr_destroy(x); octstr_destroy(x);
list_destroy(l, NULL); gwlist_destroy(l, NULL);
mms_destroy(mrep); mms_destroy(mrep);
} }
if (pfrom) if (pfrom)
@ -854,7 +864,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (xstate) if (xstate)
octstr_destroy(xstate); octstr_destroy(xstate);
if (xflags) if (xflags)
list_destroy(xflags, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy);
} }
forward_done: forward_done:
@ -881,7 +891,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (mh) if (mh)
http_destroy_headers(mh); http_destroy_headers(mh);
if (to) if (to)
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
if (otransid) if (otransid)
octstr_destroy(otransid); octstr_destroy(otransid);
if (url) if (url)
@ -934,7 +944,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
} }
if (octstr_str_compare(status, "Retrieved") == 0) { if (octstr_str_compare(status, "Retrieved") == 0) {
MmsEnvelopeTo *t = list_get(e->to, 0); MmsEnvelopeTo *t = gwlist_get(e->to, 0);
if (t) if (t)
t->process = 0; t->process = 0;
} else } else
@ -948,10 +958,10 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|| octstr_case_compare(allow_report, octstr_imm("Yes")) == 0) && || octstr_case_compare(allow_report, octstr_imm("Yes")) == 0) &&
e->dlr) { e->dlr) {
Octstr *x; Octstr *x;
List *l = list_create(); List *l = gwlist_create();
mrpt = mms_deliveryreport(e->msgId, h->client_addr, time(NULL), status); mrpt = mms_deliveryreport(e->msgId, h->client_addr, time(NULL), status);
list_append(l, octstr_duplicate(e->from)); gwlist_append(l, octstr_duplicate(e->from));
x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, 0, x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, 0,
time(NULL) + settings->default_msgexpiry, mrpt, NULL, time(NULL) + settings->default_msgexpiry, mrpt, NULL,
@ -964,7 +974,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (x) if (x)
octstr_destroy(x); octstr_destroy(x);
list_destroy(l, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
mms_destroy(mrpt); mms_destroy(mrpt);
} }
@ -998,7 +1008,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
{ {
List *mh = mms_message_headers(m); List *mh = mms_message_headers(m);
Octstr *from = h->client_addr ? octstr_duplicate(h->client_addr) : octstr_create("anon@anon"); Octstr *from = h->client_addr ? octstr_duplicate(h->client_addr) : octstr_create("anon@anon");
List *to = list_create(); List *to = gwlist_create();
Octstr *x; Octstr *x;
@ -1031,7 +1041,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (mh) if (mh)
http_destroy_headers(mh); http_destroy_headers(mh);
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
http_header_add(rh, "Content-Type", "text/plain"); http_header_add(rh, "Content-Type", "text/plain");
ctype_set = 1; ctype_set = 1;
reply_body = octstr_imm("Received"); reply_body = octstr_imm("Received");
@ -1136,7 +1146,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (xstate) if (xstate)
octstr_destroy(xstate); octstr_destroy(xstate);
if (xflags) if (xflags)
list_destroy(xflags, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy);
if (mstore) if (mstore)
mms_destroy(mstore); mms_destroy(mstore);
@ -1260,8 +1270,8 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
List *lh = mms_get_header_values(m, octstr_imm("X-Mms-Content-Location")); List *lh = mms_get_header_values(m, octstr_imm("X-Mms-Content-Location"));
Octstr *otransid = mms_get_header_value(m, octstr_imm("X-Mms-Transaction-ID")); Octstr *otransid = mms_get_header_value(m, octstr_imm("X-Mms-Transaction-ID"));
int i; int i;
List *cls = list_create(); List *cls = gwlist_create();
List *rss = list_create(); List *rss = gwlist_create();
@ -1275,8 +1285,8 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
goto delete_done; goto delete_done;
} }
for (i = 0; i < list_len(lh); i++) { for (i = 0; i < gwlist_len(lh); i++) {
Octstr *url = list_get(lh,i); Octstr *url = gwlist_get(lh,i);
int mloc; int mloc;
Octstr *qf = NULL, *token = NULL; Octstr *qf = NULL, *token = NULL;
Octstr *cl, *rs = NULL; Octstr *cl, *rs = NULL;
@ -1295,8 +1305,8 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (!e) if (!e)
rs = octstr_format("%dError-permanent-message-not-found", i); rs = octstr_format("%dError-permanent-message-not-found", i);
else { else {
for (j = 0, m = (e->to ? list_len(e->to) : 0); j < m; j++) { for (j = 0, m = (e->to ? gwlist_len(e->to) : 0); j < m; j++) {
MmsEnvelopeTo *x = list_get(e->to,j); MmsEnvelopeTo *x = gwlist_get(e->to,j);
if (x) x->process = 0; if (x) x->process = 0;
} }
if (mms_queue_update(e) != 1) /* Should be freed. */ if (mms_queue_update(e) != 1) /* Should be freed. */
@ -1315,8 +1325,8 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
if (!rs) if (!rs)
rs = octstr_format("%dError-permanent-message-not-found", i); rs = octstr_format("%dError-permanent-message-not-found", i);
list_append(rss, rs); gwlist_append(rss, rs);
list_append(cls, cl); gwlist_append(cls, cl);
if (qf) if (qf)
octstr_destroy(qf); octstr_destroy(qf);
@ -1329,9 +1339,9 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
mms_replace_header_values(mresp, "X-Mms-Response-Status", rss); mms_replace_header_values(mresp, "X-Mms-Response-Status", rss);
delete_done: delete_done:
list_destroy(cls, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(cls, (gwlist_item_destructor_t *)octstr_destroy);
list_destroy(rss, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(rss, (gwlist_item_destructor_t *)octstr_destroy);
list_destroy(lh, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(lh, (gwlist_item_destructor_t *)octstr_destroy);
if (otransid) if (otransid)
octstr_destroy(otransid); octstr_destroy(otransid);
@ -1414,14 +1424,14 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
(prof = mms_get_ua_profile(octstr_get_cstr(h->profile_url))) != NULL) { (prof = mms_get_ua_profile(octstr_get_cstr(h->profile_url))) != NULL) {
int i, n; int i, n;
for (i = 0, n = msgs ? list_len(msgs) : 0; i<n; i++) { /* Make message references. */ for (i = 0, n = msgs ? gwlist_len(msgs) : 0; i<n; i++) { /* Make message references. */
Octstr *x = list_get(msgs, i); Octstr *x = gwlist_get(msgs, i);
Octstr *sdf = NULL, *token = NULL; Octstr *sdf = NULL, *token = NULL;
int loc; int loc;
if (mms_decodefetchurl(x, &sdf, &token, &loc) == 0) { if (mms_decodefetchurl(x, &sdf, &token, &loc) == 0) {
list_insert(msgs, i, sdf); gwlist_insert(msgs, i, sdf);
list_delete(msgs, i+1, 1); gwlist_delete(msgs, i+1, 1);
octstr_destroy(x); octstr_destroy(x);
} else { } else {
if (sdf) if (sdf)
@ -1435,10 +1445,10 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
octstr_get_cstr(h->client_addr), xstates, octstr_get_cstr(h->client_addr), xstates,
xflags, start, limit, msgs); xflags, start, limit, msgs);
/* Make the locations. */ /* Make the locations. */
msglocs = list_create(); msglocs = gwlist_create();
for (i = 0, n = list_len(msgrefs); i < n; i++) { for (i = 0, n = gwlist_len(msgrefs); i < n; i++) {
Octstr *sdf = list_get(msgrefs, i); Octstr *sdf = gwlist_get(msgrefs, i);
list_append(msglocs, gwlist_append(msglocs,
mms_makefetchurl(octstr_get_cstr(sdf), mms_makefetchurl(octstr_get_cstr(sdf),
NULL, MMS_LOC_MMBOX, h->client_addr, settings)); NULL, MMS_LOC_MMBOX, h->client_addr, settings));
} }
@ -1461,20 +1471,20 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
notify_cmd = "deleted"; notify_cmd = "deleted";
if (xflags) if (xflags)
list_destroy(xflags, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy);
if (xstates) if (xstates)
list_destroy(xstates, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(xstates, (gwlist_item_destructor_t *)octstr_destroy);
if (required_headers) if (required_headers)
list_destroy(required_headers, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(required_headers, (gwlist_item_destructor_t *)octstr_destroy);
if (msgrefs) if (msgrefs)
list_destroy(msgrefs, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(msgrefs, (gwlist_item_destructor_t *)octstr_destroy);
if (msglocs) if (msglocs)
list_destroy(msglocs, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(msglocs, (gwlist_item_destructor_t *)octstr_destroy);
if (msgs) if (msgs)
list_destroy(msgs, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(msgs, (gwlist_item_destructor_t *)octstr_destroy);
if (otherhdrs) if (otherhdrs)
http_destroy_headers(otherhdrs); http_destroy_headers(otherhdrs);
@ -1531,7 +1541,7 @@ static MmsVasp *find_mm7sender(List *headers, List *vasps)
int i, n; int i, n;
#if 0 #if 0
return list_get(vasps,0); /* XXX for testing... */ return gwlist_get(vasps,0); /* XXX for testing... */
#endif #endif
if (!v || if (!v ||
octstr_search(v, octstr_imm("Basic "), 0) != 0) octstr_search(v, octstr_imm("Basic "), 0) != 0)
@ -1544,8 +1554,8 @@ static MmsVasp *find_mm7sender(List *headers, List *vasps)
octstr_delete(p, i, octstr_len(p)); octstr_delete(p, i, octstr_len(p));
/* p = user, q = pass. */ /* p = user, q = pass. */
for (i = 0, n = list_len(vasps); i<n; i++) { for (i = 0, n = gwlist_len(vasps); i<n; i++) {
MmsVasp *x = list_get(vasps, i); MmsVasp *x = gwlist_get(vasps, i);
if (octstr_compare(x->vasp_username, p) == 0 && if (octstr_compare(x->vasp_username, p) == 0 &&
octstr_compare(x->vasp_password, q) == 0) { octstr_compare(x->vasp_password, q) == 0) {
@ -1715,8 +1725,8 @@ static void mm7soap_dispatch(MmsHTTPClientInfo *h)
octstr_get_cstr(msgid), octstr_get_cstr(h->vasp->id)); octstr_get_cstr(msgid), octstr_get_cstr(h->vasp->id));
} else { /* Kill it. */ } else { /* Kill it. */
int i, n; int i, n;
for (i = 0, n = list_len(e->to); i<n; i++) { for (i = 0, n = gwlist_len(e->to); i<n; i++) {
MmsEnvelopeTo *xto = list_get(e->to,i); MmsEnvelopeTo *xto = gwlist_get(e->to,i);
xto->process = 0; xto->process = 0;
} }
mms_queue_update(e); /* Will clear it. */ mms_queue_update(e); /* Will clear it. */
@ -1781,7 +1791,7 @@ static void mm7soap_dispatch(MmsHTTPClientInfo *h)
mm7_soap_destroy(mreq); mm7_soap_destroy(mreq);
if (to) if (to)
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
free_clientInfo(h,1); free_clientInfo(h,1);
} }
@ -1795,7 +1805,7 @@ static void mm7eaif_dispatch(MmsHTTPClientInfo *h)
List *rh = http_create_empty_headers(); List *rh = http_create_empty_headers();
Octstr *reply_body = NULL, *value; Octstr *reply_body = NULL, *value;
List *to = list_create(), *hto = NULL; List *to = gwlist_create(), *hto = NULL;
Octstr *subject = NULL, *otransid = NULL, *msgid = NULL; Octstr *subject = NULL, *otransid = NULL, *msgid = NULL;
Octstr *hfrom = NULL; Octstr *hfrom = NULL;
time_t expiryt = -1, deliveryt = -1; time_t expiryt = -1, deliveryt = -1;
@ -1826,13 +1836,13 @@ static void mm7eaif_dispatch(MmsHTTPClientInfo *h)
if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL && if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL &&
list_len(hto) > 0) { /* To address is in headers. */ gwlist_len(hto) > 0) { /* To address is in headers. */
int i, n; int i, n;
if (to) if (to)
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
to = list_create(); to = gwlist_create();
for (i = 0, n = list_len(hto); i < n; i++) { for (i = 0, n = gwlist_len(hto); i < n; i++) {
Octstr *h = NULL, *v = NULL; Octstr *h = NULL, *v = NULL;
List *l; List *l;
int j, m; int j, m;
@ -1840,10 +1850,10 @@ static void mm7eaif_dispatch(MmsHTTPClientInfo *h)
http_header_get(hto,i, &h, &v); http_header_get(hto,i, &h, &v);
l = http_header_split_value(v); l = http_header_split_value(v);
for (j = 0, m = list_len(l); j < m; j++) for (j = 0, m = gwlist_len(l); j < m; j++)
list_append(to, list_get(l, j)); gwlist_append(to, gwlist_get(l, j));
list_destroy(l, NULL); gwlist_destroy(l, NULL);
if (h) octstr_destroy(h); if (h) octstr_destroy(h);
if (v) octstr_destroy(v); if (v) octstr_destroy(v);
} }
@ -1905,7 +1915,7 @@ static void mm7eaif_dispatch(MmsHTTPClientInfo *h)
if (hto) if (hto)
http_destroy_headers(hto); http_destroy_headers(hto);
if (to) if (to)
list_destroy(to, (list_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
if (hfrom) if (hfrom)
octstr_destroy(hfrom); octstr_destroy(hfrom);
if (subject) if (subject)

View File

@ -46,12 +46,12 @@ static int find_own(int i, int argc, char *argv[])
int j, m; int j, m;
List *l = octstr_split(octstr_create(argv[i+1]), List *l = octstr_split(octstr_create(argv[i+1]),
octstr_imm(":")); octstr_imm(":"));
for (j = 0, m = list_len(l); j < m; j++) { for (j = 0, m = gwlist_len(l); j < m; j++) {
Octstr *x = list_get(l, j); Octstr *x = gwlist_get(l, j);
_mms_fixup_address(x); _mms_fixup_address(x);
list_append(to, x); gwlist_append(to, x);
} }
list_destroy(l, NULL); gwlist_destroy(l, NULL);
return 1; return 1;
} else } else
return -1; return -1;
@ -83,7 +83,7 @@ int main(int argc, char *argv[])
return -1; return -1;
mms_lib_init(); mms_lib_init();
to = list_create(); to = gwlist_create();
srandom(time(NULL)); srandom(time(NULL));
cfidx = get_and_set_debugs(argc, argv, find_own); cfidx = get_and_set_debugs(argc, argv, find_own);