1
0
Fork 0

MM4 changes

This commit is contained in:
bagyenda 2007-03-20 16:43:44 +00:00
parent 2255fe303b
commit 7a0d166d21
11 changed files with 571 additions and 282 deletions

View File

@ -1,3 +1,5 @@
2007-03-20 P. A. Bagyenda <bagyenda@dsmagic.com>
* Major corrections to MM4 functionality, bringing conformance to 3GPP TS 23.140 (Thanks to Deon van der Merwe <deonvandermerwe@gmail.com> for funding)
2007-03-09 P. A. Bagyenda <bagyenda@dsmagic.com>
* Patch to fix panic in the event of missing/corrupt data file in queue (Thanks to Deon van der Merwe <deonvandermerwe@gmail.com>)
2007-01-31 Vincent Chavanis <vincent@telemaque.fr>

View File

@ -1880,12 +1880,27 @@ denied-prefix
recipient number prefixes that cannot be delivered via this proxy
</td>
</tr>
<tr>
<td valign=top >
<tt>confirmed-delivery</tt>
</td>
<td valign=top >
Boolean
</td>
<td valign=top >
Specifies whether to use request MM4 acknowledgement from the
recipient MMC for each message. Default is true.
</td>
</tr>
</table>
<p>
When an MM destined to an MSISDN cannot be delivered locally, the
gateway searches the list of Proxies to see if one of them can handle
the message. If one is found, the message is formatted as MIME and
the message. If one is found, the message is formatted as MM4 MIME
(according to 3GPP TS 23.140) and
sent via SMTP to the proxy.
</p>

View File

