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 }
00085 }
00086
00087
00088
00089
00090 int main(int argc, char** argv)
00091 {
00092
00093 signal(SIGINT, term);
00094 signal(SIGTERM, term);
00095
00096
00097 map<string,string> conf = readconfiguration(argc, argv);
00098
00099
00100 if (conf.find("workdir") != conf.end())
00101 {
00102 ibrcommon::BLOB::tmppath = File(conf["workdir"]);
00103 }
00104
00105
00106 size_t backoff = 2;
00107
00108
00109 File outbox(conf["outbox"]);
00110
00111
00112 while (_running)
00113 {
00114 try {
00115
00116 ibrcommon::tcpclient conn("127.0.0.1", 4550);
00117
00118
00119 _conn = &conn;
00120
00121
00122 dtn::api::Client client(dtn::api::Client::MODE_SENDONLY, conf["name"], conn);
00123
00124
00125
00126 client.connect();
00127
00128
00129 if (client.isConnected()) backoff = 2;
00130
00131
00132 while (client.isConnected() && _running)
00133 {
00134 list<File> files;
00135 outbox.getFiles(files);
00136
00137
00138 if (files.size() <= 2)
00139 {
00140
00141 sleep(10);
00142
00143 continue;
00144 }
00145
00146 stringstream file_list;
00147
00148 int prefix_length = outbox.getPath().length() + 1;
00149
00150 for (list<File>::iterator iter = files.begin(); iter != files.end(); iter++)
00151 {
00152 File &f = (*iter);
00153
00154
00155 if (f.isSystem()) continue;
00156
00157
00158 string rpath = f.getPath();
00159 rpath = rpath.substr(prefix_length, rpath.length() - prefix_length);
00160
00161 file_list << rpath << " ";
00162 }
00163
00164
00165 cout << "files: " << file_list.str() << endl;
00166
00167
00168 stringstream cmd; cmd << "tar --remove-files -cO -C " << outbox.getPath() << " " << file_list.str();
00169
00170
00171 appstreambuf app(cmd.str(), appstreambuf::MODE_READ);
00172 istream stream(&app);
00173
00174
00175 ibrcommon::BLOB::Reference blob = ibrcommon::TmpFileBLOB::create();
00176
00177
00178 {
00179 ibrcommon::MutexLock l(blob);
00180 (*blob) << stream.rdbuf();
00181 }
00182
00183
00184 dtn::data::EID destination = EID(conf["destination"]);
00185 dtn::api::BLOBBundle b(destination, blob);
00186
00187
00188 client << b; client.flush();
00189
00190 if (_running)
00191 {
00192
00193 sleep(10);
00194 }
00195 }
00196
00197
00198 client.close();
00199
00200
00201 conn.close();
00202
00203
00204 _conn = NULL;
00205 } catch (ibrcommon::tcpclient::SocketException ex) {
00206
00207 _conn = NULL;
00208
00209 if (_running)
00210 {
00211 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00212 sleep(backoff);
00213
00214
00215 if (backoff < 600)
00216 {
00217
00218 backoff = backoff * 2;
00219 }
00220 }
00221 } catch (ibrcommon::IOException ex) {
00222
00223 _conn = NULL;
00224
00225 if (_running)
00226 {
00227 cout << "Connection to bundle daemon failed. Retry in " << backoff << " seconds." << endl;
00228 sleep(backoff);
00229
00230
00231 if (backoff < 600)
00232 {
00233
00234 backoff = backoff * 2;
00235 }
00236 }
00237 } catch (ibrcommon::ConnectionClosedException ex) {
00238
00239 _conn = NULL;
00240 }
00241 }
00242
00243 return (EXIT_SUCCESS);
00244 }