1
0
Fork 0

Mbuni updated to Kannel 1.4.1 -- initial stab

master
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

View File

@ -1,6 +1,6 @@
dnl Mbuni - Open Source MMS Gateway
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 Paul Bagyenda <bagyenda@dsmagic.com>
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)?
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
@ -260,7 +260,7 @@ cat<<X
License:
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
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>
</UL></LI>
<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.3">Installing Required Components</A></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>
<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
href="#required_comps">here</a>.
href="#required_comps">here</a></strong>.
</p>
<p>
In brief, to install Mbuni, you need to:
<ul>
<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, patch and install the AMR encoder/decoder
<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
will first need to download, patch, compile and install Kannel v1.4.0 from <a
href="http://www.kannel.org/download/1.4.0/gateway-1.4.0.tar.bz2">kannel.org</a>:</p>
will first need to download and install Kannel v1.4.1 from <a
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>
<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
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);
lines = octstr_split(sf, octstr_imm("\n"));
for (i = 0, n = list_len(lines); i < n; i++) {
Octstr *current = list_get(lines,i);
for (i = 0, n = gwlist_len(lines); i < n; i++) {
Octstr *current = gwlist_get(lines,i);
int pos;
octstr_strip_blanks(current);
@ -182,10 +182,10 @@ mCfg *mms_cfg_read(Octstr *file)
List *l = dict_get(cfg->grps, value);
if (l == NULL) {
l = list_create();
l = gwlist_create();
dict_put(cfg->grps, value, l);
}
list_append(l, grp);
gwlist_append(l, grp);
} else if (dict_put_once(cfg->grps, value, grp) == 0)
panic(0, "Group `%s' [at line %d] cannot appear more "
"than once in config!",
@ -207,7 +207,7 @@ mCfg *mms_cfg_read(Octstr *file)
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);
return cfg;
}
@ -226,18 +226,18 @@ void mms_cfg_destroy(mCfg *cfg)
gw_assert(cfg);
for (i = 0, l = dict_keys(cfg->grps), n = list_len(l); i < n; i++) {
Octstr *grpname = list_get(l, i);
for (i = 0, l = dict_keys(cfg->grps), n = gwlist_len(l); i < n; i++) {
Octstr *grpname = gwlist_get(l, i);
void *val = dict_get(cfg->grps, grpname);
if (is_multigroup(grpname)) {
List *gl = val;
int j, m = list_len(gl);
int j, m = gwlist_len(gl);
for (j = 0; j < m; j++)
mGrp_destroy(list_get(gl, j));
mGrp_destroy(gwlist_get(gl, j));
} else
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);
octstr_destroy(cfg->file);
gw_free(cfg);
@ -262,8 +262,8 @@ List *mms_cfg_get_multi(mCfg *cfg, Octstr *name)
r = dict_get(cfg->grps, name);
if (r)
for (i = 0, l = list_create(); i < list_len(r); i++)
list_append(l, list_get(r,i));
for (i = 0, l = gwlist_create(); i < gwlist_len(r); i++)
gwlist_append(l, gwlist_get(r,i));
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.
* 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;
@ -228,31 +228,26 @@ static int parse_headers(xmlNodePtr start, List *h, int sigparent)
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;
xmlDocPtr doc;
MIMEEntity *msg = NULL;
List *h;
int s = -1;
MSoapMsg_t *smsg = NULL;
if (!mime)
return NULL;
/* Find the start element:
* - either the mime entity is multipart and has start param ...
* - or entity is multipart and start element is (implicitly) first element
* - either the mime entity is multipart and has start param (or implicitly first element) ...
* - or entity is not multipart, so body is xml
*/
if (mime->start)
xml = mime->start->body;
else if (mime->multiparts && list_len(mime->multiparts) > 0) {
MIMEEntity *x = list_get(mime->multiparts,0);
xml = x->body;
} else
xml = mime->body;
/* Don't free 'xml'! It is part of mime object. */
if ((start = mime_multipart_start_elem(mime)) != NULL)
xml = mime_entity_body(start);
else
xml = mime_entity_body(mime);
if (!xml)
goto done;
#if 1
@ -277,24 +272,26 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
MIMEEntity *c = NULL;
int i, n;
char *loc = octstr_get_cstr(cloc) + 4; /* skip 'cid:' part. */
for (i = 0, n = list_len(mime->multiparts); i<n; i++) {
MIMEEntity *x = list_get(mime->multiparts, i);
Octstr *y = x ? http_header_value(x->headers, octstr_imm("Content-ID")) : NULL;
for (i = 0, n = mime_entity_num_parts(mime); i<n; i++) {
MIMEEntity *x = mime_entity_get_part(mime, i);
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) : "");
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)
c = x;
c = mime_entity_duplicate(x);
if (y)
octstr_destroy(y);
http_destroy_headers(headers);
mime_entity_destroy(x);
if (c)
break;
}
if (c)
msg = mime_entity_duplicate(c);
msg = c; /* this is already a copy. */
octstr_destroy(cloc);
}
smsg = gw_malloc(sizeof *smsg);
@ -304,6 +301,10 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
done:
if (mime)
mime_entity_destroy(mime);
if (start)
mime_entity_destroy(start);
if (xml)
octstr_destroy(xml);
return smsg;
}
@ -333,7 +334,7 @@ static void output_rcpt(char *hdr, List *hdrs, Octstr *p)
char x[32];
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;
http_header_get(l, i, &h, &v);
@ -450,7 +451,7 @@ Octstr *headers_to_soapxml(List *hdrs)
/* 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;
char *zz;
int tag;
@ -568,8 +569,9 @@ Octstr *headers_to_soapxml(List *hdrs)
int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
{
MIMEEntity *mime;
Octstr *ctype;
Octstr *ctype, *s;
List *headers;
mime = mime_entity_create();
if (m->msg) {
@ -585,21 +587,31 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
'a' + random() % 26);
MIMEEntity *xml = mime_entity_create();
List *hh = http_header_duplicate(m->envelope);
List *hx;
/* Replace in envelope. */
http_header_remove_all(hh, "Content");
http_header_add(hh, "Content", octstr_get_cstr(cloc));
/* Replace content location in msg part. */
http_header_remove_all(c->headers, "Content-ID");
http_header_add(c->headers, "Content-ID", octstr_get_cstr(cloc_str));
http_header_add(xml->headers, "Content-Type", "\"text/xml\"");
http_header_add(xml->headers, "Content-ID", octstr_get_cstr(envloc));
xml->body = headers_to_soapxml(hh);
hx = _x_mime_entity_headers(c);
http_header_remove_all(hx, "Content-ID");
http_header_add(hx, "Content-ID", octstr_get_cstr(cloc_str));
mime_replace_headers(c, hx);
http_destroy_headers(hx);
list_append(mime->multiparts, xml);
list_append(mime->multiparts, c);
hx = http_create_empty_headers();
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);
@ -608,16 +620,25 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
octstr_destroy(envloc);
octstr_destroy(cloc);
octstr_destroy(cloc_str);
octstr_destroy(cloc_str);
mime_entity_destroy(xml);
mime_entity_destroy(c);
} else {
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));
http_header_add(mime->headers, "SOAPAction", "\"some-url\"");
mime_entity_body_and_headers(mime, body, hdrs);
headers = http_create_empty_headers();
http_header_add(headers, "Content-Type", octstr_get_cstr(ctype));
http_header_add(headers, "SOAPAction", "\"some-url\"");
mime_replace_headers(mime, headers);
http_destroy_headers(headers);
*body = mime_entity_body(mime);
*hdrs = _x_mime_entity_headers(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);
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;
int ch;
http_header_get(l, i, &h, &v);
ch = octstr_get_char(v, 0);
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(v);
}
@ -670,7 +691,7 @@ int mm7_get_envelope(MSoapMsg_t *m,
Octstr *s;
if (*to == NULL)
*to = list_create();
*to = gwlist_create();
get_rcptvalues(*to, m->envelope, "To");
get_rcptvalues(*to, m->envelope, "Cc");
@ -730,7 +751,7 @@ MmsMsg *mm7_soap_to_mmsmsg(MSoapMsg_t *m, Octstr *from)
if (!msg)
break;
mms_remove_headers(msg, "Content-ID"); /* not necessary, but... */
/* Put in some headers... */
if (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?? */
l = list_create();
l = gwlist_create();
get_rcptvalues(l, m->envelope, "To");
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");
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. */
break;
@ -877,7 +898,8 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
Octstr *s;
int i, n;
Octstr *xfrom;
List *headers;
xfrom = octstr_format("+ %S", from ? from : octstr_imm("anon@anon"));
switch(mtype) {
case MMS_MSGTYPE_SEND_REQ:
@ -886,8 +908,8 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
transid);
m->msg = mms_tomime(msg,1);
for (i = 0, n = xto ? list_len(xto) : 0; i < n; i++) { /* Add recipients. */
Octstr *xx = octstr_format("+ %S", list_get(xto, i));
for (i = 0, n = xto ? gwlist_len(xto) : 0; i < n; i++) { /* Add recipients. */
Octstr *xx = octstr_format("+ %S", gwlist_get(xto, i));
http_header_add(m->envelope, "To",
octstr_get_cstr(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??? */
http_header_remove_all(m->msg->headers, "Subject");
http_header_remove_all(m->msg->headers, "X-Mms-Message-Type");
http_header_remove_all(m->msg->headers, "X-Mms-Message-Version");
http_header_remove_all(m->msg->headers, "From");
http_header_remove_all(m->msg->headers, "To");
http_header_remove_all(m->msg->headers, "Cc");
http_header_remove_all(m->msg->headers, "Bcc");
headers = _x_mime_entity_headers(m->msg);
http_header_remove_all(headers, "Subject");
http_header_remove_all(headers, "X-Mms-Message-Type");
http_header_remove_all(headers, "X-Mms-Message-Version");
http_header_remove_all(headers, "From");
http_header_remove_all(headers, "To");
http_header_remove_all(headers, "Cc");
http_header_remove_all(headers, "Bcc");
mime_replace_headers(m->msg, headers);
http_destroy_headers(headers);
break;
case MMS_MSGTYPE_READ_ORIG_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));
if (xto && list_len(xto) > 0) {
Octstr *xx = octstr_format("+ %S", list_get(xto, 0));
if (xto && gwlist_len(xto) > 0) {
Octstr *xx = octstr_format("+ %S", gwlist_get(xto, 0));
http_header_add(m->envelope, "To",
octstr_get_cstr(xx));
octstr_destroy(xx);

View File

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

View File

@ -31,10 +31,11 @@ struct MmsMsg {
#define SIZHINT 47
static void mm_destroy(MIMEEntity *mx);
static int encode_msgheaders(Octstr *os, List *hdrs);
static int decode_msgheaders(ParseContext *context, List *hdr, Octstr *from, int stop_on_ctype);
static inline void pack_short_integer(Octstr *s, int ch)
{
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++) {
int dlen, hlen;
MIMEEntity *x = gw_malloc(sizeof *x);
MIMEEntity *x = mime_entity_create();
List *headers;
Octstr *hs;
Octstr *content;
Octstr *content_type;
memset(x, 0,sizeof *x);
hlen = 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));
x->headers = wsp_headers_unpack(hs, 1);
headers = wsp_headers_unpack(hs, 1);
octstr_destroy(hs);
strip_boundary_element(headers,NULL);
mime_replace_headers(x, headers);
parse_skip_to_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);
http_destroy_headers(headers);
if (!content || !content_type) {
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);
if (content_type) octstr_destroy(content_type);
if (content_type)
octstr_destroy(content_type);
if (content)
octstr_destroy(content);
return -1;
}
if (octstr_case_compare(content_type,
octstr_imm("application/vnd.wap.multipart.related")) == 0 ||
octstr_case_compare(content_type,
@ -129,46 +139,65 @@ static int decode_multipart(ParseContext *context, List *body)
octstr_case_compare(content_type,
octstr_imm("application/vnd.wap.multipart.mixed")) == 0) { /* Body is multipart. */
ParseContext *p = parse_context_create(content);
int res;
List *ml = x->multiparts = list_create();
res = decode_multipart(p, x->multiparts);
octstr_destroy(content);
parse_context_destroy(p);
List *ml = gwlist_create();
int res = decode_multipart(p, ml);
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) {
list_destroy(ml, (list_item_destructor_t *)mime_entity_destroy);
if (content_type)
octstr_destroy(content_type);
if (content)
octstr_destroy(content);
return -1;
}
} else
x->body = content;
mime_entity_set_body(x,content);
octstr_destroy(content);
octstr_destroy(content_type);
list_append(body, x);
gwlist_append(body, x);
}
return 0;
}
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);
i = 0;
while (i<n) {
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 (x->multiparts &&
list_len(x->multiparts) > 0) /* This is a multi-part, go down further. */
encode_multipart(mbody, x->multiparts);
else if (x->body)
octstr_append(mbody, x->body);
if ((m = mime_entity_num_parts(x)) > 0) { /* This is a multi-part,
* go down further.
*/
List *l = gwlist_create();
for (j = 0; j < m; j++)
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(mbody));
@ -188,7 +217,7 @@ static int decode_msgbody(ParseContext *context, MmsMsg *msg)
{
int res = 0;
if (msg->ismultipart) {
msg->body.l = list_create();
msg->body.l = gwlist_create();
res = decode_multipart(context, msg->body.l);
} else
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);
wsp_pack_text(encoded, cv);
n = list_len(params);
n = gwlist_len(params);
for (i = 0; i<n; i++) {
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)
{
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;
strip_boundary_element(hdrs,NULL);
/* First ensure that top headers are in place. */
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);
} else if (octstr_str_compare(ver, "1.2") <= 0)
m->enc = MS_1_2;
http_header_remove_all(m->headers, "MIME-Version");
if (m->message_type == MMS_MSGTYPE_SEND_REQ ||
m->message_type == MMS_MSGTYPE_RETRIEVE_CONF) {
Octstr *s = NULL;
@ -1030,7 +1060,8 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
} else
octstr_destroy(s);
}
strip_boundary_element(m->headers, NULL); /* remove top-level boundary element if any. */
return 0;
}
@ -1053,11 +1084,11 @@ MmsMsg *mms_frombinary(Octstr *msg, Octstr *from)
p = parse_context_create(msg);
mms_strings_init(); /* Just in case. */
_m.headers = list_create();
_m.headers = gwlist_create();
decode_msgheaders(p, _m.headers, from, 1);
if (_m.headers == NULL ||
list_len(_m.headers) == 0)
gwlist_len(_m.headers) == 0)
goto done;
/* 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;
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)
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)
{
int i, n, ism;
ism = (x->multiparts && list_len(x->multiparts) > 0) ? 1 : 0;
debug("part.dump", 0, "%sMultipart -> ", ism ? "" : "Not ");
http_header_dump(x->headers);
int i,m, ism;
List *h;
Octstr *body;
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)
for (i = 0, n = list_len(x->multiparts); i<n; i++)
_x_mime_entity_dump(list_get(x->multiparts, i), level+1, headers_only);
else if (x->body && !headers_only)
octstr_dump(x->body, level);
for (i = 0; i<m; i++) {
MIMEEntity *xm = mime_entity_get_part(x, i);
_x_mime_entity_dump(xm, level+1, headers_only);
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)
@ -1131,17 +1174,17 @@ void mms_msgdump(MmsMsg *m, int headers_only)
debug("mms.dump", 0, "Dumping MMS message body (%s) [%ld parts] --> ",
m->ismultipart ? "mulitpart" : "not multipart",
m->ismultipart ? list_len(m->body.l) : 0);
m->ismultipart ? gwlist_len(m->body.l) : 0);
if (m->ismultipart)
for (i = 0, n = list_len(m->body.l); i< n; i++) {
MIMEEntity *x = list_get(m->body.l, i);
debug("mms.dump", 0, "--->Message part: %d --->", i);
_x_mime_entity_dump(x,0,headers_only);
}
for (i = 0, n = gwlist_len(m->body.l); i< n; i++) {
MIMEEntity *x = gwlist_get(m->body.l, i);
debug("mms.dump", 0, "--->Message part: %d --->", i);
_x_mime_entity_dump(x,0,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;
Octstr *content_type, *params;
char *s = NULL;
get_content_type(m->headers, &content_type, &params);
List *h = _x_mime_entity_headers(m);
get_content_type(h, &content_type, &params);
if (content_type) {
if (octstr_str_compare(content_type,
@ -1187,24 +1231,25 @@ static void convert_mime_msg(MIMEEntity *m)
octstr_destroy(content_type);
}
if (s) {
Octstr *value;
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));
Octstr *value = (params && octstr_len(params) > 0) ?
octstr_format("%s; %S", s, params) : octstr_create(s);
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);
}
if (h)
http_destroy_headers(h);
if (params)
octstr_destroy(params);
if (m->multiparts)
for (i = 0, n = list_len(m->multiparts); i < n; i++)
convert_mime_msg(list_get(m->multiparts, i));
if ((n = mime_entity_num_parts(m)) > 0)
for (i = 0; i < n; 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)
@ -1212,8 +1257,9 @@ static void unconvert_mime_msg(MIMEEntity *m)
int i, n;
Octstr *content_type, *params;
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 (octstr_case_compare(content_type,
@ -1227,35 +1273,21 @@ static void unconvert_mime_msg(MIMEEntity *m)
s = "application/vnd.wap.multipart.mixed";
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)
octstr_destroy(params);
if (m->multiparts && list_len(m->multiparts) > 0)
for (i = 0, n = list_len(m->multiparts); i < n; i++)
unconvert_mime_msg(list_get(m->multiparts, i));
if ((n = mime_entity_num_parts(m)) > 0)
for (i = 0; i < n; 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)
return NULL;
m = gw_malloc(sizeof *m);
memset(m, 0, sizeof *m);
m->body = NULL;
m->multiparts = NULL;
m->start = NULL;
m->headers = http_header_duplicate(msg->headers);
m = mime_entity_create();
mime_replace_headers(m, msg->headers);
if (!msg->ismultipart)
m->body = msg->body.s ? octstr_duplicate(msg->body.s) : NULL;
mime_entity_set_body(m, msg->body.s);
else {
m->multiparts = list_create();
for (i = 0, n = list_len(msg->body.l); i < n; i++) {
MIMEEntity *mx = mime_entity_duplicate(list_get(msg->body.l, i));
list_append(m->multiparts, mx);
for (i = 0, n = gwlist_len(msg->body.l); i < n; i++) {
MIMEEntity *mx = gwlist_get(msg->body.l, i);
mime_entity_add_part(m, mx);
}
}
convert_mime_msg(m);
@ -1294,29 +1321,34 @@ MmsMsg *mms_frommime(MIMEEntity *mime)
MmsMsg *m;
Octstr *s;
MIMEEntity *mx;
int n;
if (!mime)
return NULL;
m = gw_malloc(sizeof *m);
memset(m, 0, sizeof *m);
n = mime_entity_num_parts(mime);
mx = mime_entity_duplicate(mime);
unconvert_mime_msg(mx); /* Fix-up content type issues. */
unpack_mimeheaders(mx);
unbase64_mimeparts(mx);
m->headers = mx->headers;
if (mx->multiparts && list_len(mx->multiparts) > 0) {
m->headers = _x_mime_entity_headers(mx);
if (n > 0) {
int i;
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 {
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 */
m->msgId = http_header_value(m->headers, octstr_imm("Message-ID"));
@ -1385,15 +1417,6 @@ MmsMsg *mms_frommime(MIMEEntity *mime)
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)
{
@ -1401,7 +1424,7 @@ void mms_destroy(MmsMsg *msg)
if (!msg)
return;
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)
octstr_destroy(msg->body.s);
http_destroy_headers(msg->headers);
@ -1596,11 +1619,11 @@ MmsMsg *mms_retrieveconf(MmsMsg *msg, Octstr *transactionid,
else
/* Body is a list of MIMEEntities, so recreate it. */
for (m->body.l = list_create(), i = 0,
n = list_len(msg->body.l);
for (m->body.l = gwlist_create(), i = 0,
n = gwlist_len(msg->body.l);
i<n; i++)
list_append(m->body.l,
mime_entity_duplicate(list_get(msg->body.l, i)));
gwlist_append(m->body.l,
mime_entity_duplicate(gwlist_get(msg->body.l, i)));
/* Remove some headers that may not be permitted. */
mms_remove_headers(m, "X-Mms-Expiry");
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);
http_header_remove_all(msg->headers, hname);
for (i = 0; i < list_len(value); i++) {
Octstr *x = list_get(value, i);
for (i = 0; i < gwlist_len(value); i++) {
Octstr *x = gwlist_get(value, i);
http_header_add(msg->headers, hname, octstr_get_cstr(x));
}
return 0;
@ -1716,14 +1739,14 @@ List *mms_get_header_values(MmsMsg *msg, Octstr *header)
int i;
gw_assert(msg);
l = list_create();
l = gwlist_create();
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;
http_header_get(h, i, &hname, &value);
list_append(l, value);
gwlist_append(l, value);
octstr_destroy(hname);
}
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));
/* Add only those headers requested. */
for (i = 0, n = list_len(reqhdrs); i < n; i++) {
Octstr *header = list_get(reqhdrs,i);
for (i = 0, n = gwlist_len(reqhdrs); i < n; i++) {
Octstr *header = gwlist_get(reqhdrs,i);
List *h = http_header_find_all(mm->headers, octstr_get_cstr(header));
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)
hasmsgid = 1;
for (j = 0; j < list_len(h); j++) {
for (j = 0; j < gwlist_len(h); j++) {
Octstr *hname, *value;
http_header_get(h, j, &hname, &value);
octstr_destroy(hname);
@ -1892,7 +1915,7 @@ static int mms_convert_to_mboxdescr(MmsMsg *mm, Octstr *cloc, List *reqhdrs,
if (!addcontent) {
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)
octstr_destroy(mm->body.s);
mm->body.s = NULL;
@ -1956,15 +1979,15 @@ MmsMsg *mms_viewconf(char *transid,
msize = mms_msgsize(m);
n = list_len(msgrefs);
n = gwlist_len(msgrefs);
msgcount = 0;
m->ismultipart = 1;
m->body.l = list_create();
m->body.l = gwlist_create();
for (i = 0; i < n; i++) {
unsigned long tmsize;
Octstr *msgref = list_get(msgrefs,i);
Octstr *msgloc = list_get(msglocs, i);
Octstr *msgref = gwlist_get(msgrefs,i);
Octstr *msgloc = gwlist_get(msglocs, i);
MmsMsg *mm = getmsg(p1, p2, msgref, &tmsize);
Octstr *ms;
@ -1976,12 +1999,16 @@ MmsMsg *mms_viewconf(char *transid,
ms = mms_tobinary(mm);
if (octstr_len(ms) + msize <= maxsize) {
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");
mtmp->body = ms;
<