📄 mms_msg.c
字号:
case MMS_HEADER_ATTRIBUTES:
ch = mms_string_to_header(value);
pack_short_integer(os, ch);
break;
case MMS_HEADER_MBOX_TOTALS:
case MMS_HEADER_MBOX_QUOTAS:
{
long i, l;
i = octstr_parse_long(&l, value, 0, 10);
if (i <0) {
warning(0, "Bad quota value for field %s!", mms_header_to_cstr(field_type));
i = 0;
}
if (octstr_case_search(value, octstr_imm("bytes"), i) < 0)
ch = 0x80;
else
ch = 0x81;
pack_short_integer(encoded, ch);
wsp_pack_integer_value(encoded, l);
wsp_pack_value(os, encoded);
}
break;
case MMS_HEADER_ELEMENT_DESCRIPTOR:
{
Octstr *cv, *cpar;
List *params;
int i, n;
split_header_value(value, &cv, &cpar);
params = get_value_parameters(cpar);
wsp_pack_text(encoded, cv);
n = gwlist_len(params);
for (i = 0; i<n; i++) {
Octstr *h, *v;
int ch;
http_header_get(params, i, &h, &v);
ch = mms_string_to_descriptor_params(h);
if (ch < 0)
wsp_pack_text(encoded, h);
else
pack_short_integer(encoded, ch);
ch = wsp_string_to_content_type(v);
if (ch < 0)
wsp_pack_text(encoded, v);
else
pack_short_integer(encoded, ch);
octstr_destroy(h);
octstr_destroy(v);
}
octstr_destroy(cv);
octstr_destroy(cpar);
http_destroy_headers(params);
wsp_pack_value(os, encoded);
}
break;
default:
warning(0, "MMS: Unknown header with code 0x%02x!", field_type);
}
if (encoded) octstr_destroy(encoded);
return;
}
static int encode_msgheaders(Octstr *os, List *hdrs)
{
int fcont = 1;
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,
octstr_imm("X-Mms-MMS-Version"));
transid = http_header_value(hdrs,
octstr_imm("X-Mms-Transaction-Id"));
msgtype = http_header_value(hdrs,
octstr_imm("X-Mms-Message-Type"));
ctype = http_header_value(hdrs,
octstr_imm("Content-Type"));
mtype = mms_string_to_message_type(msgtype);
pack_short_integer(os, MMS_HEADER_MESSAGE_TYPE);
pack_short_integer(os, mtype);
octstr_destroy(msgtype);
if (transid) {
pack_short_integer(os, MMS_HEADER_TRANSACTION_ID);
wsp_pack_text(os, transid);
octstr_destroy(transid);
}
pack_short_integer(os, MMS_HEADER_MMS_VERSION);
wsp_pack_version_value(os, version);
octstr_destroy(version);
/* Now pack the rest. */
for (i = 0; fcont && i < l; i++) {
Octstr *field = NULL, *value = NULL;
int htype;
http_header_get(hdrs, i, &field, &value);
htype = mms_string_to_header(field);
if (htype == MMS_HEADER_MMS_VERSION ||
htype == MMS_HEADER_MESSAGE_TYPE ||
htype == MMS_HEADER_TRANSACTION_ID ||
htype == MMS_HEADER_CONTENT_TYPE)
goto loop1;
if (htype < 0)
wsp_pack_application_header(os, field, value);
else {
pack_short_integer(os, htype);
mms_pack_well_known_field(os, htype, value);
}
loop1:
if (field) octstr_destroy(field);
if (value) octstr_destroy(value);
}
if (ctype) {
pack_short_integer(os, MMS_HEADER_CONTENT_TYPE);
wsp_pack_content_type(os, ctype);
octstr_destroy(ctype);
} else if (mtype == MMS_MSGTYPE_SEND_REQ ||
mtype == MMS_MSGTYPE_RETRIEVE_CONF)
warning(0, "MMS: Content type missing in encode_headers!");
return 0;
}
/* Does basic fixups on a message. */
static int fixup_msg(MmsMsg *m, Octstr *from)
{
Octstr *ver;
Octstr *s = NULL;
if (!m)
return -1;
ver = http_header_value(m->headers, octstr_imm("X-Mms-MMS-Version"));
if (!ver || octstr_str_compare(ver, "1.1") <= 0) {
m->enc = MS_1_1;
if (!ver)
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");
switch (m->message_type) {
case MMS_MSGTYPE_SEND_REQ:
case MMS_MSGTYPE_RETRIEVE_CONF:
case MMS_MSGTYPE_FORWARD_REQ:
/* Check for from. */
if (from && (s = http_header_value(m->headers, octstr_imm("From"))) == NULL)
http_header_add(m->headers, "From", octstr_get_cstr(from));
else if (s)
octstr_destroy(s);
/* Check for date. */
if ((s = http_header_value(m->headers, octstr_imm("Date"))) == NULL) {
Octstr *t = date_format_http(time(NULL));
http_header_add(m->headers, "Date", octstr_get_cstr(t));
octstr_destroy(t);
} else
octstr_destroy(s);
#if 0 /* This will be done elsewhere. */
/* Check for msgid, put in if missing. */
if ((s = http_header_value(m->headers, octstr_imm("Message-ID"))) == NULL)
http_header_add(m->headers, "Message-ID", "00000");
else
octstr_destroy(s);
#endif
/* check for content-type. */
if ((s = http_header_value(m->headers, octstr_imm("Content-Type"))) == NULL) {
char *ctype;
if (m->body.s == NULL ||
(!m->ismultipart &&
octstr_check_range(m->body.s, 0,
octstr_len(m->body.s), _mms_gw_isprint) == 0))
ctype = "application/octet-stream";
else if (m->ismultipart)
ctype = "application/vnd.wap.multipart.mixed";
else
ctype = "text/plain";
http_header_add(m->headers, "Content-Type", ctype);
} else
octstr_destroy(s);
strip_boundary_element(m->headers, NULL); /* remove top-level boundary element if any. */
break;
case MMS_MSGTYPE_SEND_CONF:
case MMS_MSGTYPE_NOTIFICATION_IND:
case MMS_MSGTYPE_DELIVERY_IND:
case MMS_MSGTYPE_READ_REC_IND:
case MMS_MSGTYPE_READ_ORIG_IND:
http_header_remove_all(m->headers, "Content-Type"); /* Just in case, particularly from mime! */
break;
}
return 0;
}
mms_encoding mms_message_enc(MmsMsg *msg)
{
gw_assert(msg);
return msg->enc;
}
MmsMsg *mms_frombinary(Octstr *msg, Octstr *from)
{
int res = 0;
MmsMsg _m = {0}, *m = NULL;
ParseContext *p;
Octstr *s;
if (!msg)
return NULL;
p = parse_context_create(msg);
mms_strings_init(); /* Just in case. */
_m.headers = gwlist_create();
decode_msgheaders(p, _m.headers, from, 1);
if (_m.headers == NULL ||
gwlist_len(_m.headers) == 0)
goto done;
/* Get the message type and also set flag for whether multipart.*/
s = http_header_value(_m.headers, octstr_imm("Content-Type"));
if (s &&
octstr_search(s, octstr_imm("application/vnd.wap.multipart"), 0) == 0)
_m.ismultipart = 1;
if (s)
octstr_destroy(s);
s = http_header_value(_m.headers, octstr_imm("X-Mms-Message-Type"));
if (s) {
_m.message_type = mms_string_to_message_type(s);
octstr_destroy(s);
} else
goto done;
s = http_header_value(_m.headers, octstr_imm("Message-ID"));
_m.msgId = s;
if ((res = decode_msgbody(p, &_m)) < 0) /* A body decode error occured. */
goto done;
m = gw_malloc(sizeof m[0]); /* all ok, copy. */
*m = _m;
fixup_msg(m, from);
done:
parse_context_destroy(p);
if (!m) { /* This means an error occurred. Delete the interim stuff. */
MmsMsg *msg = &_m;
if (msg->ismultipart && msg->body.l)
gwlist_destroy(msg->body.l, (gwlist_item_destructor_t *)mime_entity_destroy);
else if (msg->body.s)
octstr_destroy(msg->body.s);
if (msg->headers)
http_destroy_headers(msg->headers);
if (msg->msgId)
octstr_destroy(msg->msgId);
}
return m;
}
static void _x_mime_entity_dump(MIMEEntity *x, int level, int headers_only)
{
int i,m, ism;
List *h;
Octstr *body;
ism = ((m = mime_entity_num_parts(x)) > 0);
debug("part.dump", 0, "%sMultipart -> ", ism ? "" : "Not ");
h = mime_entity_headers(x);
strip_boundary_element(h,NULL);
http_header_dump(h);
http_destroy_headers(h);
if (ism)
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)
{
int i, n;
gw_assert(m);
http_header_dump(m->headers);
debug("mms.dump", 0, "Dumping MMS message body (%s) [%ld parts] --> ",
m->ismultipart ? "mulitpart" : "not multipart",
m->ismultipart ? gwlist_len(m->body.l) : 0);
if (m->ismultipart)
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 *mms_tobinary(MmsMsg *msg)
{
Octstr *s;
if (!msg)
return NULL;
s = octstr_create("");
encode_msgheaders(s, msg->headers);
if (msg->body.s)
encode_msgbody(s, msg);
return s;
}
int mms_messagetype(MmsMsg *msg)
{
gw_assert(msg);
return msg->message_type;
}
static void convert_mime_msg(MIMEEntity *m)
{
int i, n;
Octstr *content_type = NULL, *params;
char *s = NULL;
List *h = mime_entity_headers(m);
n = get_content_type(h, &content_type, ¶ms);
if (n == 0 && content_type) {
if (octstr_str_compare(content_type,
"application/vnd.wap.multipart.related") == 0)
s = "multipart/related";
else if (octstr_str_compare(content_type,
"application/vnd.wap.multipart.alternative") == 0)
s = "multipart/alternative";
else if (octstr_str_compare(content_type,
"application/vnd.wap.multipart.mixed") == 0)
s = "multipart/mixed";
octstr_destroy(content_type);
}
if (s) {
Octstr *value;
if (params && octstr_len(params) > 0) {
List *ph = get_value_parameters(params); /* unpack then re-pack them with proper quoting for mime.*/
Octstr *ps = make_value_parameters(ph);
value = octstr_format("%s; %S", s, params);
octstr_destroy(ps);
http_destroy_headers(ph);
} else
value = 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);
octstr_destroy(params);
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)
{
int i, n;
Octstr *content_type, *params;
char *s = NULL;
List *h = mime_entity_headers(m);
n = get_content_type(h, &content_type, ¶ms);
if (n == 0 && content_type) {
if (octstr_case_compare(content_type,
octstr_imm("multipart/related")) == 0)
s = "application/vnd.wap.multipart.related";
else if (octstr_case_compare(content_type,
octstr_imm("multipart/alternative")) == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -