00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #include <errno.h>
00068 #include <stdlib.h>
00069 #include <stdio.h>
00070 #include <time.h>
00071 #include <string.h>
00072 #include <signal.h>
00073 #include <unistd.h>
00074
00075 #include "gwlib/gwlib.h"
00076 #include "msg.h"
00077 #include "bearerbox.h"
00078 #include "shared.h"
00079 #include "dlr.h"
00080
00081
00082
00083 List *incoming_sms;
00084 List *outgoing_sms;
00085
00086 List *incoming_wdp;
00087 List *outgoing_wdp;
00088
00089 Counter *incoming_sms_counter;
00090 Counter *outgoing_sms_counter;
00091 Counter *incoming_wdp_counter;
00092 Counter *outgoing_wdp_counter;
00093
00094
00095 long max_incoming_sms_qlength;
00096 long max_outgoing_sms_qlength;
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 List *flow_threads;
00108
00109
00110
00111
00112
00113 List *suspended;
00114
00115
00116
00117
00118 List *isolated;
00119
00120 volatile sig_atomic_t bb_status;
00121
00122
00123
00124
00125 enum {
00126 BB_LOGREOPEN = 1,
00127 BB_CHECKLEAKS = 2
00128 };
00129
00130 static volatile sig_atomic_t bb_todo = 0;
00131
00132
00133
00134 static Mutex *status_mutex;
00135 static time_t start_time;
00136 volatile sig_atomic_t restart = 0;
00137
00138
00139
00140
00141 static void set_shutdown_status(void)
00142 {
00143 sig_atomic_t old = bb_status;
00144 bb_status = BB_SHUTDOWN;
00145
00146 if (old == BB_SUSPENDED)
00147 gwlist_remove_producer(suspended);
00148 if (old == BB_SUSPENDED || old == BB_ISOLATED)
00149 gwlist_remove_producer(isolated);
00150 }
00151
00152
00153
00154
00155
00156
00157 static void signal_handler(int signum)
00158 {
00159
00160
00161
00162
00163
00164 if (!gwthread_shouldhandlesignal(signum))
00165 return;
00166
00167 switch (signum) {
00168 case SIGINT:
00169 case SIGTERM:
00170 if (bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) {
00171 bb_status = BB_SHUTDOWN;
00172 }
00173 else if (bb_status == BB_SHUTDOWN) {
00174 bb_status = BB_DEAD;
00175 }
00176 else if (bb_status == BB_DEAD) {
00177 panic(0, "Cannot die by its own will");
00178 }
00179 break;
00180
00181 case SIGHUP:
00182 bb_todo |= BB_LOGREOPEN;
00183 break;
00184
00185
00186
00187
00188
00189 case SIGQUIT:
00190 bb_todo |= BB_CHECKLEAKS;
00191 break;
00192 }
00193 }
00194
00195 static void setup_signal_handlers(void)
00196 {
00197 struct sigaction act;
00198
00199 act.sa_handler = signal_handler;
00200 sigemptyset(&act.sa_mask);
00201 act.sa_flags = 0;
00202 sigaction(SIGINT, &act, NULL);
00203 sigaction(SIGTERM, &act, NULL);
00204 sigaction(SIGQUIT, &act, NULL);
00205 sigaction(SIGHUP, &act, NULL);
00206 sigaction(SIGPIPE, &act, NULL);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 static int start_smsc(Cfg *cfg)
00218 {
00219 static int started = 0;
00220
00221 if (started)
00222 return 0;
00223
00224 smsbox_start(cfg);
00225
00226 smsc2_start(cfg);
00227
00228 started = 1;
00229 return 0;
00230 }
00231
00232
00233 static void wdp_router(void *arg)
00234 {
00235 Msg *msg;
00236
00237 gwlist_add_producer(flow_threads);
00238
00239 while (bb_status != BB_DEAD) {
00240
00241 if ((msg = gwlist_consume(outgoing_wdp)) == NULL)
00242 break;
00243
00244 gw_assert(msg_type(msg) == wdp_datagram);
00245
00246
00247
00248
00249
00250
00251
00252 udp_addwdp(msg);
00253 }
00254 udp_die();
00255
00256
00257 gwlist_remove_producer(flow_threads);
00258 }
00259
00260
00261 static int start_wap(Cfg *cfg)
00262 {
00263 static int started = 0;
00264
00265 if (started)
00266 return 0;
00267
00268 wapbox_start(cfg);
00269
00270 debug("bb", 0, "starting WDP router");
00271 if (gwthread_create(wdp_router, NULL) == -1)
00272 panic(0, "Failed to start a new thread for WDP routing");
00273
00274 started = 1;
00275 return 0;
00276 }
00277
00278
00279 static int start_udp(Cfg *cfg)
00280 {
00281 static int started = 0;
00282
00283 if (started)
00284 return 0;
00285
00286 udp_start(cfg);
00287
00288 start_wap(cfg);
00289 started = 1;
00290 return 0;
00291 }
00292
00293
00294
00295
00296
00297 static int check_config(Cfg *cfg)
00298 {
00299 CfgGroup *grp;
00300 long smsp, wapp;
00301
00302 grp = cfg_get_single_group(cfg, octstr_imm("core"));
00303 if (grp == NULL)
00304 return -1;
00305
00306 if (cfg_get_integer(&smsp, grp, octstr_imm("smsbox-port")) == -1)
00307 smsp = -1;
00308 if (cfg_get_integer(&wapp, grp, octstr_imm("wapbox-port")) == -1)
00309 wapp = -1;
00310
00311 #ifndef NO_SMS
00312 grp = cfg_get_single_group(cfg, octstr_imm("smsbox"));
00313 if (smsp != -1 && grp == NULL) {
00314 error(0, "No 'smsbox' group in configuration, but smsbox-port set");
00315 return -1;
00316 }
00317 #else
00318 warning(0, "Kannel was compiled without SMS support");
00319 #endif
00320
00321 #ifndef NO_WAP
00322 grp = cfg_get_single_group(cfg, octstr_imm("wapbox"));
00323 if (wapp != -1 && grp == NULL) {
00324 error(0, "No 'wapbox' group in configuration, but wapbox-port set");
00325 return -1;
00326 }
00327 #else
00328 warning(0, "Kannel was compiled without WAP support");
00329 #endif
00330
00331 return 0;
00332 }
00333
00334
00335
00336
00337
00338 static int check_args(int i, int argc, char **argv)
00339 {
00340 if (strcmp(argv[i], "-S")==0 || strcmp(argv[i], "--suspended")==0)
00341 bb_status = BB_SUSPENDED;
00342 else if (strcmp(argv[i], "-I")==0 || strcmp(argv[i], "--isolated")==0)
00343 bb_status = BB_ISOLATED;
00344 else
00345 return -1;
00346
00347 return 0;
00348 }
00349
00350
00351 static Cfg *init_bearerbox(Cfg *cfg)
00352 {
00353 CfgGroup *grp;
00354 Octstr *log, *val;
00355 long loglevel, store_dump_freq;
00356 int lf, m;
00357 #ifdef HAVE_LIBSSL
00358 Octstr *ssl_server_cert_file;
00359 Octstr *ssl_server_key_file;
00360 int ssl_enabled = 0;
00361 #endif
00362
00363
00364 lf = m = 1;
00365
00366 grp = cfg_get_single_group(cfg, octstr_imm("core"));
00367
00368 log = cfg_get(grp, octstr_imm("log-file"));
00369 if (log != NULL) {
00370 if (cfg_get_integer(&loglevel, grp, octstr_imm("log-level")) == -1)
00371 loglevel = 0;
00372 log_open(octstr_get_cstr(log), loglevel, GW_NON_EXCL);
00373 octstr_destroy(log);
00374 }
00375
00376 if (check_config(cfg) == -1)
00377 panic(0, "Cannot start with corrupted configuration");
00378
00379
00380 if ((log = cfg_get(grp, octstr_imm("access-log-time"))) != NULL) {
00381 lf = (octstr_case_compare(log, octstr_imm("gmt")) == 0) ? 0 : 1;
00382 octstr_destroy(log);
00383 }
00384
00385
00386 cfg_get_bool(&m, grp, octstr_imm("access-log-clean"));
00387
00388
00389 if ((log = cfg_get(grp, octstr_imm("access-log-format"))) != NULL) {
00390 bb_alog_init(log);
00391 octstr_destroy(log);
00392 }
00393
00394
00395 if ((log = cfg_get(grp, octstr_imm("access-log"))) != NULL) {
00396 alog_open(octstr_get_cstr(log), lf, m ? 0 : 1);
00397 octstr_destroy(log);
00398 }
00399
00400 if (cfg_get_integer(&store_dump_freq, grp,
00401 octstr_imm("store-dump-freq")) == -1)
00402 store_dump_freq = -1;
00403
00404 log = cfg_get(grp, octstr_imm("store-file"));
00405
00406 if (log != NULL) {
00407 warning(0, "'store-file' option deprecated, please use 'store-location' and 'store-type' instead.");
00408 val = octstr_create("file");
00409 } else {
00410 log = cfg_get(grp, octstr_imm("store-location"));
00411 val = cfg_get(grp, octstr_imm("store-type"));
00412 }
00413 if (store_init(val, log, store_dump_freq, msg_pack, msg_unpack_wrapper) == -1)
00414 panic(0, "Could not start with store init failed.");
00415 octstr_destroy(val);
00416 octstr_destroy(log);
00417
00418 conn_config_ssl (grp);
00419
00420
00421
00422
00423
00424
00425
00426
00427 #ifdef HAVE_LIBSSL
00428 ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file"));
00429 ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file"));
00430 if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
00431
00432 } else {
00433 cfg_get_bool(&ssl_enabled, grp, octstr_imm("smsbox-port-ssl"));
00434 cfg_get_bool(&ssl_enabled, grp, octstr_imm("wapbox-port-ssl"));
00435 if (ssl_enabled) {
00436 panic(0, "You MUST specify cert and key files within core group for SSL-enabled inter-box connections!");
00437 }
00438 }
00439 octstr_destroy(ssl_server_cert_file);
00440 octstr_destroy(ssl_server_key_file);
00441 #endif
00442
00443
00444
00445 outgoing_sms = gwlist_create();
00446 incoming_sms = gwlist_create();
00447 outgoing_wdp = gwlist_create();
00448 incoming_wdp = gwlist_create();
00449
00450 outgoing_sms_counter = counter_create();
00451 incoming_sms_counter = counter_create();
00452 outgoing_wdp_counter = counter_create();
00453 incoming_wdp_counter = counter_create();
00454
00455 status_mutex = mutex_create();
00456
00457 setup_signal_handlers();
00458
00459
00460 httpadmin_start(cfg);
00461
00462 if (cfg_get_integer(&max_incoming_sms_qlength, grp,
00463 octstr_imm("maximum-queue-length")) == -1)
00464 max_incoming_sms_qlength = -1;
00465 else {
00466 warning(0, "Option 'maximum-queue-length' is deprecated! Please use"
00467 " 'sms-incoming-queue-limit' instead!");
00468 }
00469
00470 if (max_incoming_sms_qlength == -1 &&
00471 cfg_get_integer(&max_incoming_sms_qlength, grp,
00472 octstr_imm("sms-incoming-queue-limit")) == -1)
00473 max_incoming_sms_qlength = -1;
00474
00475 if (cfg_get_integer(&max_outgoing_sms_qlength, grp,
00476 octstr_imm("sms-outgoing-queue-limit")) == -1)
00477 max_outgoing_sms_qlength = -1;
00478
00479 #ifndef NO_SMS
00480 {
00481 List *list;
00482
00483 list = cfg_get_multi_group(cfg, octstr_imm("smsc"));
00484 if (list != NULL) {
00485 start_smsc(cfg);
00486 gwlist_destroy(list, NULL);
00487 }
00488 }
00489 #endif
00490
00491 #ifndef NO_WAP
00492 grp = cfg_get_single_group(cfg, octstr_imm("core"));
00493 val = cfg_get(grp, octstr_imm("wdp-interface-name"));
00494 if (val != NULL && octstr_len(val) > 0)
00495 start_udp(cfg);
00496 octstr_destroy(val);
00497
00498 if (cfg_get_single_group(cfg, octstr_imm("wapbox")) != NULL)
00499 start_wap(cfg);
00500 #endif
00501
00502 return cfg;
00503 }
00504
00505
00506 static void empty_msg_lists(void)
00507 {
00508 Msg *msg;
00509
00510 #ifndef NO_WAP
00511 if (gwlist_len(incoming_wdp) > 0 || gwlist_len(outgoing_wdp) > 0)
00512 warning(0, "Remaining WDP: %ld incoming, %ld outgoing",
00513 gwlist_len(incoming_wdp), gwlist_len(outgoing_wdp));
00514
00515 info(0, "Total WDP messages: received %ld, sent %ld",
00516 counter_value(incoming_wdp_counter),
00517 counter_value(outgoing_wdp_counter));
00518 #endif
00519
00520 while ((msg = gwlist_extract_first(incoming_wdp)) != NULL)
00521 msg_destroy(msg);
00522 while ((msg = gwlist_extract_first(outgoing_wdp)) != NULL)
00523 msg_destroy(msg);
00524
00525 gwlist_destroy(incoming_wdp, NULL);
00526 gwlist_destroy(outgoing_wdp, NULL);
00527
00528 counter_destroy(incoming_wdp_counter);
00529 counter_destroy(outgoing_wdp_counter);
00530
00531 #ifndef NO_SMS
00532
00533 if (gwlist_len(incoming_sms) > 0 || gwlist_len(outgoing_sms) > 0)
00534 debug("bb", 0, "Remaining SMS: %ld incoming, %ld outgoing",
00535 gwlist_len(incoming_sms), gwlist_len(outgoing_sms));
00536
00537 info(0, "Total SMS messages: received %ld, sent %ld",
00538 counter_value(incoming_sms_counter),
00539 counter_value(outgoing_sms_counter));
00540 #endif
00541
00542 gwlist_destroy(incoming_sms, msg_destroy_item);
00543 gwlist_destroy(outgoing_sms, msg_destroy_item);
00544
00545 counter_destroy(incoming_sms_counter);
00546 counter_destroy(outgoing_sms_counter);
00547 }
00548
00549
00550 static void dispatch_into_queue(Msg *msg)
00551 {
00552 gw_assert(msg != NULL),
00553 gw_assert(msg_type(msg) == sms);
00554
00555 switch (msg->sms.sms_type) {
00556 case mt_push:
00557 case mt_reply:
00558 case report_mt:
00559 gwlist_append(outgoing_sms, msg);
00560 break;
00561 case mo:
00562 case report_mo:
00563 gwlist_append(incoming_sms, msg);
00564 break;
00565 default:
00566 panic(0, "Not handled sms_type within store!");
00567 }
00568 }
00569
00570
00571 int main(int argc, char **argv)
00572 {
00573 int cf_index;
00574 Cfg *cfg;
00575 Octstr *filename;
00576
00577 bb_status = BB_RUNNING;
00578
00579 gwlib_init();
00580 start_time = time(NULL);
00581
00582 suspended = gwlist_create();
00583 isolated = gwlist_create();
00584 gwlist_add_producer(suspended);
00585 gwlist_add_producer(isolated);
00586
00587 cf_index = get_and_set_debugs(argc, argv, check_args);
00588
00589 if (argv[cf_index] == NULL)
00590 filename = octstr_create("kannel.conf");
00591 else
00592 filename = octstr_create(argv[cf_index]);
00593 cfg = cfg_create(filename);
00594
00595 if (cfg_read(cfg) == -1)
00596 panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));
00597
00598 octstr_destroy(filename);
00599
00600 dlr_init(cfg);
00601
00602 report_versions("bearerbox");
00603
00604 flow_threads = gwlist_create();
00605
00606 init_bearerbox(cfg);
00607
00608 info(0, "----------------------------------------");
00609 info(0, GW_NAME " bearerbox II version %s starting", GW_VERSION);
00610
00611 gwthread_sleep(5.0);
00612
00613 if (store_load(dispatch_into_queue) == -1)
00614 panic(0, "Cannot start with store-file failing");
00615
00616 info(0, "MAIN: Start-up done, entering mainloop");
00617 if (bb_status == BB_SUSPENDED) {
00618 info(0, "Gateway is now SUSPENDED by startup arguments");
00619 } else if (bb_status == BB_ISOLATED) {
00620 info(0, "Gateway is now ISOLATED by startup arguments");
00621 gwlist_remove_producer(suspended);
00622 } else {
00623 smsc2_resume();
00624 gwlist_remove_producer(suspended);
00625 gwlist_remove_producer(isolated);
00626 }
00627
00628 while (bb_status != BB_SHUTDOWN && bb_status != BB_DEAD &&
00629 gwlist_producer_count(flow_threads) > 0) {
00630
00631
00632
00633
00634
00635
00636
00637
00638 gwthread_sleep(10.0);
00639
00640
00641 if (bb_todo == 0) {
00642 continue;
00643 }
00644
00645 if (bb_todo & BB_LOGREOPEN) {
00646 warning(0, "SIGHUP received, catching and re-opening logs");
00647 log_reopen();
00648 alog_reopen();
00649 bb_todo = bb_todo & ~BB_LOGREOPEN;
00650 }
00651
00652 if (bb_todo & BB_CHECKLEAKS) {
00653 warning(0, "SIGQUIT received, reporting memory usage.");
00654 gw_check_leaks();
00655 bb_todo = bb_todo & ~BB_CHECKLEAKS;
00656 }
00657 }
00658
00659 if (bb_status == BB_SHUTDOWN || bb_status == BB_DEAD)
00660 warning(0, "Killing signal or HTTP admin command received, shutting down...");
00661
00662
00663 bb_shutdown();
00664
00665
00666 while (gwlist_consume(flow_threads) != NULL)
00667 ;
00668
00669 info(0, "All flow threads have died, killing core");
00670 bb_status = BB_DEAD;
00671 httpadmin_stop();
00672
00673 boxc_cleanup();
00674 smsc2_cleanup();
00675 store_shutdown();
00676 empty_msg_lists();
00677 gwlist_destroy(flow_threads, NULL);
00678 gwlist_destroy(suspended, NULL);
00679 gwlist_destroy(isolated, NULL);
00680 mutex_destroy(status_mutex);
00681
00682 alog_close();
00683 bb_alog_shutdown();
00684 cfg_destroy(cfg);
00685 dlr_shutdown();
00686 gwlib_shutdown();
00687
00688 if (restart == 1)
00689 execvp(argv[0],argv);
00690
00691 return 0;
00692 }
00693
00694
00695
00696
00697
00698
00699 int bb_shutdown(void)
00700 {
00701 static int called = 0;
00702
00703 mutex_lock(status_mutex);
00704
00705 if (called) {
00706 mutex_unlock(status_mutex);
00707 return -1;
00708 }
00709 debug("bb", 0, "Shutting down " GW_NAME "...");
00710
00711 called = 1;
00712 set_shutdown_status();
00713 mutex_unlock(status_mutex);
00714
00715 #ifndef NO_SMS
00716 debug("bb", 0, "shutting down smsc");
00717 smsc2_shutdown();
00718 #endif
00719 #ifndef NO_WAP
00720 debug("bb", 0, "shutting down udp");
00721 udp_shutdown();
00722 #endif
00723
00724 return 0;
00725 }
00726
00727
00728 int bb_isolate(void)
00729 {
00730 mutex_lock(status_mutex);
00731 if (bb_status != BB_RUNNING && bb_status != BB_SUSPENDED) {
00732 mutex_unlock(status_mutex);
00733 return -1;
00734 }
00735 if (bb_status == BB_RUNNING) {
00736 smsc2_suspend();
00737 gwlist_add_producer(isolated);
00738 } else
00739 gwlist_remove_producer(suspended);
00740
00741 bb_status = BB_ISOLATED;
00742 mutex_unlock(status_mutex);
00743 return 0;
00744 }
00745
00746
00747 int bb_suspend(void)
00748 {
00749 mutex_lock(status_mutex);
00750 if (bb_status != BB_RUNNING && bb_status != BB_ISOLATED) {
00751 mutex_unlock(status_mutex);
00752 return -1;
00753 }
00754 if (bb_status != BB_ISOLATED) {
00755 smsc2_suspend();
00756 gwlist_add_producer(isolated);
00757 }
00758 bb_status = BB_SUSPENDED;
00759 gwlist_add_producer(suspended);
00760 mutex_unlock(status_mutex);
00761 return 0;
00762 }
00763
00764
00765 int bb_resume(void)
00766 {
00767 mutex_lock(status_mutex);
00768 if (bb_status != BB_SUSPENDED && bb_status != BB_ISOLATED) {
00769 mutex_unlock(status_mutex);
00770 return -1;
00771 }
00772 if (bb_status == BB_SUSPENDED)
00773 gwlist_remove_producer(suspended);
00774
00775 smsc2_resume();
00776 bb_status = BB_RUNNING;
00777 gwlist_remove_producer(isolated);
00778 mutex_unlock(status_mutex);
00779 return 0;
00780 }
00781
00782
00783 int bb_flush_dlr(void)
00784 {
00785
00786 if (bb_status != BB_SUSPENDED) {
00787 return -1;
00788 }
00789 dlr_flush();
00790 return 0;
00791 }
00792
00793
00794 int bb_stop_smsc(Octstr *id)
00795 {
00796 return smsc2_stop_smsc(id);
00797 }
00798
00799
00800 int bb_restart_smsc(Octstr *id)
00801 {
00802 return smsc2_restart_smsc(id);
00803 }
00804
00805 int bb_restart(void)
00806 {
00807 restart = 1;
00808 return bb_shutdown();
00809 }
00810
00811
00812 #define append_status(r, s, f, x) { s = f(x); octstr_append(r, s); \
00813 octstr_destroy(s); }
00814
00815 Octstr *bb_print_status(int status_type)
00816 {
00817 char *s, *lb;
00818 char *frmt, *footer;
00819 char buf[1024];
00820 Octstr *ret, *str, *version;
00821 time_t t;
00822
00823 if ((lb = bb_status_linebreak(status_type)) == NULL)
00824 return octstr_create("Un-supported format");
00825
00826 t = time(NULL) - start_time;
00827
00828 if (bb_status == BB_RUNNING)
00829 s = "running";
00830 else if (bb_status == BB_ISOLATED)
00831 s = "isolated";
00832 else if (bb_status == BB_SUSPENDED)
00833 s = "suspended";
00834 else if (bb_status == BB_FULL)
00835 s = "filled";
00836 else
00837 s = "going down";
00838
00839 version = version_report_string("bearerbox");
00840
00841 if (status_type == BBSTATUS_HTML) {
00842 frmt = "%s</p>\n\n"
00843 " <p>Status: %s, uptime %ldd %ldh %ldm %lds</p>\n\n"
00844 " <p>WDP: received %ld (%ld queued), sent %ld "
00845 "(%ld queued)</p>\n\n"
00846 " <p>SMS: received %ld (%ld queued), sent %ld "
00847 "(%ld queued), store size %ld</p>\n"
00848 " <p>SMS: inbound %.2f msg/sec, outbound %.2f msg/sec</p>\n\n"
00849 " <p>DLR: %ld queued, using %s storage</p>\n\n";
00850 footer = "<p>";
00851 } else if (status_type == BBSTATUS_WML) {
00852 frmt = "%s</p>\n\n"
00853 " <p>Status: %s, uptime %ldd %ldh %ldm %lds</p>\n\n"
00854 " <p>WDP: received %ld (%ld queued)<br/>\n"
00855 " WDP: sent %ld (%ld queued)</p>\n\n"
00856 " <p>SMS: received %ld (%ld queued)<br/>\n"
00857 " SMS: sent %ld (%ld queued)<br/>\n"
00858 " SMS: store size %ld<br/>\n"
00859 " SMS: inbound %.2f msg/sec<br/>\n"
00860 " SMS: outbound %.2f msg/sec</p>\n\n"
00861 " <p>DLR: %ld queued<br/>\n"
00862 " DLR: using %s storage</p>\n\n";
00863 footer = "<p>";
00864 } else if (status_type == BBSTATUS_XML) {
00865 frmt = "<version>%s</version>\n"
00866 "<status>%s, uptime %ldd %ldh %ldm %lds</status>\n"
00867 "\t<wdp>\n\t\t<received><total>%ld</total><queued>%ld</queued>"
00868 "</received>\n\t\t<sent><total>%ld</total><queued>%ld</queued>"
00869 "</sent>\n\t</wdp>\n"
00870 "\t<sms>\n\t\t<received><total>%ld</total><queued>%ld</queued>"
00871 "</received>\n\t\t<sent><total>%ld</total><queued>%ld</queued>"
00872 "</sent>\n\t\t<storesize>%ld</storesize>\n\t\t"
00873 "<inbound>%.2f</inbound>\n\t\t<outbound>%.2f</outbound>\n\t</sms>\n"
00874 "\t<dlr>\n\t\t<queued>%ld</queued>\n\t\t<storage>%s</storage>\n\t</dlr>\n";
00875 footer = "";
00876 } else {
00877 frmt = "%s\n\nStatus: %s, uptime %ldd %ldh %ldm %lds\n\n"
00878 "WDP: received %ld (%ld queued), sent %ld (%ld queued)\n\n"
00879 "SMS: received %ld (%ld queued), sent %ld (%ld queued), store size %ld\n"
00880 "SMS: inbound %.2f msg/sec, outbound %.2f msg/sec\n\n"
00881 "DLR: %ld queued, using %s storage\n\n";
00882 footer = "";
00883 }
00884
00885 sprintf(buf, frmt,
00886 octstr_get_cstr(version),
00887 s, t/3600/24, t/3600%24, t/60%60, t%60,
00888 counter_value(incoming_wdp_counter),
00889 gwlist_len(incoming_wdp) + boxc_incoming_wdp_queue(),
00890 counter_value(outgoing_wdp_counter), gwlist_len(outgoing_wdp) + udp_outgoing_queue(),
00891 counter_value(incoming_sms_counter), gwlist_len(incoming_sms),
00892 counter_value(outgoing_sms_counter), gwlist_len(outgoing_sms),
00893 store_messages(),
00894 (float) counter_value(incoming_sms_counter)/t,
00895 (float) counter_value(outgoing_sms_counter)/t,
00896 dlr_messages(), dlr_type());
00897
00898 octstr_destroy(version);
00899 ret = octstr_create(buf);
00900
00901 append_status(ret, str, boxc_status, status_type);
00902 append_status(ret, str, smsc2_status, status_type);
00903 octstr_append_cstr(ret, footer);
00904
00905 return ret;
00906 }
00907
00908
00909 char *bb_status_linebreak(int status_type)
00910 {
00911 switch (status_type) {
00912 case BBSTATUS_HTML:
00913 return "<br>\n";
00914 case BBSTATUS_WML:
00915 return "<br/>\n";
00916 case BBSTATUS_TEXT:
00917 return "\n";
00918 case BBSTATUS_XML:
00919 return "\n";
00920 default:
00921 return NULL;
00922 }
00923 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.