Added admin interface for mmsbox
This commit is contained in:
parent
30d9e2c0d4
commit
1a3aa4c9aa
|
@ -1,3 +1,5 @@
|
||||||
|
2008-09-02 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
|
* Added admin interface to mmsbox (can now start/stop and see status of any mmsc connection)
|
||||||
2008-09-01 P. A. Bagyenda <bagyenda@dsmagic.com>
|
2008-09-01 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
* Rolled mmsrelay + mmsproxy into one item (for easier online management)
|
* Rolled mmsrelay + mmsproxy into one item (for easier online management)
|
||||||
2008-08-29 P. A. Bagyenda <bagyenda@dsmagic.com>
|
2008-08-29 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
|
|
|
@ -100,6 +100,14 @@ SINGLE_GROUP(mbuni,
|
||||||
|
|
||||||
OCTSTR(mmsbox-mt-filter-library)
|
OCTSTR(mmsbox-mt-filter-library)
|
||||||
OCTSTR(mmsbox-mt-always-multipart)
|
OCTSTR(mmsbox-mt-always-multipart)
|
||||||
|
|
||||||
|
OCTSTR(mmsbox-admin-port)
|
||||||
|
OCTSTR(mmsc-admin-port)
|
||||||
|
OCTSTR(admin-port-ssl)
|
||||||
|
OCTSTR(admin-password)
|
||||||
|
|
||||||
|
OCTSTR(admin-allow-ip)
|
||||||
|
OCTSTR(admin-deny-ip)
|
||||||
)
|
)
|
||||||
|
|
||||||
MULTI_GROUP(mmsproxy,
|
MULTI_GROUP(mmsproxy,
|
||||||
|
|
|
@ -140,7 +140,7 @@ int mmsbox_send_report(Octstr *from, char *report_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These functions are very similar to those in mmsproxy */
|
/* These functions are very similar to those in mmsproxy */
|
||||||
static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
|
static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
|
||||||
{
|
{
|
||||||
|
|
||||||
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
||||||
|
@ -167,6 +167,7 @@ static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
|
||||||
|
|
||||||
if (!mreq) {
|
if (!mreq) {
|
||||||
mresp = mm7_make_resp(NULL, MM7_SOAP_FORMAT_CORRUPT, NULL,1);
|
mresp = mm7_make_resp(NULL, MM7_SOAP_FORMAT_CORRUPT, NULL,1);
|
||||||
|
status = 4000;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,6 +316,7 @@ static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mresp = mm7_make_resp(mreq, MM7_SOAP_UNSUPPORTED_OPERATION, NULL,1);
|
mresp = mm7_make_resp(mreq, MM7_SOAP_UNSUPPORTED_OPERATION, NULL,1);
|
||||||
|
status = MM7_SOAP_UNSUPPORTED_OPERATION;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,9 +344,11 @@ static void mm7soap_receive(MmsBoxHTTPClientInfo *h)
|
||||||
mm7_soap_destroy(mreq);
|
mm7_soap_destroy(mreq);
|
||||||
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
|
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
|
||||||
octstr_destroy(mmc_id);
|
octstr_destroy(mmc_id);
|
||||||
|
|
||||||
|
return MM7_SOAP_STATUS_OK(status) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mm7eaif_receive(MmsBoxHTTPClientInfo *h)
|
static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
|
||||||
{
|
{
|
||||||
MmsMsg *m = NULL;
|
MmsMsg *m = NULL;
|
||||||
List *mh = NULL;
|
List *mh = NULL;
|
||||||
|
@ -547,7 +551,9 @@ static void mm7eaif_receive(MmsBoxHTTPClientInfo *h)
|
||||||
octstr_destroy(mmc_id);
|
octstr_destroy(mmc_id);
|
||||||
|
|
||||||
http_destroy_headers(mh);
|
http_destroy_headers(mh);
|
||||||
mms_destroy(m);
|
mms_destroy(m);
|
||||||
|
|
||||||
|
return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -557,6 +563,7 @@ static void dispatch_mm7_recv(List *rl)
|
||||||
MmsBoxHTTPClientInfo *h;
|
MmsBoxHTTPClientInfo *h;
|
||||||
|
|
||||||
while ((h = gwlist_consume(rl)) != NULL) {
|
while ((h = gwlist_consume(rl)) != NULL) {
|
||||||
|
int ret = -1;
|
||||||
MmscGrp *m = h->m;
|
MmscGrp *m = h->m;
|
||||||
if (auth_check(m->incoming.user,
|
if (auth_check(m->incoming.user,
|
||||||
m->incoming.pass,
|
m->incoming.pass,
|
||||||
|
@ -570,10 +577,16 @@ static void dispatch_mm7_recv(List *rl)
|
||||||
info(0, "MMSBox: Auth failed, incoming connection, MMC group=[%s]",
|
info(0, "MMSBox: Auth failed, incoming connection, MMC group=[%s]",
|
||||||
m->id ? octstr_get_cstr(m->id) : "(none)");
|
m->id ? octstr_get_cstr(m->id) : "(none)");
|
||||||
} else if (h->m->type == SOAP_MMSC)
|
} else if (h->m->type == SOAP_MMSC)
|
||||||
mm7soap_receive(h);
|
ret = mm7soap_receive(h);
|
||||||
else
|
else
|
||||||
mm7eaif_receive(h);
|
ret = mm7eaif_receive(h);
|
||||||
|
|
||||||
|
h->m->last_pdu = time(NULL);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
h->m->mo_pdus++;
|
||||||
|
else
|
||||||
|
h->m->mo_errors++;
|
||||||
free_mmsbox_http_clientInfo(h, 1);
|
free_mmsbox_http_clientInfo(h, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,11 +596,12 @@ void mmsc_receive_func(MmscGrp *m)
|
||||||
int i;
|
int i;
|
||||||
MmsBoxHTTPClientInfo h = {NULL};
|
MmsBoxHTTPClientInfo h = {NULL};
|
||||||
List *mmsc_incoming_reqs = gwlist_create();
|
List *mmsc_incoming_reqs = gwlist_create();
|
||||||
|
long *thids = gw_malloc((maxthreads + 1)*sizeof thids[0]);
|
||||||
|
|
||||||
gwlist_add_producer(mmsc_incoming_reqs);
|
gwlist_add_producer(mmsc_incoming_reqs);
|
||||||
|
|
||||||
for (i = 0; i<maxthreads; i++)
|
for (i = 0; i<maxthreads; i++)
|
||||||
gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs);
|
thids[i] = gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs);
|
||||||
|
|
||||||
h.m = m;
|
h.m = m;
|
||||||
while(rstop == 0 &&
|
while(rstop == 0 &&
|
||||||
|
@ -628,12 +642,17 @@ void mmsc_receive_func(MmscGrp *m)
|
||||||
free_mmsbox_http_clientInfo(&h, 0);
|
free_mmsbox_http_clientInfo(&h, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("proxy", 0, "MMSBox: MM7 receiver Shutting down...");
|
debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down...", octstr_get_cstr(m->id));
|
||||||
gwlist_remove_producer(mmsc_incoming_reqs);
|
gwlist_remove_producer(mmsc_incoming_reqs);
|
||||||
gwthread_join_every((void *)dispatch_mm7_recv);
|
|
||||||
gwlist_destroy(mmsc_incoming_reqs, NULL);
|
|
||||||
|
|
||||||
debug("proxy", 0, "MMSBox: MM7 receiver Shutting down complete.");
|
for (i = 0; i<maxthreads; i++)
|
||||||
|
if (thids[i] >= 0)
|
||||||
|
gwthread_join(thids[i]);
|
||||||
|
|
||||||
|
gwlist_destroy(mmsc_incoming_reqs, NULL);
|
||||||
|
gw_free(thids);
|
||||||
|
|
||||||
|
debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down complete.", octstr_get_cstr(m->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -984,7 +1003,11 @@ static int sendMsg(MmsEnvelope *e)
|
||||||
e->hdrs,
|
e->hdrs,
|
||||||
&new_msgid,
|
&new_msgid,
|
||||||
&err);
|
&err);
|
||||||
|
if (res == MMS_SEND_OK)
|
||||||
|
mmc->mt_pdus++;
|
||||||
|
else
|
||||||
|
mmc->mt_errors++;
|
||||||
|
mmc->last_pdu = time(NULL);
|
||||||
return_mmsc_conn(mmc); /* important. */
|
return_mmsc_conn(mmc); /* important. */
|
||||||
done:
|
done:
|
||||||
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
|
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
|
||||||
|
|
|
@ -574,7 +574,6 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Octstr *fname;
|
Octstr *fname;
|
||||||
int cfidx;
|
int cfidx;
|
||||||
mCfg *cfg;
|
|
||||||
|
|
||||||
long qthread = 0, sthread = 0;
|
long qthread = 0, sthread = 0;
|
||||||
|
|
||||||
|
@ -588,11 +587,9 @@ int main(int argc, char *argv[])
|
||||||
fname = octstr_imm("mbuni.conf");
|
fname = octstr_imm("mbuni.conf");
|
||||||
else
|
else
|
||||||
fname = octstr_create(argv[cfidx]);
|
fname = octstr_create(argv[cfidx]);
|
||||||
|
|
||||||
cfg = mms_cfg_read(fname);
|
|
||||||
|
|
||||||
if (cfg == NULL)
|
if (mms_load_mmsbox_settings(fname,(gwthread_func_t *)mmsc_receive_func) < 0)
|
||||||
panic(0, "Couldn't read configuration from '%s'.", octstr_get_cstr(fname));
|
panic(0, "Configuration file loading failed, file: %s", octstr_get_cstr(fname));
|
||||||
|
|
||||||
octstr_destroy(fname);
|
octstr_destroy(fname);
|
||||||
|
|
||||||
|
@ -600,10 +597,6 @@ int main(int argc, char *argv[])
|
||||||
info(0, " " MM_NAME " MMSBox version %s starting", MMSC_VERSION);
|
info(0, " " MM_NAME " MMSBox version %s starting", MMSC_VERSION);
|
||||||
|
|
||||||
|
|
||||||
mms_load_mmsbox_settings(cfg,(gwthread_func_t *)mmsc_receive_func);
|
|
||||||
|
|
||||||
mms_cfg_destroy(cfg);
|
|
||||||
|
|
||||||
signal(SIGHUP, relog_now);
|
signal(SIGHUP, relog_now);
|
||||||
signal(SIGTERM, quit_now);
|
signal(SIGTERM, quit_now);
|
||||||
signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for nothing*/
|
signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for nothing*/
|
||||||
|
@ -622,7 +615,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
info(0, "Shutdown started..");
|
info(0, "Shutdown started..");
|
||||||
|
|
||||||
mmsbox_cleanup_settings();
|
|
||||||
sleep(2);
|
sleep(2);
|
||||||
/* Wait for the sender thread, then quit. */
|
/* Wait for the sender thread, then quit. */
|
||||||
gwthread_join(qthread); /* Wait for it to die... */
|
gwthread_join(qthread); /* Wait for it to die... */
|
||||||
|
|
|
@ -43,30 +43,51 @@ MmsBoxResolverFuncStruct *rfs; /* resolver functions. */
|
||||||
void *rfs_data;
|
void *rfs_data;
|
||||||
Octstr *rfs_settings;
|
Octstr *rfs_settings;
|
||||||
|
|
||||||
|
static mCfg *cfg; /* Config. */
|
||||||
static Dict *mmscs = NULL; /* MMSC's indexed by ID. */
|
static Dict *mmscs = NULL; /* MMSC's indexed by ID. */
|
||||||
static List *mmsc_del_list = NULL; /* List of items to be deleted. */
|
static List *mmsc_del_list = NULL; /* List of items to be deleted. */
|
||||||
|
|
||||||
|
/* admin handler variables. */
|
||||||
|
static long admin_port;
|
||||||
|
static long admin_thread = -1;
|
||||||
|
static Octstr *admin_pass = NULL;
|
||||||
|
static Octstr *admin_allow_ip = NULL;
|
||||||
|
static Octstr *admin_deny_ip = NULL;
|
||||||
|
|
||||||
|
static gwthread_func_t *mmsc_receiver_func;
|
||||||
|
|
||||||
struct SendMmsPortInfo sendmms_port;
|
struct SendMmsPortInfo sendmms_port;
|
||||||
|
|
||||||
struct MmsBoxMTfilter *mt_filter = NULL;
|
struct MmsBoxMTfilter *mt_filter = NULL;
|
||||||
|
|
||||||
static void free_mmsc_struct (MmscGrp *m);
|
static void free_mmsc_struct (MmscGrp *m);
|
||||||
static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func);
|
|
||||||
static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc);
|
static void admin_handler(void *unused);
|
||||||
int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
|
||||||
|
int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
|
||||||
{
|
{
|
||||||
mCfgGrp *grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
|
mCfgGrp *grp;
|
||||||
mCfgGrp *cgrp = mms_cfg_get_single(cfg, octstr_imm("core"));
|
mCfgGrp *cgrp;
|
||||||
Octstr *gdir = NULL, *s;
|
Octstr *gdir = NULL, *s;
|
||||||
|
|
||||||
int send_port_ssl = 0;
|
int send_port_ssl = 0, admin_port_ssl = 0;
|
||||||
List *l;
|
List *l;
|
||||||
int i, n, xx;
|
int i, n, xx;
|
||||||
void *catchall = NULL;
|
void *catchall = NULL;
|
||||||
|
|
||||||
if (grp == NULL)
|
|
||||||
panic(0,"Missing required group `mbuni' in config file!");
|
if ((cfg = mms_cfg_read(fname)) == NULL) {
|
||||||
|
error(0, "Couldn't read configuration from '%s'.", octstr_get_cstr(fname));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
|
||||||
|
cgrp = mms_cfg_get_single(cfg, octstr_imm("core"));
|
||||||
|
|
||||||
|
if (grp == NULL) {
|
||||||
|
error(0,"Missing required group `mbuni' in config file!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
mms_load_core_settings(cfg, cgrp);
|
mms_load_core_settings(cfg, cgrp);
|
||||||
|
|
||||||
|
@ -201,10 +222,29 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
||||||
}
|
}
|
||||||
gwlist_destroy(l, NULL);
|
gwlist_destroy(l, NULL);
|
||||||
|
|
||||||
/* Get mmsc list. */
|
mmsc_receiver_func = mmsc_handler_func; /* save it. */
|
||||||
|
|
||||||
|
/* Start MMSCs. */
|
||||||
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
|
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
|
||||||
for (i = 0, n = gwlist_len(l); i < n; i++)
|
for (i = 0, n = gwlist_len(l); i < n; i++) {
|
||||||
start_mmsc_from_conf(cfg, gwlist_get(l, i), mmsc_handler_func);
|
List *errors = gwlist_create();
|
||||||
|
List *warnings = gwlist_create();
|
||||||
|
Octstr *x;
|
||||||
|
|
||||||
|
start_mmsc_from_conf(cfg, gwlist_get(l, i), mmsc_handler_func, errors, warnings);
|
||||||
|
|
||||||
|
while ((x = gwlist_extract_first(errors)) != NULL) {
|
||||||
|
error(0, "%s", octstr_get_cstr(x));
|
||||||
|
octstr_destroy(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((x = gwlist_extract_first(warnings)) != NULL) {
|
||||||
|
warning(0, "%s", octstr_get_cstr(x));
|
||||||
|
octstr_destroy(x);
|
||||||
|
}
|
||||||
|
gwlist_destroy(errors, NULL);
|
||||||
|
gwlist_destroy(warnings, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
gwlist_destroy(l, NULL);
|
gwlist_destroy(l, NULL);
|
||||||
|
|
||||||
|
@ -348,13 +388,37 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
||||||
|
|
||||||
gwlist_append(mms_services, m);
|
gwlist_append(mms_services, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Finally load admin-port config and start the thingie */
|
||||||
|
|
||||||
|
mms_cfg_get_int(cfg, grp, octstr_imm("mmsbox-admin-port"), &admin_port);
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
mms_cfg_get_bool(cfg, grp, octstr_imm("admin-port-ssl"), &admin_port_ssl);
|
||||||
|
#endif
|
||||||
|
admin_pass = mms_cfg_get(cfg, grp, octstr_imm("admin-password"));
|
||||||
|
|
||||||
|
admin_allow_ip = mms_cfg_get(cfg, grp, octstr_imm("admin-allow-ip"));
|
||||||
|
admin_deny_ip = mms_cfg_get(cfg, grp, octstr_imm("admin-deny-ip"));
|
||||||
|
|
||||||
|
if (admin_port > 0 &&
|
||||||
|
http_open_port(admin_port, admin_port_ssl)< 0)
|
||||||
|
error(0, "Failed to start admin server on port %d: %s",
|
||||||
|
(int)admin_port, strerror(errno));
|
||||||
|
else if (admin_port > 0 &&
|
||||||
|
(admin_thread = gwthread_create((gwthread_func_t *)admin_handler, NULL)) < 0) {
|
||||||
|
error(0, "Failed to start admin server thread: %s",
|
||||||
|
strerror(errno));
|
||||||
|
http_close_port(admin_port);
|
||||||
|
} else if (admin_pass == NULL)
|
||||||
|
warning(0, "Empty or no password supplied for admin port. All requests will be allowed!");
|
||||||
|
|
||||||
gwlist_destroy(l, NULL);
|
gwlist_destroy(l, NULL);
|
||||||
octstr_destroy(gdir);
|
octstr_destroy(gdir);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do nothing func. */
|
/* do nothing func: Vital it returns 0! */
|
||||||
static int do_nothing_func (void) {return 0;}
|
static int do_nothing_func (void) {return 0;}
|
||||||
|
|
||||||
static MmsBoxMmscFuncs dummy_mmsc_funcs = {
|
static MmsBoxMmscFuncs dummy_mmsc_funcs = {
|
||||||
|
@ -363,7 +427,62 @@ static MmsBoxMmscFuncs dummy_mmsc_funcs = {
|
||||||
(void *)do_nothing_func
|
(void *)do_nothing_func
|
||||||
};
|
};
|
||||||
|
|
||||||
void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func)
|
#define ERROR(fmt,...) do {if (errors) gwlist_append(errors, octstr_format((fmt), ##__VA_ARGS__));} while(0)
|
||||||
|
#define WARNING(fmt,...) do {if (warnings) gwlist_append(warnings, octstr_format((fmt), ##__VA_ARGS__));}while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mmc->type == CUSTOM_MMSC && mmc->fns
|
||||||
|
&& mmc->custom_started) {
|
||||||
|
mmc->fns->stop_conn(mmc->data);
|
||||||
|
mmc->custom_started = 0;
|
||||||
|
} else if (mmc->incoming.port > 0) {
|
||||||
|
http_close_port(mmc->incoming.port);
|
||||||
|
if (mmc->threadid >= 0)
|
||||||
|
gwthread_join(mmc->threadid);
|
||||||
|
mmc->threadid = -1;
|
||||||
|
}
|
||||||
|
info(0, "Shutdown for mmsc [%s] complete", octstr_get_cstr(mmc->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func,
|
||||||
|
List *errors, List *warnings)
|
||||||
|
{
|
||||||
|
if (m->type == CUSTOM_MMSC) {
|
||||||
|
if (m->fns->start_conn(m, qfs, unified_prefix, strip_prefixes, &m->data) != 0) {
|
||||||
|
WARNING("MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id));
|
||||||
|
m->custom_started = 0;
|
||||||
|
} else
|
||||||
|
m->custom_started = 1;
|
||||||
|
} else {
|
||||||
|
if (m->incoming.port > 0 &&
|
||||||
|
http_open_port(m->incoming.port, m->incoming.ssl) < 0) {
|
||||||
|
WARNING("MMSBox: Failed to start HTTP server on receive port for "
|
||||||
|
" MMSC %s, port %ld: %s!",
|
||||||
|
octstr_get_cstr(m->id), m->incoming.port,
|
||||||
|
strerror(errno));
|
||||||
|
m->incoming.port = 0; /* so we don't listen on it. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */
|
||||||
|
if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0)
|
||||||
|
ERROR("MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!",
|
||||||
|
octstr_get_cstr(m->id), strerror(errno));
|
||||||
|
} else
|
||||||
|
m->threadid = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
info(0, "Startup for mmsc [%s] complete", octstr_get_cstr(m->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func,
|
||||||
|
List *warnings, List *errors)
|
||||||
{
|
{
|
||||||
|
|
||||||
MmscGrp *m = gw_malloc(sizeof *m);
|
MmscGrp *m = gw_malloc(sizeof *m);
|
||||||
|
@ -373,14 +492,14 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
|
||||||
Octstr *s;
|
Octstr *s;
|
||||||
|
|
||||||
memset(m, 0, sizeof *m);
|
memset(m, 0, sizeof *m);
|
||||||
|
|
||||||
m->id = _mms_cfg_getx(cfg, x, octstr_imm("id"));
|
m->id = _mms_cfg_getx(cfg, x, octstr_imm("id"));
|
||||||
if (octstr_len(m->id) < 1) {
|
if (octstr_len(m->id) < 1) {
|
||||||
error(0,"mmsbox.mmsc_config: Missing required field value `id' in config file!");
|
ERROR("mmsbox.mmsc_config: Missing required field value `id' in config file!");
|
||||||
octstr_destroy(m->id);
|
octstr_destroy(m->id);
|
||||||
gw_free(m);
|
gw_free(m);
|
||||||
|
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->group_id = mms_cfg_get(cfg, x, octstr_imm("group-id"));
|
m->group_id = mms_cfg_get(cfg, x, octstr_imm("group-id"));
|
||||||
|
@ -432,7 +551,7 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
|
||||||
m->fns = &dummy_mmsc_funcs;
|
m->fns = &dummy_mmsc_funcs;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
warning(0, "MMSBox: Unknown MMSC type [%s]!",
|
WARNING("MMSBox: Unknown MMSC type [%s]!",
|
||||||
octstr_get_cstr(type));
|
octstr_get_cstr(type));
|
||||||
if ((xver = _mms_cfg_getx(cfg, x, octstr_imm("mm7-version"))) != NULL &&
|
if ((xver = _mms_cfg_getx(cfg, x, octstr_imm("mm7-version"))) != NULL &&
|
||||||
octstr_len(xver) > 0)
|
octstr_len(xver) > 0)
|
||||||
|
@ -468,11 +587,11 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
|
||||||
if (mt_filter)
|
if (mt_filter)
|
||||||
m->use_mt_filter = (mt_filter->init(m->mmsc_url, m->id, s) == 1);
|
m->use_mt_filter = (mt_filter->init(m->mmsc_url, m->id, s) == 1);
|
||||||
else
|
else
|
||||||
panic(0, "MMSBox: mt-filter-params set for MMSC[%s] but no MT-filter lib "
|
ERROR("MMSBox: mt-filter-params set for MMSC[%s] but no MT-filter lib "
|
||||||
"specified!",
|
"specified!",
|
||||||
octstr_get_cstr(m->id));
|
octstr_get_cstr(m->id));
|
||||||
if (!m->use_mt_filter)
|
if (!m->use_mt_filter)
|
||||||
warning(0, "MMSBox: MT MMS filter turned off for MMSC[%s]. Init failed",
|
WARNING( "MMSBox: MT MMS filter turned off for MMSC[%s]. Init failed",
|
||||||
octstr_get_cstr(m->id));
|
octstr_get_cstr(m->id));
|
||||||
octstr_destroy(s);
|
octstr_destroy(s);
|
||||||
} else
|
} else
|
||||||
|
@ -482,77 +601,38 @@ void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_f
|
||||||
mms_cfg_get_bool(cfg, x, octstr_imm("reroute-add-sender-to-subject"), &m->reroute_mod_subject);
|
mms_cfg_get_bool(cfg, x, octstr_imm("reroute-add-sender-to-subject"), &m->reroute_mod_subject);
|
||||||
m->reroute_mmsc_id = mms_cfg_get(cfg, x, octstr_imm("reroute-mmsc-id"));
|
m->reroute_mmsc_id = mms_cfg_get(cfg, x, octstr_imm("reroute-mmsc-id"));
|
||||||
if (m->reroute_mmsc_id != NULL && m->reroute == 0)
|
if (m->reroute_mmsc_id != NULL && m->reroute == 0)
|
||||||
warning(0, "MMSBox: reroute-mmsc-id parameter set but reroute=false!");
|
WARNING("MMSBox: reroute-mmsc-id parameter set but reroute=false!");
|
||||||
|
|
||||||
mms_cfg_get_bool(cfg, x, octstr_imm("no-sender-address"), &m->no_senderaddress);
|
mms_cfg_get_bool(cfg, x, octstr_imm("no-sender-address"), &m->no_senderaddress);
|
||||||
m->mutex = mutex_create();
|
m->mutex = mutex_create();
|
||||||
m->incoming.ssl = ssl;
|
m->incoming.ssl = ssl;
|
||||||
|
m->start_time = time(NULL);
|
||||||
|
|
||||||
/* finally start the thingie. */
|
/* finally start the thingie. */
|
||||||
mmsbox_start_mmsc_conn(m, mmsc_handler_func);
|
mmsbox_start_mmsc_conn(m, mmsc_handler_func, errors, warnings);
|
||||||
if (dict_put_once(mmscs, m->id, m) == 0) {
|
if (dict_put_once(mmscs, m->id, m) == 0) {
|
||||||
error(0, "Failed to load mmsc <%s>. ID is not unique!", octstr_get_cstr(m->id));
|
WARNING("Failed to load mmsc <%s>. ID is not unique!", octstr_get_cstr(m->id));
|
||||||
mmsbox_stop_mmsc_conn_real(m);
|
mmsbox_stop_mmsc_conn_real(m);
|
||||||
free_mmsc_struct(m);
|
free_mmsc_struct(m);
|
||||||
}
|
m = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func)
|
|
||||||
{
|
|
||||||
if (m->type == CUSTOM_MMSC) {
|
|
||||||
if (m->fns->start_conn(m, qfs, unified_prefix, strip_prefixes, &m->data) != 0) {
|
|
||||||
warning(0, "MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id));
|
|
||||||
m->custom_started = 0;
|
|
||||||
} else
|
|
||||||
m->custom_started = 1;
|
|
||||||
} else {
|
|
||||||
if (m->incoming.port > 0 &&
|
|
||||||
http_open_port(m->incoming.port, m->incoming.ssl) < 0) {
|
|
||||||
warning(0, "MMSBox: Failed to start HTTP server on receive port for "
|
|
||||||
" MMSC %s, port %ld: %s!",
|
|
||||||
octstr_get_cstr(m->id), m->incoming.port,
|
|
||||||
strerror(errno));
|
|
||||||
m->incoming.port = 0; /* so we don't listen on it. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */
|
|
||||||
if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0)
|
|
||||||
error(0, "MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!",
|
|
||||||
octstr_get_cstr(m->id), strerror(errno));
|
|
||||||
} else
|
|
||||||
m->threadid = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info(0, "Startup for mmsc [%s] complete", octstr_get_cstr(m->id));
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc)
|
int mmsbox_stop_mmsc_conn(Octstr *mmc_id)
|
||||||
{
|
|
||||||
|
|
||||||
if (mmc->type == CUSTOM_MMSC && mmc->fns
|
|
||||||
&& mmc->custom_started) {
|
|
||||||
mmc->fns->stop_conn(mmc->data);
|
|
||||||
mmc->custom_started = 0;
|
|
||||||
} else if (mmc->incoming.port > 0) {
|
|
||||||
http_close_port(mmc->incoming.port);
|
|
||||||
if (mmc->threadid >= 0)
|
|
||||||
gwthread_join(mmc->threadid);
|
|
||||||
mmc->threadid = -1;
|
|
||||||
}
|
|
||||||
info(0, "Shutdown for mmsc [%s] complete", octstr_get_cstr(mmc->id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmsbox_stop_mmsc_conn(Octstr *mmc_id)
|
|
||||||
{
|
{
|
||||||
MmscGrp *mmc = dict_remove(mmscs, mmc_id); /* remove it so no one else can get it. */
|
MmscGrp *mmc = dict_remove(mmscs, mmc_id); /* remove it so no one else can get it. */
|
||||||
|
|
||||||
if (mmc == NULL)
|
if (mmc == NULL)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
mmsbox_stop_mmsc_conn_real(mmc);
|
mmsbox_stop_mmsc_conn_real(mmc);
|
||||||
|
|
||||||
mmc->delete_after = time(NULL) + 5*60; /* delete after 5 minutes. */
|
mmc->delete_after = time(NULL) + 5*60; /* delete after 5 minutes. */
|
||||||
gwlist_append(mmsc_del_list, mmc); /* to be deleted later. */
|
gwlist_append(mmsc_del_list, mmc); /* to be deleted later. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmsbox_stop_all_mmsc_conn(void)
|
void mmsbox_stop_all_mmsc_conn(void)
|
||||||
|
@ -663,6 +743,18 @@ void mmsbox_settings_cleanup(void)
|
||||||
{
|
{
|
||||||
delete_stale_mmsc(1);
|
delete_stale_mmsc(1);
|
||||||
|
|
||||||
|
/* eventually we will destroy the object. For now, we only cleanup queue module. */
|
||||||
|
if (qfs)
|
||||||
|
qfs->mms_cleanup_queue_module();
|
||||||
|
|
||||||
|
if (admin_port > 0) {
|
||||||
|
http_close_port(admin_port);
|
||||||
|
gwthread_join(admin_thread);
|
||||||
|
info(0, "MmsBox: Admin port on %d, shutdown", (int)admin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mms_cfg_destroy(cfg); /* only delete at end of session. */
|
||||||
/* More cleanups to follow. */
|
/* More cleanups to follow. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,11 +828,223 @@ Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmsbox_cleanup_settings(void)
|
static void append_mmsc_status(Octstr *rbody, MmscGrp *m, List *warnings)
|
||||||
{
|
{
|
||||||
/* eventually we will destroy the object. For now, we only cleanup queue module. */
|
time_t t = time(NULL);
|
||||||
if (qfs)
|
int i, n;
|
||||||
qfs->mms_cleanup_queue_module();
|
unsigned long tdiff;
|
||||||
|
char lbuf[128], ubuf[128], tmp[64], xport[32];
|
||||||
|
|
||||||
|
char *typ;
|
||||||
|
|
||||||
|
if (m->type == SOAP_MMSC)
|
||||||
|
typ = "SOAP";
|
||||||
|
else if (m->type == EAIF_MMSC)
|
||||||
|
typ = "EAIF";
|
||||||
|
else if (m->type == CUSTOM_MMSC)
|
||||||
|
typ = "CUSTOM";
|
||||||
|
else
|
||||||
|
typ = "none";
|
||||||
|
|
||||||
|
if (m->last_pdu > 0) {
|
||||||
|
struct tm tm = gw_localtime(m->last_pdu);
|
||||||
|
gw_strftime(lbuf,sizeof lbuf, "%x %X", &tm);
|
||||||
|
} else
|
||||||
|
strcpy(lbuf, "n/a");
|
||||||
|
|
||||||
|
/* Compute uptime */
|
||||||
|
tdiff = t - m->start_time;
|
||||||
|
if (tdiff >= 24*3600) {/* we have some days */
|
||||||
|
sprintf(ubuf, "%ld days", tdiff/(24*3600));
|
||||||
|
|
||||||
|
tdiff %= 24*3600;
|
||||||
|
} else
|
||||||
|
ubuf[0] = 0;
|
||||||
|
|
||||||
|
if (tdiff >= 3600) {
|
||||||
|
long x = tdiff/3600;
|
||||||
|
sprintf(tmp, "%s%ld hrs", ubuf[0] ? " " : "", x);
|
||||||
|
strcat(ubuf, tmp);
|
||||||
|
tdiff %= 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdiff >= 60) {
|
||||||
|
sprintf(tmp, "%s%ld mins", ubuf[0] ? " " : "", tdiff/60);
|
||||||
|
strcat(ubuf, tmp);
|
||||||
|
tdiff %= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdiff > 0) {
|
||||||
|
sprintf(tmp, "%s%ld secs", ubuf[0] ? " " : "", tdiff);
|
||||||
|
strcat(ubuf, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->type != CUSTOM_MMSC)
|
||||||
|
sprintf(xport, "%d", (int)m->incoming.port);
|
||||||
|
else
|
||||||
|
sprintf(xport, "n/a");
|
||||||
|
octstr_format_append(rbody, "<Mmsc id=\"%S\" type=\"%s\">\n "
|
||||||
|
"<Port>%s</Port>\n"
|
||||||
|
"<Group>%S</Group>\n"
|
||||||
|
"<Throughput>%.4f</Throughput>\n"
|
||||||
|
"<Reroute>%s</Reroute>\n"
|
||||||
|
"<Reroute-MMSC-ID>%S</Reroute-MMSC-ID>\n"
|
||||||
|
"<Stats>\n"
|
||||||
|
"<Uptime>%s</Uptime>\n"
|
||||||
|
"<LastPDU>%s</LastPDU>\n"
|
||||||
|
"<MT><PDUS>%ld</PDUS><ERRORS>%ld</ERRORS></MT>\n"
|
||||||
|
"<MO><PDUS>%ld</PDUS><ERRORS>%ld</ERRORS></MO>\n"
|
||||||
|
"</Stats>\n",
|
||||||
|
m->id,
|
||||||
|
typ,
|
||||||
|
xport,
|
||||||
|
m->group_id ? m->group_id : octstr_imm("n/a"),
|
||||||
|
m->throughput,
|
||||||
|
m->reroute ? "true" : "false",
|
||||||
|
m->reroute_mmsc_id ? m->reroute_mmsc_id : octstr_imm("N/A"),
|
||||||
|
ubuf,
|
||||||
|
lbuf,
|
||||||
|
(long)m->mt_pdus, (long)m->mt_errors,
|
||||||
|
(long)m->mo_pdus, (long)m->mo_errors);
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0, n = gwlist_len(warnings); i<n; i++)
|
||||||
|
octstr_format_append(rbody, "<Warning>%S</Warning>\n", gwlist_get(warnings, i));
|
||||||
|
|
||||||
|
octstr_append_cstr(rbody, "</Mmsc>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void admin_handler(void *unused)
|
||||||
|
{
|
||||||
|
HTTPClient *client;
|
||||||
|
Octstr *ip;
|
||||||
|
List *headers;
|
||||||
|
Octstr *url;
|
||||||
|
Octstr *body;
|
||||||
|
List *cgivars;
|
||||||
|
Octstr *pass;
|
||||||
|
Octstr *cmd;
|
||||||
|
|
||||||
|
|
||||||
|
info(0, "MmsBox: Admin Interface -- startup on port %d", (int)admin_port);
|
||||||
|
|
||||||
|
while((client = http_accept_request(admin_port,
|
||||||
|
&ip, &url, &headers,
|
||||||
|
&body, &cgivars)) != NULL) {
|
||||||
|
int flg = -1;
|
||||||
|
Octstr *rbody = NULL;
|
||||||
|
int rstatus = HTTP_OK;
|
||||||
|
|
||||||
|
if (!(flg = is_allowed_ip(admin_allow_ip, admin_deny_ip, ip)) ||
|
||||||
|
((pass = http_cgi_variable(cgivars, "password")) == NULL && admin_pass != NULL) ||
|
||||||
|
(admin_pass && octstr_compare(pass, admin_pass) != 0)) {
|
||||||
|
error(0, "MmsBox: Improper access to mmsbox admin interface from IP[%s]: %s",
|
||||||
|
octstr_get_cstr(ip),
|
||||||
|
flg ? "Invalid/empty password" : "IP not allowed");
|
||||||
|
if (flg) {/* means it is allowed by IP */
|
||||||
|
rstatus = HTTP_UNAUTHORIZED;
|
||||||
|
rbody = octstr_imm("Auth failed");
|
||||||
|
}
|
||||||
|
} else if ((cmd = http_cgi_variable(cgivars, "command")) == NULL) {
|
||||||
|
rbody = octstr_imm("Missing Command Parameter");
|
||||||
|
rstatus = HTTP_BAD_REQUEST;
|
||||||
|
} else {
|
||||||
|
Octstr *mmc_id = http_cgi_variable(cgivars, "mmsc-id");
|
||||||
|
List *l = NULL;
|
||||||
|
|
||||||
|
rbody = octstr_create("<?xml version='1.0'?>\n");
|
||||||
|
/* Command is one of: status, start, stop.
|
||||||
|
* mmsc-id is either empty (meaning ALL) or an ID of an existing MMSC connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (octstr_str_case_compare(cmd, "start") == 0) {
|
||||||
|
mCfgGrp *m;
|
||||||
|
if (mmc_id == NULL)
|
||||||
|
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
|
||||||
|
else if ((m = mms_get_multi_by_field(cfg,
|
||||||
|
octstr_imm("mmsc"),
|
||||||
|
octstr_imm("id"),
|
||||||
|
mmc_id)) != NULL) {
|
||||||
|
l = gwlist_create();
|
||||||
|
gwlist_append(l, m);
|
||||||
|
}
|
||||||
|
/* Start MMSCs. */
|
||||||
|
|
||||||
|
while ((m = gwlist_extract_first(l)) != NULL) {
|
||||||
|
List *e = gwlist_create();
|
||||||
|
List *w = gwlist_create();
|
||||||
|
Octstr *x;
|
||||||
|
MmscGrp *mc = start_mmsc_from_conf(cfg, m, mmsc_receiver_func, e, w);
|
||||||
|
|
||||||
|
if (mc != NULL)
|
||||||
|
append_mmsc_status(rbody, mc, w);
|
||||||
|
else if (gwlist_len(e) > 0)
|
||||||
|
while ((x = gwlist_extract_first(e)) != NULL) {
|
||||||
|
octstr_format_append(rbody,
|
||||||
|
"<Start-Mmsc><Error>%S</Error></Start-Mmsc>\n",
|
||||||
|
x);
|
||||||
|
octstr_destroy(x);
|
||||||
|
}
|
||||||
|
gwlist_destroy(e, (void *)octstr_destroy);
|
||||||
|
gwlist_destroy(w, (void *)octstr_destroy);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (octstr_str_case_compare(cmd, "stop") == 0) {
|
||||||
|
Octstr *x;
|
||||||
|
if (mmc_id == NULL)
|
||||||
|
l = dict_keys(mmscs);
|
||||||
|
else {
|
||||||
|
l = gwlist_create();
|
||||||
|
gwlist_append(l, octstr_duplicate(mmc_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((x = gwlist_extract_first(l)) != NULL) {
|
||||||
|
int ret = mmsbox_stop_mmsc_conn(x);
|
||||||
|
octstr_format_append(rbody,
|
||||||
|
"<Stop-Mmsc><%s/></Stop-Mmsc>\n",
|
||||||
|
ret == 0 ? "Success" : "Failed");
|
||||||
|
octstr_destroy(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (octstr_str_case_compare(cmd, "status") == 0) {
|
||||||
|
Octstr *x;
|
||||||
|
MmscGrp *mc;
|
||||||
|
if (mmc_id == NULL)
|
||||||
|
l = dict_keys(mmscs);
|
||||||
|
else {
|
||||||
|
l = gwlist_create();
|
||||||
|
gwlist_append(l, octstr_duplicate(mmc_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((x = gwlist_extract_first(l)) != NULL) {
|
||||||
|
if ((mc = dict_get(mmscs, x)) != NULL)
|
||||||
|
append_mmsc_status(rbody, mc, NULL);
|
||||||
|
octstr_destroy(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gwlist_destroy(l, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rbody) {
|
||||||
|
List *rh = http_create_empty_headers();
|
||||||
|
http_header_add(rh, "Content-Type", "text/xml");
|
||||||
|
http_send_reply(client, rstatus, rh, rbody);
|
||||||
|
|
||||||
|
http_destroy_headers(rh);
|
||||||
|
|
||||||
|
} else
|
||||||
|
http_close_client(client);
|
||||||
|
|
||||||
|
octstr_destroy(rbody);
|
||||||
|
octstr_destroy(ip);
|
||||||
|
octstr_destroy(url);
|
||||||
|
octstr_destroy(body);
|
||||||
|
http_destroy_cgiargs(cgivars);
|
||||||
|
http_destroy_headers(headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
info(0, "MmsBox: Admin Interface -- shuttind down on port %d", (int)admin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_mmsbox_http_clientInfo(MmsBoxHTTPClientInfo *h, int freeh)
|
void free_mmsbox_http_clientInfo(MmsBoxHTTPClientInfo *h, int freeh)
|
||||||
|
|
|
@ -49,6 +49,14 @@ typedef struct MmscGrp {
|
||||||
void *data; /* data for above module. */
|
void *data; /* data for above module. */
|
||||||
int custom_started; /* set to 1 if custom mmc started. */
|
int custom_started; /* set to 1 if custom mmc started. */
|
||||||
|
|
||||||
|
unsigned long mt_pdus; /* number of MT PDUs since start. */
|
||||||
|
unsigned long mo_pdus; /* number of MO PDUs since start. */
|
||||||
|
unsigned long mt_errors; /* number of MT errors since start */
|
||||||
|
unsigned long mo_errors; /* number of MO errors since start */
|
||||||
|
|
||||||
|
time_t last_pdu; /* time of last PDU */
|
||||||
|
time_t start_time; /* when was this connection started */
|
||||||
|
|
||||||
int use_count; /* use counter. */
|
int use_count; /* use counter. */
|
||||||
time_t delete_after; /* used to control deletion of object -- not ver clean, but... */
|
time_t delete_after; /* used to control deletion of object -- not ver clean, but... */
|
||||||
} MmscGrp;
|
} MmscGrp;
|
||||||
|
@ -131,16 +139,16 @@ extern void *rfs_data;
|
||||||
extern Octstr *rfs_settings;
|
extern Octstr *rfs_settings;
|
||||||
|
|
||||||
|
|
||||||
extern int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func);
|
extern int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func);
|
||||||
extern void mmsbox_settings_cleanup(void);
|
extern void mmsbox_settings_cleanup(void);
|
||||||
extern MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from);
|
extern MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from);
|
||||||
extern void return_mmsc_conn(MmscGrp *m);
|
extern void return_mmsc_conn(MmscGrp *m);
|
||||||
|
|
||||||
extern Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
|
extern Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
|
||||||
Octstr **mmc_id);
|
Octstr **mmc_id);
|
||||||
extern void mmsbox_cleanup_settings(void);
|
MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func,
|
||||||
void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func);
|
List *errors, List *warnings);
|
||||||
void mmsbox_stop_mmsc_conn(Octstr *mmc);
|
int mmsbox_stop_mmsc_conn(Octstr *mmc);
|
||||||
void mmsbox_stop_all_mmsc_conn(void);
|
void mmsbox_stop_all_mmsc_conn(void);
|
||||||
typedef struct MmsBoxHTTPClientInfo {
|
typedef struct MmsBoxHTTPClientInfo {
|
||||||
HTTPClient *client;
|
HTTPClient *client;
|
||||||
|
|
Loading…
Reference in New Issue