00001
00002
00006 #ifndef __SHEPP_COMMAND_FUNCTIONS_H__
00007 #define __SHEPP_COMMAND_FUNCTIONS_H__
00008
00009 #include <unistd.h>
00010
00011 #include "SheppGlobal.H"
00012 #include "SheppStrUtil.H"
00013 #include "SheppObjSet.H"
00014 #include "SheppPrint.H"
00015
00016 #include "IoException.H"
00017 #include "TransportException.H"
00018 #include "EppException.H"
00019 #include "XmlException.H"
00020
00021 #include "Login.H"
00022 #include "Logout.H"
00023
00024
00025 int cmd_login(vector<string> &);
00026 int cmd_logout(vector<string> &);
00027 int cmd_hello(vector<string> &);
00028 int cmd_poll(vector<string> &);
00029 int cmd_domain(vector<string> &);
00030 int cmd_contact(vector<string> &);
00031 #if USE_BR_DOMAINS
00032 int cmd_brorg(vector<string> &);
00033 #endif //USE_BR_DOMAINS
00034
00035 int cmd_xmlcmd(vector<string> &);
00036 int cmd_xmlrsp(vector<string> &);
00037
00038 int cmd_server(vector<string> &);
00039 int cmd_port(vector<string> &);
00040 int cmd_client_pem(vector<string> &);
00041 int cmd_root_pem(vector<string> &);
00042 int cmd_pass(vector<string> &);
00043 int cmd_user(vector<string> &);
00044 int cmd_login_pw(vector<string> &);
00045 int cmd_login_new_pw(vector<string> &);
00046 int cmd_lang(vector<string> &);
00047 int cmd_connect(vector<string> &);
00048 int cmd_disconnect(vector<string> &);
00049
00050 int cmd_help(vector<string> &);
00051 int cmd_about(vector<string> &);
00052 int cmd_quit(vector<string> &);
00053
00054 int cmd_beauty(vector<string> &);
00055 int cmd_debug(vector<string> &);
00056 int cmd_autorsp(vector<string> &);
00057 int cmd_keepalive(vector<string> &);
00058 int cmd_peer_crt_check(vector<string> &);
00059
00061 void init_commands()
00062 {
00063 SheppCommand cmd;
00064
00065
00066 cmd.reset("?", cmd_help, "This help screen");
00067 _commands.insert(_commands.end(), cmd);
00068 cmd.reset("help", cmd_help, "This help screen");
00069 _commands.insert(_commands.end(), cmd);
00070 cmd.reset("about", cmd_about, "shepp version information");
00071 _commands.insert(_commands.end(), cmd);
00072 cmd.reset("exit", cmd_quit, "Exit shepp\n");
00073 _commands.insert(_commands.end(), cmd);
00074
00075
00076 cmd.reset("beauty", cmd_beauty, "Turn XML beautifier on/off");
00077 _commands.insert(_commands.end(), cmd);
00078 cmd.reset("debug", cmd_debug, "Turn debug messages on/off");
00079 _commands.insert(_commands.end(), cmd);
00080 cmd.reset("autorsp", cmd_autorsp, "Turn auto-show response on/off");
00081 _commands.insert(_commands.end(), cmd);
00082 cmd.reset("keepalive", cmd_keepalive, "Turn keep-alive on/off");
00083 _commands.insert(_commands.end(), cmd);
00084 cmd.reset("peer-crt-check", cmd_peer_crt_check,
00085 "Turn peer's certificate check on/off\n");
00086 _commands.insert(_commands.end(), cmd);
00087
00088
00089 cmd.reset("server", cmd_server, "Sets server address");
00090 _commands.insert(_commands.end(), cmd);
00091 cmd.reset("port", cmd_port, "Sets server port");
00092 _commands.insert(_commands.end(), cmd);
00093 cmd.reset("client-pem", cmd_client_pem,
00094 "Sets client.pem certificate file location");
00095 _commands.insert(_commands.end(), cmd);
00096 cmd.reset("root-pem", cmd_root_pem,
00097 "Sets root.pem certificate file location");
00098 _commands.insert(_commands.end(), cmd);
00099 cmd.reset("pass", cmd_pass, "Sets SSL certificate passphrase");
00100 _commands.insert(_commands.end(), cmd);
00101 cmd.reset("user", cmd_user, "Sets EPP Login username");
00102 _commands.insert(_commands.end(), cmd);
00103 cmd.reset("pw", cmd_login_pw, "Sets EPP Login password");
00104 _commands.insert(_commands.end(), cmd);
00105 cmd.reset("newpw", cmd_login_new_pw, "Sets new EPP Login password");
00106 _commands.insert(_commands.end(), cmd);
00107 cmd.reset("lang", cmd_lang, "Sets text language");
00108 _commands.insert(_commands.end(), cmd);
00109 cmd.reset("connect", cmd_connect, "Establishes connection");
00110 _commands.insert(_commands.end(), cmd);
00111 cmd.reset("disconnect", cmd_disconnect, "Closes connection\n");
00112 _commands.insert(_commands.end(), cmd);
00113
00114
00115 cmd.reset("login", cmd_login, "EPP Login");
00116 _commands.insert(_commands.end(), cmd);
00117 cmd.reset("logout", cmd_logout, "EPP Logout");
00118 _commands.insert(_commands.end(), cmd);
00119 cmd.reset("hello", cmd_hello, "EPP Hello");
00120 _commands.insert(_commands.end(), cmd);
00121 cmd.reset("poll", cmd_poll, "EPP Poll related actions");
00122 _commands.insert(_commands.end(), cmd);
00123 cmd.reset("domain", cmd_domain, "EPP Domain related actions");
00124 _commands.insert(_commands.end(), cmd);
00125 cmd.reset("contact", cmd_contact, "EPP Contact related actions");
00126 _commands.insert(_commands.end(), cmd);
00127 #if USE_BR_DOMAINS
00128 cmd.reset("brorg", cmd_brorg, "EPP BrOrg related actions\n");
00129 _commands.insert(_commands.end(), cmd);
00130 #endif //USE_BR_DOMAINS
00131
00132
00133 cmd.reset("xmlcmd", cmd_xmlcmd, "Show last command XML");
00134 _commands.insert(_commands.end(), cmd);
00135 cmd.reset("xmlrsp", cmd_xmlrsp, "Show last response XML");
00136 _commands.insert(_commands.end(), cmd);
00137 }
00138
00140
00144 const SheppCommand* find_command(string name)
00145 {
00146 list<SheppCommand>::const_iterator it;
00147 for (it = _commands.begin(); it != _commands.end(); it++) {
00148 if ((*it).name == name) {
00149 return &(*it);
00150 }
00151 }
00152
00153 return ((const SheppCommand *) NULL);
00154 }
00155
00157
00161 int cmd_server(vector<string> &args)
00162 {
00163 if (args.size() != 0) {
00164 string new_port;
00165 string new_server;
00166 SheppStrUtil::split(args[0], new_server, new_port, ":", true);
00167 if (new_server != _server) {
00168 _server = new_server;
00169 }
00170 if (new_port != "" && _port != atoi(new_port.c_str())) {
00171 _port = atoi(new_port.c_str());
00172 }
00173 }
00174
00175 if (_server != "") {
00176 printf("server %s:%d\n", _server.c_str(), _port);
00177 } else {
00178 printf("no server address given.\n");
00179 }
00180
00181 return 0;
00182 }
00183
00185
00189 int cmd_port(vector<string> &args)
00190 {
00191 if (args.size() == 1) {
00192 if (_port != atoi(args[0].c_str())) {
00193 _port = atoi(args[0].c_str());
00194 }
00195 }
00196
00197 printf("port %d\n", _port);
00198
00199 return 0;
00200 }
00201
00203
00207 int cmd_client_pem(vector<string> &args)
00208 {
00209 if (args.size() == 1) {
00210 if (_client_pem != args[0]) {
00211 _client_pem = args[0];
00212 printf("Warning: changing cetificates requires you to reconnect.\n");
00213 }
00214 } else if (args.size() > 1) {
00215 printf("usage: client-pem <file>\n");
00216 return -1;
00217 }
00218
00219 printf("Current client.pem is %s\n", _client_pem.c_str());
00220 return 0;
00221 }
00222
00224
00228 int cmd_root_pem(vector<string> &args)
00229 {
00230 if (args.size() == 1) {
00231 if (_root_pem != args[0]) {
00232 _root_pem = args[0];
00233 printf("Warning: changing cetificates requires you to reconnect.\n");
00234 }
00235 } else if (args.size() > 1) {
00236 printf("usage: root-pem <file>\n");
00237 return -1;
00238 }
00239
00240 printf("Current root.pem is %s\n", _root_pem.c_str());
00241 return 0;
00242 }
00243
00245
00249 int cmd_pass(vector<string> &args)
00250 {
00251 if (!args.empty()) {
00252 _passphrase = args[0];
00253 } else {
00254 _passphrase = "";
00255 }
00256 return 0;
00257 }
00258
00260
00264 int cmd_user(vector<string> &args)
00265 {
00266 if (args.size() == 0) {
00267 if (_user != "") {
00268 printf("username: %s\n", _user.c_str());
00269 return 0;
00270 } else {
00271 printf("no username given.\n");
00272 return -1;
00273 }
00274 }
00275
00276 _user = args[0];
00277
00278 return 0;
00279 }
00280
00282
00286 int cmd_login_pw(vector<string> &args)
00287 {
00288 if (!args.empty()) {
00289 _login_pw = args[0];
00290 } else {
00291 _login_pw = "";
00292 }
00293 return 0;
00294 }
00295
00297
00301 int cmd_login_new_pw(vector<string> &args)
00302 {
00303 if (!args.empty()) {
00304 _login_new_pw = args[0];
00305 } else {
00306 _login_new_pw = "";
00307 }
00308 _new_pw = true;
00309 return 0;
00310 }
00311
00313
00317 int cmd_lang(vector<string> &args)
00318 {
00319 if (args.empty()) {
00320 printf("usage: lang [en|pt]\n");
00321 return -1;
00322 } else {
00323 _lang = args[0];
00324 }
00325
00326 return 0;
00327 }
00328
00330
00334 int cmd_connect(vector<string> &args)
00335 {
00336 if (cmd_server(args) != 0) {
00337 return -1;
00338 }
00339
00340 bool exception = false;
00341
00342
00343 try {
00344 _session = auto_ptr<Session>(new Session(_server, _port));
00345 if (_peer_crt_check) {
00346 _session->enable_cert_common_name_check();
00347 } else {
00348 _session->disable_cert_common_name_check();
00349 }
00350 _session->connect(_client_pem, _root_pem, _passphrase);
00351 printf("Connected to %s\n", _server.c_str());
00352
00353 Greeting *greeting = _session->get_greeting();
00354 if (_debug) {
00355 if (greeting) {
00356 printf("Greeting received\n");
00357 }
00358 }
00359
00360 _xmlrsp = _session->get_last_response();
00361 _xmlcmd = _session->get_last_command();
00362
00363 _connected = true;
00364
00365 } catch (const IoException &e) {
00366 printf("ERROR! IO Exception [%d]:\n[%s]\n",
00367 e.get_code(), e.get_msg().c_str());
00368 exception = true;
00369 } catch (const TransportException &e) {
00370 printf("ERROR! Transport Exception [%d]:\n[%s]\n[%s]\n",
00371 e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
00372 exception = true;
00373 } catch (const GeneralException &e) {
00374 printf("ERROR! General Exception [%d]:\n[%s]\n",
00375 e.get_code(), e.get_msg().c_str());
00376 exception = true;
00377 }
00378
00379 if (exception) {
00380 return -1;
00381 }
00382
00383
00384 vector<string> dummy;
00385 cmd_xmlrsp(dummy);
00386
00387 return 0;
00388 }
00389
00391
00395 int cmd_disconnect(vector<string> &args)
00396 {
00397 if (_connected) {
00398 bool exception = false;
00399
00400
00401 try {
00402 _session->disconnect();
00403 printf("disconnected from %s\n", _server.c_str());
00404 _connected = false;
00405 } catch (const TransportException &e) {
00406 printf("ERROR! Transport Exception [%d]:\n[%s]\n[%s]\n",
00407 e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
00408 exception = true;
00409 } catch (const GeneralException &e) {
00410 printf("ERROR! General Exception [%d]:\n[%s]\n",
00411 e.get_code(), e.get_msg().c_str());
00412 exception = true;
00413 }
00414
00415 if (exception) {
00416 return -1;
00417 }
00418 } else {
00419 printf("not connected\n");
00420 }
00421
00422 return 0;
00423 }
00424
00426
00430 int cmd_beauty(vector<string> &args)
00431 {
00432 if (args.empty()) {
00433 if (_beauty) {
00434 printf("XML beautifier is ON\n");
00435 } else {
00436 printf("XML beautifier is OFF\n");
00437 }
00438 return 0;
00439 } else if (args.size() > 1) {
00440 printf("usage: beauty [on|off]\n");
00441 return -1;
00442 }
00443
00444 if (args[0] == "on") {
00445 _beauty = true;
00446 printf("XML beautifier now ON\n");
00447 } else if (args[0] == "off") {
00448 _beauty = false;
00449 printf("XML beautifier now OFF\n");
00450 } else {
00451 printf("usage: beauty [on|off]\n");
00452 return -1;
00453 }
00454
00455 return 0;
00456 }
00457
00459
00463 int cmd_debug(vector<string> &args)
00464 {
00465 if (args.empty()) {
00466 if (_debug) {
00467 printf("Debug is ON\n");
00468 } else {
00469 printf("Debug is OFF\n");
00470 }
00471 return 0;
00472 } else if (args.size() > 1) {
00473 printf("usage: debug [on|off]\n");
00474 return -1;
00475 }
00476
00477 if (args[0] == "on") {
00478 _debug = true;
00479 printf("Debug now ON\n");
00480 } else if (args[0] == "off") {
00481 _debug = false;
00482 printf("Debug now OFF\n");
00483 } else {
00484 printf("usage: beauty [on|off]\n");
00485 return -1;
00486 }
00487
00488 return 0;
00489 }
00490
00492
00496 int cmd_autorsp(vector<string> &args)
00497 {
00498 if (args.empty()) {
00499 if (_autorsp) {
00500 printf("autorsp is ON\n");
00501 } else {
00502 printf("autorsp is OFF\n");
00503 }
00504 return 0;
00505 } else if (args.size() > 1) {
00506 printf("usage: autorsp [on|off]\n");
00507 return -1;
00508 }
00509
00510 if (args[0] == "on") {
00511 _autorsp = true;
00512 printf("autorsp now ON\n");
00513 } else if (args[0] == "off") {
00514 _autorsp = false;
00515 printf("autorsp now OFF\n");
00516 } else {
00517 printf("usage: autorsp [on|off]\n");
00518 return -1;
00519 }
00520
00521 return 0;
00522 }
00523
00525
00529 int cmd_keepalive(vector<string> &args)
00530 {
00531 if (args.empty()) {
00532 if (_keepalive) {
00533 printf("Keep-alive is ON\n");
00534 } else {
00535 printf("Keep-alive is OFF\n");
00536 }
00537 return 0;
00538 } else if (args.size() > 1) {
00539 printf("usage: keepalive [on|off]\n");
00540 return -1;
00541 }
00542
00543 if (args[0] == "on") {
00544 _keepalive = true;
00545 printf("Keep-alive now ON\n");
00546 } else if (args[0] == "off") {
00547 _keepalive = false;
00548 printf("Keep-alive now OFF\n");
00549 } else {
00550 printf("usage: keepalive [on|off]\n");
00551 return -1;
00552 }
00553
00554 if (_keepalive) {
00555 alarm(_keepalive_timer);
00556 } else {
00557 alarm(0);
00558 }
00559
00560 return 0;
00561 }
00562
00564
00568 int cmd_peer_crt_check(vector<string> &args)
00569 {
00570 if (args.empty()) {
00571 if (_peer_crt_check) {
00572 printf("Peer's certificate check is ON\n");
00573 } else {
00574 printf("Peer's certificate check is OFF\n");
00575 }
00576 return 0;
00577 } else if (args.size() > 1) {
00578 printf("usage: peer-crt-check [on|off]\n");
00579 return -1;
00580 }
00581
00582 if (args[0] == "on") {
00583 _peer_crt_check = true;
00584 printf("Peer's certificate check now ON\n");
00585 } else if (args[0] == "off") {
00586 _peer_crt_check = false;
00587 printf("Peer's certificate check now OFF\n");
00588 } else {
00589 printf("usage: peer-crt-check [on|off]\n");
00590 return -1;
00591 }
00592
00593 return 0;
00594 }
00595
00597 static void sig_alrm(int signo)
00598 {
00599 if (_connected && !_cmd_running) {
00600 _ka_running = true;
00601 vector<string> args;
00602 args.push_back((string) "keepalive");
00603 cmd_hello(args);
00604 _ka_running = false;
00605 }
00606 alarm(_keepalive_timer);
00607 }
00608
00610
00614 int cmd_xmlcmd(vector<string> &args)
00615 {
00616 if (!_connected) {
00617 printf("not connected\n");
00618 return -1;
00619 }
00620
00621 if (_beauty) {
00622
00623 string last_command("");
00624 StrUtil::iso88591_to_utf8(_xmlcmd, last_command);
00625
00626 if (_session->get_last_command() == "") {
00627 printf("\n");
00628 return 0;
00629 }
00630 try {
00631 StrUtil str_util;
00632 printf("%s\n", str_util.xml_beautifier(last_command).c_str());
00633 } catch (const XmlException &e) {
00634 printf("ERROR! XML Exception [%d]:\n[%s]\n", e.get_code(),
00635 e.get_msg().c_str());
00636 }
00637 } else {
00638 printf("%s\n", _session->get_last_command().c_str());
00639 }
00640 return 0;
00641 }
00642
00644
00648 int cmd_xmlrsp(vector<string> &args)
00649 {
00650 if (!_connected) {
00651 printf("not connected\n");
00652 return -1;
00653 }
00654
00655 if (_beauty) {
00656
00657 if (_xmlrsp == "") {
00658 printf("\n");
00659 return 0;
00660 }
00661 try {
00662 StrUtil str_util;
00663 printf("%s\n", str_util.xml_beautifier(_xmlrsp).c_str());
00664 } catch (const XmlException &e) {
00665 printf("ERROR! XML Exception [%d]:\n[%s]\n", e.get_code(),
00666 e.get_msg().c_str());
00667 }
00668 } else {
00669 printf("%s\n", _xmlrsp.c_str());
00670 }
00671 return 0;
00672 }
00673
00674
00675
00677 void print_cmd_sent_ok()
00678 {
00679 if (!_autorsp) {
00680 printf("Ok! Use 'xmlcmd' and 'xmlrsp' to view command/response "
00681 "XML code.\n");
00682 } else {
00683 vector<string> dummy;
00684 cmd_xmlrsp(dummy);
00685 }
00686 }
00687
00689
00692 int process_action(Action &act)
00693 {
00694 if (!_connected) {
00695 printf("not connected\n");
00696 return -1;
00697 }
00698
00699 bool exception = false;
00700
00701
00702 if (!_ka_running) {
00703 _cmd_running = true;;
00704 } else {
00705 printf("ERROR! Keep-alive is running. Please try again.\n");
00706 return -1;
00707 }
00708
00709 try {
00710 _session->process_action(&act);
00711 _xmlrsp = _session->get_last_response();
00712 _xmlcmd = _session->get_last_command();
00713 } catch (const EppException &e) {
00714 printf("ERROR! EPP Exception [%d]:\n[%s]\n", e.get_code(),
00715 e.get_msg().c_str());
00716 exception = true;
00717 } catch (const IoException &e) {
00718 printf("ERROR! IO Exception [%d]:\n[%s]\n",
00719 e.get_code(), e.get_msg().c_str());
00720 exception = true;
00721 _connected = false;
00722 } catch (const TransportException &e) {
00723 printf("ERROR! Transport Exception [%d]:\n[%s]\n[%s]\n",
00724 e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
00725 exception = true;
00726 _connected = false;
00727 } catch (const GeneralException &e) {
00728 printf("ERROR! General Exception [%d]:\n[%s]\n",
00729 e.get_code(), e.get_msg().c_str());
00730 exception = true;
00731 }
00732
00733 if (exception) {
00734 _cmd_running = false;
00735 return -1;
00736 }
00737
00738 print_cmd_sent_ok();
00739
00740
00741 if (_keepalive) {
00742 alarm(_keepalive_timer);
00743 }
00744
00745 _cmd_running = false;
00746 return 0;
00747 }
00748
00750
00754 int cmd_login(vector<string> &args)
00755 {
00756 if (!_connected) {
00757 printf("not connected\n");
00758 return -1;
00759 }
00760
00761 if (_user == "") {
00762 printf("no username given.\n");
00763 return -1;
00764 }
00765
00766 Login act;
00767 LoginCmd *cmd = act.get_command();
00768
00769 cmd->set_clID(_user);
00770 cmd->set_pw(_login_pw);
00771
00772 if (_new_pw) {
00773 _new_pw = false;
00774 cmd->set_new_pw(_login_new_pw);
00775 }
00776
00777 if (_lang != "" && _lang != "en") {
00778 cmd->set_lang(_lang);
00779 }
00780
00781 if (process_action(act) != 0) {
00782 return -1;
00783 }
00784
00785 return 0;
00786 }
00787
00789
00793 int cmd_logout(vector<string> &args)
00794 {
00795 if (!_connected) {
00796 printf("not connected\n");
00797 return -1;
00798 }
00799
00800 Logout act;
00801
00802 if (process_action(act) != 0) {
00803 return -1;
00804 }
00805
00806 return 0;
00807 }
00808
00810
00814 int cmd_hello(vector<string> &args)
00815 {
00816 if (!_connected) {
00817 printf("not connected\n");
00818 return -1;
00819 }
00820
00821 if (_ka_running &&
00822 !(args.size() == 1 && args[0] == "keepalive")) {
00823 printf("ERROR! Keep-alive is running. Please try again.\n");
00824 return -1;
00825 }
00826
00827 bool exception = false;
00828
00829
00830 if (!_ka_running) {
00831 _cmd_running = true;
00832 }
00833
00834 try {
00835 if (_debug) {
00836 printf("Sending EPP Hello\n");
00837 }
00838 _session->send_hello();
00839
00840 if (!_ka_running) {
00841 _xmlrsp = _session->get_last_response();
00842 _xmlcmd = _session->get_last_command();
00843 }
00844 } catch (const EppException &e) {
00845 printf("ERROR! EPP Exception [%d]:\n[%s]\n", e.get_code(),
00846 e.get_msg().c_str());
00847 exception = true;
00848 } catch (const IoException &e) {
00849 printf("ERROR! IO Exception [%d]:\n[%s]\n",
00850 e.get_code(), e.get_msg().c_str());
00851 exception = true;
00852 _connected = false;
00853 } catch (const TransportException &e) {
00854 printf("ERROR! Transport Exception [%d]:\n[%s]\n[%s]\n",
00855 e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
00856 exception = true;
00857 _connected = false;
00858 } catch (const GeneralException &e) {
00859 printf("ERROR! General Exception [%d]:\n[%s]\n",
00860 e.get_code(), e.get_msg().c_str());
00861 exception = true;
00862 }
00863
00864 if (exception) {
00865 if (_cmd_running) {
00866 _cmd_running = false;
00867 }
00868 return -1;
00869 }
00870
00871 if (!_ka_running) {
00872 print_cmd_sent_ok();
00873 }
00874
00875 if (_cmd_running) {
00876
00877 if (_keepalive) {
00878 alarm(_keepalive_timer);
00879 }
00880 _cmd_running = false;
00881 }
00882 return 0;
00883 }
00884
00885
00886
00888
00892 int cmd_quit(vector<string> &args)
00893 {
00894 if (_connected) {
00895 _session->disconnect();
00896 }
00897 printf("Bye\n");
00898 exit(0);
00899 }
00900
00902
00906 int cmd_help(vector<string> &args)
00907 {
00908 list<SheppCommand>::const_iterator it;
00909 for (it = _commands.begin(); it != _commands.end(); it++) {
00910 printf("%-16s %s\n", (*it).name.c_str(), (*it).brief.c_str());
00911 }
00912
00913 return 0;
00914 }
00915
00917
00921 int cmd_about(vector<string> &args)
00922 {
00923 printf("shepp version " SHEPP_VERSION ", an EPP client shell!\n");
00924 printf("Copyright 2006 Registro.br <libepp@registro.br>\n");
00925 printf("shepp is distributed with libepp-nicbr: "
00926 "http://registro.br/epp/index-EN.html\n");
00927 #if USE_BR_DOMAINS
00928 printf("Built with BrDomain EPP extension support.\n");
00929 #endif //USE_BR_DOMAINS
00930
00931 return 0;
00932 }
00933
00934 #endif //__SHEPP_COMMAND_FUNCTIONS_H__