📄 mms_uaprof.c
字号:
/* If the first image is multi but the second isn't, then add selector. */
if (cformats[iindex].multi_image &&
!cformats[oindex].multi_image)
selector = "-[0]";
else
selector = "-";
/* We have an unsupported image now. time to convert it. */
if (icmd) {
cmd = octstr_format("%S | " IMGCONVERTCMD,
icmd, cformats[iindex].file_ext, selector,
cformats[oindex].file_ext, tmpf);
octstr_destroy(icmd);
} else
cmd = octstr_format("cat %s | " IMGCONVERTCMD,
tmpf2, cformats[iindex].file_ext, selector,
cformats[oindex].file_ext, tmpf);
send_data = 0;
} else {/* Type is audio. */
cmd = octstr_format("%s | %s > %s",
cformats[iindex].tostandard_cmd,
cformats[oindex].fromstandard_cmd, tmpf);
send_data = 1;
}
pf = popen(octstr_get_cstr(cmd), "w");
if (!pf)
goto done;
if (send_data) { /* If this is not set then write the content... */
Octstr *sx = mime_entity_body(msg);
n = octstr_print(pf, sx);
octstr_destroy(sx);
} else
n = 0;
m = pclose(pf);
if (n < 0 || m != 0)
goto done; /* Error -- finish up. */
if ((s = octstr_read_file(tmpf)) != NULL) {
replace_body(msg, s, params_h,
cformats[oindex].content_type,
cformats[oindex].file_ext,0);
supported = 1;
goto done2; /* we are done, don't even change headers. */
} else /* failed to convert, hence unsupported. */
goto done;
done:
if (h)
mime_replace_headers(msg,h);
done2:
if (!supported)
remove_object(msg, content_type);
if (h)
http_destroy_headers(h);
if (content_type)
octstr_destroy(content_type);
if (params)
octstr_destroy(params);
if (params_h)
http_destroy_headers(params_h);
if (tmpf[0])
unlink(tmpf);
if (tmpf2[0])
unlink(tmpf2);
if (cmd)
octstr_destroy(cmd);
return supported;
}
int mms_transform_msg(MmsMsg *inmsg, MmsUaProfile *prof, MmsMsg **outmsg)
{
MIMEEntity *m;
Octstr *s;
if (!prof)
return -1;
else if (!prof->ccppaccept.content)
return -2;
m = mms_tomime(inmsg,0);
modify_msg(m, prof);
*outmsg = mms_frommime(m);
mime_entity_destroy(m);
s = mms_tobinary(*outmsg);
if (octstr_len(s) > prof->maxmsgsize) {
mms_destroy(*outmsg);
*outmsg = NULL;
}
octstr_destroy(s);
/* Don't free profile! It is cached. */
return 0;
}
/* XXX Needs some work: Ensure we don't mod SMIL other than that specified in the start param.
* Also may be we should only mod the SMIL if content type of entity is multipart/related
* Also if the start param is missing we should perhaps stick it in.
*/
static int format_special(MIMEEntity *m,
int trans_smil, char *txtmsg, char *htmlmsg, int *counter)
{
int type;
Octstr *content_type = NULL, *params = NULL, *s;
int i, n;
unsigned long chash;
FILE *pf;
char tmpf[40];
Octstr *cmd = NULL;
List *params_h;
List *headers;
tmpf[0] = 0;
headers = mime_entity_headers(m);
get_content_type(headers, &content_type, ¶ms);
params_h = get_value_parameters(params);
if ((n = mime_entity_num_parts(m)) > 0) {
int presindex = -1;
Octstr *presbody;
Octstr *start = http_header_value(params_h, octstr_imm("start"));
for (i = 0; i<n; i++) {/* format sub-parts, find presentation part too */
MIMEEntity *x = mime_entity_get_part(m,i);
Octstr *ctype = NULL, *charset = NULL;
List *hx = mime_entity_headers(x);
Octstr *cid = _x_get_content_id(hx);
http_header_get_content_type(hx, &ctype, &charset);
/* Find presentation part: If we have start param, and it matches
* this one, and this one is SMIL, then...
*/
if (start && cid && octstr_compare(cid, start) == 0 &&
octstr_case_compare(ctype, octstr_imm(PRES_TYPE)) == 0)
presindex = i;
if (ctype) octstr_destroy(ctype);
if (charset) octstr_destroy(charset);
if (cid) octstr_destroy(cid);
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 (trans_smil && presindex >= 0) { /* Reformat. */
MIMEEntity *x, *pres;
Octstr *btxt = octstr_create("");
List *h = NULL, *h2 = NULL;
Octstr *tmp;
/* Remove type & start param from top level. */
http_header_remove_all(params_h, "type");
replace_ctype(headers, "multipart/related", params_h);
/* Put content ids on all siblings, and build html. */
for (i = 0, n = mime_entity_num_parts(m); i<n; i++) {
MIMEEntity *x = mime_entity_get_part(m,i);
List *hx = NULL;
Octstr *cid, *pname;
Octstr *ctype = NULL, *cparams = NULL;
Octstr *y, *loc, *cidurl;
List *cparamsl;
if (i == presindex) continue; /* Skip the presentation param. */
hx = mime_entity_headers(x);
cid = _x_get_content_id(hx);
if (cid == NULL) {
time_t t = time(NULL);
char ch[2];
ch[0] = ((t%2) ? 'A' : 'a') + (t%25); /* Make them a bit more unique. */
ch[1] = 0;
cid = octstr_format("<item-%s-%d-%d>", ch, *counter, (t%99989));
http_header_add(hx, "Content-ID", octstr_get_cstr(cid));
++*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);
loc = http_header_value(hx, octstr_imm("Content-Location"));
cidurl = octstr_duplicate(y);
octstr_url_encode(cidurl);
get_content_type(hx, &ctype, &cparams); /* Get type of object. */
if (cparams) { /* Get its name. */
if ((cparamsl = get_value_parameters(cparams)) != NULL) {
pname = http_header_value(cparamsl, octstr_imm("name"));
http_destroy_headers(cparamsl);
} else
pname = octstr_duplicate(loc ? loc : y);
octstr_destroy(cparams);
} else
pname = octstr_imm("unknown");
if (octstr_case_search(ctype, octstr_imm("image/"), 0) == 0)
octstr_format_append(btxt,
"\n<img src=\"cid:%S\" border=0 alt=\"%S\"><br><br>\n",
cidurl, pname ? pname : octstr_imm("image"));
else if (octstr_case_search(ctype, octstr_imm("text/"), 0) == 0) {
Octstr *s = mime_entity_body(x);
octstr_format_append(btxt, "%S<br><br>\n", s);
octstr_destroy(s);
}
#if 0
else if (octstr_case_search(ctype, octstr_imm("audio/"), 0) == 0)
octstr_format_append(btxt,
"<embed src=\"cid:%S\" >%S</embed><br><br>\n",
cidurl, ctype, pname);
#endif
else
octstr_format_append(btxt,
"<a type=\"%S\" href=\"cid:%S\">%S</a><br><br>\n",
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);
if (y) octstr_destroy(y);
if (loc) octstr_destroy(loc);
if (ctype) octstr_destroy(ctype);
if (cidurl) octstr_destroy(cidurl);
if (pname) octstr_destroy(pname);
octstr_destroy(cid);
}
pres = mime_entity_get_part(m,presindex);
presbody = mime_entity_body(pres);
h = mime_entity_headers(pres);
http_header_remove_all(h, "Content-Type");
http_header_add(h, "Content-Type", "multipart/alternative");
mime_replace_headers(pres,h);
http_destroy_headers(h);
/* first the text part ... */
x = mime_entity_create();
h2 = http_create_empty_headers();
http_header_add(h2, "Content-Type", "text/plain");
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... */
x = mime_entity_create();
h2 = http_create_empty_headers();
http_header_add(h2, "Content-Type", PRES_TYPE);
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. */
x = mime_entity_create();
h2 = http_create_empty_headers();
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);
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;
}
if (octstr_case_search(content_type, octstr_imm("image/"), 0) == 0)
type = TIMAGE;
else if (octstr_case_search(content_type, octstr_imm("audio/"), 0) == 0)
type = TAUDIO;
else if (octstr_case_search(content_type, octstr_imm("text/"), 0) == 0)
type = TTEXT;
else
type = TOTHER;
chash = hash_key(content_type);
if (type == TAUDIO) { /* Find the preferred format (audio only, leave images alone!),
* assuming we can support this one.
*/
int ipref = -1, iindex = -1, o;
for (i = 0; i < NELEMS(cformats); i++) {
if (ipref < 0 && cformats[i].t == type &&
cformats[i].fromstandard_cmd)
ipref = i;
if (cformats[i].chash == chash &&
octstr_case_compare(content_type,
octstr_imm(cformats[i].content_type)) == 0) {
if (cformats[i].tostandard_cmd)
iindex = i; /* Only if the cmd exists actually. */
break;
}
}
if (iindex < 0 || ipref < 0) /* Can't change it.... */
goto done;
mktmpfname(tmpf);
if (type == TAUDIO)
cmd = octstr_format("%s | %s > %s",
cformats[iindex].tostandard_cmd,
cformats[ipref].fromstandard_cmd, tmpf);
else
cmd = octstr_format(IMGCONVERTCMD,
cformats[iindex].file_ext, "-",
cformats[ipref].file_ext, tmpf);
pf = popen(octstr_get_cstr(cmd), "w");
if (!pf)
goto done;
s = mime_entity_body(m);
n = octstr_print(pf, s);
octstr_destroy(s);
o = pclose(pf);
if (n < 0 || o != 0)
goto done; /* Error -- finish up. */
if ((s = octstr_read_file(tmpf)) != NULL)
replace_body(m, s, params_h,
cformats[ipref].content_type,
cformats[ipref].file_ext,1);
else
goto done;
} else if (type == TTEXT) {/* change to default charset. */
Octstr *charset = http_header_value(params_h, octstr_imm("charset"));
Octstr *s;
if (charset == NULL ||
octstr_case_compare(charset, octstr_imm("unknown")) == 0 ||
octstr_case_compare(charset, octstr_imm(DEFAULT_CHARSET)) == 0) {
if (charset) octstr_destroy(charset);
goto done; /* Nothing more to do here. */
}
s = mime_entity_body(m);
if (charset_convert(s, octstr_get_cstr(charset),
DEFAULT_CHARSET) != -1) { /* using libiconv...*/
Octstr *tmp, *ct;
http_header_remove_all(params_h, "charset");
http_header_add(params_h, "charset", DEFAULT_CHARSET);
tmp = make_value_parameters(params_h);
ct = octstr_format("%S; %S", content_type, tmp);
octstr_destroy(tmp);
http_header_remove_all(headers, "Content-Type");
http_header_add(headers, "Content-Type", octstr_get_cstr(ct));
octstr_destroy(ct);
mime_entity_set_body(m, s);
} /* Else goto done. */
octstr_destroy(s);
} /* Else do nothing. */
done:
if (headers) {
mime_replace_headers(m, headers);
http_destroy_headers(headers);
}
if (content_type)
octstr_destroy(content_type);
if (params_h)
http_destroy_headers(params_h);
if (cmd)
octstr_destroy(cmd);
if (tmpf[0])
unlink(tmpf);
return 0;
}
int mms_format_special(MmsMsg *inmsg,
int trans_smil,
char *txtmsg,
char *htmlmsg, MIMEEntity **outmsg)
{
MIMEEntity *m = mms_tomime(inmsg,0);
int ct = 0;
if (!m)
return -1;
format_special(m, trans_smil, txtmsg, htmlmsg, &ct);
*outmsg = m;
return 0;
}
extern unsigned long mms_ua_maxmsgsize(MmsUaProfile *prof)
{
return prof ? prof->maxmsgsize : 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -