00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include <errno.h>
00022 #include <string>
00023 #include <sys/time.h>
00024
00025 #include <oasys/debug/Log.h>
00026 #include <oasys/io/NetUtils.h>
00027 #include <oasys/tclcmd/ConsoleCommand.h>
00028 #include <oasys/tclcmd/TclCommand.h>
00029 #include <oasys/thread/Timer.h>
00030 #include <oasys/util/App.h>
00031 #include <oasys/util/Getopt.h>
00032 #include <oasys/util/StringBuffer.h>
00033
00034 #include "applib/APIServer.h"
00035 #include "cmd/TestCommand.h"
00036 #include "servlib/DTNServer.h"
00037 #include "storage/DTNStorageConfig.h"
00038 #include "bundling/BundleDaemon.h"
00039
00040 extern const char* dtn_version;
00041
00045 namespace dtn {
00046
00050 class DTND : public oasys::App {
00051 public:
00052 DTND();
00053 int main(int argc, char* argv[]);
00054
00055 protected:
00056 TestCommand* testcmd_;
00057 oasys::ConsoleCommand* consolecmd_;
00058 DTNStorageConfig storage_config_;
00059
00060
00061 void fill_options();
00062
00063 void init_testcmd(int argc, char* argv[]);
00064 void run_console();
00065 };
00066
00067
00068 DTND::DTND()
00069 : App("DTND", "dtnd", dtn_version),
00070 testcmd_(NULL),
00071 consolecmd_(NULL),
00072 storage_config_("storage",
00073 "berkeleydb",
00074 "DTN",
00075 INSTALL_LOCALSTATEDIR "/dtn/db")
00076 {
00077
00078 loglevel_ = oasys::LOG_NOTICE;
00079 debugpath_ = "~/.dtndebug";
00080
00081
00082 storage_config_.db_max_tx_ = 1000;
00083
00084 testcmd_ = new TestCommand();
00085 consolecmd_ = new oasys::ConsoleCommand("dtn% ");
00086 }
00087
00088
00089 void
00090 DTND::fill_options()
00091 {
00092 fill_default_options(DAEMONIZE_OPT | CONF_FILE_OPT);
00093
00094 opts_.addopt(
00095 new oasys::BoolOpt('t', "tidy", &storage_config_.tidy_,
00096 "clear database and initialize tables on startup"));
00097
00098 opts_.addopt(
00099 new oasys::BoolOpt(0, "init-db", &storage_config_.init_,
00100 "initialize database on startup"));
00101
00102 opts_.addopt(
00103 new oasys::InAddrOpt(0, "console-addr", &consolecmd_->addr_, "<addr>",
00104 "set the console listening addr (default off)"));
00105
00106 opts_.addopt(
00107 new oasys::UInt16Opt(0, "console-port", &consolecmd_->port_, "<port>",
00108 "set the console listening port (default off)"));
00109
00110 opts_.addopt(
00111 new oasys::IntOpt('i', 0, &testcmd_->id_, "<id>",
00112 "set the test id"));
00113 }
00114
00115
00116 void
00117 DTND::init_testcmd(int argc, char* argv[])
00118 {
00119 for (int i = 0; i < argc; ++i) {
00120 testcmd_->argv_.append(argv[i]);
00121 testcmd_->argv_.append(" ");
00122 }
00123
00124 testcmd_->bind_vars();
00125 oasys::TclCommandInterp::instance()->reg(testcmd_);
00126 }
00127
00128
00129 void
00130 DTND::run_console()
00131 {
00132
00133 if (consolecmd_->port_ != 0) {
00134 log_info_p("/dtnd", "starting console on %s:%d",
00135 intoa(consolecmd_->addr_), consolecmd_->port_);
00136
00137 oasys::TclCommandInterp::instance()->
00138 command_server(consolecmd_->prompt_.c_str(),
00139 consolecmd_->addr_, consolecmd_->port_);
00140 }
00141
00142 if (daemonize_ || (consolecmd_->stdio_ == false)) {
00143 oasys::TclCommandInterp::instance()->event_loop();
00144 } else {
00145 oasys::TclCommandInterp::instance()->
00146 command_loop(consolecmd_->prompt_.c_str());
00147 }
00148 }
00149
00150
00151 int
00152 DTND::main(int argc, char* argv[])
00153 {
00154 init_app(argc, argv);
00155
00156 log_notice_p("/dtnd", "DTN daemon starting up... (pid %d)", getpid());
00157
00158 if (oasys::TclCommandInterp::init(argv[0], "/dtn/tclcmd") != 0)
00159 {
00160 log_crit_p("/dtnd", "Can't init TCL");
00161 notify_and_exit(1);
00162 }
00163
00164
00165 oasys::Thread::activate_start_barrier();
00166
00167 DTNServer* dtnserver = new DTNServer("/dtnd", &storage_config_);
00168 APIServer* apiserver = new APIServer();
00169
00170 dtnserver->init();
00171
00172 oasys::TclCommandInterp::instance()->reg(consolecmd_);
00173 init_testcmd(argc, argv);
00174
00175 if (! dtnserver->parse_conf_file(conf_file_, conf_file_set_)) {
00176 log_err_p("/dtnd", "error in configuration file, exiting...");
00177 notify_and_exit(1);
00178 }
00179
00180 if (storage_config_.init_)
00181 {
00182 log_notice_p("/dtnd", "initializing persistent data store");
00183 }
00184
00185 if (! dtnserver->init_datastore()) {
00186 log_err_p("/dtnd", "error initializing data store, exiting...");
00187 notify_and_exit(1);
00188 }
00189
00190
00191 if (storage_config_.init_ && !storage_config_.tidy_)
00192 {
00193 dtnserver->close_datastore();
00194 log_info_p("/dtnd", "database initialization complete.");
00195 notify_and_exit(0);
00196 }
00197
00198 if (BundleDaemon::instance()->local_eid().equals(EndpointID::NULL_EID()))
00199 {
00200 log_err_p("/dtnd", "no local eid specified; use the 'route local_eid' command");
00201 notify_and_exit(1);
00202 }
00203
00204
00205
00206 if (daemonize_) {
00207 daemonizer_.notify_parent(0);
00208 }
00209
00210 dtnserver->start();
00211 if (apiserver->enabled()) {
00212 apiserver->bind_listen_start(apiserver->local_addr(),
00213 apiserver->local_port());
00214 }
00215 oasys::Thread::release_start_barrier();
00216
00217
00218
00219 if (testcmd_->initscript_.length() != 0) {
00220 oasys::TclCommandInterp::instance()->
00221 exec_command(testcmd_->initscript_.c_str());
00222 }
00223
00224
00225
00226 oasys::Thread::yield();
00227 usleep(500000);
00228
00229 run_console();
00230
00231 log_notice_p("/dtnd", "command loop exited... shutting down daemon");
00232
00233 apiserver->stop();
00234
00235 oasys::TclCommandInterp::shutdown();
00236 dtnserver->shutdown();
00237
00238
00239 delete dtnserver;
00240
00241
00242
00243 oasys::Thread::yield();
00244 sleep(1);
00245
00246
00247 oasys::Log::shutdown();
00248
00249 return 0;
00250 }
00251
00252 }
00253
00254 int
00255 main(int argc, char* argv[])
00256 {
00257 dtn::DTND dtnd;
00258 dtnd.main(argc, argv);
00259 }