Go to the documentation of this file.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 ibrcommon::BLOB::tmppath = ibrcommon::File("/tmp");
00065
00066 opterr = 0;
00067
00068 while ((c = getopt (argc, argv, "w:")) != -1)
00069 switch (c)
00070 {
00071 case 'w':
00072 ibrcommon::BLOB::tmppath = ibrcommon::File(optarg);
00073 break;
00074
00075 case '?':
00076 if (optopt == 'w')
00077 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
00078 else if (isprint (optopt))
00079 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
00080 else
00081 fprintf (stderr,
00082 "Unknown option character `\\x%x'.\n",
00083 optopt);
00084 return 1;
00085
00086 default:
00087 print_help();
00088 abort();
00089 }
00090
00091 int optindex = 0;
00092 for (index = optind; index < argc; index++)
00093 {
00094 switch (optindex)
00095 {
00096 case 0:
00097 _appname = std::string(argv[index]);
00098 break;
00099
00100 case 1:
00101 _shell = std::string(argv[index]);
00102 break;
00103
00104 case 2:
00105 _script = std::string(argv[index]);
00106 break;
00107 }
00108
00109 optindex++;
00110 }
00111
00112
00113 if (optindex < 2) { print_help(); exit(0); }
00114
00115 return 0;
00116 }
00117
00118 void term(int signal)
00119 {
00120 if (signal >= 1)
00121 {
00122 _running = false;
00123 if (_conn != NULL) _conn->close();
00124 exit(0);
00125 }
00126 }
00127
00128
00129
00130
00131 int main(int argc, char** argv)
00132 {
00133
00134 signal(SIGINT, term);
00135 signal(SIGTERM, term);
00136
00137
00138 if (init(argc, argv) > 0)
00139 {
00140 return (EXIT_FAILURE);
00141 }
00142
00143
00144 size_t backoff = 2;
00145
00146
00147 while (_running)
00148 {
00149 try {
00150
00151 ibrcommon::tcpclient conn("127.0.0.1", 4550);
00152
00153
00154 conn.enableNoDelay();
00155
00156
00157 _conn = &conn;
00158
00159
00160 dtn::api::Client client(_appname, conn);
00161
00162
00163
00164 client.connect();
00165
00166
00167 backoff = 2;
00168
00169
00170 while (_running)
00171 {
00172
00173 dtn::api::Bundle b = client.getBundle();
00174
00175
00176 ibrcommon::BLOB::Reference ref = b.getData();
00177
00178
00179 ibrcommon::TemporaryFile file(ibrcommon::BLOB::tmppath, "bundle");
00180
00181
00182 try {
00183 std::fstream out(file.getPath().c_str(), ios::out|ios::binary|ios::trunc);
00184 out.exceptions(std::ios::badbit | std::ios::eofbit);
00185 out << ref.iostream()->rdbuf();
00186 out.close();
00187
00188
00189 std::string cmd = _shell + " " + _script + " " + b.getSource().getString() + " " + file.getPath();
00190 ::system(cmd.c_str());
00191
00192
00193 file.remove();
00194 } catch (const ios_base::failure&) {
00195
00196 }
00197 }
00198
00199
00200 client.close();
00201
00202
00203 conn.close();
00204
00205
00206 _conn = NULL;
00207 } catch (const ibrcommon::tcpclient::SocketException&) {
00208
00209 _conn = NULL;
00210
00211 if (_running)
00212 {
00213 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00214 sleep(backoff);
00215
00216
00217 if (backoff < 600)
00218 {
00219
00220 backoff = backoff * 2;
00221 }
00222 }
00223 } catch (const ibrcommon::IOException &ex) {
00224
00225 _conn = NULL;
00226
00227 if (_running)
00228 {
00229 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00230 sleep(backoff);
00231
00232
00233 if (backoff < 600)
00234 {
00235
00236 backoff = backoff * 2;
00237 }
00238 }
00239 } catch (const std::exception&) {
00240
00241 _conn = NULL;
00242 }
00243 }
00244
00245 return (EXIT_SUCCESS);
00246 }