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