dtntest.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #include <errno.h>
00019 #include <oasys/debug/Log.h>
00020 #include <oasys/io/NetUtils.h>
00021 #include <oasys/tclcmd/ConsoleCommand.h>
00022 #include <oasys/tclcmd/TclCommand.h>
00023 #include <oasys/util/Getopt.h>
00024 #include <oasys/util/OptParser.h>
00025 
00026 #include <dtn_api.h>
00027 #include <dtn_ipc.h>
00028 #include <APIEndpointIDOpt.h>
00029 
00030 typedef std::map<int, dtn_handle_t> HandleMap;
00031 
00032 struct State : public oasys::Singleton<State> {
00033     State() : handle_num_(0) {}
00034         
00035     HandleMap handles_;
00036     int handle_num_;
00037 };
00038 
00039 template <> State* oasys::Singleton<State>::instance_ = 0;
00040 
00041 extern int dtnipc_version;
00042 
00043 //----------------------------------------------------------------------
00044 class DTNOpenCommand : public oasys::TclCommand {
00045 public:
00046     oasys::OptParser parser_;
00047     
00048     struct OpenOpts {
00049         u_int16_t             version_;
00050     };
00051     
00052     OpenOpts opts_;
00053     
00054     void init_opts() {
00055         opts_.version_ = DTN_IPC_VERSION;
00056     }
00057     
00058     DTNOpenCommand() : TclCommand("dtn_open") {
00059         parser_.addopt(new oasys::UInt16Opt("version", &opts_.version_));
00060     }
00061     
00062     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00063     {
00064         (void)argc;
00065         (void)argv;
00066         (void)interp;
00067 
00068         if (argc < 1 || argc > 2) {
00069             wrong_num_args(argc, argv, 1, 1, 2);
00070             return TCL_ERROR;
00071         }
00072 
00073         init_opts();
00074         
00075         const char* invalid = 0;
00076         if (! parser_.parse(argc - 1, argv + 1, &invalid)) {
00077             resultf("invalid option '%s'", invalid);
00078             return TCL_ERROR;
00079         }
00080 
00081         dtnipc_version = opts_.version_;
00082         dtn_handle_t handle;
00083         int err = dtn_open(&handle);
00084         if (err != DTN_SUCCESS) {
00085             resultf("can't connect to dtn daemon: %s",
00086                     dtn_strerror(err));
00087             return TCL_ERROR;
00088         }
00089 
00090         int n = State::instance()->handle_num_++;
00091         State::instance()->handles_[n] = handle;
00092 
00093         resultf("%d", n);
00094         return TCL_OK;
00095     }
00096 };
00097 
00098 //----------------------------------------------------------------------
00099 class DTNCloseCommand : public oasys::TclCommand {
00100 public:
00101     DTNCloseCommand() : TclCommand("dtn_close") {}
00102     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00103     {
00104         (void)argc;
00105         (void)argv;
00106         (void)interp;
00107 
00108         if (argc != 2) {
00109             wrong_num_args(argc, argv, 1, 2, 2);
00110             return TCL_ERROR;
00111         }
00112 
00113         int n = atoi(argv[1]);
00114         HandleMap::iterator iter = State::instance()->handles_.find(n);
00115         if (iter == State::instance()->handles_.end()) {
00116             resultf("invalid dtn handle %d", n);
00117             return TCL_ERROR;
00118         }
00119 
00120         dtn_handle_t h = iter->second;
00121         dtn_close(h);
00122 
00123         return TCL_OK;
00124     }
00125 };
00126 
00127 //----------------------------------------------------------------------
00128 oasys::EnumOpt::Case FailureActionCases[] = {
00129     {"drop",  DTN_REG_DROP},
00130     {"defer", DTN_REG_DEFER},
00131     {"exec",  DTN_REG_EXEC},
00132     {0, 0}
00133 };
00134 
00135 class DTNRegisterCommand : public oasys::TclCommand {
00136 public:
00137     oasys::OptParser parser_;
00138 
00139     struct RegistrationOpts {
00140         dtn_endpoint_id_t endpoint_;
00141         int               failure_action_;
00142         u_int             expiration_;
00143         std::string       script_;
00144         bool              init_passive_;
00145     };
00146     
00147     RegistrationOpts opts_;
00148 
00149     void init_opts() {
00150         memset(&opts_.endpoint_, 0, sizeof(opts_.endpoint_));
00151         opts_.failure_action_ = DTN_REG_DROP;
00152         opts_.expiration_ = 0;
00153         opts_.script_ = "";
00154         opts_.init_passive_ = false;
00155     }
00156 
00157     DTNRegisterCommand() : TclCommand("dtn_register")
00158     {
00159         parser_.addopt(new dtn::APIEndpointIDOpt("endpoint", &opts_.endpoint_));
00160         parser_.addopt(new oasys::EnumOpt("failure_action",
00161                                           FailureActionCases,
00162                                           &opts_.failure_action_));
00163         parser_.addopt(new oasys::UIntOpt("expiration", &opts_.expiration_));
00164         parser_.addopt(new oasys::StringOpt("script", &opts_.script_));
00165         parser_.addopt(new oasys::BoolOpt("init_passive",
00166                                           &opts_.init_passive_));
00167     }
00168     
00169     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00170     {
00171         (void)argc;
00172         (void)argv;
00173         (void)interp;
00174 
00175         // need at least cmd, handle, endpoint, and expiration
00176         if (argc < 4) {
00177             wrong_num_args(argc, argv, 1, 4, INT_MAX);
00178             return TCL_ERROR;
00179         }
00180 
00181         int n = atoi(argv[1]);
00182         HandleMap::iterator iter = State::instance()->handles_.find(n);
00183         if (iter == State::instance()->handles_.end()) {
00184             resultf("invalid dtn handle %d", n);
00185             return TCL_ERROR;
00186         }
00187 
00188         dtn_handle_t h = iter->second;
00189 
00190         init_opts();
00191         const char* invalid = 0;
00192         if (! parser_.parse(argc - 2, argv + 2, &invalid)) {
00193             resultf("invalid option '%s'", invalid);
00194             return TCL_ERROR;
00195         }
00196 
00197         if (opts_.endpoint_.uri[0] == 0) {
00198             resultf("must set endpoint id");
00199             return TCL_ERROR;
00200         }
00201         
00202         if (opts_.expiration_ == 0) {
00203             resultf("must set expiration");
00204             return TCL_ERROR;
00205         }
00206         
00207         dtn_reg_info_t reginfo;
00208         memset(&reginfo, 0, sizeof(reginfo));
00209 
00210         dtn_copy_eid(&reginfo.endpoint, &opts_.endpoint_);
00211         reginfo.failure_action =
00212             (dtn_reg_failure_action_t)opts_.failure_action_;
00213         reginfo.expiration = opts_.expiration_;
00214         reginfo.script.script_len = opts_.script_.length();
00215         reginfo.script.script_val = (char*)opts_.script_.c_str();
00216         reginfo.init_passive = opts_.init_passive_;
00217 
00218         dtn_reg_id_t regid = 0;
00219         
00220         int ret = dtn_register(h, &reginfo, &regid);
00221         if (ret != DTN_SUCCESS) {
00222             resultf("error in dtn_register: %s",
00223                     dtn_strerror(dtn_errno(h)));
00224             return TCL_ERROR;
00225         }
00226 
00227         resultf("%u", regid);
00228         return TCL_OK;
00229     }
00230 };
00231 
00232 //----------------------------------------------------------------------
00233 class DTNUnregisterCommand : public oasys::TclCommand {
00234 public:
00235     DTNUnregisterCommand() : TclCommand("dtn_unregister") {}
00236     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00237     {
00238         (void)interp;
00239 
00240         if (argc != 3) {
00241             wrong_num_args(argc, argv, 1, 3, 3);
00242             return TCL_ERROR;
00243         }
00244 
00245         int n = atoi(argv[1]);
00246         HandleMap::iterator iter = State::instance()->handles_.find(n);
00247         if (iter == State::instance()->handles_.end()) {
00248             resultf("invalid dtn handle %d", n);
00249             return TCL_ERROR;
00250         }
00251 
00252         dtn_handle_t h = iter->second;
00253 
00254         dtn_reg_id_t regid = atoi(argv[2]);
00255 
00256         int err = dtn_unregister(h, regid);
00257         if (err != DTN_SUCCESS) {
00258             resultf("error in dtn_unregister: %s",
00259                     dtn_strerror(dtn_errno(h)));
00260             return TCL_ERROR;
00261         }
00262         
00263         return TCL_OK;
00264     }
00265 };
00266 
00267 //----------------------------------------------------------------------
00268 oasys::EnumOpt::Case PriorityCases[] = {
00269     {"bulk",      COS_BULK},
00270     {"normal",    COS_NORMAL},
00271     {"expedited", COS_EXPEDITED},
00272     {0, 0}
00273 };
00274 
00275 class DTNSendCommand : public oasys::TclCommand {
00276 public:
00277     struct SendOpts {
00278         dtn_endpoint_id_t source_;
00279         dtn_endpoint_id_t dest_;
00280         dtn_endpoint_id_t replyto_;
00281         int    priority_;
00282         bool   custody_xfer_;
00283         bool   receive_rcpt_;
00284         bool   custody_rcpt_;
00285         bool   forward_rcpt_;
00286         bool   delivery_rcpt_;
00287         bool   deletion_rcpt_;
00288         u_int  expiration_;
00289         char   payload_data_[DTN_MAX_BUNDLE_MEM];
00290         size_t payload_data_len_;
00291         char   payload_file_[DTN_MAX_PATH_LEN];
00292         size_t payload_file_len_;
00293         u_int  block_type_;
00294         u_int  block_flags_;
00295         char   block_content_[DTN_MAX_BLOCK_LEN];
00296         size_t block_content_len_;
00297     };
00298 
00299     // we use a single parser and options struct for the command for
00300     // improved efficiency
00301     oasys::OptParser parser_;
00302     SendOpts opts_;
00303 
00304     void init_opts() {
00305         memset(&opts_, 0, sizeof(opts_));
00306         opts_.expiration_ = 5 * 60;
00307     }
00308 
00309     DTNSendCommand() : TclCommand("dtn_send")
00310     {
00311         parser_.addopt(new dtn::APIEndpointIDOpt("source", &opts_.source_));
00312         parser_.addopt(new dtn::APIEndpointIDOpt("dest", &opts_.dest_));
00313         parser_.addopt(new dtn::APIEndpointIDOpt("replyto", &opts_.replyto_));
00314         parser_.addopt(new oasys::EnumOpt("priority", PriorityCases,
00315                                           &opts_.priority_));
00316         parser_.addopt(new oasys::BoolOpt("custody_xfer",
00317                                           &opts_.custody_xfer_));
00318         parser_.addopt(new oasys::BoolOpt("receive_rcpt",
00319                                           &opts_.receive_rcpt_));
00320         parser_.addopt(new oasys::BoolOpt("custody_rcpt",
00321                                           &opts_.custody_rcpt_));
00322         parser_.addopt(new oasys::BoolOpt("forward_rcpt",
00323                                           &opts_.forward_rcpt_));
00324         parser_.addopt(new oasys::BoolOpt("delivery_rcpt",
00325                                           &opts_.delivery_rcpt_));
00326         parser_.addopt(new oasys::BoolOpt("deletion_rcpt",
00327                                           &opts_.deletion_rcpt_));
00328         parser_.addopt(new oasys::UIntOpt("expiration",
00329                                           &opts_.expiration_));
00330         parser_.addopt(new oasys::CharBufOpt("payload_data",
00331                                              opts_.payload_data_,
00332                                              &opts_.payload_data_len_,
00333                                              sizeof(opts_.payload_data_)));
00334         parser_.addopt(new oasys::CharBufOpt("payload_file",
00335                                              opts_.payload_file_,
00336                                              &opts_.payload_file_len_,
00337                                              sizeof(opts_.payload_file_)));
00338         parser_.addopt(new oasys::UIntOpt("block_type", &opts_.block_type_));
00339         parser_.addopt(new oasys::UIntOpt("block_flags", &opts_.block_flags_));
00340         parser_.addopt(new oasys::CharBufOpt("block_content",
00341                                              opts_.block_content_,
00342                                              &opts_.block_content_len_,
00343                                              sizeof(opts_.block_content_)));
00344     }
00345     
00346     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00347     {
00348         (void)argc;
00349         (void)argv;
00350         (void)interp;
00351 
00352         // need at least the command, handle, source, dest, and payload
00353         if (argc < 5) {
00354             wrong_num_args(argc, argv, 1, 5, INT_MAX);
00355             return TCL_ERROR;
00356         }
00357         
00358         int n = atoi(argv[1]);
00359         HandleMap::iterator iter = State::instance()->handles_.find(n);
00360         if (iter == State::instance()->handles_.end()) {
00361             resultf("invalid dtn handle %d", n);
00362             return TCL_ERROR;
00363         }
00364         
00365         dtn_handle_t h = iter->second;
00366         
00367         // now parse all the options
00368         init_opts();
00369         const char* invalid = 0;
00370         if (! parser_.parse(argc - 2, argv + 2, &invalid)) {
00371             resultf("invalid option '%s'", invalid);
00372             return TCL_ERROR;
00373         }
00374 
00375         // validate that source, dest, and some payload was specified
00376         if (opts_.source_.uri[0] == 0) {
00377             resultf("must set source endpoint id");
00378             return TCL_ERROR;
00379         }
00380         if (opts_.dest_.uri[0] == 0) {
00381             resultf("must set dest endpoint id");
00382             return TCL_ERROR;
00383         }
00384         if (opts_.payload_data_len_ == 0 && opts_.payload_file_len_ == 0) {
00385             resultf("must set payload");
00386             return TCL_ERROR;
00387         }
00388 
00389         dtn_bundle_spec_t spec;
00390         memset(&spec, 0, sizeof(spec));
00391         dtn_copy_eid(&spec.source, &opts_.source_);
00392         dtn_copy_eid(&spec.dest,   &opts_.dest_);
00393         if (opts_.replyto_.uri[0] != 0) {
00394             dtn_copy_eid(&spec.replyto, &opts_.replyto_);
00395         }
00396         spec.priority = (dtn_bundle_priority_t)opts_.priority_;
00397         if (opts_.custody_xfer_)  spec.dopts |= DOPTS_CUSTODY;
00398         if (opts_.receive_rcpt_)  spec.dopts |= DOPTS_RECEIVE_RCPT;
00399         if (opts_.custody_rcpt_)  spec.dopts |= DOPTS_CUSTODY_RCPT;
00400         if (opts_.forward_rcpt_)  spec.dopts |= DOPTS_FORWARD_RCPT;
00401         if (opts_.delivery_rcpt_) spec.dopts |= DOPTS_DELIVERY_RCPT;
00402         if (opts_.deletion_rcpt_) spec.dopts |= DOPTS_DELETE_RCPT;
00403         spec.expiration = opts_.expiration_;
00404 
00405         dtn_bundle_payload_t payload;
00406         memset(&payload, 0, sizeof(payload));
00407         if (opts_.payload_data_len_ != 0) {
00408             dtn_set_payload(&payload, DTN_PAYLOAD_MEM,
00409                             opts_.payload_data_, opts_.payload_data_len_);
00410         } else {
00411             dtn_set_payload(&payload, DTN_PAYLOAD_FILE,
00412                             opts_.payload_file_, opts_.payload_file_len_);
00413 
00414         }
00415 
00416         dtn_extension_block_t block;
00417         memset(&block, 0, sizeof(block));
00418         if (opts_.block_type_ > 0 && opts_.block_type_ < 255) {
00419             block.type = opts_.block_type_;
00420             if (opts_.block_flags_ < 255) {
00421                 block.flags = opts_.block_flags_;
00422             }
00423             block.data.data_len = opts_.block_content_len_;
00424             block.data.data_val = opts_.block_content_;
00425 
00426             spec.blocks.blocks_len = 1;
00427             spec.blocks.blocks_val = &block;
00428         }
00429         
00430         dtn_bundle_id_t id;
00431         memset(&id, 0, sizeof(id));
00432         
00433         int ret = dtn_send(h, &spec, &payload, &id);
00434         if (ret != DTN_SUCCESS) {
00435             resultf("error in dtn_send: %s",
00436                     dtn_strerror(dtn_errno(h)));
00437             return TCL_ERROR;
00438         }
00439 
00440         resultf("%s,%u.%u",
00441                 id.source.uri, id.creation_ts.secs, id.creation_ts.seqno);
00442         return TCL_OK;
00443     }
00444 };
00445 
00446 //----------------------------------------------------------------------
00447 class DTNBindCommand : public oasys::TclCommand {
00448 public:
00449     DTNBindCommand() : TclCommand("dtn_bind") {}
00450     
00451     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00452     {
00453         (void)interp;
00454 
00455         if (argc != 3) {
00456             wrong_num_args(argc, argv, 1, 3, 3);
00457             return TCL_ERROR;
00458         }
00459 
00460         int n = atoi(argv[1]);
00461         HandleMap::iterator iter = State::instance()->handles_.find(n);
00462         if (iter == State::instance()->handles_.end()) {
00463             resultf("invalid dtn handle %d", n);
00464             return TCL_ERROR;
00465         }
00466 
00467         dtn_handle_t h = iter->second;
00468 
00469         dtn_reg_id_t regid = atoi(argv[2]);
00470 
00471         int err = dtn_bind(h, regid);
00472         if (err != DTN_SUCCESS) {
00473             resultf("error in dtn_bind: %s",
00474                     dtn_strerror(dtn_errno(h)));
00475             return TCL_ERROR;
00476         }
00477         
00478         return TCL_OK;
00479     }
00480 };
00481 
00482 //----------------------------------------------------------------------
00483 class DTNUnbindCommand : public oasys::TclCommand {
00484 public:
00485     DTNUnbindCommand() : TclCommand("dtn_unbind") {}
00486     
00487     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00488     {
00489         (void)interp;
00490 
00491         if (argc != 3) {
00492             wrong_num_args(argc, argv, 1, 3, 3);
00493             return TCL_ERROR;
00494         }
00495 
00496         int n = atoi(argv[1]);
00497         HandleMap::iterator iter = State::instance()->handles_.find(n);
00498         if (iter == State::instance()->handles_.end()) {
00499             resultf("invalid dtn handle %d", n);
00500             return TCL_ERROR;
00501         }
00502 
00503         dtn_handle_t h = iter->second;
00504 
00505         dtn_reg_id_t regid = atoi(argv[2]);
00506 
00507         int err = dtn_unbind(h, regid);
00508         if (err != DTN_SUCCESS) {
00509             resultf("error in dtn_unbind: %s",
00510                     dtn_strerror(dtn_errno(h)));
00511             return TCL_ERROR;
00512         }
00513         
00514         return TCL_OK;
00515     }
00516 };
00517 
00518 //----------------------------------------------------------------------
00519 class DTNRecvCommand : public oasys::TclCommand {
00520 public:
00521     oasys::OptParser parser_;
00522 
00523     struct RecvOpts {
00524         bool   payload_mem_;
00525         bool   payload_file_;
00526         u_int  timeout_;
00527     };
00528     
00529     RecvOpts opts_;
00530 
00531     void init_opts() {
00532         memset(&opts_, 0, sizeof(opts_));
00533     }
00534 
00535     DTNRecvCommand() : TclCommand("dtn_recv")
00536     {
00537         parser_.addopt(new oasys::BoolOpt("payload_mem", &opts_.payload_mem_));
00538         parser_.addopt(new oasys::BoolOpt("payload_file", &opts_.payload_file_));
00539         parser_.addopt(new oasys::UIntOpt("timeout", &opts_.timeout_));
00540     }
00541     
00542     int exec(int argc, const char **argv,  Tcl_Interp* interp)
00543     {
00544         (void)argc;
00545         (void)argv;
00546         (void)interp;
00547 
00548         // need at least cmd, handle, payload, and timeout
00549         if (argc < 3) {
00550             wrong_num_args(argc, argv, 1, 3, INT_MAX);
00551             return TCL_ERROR;
00552         }
00553 
00554         int n = atoi(argv[1]);
00555         HandleMap::iterator iter = State::instance()->handles_.find(n);
00556         if (iter == State::instance()->handles_.end()) {
00557             resultf("invalid dtn handle %d", n);
00558             return TCL_ERROR;
00559         }
00560 
00561         dtn_handle_t h = iter->second;
00562 
00563         init_opts();
00564 
00565         const char* invalid = 0;
00566         if (! parser_.parse(argc - 2, argv + 2, &invalid)) {
00567             resultf("invalid option '%s'", invalid);
00568             return TCL_ERROR;
00569         }
00570 
00571         if (opts_.payload_mem_ == false && opts_.payload_file_ == false) {
00572             resultf("must set payload location");
00573             return TCL_ERROR;
00574         }
00575 
00576         dtn_bundle_spec_t spec;
00577         memset(&spec, 0, sizeof(spec));
00578 
00579         dtn_bundle_payload_t payload;
00580         memset(&payload, 0, sizeof(payload));
00581         
00582         int err = dtn_recv(h, &spec,
00583                            opts_.payload_mem_ ? DTN_PAYLOAD_MEM : DTN_PAYLOAD_FILE,
00584                            &payload, opts_.timeout_);
00585         if (err != DTN_SUCCESS) {
00586             resultf("error in dtn_recv: %s",
00587                     dtn_strerror(dtn_errno(h)));
00588             return TCL_ERROR;
00589         }
00590         
00591         if (!opts_.payload_mem_) {
00592             char payload_path[PATH_MAX];
00593             memcpy(payload_path, payload.filename.filename_val,
00594                    payload.filename.filename_len);
00595             payload_path[payload.filename.filename_len] = 0;
00596             
00597             err = unlink(payload_path);
00598             if (err != 0) {
00599                 log_err("error unlinking payload file '%s': %s",
00600                         payload_path, strerror(errno));
00601             }
00602         }
00603         
00604         dtn_free_payload(&payload);
00605 
00606         // XXX/demmer should fill in the return with something useful, no?
00607         
00608         return TCL_OK;
00609     }
00610 };
00611 
00612 //----------------------------------------------------------------------
00613 class ShutdownCommand : public oasys::TclCommand {
00614 public:
00615     ShutdownCommand() : TclCommand("shutdown") {}
00616     static void call_exit(void* clientData);
00617     int exec(int argc, const char **argv,  Tcl_Interp* interp);
00618 };
00619 
00620 void
00621 ShutdownCommand::call_exit(void* clientData)
00622 {
00623     (void)clientData;
00624     exit(0);
00625 }
00626 
00627 //----------------------------------------------------------------------
00628 int
00629 ShutdownCommand::exec(int argc, const char **argv, Tcl_Interp* interp)
00630 {
00631     (void)argc;
00632     (void)argv;
00633     (void)interp;
00634     Tcl_CreateTimerHandler(0, ShutdownCommand::call_exit, 0);
00635     return TCL_OK;
00636 }
00637 
00638 //----------------------------------------------------------------------
00639 int
00640 main(int argc, char** argv)
00641 {
00642     oasys::TclCommandInterp* interp;
00643     oasys::ConsoleCommand* console_cmd;
00644     std::string conf_file;
00645     bool conf_file_set = false;
00646     bool daemon = false;
00647 
00648     oasys::Log::init();
00649     
00650     oasys::TclCommandInterp::init("dtn-test");
00651     interp = oasys::TclCommandInterp::instance();
00652 
00653     oasys::Getopt opts;
00654     opts.addopt(
00655         new oasys::StringOpt('c', "conf", &conf_file, "<conf>",
00656                              "set the configuration file", &conf_file_set));
00657 
00658     opts.addopt(
00659         new oasys::BoolOpt('d', "daemon", &daemon,
00660                            "run as a daemon"));
00661     
00662     int remainder = opts.getopt(argv[0], argc, argv);
00663     if (remainder != argc) 
00664     {
00665         fprintf(stderr, "invalid argument '%s'\n", argv[remainder]);
00666         opts.usage("dtn-test");
00667         exit(1);
00668     }
00669 
00670     console_cmd = new oasys::ConsoleCommand("dtntest% ");
00671     interp->reg(console_cmd);
00672     interp->reg(new DTNOpenCommand());
00673     interp->reg(new DTNCloseCommand());
00674     interp->reg(new DTNRegisterCommand());
00675     interp->reg(new DTNUnregisterCommand());
00676     interp->reg(new DTNBindCommand());
00677     interp->reg(new DTNUnbindCommand());
00678     interp->reg(new DTNSendCommand());
00679     interp->reg(new DTNRecvCommand());
00680     interp->reg(new ShutdownCommand());
00681 
00682     if (conf_file_set) {
00683         interp->exec_file(conf_file.c_str());
00684     }
00685     
00686     log_notice_p("/dtn-test", "dtn-test starting up...");
00687     
00688     if (console_cmd->port_ != 0) {
00689         log_notice_p("/dtn-test", "starting console on %s:%d",
00690                      intoa(console_cmd->addr_), console_cmd->port_);
00691         interp->command_server("dtn-test", console_cmd->addr_, console_cmd->port_);
00692     }
00693 
00694     if (daemon || (console_cmd->stdio_ == false)) {
00695         oasys::TclCommandInterp::instance()->event_loop();
00696     } else {
00697         oasys::TclCommandInterp::instance()->
00698             command_loop(console_cmd->prompt_.c_str());
00699     }
00700 
00701     log_notice_p("/dtn-test", "dtn-test shutting down...");
00702     delete State::instance();
00703     oasys::TclCommandInterp::shutdown();
00704     oasys::Log::shutdown();
00705 }

Generated on Thu Jun 7 12:54:27 2007 for DTN Reference Implementation by  doxygen 1.5.1