dtntest.cc

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

Generated on Fri Dec 22 14:47:58 2006 for DTN Reference Implementation by  doxygen 1.5.1