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 "ibrdtn/api/FileBundle.h"
00011 #include "ibrcommon/net/tcpclient.h"
00012 #include "ibrcommon/thread/Mutex.h"
00013 #include "ibrcommon/thread/MutexLock.h"
00014 #include "ibrdtn/data/PayloadBlock.h"
00015 #include "ibrdtn/api/BLOBBundle.h"
00016 #include "ibrcommon/data/BLOB.h"
00017 #include "ibrcommon/data/File.h"
00018 #include "ibrcommon/appstreambuf.h"
00019
00020 #include <stdlib.h>
00021 #include <iostream>
00022 #include <map>
00023 #include <vector>
00024 #include <csignal>
00025 #include <sys/types.h>
00026
00027 using namespace ibrcommon;
00028
00029 void print_help()
00030 {
00031 cout << "-- dtnoutbox (IBR-DTN) --" << endl;
00032 cout << "Syntax: dtnoutbox [options] <name> <outbox> <destination>" << endl;
00033 cout << " <name> the application name" << endl;
00034 cout << " <outbox> directory with outgoing files" << endl;
00035 cout << " <destination> the destination EID for all outgoing files" << endl;
00036 cout << "* optional parameters *" << endl;
00037 cout << " -h|--help display this text" << endl;
00038 cout << " -w|--workdir temporary work directory" << endl;
00039 }
00040
00041 map<string,string> readconfiguration(int argc, char** argv)
00042 {
00043
00044 if (argc < 4) { print_help(); exit(0); }
00045
00046 map<string,string> ret;
00047
00048 ret["name"] = argv[argc - 3];
00049 ret["outbox"] = argv[argc - 2];
00050 ret["destination"] = argv[argc - 1];
00051
00052 for (int i = 0; i < (argc - 3); i++)
00053 {
00054 string arg = argv[i];
00055
00056
00057 if (arg == "-h" || arg == "--help")
00058 {
00059 print_help();
00060 exit(0);
00061 }
00062
00063 if ((arg == "-w" || arg == "--workdir") && (argc > i))
00064 {
00065 ret["workdir"] = argv[i + 1];
00066 }
00067 }
00068
00069 return ret;
00070 }
00071
00072
00073 bool _running = true;
00074
00075
00076 ibrcommon::tcpclient *_conn = NULL;
00077
00078 void term(int signal)
00079 {
00080 if (signal >= 1)
00081 {
00082 _running = false;
00083 if (_conn != NULL) _conn->close();
00084 exit(0);
00085 }
00086 }
00087
00088
00089
00090
00091 int main(int argc, char** argv)
00092 {
00093
00094 signal(SIGINT, term);
00095 signal(SIGTERM, term);
00096
00097
00098 map<string,string> conf = readconfiguration(argc, argv);
00099
00100
00101 if (conf.find("workdir") != conf.end())
00102 {
00103 ibrcommon::BLOB::tmppath = File(conf["workdir"]);
00104 }
00105
00106
00107 size_t backoff = 2;
00108
00109
00110 File outbox(conf["outbox"]);
00111
00112
00113 while (_running)
00114 {
00115 try {
00116
00117 ibrcommon::tcpclient conn("127.0.0.1", 4550);
00118
00119
00120 conn.enableNoDelay();
00121
00122
00123 _conn = &conn;
00124
00125
00126 dtn::api::Client client(conf["name"], conn, dtn::api::Client::MODE_SENDONLY);
00127
00128
00129
00130 client.connect();
00131
00132
00133 backoff = 2;
00134
00135
00136 while (_running)
00137 {
00138 list<File> files;
00139 outbox.getFiles(files);
00140
00141
00142 if (files.size() <= 2)
00143 {
00144
00145 sleep(10);
00146
00147 continue;
00148 }
00149
00150 stringstream file_list;
00151
00152 int prefix_length = outbox.getPath().length() + 1;
00153
00154 for (list<File>::iterator iter = files.begin(); iter != files.end(); iter++)
00155 {
00156 File &f = (*iter);
00157
00158
00159 if (f.isSystem()) continue;
00160
00161
00162 string rpath = f.getPath();
00163 rpath = rpath.substr(prefix_length, rpath.length() - prefix_length);
00164
00165 file_list << rpath << " ";
00166 }
00167
00168
00169 cout << "files: " << file_list.str() << endl;
00170
00171
00172 stringstream cmd; cmd << "tar --remove-files -cO -C " << outbox.getPath() << " " << file_list.str();
00173
00174
00175 appstreambuf app(cmd.str(), appstreambuf::MODE_READ);
00176 istream stream(&app);
00177
00178
00179 ibrcommon::BLOB::Reference blob = ibrcommon::TmpFileBLOB::create();
00180
00181
00182 (*blob.iostream()) << stream.rdbuf();
00183
00184
00185 dtn::data::EID destination = EID(conf["destination"]);
00186 dtn::api::BLOBBundle b(destination, blob);
00187
00188
00189 client << b; client.flush();
00190
00191 if (_running)
00192 {
00193
00194 sleep(10);
00195 }
00196 }
00197
00198
00199 client.close();
00200
00201
00202 conn.close();
00203
00204
00205 _conn = NULL;
00206 } catch (const ibrcommon::tcpclient::SocketException&) {
00207
00208 _conn = NULL;
00209
00210 if (_running)
00211 {
00212 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00213 sleep(backoff);
00214
00215
00216 if (backoff < 600)
00217 {
00218
00219 backoff = backoff * 2;
00220 }
00221 }
00222 } catch (const ibrcommon::IOException&) {
00223
00224 _conn = NULL;
00225
00226 if (_running)
00227 {
00228 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00229 sleep(backoff);
00230
00231
00232 if (backoff < 600)
00233 {
00234
00235 backoff = backoff * 2;
00236 }
00237 }
00238 } catch (const std::exception&) {
00239
00240 _conn = NULL;
00241 }
00242 }
00243
00244 return (EXIT_SUCCESS);
00245 }