diff --git a/mbuni/ChangeLog b/mbuni/ChangeLog index 52aaf86..bfdeeff 100644 --- a/mbuni/ChangeLog +++ b/mbuni/ChangeLog @@ -1,4 +1,6 @@ -2009-01-04 P. A. Bagyenda +2010-01-25 P. A. Bagyenda + * SunOS locking fixes (thanks to Ian Donaldson (iand at ekit-inc.com) +2010-01-04 P. A. Bagyenda * Minor fix, throttling in MMSC VASP connections 2009-12-01 P. A. Bagyenda * Change queue location for MM1 notifications diff --git a/mbuni/configure.ac b/mbuni/configure.ac index 4f1dd7d..4f64efe 100644 --- a/mbuni/configure.ac +++ b/mbuni/configure.ac @@ -71,7 +71,7 @@ dnl Change a few things (a la kannel config) EXE_EXT="" LIB_EXT="a" case "$host" in - *-sun-solaris* | *SunOS*) + *-sun-solaris* | *SunOS* | *-pc-solaris*) CFLAGS="$CFLAGS -DSunOS=1 -D_POSIX_PTHREAD_SEMANTICS" ;; *-cygwin*) diff --git a/mbuni/mmlib/mms_mmbox.c b/mbuni/mmlib/mms_mmbox.c index b630e04..563e971 100644 --- a/mbuni/mmlib/mms_mmbox.c +++ b/mbuni/mmlib/mms_mmbox.c @@ -178,7 +178,7 @@ static int mkdf(char df[64], char *mmbox_home) if (fd >= 0 && mm_lockfile(fd,ctmp,1) != 0) { unlink(ctmp); - close(fd); + unlock_and_close(fd); fd = -1; } octstr_destroy(tmp); @@ -202,7 +202,7 @@ static int open_mmbox_index(char *mmbox_dir, int shouldblock) fbuf, strerror(errno)); break; } else if (mm_lockfile(fd, fbuf, shouldblock) != 0) { - close(fd); + unlock_and_close(fd); fd = -1; } while (i++ < MAXTRIES && fd < 0); @@ -272,7 +272,7 @@ static int update_mmbox_index(int fd, char *mmbox_dir, int cmd, mms_error(0, "mmbox", NULL,"Failed lock temp file %s: error = %s\n", fbuf, strerror(errno)); - close(tempfd); + unlock_and_close(tempfd); tempfd = -1; goto done; @@ -284,7 +284,7 @@ static int update_mmbox_index(int fd, char *mmbox_dir, int cmd, fbuf, strerror(errno)); - close(tempfd); + unlock_and_close(tempfd); tempfd = -1; goto done; } @@ -434,18 +434,14 @@ Octstr *mms_mmbox_addmsg(char *mmbox_root, char *user, MmsMsg *msg, List *flag_c octstr_replace(sdf, octstr_imm("/"), octstr_imm("-")); done: if (dfd > 0) - close(dfd); + unlock_and_close(dfd); if (ifd > 0) - close(ifd); + unlock_and_close(ifd); - if (s) - octstr_destroy(s); - if (home) - octstr_destroy(home); - if (state) - octstr_destroy(state); - if (flags) - gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy); + octstr_destroy(s); + octstr_destroy(home); + octstr_destroy(state); + gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy); return sdf; } diff --git a/mbuni/mmlib/mms_queue.c b/mbuni/mmlib/mms_queue.c index 1c00238..bb22696 100644 --- a/mbuni/mmlib/mms_queue.c +++ b/mbuni/mmlib/mms_queue.c @@ -21,8 +21,8 @@ #include #ifdef SunOS #include -#include #endif +#include #include #include "mms_queue.h" @@ -208,7 +208,7 @@ static MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int sho octstr_destroy(fname); return NULL; } else if (mm_lockfile(fd, octstr_get_cstr(fname), shouldblock) != 0) { - close(fd); + unlock_and_close(fd); octstr_destroy(fname); return NULL; } @@ -566,7 +566,7 @@ static int writeenvelope(MmsEnvelope *e, int newenv) close(fd); /* Close new one, keep old one. */ res = -1; } else { /* On success, new descriptor replaces old one and we close old one. */ - close(qfs->fd); + unlock_and_close(qfs->fd); qfs->fd = fd; } octstr_destroy(qfname); @@ -630,7 +630,7 @@ static int mkqf(char qf[QFNAMEMAX], char subdir[64], char *mms_queuedir) if (fd >= 0 && mm_lockfile(fd,ctmp,1) != 0) { unlink(ctmp); - close(fd); + unlock_and_close(fd); fd = -1; } octstr_destroy(tmp); @@ -804,7 +804,7 @@ static int free_envelope(MmsEnvelope *e, int removefromqueue) snprintf(fname, -1 + sizeof fname, "%s/%s%s", qfs->dir, qfs->subdir, qfs->name); unlink(fname); } - close(qfs->fd); /* close and unlock now that we have deleted it. */ + unlock_and_close(qfs->fd); /* close and unlock now that we have deleted it. */ mms_queue_free_envelope(e); diff --git a/mbuni/mmlib/mms_util.c b/mbuni/mmlib/mms_util.c index 2611811..de9c312 100644 --- a/mbuni/mmlib/mms_util.c +++ b/mbuni/mmlib/mms_util.c @@ -20,6 +20,8 @@ #ifdef SunOS #include +#include +#include #endif #include @@ -32,341 +34,341 @@ Octstr *_mms_cfg_getx(mCfg *cfg, mCfgGrp *grp, Octstr *item) { - Octstr *v = mms_cfg_get(cfg, grp, item); + Octstr *v = mms_cfg_get(cfg, grp, item); - void *x = v ? v : octstr_create(""); + void *x = v ? v : octstr_create(""); - return x; + return x; } int mms_load_core_settings(mCfg *cfg, mCfgGrp *cgrp) { - Octstr *log, *alog; - Octstr *http_proxy_host; - Octstr *our_interface; - long loglevel; + Octstr *log, *alog; + Octstr *http_proxy_host; + Octstr *our_interface; + long loglevel; - if (cgrp == NULL) - panic(0,"Missing required group `core' in config file!"); + if (cgrp == NULL) + panic(0,"Missing required group `core' in config file!"); - /* Set the log file. */ - log = mms_cfg_get(cfg, cgrp, octstr_imm("log-file")); - if (log != NULL) { - if (mms_cfg_get_int(cfg, cgrp, octstr_imm("log-level"), &loglevel) == -1) - loglevel = 0; - log_open(octstr_get_cstr(log), loglevel, GW_NON_EXCL); - octstr_destroy(log); - } + /* Set the log file. */ + log = mms_cfg_get(cfg, cgrp, octstr_imm("log-file")); + if (log != NULL) { + if (mms_cfg_get_int(cfg, cgrp, octstr_imm("log-level"), &loglevel) == -1) + loglevel = 0; + log_open(octstr_get_cstr(log), loglevel, GW_NON_EXCL); + octstr_destroy(log); + } - /* Get access log and open it. */ - alog = mms_cfg_get(cfg, cgrp, octstr_imm("access-log")); - if (alog) { - alog_open(octstr_get_cstr(alog), 1, 1); - octstr_destroy(alog); - } + /* Get access log and open it. */ + alog = mms_cfg_get(cfg, cgrp, octstr_imm("access-log")); + if (alog) { + alog_open(octstr_get_cstr(alog), 1, 1); + octstr_destroy(alog); + } - if ((our_interface = mms_cfg_get(cfg, cgrp, octstr_imm("http-interface-name"))) != NULL) { - http_set_interface(our_interface); - octstr_destroy(our_interface); - } + if ((our_interface = mms_cfg_get(cfg, cgrp, octstr_imm("http-interface-name"))) != NULL) { + http_set_interface(our_interface); + octstr_destroy(our_interface); + } - /* look for http proxy. If set, use it. */ - if ((http_proxy_host = mms_cfg_get(cfg, cgrp, octstr_imm("http-proxy-host"))) != NULL) { + /* look for http proxy. If set, use it. */ + if ((http_proxy_host = mms_cfg_get(cfg, cgrp, octstr_imm("http-proxy-host"))) != NULL) { - Octstr *username = mms_cfg_get(cfg, cgrp, - octstr_imm("http-proxy-username")); - Octstr *password = mms_cfg_get(cfg, cgrp, - octstr_imm("http-proxy-password")); - List *exceptions = mms_cfg_get_list(cfg, cgrp, - octstr_imm("http-proxy-exceptions")); - Octstr *except_regex = mms_cfg_get(cfg, cgrp, - octstr_imm("http-proxy-exceptions-regex")); - long http_proxy_port = -1; + Octstr *username = mms_cfg_get(cfg, cgrp, + octstr_imm("http-proxy-username")); + Octstr *password = mms_cfg_get(cfg, cgrp, + octstr_imm("http-proxy-password")); + List *exceptions = mms_cfg_get_list(cfg, cgrp, + octstr_imm("http-proxy-exceptions")); + Octstr *except_regex = mms_cfg_get(cfg, cgrp, + octstr_imm("http-proxy-exceptions-regex")); + long http_proxy_port = -1; - mms_cfg_get_int(cfg, cgrp, octstr_imm("http-proxy-port"), &http_proxy_port); + mms_cfg_get_int(cfg, cgrp, octstr_imm("http-proxy-port"), &http_proxy_port); - if (http_proxy_port > 0) - http_use_proxy(http_proxy_host, http_proxy_port, 0, - exceptions, username, password, except_regex); - octstr_destroy(http_proxy_host); - octstr_destroy(username); - octstr_destroy(password); - octstr_destroy(except_regex); - gwlist_destroy(exceptions, octstr_destroy_item); - } + if (http_proxy_port > 0) + http_use_proxy(http_proxy_host, http_proxy_port, 0, + exceptions, username, password, except_regex); + octstr_destroy(http_proxy_host); + octstr_destroy(username); + octstr_destroy(password); + octstr_destroy(except_regex); + gwlist_destroy(exceptions, octstr_destroy_item); + } #ifdef HAVE_LIBSSL - /* We expect that gwlib_init() has been called already, so only need - * to setup cert files. - * -- adapted from gwlib/conn.c - */ - { - Octstr *ssl_client_certkey_file = NULL; - Octstr *ssl_server_cert_file = NULL; - Octstr *ssl_server_key_file = NULL; - Octstr *ssl_trusted_ca_file = NULL; + /* We expect that gwlib_init() has been called already, so only need + * to setup cert files. + * -- adapted from gwlib/conn.c + */ + { + Octstr *ssl_client_certkey_file = NULL; + Octstr *ssl_server_cert_file = NULL; + Octstr *ssl_server_key_file = NULL; + Octstr *ssl_trusted_ca_file = NULL; - /* - * check if SSL is desired for HTTP servers and then - * load SSL client and SSL server public certificates - * and private keys - */ - ssl_client_certkey_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-client-certkey-file")); - if (ssl_client_certkey_file != NULL) - use_global_client_certkey_file(ssl_client_certkey_file); + /* + * check if SSL is desired for HTTP servers and then + * load SSL client and SSL server public certificates + * and private keys + */ + ssl_client_certkey_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-client-certkey-file")); + if (ssl_client_certkey_file != NULL) + use_global_client_certkey_file(ssl_client_certkey_file); - ssl_server_cert_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-server-cert-file")); - ssl_server_key_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-server-key-file")); + ssl_server_cert_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-server-cert-file")); + ssl_server_key_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-server-key-file")); - if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) - use_global_server_certkey_file(ssl_server_cert_file, - ssl_server_key_file); + if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) + use_global_server_certkey_file(ssl_server_cert_file, + ssl_server_key_file); - ssl_trusted_ca_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-trusted-ca-file")); + ssl_trusted_ca_file = mms_cfg_get(cfg, cgrp, octstr_imm("ssl-trusted-ca-file")); - use_global_trusted_ca_file(ssl_trusted_ca_file); + use_global_trusted_ca_file(ssl_trusted_ca_file); - octstr_destroy(ssl_client_certkey_file); - octstr_destroy(ssl_server_cert_file); - octstr_destroy(ssl_server_key_file); - octstr_destroy(ssl_trusted_ca_file); - } + octstr_destroy(ssl_client_certkey_file); + octstr_destroy(ssl_server_cert_file); + octstr_destroy(ssl_server_key_file); + octstr_destroy(ssl_trusted_ca_file); + } #endif - return 0; + return 0; } Octstr *mms_maketransid(char *qf, Octstr *mmscname) { - Octstr *res; - Octstr *x, *y = NULL; - static int ct; + Octstr *res; + Octstr *x, *y = NULL; + static int ct; - if (!qf) - x = octstr_format("msg.%ld.x%d.%d.%d", - (long)time(NULL) % 10000, (++ct % 1000), getpid()%100, random()%100); - else - x = octstr_create(qf); + if (!qf) + x = octstr_format("msg.%ld.x%d.%d.%d", + (long)time(NULL) % 10000, (++ct % 1000), getpid()%100, random()%100); + else + x = octstr_create(qf); - res = octstr_format("%S-%S", mmscname, x); + res = octstr_format("%S-%S", mmscname, x); - octstr_destroy(x); - octstr_destroy(y); + octstr_destroy(x); + octstr_destroy(y); - return res; + return res; } Octstr *mms_make_msgid(char *qf, Octstr *mmscname) {/* Message ID is a little differently done. */ - Octstr *res; - Octstr *x, *y = NULL; - static int ct; + Octstr *res; + Octstr *x, *y = NULL; + static int ct; - if (!qf) - x = octstr_format("msg.%ld.x%d.%d.%d", - (long)time(NULL) % 10000, (++ct % 1000), getpid()%100, random()%100); - else - x = octstr_create(qf); + if (!qf) + x = octstr_format("msg.%ld.x%d.%d.%d", + (long)time(NULL) % 10000, (++ct % 1000), getpid()%100, random()%100); + else + x = octstr_create(qf); - if (mmscname) - res = octstr_format("%S@%S", x,mmscname); - else - res = octstr_duplicate(x); + if (mmscname) + res = octstr_format("%S@%S", x,mmscname); + else + res = octstr_duplicate(x); - octstr_destroy(x); - octstr_destroy(y); + octstr_destroy(x); + octstr_destroy(y); - return res; + return res; } extern Octstr *mms_getqf_fromtransid(Octstr *transid) { - int i; + int i; - if (transid == NULL) - return NULL; - i = octstr_search_char(transid, '-', 0); - if (i < 0) - i = octstr_search_char(transid, '@', 0); /* XXX backward compartibility. */ + if (transid == NULL) + return NULL; + i = octstr_search_char(transid, '-', 0); + if (i < 0) + i = octstr_search_char(transid, '@', 0); /* XXX backward compartibility. */ - return (i >= 0) ? octstr_copy(transid, i+1, octstr_len(transid)) : octstr_duplicate(transid); + return (i >= 0) ? octstr_copy(transid, i+1, octstr_len(transid)) : octstr_duplicate(transid); } extern Octstr *mms_getqf_from_msgid(Octstr *msgid) { - int i; + int i; - if (msgid == NULL) - return NULL; - if ((i = octstr_search_char(msgid, '@', 0)) > 0) - return octstr_copy(msgid, 0, i); - else - return mms_getqf_fromtransid(msgid); /* For older ones where transid = msgid. */ + if (msgid == NULL) + return NULL; + if ((i = octstr_search_char(msgid, '@', 0)) > 0) + return octstr_copy(msgid, 0, i); + else + return mms_getqf_fromtransid(msgid); /* For older ones where transid = msgid. */ } Octstr *mms_isodate(time_t t) { - Octstr *current_time; - struct tm now; + Octstr *current_time; + struct tm now; - now = gw_gmtime(t); - current_time = octstr_format("%04d-%02d-%02dT%02d:%02d:%02dZ", - now.tm_year + 1900, now.tm_mon + 1, - now.tm_mday, now.tm_hour, now.tm_min, - now.tm_sec); + now = gw_gmtime(t); + current_time = octstr_format("%04d-%02d-%02dT%02d:%02d:%02dZ", + now.tm_year + 1900, now.tm_mon + 1, + now.tm_mday, now.tm_hour, now.tm_min, + now.tm_sec); - return current_time; + return current_time; } void mms_lib_init(void) { - srandom(time(NULL)); /* Seed random number generator. */ - gwlib_init(); - mms_strings_init(); + srandom(time(NULL)); /* Seed random number generator. */ + gwlib_init(); + mms_strings_init(); } void mms_lib_shutdown(void) { - mms_strings_shutdown(); - gwlib_shutdown(); + mms_strings_shutdown(); + gwlib_shutdown(); } static void strip_quotes(Octstr *s) { - int l = s ? octstr_len(s) : 0; + int l = s ? octstr_len(s) : 0; - if (l == 0) - return; - if (octstr_get_char(s, 0) == '"') { - octstr_delete(s, 0, 1); - l--; - } - if (octstr_get_char(s, l-1) == '"') - octstr_delete(s, l-1, 1); + if (l == 0) + return; + if (octstr_get_char(s, 0) == '"') { + octstr_delete(s, 0, 1); + l--; + } + if (octstr_get_char(s, l-1) == '"') + octstr_delete(s, l-1, 1); } List *get_value_parameters(Octstr *params) { - int i,n, k = 0; - List *h = http_create_empty_headers(); - Octstr *xparams = octstr_duplicate(params); + int i,n, k = 0; + List *h = http_create_empty_headers(); + Octstr *xparams = octstr_duplicate(params); - octstr_format_append(xparams, ";"); /* So parsing is easier. (aka cheap hack) */ + octstr_format_append(xparams, ";"); /* So parsing is easier. (aka cheap hack) */ - for (i = 0, n = octstr_len(xparams); i < n; i++) { - int c = octstr_get_char(xparams, i); + for (i = 0, n = octstr_len(xparams); i < n; i++) { + int c = octstr_get_char(xparams, i); - if (c == ';') { - int j = octstr_search_char(xparams, '=', k); - Octstr *name, *value; - if (j > 0 && j < i) { - name = octstr_copy(xparams, k, j - k); - value = octstr_copy(xparams, j+1,i-j-1); - octstr_strip_blanks(name); - octstr_strip_blanks(value); - strip_quotes(value); - if (octstr_len(name) > 0) - http_header_add(h, - octstr_get_cstr(name), - octstr_get_cstr(value)); - octstr_destroy(name); - octstr_destroy(value); - } - k = i + 1; - } else if (c == '"') - i += http_header_quoted_string_len(xparams, i) - 1; - } - octstr_destroy(xparams); - return h; + if (c == ';') { + int j = octstr_search_char(xparams, '=', k); + Octstr *name, *value; + if (j > 0 && j < i) { + name = octstr_copy(xparams, k, j - k); + value = octstr_copy(xparams, j+1,i-j-1); + octstr_strip_blanks(name); + octstr_strip_blanks(value); + strip_quotes(value); + if (octstr_len(name) > 0) + http_header_add(h, + octstr_get_cstr(name), + octstr_get_cstr(value)); + octstr_destroy(name); + octstr_destroy(value); + } + k = i + 1; + } else if (c == '"') + i += http_header_quoted_string_len(xparams, i) - 1; + } + octstr_destroy(xparams); + return h; } int split_header_value(Octstr *value, Octstr **base_value, Octstr **params) { - int i, n; - for (i = 0, n = octstr_len(value); i < n; i++) { - int c = octstr_get_char(value, i); + int i, n; + for (i = 0, n = octstr_len(value); i < n; i++) { + int c = octstr_get_char(value, i); - if (c == ';') - break; - else if (c == '"') - i += http_header_quoted_string_len(value, i) - 1; - } + if (c == ';') + break; + else if (c == '"') + i += http_header_quoted_string_len(value, i) - 1; + } - *base_value = octstr_duplicate(value); - if (i < n) { - *params = octstr_copy(value, i+1, octstr_len(value)); - octstr_delete(*base_value, i, octstr_len(*base_value)); - } else - *params = octstr_create(""); - return 0; + *base_value = octstr_duplicate(value); + if (i < n) { + *params = octstr_copy(value, i+1, octstr_len(value)); + octstr_delete(*base_value, i, octstr_len(*base_value)); + } else + *params = octstr_create(""); + return 0; } int get_content_type(List *hdrs, Octstr **type, Octstr **params) { - Octstr *v; + Octstr *v; - v = http_header_find_first(hdrs, "Content-Type"); - *params =NULL; + v = http_header_find_first(hdrs, "Content-Type"); + *params =NULL; - if (!v) { - *type = octstr_create("application/octet-stream"); - *params = octstr_create(""); - return -1; - } + if (!v) { + *type = octstr_create("application/octet-stream"); + *params = octstr_create(""); + return -1; + } - split_header_value(v, type, params); + split_header_value(v, type, params); - octstr_destroy(v); - return 0; + octstr_destroy(v); + return 0; } static int is_mime_special_char(int ch) { - const char *x = "=;<>[]?()@:\\/,"; - char *p; - for (p = (char *)x; *p; p++) - if (ch == *p) - return 1; - return 0; + const char *x = "=;<>[]?()@:\\/,"; + char *p; + for (p = (char *)x; *p; p++) + if (ch == *p) + return 1; + return 0; } static int needs_quotes(Octstr *s) { - int i, n; - if (!s) - return 0; + int i, n; + if (!s) + return 0; - for (i = 0, n = octstr_len(s); i= 0) /* Don't allow space in the name. */ - goto loop; + if (header == NULL || + octstr_str_compare(header, "X-Unknown") == 0 || + octstr_search_chars(header, octstr_imm(" \n\t"), 0) >= 0) /* Don't allow space in the name. */ + goto loop; - if (octstr_case_compare(header, octstr_imm("Cc")) == 0 || - octstr_case_compare(header, octstr_imm("To")) == 0 || - octstr_case_compare(header, octstr_imm("Bcc")) == 0) - skip = 0; - else - skip = 1; - /* XXX This may not be safe. Need to skip over quotes. */ - if (!skip && octstr_search_char(value, ',', 0) > 0 && - (l = http_header_split_value(value)) != NULL && - gwlist_len(l) > 1) - for (j = 0, m = gwlist_len(l); j 0 && + (l = http_header_split_value(value)) != NULL && + gwlist_len(l) > 1) + for (j = 0, m = gwlist_len(l); j 0) - for (i = 0; i 0) + for (i = 0; i 0) - for (i = 0; i 0) + for (i = 0; i= 0) - return; /* Nothing to do. */ + if (octstr_search_char(s, '@', 0) >= 0) + return; /* Nothing to do. */ - j = octstr_case_search(s, octstr_imm("/TYPE=PLMN"), 0); - if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len) /* A proper number. */ - octstr_format_append(s, "@%S", myhostname); + j = octstr_case_search(s, octstr_imm("/TYPE=PLMN"), 0); + if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len) /* A proper number. */ + octstr_format_append(s, "@%S", myhostname); } @@ -527,176 +529,176 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject, MIMEEntity *m, int append_hostname, Octstr **error, char *sendmail_cmd, Octstr *myhostname) { - Octstr *s; - FILE *f; - 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. */ + Octstr *s; + FILE *f; + 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 (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"); + 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; + for (i = 0, n = gwlist_len(lto); i < n; i++) { + Octstr *name, *value; - http_header_get(lto, i, &name, &value); + http_header_get(lto, i, &name, &value); - if (!value || !name || - octstr_case_compare(name, octstr_imm("To")) != 0) - goto loop; + 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: - octstr_destroy(value); - octstr_destroy(name); - } + addmmscname(value, myhostname); + http_header_add(l, "To", octstr_get_cstr(value)); + loop: + octstr_destroy(value); + octstr_destroy(name); + } - http_destroy_headers(lto); - http_header_remove_all(headers, "To"); + http_destroy_headers(lto); + http_header_remove_all(headers, "To"); - for (i = 0, n = gwlist_len(lcc); i < n; i++) { - Octstr *name, *value; + for (i = 0, n = gwlist_len(lcc); i < n; i++) { + Octstr *name, *value; - http_header_get(lcc, i, &name, &value); + http_header_get(lcc, i, &name, &value); - if (!value || !name || - octstr_case_compare(name, octstr_imm("Cc")) != 0) - goto loop2; + 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: - octstr_destroy(value); - octstr_destroy(name); - } + addmmscname(value, myhostname); + http_header_add(l, "Cc", octstr_get_cstr(value)); + loop2: + octstr_destroy(value); + octstr_destroy(name); + } - http_destroy_headers(lcc); - http_header_remove_all(headers, "Cc"); + http_destroy_headers(lcc); + http_header_remove_all(headers, "Cc"); - http_append_headers(headers, l); /* combine old with new. */ - http_destroy_headers(l); - } + http_append_headers(headers, l); /* combine old with new. */ + http_destroy_headers(l); + } - /* Pack headers, get string rep of mime entity. */ - http_header_pack(headers); - mime_replace_headers(m, headers); - s = mime_entity_to_octstr(m); + /* Pack headers, get string rep of mime entity. */ + http_header_pack(headers); + mime_replace_headers(m, headers); + s = mime_entity_to_octstr(m); - /* - * Make the command: Transpose % formatting characters: - * f - from address - * t - recipient - * s - subject - * m - message id - */ + /* + * Make the command: Transpose % formatting characters: + * f - from address + * t - recipient + * s - subject + * m - message id + */ - i = 0; - for (;;) { - Octstr *tmp; - while (sendmail_cmd[i]) { - char c = sendmail_cmd[i]; - if (c == '%' && sendmail_cmd[i + 1]) - break; - octstr_append_char(cmd, c); - i++; - } - if (!sendmail_cmd[i]) - break; + i = 0; + for (;;) { + Octstr *tmp; + while (sendmail_cmd[i]) { + char c = sendmail_cmd[i]; + if (c == '%' && sendmail_cmd[i + 1]) + break; + octstr_append_char(cmd, c); + i++; + } + if (!sendmail_cmd[i]) + break; - switch(sendmail_cmd[i+1]) { - case 't': - tmp = octstr_duplicate(to); - escape_shell_chars(tmp); - octstr_append(cmd, tmp); - octstr_destroy(tmp); - break; - case 'f': - if (append_hostname) { - Octstr *xfrom = octstr_duplicate(from); - addmmscname(xfrom, myhostname); - escape_shell_chars(xfrom); + switch(sendmail_cmd[i+1]) { + case 't': + tmp = octstr_duplicate(to); + escape_shell_chars(tmp); + octstr_append(cmd, tmp); + octstr_destroy(tmp); + break; + case 'f': + if (append_hostname) { + Octstr *xfrom = octstr_duplicate(from); + addmmscname(xfrom, myhostname); + escape_shell_chars(xfrom); - octstr_append(cmd, xfrom); - octstr_destroy(xfrom); - } else { - tmp = octstr_duplicate(from); - escape_shell_chars(tmp); - octstr_append(cmd, tmp); - octstr_destroy(tmp); - } - break; - case 's': - tmp = octstr_duplicate(subject); - escape_shell_chars(tmp); - octstr_append(cmd, subject); - octstr_destroy(tmp); - break; - case 'm': - tmp = octstr_duplicate(msgid); - escape_shell_chars(tmp); - octstr_append(cmd, msgid); - octstr_destroy(tmp); - break; - case '%': - octstr_format_append(cmd, "%%"); - break; - default: - octstr_format_append(cmd, "%%%c", sendmail_cmd[i+1]); - break; - } - i += 2; - } + octstr_append(cmd, xfrom); + octstr_destroy(xfrom); + } else { + tmp = octstr_duplicate(from); + escape_shell_chars(tmp); + octstr_append(cmd, tmp); + octstr_destroy(tmp); + } + break; + case 's': + tmp = octstr_duplicate(subject); + escape_shell_chars(tmp); + octstr_append(cmd, subject); + octstr_destroy(tmp); + break; + case 'm': + tmp = octstr_duplicate(msgid); + escape_shell_chars(tmp); + octstr_append(cmd, msgid); + octstr_destroy(tmp); + break; + case '%': + octstr_format_append(cmd, "%%"); + break; + default: + octstr_format_append(cmd, "%%%c", sendmail_cmd[i+1]); + break; + } + i += 2; + } - debug("mms.sendtoemail", 0, "preparing to execute %s to send to email: ", octstr_get_cstr(cmd)); + debug("mms.sendtoemail", 0, "preparing to execute %s to send to email: ", octstr_get_cstr(cmd)); - if ((f = popen(octstr_get_cstr(cmd), "w")) == NULL) { - *error = octstr_format("popen failed for %S: %d: %s", - cmd, errno, strerror(errno)); - ret = MMS_SEND_ERROR_TRANSIENT; - goto done; - } + if ((f = popen(octstr_get_cstr(cmd), "w")) == NULL) { + *error = octstr_format("popen failed for %S: %d: %s", + cmd, errno, strerror(errno)); + ret = MMS_SEND_ERROR_TRANSIENT; + goto done; + } - if (octstr_print(f, s) < 0) { - *error = octstr_format("send email failed in octstr_print %d: %s", - errno, strerror(errno)); - pclose(f); - ret = MMS_SEND_ERROR_TRANSIENT; - goto done; - } + if (octstr_print(f, s) < 0) { + *error = octstr_format("send email failed in octstr_print %d: %s", + errno, strerror(errno)); + pclose(f); + ret = MMS_SEND_ERROR_TRANSIENT; + goto done; + } - if ((ret = pclose(f)) != 0) { - *error = octstr_format("Send email command returned non-zero %d: errno=%s", - ret, strerror(errno)); - ret = MMS_SEND_ERROR_TRANSIENT; - } else - ret = MMS_SEND_QUEUED; + if ((ret = pclose(f)) != 0) { + *error = octstr_format("Send email command returned non-zero %d: errno=%s", + ret, strerror(errno)); + ret = MMS_SEND_ERROR_TRANSIENT; + } else + ret = MMS_SEND_QUEUED; done: - http_destroy_headers(headers); - octstr_destroy(cmd); - octstr_destroy(s); - return ret; + http_destroy_headers(headers); + octstr_destroy(cmd); + octstr_destroy(s); + return ret; } 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) + 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); + return send2email(to,from,subject,msgid,m,append_hostname,error,sendmail_cmd,myhostname); } /* Send this message to email recipient. */ @@ -712,140 +714,140 @@ int mms_sendtoemail(Octstr *from, Octstr *to, List *extra_headers) { - MIMEEntity *m = NULL; - List *headers = NULL; - List *newhdrs = http_create_empty_headers(); - int ret = 0, mtype; + MIMEEntity *m = NULL; + List *headers = NULL; + List *newhdrs = http_create_empty_headers(); + int ret = 0, mtype; - gw_assert(msg); - mtype = mms_messagetype(msg); + gw_assert(msg); + mtype = mms_messagetype(msg); - if (!to || - octstr_search_char(to, '@', 0) < 0) { - *error = octstr_format("Invalid email address %S!", to); - return MMS_SEND_ERROR_FATAL; - } + if (!to || + octstr_search_char(to, '@', 0) < 0) { + *error = octstr_format("Invalid email address %S!", to); + return MMS_SEND_ERROR_FATAL; + } - if (!trans_msg) - m = mms_tomime(msg,0); - else if ((ret = mms_format_special(msg, trans_smil, txt, html, &m)) < 0 || - m == NULL) { - mms_warning(0, "send2email", NULL, "Failed to format message (msg=%s,ret=%d)", - m ? "OK" : "Not transformed",ret); - return -ret; - } + if (!trans_msg) + m = mms_tomime(msg,0); + else if ((ret = mms_format_special(msg, trans_smil, txt, html, &m)) < 0 || + m == NULL) { + mms_warning(0, "send2email", NULL, "Failed to format message (msg=%s,ret=%d)", + m ? "OK" : "Not transformed",ret); + return -ret; + } - base64_mimeparts(m,0); /* make sure parts are base64 formatted. */ + base64_mimeparts(m,0); /* make sure parts are base64 formatted. */ - if (extra_headers) /* add any other headers into the mix. */ - http_header_combine(newhdrs, extra_headers); + if (extra_headers) /* add any other headers into the mix. */ + http_header_combine(newhdrs, extra_headers); - headers = mime_entity_headers(m); + headers = mime_entity_headers(m); - /* Before we send it, we insert some email friendly headers if they are missing. */ - 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, tmp[32]; - Octstr *xsender = octstr_format("system-user@%S", myhostname); - Octstr *y; + /* Before we send it, we insert some email friendly headers if they are missing. */ + 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, tmp[32]; + Octstr *xsender = octstr_format("system-user@%S", myhostname); + Octstr *y; - if (msgid) { - y = (octstr_get_char(msgid, 0) == '"') ? octstr_duplicate(msgid) : - octstr_format("\"%S\"", msgid); + if (msgid) { + y = (octstr_get_char(msgid, 0) == '"') ? octstr_duplicate(msgid) : + octstr_format("\"%S\"", msgid); - http_header_add(newhdrs, "X-Mms-Message-ID", octstr_get_cstr(y)); - octstr_destroy(y); - } + http_header_add(newhdrs, "X-Mms-Message-ID", octstr_get_cstr(y)); + octstr_destroy(y); + } - /* fixup messageid */ - if ((y = http_header_value(headers, octstr_imm("Message-ID"))) != NULL) { - if (octstr_get_char(y, 0) != '<') { - octstr_insert_char(y, 0, '<'); - octstr_append_char(y, '>'); - } - http_header_remove_all(headers, "Message-ID"); + /* fixup messageid */ + if ((y = http_header_value(headers, octstr_imm("Message-ID"))) != NULL) { + if (octstr_get_char(y, 0) != '<') { + octstr_insert_char(y, 0, '<'); + octstr_append_char(y, '>'); + } + http_header_remove_all(headers, "Message-ID"); - http_header_add(newhdrs, "Message-ID", octstr_get_cstr(y)); - octstr_destroy(y); - } - sprintf(tmp, "%d.%d.%d", - MAJOR_VERSION(MMS_3GPP_VERSION), - MINOR1_VERSION(MMS_3GPP_VERSION), - MINOR2_VERSION(MMS_3GPP_VERSION)); - http_header_add(newhdrs, "X-Mms-3GPP-MMS-Version", tmp); - 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) { - Octstr *s = http_header_value(headers, octstr_imm("X-Mms-Status")); - x = "MM4_delivery_report.REQ"; + http_header_add(newhdrs, "Message-ID", octstr_get_cstr(y)); + octstr_destroy(y); + } + sprintf(tmp, "%d.%d.%d", + MAJOR_VERSION(MMS_3GPP_VERSION), + MINOR1_VERSION(MMS_3GPP_VERSION), + MINOR2_VERSION(MMS_3GPP_VERSION)); + http_header_add(newhdrs, "X-Mms-3GPP-MMS-Version", tmp); + 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) { + Octstr *s = http_header_value(headers, octstr_imm("X-Mms-Status")); + x = "MM4_delivery_report.REQ"; #if 0 - /* insert FROM address as recipient as per spec */ - http_header_add(newhdrs, "From", octstr_get_cstr(to)); + /* insert FROM address as recipient as per spec */ + http_header_add(newhdrs, "From", octstr_get_cstr(to)); #else - http_header_add(newhdrs, "To", octstr_get_cstr(to)); + http_header_add(newhdrs, "To", octstr_get_cstr(to)); #endif - /* rename status header. */ - http_header_remove_all(headers, "X-Mms-Status"); - http_header_add(newhdrs, "X-Mms-MM-Status-Code", - s ? octstr_get_cstr(s) : "Unrecognised"); - if (!s) - mms_warning(0, NULL, NULL, "MMS Delivery report with missing Status!"); - octstr_destroy(s); - } else if (mtype == MMS_MSGTYPE_READ_REC_IND) { - x = "MM4_read_reply_report.REQ"; + /* rename status header. */ + http_header_remove_all(headers, "X-Mms-Status"); + http_header_add(newhdrs, "X-Mms-MM-Status-Code", + s ? octstr_get_cstr(s) : "Unrecognised"); + if (!s) + mms_warning(0, NULL, NULL, "MMS Delivery report with missing Status!"); + octstr_destroy(s); + } else if (mtype == MMS_MSGTYPE_READ_REC_IND) { + x = "MM4_read_reply_report.REQ"; #if 0 - /* insert FROM address as recipient as per spec */ - http_header_add(newhdrs, "From", octstr_get_cstr(to)); + /* insert FROM address as recipient as per spec */ + http_header_add(newhdrs, "From", octstr_get_cstr(to)); #else - http_header_add(newhdrs, "To", octstr_get_cstr(to)); + http_header_add(newhdrs, "To", octstr_get_cstr(to)); #endif - } 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; - } + } 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-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)); - y = (transid && transid[0] == '"') ? octstr_create(transid) : - octstr_format("\"%s\"", transid ? transid : "x"); + y = (transid && transid[0] == '"') ? octstr_create(transid) : + octstr_format("\"%s\"", transid ? transid : "x"); - http_header_add(newhdrs, "X-Mms-Transaction-ID", octstr_get_cstr(y)); + http_header_add(newhdrs, "X-Mms-Transaction-ID", octstr_get_cstr(y)); - octstr_destroy(y); - octstr_destroy(xsender); - } + octstr_destroy(y); + octstr_destroy(xsender); + } - http_header_combine(headers, newhdrs); - mime_replace_headers(m, headers); + http_header_combine(headers, newhdrs); + mime_replace_headers(m, headers); done: - http_destroy_headers(headers); - http_destroy_headers(newhdrs); + http_destroy_headers(headers); + http_destroy_headers(newhdrs); - if (ret == 0) - ret = send2email(to, - from, subject, msgid, m, mm4 == 0, error, sendmail_cmd, myhostname); - mime_entity_destroy(m); + if (ret == 0) + ret = send2email(to, + from, subject, msgid, m, mm4 == 0, error, sendmail_cmd, myhostname); + mime_entity_destroy(m); - return ret; + return ret; } void mms_log2(char *logmsg, Octstr *from, Octstr *to, @@ -854,17 +856,17 @@ void mms_log2(char *logmsg, Octstr *from, Octstr *to, Octstr *viaproxy, char *interface, Octstr *ua, Octstr *mmboxloc) { - List *l; - if (to) { - l = gwlist_create(); - gwlist_append(l, to); - } else - l = NULL; + List *l; + if (to) { + l = gwlist_create(); + gwlist_append(l, to); + } else + l = NULL; - mms_log(logmsg, from,l,msize,msgid,acct,viaproxy,interface,ua,mmboxloc); + mms_log(logmsg, from,l,msize,msgid,acct,viaproxy,interface,ua,mmboxloc); - if (l) - gwlist_destroy(l, NULL); + if (l) + gwlist_destroy(l, NULL); } void mms_log(char *logmsg, Octstr *from, List *to, @@ -873,106 +875,291 @@ void mms_log(char *logmsg, Octstr *from, List *to, Octstr *viaproxy, char *interface, Octstr *ua, Octstr *mmboxloc) { - Octstr *xto = octstr_create(""); - int i, n = to ? gwlist_len(to) : 0; - Octstr *xfrom = from ? octstr_duplicate(from) : NULL; - int j = xfrom ? octstr_case_search(xfrom, octstr_imm("/TYPE=PLMN"), 0) : -1; + Octstr *xto = octstr_create(""); + int i, n = to ? gwlist_len(to) : 0; + Octstr *xfrom = from ? octstr_duplicate(from) : NULL; + int j = xfrom ? octstr_case_search(xfrom, octstr_imm("/TYPE=PLMN"), 0) : -1; - if (j >= 0) - octstr_delete(xfrom, j, octstr_len(xfrom)); + if (j >= 0) + octstr_delete(xfrom, j, octstr_len(xfrom)); - for (i = 0; i < n; i++) { - void *y; - Octstr *x = (y = gwlist_get(to,i)) ? octstr_duplicate(y) : NULL; - int j = x ? octstr_case_search(x, octstr_imm("/TYPE=PLMN"), 0) : -1; + for (i = 0; i < n; i++) { + void *y; + Octstr *x = (y = gwlist_get(to,i)) ? octstr_duplicate(y) : NULL; + int j = x ? octstr_case_search(x, octstr_imm("/TYPE=PLMN"), 0) : -1; - if (j >= 0) - octstr_delete(x, j, octstr_len(x)); + if (j >= 0) + octstr_delete(x, j, octstr_len(x)); - octstr_format_append(xto, - "%s%S", - (i == 0) ? "" : ", ", - x); + octstr_format_append(xto, + "%s%S", + (i == 0) ? "" : ", ", + x); - octstr_destroy(x); - } + octstr_destroy(x); + } - alog("%s MMS [INT:%s] [ACT:%s] [MMSC:%s] [from:%s] [to:%s] [msgid:%s] [size=%d] [UA:%s] [MMBox:%s]", - logmsg, interface, - acct ? octstr_get_cstr(acct) : "", - viaproxy ? octstr_get_cstr(viaproxy) : "", - xfrom ? octstr_get_cstr(xfrom) : "", - octstr_get_cstr(xto), - msgid ? octstr_get_cstr(msgid) : "", - msize, - ua ? octstr_get_cstr(ua) : "", - mmboxloc ? octstr_get_cstr(mmboxloc) : ""); + alog("%s MMS [INT:%s] [ACT:%s] [MMSC:%s] [from:%s] [to:%s] [msgid:%s] [size=%d] [UA:%s] [MMBox:%s]", + logmsg, interface, + acct ? octstr_get_cstr(acct) : "", + viaproxy ? octstr_get_cstr(viaproxy) : "", + xfrom ? octstr_get_cstr(xfrom) : "", + octstr_get_cstr(xto), + msgid ? octstr_get_cstr(msgid) : "", + msize, + ua ? octstr_get_cstr(ua) : "", + mmboxloc ? octstr_get_cstr(mmboxloc) : ""); - octstr_destroy(xto); - octstr_destroy(xfrom); + octstr_destroy(xto); + octstr_destroy(xfrom); } -static int lockfile(int fd, int shouldblock) +/* Compare a file_lock(lhs) to the file_key(rhs) + * and see if they match + */ +int file_lock_inode_cmp(void *_lhs, void *_rhs); + +/* Each file gets a condition, there is only a single file_loc + for each inode number. Assumes a uni +*/ +typedef struct { + dev_t dev; + ino_t inode; +} file_key; + +typedef struct { + file_key key; + pthread_cond_t condition; + int fd; +} file_lock; + +static List *openFileList = NULL; +static pthread_mutex_t listMutex = PTHREAD_MUTEX_INITIALIZER; + +void release_file_lock(int fd, file_key *key) +{ + debug("mm_util",0,"----->Locked"); + pthread_mutex_lock(&listMutex); + + if (openFileList == NULL) { + openFileList = (List *)gwlist_create(); + } + + file_lock *item = (file_lock*)gwlist_search(openFileList, key, file_lock_inode_cmp); + if (item && item->fd == fd) { + /* we own the lock */ + gwlist_delete_equal(openFileList, item); + pthread_cond_broadcast(&item->condition); + pthread_cond_destroy(&item->condition); + gw_free(item); + } + debug("mm_util",0,"<-----UnLocked"); + pthread_mutex_unlock(&listMutex); +} + +int unlock_and_close(int fd) { - int n, stop; #ifdef SunOS - int flg = shouldblock ? F_SETLKW : F_SETLK; - flock_t lock; -#else - unsigned flg = shouldblock ? 0 : LOCK_NB; + struct stat buf; + if (fstat(fd, &buf)) { + perror("Unable to fstat file for lock"); + return close(fd); + } + + file_key key; + key.inode = buf.st_ino; + key.dev = buf.st_dev; + + release_file_lock(fd, &key); #endif - do { + + return close(fd); +} + +int unlock_and_fclose(FILE *fp) +{ #ifdef SunOS - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - lock.l_type = F_WRLCK; - n = fcntl(fd, flg, &lock); + int fd = fileno(fp); + struct stat buf; + if (fstat(fd, &buf)) { + perror("Unable to fstat file for lock"); + return fclose(fp); + } + + file_key key; + key.inode = buf.st_ino; + key.dev = buf.st_dev; + + release_file_lock(fd, &key); +#endif + return fclose(fp); +} + +/* Compare a file_lock(lhs) to the file_key(rhs) + and see if they match +*/ +int file_lock_inode_cmp(void *_lhs, void *_rhs) { + file_key *rhs = (file_key*)_rhs; + file_lock *lhs = (file_lock *)_lhs; + + return ( + lhs && + lhs->key.inode == rhs->inode && + lhs->key.dev == rhs->dev + ); +} + +int sun_lockfile(int fd, int shouldblock) +{ + +#ifdef SunOS + int n, stop; + int flg = shouldblock ? F_SETLKW : F_SETLK; + flock_t lock; + + struct stat buf; + if (fstat(fd, &buf)) { + int e = errno; + perror("Unable to fstat file for lock"); + errno = e; + return(-1); + } + + file_key key; + key.inode = buf.st_ino; + key.dev = buf.st_dev; + + debug("mm_util",0,"----->Locked"); + pthread_mutex_lock(&listMutex); + + if (openFileList == NULL) { + openFileList = (List *)gwlist_create(); + } + + /* See if the inode exists in the list */ + file_lock *item = NULL; + do { + item = (file_lock*)gwlist_search(openFileList, &key, file_lock_inode_cmp); + if (item) { + /* It exists, that means that someone has already locked the file */ + if (!shouldblock) { + n = -1; + debug("mm_util",0,"<-----UnLocked"); + pthread_mutex_unlock(&listMutex); + errno = EWOULDBLOCK; + return n; + } + + pthread_cond_wait(&item->condition, &listMutex); + /* O.k. we've got the file, but now item is invalid, + the unlock_and_close removes it. + */ + } + } while (item != NULL); + + /* No one else has locked the file, create the condition for + anyone else. + */ + item = (file_lock*)gw_malloc(sizeof(file_lock)); + item->key.inode = key.inode; + item->key.dev = key.dev; + item->fd = fd; + pthread_cond_init(&item->condition, NULL); + gwlist_append(openFileList, item); + + /* Release the global lock so that we don't block the + entire system waiting for fnctl to return + */ + debug("mm_util",0,"<-----UnLocked"); + pthread_mutex_unlock(&listMutex); + + do { + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + lock.l_type = F_WRLCK; + n = fcntl(fd, flg, &lock); + if (n < 0) { + if (errno == EINTR) + stop = 0; + else + stop = 1; + } else + stop = 1; + } while (!stop); + + /* If we failed to get the fcntl lock, then we need to + release the local lock */ + if (n != 0) { + release_file_lock(fd, &key); + } + + return (n == 0) ? 0 : errno; #else - n = flock(fd, LOCK_EX|flg); + panic(0, "Attempt to call sun_lockfile on a non-solaris system"); + return 0; #endif - if (n < 0) { - if (errno == EINTR) - stop = 0; - else - stop = 1; - } else - stop = 1; - } while (!stop); +} + +int lockfile(int fd, int shouldblock) +{ +#ifdef SunOS + return sun_lockfile(fd, shouldblock); +#else + int n, stop; + unsigned flg = shouldblock ? 0 : LOCK_NB; + + do { + n = flock(fd, LOCK_EX|flg); + if (n < 0) { + if (errno == EINTR) + stop = 0; + else + stop = 1; + } else + stop = 1; + } while (!stop); - return (n == 0) ? 0 : errno; + return (n == 0) ? 0 : errno; +#endif } static int check_lock(int fd, char *fname) { - struct stat fs = {0}, ds = {0}; + struct stat fs = {0}, ds = {0}; - /* You might grab a lock on a file, but the file - * might be changed just before you grabbed the lock. Detect that and fail.. - */ - if (fstat(fd, &ds) < 0 || - stat(fname, &fs) < 0 || + /* You might grab a lock on a file, but the file + * might be changed just before you grabbed the lock. Detect that and fail.. + */ + if (fstat(fd, &ds) < 0 || + stat(fname, &fs) < 0 || - ds.st_nlink != fs.st_nlink || - memcmp(&ds.st_dev,&fs.st_dev, sizeof ds.st_dev) != 0 || - memcmp(&ds.st_ino,&fs.st_ino, sizeof ds.st_ino) != 0 || - ds.st_uid != fs.st_uid || - ds.st_gid != fs.st_gid || - ds.st_size != fs.st_size) - return -1; - else - return 0; + ds.st_nlink != fs.st_nlink || + memcmp(&ds.st_dev,&fs.st_dev, sizeof ds.st_dev) != 0 || + memcmp(&ds.st_ino,&fs.st_ino, sizeof ds.st_ino) != 0 || + ds.st_uid != fs.st_uid || + ds.st_gid != fs.st_gid || + ds.st_size != fs.st_size) + return -1; + else + return 0; } int mm_lockfile(int fd, char *fname, int shouldblock) { - int ret = lockfile(fd,shouldblock); + int ret = lockfile(fd,shouldblock); - if (ret != 0 || - (ret = check_lock(fd,fname)) != 0) - return ret; - return 0; + if (ret != 0 && errno != EWOULDBLOCK) { + debug("mm_util", 0, "Unable to lock '%s', error= %d, %s, shouldblock=%d", + fname, errno, strerror(errno), shouldblock); + perror("Unable to lock file"); + } + + if (ret != 0 || + (ret = check_lock(fd,fname)) != 0) + return ret; + return 0; } void mms_collect_envdata_from_msgheaders(List *mh, List **xto, @@ -983,323 +1170,323 @@ void mms_collect_envdata_from_msgheaders(List *mh, List **xto, char *unified_prefix, List *strip_prefixes) { - Octstr *s; - List *l = http_header_find_all(mh, "To"); - if (l) { - int i, n; - for (i = 0, n = gwlist_len(l); i 0 - && (*expiryt - time(NULL)) > max_msgexpiry) - *expiryt = time(NULL) + max_msgexpiry; - } + if (max_msgexpiry > 0 + && (*expiryt - time(NULL)) > max_msgexpiry) + *expiryt = time(NULL) + max_msgexpiry; + } - if (deliveryt) { - s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time")); - if (s) { - *deliveryt = date_parse_http(s); - octstr_destroy(s); - } else - *deliveryt = 0; - } - if (subject) - *subject = http_header_value(mh, octstr_imm("Subject")); + if (deliveryt) { + s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time")); + if (s) { + *deliveryt = date_parse_http(s); + octstr_destroy(s); + } else + *deliveryt = 0; + } + if (subject) + *subject = http_header_value(mh, octstr_imm("Subject")); - if (otransid) - *otransid = http_header_value(mh, octstr_imm("X-Mms-Transaction-ID")); + if (otransid) + *otransid = http_header_value(mh, octstr_imm("X-Mms-Transaction-ID")); } unsigned long _mshash(char *s) { - unsigned h = 0; + unsigned h = 0; - while (*s) { - unsigned int ch = tolower(*s); - s++; - h += ((unsigned)(ch) << 4) + 1249; - } - return h; + while (*s) { + unsigned int ch = tolower(*s); + s++; + h += ((unsigned)(ch) << 4) + 1249; + } + return h; } int isphonenum(Octstr *s) { - int i = 0, n = octstr_len(s); - char *cs; + int i = 0, n = octstr_len(s); + char *cs; - if (s && octstr_len(s) >= 1 && - octstr_get_cstr(s)[0] == '+') - i++; - for ( cs = octstr_get_cstr(s); i= 1 && + octstr_get_cstr(s)[0] == '+') + i++; + for ( cs = octstr_get_cstr(s); i0) /* an email address. */ - return; + if (!address || !*address) return; + i = octstr_search_char(*address, '@', 0); + if (i>0) /* an email address. */ + return; - i = octstr_case_search(*address, octstr_imm("/TYPE="), 0); - if (i > 0) { - typ = octstr_copy(*address, i, octstr_len(*address)); - octstr_delete(*address, i, octstr_len(*address)); - } else - typ = NULL; + i = octstr_case_search(*address, octstr_imm("/TYPE="), 0); + if (i > 0) { + typ = octstr_copy(*address, i, octstr_len(*address)); + octstr_delete(*address, i, octstr_len(*address)); + } else + typ = NULL; - if (isphonenum(*address) || (typ && octstr_str_case_compare(typ, "/TYPE=PLMN") == 0)) { - mms_normalize_phonenum(address, unified_prefix, strip_prefixes); - octstr_append(*address, keep_suffix ? octstr_imm("/TYPE=PLMN") : octstr_imm("")); - } else if (typ) - octstr_append(*address, keep_suffix ? typ : octstr_imm("")); - else - octstr_append(*address, keep_suffix ? octstr_imm("@unknown") : octstr_imm("")); - octstr_destroy(typ); + if (isphonenum(*address) || (typ && octstr_str_case_compare(typ, "/TYPE=PLMN") == 0)) { + mms_normalize_phonenum(address, unified_prefix, strip_prefixes); + octstr_append(*address, keep_suffix ? octstr_imm("/TYPE=PLMN") : octstr_imm("")); + } else if (typ) + octstr_append(*address, keep_suffix ? typ : octstr_imm("")); + else + octstr_append(*address, keep_suffix ? octstr_imm("@unknown") : octstr_imm("")); + octstr_destroy(typ); } /* compare, reversed result! */ static int comp_fn(void *item, void *pattern) { - return (octstr_case_compare(item, pattern) == 0) ? 1 : 0; + return (octstr_case_compare(item, pattern) == 0) ? 1 : 0; } int is_allowed_host(Octstr *host, Octstr *host_list) { - List *l; - int ret; - gw_assert(host_list); - gw_assert(host); + List *l; + int ret; + gw_assert(host_list); + gw_assert(host); - l = octstr_split(host_list, octstr_imm(";")); + l = octstr_split(host_list, octstr_imm(";")); - ret = (gwlist_search(l, host, comp_fn) != NULL) ? 1 : 0; + ret = (gwlist_search(l, host, comp_fn) != NULL) ? 1 : 0; - gwlist_destroy(l, (void *)octstr_destroy); + gwlist_destroy(l, (void *)octstr_destroy); - return ret; + return ret; } #define SHELLCHARS "'|\"()[]{}$&!?*><%`\n \t\\" void escape_shell_chars(Octstr *str) { - Octstr *tmp; - int i, n; + Octstr *tmp; + int i, n; - octstr_strip_blanks(str); + octstr_strip_blanks(str); - tmp = octstr_duplicate(str); - octstr_delete(str, 0, octstr_len(str)); + tmp = octstr_duplicate(str); + octstr_delete(str, 0, octstr_len(str)); - for (i = 0, n = octstr_len(tmp); i < n; i++) { - int ch = octstr_get_char(tmp,i); + for (i = 0, n = octstr_len(tmp); i < n; i++) { + int ch = octstr_get_char(tmp,i); - if (strchr(SHELLCHARS, ch) != NULL) - octstr_append_char(str, '\\'); - octstr_append_char(str, ch); - } - octstr_destroy(tmp); + if (strchr(SHELLCHARS, ch) != NULL) + octstr_append_char(str, '\\'); + octstr_append_char(str, ch); + } + octstr_destroy(tmp); } int parse_cgivars(List *request_headers, Octstr *request_body, List **cgivars, List **cgivar_ctypes) { - Octstr *ctype = NULL, *charset = NULL; - int ret = 0; + Octstr *ctype = NULL, *charset = NULL; + int ret = 0; - if (request_body == NULL || - octstr_len(request_body) == 0 || cgivars == NULL) - return 0; /* Nothing to do, this is a normal GET request. */ + if (request_body == NULL || + octstr_len(request_body) == 0 || cgivars == NULL) + return 0; /* Nothing to do, this is a normal GET request. */ - http_header_get_content_type(request_headers, &ctype, &charset); + http_header_get_content_type(request_headers, &ctype, &charset); - if (*cgivars == NULL) - *cgivars = gwlist_create(); + if (*cgivars == NULL) + *cgivars = gwlist_create(); - if (*cgivar_ctypes == NULL) - *cgivar_ctypes = gwlist_create(); + if (*cgivar_ctypes == NULL) + *cgivar_ctypes = gwlist_create(); - if (!ctype) { - mms_warning(0, NULL, NULL, "MMS: Parse CGI Vars: Missing Content Type!"); - ret = -1; - goto done; - } + if (!ctype) { + mms_warning(0, NULL, NULL, "MMS: Parse CGI Vars: Missing Content Type!"); + ret = -1; + goto done; + } - if (octstr_case_compare(ctype, octstr_imm("application/x-www-form-urlencoded")) == 0) { - /* This is a normal POST form */ - List *l = octstr_split(request_body, octstr_imm("&")); - Octstr *v; + if (octstr_case_compare(ctype, octstr_imm("application/x-www-form-urlencoded")) == 0) { + /* This is a normal POST form */ + List *l = octstr_split(request_body, octstr_imm("&")); + Octstr *v; - while ((v = gwlist_extract_first(l)) != NULL) { - List *r = octstr_split(v, octstr_imm("=")); + while ((v = gwlist_extract_first(l)) != NULL) { + List *r = octstr_split(v, octstr_imm("=")); - if (gwlist_len(r) == 0) - mms_warning(0, NULL, NULL, "MMS: Parse CGI Vars: Missing CGI var name/value in POST data: %s", - octstr_get_cstr(request_body)); - else { - HTTPCGIVar *x = gw_malloc(sizeof *x); - x->name = gwlist_extract_first(r); - x->value = gwlist_extract_first(r); - if (!x->value) - x->value = octstr_create(""); + if (gwlist_len(r) == 0) + mms_warning(0, NULL, NULL, "MMS: Parse CGI Vars: Missing CGI var name/value in POST data: %s", + octstr_get_cstr(request_body)); + else { + HTTPCGIVar *x = gw_malloc(sizeof *x); + x->name = gwlist_extract_first(r); + x->value = gwlist_extract_first(r); + if (!x->value) + x->value = octstr_create(""); - octstr_strip_blanks(x->name); - octstr_strip_blanks(x->value); + octstr_strip_blanks(x->name); + octstr_strip_blanks(x->value); - octstr_url_decode(x->name); - octstr_url_decode(x->value); + octstr_url_decode(x->name); + octstr_url_decode(x->value); - gwlist_append(*cgivars, x); - } - octstr_destroy(v); - gwlist_destroy(r, octstr_destroy_item); - } - gwlist_destroy(l, NULL); - } else if (octstr_case_compare(ctype, octstr_imm("multipart/form-data")) == 0) { - /* multi-part form data */ - MIMEEntity *m = mime_http_to_entity(request_headers, request_body); - int i, n; + gwlist_append(*cgivars, x); + } + octstr_destroy(v); + gwlist_destroy(r, octstr_destroy_item); + } + gwlist_destroy(l, NULL); + } else if (octstr_case_compare(ctype, octstr_imm("multipart/form-data")) == 0) { + /* multi-part form data */ + MIMEEntity *m = mime_http_to_entity(request_headers, request_body); + int i, n; - if (!m) { - mms_warning(0, NULL, NULL, "MMS: Parse CGI Vars: Failed to parse multipart/form-data body: %s", - octstr_get_cstr(request_body)); - ret = -1; - goto done; - } - /* Go through body parts, pick out what we need. */ - for (i = 0, n = mime_entity_num_parts(m); i < n; i++) { - MIMEEntity *mp = mime_entity_get_part(m, i); - List *headers = mime_entity_headers(mp); - Octstr *body = mime_entity_body(mp); - Octstr *ct = http_header_value(headers, - octstr_imm("Content-Type")); - Octstr *cd = http_header_value(headers, - octstr_imm("Content-Disposition")); - Octstr *name = http_get_header_parameter(cd, octstr_imm("name")); + if (!m) { + mms_warning(0, NULL, NULL, "MMS: Parse CGI Vars: Failed to parse multipart/form-data body: %s", + octstr_get_cstr(request_body)); + ret = -1; + goto done; + } + /* Go through body parts, pick out what we need. */ + for (i = 0, n = mime_entity_num_parts(m); i < n; i++) { + MIMEEntity *mp = mime_entity_get_part(m, i); + List *headers = mime_entity_headers(mp); + Octstr *body = mime_entity_body(mp); + Octstr *ct = http_header_value(headers, + octstr_imm("Content-Type")); + Octstr *cd = http_header_value(headers, + octstr_imm("Content-Disposition")); + Octstr *name = http_get_header_parameter(cd, octstr_imm("name")); - if (name) { - HTTPCGIVar *x = gw_malloc(sizeof *x); + if (name) { + HTTPCGIVar *x = gw_malloc(sizeof *x); - /* Strip quotes */ - if (octstr_get_char(name, 0) == '"') { - octstr_delete(name, 0, 1); - octstr_truncate(name, octstr_len(name) - 1); - } + /* Strip quotes */ + if (octstr_get_char(name, 0) == '"') { + octstr_delete(name, 0, 1); + octstr_truncate(name, octstr_len(name) - 1); + } - x->name = octstr_duplicate(name); - x->value = octstr_duplicate(body); + x->name = octstr_duplicate(name); + x->value = octstr_duplicate(body); - gwlist_append(*cgivars, x); + gwlist_append(*cgivars, x); - if (ct) { /* If the content type is set, use it. */ - x = gw_malloc(sizeof *x); - x->name = octstr_duplicate(name); - x->value = octstr_duplicate(ct); + if (ct) { /* If the content type is set, use it. */ + x = gw_malloc(sizeof *x); + x->name = octstr_duplicate(name); + x->value = octstr_duplicate(ct); - gwlist_append(*cgivar_ctypes, x); - } - octstr_destroy(name); - } + gwlist_append(*cgivar_ctypes, x); + } + octstr_destroy(name); + } - octstr_destroy(ct); - octstr_destroy(cd); - octstr_destroy(body); - http_destroy_headers(headers); - mime_entity_destroy(mp); - } - mime_entity_destroy(m); + octstr_destroy(ct); + octstr_destroy(cd); + octstr_destroy(body); + http_destroy_headers(headers); + mime_entity_destroy(mp); + } + mime_entity_destroy(m); - } else /* else it is nothing that we know about, so simply go away... */ - ret = -1; -done: - octstr_destroy(ctype); - octstr_destroy(charset); - return ret; + } else /* else it is nothing that we know about, so simply go away... */ + ret = -1; + done: + octstr_destroy(ctype); + octstr_destroy(charset); + return ret; } /* get content-ID header, fix: WAP decoder may leave \" at beginning */ Octstr *_x_get_content_id(List *headers) { - Octstr *cid = http_header_value(headers, octstr_imm("Content-ID")); + Octstr *cid = http_header_value(headers, octstr_imm("Content-ID")); - if (cid) - if (octstr_get_char(cid, 0) == '"' && - octstr_get_char(cid, octstr_len(cid) - 1) != '"') - octstr_delete(cid, 0,1); - return cid; + if (cid) + if (octstr_get_char(cid, 0) == '"' && + octstr_get_char(cid, octstr_len(cid) - 1) != '"') + octstr_delete(cid, 0,1); + return cid; } /* Utility: Take a header list, remove any boundary parameter from the content-type @@ -1307,261 +1494,261 @@ Octstr *_x_get_content_id(List *headers) */ void strip_boundary_element(List *headers, char *s) { - Octstr *ctype = NULL, *params = NULL; - Octstr *value; - int n; + Octstr *ctype = NULL, *params = NULL; + Octstr *value; + int n; - gw_assert(headers); + gw_assert(headers); - if ((n = get_content_type(headers, &ctype, ¶ms)) < 0) { - octstr_destroy(ctype); - ctype = NULL; /* no ctype found, so do not replace it! */ - } else if (ctype && - DRM_CONTENT_TYPE(ctype)) { - octstr_destroy(ctype); - ctype = NULL; /* leave drm alone! */ - } + if ((n = get_content_type(headers, &ctype, ¶ms)) < 0) { + octstr_destroy(ctype); + ctype = NULL; /* no ctype found, so do not replace it! */ + } else if (ctype && + DRM_CONTENT_TYPE(ctype)) { + octstr_destroy(ctype); + ctype = NULL; /* leave drm alone! */ + } - if (s) {/* we are replacing the content type as well as stripping */ - octstr_destroy(ctype); - ctype = octstr_create(s); - } + if (s) {/* we are replacing the content type as well as stripping */ + octstr_destroy(ctype); + ctype = octstr_create(s); + } - 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. */ - ps = make_value_parameters(h); + 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. */ + ps = make_value_parameters(h); - value = octstr_format("%S%s%S", ctype, - (ps && octstr_len(ps) > 0) ? "; " : "", - ps); - octstr_destroy(ps); - http_destroy_headers(h); - } else - value = ctype; - if (value) { - http_header_remove_all(headers, "Content-Type"); - http_header_add(headers, "Content-Type", octstr_get_cstr(value)); - } - if (ctype != value) - octstr_destroy(ctype); - octstr_destroy(value); - octstr_destroy(params); + value = octstr_format("%S%s%S", ctype, + (ps && octstr_len(ps) > 0) ? "; " : "", + ps); + octstr_destroy(ps); + http_destroy_headers(h); + } else + value = ctype; + if (value) { + http_header_remove_all(headers, "Content-Type"); + http_header_add(headers, "Content-Type", octstr_get_cstr(value)); + } + if (ctype != value) + octstr_destroy(ctype); + octstr_destroy(value); + octstr_destroy(params); } /* Mapping file extensions to content types. */ static struct { - char *ctype, *file_ext; + char *ctype, *file_ext; } exts[] = { - {"text/plain", "txt"}, - {"image/jpeg", "jpg"}, - {"image/jpeg", "jpeg"}, - {"image/png", "png"}, - {"image/tiff", "tiff"}, - {"image/gif", "gif"}, - {"image/bmp", "bmp"}, - {"image/vnd.wap.wbmp", "wbmp"}, - {"image/x-bmp", "bmp"}, - {"image/x-wmf", "bmp"}, - {"image/vnd.wap.wpng", "png"}, - {"image/x-up-wpng", "png"}, - {"audio/mpeg", "mp3"}, - {"audio/wav", "wav"}, - {"audio/basic", "au"}, - {"audio/amr", "amr"}, - {"audio/x-amr", "amr"}, - {"audio/amr-wb", "amr"}, - {"audio/midi", "mid"}, - {"audio/sp-midi", "mid"}, - {"application/smil", "smil"}, - {"application/smil", "smi"}, - {"application/vnd.wap.mms-message", "mms"}, - {"application/java-archive", "jar"}, - {"video/3gpp", "3gp"}, - {"video/3gpp", "3gp2"}, - {"video/3gpp2","3g2"}, - {"audio/vnd.qcelp", "qcp"}, + {"text/plain", "txt"}, + {"image/jpeg", "jpg"}, + {"image/jpeg", "jpeg"}, + {"image/png", "png"}, + {"image/tiff", "tiff"}, + {"image/gif", "gif"}, + {"image/bmp", "bmp"}, + {"image/vnd.wap.wbmp", "wbmp"}, + {"image/x-bmp", "bmp"}, + {"image/x-wmf", "bmp"}, + {"image/vnd.wap.wpng", "png"}, + {"image/x-up-wpng", "png"}, + {"audio/mpeg", "mp3"}, + {"audio/wav", "wav"}, + {"audio/basic", "au"}, + {"audio/amr", "amr"}, + {"audio/x-amr", "amr"}, + {"audio/amr-wb", "amr"}, + {"audio/midi", "mid"}, + {"audio/sp-midi", "mid"}, + {"application/smil", "smil"}, + {"application/smil", "smi"}, + {"application/vnd.wap.mms-message", "mms"}, + {"application/java-archive", "jar"}, + {"video/3gpp", "3gp"}, + {"video/3gpp", "3gp2"}, + {"video/3gpp2","3g2"}, + {"audio/vnd.qcelp", "qcp"}, - {MBUNI_MULTIPART_TYPE, "urls"}, /* mbuni url list type. */ - {NULL, NULL} + {MBUNI_MULTIPART_TYPE, "urls"}, /* mbuni url list type. */ + {NULL, NULL} }; /* Some of Web languages used for generating content, but can't be a content itself. */ static struct { - char *language, *file_ext; + char *language, *file_ext; } l_exts[] = { - {"Perl", "pl"}, - {"Php", "php"}, - {"Python", "py"}, - {"Common Gateway Interface", "cgi"}, - {"Active Server Page", "asp"}, - {"Java Server Page", "jsp"}, - {"Ruby on Rails", "rb"}, - {"Tool Command Language", "tcl"}, - {"Shell Command Language", "sh"}, - {"Executables", "exe"}, - {NULL, NULL} + {"Perl", "pl"}, + {"Php", "php"}, + {"Python", "py"}, + {"Common Gateway Interface", "cgi"}, + {"Active Server Page", "asp"}, + {"Java Server Page", "jsp"}, + {"Ruby on Rails", "rb"}, + {"Tool Command Language", "tcl"}, + {"Shell Command Language", "sh"}, + {"Executables", "exe"}, + {NULL, NULL} }; Octstr *filename2content_type(char *fname) { - char *p = strrchr(fname, '.'); - int i; + char *p = strrchr(fname, '.'); + int i; - if (p) - for (i = 0; exts[i].file_ext; i++) - if (strcasecmp(p+1, exts[i].file_ext) == 0) - return octstr_imm(exts[i].ctype); + if (p) + for (i = 0; exts[i].file_ext; i++) + if (strcasecmp(p+1, exts[i].file_ext) == 0) + return octstr_imm(exts[i].ctype); - return octstr_imm("application/octet-stream"); + return octstr_imm("application/octet-stream"); } static char *content_type2file_ext(Octstr *ctype) { - int i, j; + int i, j; - /* Take the first value, expecting content-type! */ - if ((j = octstr_search_char(ctype, ';', 0)) != -1) - octstr_delete(ctype, j, octstr_len(ctype)); + /* Take the first value, expecting content-type! */ + if ((j = octstr_search_char(ctype, ';', 0)) != -1) + octstr_delete(ctype, j, octstr_len(ctype)); - for (i = 0; exts[i].file_ext; i++) - if (octstr_str_case_compare(ctype, exts[i].ctype) == 0) - return exts[i].file_ext; + for (i = 0; exts[i].file_ext; i++) + if (octstr_str_case_compare(ctype, exts[i].ctype) == 0) + return exts[i].file_ext; - return "dat"; + return "dat"; } char *make_file_ext(Octstr *url, Octstr *ctype, char fext[5]) { - int i; - fext[0] = 0; - if (url) { - HTTPURLParse *h = parse_url(url); - char *s, *p; - if (!h) - goto done; + int i; + fext[0] = 0; + if (url) { + HTTPURLParse *h = parse_url(url); + char *s, *p; + if (!h) + goto done; - s = h->path ? octstr_get_cstr(h->path) : ""; + s = h->path ? octstr_get_cstr(h->path) : ""; - if ((p = strrchr(s, '.')) != NULL) - strncpy(fext, p+1, 4); /* max length of 4. */ + if ((p = strrchr(s, '.')) != NULL) + strncpy(fext, p+1, 4); /* max length of 4. */ - http_urlparse_destroy(h); + http_urlparse_destroy(h); - for (i = 0; l_exts[i].file_ext; i++) - if (strcasecmp(fext, l_exts[i].file_ext) == 0) - return content_type2file_ext(ctype); + for (i = 0; l_exts[i].file_ext; i++) + if (strcasecmp(fext, l_exts[i].file_ext) == 0) + return content_type2file_ext(ctype); - if (fext[0]) - return fext; - } + if (fext[0]) + return fext; + } done: - return content_type2file_ext(ctype); + return content_type2file_ext(ctype); } static int fetch_url_with_auth(HTTPCaller *c, int method, Octstr *url, List *request_headers, Octstr *body, Octstr *auth_hdr, List **reply_headers, Octstr **reply_body); int mms_url_fetch_content(int method, Octstr *url, List *request_headers, - Octstr *body, List **reply_headers, Octstr **reply_body) + Octstr *body, List **reply_headers, Octstr **reply_body) { - int status = 0; - Octstr *furl = NULL; + int status = 0; + Octstr *furl = NULL; - if (octstr_search(url, octstr_imm("data:"), 0) == 0) { - int i = octstr_search_char(url, ',',0); - Octstr *ctype = (i >= 0) ? octstr_copy(url, 5, i-5) : octstr_create("text/plain; charset=us-ascii"); - Octstr *data = (i >= 0) ? octstr_copy(url, i+1, octstr_len(url)) : octstr_duplicate(url); + if (octstr_search(url, octstr_imm("data:"), 0) == 0) { + int i = octstr_search_char(url, ',',0); + Octstr *ctype = (i >= 0) ? octstr_copy(url, 5, i-5) : octstr_create("text/plain; charset=us-ascii"); + Octstr *data = (i >= 0) ? octstr_copy(url, i+1, octstr_len(url)) : octstr_duplicate(url); - Octstr *n = NULL, *h = NULL; + Octstr *n = NULL, *h = NULL; - if (octstr_len(ctype) == 0) - octstr_append_cstr(ctype, "text/plain; charset=us-ascii"); + if (octstr_len(ctype) == 0) + octstr_append_cstr(ctype, "text/plain; charset=us-ascii"); - split_header_value(ctype, &n, &h); + split_header_value(ctype, &n, &h); - if (h) { - List *ph = get_value_parameters(h); - Octstr *v = NULL; + if (h) { + List *ph = get_value_parameters(h); + Octstr *v = NULL; - if ((ph && (v = http_header_value(ph, octstr_imm("base64"))) != NULL) || - octstr_case_search(h, octstr_imm("base64"), 0) >= 0) { /* has base64 item */ - Octstr *p = NULL; + if ((ph && (v = http_header_value(ph, octstr_imm("base64"))) != NULL) || + octstr_case_search(h, octstr_imm("base64"), 0) >= 0) { /* has base64 item */ + Octstr *p = NULL; - octstr_base64_to_binary(data); - http_header_remove_all(ph, "base64"); + octstr_base64_to_binary(data); + http_header_remove_all(ph, "base64"); - octstr_destroy(ctype); + octstr_destroy(ctype); - if (gwlist_len(ph) > 0) { - p = make_value_parameters(ph); - ctype = octstr_format("%S; %S", - n,p); - octstr_destroy(p); - } else - ctype = octstr_format("%S", n); - } + if (gwlist_len(ph) > 0) { + p = make_value_parameters(ph); + ctype = octstr_format("%S; %S", + n,p); + octstr_destroy(p); + } else + ctype = octstr_format("%S", n); + } - if (ph) - http_destroy_headers(ph); + if (ph) + http_destroy_headers(ph); - octstr_destroy(v); - octstr_destroy(h); - } + octstr_destroy(v); + octstr_destroy(h); + } - octstr_destroy(n); + octstr_destroy(n); - *reply_body = data; - *reply_headers = http_create_empty_headers(); - http_header_add(*reply_headers, "Content-Type", octstr_get_cstr(ctype)); + *reply_body = data; + *reply_headers = http_create_empty_headers(); + http_header_add(*reply_headers, "Content-Type", octstr_get_cstr(ctype)); - octstr_destroy(ctype); - status = HTTP_OK; - } else if (octstr_search(url, octstr_imm("file://"), 0) == 0) { - char *file = octstr_get_cstr(url) + 6; - Octstr *ctype = filename2content_type(file); - Octstr *data = octstr_read_file(file); + octstr_destroy(ctype); + status = HTTP_OK; + } else if (octstr_search(url, octstr_imm("file://"), 0) == 0) { + char *file = octstr_get_cstr(url) + 6; + Octstr *ctype = filename2content_type(file); + Octstr *data = octstr_read_file(file); - *reply_body = data; - *reply_headers = http_create_empty_headers(); - http_header_add(*reply_headers, "Content-Type", octstr_get_cstr(ctype)); + *reply_body = data; + *reply_headers = http_create_empty_headers(); + http_header_add(*reply_headers, "Content-Type", octstr_get_cstr(ctype)); - status = data ? HTTP_OK : HTTP_NOT_FOUND; - octstr_destroy(ctype); - } else { - HTTPCaller *c = http_caller_create(); - http_start_request(c, method, url, request_headers, body, 1, NULL, NULL); - if (http_receive_result_real(c, &status, &furl, reply_headers, reply_body,1) == NULL) - status = -1; - if (status == HTTP_UNAUTHORIZED) { - Octstr *v = http_header_value(*reply_headers, octstr_imm("WWW-Authenticate")); + status = data ? HTTP_OK : HTTP_NOT_FOUND; + octstr_destroy(ctype); + } else { + HTTPCaller *c = http_caller_create(); + http_start_request(c, method, url, request_headers, body, 1, NULL, NULL); + if (http_receive_result_real(c, &status, &furl, reply_headers, reply_body,1) == NULL) + status = -1; + if (status == HTTP_UNAUTHORIZED) { + Octstr *v = http_header_value(*reply_headers, octstr_imm("WWW-Authenticate")); - status = fetch_url_with_auth(c, method, url, request_headers, body, v, - reply_headers, reply_body); + status = fetch_url_with_auth(c, method, url, request_headers, body, v, + reply_headers, reply_body); - octstr_destroy(v); - } - http_caller_destroy(c); - } + octstr_destroy(v); + } + http_caller_destroy(c); + } - octstr_destroy(furl); + octstr_destroy(furl); - return status; + return status; } - Octstr *get_stripped_param_value(Octstr *value, Octstr *param) +Octstr *get_stripped_param_value(Octstr *value, Octstr *param) { - Octstr *x = http_get_header_parameter(value, param); + Octstr *x = http_get_header_parameter(value, param); - if (x != NULL && - octstr_get_char(x, 0) == '"' && - octstr_get_char(x, octstr_len(x) - 1) == '"') { - octstr_delete(x, 0, 1); - octstr_delete(x, octstr_len(x) - 1, 1); - } - return x; + if (x != NULL && + octstr_get_char(x, 0) == '"' && + octstr_get_char(x, octstr_len(x) - 1) == '"') { + octstr_delete(x, 0, 1); + octstr_delete(x, octstr_len(x) - 1, 1); + } + return x; } @@ -1571,448 +1758,448 @@ static Octstr *make_url(HTTPURLParse *h); static int fetch_url_with_auth(HTTPCaller *c, int method, Octstr *url, List *request_headers, Octstr *body, Octstr *auth_hdr, List **reply_headers, Octstr **reply_body) { - Octstr *xauth_value = auth_hdr ? octstr_duplicate(auth_hdr) : octstr_create(""); - Octstr *domain = NULL, *nonce = NULL, *opaque = NULL, *algo = NULL, *auth_type = NULL, *x; - Octstr *realm = NULL, *xurl = NULL; - Octstr *cnonce = NULL; - char *nonce_count = "00000001"; - Octstr *A1 = NULL, *A2 = NULL, *rd = NULL; - List *qop = NULL, *l = NULL; - int i, status = HTTP_UNAUTHORIZED, has_auth = 0, has_auth_int = 0; - HTTPURLParse *h = parse_url(url); - char *m_qop = NULL; - time_t t = time(NULL); + Octstr *xauth_value = auth_hdr ? octstr_duplicate(auth_hdr) : octstr_create(""); + Octstr *domain = NULL, *nonce = NULL, *opaque = NULL, *algo = NULL, *auth_type = NULL, *x; + Octstr *realm = NULL, *xurl = NULL; + Octstr *cnonce = NULL; + char *nonce_count = "00000001"; + Octstr *A1 = NULL, *A2 = NULL, *rd = NULL; + List *qop = NULL, *l = NULL; + int i, status = HTTP_UNAUTHORIZED, has_auth = 0, has_auth_int = 0; + HTTPURLParse *h = parse_url(url); + char *m_qop = NULL; + time_t t = time(NULL); - /* Check that there is a username and password in the URL! */ + /* Check that there is a username and password in the URL! */ - if (h == NULL || h->user == NULL || octstr_len(h->user) == 0) - goto done; + if (h == NULL || h->user == NULL || octstr_len(h->user) == 0) + goto done; - /* First we get the auth type: */ + /* First we get the auth type: */ - if ((i = octstr_search_char(xauth_value, ' ', 0)) < 0) { - mms_warning(0, NULL, NULL, "Mal-formed WWW-Authenticate header (%s) received while fetching %s!", - octstr_get_cstr(xauth_value), url ? octstr_get_cstr(url) : ""); - status = -1; - goto done; - } - auth_type = octstr_copy(xauth_value, 0, i); - octstr_delete(xauth_value, 0, i+1); + if ((i = octstr_search_char(xauth_value, ' ', 0)) < 0) { + mms_warning(0, NULL, NULL, "Mal-formed WWW-Authenticate header (%s) received while fetching %s!", + octstr_get_cstr(xauth_value), url ? octstr_get_cstr(url) : ""); + status = -1; + goto done; + } + auth_type = octstr_copy(xauth_value, 0, i); + octstr_delete(xauth_value, 0, i+1); - if (octstr_str_case_compare(auth_type, "Basic") == 0) { - status = HTTP_UNAUTHORIZED; /* suported by default by GWLIB so if we get here, means bad passwd. */ - goto done; - } /* else digest. */ + if (octstr_str_case_compare(auth_type, "Basic") == 0) { + status = HTTP_UNAUTHORIZED; /* suported by default by GWLIB so if we get here, means bad passwd. */ + goto done; + } /* else digest. */ - /* Put back some fake data so what we have can be parsed easily. */ - if ((l = http_header_split_auth_value(xauth_value)) != NULL) { - Octstr *x = gwlist_get(l, 0); - octstr_insert(x, octstr_imm("_none; "), 0); /* make it easier to parse. */ - octstr_destroy(xauth_value); - xauth_value = octstr_duplicate(x); + /* Put back some fake data so what we have can be parsed easily. */ + if ((l = http_header_split_auth_value(xauth_value)) != NULL) { + Octstr *x = gwlist_get(l, 0); + octstr_insert(x, octstr_imm("_none; "), 0); /* make it easier to parse. */ + octstr_destroy(xauth_value); + xauth_value = octstr_duplicate(x); - gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy); - } else - mms_warning(0, NULL, NULL, "Mal-formed Digest header (%s) while fetching (%s)!", - octstr_get_cstr(xauth_value), url ? octstr_get_cstr(url) : ""); + gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy); + } else + mms_warning(0, NULL, NULL, "Mal-formed Digest header (%s) while fetching (%s)!", + octstr_get_cstr(xauth_value), url ? octstr_get_cstr(url) : ""); - realm = get_stripped_param_value(xauth_value, octstr_imm("realm")); - domain = get_stripped_param_value(xauth_value, octstr_imm("domain")); - nonce = get_stripped_param_value(xauth_value, octstr_imm("nonce")); - opaque = get_stripped_param_value(xauth_value, octstr_imm("opaque")); - algo = get_stripped_param_value(xauth_value, octstr_imm("algorithm")); + realm = get_stripped_param_value(xauth_value, octstr_imm("realm")); + domain = get_stripped_param_value(xauth_value, octstr_imm("domain")); + nonce = get_stripped_param_value(xauth_value, octstr_imm("nonce")); + opaque = get_stripped_param_value(xauth_value, octstr_imm("opaque")); + algo = get_stripped_param_value(xauth_value, octstr_imm("algorithm")); - if ((x = get_stripped_param_value(xauth_value, octstr_imm("qop"))) != NULL) { - int i; - qop = octstr_split(x, octstr_imm(",")); - octstr_destroy(x); - for (i = 0; iuser, realm, h->pass ? h->pass : octstr_imm("")); - A1 = md5(x); - octstr_destroy(x); + /* Make A1 */ + x = octstr_format("%S:%S:%S", + h->user, realm, h->pass ? h->pass : octstr_imm("")); + A1 = md5(x); + octstr_destroy(x); - if (algo != NULL && octstr_str_case_compare(algo, "MD5-sess") == 0) { - x = octstr_format("%S:%S:%S", - A1, nonce, cnonce); - octstr_destroy(A1); - A1 = md5(x); - octstr_destroy(x); - } - octstr_binary_to_hex(A1,0); + if (algo != NULL && octstr_str_case_compare(algo, "MD5-sess") == 0) { + x = octstr_format("%S:%S:%S", + A1, nonce, cnonce); + octstr_destroy(A1); + A1 = md5(x); + octstr_destroy(x); + } + octstr_binary_to_hex(A1,0); - /* Make A2. */ - x = octstr_format("%s:%S", - http_method2name(method), - h->path); - if (qop != NULL && has_auth_int && !has_auth) { /* if qop, and qop=auth-int */ - Octstr *y; - m_qop = "auth-int"; + /* Make A2. */ + x = octstr_format("%s:%S", + http_method2name(method), + h->path); + if (qop != NULL && has_auth_int && !has_auth) { /* if qop, and qop=auth-int */ + Octstr *y; + m_qop = "auth-int"; - y = md5(body); - octstr_binary_to_hex(y,0); + y = md5(body); + octstr_binary_to_hex(y,0); - octstr_append_char(x, ':'); - octstr_append(x, y); + octstr_append_char(x, ':'); + octstr_append(x, y); - octstr_destroy(y); - } else if (qop) - m_qop = "auth"; + octstr_destroy(y); + } else if (qop) + m_qop = "auth"; - A2 = md5(x); - octstr_destroy(x); - octstr_binary_to_hex(A2,0); + A2 = md5(x); + octstr_destroy(x); + octstr_binary_to_hex(A2,0); - /* Finally make the digest response */ - if (qop) - x = octstr_format("%S:%S:%s:%S:%s:%S", - A1, nonce, nonce_count, cnonce, - m_qop, A2); - else - x = octstr_format("%S:%S:%S", A1, nonce, A2); + /* Finally make the digest response */ + if (qop) + x = octstr_format("%S:%S:%s:%S:%s:%S", + A1, nonce, nonce_count, cnonce, + m_qop, A2); + else + x = octstr_format("%S:%S:%S", A1, nonce, A2); - rd = md5(x); - octstr_destroy(x); - octstr_binary_to_hex(rd, 0); + rd = md5(x); + octstr_destroy(x); + octstr_binary_to_hex(rd, 0); - /* make the header value */ - x = octstr_format("Digest username=\"%S\", realm=\"%S\", response=\"%S\", nonce=\"%S\", uri=\"%S\"", - h->user, realm, rd, nonce, h->path); + /* make the header value */ + x = octstr_format("Digest username=\"%S\", realm=\"%S\", response=\"%S\", nonce=\"%S\", uri=\"%S\"", + h->user, realm, rd, nonce, h->path); - if (opaque) - octstr_format_append(x, ", opaque=\"%S\"", opaque); + if (opaque) + octstr_format_append(x, ", opaque=\"%S\"", opaque); - if (cnonce) - octstr_format_append(x, ", cnonce=\"%S\", nc=%s", cnonce, nonce_count); - if (m_qop) - octstr_format_append(x,", qop=%s", m_qop); - if (algo) - octstr_format_append(x,", algorithm=%S", algo); + if (cnonce) + octstr_format_append(x, ", cnonce=\"%S\", nc=%s", cnonce, nonce_count); + if (m_qop) + octstr_format_append(x,", qop=%s", m_qop); + if (algo) + octstr_format_append(x,", algorithm=%S", algo); - http_header_remove_all(request_headers, "Authorization"); - http_header_add(request_headers, "Authorization", octstr_get_cstr(x)); - octstr_destroy(x); + http_header_remove_all(request_headers, "Authorization"); + http_header_add(request_headers, "Authorization", octstr_get_cstr(x)); + octstr_destroy(x); - /* Remove username, password, then remake URL */ - octstr_destroy(h->user); - h->user = NULL; + /* Remove username, password, then remake URL */ + octstr_destroy(h->user); + h->user = NULL; - octstr_destroy(h->pass); - h->pass = NULL; + octstr_destroy(h->pass); + h->pass = NULL; - xurl = make_url(h); - x = NULL; - http_start_request(c, method, xurl, request_headers, body, 1, NULL, NULL); - if (http_receive_result_real(c, &status, &x, reply_headers, reply_body,1) == NULL) - status = -1; - if (x) - octstr_destroy(x); + xurl = make_url(h); + x = NULL; + http_start_request(c, method, xurl, request_headers, body, 1, NULL, NULL); + if (http_receive_result_real(c, &status, &x, reply_headers, reply_body,1) == NULL) + status = -1; + if (x) + octstr_destroy(x); done: - octstr_destroy(xauth_value); - octstr_destroy(realm); - octstr_destroy(domain); - octstr_destroy(nonce); - octstr_destroy(opaque); - octstr_destroy(algo); - octstr_destroy(xurl); - octstr_destroy(cnonce); - gwlist_destroy(qop, (gwlist_item_destructor_t *)octstr_destroy); - if (h) - http_urlparse_destroy(h); + octstr_destroy(xauth_value); + octstr_destroy(realm); + octstr_destroy(domain); + octstr_destroy(nonce); + octstr_destroy(opaque); + octstr_destroy(algo); + octstr_destroy(xurl); + octstr_destroy(cnonce); + gwlist_destroy(qop, (gwlist_item_destructor_t *)octstr_destroy); + if (h) + http_urlparse_destroy(h); - return status; + return status; } static Octstr *make_url(HTTPURLParse *h) { - Octstr *url = octstr_duplicate(h->scheme); + Octstr *url = octstr_duplicate(h->scheme); - if (h->user) { - octstr_format_append(url, "%S", h->user); + if (h->user) { + octstr_format_append(url, "%S", h->user); - if (h->pass) - octstr_format_append(url, ":%S", h->pass); - octstr_format_append(url, "@"); - } - octstr_format_append(url, "%S:%d%S", h->host, h->port, h->path); + if (h->pass) + octstr_format_append(url, ":%S", h->pass); + octstr_format_append(url, "@"); + } + octstr_format_append(url, "%S:%d%S", h->host, h->port, h->path); - if (h->query) - octstr_format_append(url, "?%S", h->query); + if (h->query) + octstr_format_append(url, "?%S", h->query); - if (h->fragment) - octstr_format_append(url, "#%S", h->fragment); - return url; + if (h->fragment) + octstr_format_append(url, "#%S", h->fragment); + return url; } static int is_separator_char(int c) { - switch (c) { - case '(': - case ')': - case '<': - case '>': - case '@': - case ',': - case ';': - case ':': - case '\\': - case '"': - case '/': - case '[': - case ']': - case '?': - case '=': - case '{': - case '}': - case 32: /* SP */ - case 9: /* HT */ - return 1; - default: - return 0; - } + switch (c) { + case '(': + case ')': + case '<': + case '>': + case '@': + case ',': + case ';': + case ':': + case '\\': + case '"': + case '/': + case '[': + case ']': + case '?': + case '=': + case '{': + case '}': + case 32: /* SP */ + case 9: /* HT */ + return 1; + default: + return 0; + } } /* Is this char part of a 'token' as defined by HTTP? */ static int is_token_char(int c) { - return c >= 32 && c < 127 && !is_separator_char(c); + return c >= 32 && c < 127 && !is_separator_char(c); } /* Is this string a 'token' as defined by HTTP? */ int mms_is_token(Octstr *token) { - return octstr_len(token) > 0 && - octstr_check_range(token, 0, octstr_len(token), is_token_char); + return octstr_len(token) > 0 && + octstr_check_range(token, 0, octstr_len(token), is_token_char); } int has_node_children(xmlNodePtr node) { - xmlNodePtr x; + xmlNodePtr x; - for (x = node->xmlChildrenNode; x; x = x->next) - if (x->type == XML_ELEMENT_NODE) - return 1; - return 0; + for (x = node->xmlChildrenNode; x; x = x->next) + if (x->type == XML_ELEMENT_NODE) + return 1; + return 0; } /* strip all but content-type, content-id, content-transfer-disposition, content-location */ void strip_non_essential_headers(MIMEEntity *mime) { - Octstr *v; - List *h, *h2; + Octstr *v; + List *h, *h2; - if (!mime) return; + if (!mime) return; - h = mime_entity_headers(mime); - h2 = http_create_empty_headers(); + h = mime_entity_headers(mime); + h2 = http_create_empty_headers(); - if ((v = http_header_value(h, octstr_imm("Content-Type"))) != NULL) { - http_header_add(h2, "Content-Type", octstr_get_cstr(v)); - octstr_destroy(v); - } + if ((v = http_header_value(h, octstr_imm("Content-Type"))) != NULL) { + http_header_add(h2, "Content-Type", octstr_get_cstr(v)); + octstr_destroy(v); + } - if ((v = http_header_value(h, octstr_imm("Content-ID"))) != NULL) { - http_header_add(h2, "Content-ID", octstr_get_cstr(v)); - octstr_destroy(v); - } + if ((v = http_header_value(h, octstr_imm("Content-ID"))) != NULL) { + http_header_add(h2, "Content-ID", octstr_get_cstr(v)); + octstr_destroy(v); + } - if ((v = http_header_value(h, octstr_imm("Content-Location"))) != NULL) { - http_header_add(h2, "Content-Location", octstr_get_cstr(v)); - octstr_destroy(v); - } + if ((v = http_header_value(h, octstr_imm("Content-Location"))) != NULL) { + http_header_add(h2, "Content-Location", octstr_get_cstr(v)); + octstr_destroy(v); + } - if ((v = http_header_value(h, octstr_imm("Content-Transfer-Encoding"))) != NULL) { - http_header_add(h2, "Content-Transfer-Encoding", octstr_get_cstr(v)); - octstr_destroy(v); - } + if ((v = http_header_value(h, octstr_imm("Content-Transfer-Encoding"))) != NULL) { + http_header_add(h2, "Content-Transfer-Encoding", octstr_get_cstr(v)); + octstr_destroy(v); + } - mime_replace_headers(mime,h2); - http_destroy_headers(h); - http_destroy_headers(h2); + mime_replace_headers(mime,h2); + http_destroy_headers(h); + http_destroy_headers(h2); } void *_mms_load_module(mCfg *cfg, mCfgGrp *grp, char *config_key, char *symbolname, - void *shell_builtin) + void *shell_builtin) { - Octstr *s = NULL; - void *retval = NULL; + Octstr *s = NULL; + void *retval = NULL; - s = mms_cfg_get(cfg, grp, octstr_imm(config_key)); + s = mms_cfg_get(cfg, grp, octstr_imm(config_key)); - if (s) { - void *x; - void *y = NULL; + if (s) { + void *x; + void *y = NULL; #ifdef __APPLE__ - char sbuf[512]; + char sbuf[512]; #endif - /* First look for the builtin: keyword. - * For now only builtin:shell is supported. - */ - if (octstr_case_search(s, octstr_imm("builtin:shell"), 0) >= 0) - retval = shell_builtin; - else { - x = dlopen(octstr_get_cstr(s), RTLD_LAZY); + /* First look for the builtin: keyword. + * For now only builtin:shell is supported. + */ + if (octstr_case_search(s, octstr_imm("builtin:shell"), 0) >= 0) + retval = shell_builtin; + else { + x = dlopen(octstr_get_cstr(s), RTLD_LAZY); #ifdef __APPLE__ - sprintf(sbuf, "_%s", symbolname); + sprintf(sbuf, "_%s", symbolname); #endif - if (x == NULL || ((y = dlsym(x, symbolname)) == NULL + if (x == NULL || ((y = dlsym(x, symbolname)) == NULL #ifdef __APPLE__ /* fink version of dlsym has issues it seems. */ - && (y = dlsym(x, sbuf)) == NULL + && (y = dlsym(x, sbuf)) == NULL #endif )) - panic(0, "Unable to load dynamic libary (%s): %s", - octstr_get_cstr(s), - dlerror()); - else - retval = y; - } - octstr_destroy(s); - } + panic(0, "Unable to load dynamic libary (%s): %s", + octstr_get_cstr(s), + dlerror()); + else + retval = y; + } + octstr_destroy(s); + } - return retval; + return retval; } Octstr *extract_phonenum(Octstr *num, Octstr *unified_prefix) { - Octstr *phonenum; - int j = octstr_case_search(num, octstr_imm("/TYPE=PLMN"), 0); + Octstr *phonenum; + int j = octstr_case_search(num, octstr_imm("/TYPE=PLMN"), 0); - if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == octstr_len(num)) - phonenum = octstr_copy(num, 0, j); - else - phonenum = octstr_duplicate(num); + if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == octstr_len(num)) + phonenum = octstr_copy(num, 0, j); + else + phonenum = octstr_duplicate(num); - if (unified_prefix) - normalize_number(octstr_get_cstr(unified_prefix), &phonenum); + if (unified_prefix) + normalize_number(octstr_get_cstr(unified_prefix), &phonenum); - return phonenum; + return phonenum; } void strip_quoted_string(Octstr *s) { - if (s == NULL) return; + if (s == NULL) return; - octstr_strip_blanks(s); - if (octstr_get_char(s, 0) == '"') { - octstr_delete(s, 0, 1); - octstr_delete(s, octstr_len(s)-1, 1); - } + octstr_strip_blanks(s); + if (octstr_get_char(s, 0) == '"') { + octstr_delete(s, 0, 1); + octstr_delete(s, octstr_len(s)-1, 1); + } } MIMEEntity *make_multipart_formdata(void) { - MIMEEntity *x = mime_entity_create(); - List *rh = http_create_empty_headers(); + MIMEEntity *x = mime_entity_create(); + List *rh = http_create_empty_headers(); - http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); - http_header_add(rh, "Accept", "*/*"); - http_header_add(rh, "Content-Type", "multipart/form-data"); - mime_replace_headers(x, rh); - http_destroy_headers(rh); + http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); + http_header_add(rh, "Accept", "*/*"); + http_header_add(rh, "Content-Type", "multipart/form-data"); + mime_replace_headers(x, rh); + http_destroy_headers(rh); - return x; + return x; } void add_multipart_form_field(MIMEEntity *multipart, char *field_name, char *ctype, char *content_loc, - Octstr *data) + Octstr *data) { - MIMEEntity *p = mime_entity_create(); - List *xh = http_create_empty_headers(); - Octstr *cd = octstr_format("form-data; name=\"%s\"", field_name); + MIMEEntity *p = mime_entity_create(); + List *xh = http_create_empty_headers(); + Octstr *cd = octstr_format("form-data; name=\"%s\"", field_name); - if (content_loc) - octstr_format_append(cd, "; filename=\"%s\"", content_loc); + if (content_loc) + octstr_format_append(cd, "; filename=\"%s\"", content_loc); - http_header_add(xh, "Content-Disposition", octstr_get_cstr(cd)); - if (ctype) /* This header must come after the above it seems. */ - http_header_add(xh, "Content-Type", ctype); + http_header_add(xh, "Content-Disposition", octstr_get_cstr(cd)); + if (ctype) /* This header must come after the above it seems. */ + http_header_add(xh, "Content-Type", ctype); - mime_entity_set_body(p, data); - mime_replace_headers(p, xh); + mime_entity_set_body(p, data); + mime_replace_headers(p, xh); - mime_entity_add_part(multipart, p); /* add it to list so far. */ + mime_entity_add_part(multipart, p); /* add it to list so far. */ - mime_entity_destroy(p); - http_destroy_headers(xh); - octstr_destroy(cd); + mime_entity_destroy(p); + http_destroy_headers(xh); + octstr_destroy(cd); } MIMEEntity *multipart_from_urls(List *url_list) { - int i, n; - List *rh = http_create_empty_headers(); - MIMEEntity *m = mime_entity_create(); + int i, n; + List *rh = http_create_empty_headers(); + MIMEEntity *m = mime_entity_create(); - http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); - for (i = 0, n = gwlist_len(url_list); i= 0) { Octstr *x = octstr_format("%S %S", transid ? transid : octstr_imm("x"), dlr_url); /* better have no spaces in transid! */ octstr_write_data(x, fd, 0); - close(fd); + unlock_and_close(fd); octstr_destroy(x); } } @@ -106,7 +106,7 @@ int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_u Octstr *s = octstr_read_pipe(f); int i, ret; - fclose(f); + unlock_and_fclose(f); if (s && octstr_len(s) == 0) { ret = -1; } else if ((i = octstr_search_char(s, ' ', 0)) >= 0) { @@ -118,7 +118,7 @@ int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_u octstr_destroy(s); return ret; } else if (fd >= 0) - close(fd); + unlock_and_close(fd); return -1; } @@ -132,6 +132,6 @@ void mms_dlr_url_remove(Octstr *msgid, char *rtype, Octstr *mmc_gid) octstr_destroy(fname); } if (fd >= 0) - close(fd); + unlock_and_close(fd); } diff --git a/mbuni/mmsbox/mmsbox.c b/mbuni/mmsbox/mmsbox.c index 738806d..fdb9a37 100644 --- a/mbuni/mmsbox/mmsbox.c +++ b/mbuni/mmsbox/mmsbox.c @@ -31,78 +31,78 @@ int rstop = 0; static void quit_now(int notused) { - rstop = 1; + rstop = 1; - mms_info(0, "mmsbox", NULL, "shutdown in progress..."); - /* Close all MMSC http ports, kill all MMSC threads, kill sendmms port... */ - if (sendmms_port.port > 0) - http_close_port(sendmms_port.port); + mms_info(0, "mmsbox", NULL, "shutdown in progress..."); + /* Close all MMSC http ports, kill all MMSC threads, kill sendmms port... */ + if (sendmms_port.port > 0) + http_close_port(sendmms_port.port); - mmsbox_stop_all_mmsc_conn(); + mmsbox_stop_all_mmsc_conn(); } /* manage the SIGHUP signal */ static void relog_now(int notused) { - mms_warning(0, "mmsbox", NULL, "SIGHUP received, catching and re-opening logs"); - log_reopen(); - alog_reopen(); + mms_warning(0, "mmsbox", NULL, "SIGHUP received, catching and re-opening logs"); + log_reopen(); + alog_reopen(); } /* Finds text part, returns copy. */ static MIMEEntity *find_textpart(MIMEEntity *m) { - Octstr *ctype = NULL, *params = NULL; - MIMEEntity *res = NULL; - List *headers; - int i, n; + Octstr *ctype = NULL, *params = NULL; + MIMEEntity *res = NULL; + List *headers; + int i, n; - if (!m) return NULL; + if (!m) return NULL; - headers = mime_entity_headers(m); - get_content_type(headers, &ctype, ¶ms); - http_destroy_headers(headers); + headers = mime_entity_headers(m); + get_content_type(headers, &ctype, ¶ms); + http_destroy_headers(headers); - if (ctype && octstr_str_compare(ctype, "text/plain") == 0) { - res = mime_entity_duplicate(m); - goto done; - } + if (ctype && octstr_str_compare(ctype, "text/plain") == 0) { + res = mime_entity_duplicate(m); + goto done; + } - if ((n = mime_entity_num_parts(m)) > 0) { - for (i = 0; i < n; i++) { - MIMEEntity *x = mime_entity_get_part(m, i); - res = find_textpart(x); - mime_entity_destroy(x); + if ((n = mime_entity_num_parts(m)) > 0) { + for (i = 0; i < n; i++) { + MIMEEntity *x = mime_entity_get_part(m, i); + res = find_textpart(x); + mime_entity_destroy(x); - if (res != NULL) - goto done2; - } - } -done: - if (res) { /* We got it! Convert charset if needed. */ - List *params_h = get_value_parameters(params); - Octstr *charset = http_header_value(params_h, octstr_imm("charset")); - Octstr *body = mime_entity_body(res); - if (charset == NULL || - octstr_str_compare(charset, "unknown") == 0) { - octstr_destroy(charset); - charset = octstr_create(DEFAULT_CHARSET); - } + if (res != NULL) + goto done2; + } + } + done: + if (res) { /* We got it! Convert charset if needed. */ + List *params_h = get_value_parameters(params); + Octstr *charset = http_header_value(params_h, octstr_imm("charset")); + Octstr *body = mime_entity_body(res); + if (charset == NULL || + octstr_str_compare(charset, "unknown") == 0) { + octstr_destroy(charset); + charset = octstr_create(DEFAULT_CHARSET); + } - if (octstr_str_case_compare(charset, DEFAULT_CHARSET) != 0) { - charset_convert(body, DEFAULT_CHARSET, octstr_get_cstr(charset)); /* XXX error ignored? */ - mime_entity_set_body(res, body); - } - octstr_destroy(body); - http_destroy_headers(params_h); - octstr_destroy(charset); - } + if (octstr_str_case_compare(charset, DEFAULT_CHARSET) != 0) { + charset_convert(body, DEFAULT_CHARSET, octstr_get_cstr(charset)); /* XXX error ignored? */ + mime_entity_set_body(res, body); + } + octstr_destroy(body); + http_destroy_headers(params_h); + octstr_destroy(charset); + } -done2: + done2: - octstr_destroy(ctype); - octstr_destroy(params); - return res; + octstr_destroy(ctype); + octstr_destroy(params); + return res; } @@ -112,66 +112,66 @@ done2: static Octstr *get_keyword(MIMEEntity *me) { - MIMEEntity *t = find_textpart(me); - Octstr *txt = t ? mime_entity_body(t) : NULL; - List *l = t ? octstr_split_words(txt) : NULL; - Octstr *keyword = l ? gwlist_extract_first(l) : NULL; + MIMEEntity *t = find_textpart(me); + Octstr *txt = t ? mime_entity_body(t) : NULL; + List *l = t ? octstr_split_words(txt) : NULL; + Octstr *keyword = l ? gwlist_extract_first(l) : NULL; - if (t) - mime_entity_destroy(t); - gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy); - octstr_destroy(txt); + if (t) + mime_entity_destroy(t); + gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy); + octstr_destroy(txt); - return keyword; + return keyword; } static int _x_octstr_comp(Octstr *x, Octstr *y) { - return (octstr_case_compare(x,y) == 0); + return (octstr_case_compare(x,y) == 0); } static MmsService *get_service(Octstr *keyword, Octstr *mmc_id, Octstr *receiver) { - int i, n; - MmsService *catch_all = NULL; - Octstr *phonenum = receiver ? extract_phonenum(receiver, NULL) : NULL; + int i, n; + MmsService *catch_all = NULL; + Octstr *phonenum = receiver ? extract_phonenum(receiver, NULL) : NULL; - for (i = 0, n = gwlist_len(mms_services); i < n; i++) { - MmsService *ms = gwlist_get(mms_services,i); + for (i = 0, n = gwlist_len(mms_services); i < n; i++) { + MmsService *ms = gwlist_get(mms_services,i); - /* Check that mmc_id is allowed: - * denied list is not null and we are on it, or allowed list is not null and we - * are *not* on it. - */ - if (ms->denied_mmscs && - gwlist_search(ms->denied_mmscs, mmc_id, (gwlist_item_matches_t *)_x_octstr_comp) != NULL) - continue; + /* Check that mmc_id is allowed: + * denied list is not null and we are on it, or allowed list is not null and we + * are *not* on it. + */ + if (ms->denied_mmscs && + gwlist_search(ms->denied_mmscs, mmc_id, (gwlist_item_matches_t *)_x_octstr_comp) != NULL) + continue; - if (ms->allowed_mmscs && - gwlist_search(ms->allowed_mmscs, mmc_id, (gwlist_item_matches_t *)_x_octstr_comp) == NULL) - continue; + if (ms->allowed_mmscs && + gwlist_search(ms->allowed_mmscs, mmc_id, (gwlist_item_matches_t *)_x_octstr_comp) == NULL) + continue; - if (ms->denied_receiver_prefix && phonenum && - does_prefix_match(ms->denied_receiver_prefix, phonenum) != 0) - continue; + if (ms->denied_receiver_prefix && phonenum && + does_prefix_match(ms->denied_receiver_prefix, phonenum) != 0) + continue; - if (ms->allowed_receiver_prefix && phonenum && - does_prefix_match(ms->allowed_receiver_prefix, phonenum) == 0) - continue; + if (ms->allowed_receiver_prefix && phonenum && + does_prefix_match(ms->allowed_receiver_prefix, phonenum) == 0) + continue; - if (keyword && - gwlist_search(ms->keywords, keyword, - (gwlist_item_matches_t *)_x_octstr_comp) != NULL) { - octstr_destroy(phonenum); - return ms; - } + if (keyword && + gwlist_search(ms->keywords, keyword, + (gwlist_item_matches_t *)_x_octstr_comp) != NULL) { + octstr_destroy(phonenum); + return ms; + } - if (ms->isdefault && catch_all == NULL) /* We also find the catch-all for this sender. */ - catch_all = ms; - } + if (ms->isdefault && catch_all == NULL) /* We also find the catch-all for this sender. */ + catch_all = ms; + } - octstr_destroy(phonenum); - return catch_all; + octstr_destroy(phonenum); + return catch_all; } static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm, @@ -179,129 +179,129 @@ static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm, MIMEEntity *me, MmsMsg *msg, int lev, int count) { - int i, n; - List *headers = NULL; - Octstr *data = NULL, *ctype = NULL, *xctype = NULL, *params = NULL; - Octstr *s; + int i, n; + List *headers = NULL; + Octstr *data = NULL, *ctype = NULL, *xctype = NULL, *params = NULL; + Octstr *s; - headers = mime_entity_headers(me); - if (pm->type == WHOLE_BINARY && lev == 0) { - data = mms_tobinary(msg); - ctype = octstr_create("application/vnd.wap.mms-message"); - } else if (pm->type == NO_PART && lev == 0) { - data = octstr_create(""); /* We'll add value below. */ - goto done; - } else if (pm->type == KEYWORD_PART && lev == 0) { - data = keyword ? octstr_duplicate(keyword) : octstr_create(""); - ctype = octstr_create("text/plain"); - goto done; - } + headers = mime_entity_headers(me); + if (pm->type == WHOLE_BINARY && lev == 0) { + data = mms_tobinary(msg); + ctype = octstr_create("application/vnd.wap.mms-message"); + } else if (pm->type == NO_PART && lev == 0) { + data = octstr_create(""); /* We'll add value below. */ + goto done; + } else if (pm->type == KEYWORD_PART && lev == 0) { + data = keyword ? octstr_duplicate(keyword) : octstr_create(""); + ctype = octstr_create("text/plain"); + goto done; + } - if ((n = mime_entity_num_parts(me)) > 0) { /* Recurse over multi-parts. */ - for (i = 0; i < n; i++) { - MIMEEntity *x = mime_entity_get_part(me,i); - add_all_matching_parts(plist, pm, NULL, x, msg, lev+1,i); - mime_entity_destroy(x); - } - goto done; - } + if ((n = mime_entity_num_parts(me)) > 0) { /* Recurse over multi-parts. */ + for (i = 0; i < n; i++) { + MIMEEntity *x = mime_entity_get_part(me,i); + add_all_matching_parts(plist, pm, NULL, x, msg, lev+1,i); + mime_entity_destroy(x); + } + goto done; + } - get_content_type(headers, &xctype, ¶ms); + get_content_type(headers, &xctype, ¶ms); #define BEGINSWITH(s, prefix) (octstr_case_search(s, octstr_imm(prefix),0) == 0) -#define TYPE_MATCH(typ, prefix) ((pm->type) == (typ) && \ +#define TYPE_MATCH(typ, prefix) ((pm->type) == (typ) && \ BEGINSWITH(xctype, prefix)) - if (xctype) - if (TYPE_MATCH(IMAGE_PART,"image/") || - TYPE_MATCH(AUDIO_PART,"audio/") || - TYPE_MATCH(VIDEO_PART,"video/") || - TYPE_MATCH(TEXT_PART,"text/") || - TYPE_MATCH(SMIL_PART,"application/smil") || - pm->type == ANY_PART || /* Skip top-level for 'any' parts. */ - (pm->type == OTHER_PART && - (!BEGINSWITH(xctype, "text/") && - !BEGINSWITH(xctype, "video/") && - !BEGINSWITH(xctype, "image/") && - !BEGINSWITH(xctype, "application/smil")))) { + if (xctype) + if (TYPE_MATCH(IMAGE_PART,"image/") || + TYPE_MATCH(AUDIO_PART,"audio/") || + TYPE_MATCH(VIDEO_PART,"video/") || + TYPE_MATCH(TEXT_PART,"text/") || + TYPE_MATCH(SMIL_PART,"application/smil") || + pm->type == ANY_PART || /* Skip top-level for 'any' parts. */ + (pm->type == OTHER_PART && + (!BEGINSWITH(xctype, "text/") && + !BEGINSWITH(xctype, "video/") && + !BEGINSWITH(xctype, "image/") && + !BEGINSWITH(xctype, "application/smil")))) { - ctype = http_header_value(headers, octstr_imm("Content-Type")); - data = mime_entity_body(me); - } + ctype = http_header_value(headers, octstr_imm("Content-Type")); + data = mime_entity_body(me); + } -done: - if (data) { - MIMEEntity *p = mime_entity_create(); - Octstr *cd = octstr_format("form-data; name=\"%S\"", pm->name); - List *xh; + done: + if (data) { + MIMEEntity *p = mime_entity_create(); + Octstr *cd = octstr_format("form-data; name=\"%S\"", pm->name); + List *xh; - if (ctype && pm->type != KEYWORD_PART) { - /* If Content-Location header or name (content-type) parameter given, pass it as filename. */ - Octstr *c = NULL, *q = NULL; - Octstr *cloc = http_header_value(headers, - octstr_imm("Content-Location")); - split_header_value(ctype, &c, &q); + if (ctype && pm->type != KEYWORD_PART) { + /* If Content-Location header or name (content-type) parameter given, pass it as filename. */ + Octstr *c = NULL, *q = NULL; + Octstr *cloc = http_header_value(headers, + octstr_imm("Content-Location")); + split_header_value(ctype, &c, &q); - if (q || cloc) { - List *ph = q ? get_value_parameters(q) : http_create_empty_headers(); - Octstr *v = cloc ? cloc : http_header_value(ph, octstr_imm("name")); + if (q || cloc) { + List *ph = q ? get_value_parameters(q) : http_create_empty_headers(); + Octstr *v = cloc ? cloc : http_header_value(ph, octstr_imm("name")); - if (!v) /* make up a fake name if none is given */ - v = octstr_format("part-%d-%d", lev, count); + if (!v) /* make up a fake name if none is given */ + v = octstr_format("part-%d-%d", lev, count); - octstr_format_append(cd, "; filename=\"%S\"", v); - http_header_remove_all(ph, "name"); + octstr_format_append(cd, "; filename=\"%S\"", v); + http_header_remove_all(ph, "name"); - if (v != cloc) - octstr_destroy(v); - octstr_destroy(ctype); + if (v != cloc) + octstr_destroy(v); + octstr_destroy(ctype); - v = make_value_parameters(ph); - if (v && octstr_len(v) > 0) - ctype = octstr_format("%S; %S", c, v); - else - ctype = octstr_duplicate(c); + v = make_value_parameters(ph); + if (v && octstr_len(v) > 0) + ctype = octstr_format("%S; %S", c, v); + else + ctype = octstr_duplicate(c); - octstr_destroy(v); + octstr_destroy(v); - http_destroy_headers(ph); + http_destroy_headers(ph); - octstr_destroy(q); - } + octstr_destroy(q); + } - octstr_destroy(c); - octstr_destroy(cloc); - } + octstr_destroy(c); + octstr_destroy(cloc); + } - xh = http_create_empty_headers(); - http_header_add(xh, "Content-Disposition", octstr_get_cstr(cd)); - if (ctype) /* This header must come after the above it seems. */ - http_header_add(xh, "Content-Type", octstr_get_cstr(ctype)); + xh = http_create_empty_headers(); + http_header_add(xh, "Content-Disposition", octstr_get_cstr(cd)); + if (ctype) /* This header must come after the above it seems. */ + http_header_add(xh, "Content-Type", octstr_get_cstr(ctype)); - mime_replace_headers(p, xh); - http_destroy_headers(xh); + mime_replace_headers(p, xh); + http_destroy_headers(xh); - s = octstr_duplicate(data); /* data for the parameter */ - if (pm->value) /* add value part as needed. */ - octstr_append(s, pm->value); - mime_entity_set_body(p, s); - octstr_destroy(s); + s = octstr_duplicate(data); /* data for the parameter */ + if (pm->value) /* add value part as needed. */ + octstr_append(s, pm->value); + mime_entity_set_body(p, s); + octstr_destroy(s); #if 0 - base64_mimeparts(p); + base64_mimeparts(p); #endif - mime_entity_add_part(plist, p); /* add it to list so far. */ - mime_entity_destroy(p); + mime_entity_add_part(plist, p); /* add it to list so far. */ + mime_entity_destroy(p); - octstr_destroy(cd); - } + octstr_destroy(cd); + } - octstr_destroy(xctype); - octstr_destroy(params); - octstr_destroy(ctype); - octstr_destroy(data); + octstr_destroy(xctype); + octstr_destroy(params); + octstr_destroy(ctype); + octstr_destroy(data); - http_destroy_headers(headers); + http_destroy_headers(headers); } enum _xurltype {FILE_TYPE, URL_TYPE}; @@ -322,186 +322,186 @@ static int fetch_serviceurl(MmsEnvelope *e, Octstr *keyword, Octstr **err) { - List *rh, *rph = NULL; - Octstr *body = NULL, *rb = NULL, *transid; - Octstr *ctype = NULL, *params = NULL; - Octstr *s; - int i, n, method, typ = FILE_TYPE; - FILE *fp = NULL; + List *rh, *rph = NULL; + Octstr *body = NULL, *rb = NULL, *transid; + Octstr *ctype = NULL, *params = NULL; + Octstr *s; + int i, n, method, typ = FILE_TYPE; + FILE *fp = NULL; - int res = -1; + int res = -1; - transid = mms_maketransid(e->xqfname, octstr_imm(MM_NAME)); - switch (ms->type) { - case TRANS_TYPE_GET_URL: - case TRANS_TYPE_POST_URL: - rh = http_create_empty_headers(); + transid = mms_maketransid(e->xqfname, octstr_imm(MM_NAME)); + switch (ms->type) { + case TRANS_TYPE_GET_URL: + case TRANS_TYPE_POST_URL: + rh = http_create_empty_headers(); - http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); - /* Put in some useful headers. */ - if (e->msgId) - http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(e->msgId)); - if (e->fromproxy) - http_header_add(rh, "X-Mbuni-MMSC-ID", octstr_get_cstr(e->fromproxy)); - if (e->token) - http_header_add(rh, "X-Mbuni-LinkedID", octstr_get_cstr(e->token)); - if (e->from) { - Octstr *xfrom = octstr_duplicate(e->from); + http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); + /* Put in some useful headers. */ + if (e->msgId) + http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(e->msgId)); + if (e->fromproxy) + http_header_add(rh, "X-Mbuni-MMSC-ID", octstr_get_cstr(e->fromproxy)); + if (e->token) + http_header_add(rh, "X-Mbuni-LinkedID", octstr_get_cstr(e->token)); + if (e->from) { + Octstr *xfrom = octstr_duplicate(e->from); - _mms_fixup_address(&xfrom, unified_prefix ? octstr_get_cstr(unified_prefix) : NULL, - strip_prefixes, 0); - http_header_add(rh, "X-Mbuni-From", octstr_get_cstr(xfrom)); - octstr_destroy(xfrom); - } - if (e->subject) - http_header_add(rh, "X-Mbuni-Subject", octstr_get_cstr(e->subject)); + _mms_fixup_address(&xfrom, unified_prefix ? octstr_get_cstr(unified_prefix) : NULL, + strip_prefixes, 0); + http_header_add(rh, "X-Mbuni-From", octstr_get_cstr(xfrom)); + octstr_destroy(xfrom); + } + if (e->subject) + http_header_add(rh, "X-Mbuni-Subject", octstr_get_cstr(e->subject)); - /* Put in a transaction ID. */ - http_header_add(rh, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); + /* Put in a transaction ID. */ + http_header_add(rh, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); - for (i = 0, n = gwlist_len(e->to); i < n; i++) { - MmsEnvelopeTo *r = gwlist_get(e->to, i); - if (r && r->rcpt) { - Octstr *xto = octstr_duplicate(r->rcpt); - _mms_fixup_address(&xto, unified_prefix ? octstr_get_cstr(unified_prefix) : NULL, - strip_prefixes, 0); - http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(xto)); - octstr_destroy(xto); - } - } + for (i = 0, n = gwlist_len(e->to); i < n; i++) { + MmsEnvelopeTo *r = gwlist_get(e->to, i); + if (r && r->rcpt) { + Octstr *xto = octstr_duplicate(r->rcpt); + _mms_fixup_address(&xto, unified_prefix ? octstr_get_cstr(unified_prefix) : NULL, + strip_prefixes, 0); + http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(xto)); + octstr_destroy(xto); + } + } - if ((s = http_header_value(e->hdrs, octstr_imm("X-Mbuni-UAProf"))) != NULL) { /* add UAProf info, if any. */ - Octstr *sx = http_header_value(e->hdrs,octstr_imm("X-Mbuni-Timestamp")); - http_header_add(rh, "X-Mbuni-UAProf", octstr_get_cstr(s)); - if (sx) - http_header_add(rh, "X-Mbuni-Timestamp", octstr_get_cstr(sx)); - octstr_destroy(sx); - octstr_destroy(s); - } + if ((s = http_header_value(e->hdrs, octstr_imm("X-Mbuni-UAProf"))) != NULL) { /* add UAProf info, if any. */ + Octstr *sx = http_header_value(e->hdrs,octstr_imm("X-Mbuni-Timestamp")); + http_header_add(rh, "X-Mbuni-UAProf", octstr_get_cstr(s)); + if (sx) + http_header_add(rh, "X-Mbuni-Timestamp", octstr_get_cstr(sx)); + octstr_destroy(sx); + octstr_destroy(s); + } - if ((s = mms_get_header_value(m, octstr_imm("Date"))) != NULL) { - http_header_add(rh, "X-Mbuni-Message-Date", octstr_get_cstr(s)); - octstr_destroy(s); - } + if ((s = mms_get_header_value(m, octstr_imm("Date"))) != NULL) { + http_header_add(rh, "X-Mbuni-Message-Date", octstr_get_cstr(s)); + octstr_destroy(s); + } - s = date_format_http(e->created); - http_header_add(rh, "X-Mbuni-Received-Date", octstr_get_cstr(s)); - octstr_destroy(s); + s = date_format_http(e->created); + http_header_add(rh, "X-Mbuni-Received-Date", octstr_get_cstr(s)); + octstr_destroy(s); - if (ms->type == TRANS_TYPE_POST_URL) { /* Put in the parameters. */ - MIMEEntity *x = mime_entity_create(); + if (ms->type == TRANS_TYPE_POST_URL) { /* Put in the parameters. */ + MIMEEntity *x = mime_entity_create(); - http_header_add(rh, "Content-Type", "multipart/form-data"); - mime_replace_headers(x, rh); - http_destroy_headers(rh); + http_header_add(rh, "Content-Type", "multipart/form-data"); + mime_replace_headers(x, rh); + http_destroy_headers(rh); - for (i = 0, n = gwlist_len(ms->params); i < n; i++) { - MmsServiceUrlParam *p = gwlist_get(ms->params, i); - add_all_matching_parts(x, p, keyword, msg, m, 0, i); - } + for (i = 0, n = gwlist_len(ms->params); i < n; i++) { + MmsServiceUrlParam *p = gwlist_get(ms->params, i); + add_all_matching_parts(x, p, keyword, msg, m, 0, i); + } - body = mime_entity_body(x); - rh = mime_entity_headers(x); + body = mime_entity_body(x); + rh = mime_entity_headers(x); - mime_entity_destroy(x); + mime_entity_destroy(x); - method = HTTP_METHOD_POST; - } else - method = HTTP_METHOD_GET; + method = HTTP_METHOD_POST; + } else + method = HTTP_METHOD_GET; - typ = URL_TYPE; - if (mmsbox_url_fetch_content(method, ms->url, rh, body, &rph, &rb) == HTTP_OK) { - get_content_type(rph, &ctype, ¶ms); - /* add transaction id back.*/ - http_header_remove_all(rph, "X-Mbuni-TransactionID"); - http_header_add(rph, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); - } else - *err = octstr_format("MMSBox: Failed to fetch content for Service %S, url %S!", - ms->name, ms->url); - http_destroy_headers(rh); - octstr_destroy(body); - break; - case TRANS_TYPE_FILE: - if ((fp = fopen(octstr_get_cstr(ms->url), "r")) != NULL) { - rb = octstr_read_pipe(fp); - fclose(fp); - ctype = filename2content_type(octstr_get_cstr(ms->url)); - } + typ = URL_TYPE; + if (mmsbox_url_fetch_content(method, ms->url, rh, body, &rph, &rb) == HTTP_OK) { + get_content_type(rph, &ctype, ¶ms); + /* add transaction id back.*/ + http_header_remove_all(rph, "X-Mbuni-TransactionID"); + http_header_add(rph, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); + } else + *err = octstr_format("MMSBox: Failed to fetch content for Service %S, url %S!", + ms->name, ms->url); + http_destroy_headers(rh); + octstr_destroy(body); + break; + case TRANS_TYPE_FILE: + if ((fp = fopen(octstr_get_cstr(ms->url), "r")) != NULL) { + rb = octstr_read_pipe(fp); + fclose(fp); + ctype = filename2content_type(octstr_get_cstr(ms->url)); + } - if (!rb) - *err = octstr_format("MMSBox: Failed to open file %S for service %S!", - ms->url, ms->name); - typ = FILE_TYPE; - break; - case TRANS_TYPE_EXEC: - if ((fp = popen(octstr_get_cstr(ms->url), "r+")) != NULL) { - Octstr *s = mime_entity_to_octstr(msg); - if (s) { /* Send the MMS to the exec program */ - octstr_print(fp, s); - fflush(fp); - octstr_destroy(s); - } - rb = octstr_read_pipe(fp); - ctype = octstr_create("application/smil"); - pclose(fp); - } - if (!rb) - *err = octstr_format("MMSBox: Failed to fetch content for Service %S, exec path = %S!", - ms->name, ms->url); - typ = FILE_TYPE; - break; - case TRANS_TYPE_TEXT: - rb = octstr_duplicate(ms->url); - ctype = octstr_create("text/plain"); - typ = URL_TYPE; - break; + if (!rb) + *err = octstr_format("MMSBox: Failed to open file %S for service %S!", + ms->url, ms->name); + typ = FILE_TYPE; + break; + case TRANS_TYPE_EXEC: + if ((fp = popen(octstr_get_cstr(ms->url), "r+")) != NULL) { + Octstr *s = mime_entity_to_octstr(msg); + if (s) { /* Send the MMS to the exec program */ + octstr_print(fp, s); + fflush(fp); + octstr_destroy(s); + } + rb = octstr_read_pipe(fp); + ctype = octstr_create("application/smil"); + pclose(fp); + } + if (!rb) + *err = octstr_format("MMSBox: Failed to fetch content for Service %S, exec path = %S!", + ms->name, ms->url); + typ = FILE_TYPE; + break; + case TRANS_TYPE_TEXT: + rb = octstr_duplicate(ms->url); + ctype = octstr_create("text/plain"); + typ = URL_TYPE; + break; - default: - *err = octstr_format(0, "MMSBOX: Unknown Service type for service %S!", ms->name); - break; - } + default: + *err = octstr_format(0, "MMSBOX: Unknown Service type for service %S!", ms->name); + break; + } - /* If we have the content, make the message and write it to out-going. - * if we have no content, or we have been told to suppress the reply, then we suppress - */ - if (!ctype || !rb || - (octstr_len(rb) == 0 && ms->omitempty) || - ms->noreply) { - mms_info(0, "mmsbox", NULL, "MMSBox.service_request: Suppressed reply for service %s, " - "suppress-reply=%s, omit-empty=%s, reply-len=%ld, content-type=%s", - octstr_get_cstr(ms->name), ms->noreply ? "true" : "false", - ms->omitempty ? "true" : "false", - rb ? octstr_len(rb) : 0, - ctype ? octstr_get_cstr(ctype) : ""); - goto done; - } else { - Octstr *base_url = url_path_prefix(ms->url, typ); + /* If we have the content, make the message and write it to out-going. + * if we have no content, or we have been told to suppress the reply, then we suppress + */ + if (!ctype || !rb || + (octstr_len(rb) == 0 && ms->omitempty) || + ms->noreply) { + mms_info(0, "mmsbox", NULL, "MMSBox.service_request: Suppressed reply for service %s, " + "suppress-reply=%s, omit-empty=%s, reply-len=%ld, content-type=%s", + octstr_get_cstr(ms->name), ms->noreply ? "true" : "false", + ms->omitempty ? "true" : "false", + rb ? octstr_len(rb) : 0, + ctype ? octstr_get_cstr(ctype) : ""); + goto done; + } else { + Octstr *base_url = url_path_prefix(ms->url, typ); - if (ms->special_header) { - if (rph == NULL) - rph = http_create_empty_headers(); - http_header_remove_all(rph, "X-Mbuni-Content-Header"); - http_header_add(rph, "X-Mbuni-Content-Header", octstr_get_cstr(ms->special_header)); - } - res = make_and_queue_msg(rb, ctype, rph, - ms->url, - base_url, - typ, e, ms->name, ms->faked_sender, ms->service_code, - ms->accept_x_headers, ms->passthro_headers, - outgoing_qdir, - err); + if (ms->special_header) { + if (rph == NULL) + rph = http_create_empty_headers(); + http_header_remove_all(rph, "X-Mbuni-Content-Header"); + http_header_add(rph, "X-Mbuni-Content-Header", octstr_get_cstr(ms->special_header)); + } + res = make_and_queue_msg(rb, ctype, rph, + ms->url, + base_url, + typ, e, ms->name, ms->faked_sender, ms->service_code, + ms->accept_x_headers, ms->passthro_headers, + outgoing_qdir, + err); - octstr_destroy(base_url); - } + octstr_destroy(base_url); + } -done: - octstr_destroy(ctype); - octstr_destroy(rb); - http_destroy_headers(rph); - octstr_destroy(params); - octstr_destroy(transid); + done: + octstr_destroy(ctype); + octstr_destroy(rb); + http_destroy_headers(rph); + octstr_destroy(params); + octstr_destroy(transid); - return res; + return res; } @@ -514,283 +514,294 @@ static int mmsbox_send_report(Octstr *from, char *report_type, Octstr *err, Octstr *statustxt, Octstr *details) { - List *rh = NULL, *rph = NULL; - Octstr *rb = NULL, *xfrom = from ? octstr_duplicate(from) : NULL; - int ret = HTTP_NOT_FOUND; + List *rh = NULL, *rph = NULL; + Octstr *rb = NULL, *xfrom = from ? octstr_duplicate(from) : NULL; + int ret = HTTP_NOT_FOUND; - if (xfrom) - _mms_fixup_address(&xfrom, unified_prefix ? octstr_get_cstr(unified_prefix) : NULL, - strip_prefixes, 0); + if (xfrom) + _mms_fixup_address(&xfrom, unified_prefix ? octstr_get_cstr(unified_prefix) : NULL, + strip_prefixes, 0); - rh = http_create_empty_headers(); + rh = http_create_empty_headers(); - http_header_add(rh, "X-Mbuni-Report-Type", report_type); - http_header_add(rh, "X-Mbuni-MM-Status", octstr_get_cstr(status)); - if (mmc_gid) - http_header_add(rh, "X-Mbuni-MMSC-GID", octstr_get_cstr(mmc_gid)); - http_header_add(rh, "X-Mbuni-MMSC-ID", octstr_get_cstr(mmc_id)); - if (xfrom) - http_header_add(rh, "X-Mbuni-From", octstr_get_cstr(xfrom)); + http_header_add(rh, "X-Mbuni-Report-Type", report_type); + http_header_add(rh, "X-Mbuni-MM-Status", octstr_get_cstr(status)); + if (mmc_gid) + http_header_add(rh, "X-Mbuni-MMSC-GID", octstr_get_cstr(mmc_gid)); + http_header_add(rh, "X-Mbuni-MMSC-ID", octstr_get_cstr(mmc_id)); + if (xfrom) + http_header_add(rh, "X-Mbuni-From", octstr_get_cstr(xfrom)); - if (orig_transid) - http_header_add(rh, "X-Mbuni-TransactionID", - octstr_get_cstr(orig_transid)); - if (msgid) - http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(msgid)); + if (orig_transid) + http_header_add(rh, "X-Mbuni-TransactionID", + octstr_get_cstr(orig_transid)); + if (msgid) + http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(msgid)); - if (orig_msgid) - http_header_add(rh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(orig_msgid)); + if (orig_msgid) + http_header_add(rh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(orig_msgid)); - if (err) - http_header_add(rh, "X-Mbuni-MM-Error", octstr_get_cstr(err)); + if (err) + http_header_add(rh, "X-Mbuni-MM-Error", octstr_get_cstr(err)); - if (statustxt) - http_header_add(rh, "X-Mbuni-MM-StatusText", octstr_get_cstr(statustxt)); + if (statustxt) + http_header_add(rh, "X-Mbuni-MM-StatusText", octstr_get_cstr(statustxt)); - if (details) - http_header_add(rh, "X-Mbuni-MM-StatusDetails", octstr_get_cstr(details)); + if (details) + http_header_add(rh, "X-Mbuni-MM-StatusDetails", octstr_get_cstr(details)); - if (uaprof) { - http_header_add(rh, "X-Mbuni-UAProf", octstr_get_cstr(uaprof)); - http_header_add(rh, "X-Mbuni-Timestamp", octstr_get_cstr(uaprof_tstamp)); - } - ret = mms_url_fetch_content(HTTP_METHOD_GET, dlr_url, rh, NULL, &rph, &rb); + if (uaprof) { + http_header_add(rh, "X-Mbuni-UAProf", octstr_get_cstr(uaprof)); + http_header_add(rh, "X-Mbuni-Timestamp", octstr_get_cstr(uaprof_tstamp)); + } + ret = mms_url_fetch_content(HTTP_METHOD_GET, dlr_url, rh, NULL, &rph, &rb); - octstr_destroy(rb); - octstr_destroy(xfrom); + octstr_destroy(rb); + octstr_destroy(xfrom); - http_destroy_headers(rph); - http_destroy_headers(rh); + http_destroy_headers(rph); + http_destroy_headers(rh); - return http_status_class(ret) == HTTP_STATUS_SUCCESSFUL ? 0 : -1; + return http_status_class(ret) == HTTP_STATUS_SUCCESSFUL ? 0 : -1; } static int mmsbox_service_dispatch(MmsEnvelope *e) { - MmsMsg *msg = NULL; - MIMEEntity *me = NULL; - int i, n, res = 0; - time_t tnow = time(NULL); - Octstr *err = NULL, *keyword = NULL; - MmsService *ms; - MmsEnvelopeTo *xto; - Octstr *prio = NULL, *mclass = NULL, *mstatus = NULL; + MmsMsg *msg = NULL; + MIMEEntity *me = NULL; + int i, n, res = 0; + time_t tnow = time(NULL); + Octstr *err = NULL, *keyword = NULL; + MmsService *ms; + MmsEnvelopeTo *xto; + Octstr *prio = NULL, *mclass = NULL, *mstatus = NULL; - gw_assert(e->msgtype == MMS_MSGTYPE_SEND_REQ || - e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF || - e->msgtype == MMS_MSGTYPE_DELIVERY_IND || - e->msgtype == MMS_MSGTYPE_READ_ORIG_IND); + gw_assert(e->msgtype == MMS_MSGTYPE_SEND_REQ || + e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF || + e->msgtype == MMS_MSGTYPE_DELIVERY_IND || + e->msgtype == MMS_MSGTYPE_READ_ORIG_IND); - if ((msg = qfs->mms_queue_getdata(e)) == NULL) { - err = octstr_format("Failed to read message for queue entry %s!", - e->xqfname); - res = -1; - goto done; - } else if (e->expiryt != 0 && /* Handle message expiry. */ - e->expiryt < tnow) { - err = octstr_format("Queue entry [msgid=%S,mmc_id=%S] " - "expired while sending to service!", e->msgId, e->fromproxy); - res = -1; + if ((msg = qfs->mms_queue_getdata(e)) == NULL) { + err = octstr_format("Failed to read message for queue entry %s!", + e->xqfname); + res = -1; + goto done; + } else if (e->expiryt != 0 && /* Handle message expiry. */ + e->expiryt < tnow) { + err = octstr_format("Queue entry [msgid=%S,mmc_id=%S] " + "expired while sending to service!", e->msgId, e->fromproxy); + res = -1; - goto done; - } else if (e->attempts >= svc_maxsendattempts) { - err = octstr_format("Failed to deliver [msgid=%S,mmc_id=%S] " - "after %ld attempts. (max attempts allowed is %ld)!", - e->msgId, e->fromproxy, e->attempts, - svc_maxsendattempts); - res = -1; - goto done; - } + goto done; + } else if (e->attempts >= svc_maxsendattempts) { + err = octstr_format("Failed to deliver [msgid=%S,mmc_id=%S] " + "after %ld attempts. (max attempts allowed is %ld)!", + e->msgId, e->fromproxy, e->attempts, + svc_maxsendattempts); + res = -1; + goto done; + } - mclass = mms_get_header_value(msg, octstr_imm("X-Mms-Message-Class")); - prio = mms_get_header_value(msg, octstr_imm("X-Mms-Priority")); - mstatus = mms_get_header_value(msg, octstr_imm("X-Mms-Status")); + mclass = mms_get_header_value(msg, octstr_imm("X-Mms-Message-Class")); + prio = mms_get_header_value(msg, octstr_imm("X-Mms-Priority")); + mstatus = mms_get_header_value(msg, octstr_imm("X-Mms-Status")); - if (e->msgtype == MMS_MSGTYPE_DELIVERY_IND || - e->msgtype == MMS_MSGTYPE_READ_ORIG_IND) { - char *report_type = (e->msgtype == MMS_MSGTYPE_DELIVERY_IND) ? "delivery-report" : "read-report"; - Octstr *msgid = mms_get_header_value(msg, octstr_imm("Message-ID")); - Octstr *orig_msgid = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-Orig-Message-ID")) : NULL; - Octstr *status = mms_get_header_value(msg, - e->msgtype == MMS_MSGTYPE_DELIVERY_IND ? - octstr_imm("X-Mms-Status") : - octstr_imm("X-Mms-Read-Status")); - Octstr *orig_transid = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL; - Octstr *uaprof = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-UAProf")) : NULL; + if (e->msgtype == MMS_MSGTYPE_DELIVERY_IND || + e->msgtype == MMS_MSGTYPE_READ_ORIG_IND) { + char *report_type = (e->msgtype == MMS_MSGTYPE_DELIVERY_IND) ? "delivery-report" : "read-report"; + Octstr *msgid = mms_get_header_value(msg, octstr_imm("Message-ID")); + Octstr *orig_msgid = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-Orig-Message-ID")) : NULL; + Octstr *status = mms_get_header_value(msg, + e->msgtype == MMS_MSGTYPE_DELIVERY_IND ? + octstr_imm("X-Mms-Status") : + octstr_imm("X-Mms-Read-Status")); + Octstr *orig_transid = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL; + Octstr *uaprof = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-UAProf")) : NULL; - Octstr *tstamp = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-Timestamp")) : NULL; - Octstr *gid = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-Mmsc-GroupID")) : NULL; + Octstr *tstamp = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-Timestamp")) : NULL; + Octstr *gid = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-Mmsc-GroupID")) : NULL; - Octstr *err = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-Error")) : NULL; - Octstr *statustxt = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-StatusText")) : NULL; - Octstr *details = e->hdrs ? - http_header_value(e->hdrs, octstr_imm("X-Mbuni-StatusDetails")) : NULL; + Octstr *err = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-Error")) : NULL; + Octstr *statustxt = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-StatusText")) : NULL; + Octstr *details = e->hdrs ? + http_header_value(e->hdrs, octstr_imm("X-Mbuni-StatusDetails")) : NULL; - if (e->url1) - res = mmsbox_send_report(e->from, report_type, - e->url1, status, msgid, orig_msgid, - e->fromproxy, gid, orig_transid, - uaprof,tstamp, err, statustxt, details); - else { - mms_info(0, "MM7", e->fromproxy, "MMSBox: Skipped %s URL call for [%s]. Empty URL, from [%s]", - report_type, octstr_get_cstr(msgid), octstr_get_cstr(e->from)); - res = 0; - } + if (e->url1) + res = mmsbox_send_report(e->from, report_type, + e->url1, status, msgid, orig_msgid, + e->fromproxy, gid, orig_transid, + uaprof,tstamp, err, statustxt, details); + else { + mms_info(0, "MM7", e->fromproxy, "MMSBox: Skipped %s URL call for [%s]. Empty URL, from [%s]", + report_type, octstr_get_cstr(msgid), octstr_get_cstr(e->from)); + res = 0; + } - octstr_destroy(msgid); - octstr_destroy(orig_msgid); - octstr_destroy(status); - octstr_destroy(orig_transid); - octstr_destroy(uaprof); - octstr_destroy(tstamp); - octstr_destroy(gid); - octstr_destroy(err); - octstr_destroy(statustxt); - octstr_destroy(details); - goto done; /* No more processing. */ - } + octstr_destroy(msgid); + octstr_destroy(orig_msgid); + octstr_destroy(status); + octstr_destroy(orig_transid); + octstr_destroy(uaprof); + octstr_destroy(tstamp); + octstr_destroy(gid); + octstr_destroy(err); + octstr_destroy(statustxt); + octstr_destroy(details); + goto done; /* No more processing. */ + } - if (gwlist_len(e->to) == 0) { /* nothing to do. odd XXX */ - res = 0; - goto done; - } + if (gwlist_len(e->to) == 0) { /* nothing to do. odd XXX */ + res = 0; + goto done; + } - me = mms_tomime(msg, 0); - keyword = get_keyword(me); + me = mms_tomime(msg, 0); + keyword = get_keyword(me); - xto = gwlist_get(e->to, 0); - ms = get_service(keyword, e->fromproxy, xto ? xto->rcpt : NULL); + xto = gwlist_get(e->to, 0); + ms = get_service(keyword, e->fromproxy, xto ? xto->rcpt : NULL); - if (!ms) { - err = octstr_format("No Service to handle %S (keyword %S)!", - e->msgId, keyword ? octstr_imm("") : keyword); - res = -1; - goto done; - } + if (!ms) { + err = octstr_format("No Service to handle %S (keyword %S)!", + e->msgId, keyword ? octstr_imm("") : keyword); + res = -1; + goto done; + } - e->_x = ms; /* Remember it for later. */ + e->_x = ms; /* Remember it for later. */ - res = fetch_serviceurl(e, ms, msg, me, keyword, &err); -done: + res = fetch_serviceurl(e, ms, msg, me, keyword, &err); + done: - if (err && res != 0) - mms_error(0, "mmsbox", NULL, "Error: %s", octstr_get_cstr(err)); + if (err && res != 0) + mms_error(0, "mmsbox", NULL, "Error: %s", octstr_get_cstr(err)); - if (res == -1 || res == 0) /* Fatal error, or success delete queue entry. */ - for (i = 0, n = gwlist_len(e->to); i < n; i++) { + if (res == -1 || res == 0) /* Fatal error, or success delete queue entry. */ + for (i = 0, n = gwlist_len(e->to); i < n; i++) { - MmsEnvelopeTo *r = gwlist_get(e->to,i); - if (r) - r->process = 0; - /* Do CDR */ - cdrfs->logcdr(e->created, - octstr_get_cstr(e->from), - octstr_get_cstr(r->rcpt), - octstr_get_cstr(e->msgId), - e->fromproxy ? octstr_get_cstr(e->fromproxy) : NULL, - e->src_interface, - "mms-service", - e->msize, - (char *)mms_message_type_to_cstr(e->msgtype), - prio ? octstr_get_cstr(prio) : NULL, - mclass ? octstr_get_cstr(mclass) : NULL, - mstatus ? octstr_get_cstr(mstatus) : - (res == 0 ? "forwarded" : "dropped"), - e->dlr, - 0); - } - else { /* Not succeeded so we need to wait a bit and try later. */ - e->lasttry = time(NULL); - e->attempts++; /* Update count of number of delivery attempts. */ - e->sendt = e->lasttry + mmsbox_send_back_off * e->attempts; - } + MmsEnvelopeTo *r = gwlist_get(e->to,i); + if (r) + r->process = 0; + /* Do CDR */ + cdrfs->logcdr(e->created, + octstr_get_cstr(e->from), + octstr_get_cstr(r->rcpt), + octstr_get_cstr(e->msgId), + e->fromproxy ? octstr_get_cstr(e->fromproxy) : NULL, + e->src_interface, + "mms-service", + e->msize, + (char *)mms_message_type_to_cstr(e->msgtype), + prio ? octstr_get_cstr(prio) : NULL, + mclass ? octstr_get_cstr(mclass) : NULL, + mstatus ? octstr_get_cstr(mstatus) : + (res == 0 ? "forwarded" : "dropped"), + e->dlr, + 0); + } + else { /* Not succeeded so we need to wait a bit and try later. */ + e->lasttry = time(NULL); + e->attempts++; /* Update count of number of delivery attempts. */ + e->sendt = e->lasttry + mmsbox_send_back_off * e->attempts; + } - if (qfs->mms_queue_update(e) != 1) - qfs->mms_queue_free_env(e); + if (qfs->mms_queue_update(e) != 1) + qfs->mms_queue_free_env(e); - octstr_destroy(err); - octstr_destroy(keyword); - mms_destroy(msg); + octstr_destroy(err); + octstr_destroy(keyword); + mms_destroy(msg); - octstr_destroy(prio); - octstr_destroy(mclass); - octstr_destroy(mstatus); + octstr_destroy(prio); + octstr_destroy(mclass); + octstr_destroy(mstatus); - if (me) - mime_entity_destroy(me); - return 1; + if (me) + mime_entity_destroy(me); + return 1; } static void sendmms_func(void *unused); int main(int argc, char *argv[]) { - Octstr *fname; - int cfidx; + Octstr *fname; + int cfidx; - long qthread = 0, sthread = 0; + long qthread = 0, sthread = 0; - mms_lib_init(); + mms_lib_init(); - srandom(time(NULL)); + srandom(time(NULL)); - cfidx = get_and_set_debugs(argc, argv, NULL); + cfidx = get_and_set_debugs(argc, argv, NULL); - if (argv[cfidx] == NULL) - fname = octstr_create("mbuni.conf"); - else - fname = octstr_create(argv[cfidx]); + if (argv[cfidx] == NULL) + fname = octstr_create("mbuni.conf"); + else + fname = octstr_create(argv[cfidx]); - if (mms_load_mmsbox_settings(fname,(gwthread_func_t *)mmsc_receive_func) < 0) - panic(0, "Configuration file loading failed, file: %s", octstr_get_cstr(fname)); + if (mms_load_mmsbox_settings(fname,(gwthread_func_t *)mmsc_receive_func) < 0) + panic(0, "Configuration file loading failed, file: %s", octstr_get_cstr(fname)); - octstr_destroy(fname); + octstr_destroy(fname); - mms_info(0, "mmsbox", NULL,"----------------------------------------"); - mms_info(0, "mmsbox", NULL," " MM_NAME " MMSBox version %s starting", MMSC_VERSION); + mms_info(0, "mmsbox", NULL,"----------------------------------------"); + mms_info(0, "mmsbox", NULL," " MM_NAME " MMSBox version %s starting", MMSC_VERSION); - signal(SIGHUP, relog_now); - signal(SIGTERM, quit_now); - signal(SIGINT, quit_now); - signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for nothing*/ +#ifdef SA_RESTART + { + struct sigaction nact; + + memset(&nact, 0, sizeof(nact)); + nact.sa_handler = relog_now; + nact.sa_flags = SA_RESTART; + sigaction(SIGHUP, &nact, (struct sigaction *)0); + } +#else + signal(SIGHUP, relog_now); +#endif + signal(SIGTERM, quit_now); + signal(SIGINT, quit_now); + signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for nothing*/ - /* Start sendmms port */ - if (sendmms_port.port > 0) - sthread = gwthread_create((gwthread_func_t *)sendmms_func, NULL); + /* Start sendmms port */ + if (sendmms_port.port > 0) + sthread = gwthread_create((gwthread_func_t *)sendmms_func, NULL); - /* Start out-going queue thread. */ - qthread = gwthread_create((gwthread_func_t *)mmsbox_outgoing_queue_runner, &rstop); + /* Start out-going queue thread. */ + qthread = gwthread_create((gwthread_func_t *)mmsbox_outgoing_queue_runner, &rstop); - qfs->mms_queue_run(octstr_get_cstr(incoming_qdir), - mmsbox_service_dispatch, - queue_interval, maxthreads, &rstop); + qfs->mms_queue_run(octstr_get_cstr(incoming_qdir), + mmsbox_service_dispatch, + queue_interval, maxthreads, &rstop); - mms_info(0, "mmsbox", NULL,"Shutdown started.."); + mms_info(0, "mmsbox", NULL,"Shutdown started.."); - sleep(2); - /* Wait for the sender thread, then quit. */ - if (qthread >= 0) - gwthread_join(qthread); /* Wait for it to die... */ + sleep(2); + /* Wait for the sender thread, then quit. */ + if (qthread >= 0) + gwthread_join(qthread); /* Wait for it to die... */ - if (sendmms_port.port > 0 && sthread >= 0) - gwthread_join(sthread); + if (sendmms_port.port > 0 && sthread >= 0) + gwthread_join(sthread); - mmsbox_settings_cleanup(); - mms_info(0, "mmsbox", NULL, "Shutdown complete.."); + mmsbox_settings_cleanup(); + mms_info(0, "mmsbox", NULL, "Shutdown complete.."); - mms_lib_shutdown(); - return 0; + mms_lib_shutdown(); + return 0; } @@ -798,88 +809,88 @@ int main(int argc, char *argv[]) /* Return the prefix part of a url or file. */ static Octstr *url_path_prefix(Octstr *url, int type) { - int i, j, len = octstr_len(url); - char *p = octstr_get_cstr(url); + int i, j, len = octstr_len(url); + char *p = octstr_get_cstr(url); - /* Set lower/upper limit of search. */ - if (type == URL_TYPE) { /* then skip first slashes. */ - char *x; - i = octstr_search(url, octstr_imm("://"),0); - if (i > 0) - i += 3; - else - i = 0; - x = rindex(p, '#'); /* look for fragment if any. */ + /* Set lower/upper limit of search. */ + if (type == URL_TYPE) { /* then skip first slashes. */ + char *x; + i = octstr_search(url, octstr_imm("://"),0); + if (i > 0) + i += 3; + else + i = 0; + x = rindex(p, '#'); /* look for fragment if any. */ - if (x) - j = x - p - 1; - else - j = len - 1; - } else { - i = 0; - j = len - 1; - } + if (x) + j = x - p - 1; + else + j = len - 1; + } else { + i = 0; + j = len - 1; + } - /* Now search backwards for the last '/'. - * if you don't find one, set to end of string. - */ + /* Now search backwards for the last '/'. + * if you don't find one, set to end of string. + */ - for (;j > i; j--) - if (p[j] == '/') - break; - if (j <= i) - j = len; + for (;j > i; j--) + if (p[j] == '/') + break; + if (j <= i) + j = len; - return octstr_copy(url, 0, j); + return octstr_copy(url, 0, j); } /* Get's just the host:port part, leaving out UrI */ static Octstr *get_toplevel_url(Octstr *url) { - int i, len = octstr_len(url); - char *p = octstr_get_cstr(url); + int i, len = octstr_len(url); + char *p = octstr_get_cstr(url); - i = octstr_search(url, octstr_imm("://"),0); + i = octstr_search(url, octstr_imm("://"),0); - if (i > 0) - i += 3; - else - i = 0; + if (i > 0) + i += 3; + else + i = 0; - for ( ; i < len; i++) - if (p[i] == '/') - break; + for ( ; i < len; i++) + if (p[i] == '/') + break; - return octstr_copy(url, 0, i); + return octstr_copy(url, 0, i); } /* little dirty method to see if file begins with url scheme. */ static int has_url_scheme(char *url, int *supported_scheme) { - char *p = strstr(url, "://"); + char *p = strstr(url, "://"); - *supported_scheme = 1; + *supported_scheme = 1; - if (strstr(url, "data:") == url || /* data: url scheme */ - strstr(url, "http://") == url || + if (strstr(url, "data:") == url || /* data: url scheme */ + strstr(url, "http://") == url || #ifdef HAVE_LIBSSL - strstr(url, "https://") == url || + strstr(url, "https://") == url || #endif - strstr(url, "file://") == url) - return 1; + strstr(url, "file://") == url) + return 1; - if (p) { + if (p) { - for (p--; p >= url; p--) - if (!isalpha(*p)) - break; - if (p < url) { - *supported_scheme = 0; /* we don't support this one. */ - return 1; - } else - return 0; - } else - return 0; + for (p--; p >= url; p--) + if (!isalpha(*p)) + break; + if (p < url) { + *supported_scheme = 0; /* we don't support this one. */ + return 1; + } else + return 0; + } else + return 0; } static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, @@ -888,114 +899,114 @@ static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, Octstr *mmc_id, Dict *url_map, Octstr *xmhdr, Octstr *xmhdr_val) { - Octstr *curl = NULL, *ctype = NULL, *body = NULL, *xcid = NULL; - char *src = NULL; - int isurl, slash_prefix; - Octstr *cid = NULL; - int supported_url_scheme = 0; + Octstr *curl = NULL, *ctype = NULL, *body = NULL, *xcid = NULL; + char *src = NULL; + int isurl, slash_prefix; + Octstr *cid = NULL; + int supported_url_scheme = 0; - /* For each node in the smil doc, if it has an src attribute, then: - * - if our type of base_url is FILE *and the src attribute does not look - * like a url, then file the file referenced, load it into the message and go - * - if our type is URL and the url scheme is http/https (or has no scheme) - * then fetch it and put into message. - */ + /* For each node in the smil doc, if it has an src attribute, then: + * - if our type of base_url is FILE *and the src attribute does not look + * like a url, then file the file referenced, load it into the message and go + * - if our type is URL and the url scheme is http/https (or has no scheme) + * then fetch it and put into message. + */ - if (!node || node->type != XML_ELEMENT_NODE || - (src = (char *)xmlGetProp(node, (unsigned char *)"src")) == NULL) - return 0; /* Nothing to do. */ + if (!node || node->type != XML_ELEMENT_NODE || + (src = (char *)xmlGetProp(node, (unsigned char *)"src")) == NULL) + return 0; /* Nothing to do. */ - if (src[0] == '\\') { /* User can escape url to prevent substitution. */ - xmlSetProp(node, (xmlChar *)"src", (xmlChar *)(src + 1)); - goto done; - } + if (src[0] == '\\') { /* User can escape url to prevent substitution. */ + xmlSetProp(node, (xmlChar *)"src", (xmlChar *)(src + 1)); + goto done; + } - isurl = has_url_scheme(src, &supported_url_scheme); - slash_prefix = (src[0] == '/'); + isurl = has_url_scheme(src, &supported_url_scheme); + slash_prefix = (src[0] == '/'); - if (isurl && !supported_url_scheme) - goto done; - else if (isurl) - curl = octstr_create(src); - else if (slash_prefix) { - if (type == URL_TYPE) - curl = octstr_format("%S%s", - top_url, src); - else - curl = octstr_create(src); - } else - curl = octstr_format("%S/%s",base_url, src); + if (isurl && !supported_url_scheme) + goto done; + else if (isurl) + curl = octstr_create(src); + else if (slash_prefix) { + if (type == URL_TYPE) + curl = octstr_format("%S%s", + top_url, src); + else + curl = octstr_create(src); + } else + curl = octstr_format("%S/%s",base_url, src); - if ((cid = dict_get(url_map, curl)) != NULL) { /* We've seen it before. */ - xmlSetProp(node, (xmlChar *)"src", (xmlChar *)octstr_get_cstr(cid)); - /* Don't delete cid! */ - goto done; - } + if ((cid = dict_get(url_map, curl)) != NULL) { /* We've seen it before. */ + xmlSetProp(node, (xmlChar *)"src", (xmlChar *)octstr_get_cstr(cid)); + /* Don't delete cid! */ + goto done; + } - isurl |= (type == URL_TYPE); /* From now on, this flag tells us whether we are fetching a url.*/ + isurl |= (type == URL_TYPE); /* From now on, this flag tells us whether we are fetching a url.*/ - if (isurl) { - List *rh = http_create_empty_headers(), *rph = NULL; + if (isurl) { + List *rh = http_create_empty_headers(), *rph = NULL; - http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); - if (mmsbox_url_fetch_content(HTTP_METHOD_GET, curl, rh, NULL, &rph, &body) == HTTP_OK) { - ctype = http_header_value(rph, octstr_imm("Content-Type")); - xcid = http_header_value(rph, octstr_imm("Content-ID")); - } else - mms_error(0, "mmsbox", NULL, "Failed to load url %s within SMIL content from service %s!", - octstr_get_cstr(curl), - svc_name ? octstr_get_cstr(svc_name) : "unknown"); - if (rph) - http_destroy_headers(rph); - http_destroy_headers(rh); - } else { - body = octstr_read_file(octstr_get_cstr(curl)); - ctype = filename2content_type(src); - } + http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); + if (mmsbox_url_fetch_content(HTTP_METHOD_GET, curl, rh, NULL, &rph, &body) == HTTP_OK) { + ctype = http_header_value(rph, octstr_imm("Content-Type")); + xcid = http_header_value(rph, octstr_imm("Content-ID")); + } else + mms_error(0, "mmsbox", NULL, "Failed to load url %s within SMIL content from service %s!", + octstr_get_cstr(curl), + svc_name ? octstr_get_cstr(svc_name) : "unknown"); + if (rph) + http_destroy_headers(rph); + http_destroy_headers(rh); + } else { + body = octstr_read_file(octstr_get_cstr(curl)); + ctype = filename2content_type(src); + } - if (ctype && body) { /* If we got it, put it in. */ - static int cntr; /* For generating cids */ - char _fext[5] = {0}, *fext = make_file_ext(curl, ctype, _fext); - Octstr *attr = xcid ? octstr_format("cid:%S", xcid) : octstr_format("cid:%06d.%s", ++cntr,fext); - char *p = octstr_get_cstr(attr) + 4; - Octstr *cid_header_val = octstr_format("<%s>", p); - MIMEEntity *x = mime_entity_create(); - List *headers = http_create_empty_headers(); + if (ctype && body) { /* If we got it, put it in. */ + static int cntr; /* For generating cids */ + char _fext[5] = {0}, *fext = make_file_ext(curl, ctype, _fext); + Octstr *attr = xcid ? octstr_format("cid:%S", xcid) : octstr_format("cid:%06d.%s", ++cntr,fext); + char *p = octstr_get_cstr(attr) + 4; + Octstr *cid_header_val = octstr_format("<%s>", p); + MIMEEntity *x = mime_entity_create(); + List *headers = http_create_empty_headers(); - http_header_add(headers, "Content-Type", octstr_get_cstr(ctype)); - http_header_add(headers, "Content-ID", octstr_get_cstr(cid_header_val)); - http_header_add(headers, "Content-Location", p); + http_header_add(headers, "Content-Type", octstr_get_cstr(ctype)); + http_header_add(headers, "Content-ID", octstr_get_cstr(cid_header_val)); + http_header_add(headers, "Content-Location", p); - if (xmhdr) - http_header_add(headers, octstr_get_cstr(xmhdr), octstr_get_cstr(xmhdr_val)); + if (xmhdr) + http_header_add(headers, octstr_get_cstr(xmhdr), octstr_get_cstr(xmhdr_val)); - mime_replace_headers(x, headers); - mime_entity_set_body(x, body); + mime_replace_headers(x, headers); + mime_entity_set_body(x, body); - if (mt_filter && mmc_id) - mt_filter->filter(&x, curl, mmc_id); + if (mt_filter && mmc_id) + mt_filter->filter(&x, curl, mmc_id); - mime_entity_add_part(res, x); - mime_entity_destroy(x); + mime_entity_add_part(res, x); + mime_entity_destroy(x); - dict_put_once(url_map, curl, octstr_duplicate(attr)); /* Store the cid. */ + dict_put_once(url_map, curl, octstr_duplicate(attr)); /* Store the cid. */ - xmlSetProp(node, (xmlChar *)"src", (xmlChar *)octstr_get_cstr(attr)); + xmlSetProp(node, (xmlChar *)"src", (xmlChar *)octstr_get_cstr(attr)); - octstr_destroy(attr); - octstr_destroy(cid_header_val); - http_destroy_headers(headers); - } + octstr_destroy(attr); + octstr_destroy(cid_header_val); + http_destroy_headers(headers); + } -done: + done: - octstr_destroy(curl); - octstr_destroy(ctype); - octstr_destroy(body); - octstr_destroy(xcid); - xmlFree(src); - return 0; + octstr_destroy(curl); + octstr_destroy(ctype); + octstr_destroy(body); + octstr_destroy(xcid); + xmlFree(src); + return 0; } /* Traverse the tree doing the above. */ @@ -1005,14 +1016,14 @@ static void add_msg_parts(MIMEEntity *res, xmlNodePtr node, Octstr *base_url, Octstr *mmc_id, Dict *url_map, Octstr *xmhdr, Octstr *xmhdr_val) { - xmlNodePtr n; - /* Do all the children recursively, then come back and do parent. */ - for (n = node; n; n = n->next) - if (n->type != XML_COMMENT_NODE) { - add_msg_part(res, n, base_url, top_url, type, svc_name, mmc_id, url_map, xmhdr, xmhdr_val); - add_msg_parts(res, n->xmlChildrenNode, base_url, top_url, type, - svc_name, mmc_id, url_map, xmhdr, xmhdr_val); - } + xmlNodePtr n; + /* Do all the children recursively, then come back and do parent. */ + for (n = node; n; n = n->next) + if (n->type != XML_COMMENT_NODE) { + add_msg_part(res, n, base_url, top_url, type, svc_name, mmc_id, url_map, xmhdr, xmhdr_val); + add_msg_parts(res, n->xmlChildrenNode, base_url, top_url, type, + svc_name, mmc_id, url_map, xmhdr, xmhdr_val); + } } /* Given content, make a message. We'll also use this for send-mms-user! */ @@ -1024,640 +1035,640 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, Octstr *qdir, Octstr **err) { - Octstr *from = NULL, *xfrom = NULL, *subject = NULL, *turl = get_toplevel_url(base_url); - Octstr *dlr_url = NULL, *rr_url = NULL, *mmc = NULL, *xservice_code = NULL, *hsvc_code = NULL; - Octstr *allow_adaptations = NULL, *mclass = NULL, *prio = NULL, *distro = NULL, *chargedparty = NULL; - MmsMsg *m = NULL; - MIMEEntity *me = mime_entity_create(); - List *xheaders = NULL; - List *hdrs = http_create_empty_headers(); - Octstr *otransid = NULL; - Octstr *xmhdr = NULL, *xmhdr_val = NULL; + Octstr *from = NULL, *xfrom = NULL, *subject = NULL, *turl = get_toplevel_url(base_url); + Octstr *dlr_url = NULL, *rr_url = NULL, *mmc = NULL, *xservice_code = NULL, *hsvc_code = NULL; + Octstr *allow_adaptations = NULL, *mclass = NULL, *prio = NULL, *distro = NULL, *chargedparty = NULL; + MmsMsg *m = NULL; + MIMEEntity *me = mime_entity_create(); + List *xheaders = NULL; + List *hdrs = http_create_empty_headers(); + Octstr *otransid = NULL; + Octstr *xmhdr = NULL, *xmhdr_val = NULL; - time_t expiryt = time(NULL) + DEFAULT_EXPIRE; - Octstr *x; - List *xto = gwlist_create(); - int i, n, res = -1; + time_t expiryt = time(NULL) + DEFAULT_EXPIRE; + Octstr *x; + List *xto = gwlist_create(); + int i, n, res = -1; - gw_assert(svc_name); + gw_assert(svc_name); - /* Get headers needed, if we are allowed to do so. */ - if (accept_x_headers && reply_headers) { - Octstr *x = NULL; - List *l = NULL; - subject = http_header_value(reply_headers, octstr_imm("X-Mbuni-Subject")); + /* Get headers needed, if we are allowed to do so. */ + if (accept_x_headers && reply_headers) { + Octstr *x = NULL; + List *l = NULL; + subject = http_header_value(reply_headers, octstr_imm("X-Mbuni-Subject")); - if ((x = http_header_value(reply_headers, octstr_imm("X-Mbuni-Expiry"))) != NULL) - expiryt = date_parse_http(x); + if ((x = http_header_value(reply_headers, octstr_imm("X-Mbuni-Expiry"))) != NULL) + expiryt = date_parse_http(x); - if ((l = http_header_find_all(reply_headers, "X-Mbuni-To")) != NULL) { - int i, n; - for (i = 0, n = gwlist_len(l); ifrom) - gwlist_append(xto, octstr_duplicate(e->from)); + if (reply_headers) { + /* always capture transid and distro */ + otransid = http_header_value(reply_headers, octstr_imm("X-Mbuni-TransactionID")); + distro = http_header_value(reply_headers, octstr_imm("X-Mbuni-DistributionIndicator")); + } + if (gwlist_len(xto) == 0 && e && e->from) + gwlist_append(xto, octstr_duplicate(e->from)); - if (!subject && e && e->subject) - subject = octstr_duplicate(e->subject); + if (!subject && e && e->subject) + subject = octstr_duplicate(e->subject); - /* Look for special header name/value to be inserted on all objects. */ - if (reply_headers && - (xmhdr = http_header_value(reply_headers, octstr_imm("X-Mbuni-Content-Header"))) != NULL) { - int x = octstr_search_char(xmhdr,':', 0); + /* Look for special header name/value to be inserted on all objects. */ + if (reply_headers && + (xmhdr = http_header_value(reply_headers, octstr_imm("X-Mbuni-Content-Header"))) != NULL) { + int x = octstr_search_char(xmhdr,':', 0); - if (x > 0) { - xmhdr_val = octstr_copy(xmhdr, x+1, octstr_len(xmhdr)); - octstr_delete(xmhdr, x, octstr_len(xmhdr)); - } else - xmhdr_val = octstr_create(""); + if (x > 0) { + xmhdr_val = octstr_copy(xmhdr, x+1, octstr_len(xmhdr)); + octstr_delete(xmhdr, x, octstr_len(xmhdr)); + } else + xmhdr_val = octstr_create(""); - octstr_strip_blanks(xmhdr_val); - octstr_strip_blanks(xmhdr); - } + octstr_strip_blanks(xmhdr_val); + octstr_strip_blanks(xmhdr); + } #if 0 /* don't route via sender, instead use allow/deny settings. */ - if (!mmc && e) - mmc = octstr_duplicate(e->fromproxy); + if (!mmc && e) + mmc = octstr_duplicate(e->fromproxy); #endif - /* Get the from address. */ - if (faked_sender) - from = octstr_duplicate(faked_sender); - else if (xfrom != NULL) - from = octstr_duplicate(xfrom); /* all done above. */ - else { - /* get first recipient, set that as sender. */ - MmsEnvelopeTo *r = (e) ? gwlist_get(e->to, 0) : NULL; - if (r) - from = octstr_duplicate(r->rcpt); - else - from = octstr_create("anon@anon"); - } + /* Get the from address. */ + if (faked_sender) + from = octstr_duplicate(faked_sender); + else if (xfrom != NULL) + from = octstr_duplicate(xfrom); /* all done above. */ + else { + /* get first recipient, set that as sender. */ + MmsEnvelopeTo *r = (e) ? gwlist_get(e->to, 0) : NULL; + if (r) + from = octstr_duplicate(r->rcpt); + else + from = octstr_create("anon@anon"); + } - /* Get service code. */ - if (service_code) - xservice_code = octstr_duplicate(service_code); - else if (hsvc_code) - xservice_code = octstr_duplicate(hsvc_code); + /* Get service code. */ + if (service_code) + xservice_code = octstr_duplicate(service_code); + else if (hsvc_code) + xservice_code = octstr_duplicate(hsvc_code); - if (from) - _mms_fixup_address(&from, NULL, NULL, 1); /* Don't normalise. */ + if (from) + _mms_fixup_address(&from, NULL, NULL, 1); /* Don't normalise. */ - /* Now get the data. */ - if (octstr_str_case_compare(ctype, "application/vnd.wap.mms-message") == 0) - m = mms_frombinary(data, from); - else if (octstr_case_search(ctype, octstr_imm("multipart/"), 0) == 0) { /* treat it differently. */ - MIMEEntity *mime = mime_http_to_entity(reply_headers, data); - if (mime) { - mime_entity_destroy(me); - me = mime; - } - } else if (octstr_case_search(ctype, - octstr_imm(MBUNI_MULTIPART_TYPE), 0) == 0) { /* Mbuni multipart.*/ - List *l = octstr_split_words(data); - MIMEEntity *mime = multipart_from_urls(l); + /* Now get the data. */ + if (octstr_str_case_compare(ctype, "application/vnd.wap.mms-message") == 0) + m = mms_frombinary(data, from); + else if (octstr_case_search(ctype, octstr_imm("multipart/"), 0) == 0) { /* treat it differently. */ + MIMEEntity *mime = mime_http_to_entity(reply_headers, data); + if (mime) { + mime_entity_destroy(me); + me = mime; + } + } else if (octstr_case_search(ctype, + octstr_imm(MBUNI_MULTIPART_TYPE), 0) == 0) { /* Mbuni multipart.*/ + List *l = octstr_split_words(data); + MIMEEntity *mime = multipart_from_urls(l); - if (mime) { - mime_entity_destroy(me); - me = mime; - } - gwlist_destroy(l, (void *)octstr_destroy); - } else if (octstr_case_search(ctype, octstr_imm("application/smil"), 0) == 0) { - xmlDocPtr smil; - xmlChar *buf = NULL; - int bsize = 0; - Dict *url_map = dict_create(97, (void (*)(void *))octstr_destroy); - List *xh = http_create_empty_headers(); + if (mime) { + mime_entity_destroy(me); + me = mime; + } + gwlist_destroy(l, (void *)octstr_destroy); + } else if (octstr_case_search(ctype, octstr_imm("application/smil"), 0) == 0) { + xmlDocPtr smil; + xmlChar *buf = NULL; + int bsize = 0; + Dict *url_map = dict_create(97, (void (*)(void *))octstr_destroy); + List *xh = http_create_empty_headers(); - /* This is the hard bit: Fetch each external reference in smil, add it to message! */ - http_header_add(xh, "Content-Type", "multipart/related; " - "type=\"application/smil\"; start=\"\""); - mime_replace_headers(me,xh); - http_destroy_headers(xh); + /* This is the hard bit: Fetch each external reference in smil, add it to message! */ + http_header_add(xh, "Content-Type", "multipart/related; " + "type=\"application/smil\"; start=\"\""); + mime_replace_headers(me,xh); + http_destroy_headers(xh); - /* Parse the smil as XML. */ - smil = xmlParseMemory(octstr_get_cstr(data), octstr_len(data)); - if (!smil || !smil->xmlChildrenNode) { - *err = octstr_format("MMSBox: Error parsing SMIL response from service[%s], " - " msgid %s!", octstr_get_cstr(svc_name), - (e && e->msgId) ? octstr_get_cstr(e->msgId) : "(none)"); - dict_destroy(url_map); - goto done; - } + /* Parse the smil as XML. */ + smil = xmlParseMemory(octstr_get_cstr(data), octstr_len(data)); + if (!smil || !smil->xmlChildrenNode) { + *err = octstr_format("MMSBox: Error parsing SMIL response from service[%s], " + " msgid %s!", octstr_get_cstr(svc_name), + (e && e->msgId) ? octstr_get_cstr(e->msgId) : "(none)"); + dict_destroy(url_map); + goto done; + } - add_msg_parts(me, smil->xmlChildrenNode, - base_url, turl, type, svc_name, - mmc, url_map, xmhdr, xmhdr_val); + add_msg_parts(me, smil->xmlChildrenNode, + base_url, turl, type, svc_name, + mmc, url_map, xmhdr, xmhdr_val); - dict_destroy(url_map); - /* SMIL has been modified, convert it to text, put it in. */ - xmlDocDumpFormatMemory(smil, &buf, &bsize, 1); - xmlFreeDoc(smil); - if (buf) { - MIMEEntity *sm = mime_entity_create(); - List *xh = http_create_empty_headers(); - Octstr *s; + dict_destroy(url_map); + /* SMIL has been modified, convert it to text, put it in. */ + xmlDocDumpFormatMemory(smil, &buf, &bsize, 1); + xmlFreeDoc(smil); + if (buf) { + MIMEEntity *sm = mime_entity_create(); + List *xh = http_create_empty_headers(); + Octstr *s; - http_header_add(xh, "Content-Type", "application/smil"); - http_header_add(xh, "Content-ID", ""); /* identify it as start element. */ - if (xmhdr) - http_header_add(xh, octstr_get_cstr(xmhdr), octstr_get_cstr(xmhdr_val)); - s = octstr_create_from_data((char *)buf, bsize); + http_header_add(xh, "Content-Type", "application/smil"); + http_header_add(xh, "Content-ID", ""); /* identify it as start element. */ + if (xmhdr) + http_header_add(xh, octstr_get_cstr(xmhdr), octstr_get_cstr(xmhdr_val)); + s = octstr_create_from_data((char *)buf, bsize); - mime_replace_headers(sm, xh); - mime_entity_set_body(sm, s); + mime_replace_headers(sm, xh); + mime_entity_set_body(sm, s); - mime_entity_add_part(me, sm); + mime_entity_add_part(me, sm); - mime_entity_destroy(sm); - http_destroy_headers(xh); - octstr_destroy(s); + mime_entity_destroy(sm); + http_destroy_headers(xh); + octstr_destroy(s); - xmlFree(buf); - } else { - *err = octstr_format("MMSBox: Error writing converted SMIL " - "for response from service[%s], " - " msgid %s!", - octstr_get_cstr(svc_name), - (e && e->msgId) ? octstr_get_cstr(e->msgId) : "(none)"); - goto done; - } - } else { /* all others, make the message as-is and hope for the best! */ - List *xh = http_create_empty_headers(); + xmlFree(buf); + } else { + *err = octstr_format("MMSBox: Error writing converted SMIL " + "for response from service[%s], " + " msgid %s!", + octstr_get_cstr(svc_name), + (e && e->msgId) ? octstr_get_cstr(e->msgId) : "(none)"); + goto done; + } + } else { /* all others, make the message as-is and hope for the best! */ + List *xh = http_create_empty_headers(); - if (mt_multipart) { /* if it's going to be multi-part, add some headers. */ - static int cntr = 0; - char _fext[5] = {0}, *fext = make_file_ext(msg_url, ctype, _fext); - Octstr *attr = octstr_format("%06d.%s", ++cntr,fext); - Octstr *cid_header_val = octstr_format("<%S>", attr); + if (mt_multipart) { /* if it's going to be multi-part, add some headers. */ + static int cntr = 0; + char _fext[5] = {0}, *fext = make_file_ext(msg_url, ctype, _fext); + Octstr *attr = octstr_format("%06d.%s", ++cntr,fext); + Octstr *cid_header_val = octstr_format("<%S>", attr); - http_header_add(xh, "Content-ID", octstr_get_cstr(cid_header_val)); - http_header_add(xh, "Content-Location", octstr_get_cstr(attr)); + http_header_add(xh, "Content-ID", octstr_get_cstr(cid_header_val)); + http_header_add(xh, "Content-Location", octstr_get_cstr(attr)); - octstr_destroy(attr); - octstr_destroy(cid_header_val); - } + octstr_destroy(attr); + octstr_destroy(cid_header_val); + } - http_header_add(xh, "Content-Type", octstr_get_cstr(ctype)); - if (xmhdr) - http_header_add(xh, octstr_get_cstr(xmhdr), octstr_get_cstr(xmhdr_val)); + http_header_add(xh, "Content-Type", octstr_get_cstr(ctype)); + if (xmhdr) + http_header_add(xh, octstr_get_cstr(xmhdr), octstr_get_cstr(xmhdr_val)); - mime_replace_headers(me, xh); + mime_replace_headers(me, xh); - http_destroy_headers(xh); - mime_entity_set_body(me, data); + http_destroy_headers(xh); + mime_entity_set_body(me, data); - if (mt_filter && mmc) /* filter it too. */ - mt_filter->filter(&me, msg_url, mmc); + if (mt_filter && mmc) /* filter it too. */ + mt_filter->filter(&me, msg_url, mmc); - if (mt_multipart && - octstr_case_search(ctype, octstr_imm("multipart/"), 0) != 0) { /* requires multipart but this one is not, wrap it */ - MIMEEntity *xm = mime_entity_create(); - List *h1 = http_create_empty_headers(); + if (mt_multipart && + octstr_case_search(ctype, octstr_imm("multipart/"), 0) != 0) { /* requires multipart but this one is not, wrap it */ + MIMEEntity *xm = mime_entity_create(); + List *h1 = http_create_empty_headers(); - http_header_add(h1, "Content-Type", "multipart/related"); - mime_replace_headers(xm, h1); - mime_entity_add_part(xm, me); + http_header_add(h1, "Content-Type", "multipart/related"); + mime_replace_headers(xm, h1); + mime_entity_add_part(xm, me); - http_destroy_headers(h1); + http_destroy_headers(h1); - me = xm; - } - } + me = xm; + } + } - /* Add some nice headers. */ - xheaders = mime_entity_headers(me); - http_header_add(xheaders, "From", octstr_get_cstr(from)); + /* Add some nice headers. */ + xheaders = mime_entity_headers(me); + http_header_add(xheaders, "From", octstr_get_cstr(from)); - for (i = 0, n = gwlist_len(xto); i < n; i++) { - Octstr *v; - v = gwlist_get(xto, i); - http_header_add(xheaders, "To", octstr_get_cstr(v)); - } + for (i = 0, n = gwlist_len(xto); i < n; i++) { + Octstr *v; + v = gwlist_get(xto, i); + http_header_add(xheaders, "To", octstr_get_cstr(v)); + } - if (dlr_url) - http_header_add(xheaders, "X-Mms-Delivery-Report", "Yes"); - if (rr_url) - http_header_add(xheaders, "X-Mms-Read-Report", "Yes"); - if (allow_adaptations) - http_header_add(xheaders, "X-Mms-Allow-Adaptations", - (octstr_str_compare(allow_adaptations, "true") == 0) ? "true" : "false"); + if (dlr_url) + http_header_add(xheaders, "X-Mms-Delivery-Report", "Yes"); + if (rr_url) + http_header_add(xheaders, "X-Mms-Read-Report", "Yes"); + if (allow_adaptations) + http_header_add(xheaders, "X-Mms-Allow-Adaptations", + (octstr_str_compare(allow_adaptations, "true") == 0) ? "true" : "false"); - if (mclass) - http_header_add(xheaders, "X-Mms-Message-Class", octstr_get_cstr(mclass)); + if (mclass) + http_header_add(xheaders, "X-Mms-Message-Class", octstr_get_cstr(mclass)); - if (prio) - http_header_add(xheaders, "X-Mms-Priority", octstr_get_cstr(prio)); + if (prio) + http_header_add(xheaders, "X-Mms-Priority", octstr_get_cstr(prio)); - if (subject) - http_header_add(xheaders, "Subject", octstr_get_cstr(subject)); - if (expiryt > 0) { - Octstr *x = date_format_http(expiryt); - http_header_add(xheaders, "X-Mms-Expiry", octstr_get_cstr(x)); - octstr_destroy(x); - } - mime_replace_headers(me, xheaders); - http_destroy_headers(xheaders); + if (subject) + http_header_add(xheaders, "Subject", octstr_get_cstr(subject)); + if (expiryt > 0) { + Octstr *x = date_format_http(expiryt); + http_header_add(xheaders, "X-Mms-Expiry", octstr_get_cstr(x)); + octstr_destroy(x); + } + mime_replace_headers(me, xheaders); + http_destroy_headers(xheaders); - if (me && !m) /* Set m if it hasn't been set yet. */ - m = mms_frommime(me); - if (!m) { - *err = octstr_format("MMSBox: Failed to convert Mms Message from service %s!", - octstr_get_cstr(svc_name)); - goto done; - } + if (me && !m) /* Set m if it hasn't been set yet. */ + m = mms_frommime(me); + if (!m) { + *err = octstr_format("MMSBox: Failed to convert Mms Message from service %s!", + octstr_get_cstr(svc_name)); + goto done; + } - if (otransid) /* always add transid */ - http_header_add(hdrs, "X-Mbuni-TransactionID", octstr_get_cstr(otransid)); + if (otransid) /* always add transid */ + http_header_add(hdrs, "X-Mbuni-TransactionID", octstr_get_cstr(otransid)); - if (distro) /* always add distrib */ - http_header_add(hdrs, "X-Mbuni-DistributionIndicator", - (octstr_str_case_compare(distro, "true") == 0) ? "true" : "false"); + if (distro) /* always add distrib */ + http_header_add(hdrs, "X-Mbuni-DistributionIndicator", + (octstr_str_case_compare(distro, "true") == 0) ? "true" : "false"); - if (chargedparty) - http_header_add(hdrs, "X-Mbuni-Charged-Party", octstr_get_cstr(chargedparty)); - if (passthro_headers && reply_headers) { /* if user wants passthro headers, get them and add them. */ - int n = gwlist_len(reply_headers); - int i; - for (i = 0; i < n; i++) { - Octstr *h = NULL, *v = NULL; - int j; - http_header_get(reply_headers, i, &h, &v); - if (h == NULL || v == NULL) - goto loop; + if (chargedparty) + http_header_add(hdrs, "X-Mbuni-Charged-Party", octstr_get_cstr(chargedparty)); + if (passthro_headers && reply_headers) { /* if user wants passthro headers, get them and add them. */ + int n = gwlist_len(reply_headers); + int i; + for (i = 0; i < n; i++) { + Octstr *h = NULL, *v = NULL; + int j; + http_header_get(reply_headers, i, &h, &v); + if (h == NULL || v == NULL) + goto loop; - /* Check for this header in - * pass thro list. - */ - for (j = 0; j < gwlist_len(passthro_headers); j++) - if (octstr_case_compare(h, gwlist_get(passthro_headers, j)) == 0) { - http_header_add(hdrs, octstr_get_cstr(h), octstr_get_cstr(v)); - break; - } - loop: - octstr_destroy(h); - octstr_destroy(v); - } - } + /* Check for this header in + * pass thro list. + */ + for (j = 0; j < gwlist_len(passthro_headers); j++) + if (octstr_case_compare(h, gwlist_get(passthro_headers, j)) == 0) { + http_header_add(hdrs, octstr_get_cstr(h), octstr_get_cstr(v)); + break; + } + loop: + octstr_destroy(h); + octstr_destroy(v); + } + } - /* Write to queue. */ - x = qfs->mms_queue_add(from, xto, subject, - e ? e->fromproxy : NULL, - mmc, - time(NULL), expiryt, m, NULL, - xservice_code, /* Send service code as vasp id XXX - not very nice, but */ - svc_name, - dlr_url, rr_url, - hdrs, - (dlr_url != NULL), - octstr_get_cstr(qdir), - "MMSBox", - NULL); - mms_info(2, "mmsbox", NULL,"MMSBox: Queued message from service [%s], [transid [%s]: %s", - octstr_get_cstr(svc_name), - otransid ? octstr_get_cstr(otransid) : "", - octstr_get_cstr(x)); - *err = x; - res = 0; -done: + /* Write to queue. */ + x = qfs->mms_queue_add(from, xto, subject, + e ? e->fromproxy : NULL, + mmc, + time(NULL), expiryt, m, NULL, + xservice_code, /* Send service code as vasp id XXX - not very nice, but */ + svc_name, + dlr_url, rr_url, + hdrs, + (dlr_url != NULL), + octstr_get_cstr(qdir), + "MMSBox", + NULL); + mms_info(2, "mmsbox", NULL,"MMSBox: Queued message from service [%s], [transid [%s]: %s", + octstr_get_cstr(svc_name), + otransid ? octstr_get_cstr(otransid) : "", + octstr_get_cstr(x)); + *err = x; + res = 0; + done: - octstr_destroy(dlr_url); - octstr_destroy(rr_url); - octstr_destroy(mclass); - octstr_destroy(prio); - octstr_destroy(mmc); - octstr_destroy(allow_adaptations); - octstr_destroy(from); - octstr_destroy(xfrom); - octstr_destroy(subject); - octstr_destroy(otransid); - octstr_destroy(turl); - octstr_destroy(chargedparty); + octstr_destroy(dlr_url); + octstr_destroy(rr_url); + octstr_destroy(mclass); + octstr_destroy(prio); + octstr_destroy(mmc); + octstr_destroy(allow_adaptations); + octstr_destroy(from); + octstr_destroy(xfrom); + octstr_destroy(subject); + octstr_destroy(otransid); + octstr_destroy(turl); + octstr_destroy(chargedparty); - octstr_destroy(xmhdr); - octstr_destroy(xmhdr_val); - if (me) - mime_entity_destroy(me); + octstr_destroy(xmhdr); + octstr_destroy(xmhdr_val); + if (me) + mime_entity_destroy(me); - mms_destroy(m); - gwlist_destroy(xto, (void *)octstr_destroy); - http_destroy_headers(hdrs); - octstr_destroy(xservice_code); - octstr_destroy(hsvc_code); + mms_destroy(m); + gwlist_destroy(xto, (void *)octstr_destroy); + http_destroy_headers(hdrs); + octstr_destroy(xservice_code); + octstr_destroy(hsvc_code); - return res; + return res; } static SendMmsUser *auth_user(Octstr *user, Octstr *pass) { - int i, n; - SendMmsUser *u = NULL; + int i, n; + SendMmsUser *u = NULL; - if (!user || !pass) - return NULL; - for (i = 0, n = gwlist_len(sendmms_users); i < n; i++) - if ((u = gwlist_get(sendmms_users, i)) != NULL && - octstr_compare(u->user, user) == 0 && - octstr_compare(u->pass, pass) == 0) - return u; - return NULL; + if (!user || !pass) + return NULL; + for (i = 0, n = gwlist_len(sendmms_users); i < n; i++) + if ((u = gwlist_get(sendmms_users, i)) != NULL && + octstr_compare(u->user, user) == 0 && + octstr_compare(u->pass, pass) == 0) + return u; + return NULL; } static void dispatch_sendmms_recv(List *rl) { - MmsBoxHTTPClientInfo *h; + MmsBoxHTTPClientInfo *h; - while ((h = gwlist_consume(rl)) != NULL) { - SendMmsUser *u = NULL; - List *hh = http_create_empty_headers(); - Octstr *username; - Octstr *password; - Octstr *err = NULL; - List *cgivar_ctypes = NULL; - char *etype = NULL; + while ((h = gwlist_consume(rl)) != NULL) { + SendMmsUser *u = NULL; + List *hh = http_create_empty_headers(); + Octstr *username; + Octstr *password; + Octstr *err = NULL; + List *cgivar_ctypes = NULL; + char *etype = NULL; - int res = 0, tparse = parse_cgivars(h->headers, h->body, &h->cgivars, &cgivar_ctypes); + int res = 0, tparse = parse_cgivars(h->headers, h->body, &h->cgivars, &cgivar_ctypes); - username = http_cgi_variable(h->cgivars, "username"); - password = http_cgi_variable(h->cgivars, "password"); - if (username) - octstr_strip_blanks(username); - if (password) - octstr_strip_blanks(password); - if ((u = auth_user(username, password)) != NULL && - is_allowed_ip(sendmms_port.allow_ip, sendmms_port.deny_ip, h->ip)) { - Octstr *data, *external_data = NULL, *ctype = NULL, *mmc, *to, *from, *dlr_url; - Octstr *rr_url, *allow_adaptations, *subject = NULL; - List *lto = NULL, *rh = http_create_empty_headers(); - Octstr *rb = NULL, *base_url; - int i, n, skip_ctype = 0; - Octstr *vasid = http_cgi_variable(h->cgivars, "vasid"); - Octstr *service_code = http_cgi_variable(h->cgivars, "servicecode"); - Octstr *mclass = http_cgi_variable(h->cgivars, "mclass"); - Octstr *prio = http_cgi_variable(h->cgivars, "priority"); - Octstr *distro = http_cgi_variable(h->cgivars, "distribution"); - Octstr *send_type = http_cgi_variable(h->cgivars, "mms-direction"); - Octstr *sheader = http_cgi_variable(h->cgivars, "extra-content-header"); - Octstr *validity = http_cgi_variable(h->cgivars, "validityperiod"); - Octstr *chargedparty = http_cgi_variable(h->cgivars, "charged-party"); - Octstr *data_url = NULL; + username = http_cgi_variable(h->cgivars, "username"); + password = http_cgi_variable(h->cgivars, "password"); + if (username) + octstr_strip_blanks(username); + if (password) + octstr_strip_blanks(password); + if ((u = auth_user(username, password)) != NULL && + is_allowed_ip(sendmms_port.allow_ip, sendmms_port.deny_ip, h->ip)) { + Octstr *data, *external_data = NULL, *ctype = NULL, *mmc, *to, *from, *dlr_url; + Octstr *rr_url, *allow_adaptations, *subject = NULL; + List *lto = NULL, *rh = http_create_empty_headers(); + Octstr *rb = NULL, *base_url; + int i, n, skip_ctype = 0; + Octstr *vasid = http_cgi_variable(h->cgivars, "vasid"); + Octstr *service_code = http_cgi_variable(h->cgivars, "servicecode"); + Octstr *mclass = http_cgi_variable(h->cgivars, "mclass"); + Octstr *prio = http_cgi_variable(h->cgivars, "priority"); + Octstr *distro = http_cgi_variable(h->cgivars, "distribution"); + Octstr *send_type = http_cgi_variable(h->cgivars, "mms-direction"); + Octstr *sheader = http_cgi_variable(h->cgivars, "extra-content-header"); + Octstr *validity = http_cgi_variable(h->cgivars, "validityperiod"); + Octstr *chargedparty = http_cgi_variable(h->cgivars, "charged-party"); + Octstr *data_url = NULL; - dlr_url = http_cgi_variable(h->cgivars, "dlr-url"); - rr_url = http_cgi_variable(h->cgivars, "rr-url"); - allow_adaptations = http_cgi_variable(h->cgivars, "allow-adaptations"); + dlr_url = http_cgi_variable(h->cgivars, "dlr-url"); + rr_url = http_cgi_variable(h->cgivars, "rr-url"); + allow_adaptations = http_cgi_variable(h->cgivars, "allow-adaptations"); - if ((mmc = http_cgi_variable(h->cgivars, "mmsc")) == NULL) { - mmc = octstr_duplicate(u->mmsc); /* could still be NULL */ - } - subject = http_cgi_variable(h->cgivars, "subject"); + if ((mmc = http_cgi_variable(h->cgivars, "mmsc")) == NULL) { + mmc = octstr_duplicate(u->mmsc); /* could still be NULL */ + } + subject = http_cgi_variable(h->cgivars, "subject"); - if ((base_url = http_cgi_variable(h->cgivars, "base-url")) == NULL) - base_url = octstr_create("http://localhost"); - else - base_url = octstr_duplicate(base_url); /* because we need to delete it below. */ + if ((base_url = http_cgi_variable(h->cgivars, "base-url")) == NULL) + base_url = octstr_create("http://localhost"); + else + base_url = octstr_duplicate(base_url); /* because we need to delete it below. */ - /* Now get the data. */ - if ((data = http_cgi_variable(h->cgivars, "text")) != NULL) { /* text. */ - Octstr *charset = http_cgi_variable(h->cgivars, "charset"); + /* Now get the data. */ + if ((data = http_cgi_variable(h->cgivars, "text")) != NULL) { /* text. */ + Octstr *charset = http_cgi_variable(h->cgivars, "charset"); - ctype = octstr_format("text/plain"); - if (charset) - octstr_format_append(ctype, "; charset=%S", charset); - } else if ((data = http_cgi_variable(h->cgivars, "smil")) != NULL) /* smil. */ - ctype = octstr_create("application/smil"); - else if ((data = http_cgi_variable(h->cgivars, "content-url")) != NULL) { /* arbitrary content. */ - List *reqh = http_create_empty_headers(), *rph = NULL; - Octstr *reply = NULL, *params = NULL; + ctype = octstr_format("text/plain"); + if (charset) + octstr_format_append(ctype, "; charset=%S", charset); + } else if ((data = http_cgi_variable(h->cgivars, "smil")) != NULL) /* smil. */ + ctype = octstr_create("application/smil"); + else if ((data = http_cgi_variable(h->cgivars, "content-url")) != NULL) { /* arbitrary content. */ + List *reqh = http_create_empty_headers(), *rph = NULL; + Octstr *reply = NULL, *params = NULL; - http_header_add(reqh, "User-Agent", MM_NAME "/" VERSION); + http_header_add(reqh, "User-Agent", MM_NAME "/" VERSION); - if (mmsbox_url_fetch_content(HTTP_METHOD_GET, data, reqh, NULL, &rph, &reply) == HTTP_OK) - get_content_type(rph, &ctype, ¶ms); - else - rb = octstr_format("failed to fetch content from url [%S]!", data); - base_url = url_path_prefix(data, URL_TYPE); + if (mmsbox_url_fetch_content(HTTP_METHOD_GET, data, reqh, NULL, &rph, &reply) == HTTP_OK) + get_content_type(rph, &ctype, ¶ms); + else + rb = octstr_format("failed to fetch content from url [%S]!", data); + base_url = url_path_prefix(data, URL_TYPE); - data_url = octstr_duplicate(data); /* the URL of the message. */ - data = external_data = reply; /* We record it separately for deletion below. */ + data_url = octstr_duplicate(data); /* the URL of the message. */ + data = external_data = reply; /* We record it separately for deletion below. */ - http_destroy_headers(reqh); - http_destroy_headers(rh); - rh = rph ? rph : http_create_empty_headers(); /* replace as real reply headers. */ - skip_ctype = 1; - octstr_destroy(params); - } else if ((data = http_cgi_variable(h->cgivars, "content")) != NULL) { /* any content. */ - Octstr *_xctype = NULL; /* ... because cgi var stuff is destroyed elsewhere, we must dup it !! */ + http_destroy_headers(reqh); + http_destroy_headers(rh); + rh = rph ? rph : http_create_empty_headers(); /* replace as real reply headers. */ + skip_ctype = 1; + octstr_destroy(params); + } else if ((data = http_cgi_variable(h->cgivars, "content")) != NULL) { /* any content. */ + Octstr *_xctype = NULL; /* ... because cgi var stuff is destroyed elsewhere, we must dup it !! */ - /* If the user sent us a content element, then they should have - * sent us its type either as part of the HTTP POST (multipart/form-data) - * or as CGI VAR called content_type - */ - if ((_xctype = http_cgi_variable(h->cgivars, "content_type")) == NULL) - if (cgivar_ctypes) - _xctype = http_cgi_variable(cgivar_ctypes, "content"); - if (_xctype) - ctype = octstr_duplicate(_xctype); - else - ctype = octstr_create("application/octet-stream"); - } else if (h->body && tparse != 0) { /* if all above fails, - use send-mms msg body if any. */ - data = octstr_duplicate(h->body); - ctype = http_header_value(h->headers, octstr_imm("Content-Type")); - } else - rb = octstr_create("Missing content"); + /* If the user sent us a content element, then they should have + * sent us its type either as part of the HTTP POST (multipart/form-data) + * or as CGI VAR called content_type + */ + if ((_xctype = http_cgi_variable(h->cgivars, "content_type")) == NULL) + if (cgivar_ctypes) + _xctype = http_cgi_variable(cgivar_ctypes, "content"); + if (_xctype) + ctype = octstr_duplicate(_xctype); + else + ctype = octstr_create("application/octet-stream"); + } else if (h->body && tparse != 0) { /* if all above fails, + use send-mms msg body if any. */ + data = octstr_duplicate(h->body); + ctype = http_header_value(h->headers, octstr_imm("Content-Type")); + } else + rb = octstr_create("Missing content"); - if ((to = http_cgi_variable(h->cgivars, "to")) == NULL) - rb = octstr_create("Missing recipient!"); - else - lto = octstr_split_words(to); + if ((to = http_cgi_variable(h->cgivars, "to")) == NULL) + rb = octstr_create("Missing recipient!"); + else + lto = octstr_split_words(to); - /* Build the fake reply headers. */ - if (ctype && !skip_ctype) - http_header_add(rh, "Content-Type", octstr_get_cstr(ctype)); + /* Build the fake reply headers. */ + if (ctype && !skip_ctype) + http_header_add(rh, "Content-Type", octstr_get_cstr(ctype)); - if ((from = http_cgi_variable(h->cgivars, "from")) != NULL) { - from = octstr_duplicate(from); - _mms_fixup_address(&from, NULL, NULL, 1); - if (from) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-From", octstr_get_cstr(from)); - octstr_destroy(from); - } else if (!u->faked_sender) - rb = octstr_create("Missing Sender address"); + if ((from = http_cgi_variable(h->cgivars, "from")) != NULL) { + from = octstr_duplicate(from); + _mms_fixup_address(&from, NULL, NULL, 1); + if (from) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-From", octstr_get_cstr(from)); + octstr_destroy(from); + } else if (!u->faked_sender) + rb = octstr_create("Missing Sender address"); - if (lto) { - for (i = 0, n = gwlist_len(lto); i < n; i++) { - Octstr *x = gwlist_get(lto, i); - http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(x)); - } - gwlist_destroy(lto, (gwlist_item_destructor_t *)octstr_destroy); - } - if (dlr_url) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-DLR-Url", octstr_get_cstr(dlr_url)); + if (lto) { + for (i = 0, n = gwlist_len(lto); i < n; i++) { + Octstr *x = gwlist_get(lto, i); + http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(x)); + } + gwlist_destroy(lto, (gwlist_item_destructor_t *)octstr_destroy); + } + if (dlr_url) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-DLR-Url", octstr_get_cstr(dlr_url)); - if (rr_url) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-RR-Url", octstr_get_cstr(rr_url)); + if (rr_url) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-RR-Url", octstr_get_cstr(rr_url)); - if (allow_adaptations) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-Allow-Adaptations", - (octstr_str_compare(allow_adaptations, "1") == 0) ? - "true" : "false"); - if (mmc) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-MMSC", octstr_get_cstr(mmc)); + if (allow_adaptations) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-Allow-Adaptations", + (octstr_str_compare(allow_adaptations, "1") == 0) ? + "true" : "false"); + if (mmc) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-MMSC", octstr_get_cstr(mmc)); - if (subject) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-Subject", octstr_get_cstr(subject)); + if (subject) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-Subject", octstr_get_cstr(subject)); - if (mclass) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-MessageClass", octstr_get_cstr(mclass)); - if (prio) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-Priority", octstr_get_cstr(prio)); - if (distro) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-DistributionIndicator", octstr_get_cstr(distro)); + if (mclass) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-MessageClass", octstr_get_cstr(mclass)); + if (prio) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-Priority", octstr_get_cstr(prio)); + if (distro) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-DistributionIndicator", octstr_get_cstr(distro)); - if (sheader) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-Content-Header", octstr_get_cstr(sheader)); + if (sheader) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-Content-Header", octstr_get_cstr(sheader)); - if (chargedparty) - HTTP_REPLACE_HEADER(rh, "X-Mbuni-Charged-Party", octstr_get_cstr(chargedparty)); + if (chargedparty) + HTTP_REPLACE_HEADER(rh, "X-Mbuni-Charged-Party", octstr_get_cstr(chargedparty)); - if (validity) { - int diff = atoi(octstr_get_cstr(validity)); - time_t t = time(NULL) + (diff *60); - Octstr *xt = date_format_http(t); + if (validity) { + int diff = atoi(octstr_get_cstr(validity)); + time_t t = time(NULL) + (diff *60); + Octstr *xt = date_format_http(t); - HTTP_REPLACE_HEADER(rh, "X-Mbuni-Expiry", octstr_get_cstr(xt)); + HTTP_REPLACE_HEADER(rh, "X-Mbuni-Expiry", octstr_get_cstr(xt)); - octstr_destroy(xt); - } + octstr_destroy(xt); + } - /* Requests to make_and_queue below can block, but for now we don't care. */ - if (ctype && data && !rb) { /* only send if no error. */ - int send_as_incoming = (send_type && - octstr_str_case_compare(send_type, "mo") == 0); - Octstr *transid = NULL; - if (!send_as_incoming) { /* for outgoing, track TransactionID for DLR. */ - transid = mms_maketransid(NULL, octstr_imm(MM_NAME)); - HTTP_REPLACE_HEADER(rh, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); - } - res = make_and_queue_msg(data, ctype, rh, - data_url ? data_url : base_url, - base_url, URL_TYPE, NULL, - vasid ? vasid : octstr_imm("sendmms-user"), - u->faked_sender, service_code, - 1, NULL, - send_as_incoming ? incoming_qdir : outgoing_qdir, - &err); - if (res < 0) - rb = octstr_format("Error in message conversion: %S", err); - else - rb = octstr_format("Accepted: %S", /* repeat transid. */ - send_as_incoming ? err : transid); - octstr_destroy(transid); - } else if (!rb) - rb = octstr_create("Failed to send message"); - http_send_reply(h->client, (res == 0) ? HTTP_OK : HTTP_BAD_REQUEST, hh, - rb ? rb : octstr_imm("Sent")); - mms_info(0, "mmsbox", NULL,"MMSBox.mmssend: u=%s, %s [%s]", - u ? octstr_get_cstr(u->user) : "none", - (res == 0) ? "Queued" : "Not Queued", - rb ? octstr_get_cstr(rb) : ""); + /* Requests to make_and_queue below can block, but for now we don't care. */ + if (ctype && data && !rb) { /* only send if no error. */ + int send_as_incoming = (send_type && + octstr_str_case_compare(send_type, "mo") == 0); + Octstr *transid = NULL; + if (!send_as_incoming) { /* for outgoing, track TransactionID for DLR. */ + transid = mms_maketransid(NULL, octstr_imm(MM_NAME)); + HTTP_REPLACE_HEADER(rh, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); + } + res = make_and_queue_msg(data, ctype, rh, + data_url ? data_url : base_url, + base_url, URL_TYPE, NULL, + vasid ? vasid : octstr_imm("sendmms-user"), + u->faked_sender, service_code, + 1, NULL, + send_as_incoming ? incoming_qdir : outgoing_qdir, + &err); + if (res < 0) + rb = octstr_format("Error in message conversion: %S", err); + else + rb = octstr_format("Accepted: %S", /* repeat transid. */ + send_as_incoming ? err : transid); + octstr_destroy(transid); + } else if (!rb) + rb = octstr_create("Failed to send message"); + http_send_reply(h->client, (res == 0) ? HTTP_OK : HTTP_BAD_REQUEST, hh, + rb ? rb : octstr_imm("Sent")); + mms_info(0, "mmsbox", NULL,"MMSBox.mmssend: u=%s, %s [%s]", + u ? octstr_get_cstr(u->user) : "none", + (res == 0) ? "Queued" : "Not Queued", + rb ? octstr_get_cstr(rb) : ""); - http_destroy_headers(rh); - octstr_destroy(ctype); - octstr_destroy(rb); - octstr_destroy(base_url); - octstr_destroy(data_url); - octstr_destroy(external_data); - } else { - http_send_reply(h->client, HTTP_UNAUTHORIZED, hh, - octstr_imm("Authentication failed")); - err = octstr_format("MMSBox: SendMMS, Authentication failed, " - "username=%s, password=%s!", - username ? octstr_get_cstr(username) : "(null)", - password ? octstr_get_cstr(password) : "(null)"); - etype = "auth"; - } + http_destroy_headers(rh); + octstr_destroy(ctype); + octstr_destroy(rb); + octstr_destroy(base_url); + octstr_destroy(data_url); + octstr_destroy(external_data); + } else { + http_send_reply(h->client, HTTP_UNAUTHORIZED, hh, + octstr_imm("Authentication failed")); + err = octstr_format("MMSBox: SendMMS, Authentication failed, " + "username=%s, password=%s!", + username ? octstr_get_cstr(username) : "(null)", + password ? octstr_get_cstr(password) : "(null)"); + etype = "auth"; + } - if (err && res != 0) - mms_error_ex(etype, 0, "mmsbox", NULL, "%s", octstr_get_cstr(err)); - octstr_destroy(err); - /* Free the ip and other stuff here. */ + if (err && res != 0) + mms_error_ex(etype, 0, "mmsbox", NULL, "%s", octstr_get_cstr(err)); + octstr_destroy(err); + /* Free the ip and other stuff here. */ - http_destroy_cgiargs(cgivar_ctypes); + http_destroy_cgiargs(cgivar_ctypes); - http_destroy_headers(hh); - free_mmsbox_http_clientInfo(h, 1); - } + http_destroy_headers(hh); + free_mmsbox_http_clientInfo(h, 1); + } } static void sendmms_func(void *unused) { - MmsBoxHTTPClientInfo h = {NULL}; - int i; - List *rl = gwlist_create(); + MmsBoxHTTPClientInfo h = {NULL}; + int i; + List *rl = gwlist_create(); - gwlist_add_producer(rl); + gwlist_add_producer(rl); - for (i = 0; iua = http_header_value(h.headers, octstr_imm("User-Agent")); + *hx = h; + hx->ua = http_header_value(h.headers, octstr_imm("User-Agent")); - gwlist_produce(rl, hx); - } + gwlist_produce(rl, hx); + } - debug("proxy", 0, "MMSBox: MMS-Send Interface shutting down ... "); - gwlist_remove_producer(rl); - gwthread_join_every((void *)dispatch_sendmms_recv); - gwlist_destroy(rl, NULL); - debug("proxy", 0, "MMSBox: MMS-Send Interface shutdown complete. "); + debug("proxy", 0, "MMSBox: MMS-Send Interface shutting down ... "); + gwlist_remove_producer(rl); + gwthread_join_every((void *)dispatch_sendmms_recv); + gwlist_destroy(rl, NULL); + debug("proxy", 0, "MMSBox: MMS-Send Interface shutdown complete. "); } diff --git a/mbuni/mmsc/mms_billing_shell.c b/mbuni/mmsc/mms_billing_shell.c index 67fcf77..ca17b64 100644 --- a/mbuni/mmsc/mms_billing_shell.c +++ b/mbuni/mmsc/mms_billing_shell.c @@ -12,7 +12,9 @@ */ #include #include - +#ifndef DARWIN +#include +#endif #include diff --git a/mbuni/mmsc/mmsc.c b/mbuni/mmsc/mmsc.c index 7916bc2..96586b9 100644 --- a/mbuni/mmsc/mmsc.c +++ b/mbuni/mmsc/mmsc.c @@ -59,8 +59,18 @@ int main(int argc, char *argv[]) if (!settings) panic(0, "No MMSC configuration!"); +#ifdef SA_RESTART + { + struct sigaction nact; + memset(&nact, 0, sizeof(nact)); + nact.sa_handler = relog_now; + nact.sa_flags = SA_RESTART; + sigaction(SIGHUP, &nact, (struct sigaction *)0); + } +#else signal(SIGHUP, relog_now); +#endif signal(SIGTERM, quit_now); signal(SIGINT, quit_now); signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for no reason*/