00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009 #include <ibrdtn/api/Client.h>
00010 #include <ibrcommon/net/tcpclient.h>
00011
00012 #include <ibrcommon/data/File.h>
00013
00031 #include <csignal>
00032 #include <ctype.h>
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <unistd.h>
00036
00037
00038
00039 bool _running = true;
00040
00041
00042 ibrcommon::tcpclient *_conn = NULL;
00043
00044 std::string _appname = "trigger";
00045 std::string _script = "";
00046 std::string _shell = "/bin/sh";
00047
00048 void print_help()
00049 {
00050 cout << "-- dtntrigger (IBR-DTN) --" << endl;
00051 cout << "Syntax: dtntrigger [options] <name> <shell> [trigger-script]" << endl;
00052 cout << "<name> the application name" << endl;
00053 cout << "<shell> shell to execute the trigger script" << endl;
00054 cout << "[trigger-script] optional: the trigger script to execute on incoming bundle" << endl;
00055 cout << "* optional parameters *" << endl;
00056 cout << " -h|--help display this text" << endl;
00057 cout << " -w|--workdir temporary work directory" << endl;
00058 }
00059
00060 int init(int argc, char** argv)
00061 {
00062 int index;
00063 int c;
00064
00065 opterr = 0;
00066
00067 while ((c = getopt (argc, argv, "w:")) != -1)
00068 switch (c)
00069 {
00070 case 'w':
00071 ibrcommon::BLOB::tmppath = ibrcommon::File(optarg);
00072 break;
00073
00074 case '?':
00075 if (optopt == 'w')
00076 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
00077 else if (isprint (optopt))
00078 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
00079 else
00080 fprintf (stderr,
00081 "Unknown option character `\\x%x'.\n",
00082 optopt);
00083 return 1;
00084
00085 default:
00086 print_help();
00087 abort();
00088 }
00089
00090 int optindex = 0;
00091 for (index = optind; index < argc; index++)
00092 {
00093 switch (optindex)
00094 {
00095 case 0:
00096 _appname = std::string(argv[index]);
00097 break;
00098
00099 case 1:
00100 _shell = std::string(argv[index]);
00101 break;
00102
00103 case 2:
00104 _script = std::string(argv[index]);
00105 break;
00106 }
00107
00108 optindex++;
00109 }
00110
00111
00112 if (optindex < 2) { print_help(); exit(0); }
00113
00114 return 0;
00115 }
00116
00117 void term(int signal)
00118 {
00119 if (signal >= 1)
00120 {
00121 _running = false;
00122 if (_conn != NULL) _conn->close();
00123 }
00124 }
00125
00126
00127
00128
00129 int main(int argc, char** argv)
00130 {
00131
00132 signal(SIGINT, term);
00133 signal(SIGTERM, term);
00134
00135
00136 if (init(argc, argv) > 0)
00137 {
00138 return (EXIT_FAILURE);
00139 }
00140
00141
00142 size_t backoff = 2;
00143
00144
00145 while (_running)
00146 {
00147 try {
00148
00149 ibrcommon::tcpclient conn("127.0.0.1", 4550);
00150
00151
00152 _conn = &conn;
00153
00154
00155 dtn::api::Client client(_appname, conn);
00156
00157
00158
00159 client.connect();
00160
00161
00162 if (client.isConnected()) backoff = 2;
00163
00164
00165 while (client.isConnected() && _running)
00166 {
00167
00168 dtn::api::Bundle b = client.getBundle();
00169
00170
00171 ibrcommon::BLOB::Reference ref = b.getData();
00172
00173
00174 ibrcommon::TemporaryFile file(ibrcommon::BLOB::tmppath, "bundle");
00175
00176
00177 try {
00178 std::fstream out(file.getPath().c_str(), ios::out|ios::binary|ios::trunc);
00179 out.exceptions(std::ios::badbit | std::ios::failbit | std::ios::eofbit);
00180 ibrcommon::Mutex l(ref);
00181 out << (*ref).rdbuf();
00182 out.close();
00183
00184
00185 std::string cmd = _shell + " " + _script + " " + b.getSource().getString() + " " + file.getPath();
00186 ::system(cmd.c_str());
00187
00188
00189 file.remove();
00190 } catch (ios_base::failure ex) {
00191
00192 }
00193 }
00194
00195
00196 client.close();
00197
00198
00199 conn.close();
00200
00201
00202 _conn = NULL;
00203 } catch (ibrcommon::tcpclient::SocketException ex) {
00204
00205 _conn = NULL;
00206
00207 if (_running)
00208 {
00209 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00210 sleep(backoff);
00211
00212
00213 if (backoff < 600)
00214 {
00215
00216 backoff = backoff * 2;
00217 }
00218 }
00219 } catch (ibrcommon::IOException ex) {
00220
00221 _conn = NULL;
00222
00223 if (_running)
00224 {
00225 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00226 sleep(backoff);
00227
00228
00229 if (backoff < 600)
00230 {
00231
00232 backoff = backoff * 2;
00233 }
00234 }
00235 } catch (ibrcommon::ConnectionClosedException ex) {
00236
00237 _conn = NULL;
00238 }
00239 }
00240
00241 return (EXIT_SUCCESS);
00242 }