IBR-DTNSuite  0.8
tools/src/dtnsend.cpp
Go to the documentation of this file.
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 }