|
|
|
@ -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);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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, ¶ms);
|
|
|
|
|
List *h = _x_mime_entity_headers(m);
|
|
|
|
|
|
|
|
|
|
get_content_type(h, &content_type, ¶ms);
|
|
|
|
|
|
|
|
|
|
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, ¶ms);
|
|
|
|
|
get_content_type(h, &content_type, ¶ms);
|
|
|
|
|
|
|
|
|
|
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) {
|
|