IBR-DTNSuite
0.8
|
00001 /* 00002 * dtnsend.cpp 00003 * 00004 * Created on: 15.10.2009 00005 * Author: morgenro 00006 */ 00007 00008 #include "config.h" 00009 #include <ibrdtn/api/Client.h> 00010 #include <ibrdtn/api/FileBundle.h> 00011 #include <ibrdtn/api/BLOBBundle.h> 00012 #include <ibrcommon/net/tcpclient.h> 00013 #include <ibrcommon/thread/Mutex.h> 00014 #include <ibrcommon/thread/MutexLock.h> 00015 #include <ibrcommon/data/BLOB.h> 00016 #include <ibrcommon/Logger.h> 00017 00018 #include <iostream> 00019 00020 void print_help() 00021 { 00022 cout << "-- dtnsend (IBR-DTN) --" << endl; 00023 cout << "Syntax: dtnsend [options] <dst> <filename>" << endl; 00024 cout << " <dst> set the destination eid (e.g. dtn://node/filetransfer)" << endl; 00025 cout << " <filename> the file to transfer" << endl; 00026 cout << "* optional parameters *" << endl; 00027 cout << " -h|--help display this text" << endl; 00028 cout << " --src <name> set the source application name (e.g. filetransfer)" << endl; 00029 cout << " -p <0..2> set the bundle priority (0 = low, 1 = normal, 2 = high)" << endl; 00030 cout << " -g receiver is a destination group" << endl; 00031 cout << " --lifetime <seconds>" << endl; 00032 cout << " set the lifetime of outgoing bundles; default: 3600" << endl; 00033 cout << " -U <socket> use UNIX domain sockets" << endl; 00034 cout << " -n <copies> create <copies> bundle copies" << endl; 00035 cout << " --encrypt request encryption on the bundle layer" << endl; 00036 cout << " --sign request signature on the bundle layer" << endl; 00037 cout << " --custody request custody transfer of the bundle" << endl; 00038 cout << " --compression request compression of the payload" << endl; 00039 00040 } 00041 00042 int main(int argc, char *argv[]) 00043 { 00044 bool error = false; 00045 string file_destination = "dtn://local/filetransfer"; 00046 string file_source = ""; 00047 unsigned int lifetime = 3600; 00048 bool use_stdin = false; 00049 std::string filename; 00050 ibrcommon::File unixdomain; 00051 int priority = 1; 00052 int copies = 1; 00053 bool bundle_encryption = false; 00054 bool bundle_signed = false; 00055 bool bundle_custody = false; 00056 bool bundle_compression = false; 00057 bool bundle_group = false; 00058 00059 // ibrcommon::Logger::setVerbosity(99); 00060 // ibrcommon::Logger::addStream(std::cout, ibrcommon::Logger::LOGGER_ALL, ibrcommon::Logger::LOG_DATETIME | ibrcommon::Logger::LOG_LEVEL); 00061 00062 std::list<std::string> arglist; 00063 00064 for (int i = 0; i < argc; i++) 00065 { 00066 if (argv[i][0] == '-') 00067 { 00068 std::string arg = argv[i]; 00069 00070 // print help if requested 00071 if (arg == "-h" || arg == "--help") 00072 { 00073 print_help(); 00074 return 0; 00075 } 00076 else if (arg == "--encrypt") 00077 { 00078 bundle_encryption = true; 00079 } 00080 else if (arg == "--sign") 00081 { 00082 bundle_signed = true; 00083 } 00084 else if (arg == "--custody") 00085 { 00086 bundle_custody = true; 00087 } 00088 else if (arg == "--compression") 00089 { 00090 bundle_compression = true; 00091 } 00092 else if (arg == "--src" && argc > i) 00093 { 00094 if (++i > argc) 00095 { 00096 std::cout << "argument missing!" << std::endl; 00097 return -1; 00098 } 00099 00100 file_source = argv[i]; 00101 } 00102 else if (arg == "--lifetime" && argc > i) 00103 { 00104 if (++i > argc) 00105 { 00106 std::cout << "argument missing!" << std::endl; 00107 return -1; 00108 } 00109 00110 stringstream data; data << argv[i]; 00111 data >> lifetime; 00112 } 00113 else if (arg == "-p" && argc > i) 00114 { 00115 if (++i > argc) 00116 { 00117 std::cout << "argument missing!" << std::endl; 00118 return -1; 00119 } 00120 stringstream data; data << argv[i]; 00121 data >> priority; 00122 } 00123 else if (arg == "-U" && argc > i) 00124 { 00125 if (++i > argc) 00126 { 00127 std::cout << "argument missing!" << std::endl; 00128 return -1; 00129 } 00130 00131 unixdomain = ibrcommon::File(argv[i]); 00132 } 00133 else if (arg == "-n" && argc > i) 00134 { 00135 if (++i > argc) 00136 { 00137 std::cout << "argument missing!" << std::endl; 00138 return -1; 00139 } 00140 00141 stringstream data; data << argv[i]; 00142 data >> copies; 00143 00144 if( copies < 1 ) { 00145 std::cout << "invalid number of bundle copies!" << std::endl; 00146 return -1; 00147 } 00148 } 00149 else if (arg == "-g") 00150 { 00151 bundle_group = true; 00152 } 00153 else 00154 { 00155 std::cout << "invalid argument " << arg << std::endl; 00156 return -1; 00157 } 00158 } 00159 else 00160 { 00161 arglist.push_back(argv[i]); 00162 } 00163 } 00164 00165 if (arglist.size() <= 1) 00166 { 00167 print_help(); 00168 return -1; 00169 } else if (arglist.size() == 2) 00170 { 00171 std::list<std::string>::iterator iter = arglist.begin(); iter++; 00172 00173 // the first parameter is the destination 00174 file_destination = (*iter); 00175 00176 use_stdin = true; 00177 } 00178 else if (arglist.size() > 2) 00179 { 00180 std::list<std::string>::iterator iter = arglist.begin(); iter++; 00181 00182 // the first parameter is the destination 00183 file_destination = (*iter); iter++; 00184 00185 // the second parameter is the filename 00186 filename = (*iter); 00187 } 00188 00189 try { 00190 // Create a stream to the server using TCP. 00191 ibrcommon::tcpclient conn; 00192 00193 // check if the unixdomain socket exists 00194 if (unixdomain.exists()) 00195 { 00196 // connect to the unix domain socket 00197 conn.open(unixdomain); 00198 } 00199 else 00200 { 00201 // connect to the standard local api port 00202 conn.open("127.0.0.1", 4550); 00203 00204 // enable nodelay option 00205 conn.enableNoDelay(); 00206 } 00207 00208 try { 00209 // Initiate a client for synchronous receiving 00210 dtn::api::Client client(file_source, conn, dtn::api::Client::MODE_SENDONLY); 00211 00212 // Connect to the server. Actually, this function initiate the 00213 // stream protocol by starting the thread and sending the contact header. 00214 client.connect(); 00215 00216 // target address 00217 EID addr = EID(file_destination); 00218 00219 try { 00220 if (use_stdin) 00221 { 00222 cout << "Transfer stdin to " << addr.getString() << endl; 00223 00224 // create an empty BLOB 00225 ibrcommon::BLOB::Reference ref = ibrcommon::BLOB::create(); 00226 00227 // copy cin to a BLOB 00228 (*ref.iostream()) << cin.rdbuf(); 00229 00230 for(int u=0; u<copies; u++){ 00231 dtn::api::BLOBBundle b(file_destination, ref); 00232 00233 // set destination address to non-singleton 00234 if (bundle_group) b.setSingleton(false); 00235 00236 // enable encryption if requested 00237 if (bundle_encryption) b.requestEncryption(); 00238 00239 // enable signature if requested 00240 if (bundle_signed) b.requestSigned(); 00241 00242 // enable custody transfer if requested 00243 if (bundle_custody) b.requestCustodyTransfer(); 00244 00245 // enable compression 00246 if (bundle_compression) b.requestCompression(); 00247 00248 // set the lifetime 00249 b.setLifetime(lifetime); 00250 00251 // set the bundles priority 00252 b.setPriority(dtn::api::Bundle::BUNDLE_PRIORITY(priority)); 00253 00254 // send the bundle 00255 client << b; 00256 00257 if (copies > 1) 00258 { 00259 std::cout << "sent copy #" << (u+1) << std::endl; 00260 } 00261 } 00262 } 00263 else 00264 { 00265 cout << "Transfer file \"" << filename << "\" to " << addr.getString() << endl; 00266 00267 for(int u=0; u<copies; u++){ 00268 // create a bundle from the file 00269 dtn::api::FileBundle b(file_destination, filename); 00270 00271 // set destination address to non-singleton 00272 if (bundle_group) b.setSingleton(false); 00273 00274 // enable encryption if requested 00275 if (bundle_encryption) b.requestEncryption(); 00276 00277 // enable signature if requested 00278 if (bundle_signed) b.requestSigned(); 00279 00280 // enable custody transfer if requested 00281 if (bundle_custody) b.requestCustodyTransfer(); 00282 00283 // enable compression 00284 if (bundle_compression) b.requestCompression(); 00285 00286 // set the lifetime 00287 b.setLifetime(lifetime); 00288 00289 // set the bundles priority 00290 b.setPriority(dtn::api::Bundle::BUNDLE_PRIORITY(priority)); 00291 00292 // send the bundle 00293 client << b; 00294 00295 if (copies > 1) 00296 { 00297 std::cout << "sent copy #" << (u+1) << std::endl; 00298 } 00299 } 00300 } 00301 00302 // flush the buffers 00303 client.flush(); 00304 } catch (const ibrcommon::IOException &ex) { 00305 std::cerr << "Error while sending bundle." << std::endl; 00306 std::cerr << "\t" << ex.what() << std::endl; 00307 error = true; 00308 } 00309 00310 // Shutdown the client connection. 00311 client.close(); 00312 00313 } catch (const ibrcommon::IOException &ex) { 00314 cout << "Error: " << ex.what() << endl; 00315 error = true; 00316 } catch (const dtn::api::ConnectionException&) { 00317 // connection already closed, the daemon was faster 00318 } 00319 00320 // close the tcpstream 00321 conn.close(); 00322 } catch (const std::exception &ex) { 00323 cout << "Error: " << ex.what() << endl; 00324 error = true; 00325 } 00326 00327 if (error) return -1; 00328 00329 return 0; 00330 }