@ -91,6 +91,7 @@ MULTI_GROUP(mmsproxy,
OCTSTR(host)
OCTSTR(allowed-prefix)
OCTSTR(denied-prefix)
OCTSTR(confirmed-delivery)
)
MULTI_GROUP(mms-vasp,

View File

@ -16,9 +16,10 @@
#define MM7_SOAP_OK 1000
#define MM7_SOAP_FORMAT_CORRUPT 2007
#define MM7_SOAP_COMMAND_REJECTED 3005
#define MM7_SOAP_UNSUPPORTED_OPERATION 4003
#define MM7_SOAP_STATUS_OK(e) ((e) / 1000 == 1)
#define MM7_DEFAULT_VERSION "5.3.0"
#define MM7_DEFAULT_VERSION MMS_3GPP_VERSION
typedef struct MSoapMsg_t MSoapMsg_t;

View File

@ -1007,6 +1007,7 @@ static int encode_msgheaders(Octstr *os, List *hdrs)
static int fixup_msg(MmsMsg *m, Octstr *from)
{
Octstr *ver;
Octstr *s = NULL;
if (!m)
return -1;
@ -1018,10 +1019,11 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
} 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;
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));
@ -1036,7 +1038,7 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
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)
@ -1059,9 +1061,16 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
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;
}
strip_boundary_element(m->headers, NULL); /* remove top-level boundary element if any. */
return 0;
}
@ -1212,13 +1221,13 @@ int mms_messagetype(MmsMsg *msg)
static void convert_mime_msg(MIMEEntity *m)
{
int i, n;
Octstr *content_type, *params;
Octstr *content_type = NULL, *params;
char *s = NULL;
List *h = mime_entity_headers(m);
get_content_type(h, &content_type, &params);
n = get_content_type(h, &content_type, &params);
if (content_type) {
if (n == 0 && content_type) {
if (octstr_str_compare(content_type,
"application/vnd.wap.multipart.related") == 0)
s = "multipart/related";
@ -1267,9 +1276,9 @@ static void unconvert_mime_msg(MIMEEntity *m)
char *s = NULL;
List *h = mime_entity_headers(m);
get_content_type(h, &content_type, &params);
n = get_content_type(h, &content_type, &params);
if (content_type) {
if (n == 0 && content_type) {
if (octstr_case_compare(content_type,
octstr_imm("multipart/related")) == 0)
s = "application/vnd.wap.multipart.related";

View File

@ -177,9 +177,9 @@ Octstr *mms_isodate(time_t t)
void mms_lib_init(void)
{
srandom(time(NULL)); /* Seed random number generator. */
gwlib_init();
mms_strings_init();
}
void mms_lib_shutdown(void)
@ -470,6 +470,7 @@ static void addmmscname(Octstr *s, Octstr *myhostname)
}
static int send2email(Octstr *to, Octstr *from, Octstr *subject,
Octstr *msgid,
MIMEEntity *m, int append_hostname, Octstr **error,
@ -477,21 +478,61 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
{
Octstr *s;
FILE *f;
int ret = MMS_SEND_OK, i;
int ret = MMS_SEND_OK, i, n;
Octstr *cmd = octstr_create("");
List *headers = mime_entity_headers(m); /* we don't want the mime version header removed. */
if (append_hostname) { /* Add our hostname to all phone numbers. */
List *l = http_create_empty_headers();
Octstr *xfrom = http_header_value(headers, octstr_imm("From"));
List *lto = http_header_find_all(headers, "To");
List *lcc = http_header_find_all(headers, "Cc");
if (xfrom) {
addmmscname(xfrom, myhostname);
http_header_add(l, "From", octstr_get_cstr(xfrom));
octstr_destroy(xfrom);
}
http_header_remove_all(headers, "From");
for (i = 0, n = gwlist_len(lto); i < n; i++) {
Octstr *name, *value;
http_header_get(lto, i, &name, &value);
if (!value || !name ||
octstr_case_compare(name, octstr_imm("To")) != 0)
goto loop;
addmmscname(value, myhostname);
http_header_add(l, "To", octstr_get_cstr(value));
loop:
if (value) octstr_destroy(value);
if (name) octstr_destroy(name);
}
http_destroy_headers(lto);
http_header_remove_all(headers, "To");
for (i = 0, n = gwlist_len(lcc); i < n; i++) {
Octstr *name, *value;
http_header_get(lcc, i, &name, &value);
if (!value || !name ||
octstr_case_compare(name, octstr_imm("Cc")) != 0)
goto loop2;
addmmscname(value, myhostname);
http_header_add(l, "Cc", octstr_get_cstr(value));
loop2:
if (value) octstr_destroy(value);
if (name) octstr_destroy(name);
}
http_destroy_headers(lcc);
http_header_remove_all(headers, "Cc");
http_append_headers(headers, l); /* combine old with new. */
http_destroy_headers(l);
}
@ -589,7 +630,7 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
ret, strerror(errno));
ret = MMS_SEND_ERROR_TRANSIENT;
} else
ret = MMS_SEND_OK;
ret = MMS_SEND_QUEUED;
done:
http_destroy_headers(headers);
@ -599,20 +640,33 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
}
int mm_send_to_email(Octstr *to, Octstr *from, Octstr *subject,
Octstr *msgid,
MIMEEntity *m, int append_hostname, Octstr **error,
char *sendmail_cmd, Octstr *myhostname)
{
return send2email(to,from,subject,msgid,m,append_hostname,error,sendmail_cmd,myhostname);
}
/* Send this message to email recipient. */
int mms_sendtoemail(Octstr *from, Octstr *to,
Octstr *subject, Octstr *msgid,
MmsMsg *msg, int dlr, Octstr **error, char *sendmail_cmd,
MmsMsg *msg, int dlr,
Octstr **error, char *sendmail_cmd,
Octstr *myhostname,
int trans_msg,
int trans_smil, char *txt, char *html,
int append_hostname)
int mm4,
char *transid)
{
MIMEEntity *m = NULL;
List *headers = NULL;
List *newhdrs = http_create_empty_headers();
int ret;
int ret = 0, mtype;
gw_assert(msg);
mtype = mms_messagetype(msg);
if (!to ||
octstr_search_char(to, '@', 0) < 0) {
@ -622,40 +676,68 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
if (!trans_msg)
m = mms_tomime(msg,0);
else
if ((ret = mms_format_special(msg, trans_smil, txt, html, &m)) < 0 ||
else if ((ret = mms_format_special(msg, trans_smil, txt, html, &m)) < 0 ||
m == NULL) {
warning(0, "MMS: send2email failed to format message (msg=%s,ret=%d)",
m ? "OK" : "Not transformed",ret);
warning(0, "MMS: send2email failed to format message (msg=%s,ret=%d)",
m ? "OK" : "Not transformed",ret);
return -ret;
}
}
base64_mimeparts(m); /* make sure parts are base64 formatted. */
headers = mime_entity_headers(m);
/* Before we send it, we insert some email friendly headers if they are missing. */
http_header_add(newhdrs, "Subject", subject ? octstr_get_cstr(subject) : "MMS Message");
http_header_remove_all(headers, "From");
http_header_add(newhdrs, "From", octstr_get_cstr(from));
http_header_remove_all(headers, "To");
http_header_add(newhdrs, "To", octstr_get_cstr(to));
http_header_add(newhdrs, "Message-ID", msgid ? octstr_get_cstr(msgid) : "");
if (!mm4) {
http_header_add(newhdrs, "Subject", subject ? octstr_get_cstr(subject) : "MMS Message");
http_header_remove_all(headers, "From");
http_header_add(newhdrs, "From", octstr_get_cstr(from));
http_header_remove_all(headers, "To");
http_header_add(newhdrs, "To", octstr_get_cstr(to));
http_header_add(newhdrs, "Message-ID", msgid ? octstr_get_cstr(msgid) : "");
http_header_add(newhdrs, "MIME-Version", "1.0");
} else {
char *x;
Octstr *xsender = octstr_format("system-user@%S", myhostname);
http_header_add(newhdrs, "X-Mms-Message-ID", msgid ? octstr_get_cstr(msgid) : "");
http_header_add(newhdrs, "X-Mms-3GPP-MMS-Version", MMS_3GPP_VERSION);
http_header_add(newhdrs, "X-Mms-Originator-System",
octstr_get_cstr(xsender));
http_header_remove_all(headers, "X-Mms-Message-Type");
if (mtype == MMS_MSGTYPE_SEND_REQ ||
mtype == MMS_MSGTYPE_RETRIEVE_CONF)
x = "MM4_forward.REQ";
else if (mtype == MMS_MSGTYPE_DELIVERY_IND)
x = "MM4_delivery_report.REQ";
else if (mtype == MMS_MSGTYPE_READ_REC_IND)
x = "MM4_read_reply_report.REQ";
else {
*error = octstr_format("Invalid message type %s on MM4 outgoing interface!",
mms_message_type_to_cstr(mtype));
x = "";
ret = MMS_SEND_ERROR_FATAL;
goto done;
}
http_header_add(newhdrs, "X-Mms-Message-Type", x);
/* Add a few more MM4 headers. */
http_header_add(newhdrs, "X-Mms-Ack-Request", dlr ? "Yes" : "No");
http_header_add(newhdrs, "Sender", octstr_get_cstr(from));
http_header_add(newhdrs, "X-Mms-Transaction-ID", transid);
http_header_add(newhdrs, "X-Mms-Message-ID", msgid ? octstr_get_cstr(msgid) : "");
http_header_add(newhdrs, "MIME-Version", "1.0");
http_header_add(newhdrs, "X-Mms-3GPP-MMS-Version", "5.5.0");
http_header_add(newhdrs, "X-Mms-Originator-System", myhostname ? octstr_get_cstr(myhostname) : "none");
http_header_remove_all(headers, "X-Mms-Message-Type");
http_header_add(newhdrs, "X-Mms-Message-Type", "MM4_forward.REQ");
octstr_destroy(xsender);
}
http_header_combine(headers, newhdrs);
mime_replace_headers(m, headers);
done:
http_destroy_headers(headers);
http_destroy_headers(newhdrs);
ret = send2email(to, from, subject, msgid, m, append_hostname, error, sendmail_cmd, myhostname);
if (ret == 0)
ret = send2email(to,
from, subject, msgid, m, mm4 == 0, error, sendmail_cmd, myhostname);
mime_entity_destroy(m);
return ret;
@ -1062,9 +1144,15 @@ void strip_boundary_element(List *headers, char *s)
{
Octstr *ctype = NULL, *params = NULL;
Octstr *value;
int n;
gw_assert(headers);
get_content_type(headers, &ctype, &params);
if ((n = get_content_type(headers, &ctype, &params)) < 0) {
if (ctype)
octstr_destroy(ctype);
ctype = NULL; /* no ctype found, so do not replace it! */
}
if (s) {/* we are replacing the content type as well as stripping */
if (ctype)
@ -1072,7 +1160,7 @@ void strip_boundary_element(List *headers, char *s)
ctype = octstr_create(s);
}
if (params) {
if (params && ctype) {
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. */
@ -1085,10 +1173,12 @@ void strip_boundary_element(List *headers, char *s)
http_destroy_headers(h);
} else
value = ctype;
http_header_remove_all(headers, "Content-Type");
http_header_add(headers, "Content-Type", octstr_get_cstr(value));
if (ctype != value)
if (value) {
http_header_remove_all(headers, "Content-Type");
http_header_add(headers, "Content-Type", octstr_get_cstr(value));
}
if (ctype != value && ctype != NULL)
octstr_destroy(ctype);
octstr_destroy(value);
if (value)
octstr_destroy(value);
}

View File

@ -23,12 +23,18 @@
#include "mms_cfg.h"
#include "mms_mmbox.h"
/* supported 3GPP MMS version */
#define MMS_3GPP_VERSION "5.5.0"
/* Send errors */
#define MMS_SEND_OK 0
#define MMS_SEND_QUEUED 1
#define MMS_SEND_ERROR_TRANSIENT -1
#define MMS_SEND_ERROR_FATAL -2
#define SEND_ERROR_STR(e) ((e) == MMS_SEND_OK ? "Sent" : (e) == MMS_SEND_ERROR_TRANSIENT ? "Retry later" : "Failed")
#define SEND_ERROR_STR(e) ((e) == MMS_SEND_OK ? "Sent" : \
(e) == MMS_SEND_ERROR_TRANSIENT ? "Retry later" : \
((e) == MMS_SEND_QUEUED ? "Queued" : "Failed"))
/* Useful headers. */
#define XMSISDN_HEADER "X-WAP-Network-Client-MSISDN"
#define XIP_HEADER "X-WAP-Network-Client-IP"
@ -88,7 +94,14 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
MmsMsg *msg, int dlr, Octstr **error,
char *sendmail_cmd, Octstr *myhostname,
int trans_msg,
int trans_smil, char *txt, char *html, int append_hostname);
int trans_smil, char *txt, char *html, int mm4,
char *transid);
/* Send directly to email. */
int mm_send_to_email(Octstr *to, Octstr *from, Octstr *subject,
Octstr *msgid,
MIMEEntity *m, int append_hostname, Octstr **error,
char *sendmail_cmd, Octstr *myhostname);
/* log to access log. */
void mms_log(char *logmsg, Octstr *from, List *to,

View File

@ -92,15 +92,17 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
mms_load_core_settings(cgrp);
m->hostname = _mms_cfg_getx(grp, octstr_imm("hostname"));
if (proxyrelays)
*proxyrelays = mms_proxy_relays(cfg);
*proxyrelays = mms_proxy_relays(cfg, m->hostname);
if (mms_cfg_get_int(grp, octstr_imm("max-send-threads"), &m->maxthreads) == -1)
m->maxthreads = 10;
m->unified_prefix = _mms_cfg_getx(grp, octstr_imm("unified-prefix"));
m->local_prefix = _mms_cfg_getx(grp, octstr_imm("local-prefixes"));
m->hostname = _mms_cfg_getx(grp, octstr_imm("hostname"));
if (m->hostname == NULL || octstr_len(m->hostname) == 0)
m->hostname = octstr_create("localhost");
@ -122,8 +124,6 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
m->global_queuedir = octstr_format("%S/global", qdir);
m->mm1_queuedir = octstr_format("%S/mm1", qdir);
m->mm4_queuedir = octstr_format("%S/mm4", qdir);
if (mms_init_queuedir(m->mm1_queuedir) < 0)
panic(0, "Failed to initialise local queue directory: %s - %s!",
@ -131,9 +131,6 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
else if (mms_init_queuedir(m->global_queuedir) < 0)
panic(0, "Failed to initialise global queue directory: %s - %s!",
octstr_get_cstr(m->global_queuedir), strerror(errno));
else if (mms_init_queuedir(m->mm4_queuedir) < 0)
panic(0, "Failed to initialise global queue directory: %s - %s!",
octstr_get_cstr(m->mm4_queuedir), strerror(errno));
m->mmbox_rootdir = octstr_format("%S/mmbox", qdir);
@ -336,7 +333,7 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
return m;
}
List *mms_proxy_relays(mCfg *cfg)
List *mms_proxy_relays(mCfg *cfg, Octstr *myhostname)
{
List *gl = mms_cfg_get_multi(cfg, octstr_imm("mmsproxy"));
int i, n;
@ -349,8 +346,13 @@ List *mms_proxy_relays(mCfg *cfg)
m->host = _mms_cfg_getx(grp, octstr_imm("host"));
m->name = _mms_cfg_getx(grp, octstr_imm("name"));
m->allowed_prefix = _mms_cfg_getx(grp, octstr_imm("allowed-prefix"));
m->denied_prefix = _mms_cfg_getx(grp, octstr_imm("denied-prefix"));
m->denied_prefix = _mms_cfg_getx(grp, octstr_imm("denied-prefix"));
if (mms_cfg_get_bool(grp, octstr_imm("confirmed-delivery"), &m->confirmed_mm4) < 0)
m->confirmed_mm4 = 1;
if (octstr_compare(m->host, myhostname) == 0)
warning(0, "MMSC Config: Found MM4 Proxy %s with same hostname as local host!",
octstr_get_cstr(m->name));
gwlist_append(l, m);
}

View File

@ -22,6 +22,7 @@ typedef struct MmsProxyRelay {
Octstr *name;
Octstr *allowed_prefix;
Octstr *denied_prefix;
int confirmed_mm4;
} MmsProxyRelay;
typedef struct MmsVasp {
@ -37,7 +38,7 @@ typedef struct MmscSettings {
Octstr *name, *hostname, *host_alias;
Octstr *unified_prefix, *local_prefix;
Octstr *sendmail;
Octstr *global_queuedir, *mm1_queuedir, *mm4_queuedir;
Octstr *global_queuedir, *mm1_queuedir;
Octstr *mmbox_rootdir;
Octstr *ua_profile_cache_dir;
@ -100,7 +101,7 @@ typedef struct MmscSettings {
MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays);
/* Returns list of MmsProxyRelay */
extern List *mms_proxy_relays(mCfg *cfg);
extern List *mms_proxy_relays(mCfg *cfg, Octstr *myhostname);
extern Octstr *mms_makefetchurl(char *qf, Octstr *token, int loc,
Octstr *to,

View File

@ -22,12 +22,31 @@ static Octstr *xto;
static Octstr *xproxy;
enum {TPLMN, TEMAIL, TOTHER} ttype;
/* MM4 message types. */
enum {MM4_FORWARD_REQ = 0, MM4_FORWARD_RES, MM4_READ_REPLY_REPORT_REQ,
MM4_READ_REPLY_REPORT_RES, MM4_DELIVERY_REPORT_REQ, MM4_DELIVERY_REPORT_RES};
static struct {
char *mm4str;
int mm1_type;
} mm4_types[] = {
{"MM4_forward.REQ", MMS_MSGTYPE_SEND_REQ},
{"MM4_forward.RES",-1},
{"MM4_read_reply_report.REQ", MMS_MSGTYPE_READ_REC_IND},
{"MM4_read_reply_report.RES",-1},
{"MM4_delivery_report.REQ",MMS_MSGTYPE_DELIVERY_IND},
{"MM4_delivery_report.RES",-1},
{NULL}
};
/* above indexed by types! */
static int find_own(int i, int argc, char *argv[]);
static void fixup_recipient(void);
static void fixup_sender(void);
static void send_mm4_res(int mtype, Octstr *to, Octstr *sender, Octstr *transid, char *status, Octstr *msgid);
static mCfg *cfg;
static List *proxyrelays;
int main(int argc, char *argv[])
@ -38,14 +57,17 @@ int main(int argc, char *argv[])
MIMEEntity *mm;
MmsMsg *msg;
Octstr *email;
Octstr *email, *me, *rstatus;
Octstr *home_mmsc = NULL;
List *headers;
Octstr *mm4_type = NULL, *transid, *ack, *msgid, *orig_sys;
Octstr *newmsgid = NULL;
int mtype = -1, mm1_type = -1;
char *err = NULL;
mms_lib_init();
srandom(time(NULL));
cfidx = get_and_set_debugs(argc, argv, find_own);
if (argv[cfidx] == NULL)
@ -71,8 +93,10 @@ int main(int argc, char *argv[])
if (!settings)
panic(0, "No global MMSC configuration!");
if (!xto || !xfrom)
panic(0, "usage: %s -f from -t to!", argv[0]);
if (!xto || !xfrom) {
error(0, "usage: %s -f from -t to!", argv[0]);
return -1;
}
/* normalize recipient address, then if phone number,
* check whether we are allowed to process.
@ -120,33 +144,93 @@ int main(int argc, char *argv[])
http_header_remove_all(headers, "Received");
http_header_remove_all(headers, "X-MimeOLE");
http_header_remove_all(headers, "X-Mailer");
/* Look for MM4 headers... */
mm4_type = http_header_value(headers, octstr_imm("X-Mms-Message-Type"));
ack = http_header_value(headers, octstr_imm("X-Mms-Ack-Request"));
rstatus = http_header_value(headers, octstr_imm("X-Mms-Request-Status-Code"));
if ((transid = http_header_value(headers, octstr_imm("X-Mms-Transaction-ID"))) == NULL)
transid = octstr_create("001");
/* get originator system. */
if ((orig_sys = http_header_value(headers, octstr_imm("X-Mms-Originator-System"))) == NULL)
orig_sys = http_header_value(headers, octstr_imm("Sender"));
if (xproxy == NULL && orig_sys != NULL) { /* Copy proxy address from originator system. */
int i = octstr_search_char(orig_sys, '@', 0);
if (i >= 0)
xproxy = octstr_copy(orig_sys, i+1, octstr_len(orig_sys));
}
if ((msgid = http_header_value(headers, octstr_imm("X-Mms-Message-ID"))) == NULL)
msgid = http_header_value(headers, octstr_imm("Message-ID"));
if (msgid)
octstr_strip_nonalphanums(msgid);
if (transid)
octstr_strip_nonalphanums(transid);
/* ... and remove non-essential ones */
http_header_remove_all(headers, "X-Mms-3GPP-MMS-Version");
http_header_remove_all(headers, "MIME-Version");
http_header_remove_all(headers, "X-Mms-Message-ID");
http_header_remove_all(headers, "Message-ID");
http_header_remove_all(headers, "X-Mms-Ack-Request");
http_header_remove_all(headers, "X-Mms-Originator-System");
http_header_remove_all(headers, "Sender");
/* msgid was there, put it back in proper form. */
if (msgid)
http_header_add(headers, "Message-ID", octstr_get_cstr(msgid));
if (mm4_type) {
unsigned char *x = NULL;
int i;
http_header_remove_all(headers, "X-Mms-Message-Type");
for (i = 0; mm4_types[i].mm4str; i++)
if (octstr_str_case_compare(mm4_type, mm4_types[i].mm4str) == 0) {
mtype = i;
mm1_type = mm4_types[i].mm1_type;
x = mms_message_type_to_cstr(mm1_type);
break;
}
if (x)
http_header_add(headers, "X-Mms-Message-Type", (char *)x);
if (orig_sys == NULL) /* Make it up! */
orig_sys = octstr_format("system-user@%S", xproxy ? xproxy : octstr_imm("unknown"));
} else { /* else assume a normal send message. */
http_header_add(headers, "X-Mms-Message-Type", "m-send-req");
mm1_type = MMS_MSGTYPE_SEND_REQ;
mtype = MM4_FORWARD_REQ;
}
mime_replace_headers(mm, headers);
http_destroy_headers(headers);
/* Now convert from mime to MMS message. */
msg = mms_frommime(mm);
mime_entity_destroy(mm);
/* Now convert from mime to MMS message, if we should */
if (mm1_type >= 0) {
if ((msg = mms_frommime(mm)) == NULL) {
error(0, "Unable to create MM!");
mms_lib_shutdown();
return -1;
}
} else
msg = NULL;
mime_entity_destroy(mm);
me = octstr_format("system-user@%S", settings->hostname);
if (!msg) {
error(0, "Unable to create MM!");
mms_lib_shutdown();
return -1;
}
switch(mms_messagetype(msg)) {
case MMS_MSGTYPE_SEND_REQ:
if (ttype != TPLMN)
switch(mtype) {
case MM4_FORWARD_REQ:
if (ttype != TPLMN) {
err = "Error-service-denied";
error(0, "Not allowed to send to non-phone recipient, to=%s!", octstr_get_cstr(xto));
else {
} else {
List *lto = gwlist_create();
Octstr *qf;
Octstr *msgid = mms_get_header_value(msg, octstr_imm("Message-ID"));
Octstr *transid = mms_get_header_value(msg, octstr_imm("X-Mms-Transaction-ID"));
Octstr *dreport = mms_get_header_value(msg,
octstr_imm("X-Mms-Delivery-Report"));
char *err;
Octstr *rto;
Octstr *dreport = mms_get_header_value(msg, octstr_imm("X-Mms-Delivery-Report"));
int dlr;
octstr_format_append(xto, "/TYPE=PLMN");
@ -167,8 +251,10 @@ int main(int argc, char *argv[])
octstr_get_cstr(settings->global_queuedir),
settings->host_alias);
if (qf) {
info(0, "Email2MMS Queued message to %s from %s (via %s) => %s",
newmsgid = mms_maketransid(octstr_get_cstr(qf),
settings->host_alias);
info(0, "%s Queued message to %s from %s (via %s) => %s",
mm4_type ? "MM4 Incoming" : "Email2MMS",
octstr_get_cstr(xto), octstr_get_cstr(xfrom),
xproxy ? octstr_get_cstr(xproxy) : "(None)", octstr_get_cstr(qf));
octstr_destroy(qf);
@ -176,156 +262,181 @@ int main(int argc, char *argv[])
/* Queue our response to the chap. */
err = "Ok";
} else
err = "Error-transient-failure";
if (xproxy) {
MmsMsg *mresp;
List *xlto;
mresp = mms_sendconf(err, octstr_get_cstr(msgid),
transid ? octstr_get_cstr(transid) : "001",
0,MS_1_1);
rto = octstr_format("system-user@%S", xproxy);
xlto = gwlist_create();
gwlist_append(xlto, rto);
qf = mms_queue_add(settings->system_user, xlto, NULL,
xproxy, NULL,
0, time(NULL) + settings->default_msgexpiry,
mresp, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(settings->global_queuedir),
settings->host_alias);
gwlist_destroy(xlto, (gwlist_item_destructor_t *)octstr_destroy);
mms_destroy(mresp);
octstr_destroy(qf);
}
err = "Error-network-problem";
mms_log("Received", xfrom, lto,
-1, msgid, NULL, xproxy, xproxy ? "MM4" : "MM3", NULL,NULL);
-1, msgid, NULL, xproxy, mm4_type ? "MM4" : "MM3", NULL,NULL);
gwlist_destroy(lto,NULL);
octstr_destroy(transid);
octstr_destroy(msgid);
if (dreport)
octstr_destroy(dreport);
}
break;
case MMS_MSGTYPE_SEND_CONF:
case MM4_DELIVERY_REPORT_REQ:
if (ttype != TPLMN) { /* We only send to phones from this interface */
error(0, "Not allowed to send to %s!", octstr_get_cstr(xto));
err = "Error-service-denied";
} else {
List *lto = gwlist_create();
Octstr *qf;
octstr_format_append(xto, "/TYPE=PLMN");
gwlist_append(lto, xto);
qf = mms_queue_add(xfrom, lto, NULL,
xproxy, NULL,
0, time(NULL) + settings->default_msgexpiry, msg, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(settings->global_queuedir),
settings->host_alias);
gwlist_destroy(lto, NULL);
if (qf) {
info(0, "MM4 Queued DLR from proxy %s to %s from %s => %s",
octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom),
octstr_get_cstr(qf));
octstr_destroy(qf);
err = "Ok";
} else
err = "Error-network-problem";
newmsgid = msgid ? octstr_duplicate(msgid) : NULL; /* report old msg id */
}
break;
case MM4_READ_REPLY_REPORT_REQ:
if (ttype != TPLMN) { /* We only send to phones from this interface */
error(0, "Not allowed to send to %s!", octstr_get_cstr(xto));
err = "Error-service-denied";
} else {
List *lto = gwlist_create();
Octstr *qf;
octstr_format_append(xto, "/TYPE=PLMN");
gwlist_append(lto, xto);
qf = mms_queue_add(xfrom, lto, NULL,
xproxy, NULL,
0, time(NULL) + settings->default_msgexpiry, msg, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(settings->global_queuedir),
settings->host_alias);
gwlist_destroy(lto, NULL);
if (qf) {
info(0, "MM4 Queued read report from proxy %s to %s from %s => %s",
octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom),
octstr_get_cstr(qf));
octstr_destroy(qf);
err = "Ok";
} else
err = "Error-network-problem";
}
case MM4_FORWARD_RES:
case MM4_READ_REPLY_REPORT_RES:
case MM4_DELIVERY_REPORT_RES: /* remove corresponding queue entry. */
{
Octstr *transid = mms_get_header_value(msg, octstr_imm("X-Mms-Transaction-ID"));
Octstr *qf = mms_getqf_fromtransid(transid);
Octstr *qf, *o_to;
int i;
octstr_destroy(transid);
/* Pull the number out of the fake transaction ID */
if ((i = octstr_search_char(transid, '-',0)) > 0) {
o_to = octstr_copy(transid, 0, i);
octstr_delete(transid, 0, i+1);
} else
o_to = NULL;
qf = mms_getqf_fromtransid(transid);
if (qf) {
MmsEnvelope *e = mms_queue_readenvelope(octstr_get_cstr(qf),
octstr_get_cstr(settings->mm4_queuedir),
octstr_get_cstr(settings->global_queuedir),
1);
if (!e)
warning(0, "Received confirm MMS but cannot find message %s [%s] in queue!",
warning(0, "MM4 Received %s from %s but cannot load queue entry %s [%s] in queue!",
mm4_types[mtype].mm4str,
octstr_get_cstr(xproxy),
octstr_get_cstr(transid),
octstr_get_cstr(qf));
else {
MmsEnvelopeTo *t;
int i, n;
for (i = 0, n = gwlist_len(e->to); i<n; i++)
if ((t = gwlist_get(e->to, i)) != NULL)
if ((t = gwlist_get(e->to, i)) != NULL &&
(o_to == NULL || octstr_case_compare(o_to, t->rcpt) == 0))
t->process = 0; /* Should make it go away. */
/* write CDR if it is a forward confirmation */
if (mtype == MM4_FORWARD_RES &&
rstatus && octstr_str_case_compare(rstatus, "Ok") == 0) {
MmsCdrStruct _cdr, *cdr = &_cdr;
cdr->module_data = settings->mms_bill_module_data;
cdr->sdate = e->created;
strncpy(cdr->from, octstr_get_cstr(e->from), sizeof cdr->from);
strncpy(cdr->to, o_to ? octstr_get_cstr(o_to) : "", sizeof cdr->to);
strncpy(cdr->msgid, e->msgId ? octstr_get_cstr(e->msgId) : "", sizeof cdr->msgid);
strncpy(cdr->vaspid, e->vaspid ? octstr_get_cstr(e->vaspid) : "", sizeof cdr->vaspid);
cdr->msg_size = e->msize;
settings->mms_billfuncs->mms_logcdr(cdr);
}
mms_queue_update(e);
info(0, "Email2MMS received send conf from proxy %s to %s from %s => %s",
octstr_get_cstr(xproxy), octstr_get_cstr(xto),
info(0, "MM4 received %s from proxy %s to %s from %s => %s, status: %s",
mm4_types[mtype].mm4str,
octstr_get_cstr(xproxy), o_to ? octstr_get_cstr(o_to) : octstr_get_cstr(xto),
octstr_get_cstr(xfrom),
octstr_get_cstr(qf));
octstr_get_cstr(qf),
rstatus ? octstr_get_cstr(rstatus) : "");
}
} else
warning(0, "Received confirm MMS but cannot find message %s in queue!",
warning(0, "Received %s but cannot find message %s in queue!",
mm4_types[mtype].mm4str,
octstr_get_cstr(transid));
if (o_to)
octstr_destroy(o_to);
}
break;
case MMS_MSGTYPE_DELIVERY_IND:
if (ttype != TPLMN) /* We only send to phones from this interface */
error(0, "Not allowed to send to %s!", octstr_get_cstr(xto));
else {
List *lto = gwlist_create();
Octstr *qf;
octstr_format_append(xto, "/TYPE=PLMN");
gwlist_append(lto, xto);
qf = mms_queue_add(xfrom, lto, NULL,
xproxy, NULL,
0, time(NULL) + settings->default_msgexpiry, msg, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(settings->global_queuedir),
settings->host_alias);
gwlist_destroy(lto, NULL);
if (qf) {
info(0, "Email2MMS Queued DLR from proxy %s to %s from %s => %s",
octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom),
octstr_get_cstr(qf));
octstr_destroy(qf);
}
gwlist_destroy(lto, NULL);
}
break;
case MMS_MSGTYPE_READ_REC_IND:
mms_convert_readrec2readorig(msg);
/* Fall through. */
case MMS_MSGTYPE_READ_ORIG_IND:
if (ttype != TPLMN) /* We only send to phones from this interface */
error(0, "Not allowed to send to %s!", octstr_get_cstr(xto));
else {
List *lto = gwlist_create();
Octstr *qf;
octstr_format_append(xto, "/TYPE=PLMN");
gwlist_append(lto, xto);
qf = mms_queue_add(xfrom, lto, NULL,
xproxy, NULL,
0, time(NULL) + settings->default_msgexpiry, msg, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(settings->global_queuedir),
settings->host_alias);
gwlist_destroy(lto, NULL);
if (qf) {
info(0, "Email2MMS Queued read report from proxy %s to %s from %s => %s",
octstr_get_cstr(xproxy), octstr_get_cstr(xto), octstr_get_cstr(xfrom),
octstr_get_cstr(qf));
octstr_destroy(qf);
}
gwlist_destroy(lto, NULL);
}
break;
default:
{
int x = mms_messagetype(msg);
warning(0, "Unexpected message type: %d=>%s",
x,
mms_message_type_to_cstr(x));
warning(0, "Unexpected message type: %s",
mm4_type ? octstr_get_cstr(mm4_type) : "not given!");
break;
}
}
/* respond to the sender as necessary. */
if (mm4_type &&
err &&
ack && octstr_str_case_compare(ack, "Yes") == 0)
send_mm4_res(mtype+1, orig_sys, me, transid, err, newmsgid);
if (mm4_type)
octstr_destroy(mm4_type);
if (transid)
octstr_destroy(transid);
if (orig_sys)
octstr_destroy(orig_sys);
if (msgid)
octstr_destroy(msgid);
if (newmsgid)
octstr_destroy(newmsgid);
if (rstatus)
octstr_destroy(rstatus);
if (xto)
octstr_destroy(xto);
if (xfrom)
octstr_destroy(xfrom);
if (xproxy)
octstr_destroy(xproxy);
octstr_destroy(me);
mms_destroy(msg);
mms_lib_shutdown();
@ -365,11 +476,12 @@ static void fixup_recipient(void)
Octstr *typ = NULL;
if (!xto) xto = octstr_imm("");
i = octstr_search_char(xto, '@', 0);
if (!xto) return;
i = octstr_search_char(xto, '@', 0); /* Remove '@' */
if (i>0)
octstr_delete(xto, i, octstr_len(xto));
i = octstr_search(xto, octstr_imm("/TYPE="), 0);
if (i > 0) {
typ = octstr_copy(xto, i+1, octstr_len(xto));
@ -383,25 +495,60 @@ static void fixup_recipient(void)
} else { /* For now everything else is email. */
ttype = TEMAIL;
}
octstr_destroy(typ);
if (typ)
octstr_destroy(typ);
}
static void fixup_sender(void)
{
int i;
if (!xfrom) xfrom = octstr_imm("");
i = octstr_search_char(xfrom, '@', 0);
if (i>0)
return;
/* Find the TYPE=xxx element. If it is there, it is a number. Strip the @ */
if (!xfrom) return;
i = octstr_search(xfrom, octstr_imm("/TYPE="), 0);
if (i > 0)
return;
if (isphonenum(xfrom))
octstr_append(xfrom, octstr_imm("/TYPE=PLMN"));
else
octstr_append(xfrom, octstr_imm("@unknown"));
if (i>0) {
int j = octstr_search_char(xfrom, '@', 0);
if (j > i) { /* we have @, remove it */
if (xproxy == NULL)
xproxy = octstr_copy(xfrom, j+1, octstr_len(xfrom));
octstr_delete(xfrom, j, octstr_len(xfrom));
}
} else if (isphonenum(xfrom)) /* Add the TYPE element if missing. */
octstr_append(xfrom, octstr_imm("/TYPE=PLMN"));
else {
i = octstr_search_char(xfrom, '@', 0);
if (i<0)
octstr_format_append(xfrom, "@unknown");
else if (xproxy == NULL)
xproxy = octstr_copy(xfrom, i+1, octstr_len(xfrom));
}
}
static void send_mm4_res(int mtype, Octstr *to, Octstr *sender, Octstr *transid, char *status, Octstr *msgid)
{
List *h = http_create_empty_headers();
MIMEEntity *m = mime_entity_create();
Octstr *err = NULL;
/* Make headers */
http_header_add(h, "X-Mms-3GPP-MMS-Version", MMS_3GPP_VERSION);
http_header_add(h, "X-Mms-Transaction-ID", octstr_get_cstr(transid));
http_header_add(h, "X-Mms-Message-Type", mm4_types[mtype].mm4str);
if (msgid)
http_header_add(h, "X-Mms-Message-ID", octstr_get_cstr(msgid));
http_header_add(h, "X-Mms-Request-Status-Code", status);
http_header_add(h, "Sender", octstr_get_cstr(sender));
http_header_add(h, "To", octstr_get_cstr(to));
mime_replace_headers(m, h);
http_destroy_headers(h);
mm_send_to_email(to, sender, octstr_imm(""), msgid, m, 0, &err, octstr_get_cstr(settings->sendmail),
settings->hostname);
if (err) {
warning(0, "MM4 send.RES reported: %s!", octstr_get_cstr(err));
octstr_destroy(err);
}
mime_entity_destroy(m);
}

View File

@ -15,15 +15,12 @@
#define NMAX 256
static char mobile_qdir[NMAX];
static char mm4_qdir[NMAX];
static char sendmail_cmd[NMAX];
/* Set the queue directory for messages going to mobile. */
static int mms_setmobile_queuedir(char *mqdir);
/* Set the queue directory for messages going to remote proxies. */
static int mms_setmm4_queuedir(char *mqdir);
/* Send command for sending mail. It will be called as <sendmail> <to> with
* headers and message on stdin.
@ -47,7 +44,9 @@ static int mms_sendtomobile(Octstr *from, Octstr *to,
*/
static int mms_sendtoproxy(Octstr *from, Octstr *to,
Octstr *subject, Octstr *proxy,
Octstr *msgid, time_t expires, MmsMsg *m, int dlr, Octstr **error);
char *transid,
Octstr *msgid, time_t expires, MmsMsg *msg,
int dlr, Octstr **error);
static int mms_sendtovasp(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
MmsMsg *m, Octstr **error);
@ -147,26 +146,34 @@ static int sendMsg(MmsEnvelope *e)
*/
if (octstr_search_char(to->rcpt, '@', 0) > 0) {
Octstr *pfrom;
if (octstr_search_char(e->from, '@', 0) < 0)
pfrom = octstr_format("%S@%S", e->from, settings->hostname);
else
pfrom = e->from;
if (settings->mms2email)
res = mms_sendtovasp(settings->mms2email,
e->from, to->rcpt,
e->msgId,
msg, &err);
else
res = mms_sendtoemail(e->from, to->rcpt,
res = mms_sendtoemail(pfrom, to->rcpt,
e->subject ? e->subject : settings->mms_email_subject,
e->msgId, msg, e->dlr, &err, sendmail_cmd,
e->msgId, msg, 0, &err, sendmail_cmd,
settings->hostname, 1, 1,
octstr_get_cstr(settings->mms_email_txt),
octstr_get_cstr(settings->mms_email_html), 1);
octstr_get_cstr(settings->mms_email_html), 0, e->xqfname);
if (res == MMS_SEND_QUEUED)
res = MMS_SEND_OK; /* queued to email treated same as sent.
* XXX - this means DLR requests for emailed messages not supported!
*/
if (res == MMS_SEND_OK)
mms_log2("Sent", e->from, to->rcpt,
-1, e->msgId, NULL, NULL, "MM3", NULL,NULL);
} else if (e->viaproxy && octstr_len(e->viaproxy) > 0)
res = mms_sendtoproxy(e->from,
to->rcpt, e->subject, e->viaproxy,
e->msgId, e->expiryt, msg, e->dlr, &err);
else {
if (pfrom != e->from)
octstr_destroy(pfrom);
} else {
int j = octstr_case_search(to->rcpt, octstr_imm("/TYPE=PLMN"), 0);
int k = octstr_case_search(to->rcpt, octstr_imm("/TYPE=IPv"), 0);
int len = octstr_len(to->rcpt);
@ -227,7 +234,7 @@ static int sendMsg(MmsEnvelope *e)
settings, proxyrelays))) {
info(0, "mmsc for \"%s\" resolved to: \"%s\"",
octstr_get_cstr(phonenum), octstr_get_cstr(mmsc));
/* If resolved to my hostname, then this is local. */
if (octstr_compare(mmsc, settings->hostname) == 0) {
if (settings->mms2mobile &&
e->msgtype == MMS_MSGTYPE_SEND_REQ) { /* Send a copy to this VASP. */
@ -251,16 +258,20 @@ static int sendMsg(MmsEnvelope *e)
e->msgId, e->expiryt, msg, e->dlr,
&err);
sent = 1;
} else if (proxyrelays && gwlist_len(proxyrelays) > 0) /* Step through proxies. */
} else if (proxyrelays && gwlist_len(proxyrelays) > 0)
/* else, step through proxies, look for one that matches. */
for (j = 0, m = gwlist_len(proxyrelays); j<m; j++) {
MmsProxyRelay *mp = gwlist_get(proxyrelays, j);
if (!octstr_compare(mp->host, mmsc)) {
Octstr *xtransid = mms_maketransid(e->xqfname, settings->host_alias);
res = mms_sendtoproxy(e->from, to->rcpt,
e->subject, mp->host,
e->subject, mp->host,
octstr_get_cstr(xtransid),
e->msgId, e->expiryt, msg,
e->dlr, &err);
mp->confirmed_mm4, &err);
sent = 1;
octstr_destroy(xtransid);
break;
}
}
@ -282,11 +293,16 @@ static int sendMsg(MmsEnvelope *e)
if (e->dlr) {
Octstr *qfs;
MmsMsg *m = mms_deliveryreport(e->msgId, to->rcpt, tnow,
(e->expiryt != 0 && e->expiryt < tnow) ?
octstr_imm("Expired") : octstr_imm("Rejected"));
char *mstatus;
if (res == MMS_SEND_QUEUED)
mstatus = "Forwarded";
else if (e->expiryt != 0 && e->expiryt < tnow)
mstatus = "Expired";
else
mstatus = "Rejected";
MmsMsg *m = mms_deliveryreport(e->msgId, to->rcpt, tnow, octstr_imm(mstatus));
List *l = gwlist_create();
gwlist_append(l, octstr_duplicate(e->from));
@ -369,7 +385,6 @@ void mbuni_global_queue_runner(int *rstop)
{
mms_setmobile_queuedir(octstr_get_cstr(settings->mm1_queuedir));
mms_setmm4_queuedir(octstr_get_cstr(settings->mm4_queuedir));
mms_setsendmail_cmd(octstr_get_cstr(settings->sendmail));
@ -398,11 +413,6 @@ static int mms_setmobile_queuedir(char *mqdir)
return 0;
}
static int mms_setmm4_queuedir(char *mqdir)
{
strncpy(mm4_qdir, mqdir, sizeof mm4_qdir);
return 0;
}
static int mms_setsendmail_cmd(char *sendmail)
{
@ -460,52 +470,50 @@ int mms_sendtomobile(Octstr *from, Octstr *to,
* so we can handle delivery receipts and such.
*/
static int mms_sendtoproxy(Octstr *from, Octstr *to,
Octstr *subject, Octstr *proxy,
Octstr *msgid, time_t expires, MmsMsg *msg, int dlr, Octstr **error)
Octstr *subject, Octstr *proxy,
char *transid,
Octstr *msgid, time_t expires, MmsMsg *msg,
int dlr, Octstr **error)
{
Octstr *pto;
Octstr *pto, *pfrom;
int x = MMS_SEND_ERROR_FATAL;
Octstr *xtransid; /* We make a fake transaction ID that includes 'to' field. */
if (!to ||
octstr_search_char(to, '@', 0) >= 0) {
*error = octstr_format("Bad recipient address sent to MM4 interface, addresss is %S!", to);
return MMS_SEND_ERROR_FATAL;
}
if (msg &&
mms_messagetype(msg) == MMS_MSGTYPE_SEND_REQ) { /* Only queue these ones for future response. */
List *l = gwlist_create();
Octstr *ret;
gwlist_append(l, to);
ret = mms_queue_add(from, l, subject, NULL, proxy, 0, expires, msg,NULL,
NULL, NULL,
NULL, NULL,
NULL,
dlr, mm4_qdir,
settings->host_alias);
gwlist_destroy(l, NULL);
if (ret == NULL) {
*error = octstr_format("MM4: Failed to queue message to %S for future tracking. ", to);
return MMS_SEND_ERROR_TRANSIENT;
}
octstr_destroy(ret);
}
if (msg) {
pto = octstr_format("%S@%S", to, proxy);
x = mms_sendtoemail(from, pto,
subject ? subject : settings->mms_email_subject,
msgid, msg, 0,
error, sendmail_cmd,
settings->hostname, 0, 0,NULL,NULL,0);
mms_log2("Sent", from, pto,
-1, msgid, NULL, proxy, "MM4", NULL,NULL);
octstr_destroy(pto);
} else
if (!msg) {
*error = octstr_format("GlobalSend: Failed to send to %S, Message format is corrupt!", to);
return MMS_SEND_ERROR_FATAL;
}
pto = octstr_format("%S@%S", to, proxy);
if (octstr_search_char(from, '@', 0) < 0)
pfrom = octstr_format("%S@%S", from, settings->hostname);
else
pfrom = from;
xtransid = octstr_format("%S-%s", to,transid);
x = mms_sendtoemail(from, pto,
subject ? subject : settings->mms_email_subject,
msgid, msg, dlr,
error, sendmail_cmd,
settings->hostname, 0, 0,NULL,NULL,1, octstr_get_cstr(xtransid));
octstr_destroy(xtransid);
if (x == MMS_SEND_QUEUED && !dlr) /* No confirmed sending, and message was queued successfully... */
x = MMS_SEND_OK; /* we assume fully sent! */
if (x >= 0) /* no error. */
mms_log2(x == MMS_SEND_OK ? "Sent" : "Queued", from, pto,
-1, msgid, NULL, proxy, "MM4", NULL,NULL);
octstr_destroy(pto);
if (pfrom != from)
octstr_destroy(pfrom);
return x;
}