📄 mms_msg.c
字号:
s = "application/vnd.wap.multipart.alternative";
else if (octstr_case_compare(content_type,
octstr_imm("multipart/mixed")) == 0)
s = "application/vnd.wap.multipart.mixed";
else if (DRM_CONTENT_TYPE(content_type) &&
mime_entity_num_parts(m) > 0) { /* fixup drm that might have been screwed up. */
Octstr *x = mime_entity_body(m);
while (mime_entity_num_parts(m) > 0) /* remove them all. this message must not be parsed as mime. */
mime_entity_remove_part(m, 0);
mime_entity_set_body(m, x);
octstr_destroy(x);
}
octstr_destroy(content_type);
}
if (s)
strip_boundary_element(h,s);
mime_replace_headers(m, h);
http_destroy_headers(h);
if (params)
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);
unconvert_mime_msg(x);
mime_entity_replace_part(m, i, x);
}
}
MIMEEntity *mms_tomime(MmsMsg *msg, int base64)
{
MIMEEntity *m;
int i, n;
if (!msg)
return NULL;
m = mime_entity_create();
mime_replace_headers(m, msg->headers);
if (!msg->ismultipart)
mime_entity_set_body(m, msg->body.s);
else {
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);
if (base64)
base64_mimeparts(m,0);
return m;
}
static void fixup_date(List *headers, Octstr *hname)
{
Octstr *s;
if ((s = http_header_value(headers, hname)) != NULL) {
struct tm xtm, ytm, *tm;
time_t t = time(NULL), t2;
char buf[64], *p, *q;
http_header_remove_all(headers, octstr_get_cstr(hname));
localtime_r(&t, &xtm); /* Initialise it. */
strptime(octstr_get_cstr(s), "%a, %d %b %Y %T %z", &xtm); /* Parse date value with time zone. */
t2 = gw_mktime(&xtm); /* Convert to unix time... */
tm = gmtime_r(&t2, &ytm); /* Then convert to GM time. */
if (!tm || asctime_r(tm, buf) == NULL) /* Then convert to ascii. If that fails...*/
ctime_r(&t, buf); /* .. just use current time. */
/* Strip leading and trailing blanks. */
for (p = buf; *p && p < buf + sizeof buf; p++)
if (!isspace(*p))
break;
q = p + (strlen(p) - 1);
while (isspace(*q) && q > p)
*q-- = 0;
http_header_add(headers, octstr_get_cstr(hname), p);
octstr_destroy(s);
}
}
MmsMsg *mms_frommime(MIMEEntity *mime)
{
MmsMsg *m;
Octstr *s;
MIMEEntity *mx;
int i, n;
List *h;
if (!mime)
return NULL;
m = gw_malloc(sizeof *m);
memset(m, 0, sizeof *m);
mx = mime_entity_duplicate(mime);
unconvert_mime_msg(mx); /* Fix-up content type issues. */
unpack_mimeheaders(mx);
unbase64_mimeparts(mx);
m->headers = mime_entity_headers(mx);
if ((n = mime_entity_num_parts(mx)) > 0) {
m->ismultipart = 1;
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 = mime_entity_body(mx);
}
mime_entity_destroy(mx); /* Because all its bits are used above. XXX not very clean! */
/* Now check for important headers. If missing, put them in - MsgId fixup - Vince */
s = http_header_value(m->headers, octstr_imm("Message-ID"));
if (s) {
octstr_replace(s, octstr_imm("<"), octstr_imm(""));
octstr_replace(s, octstr_imm(">"), octstr_imm(""));
if (octstr_get_char(s, 0) == '"') {
octstr_delete(s, 0, 1);
octstr_delete(s, octstr_len(s)-1, 1);
}
http_header_remove_all(m->headers, "Message-ID");
http_header_add(m->headers, "Message-ID", octstr_get_cstr(s));
m->msgId = octstr_duplicate(s);
octstr_destroy(s);
}
/* Default type is send */
if ((s = http_header_value(m->headers, octstr_imm("X-Mms-Message-Type"))) == NULL ||
octstr_compare(s, octstr_imm("MM4_forward.REQ")) == 0) {
http_header_remove_all(m->headers, "X-Mms-Message-Type");
http_header_add(m->headers, "X-Mms-Message-Type",
(char *)mms_message_type_to_cstr(MMS_MSGTYPE_SEND_REQ));
m->message_type = MMS_MSGTYPE_SEND_REQ;
if (s)
octstr_destroy(s);
} else {
m->message_type = mms_string_to_message_type(s);
if (m->message_type < 0) {
error(0, "Unknown message type: %s while parsing mime entity.", octstr_get_cstr(s));
octstr_destroy(s);
goto failed;
}
octstr_destroy(s);
}
if ((s = http_header_value(m->headers, octstr_imm("X-Mms-MMS-Version"))) == NULL)
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
else
octstr_destroy(s);
/* Fix-up date strings: Put it in GMT format, since it might not be. */
fixup_date(m->headers, octstr_imm("Date"));
fixup_date(m->headers, octstr_imm("X-Mms-Expiry"));
fixup_date(m->headers, octstr_imm("X-Mms-Delivery-Time"));
fixup_date(m->headers, octstr_imm("X-Mms-Previously-Sent-Date"));
fixup_date(m->headers, octstr_imm("X-Mms-Reply-Charging-Deadline"));
/* rebuild headers, skipping bad ones. */
h = http_create_empty_headers();
for (i = 0; i<gwlist_len(m->headers); i++) {
Octstr *name = NULL, *value = NULL;
http_header_get(m->headers, i, &name, &value);
if (mms_is_token(name)) /* if header name is bad, kill this header field. */
http_header_add(h, octstr_get_cstr(name), octstr_get_cstr(value));
octstr_destroy(name);
octstr_destroy(value);
}
http_destroy_headers(m->headers);
m->headers = h;
/* XXXX Probably ought to handle some more headers here:
* Return-Receipt-To becomes Read request is yes
* Disposition-Notification-To: becomes X-Mms-Delivery-Report = Yes
*/
/* XXXX Also need to validate this message a bit better. */
fixup_msg(m, octstr_imm("anon@unknown"));
return m;
failed:
mms_destroy(m);
return NULL;
}
void mms_destroy(MmsMsg *msg)
{
if (!msg)
return;
if (msg->ismultipart)
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);
if (msg->msgId)
octstr_destroy(msg->msgId);
gw_free(msg);
}
List *mms_message_headers(MmsMsg *msg)
{
gw_assert(msg);
return http_header_duplicate(msg->headers);
}
MmsMsg *mms_readreport(Octstr *msgid, Octstr *from, Octstr *to, time_t date, Octstr *status)
{
MmsMsg *m;
Octstr *s;
m = gw_malloc(sizeof *m);
m->ismultipart = 0;
m->headers = http_create_empty_headers();
m->message_type = MMS_MSGTYPE_READ_ORIG_IND;
m->body.s = NULL;
m->msgId = octstr_duplicate(msgid ? msgid : octstr_imm("none"));
/* Now append headers. */
http_header_add(m->headers, "X-Mms-Message-Type", "m-read-orig-ind");
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
http_header_add(m->headers, "Message-ID", msgid ? octstr_get_cstr(msgid) : "none");
http_header_add(m->headers, "To", octstr_get_cstr(to));
http_header_add(m->headers, "From", octstr_get_cstr(from));
s = date_format_http(date);
http_header_add(m->headers, "Date", octstr_get_cstr(s));
http_header_add(m->headers, "X-Mms-Status", octstr_get_cstr(status));
octstr_destroy(s);
return m;
}
MmsMsg *mms_deliveryreport(Octstr *msgid, Octstr *to, time_t date, Octstr *status)
{
MmsMsg *m = gw_malloc(sizeof *m);
Octstr *s;
m->ismultipart = 0;
m->headers = http_create_empty_headers();
m->message_type = MMS_MSGTYPE_DELIVERY_IND;
m->body.s = NULL;
m->msgId = octstr_duplicate(msgid ? msgid : octstr_imm("none"));
/* Now append headers. */
http_header_add(m->headers, "X-Mms-Message-Type", "m-delivery-ind");
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
http_header_add(m->headers, "Message-ID", msgid ? octstr_get_cstr(msgid) : "none");
http_header_add(m->headers, "To", octstr_get_cstr(to));
s = date_format_http(date);
http_header_add(m->headers, "Date", octstr_get_cstr(s));
http_header_add(m->headers, "X-Mms-Status", octstr_get_cstr(status));
octstr_destroy(s);
return m;
}
MmsMsg *mms_notification(MmsMsg *msg, unsigned int msize, Octstr *url,
Octstr *transactionid, time_t expiryt, int optimizesize)
{
MmsMsg *m = gw_malloc(sizeof *m);
char buf[10];
time_t tnow = time(NULL);
m->ismultipart = 0;
m->msgId = NULL;
m->body.s = NULL;
m->headers = http_create_empty_headers();
m->message_type = MMS_MSGTYPE_NOTIFICATION_IND;
http_header_add(m->headers, "X-Mms-Message-Type", "m-notification-ind");
http_header_add(m->headers, "X-Mms-Transaction-ID",
octstr_get_cstr(transactionid));
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
#define HX(h,d) do {\
Octstr *s = http_header_value(msg->headers, octstr_imm(#h)); \
if (s) { \
http_header_add(m->headers, #h, octstr_get_cstr(s)); \
octstr_destroy(s); \
} else if (d) \
http_header_add(m->headers, #h, d); \
} while(0)
if (!optimizesize) {
HX(From,NULL);
HX(Subject,NULL);
}
HX(X-Mms-Message-Class, "Personal");
#undef HX
sprintf(buf, "%d", msize);
http_header_add(m->headers, "X-Mms-Message-Size", buf);
#define LARGET 365*24*3600
sprintf(buf, "%ld", expiryt ? expiryt - tnow : LARGET);
http_header_add(m->headers, "X-Mms-Expiry", buf);
/* No reply charge stuff for now. */
http_header_add(m->headers, "X-Mms-Content-Location", octstr_get_cstr(url));
return m;
}
MmsMsg *mms_retrieveconf(MmsMsg *msg, Octstr *transactionid,
char *err, char *errtxt, Octstr *opt_from,
int menc)
{
MmsMsg *m;
m = gw_malloc(sizeof *m);
m->msgId = msg ? octstr_duplicate(msg->msgId) : octstr_imm("00000");
m->headers = http_create_empty_headers();
m->message_type = MMS_MSGTYPE_RETRIEVE_CONF;
http_header_add(m->headers, "X-Mms-Message-Type", "m-retrieve-conf");
if (transactionid)
http_header_add(m->headers, "X-Mms-Transaction-ID",
octstr_get_cstr(transactionid));
if (menc >= MS_1_2)
http_header_add(m->headers, "X-Mms-MMS-Version", "1.2");
else
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
if (!msg) {
Octstr *x = date_format_http(time(NULL));
m->ismultipart = 0;
http_header_add(m->headers, "Date", octstr_get_cstr(x));
http_header_add(m->headers, "X-Mms-Retrieve-Status",err);
if (err)
http_header_add(m->headers, "X-Mms-Retrieve-Text",err);
if (opt_from)
http_header_add(m->headers, "From", octstr_get_cstr(opt_from));
http_header_add(m->headers, "Content-Type", "text/plain");
if (errtxt)
m->body.s = octstr_create(errtxt);
else
m->body.s = octstr_create(" ");
octstr_destroy(x);
} else { /* Otherwise copy from message. */
List *h = mms_message_headers(msg);
int i, n;
#if 0 /* Some phones do not like this header! */
http_header_add(m->headers, "X-Mms-Retrieve-Status", "Ok");
#endif
http_header_combine(h, m->headers);
http_destroy_headers(m->headers);
m->headers = h;
m->ismultipart = msg->ismultipart;
if (!m->ismultipart)
m->body.s = octstr_duplicate(msg->body.s);
else
/* Body is a list of MIMEEntities, so recreate it. */
for (m->body.l = gwlist_create(), i = 0,
n = gwlist_len(msg->body.l);
i<n; 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");
mms_remove_headers(m, "X-Mms-Sender-Visibility");
}
return m;
}
int mms_remove_headers(MmsMsg *m, char *name)
{
gw_assert(m);
http_header_remove_all(m->headers, name);
return 0;
}
MmsMsg *mms_sendconf(char *errstr, char *msgid, char *transid, int isforward, int menc)
{
MmsMsg *m = gw_malloc(sizeof *m);
m->ismultipart = 0;
m->msgId = msgid ? octstr_create(msgid) : NULL;
m->body.s = NULL;
m->headers = http_create_empty_headers();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -