tool/CommandFoeWrite.cpp
changeset 1335 09c6fce1ae45
child 1336 e27b37e80a99
equal deleted inserted replaced
1334:da3d22a27500 1335:09c6fce1ae45
       
     1 /*****************************************************************************
       
     2  *
       
     3  * $Id$
       
     4  *
       
     5  ****************************************************************************/
       
     6 
       
     7 #include <libgen.h> // basename()
       
     8 
       
     9 #include <iostream>
       
    10 #include <iomanip>
       
    11 #include <fstream>
       
    12 using namespace std;
       
    13 
       
    14 #include "CommandFoeWrite.h"
       
    15 
       
    16 /*****************************************************************************/
       
    17 
       
    18 CommandFoeWrite::CommandFoeWrite():
       
    19     FoeCommand("foe_write", "Store a file on a slave via FoE.")
       
    20 {
       
    21 }
       
    22 
       
    23 /*****************************************************************************/
       
    24 
       
    25 string CommandFoeWrite::helpString() const
       
    26 {
       
    27     stringstream str;
       
    28 
       
    29     str << getName() << " [OPTIONS] <FILENAME>" << endl
       
    30         << endl
       
    31         << getBriefDescription() << endl
       
    32         << endl
       
    33         << "This command requires a single slave to be selected." << endl
       
    34     	<< endl
       
    35         << "Arguments:" << endl
       
    36         << "  FILENAME can either be a path to a file, or '-'. In" << endl
       
    37         << "           the latter case, data are read from stdin and" << endl
       
    38         << "           the --output-file option has to be specified." << endl
       
    39         << endl
       
    40         << "Command-specific options:" << endl
       
    41         << "  --output-file -o <file>   Target filename on the slave." << endl
       
    42         << "                            If the FILENAME argument is" << endl
       
    43         << "                            '-', this is mandatory." << endl
       
    44         << "                            Otherwise, the basename() of" << endl
       
    45         << "                            FILENAME is used by default." << endl
       
    46         << "  --alias       -a <alias>" << endl
       
    47         << "  --position    -p <pos>    Slave selection. See the help" << endl
       
    48         << "                            of the 'slaves' command." << endl
       
    49         << endl
       
    50         << numericInfo();
       
    51 
       
    52     return str.str();
       
    53 }
       
    54 
       
    55 /****************************************************************************/
       
    56 
       
    57 void CommandFoeWrite::execute(MasterDevice &m, const StringVector &args)
       
    58 {
       
    59     stringstream err;
       
    60     ec_ioctl_slave_foe_t data;
       
    61     ifstream file;
       
    62     SlaveList slaves;
       
    63     string storeFileName;
       
    64 
       
    65     if (args.size() != 1) {
       
    66         err << "'" << getName() << "' takes exactly one argument!";
       
    67         throwInvalidUsageException(err);
       
    68     }
       
    69 
       
    70     if (args[0] == "-") {
       
    71         loadFoeData(&data, cin);
       
    72         if (getOutputFile().empty()) {
       
    73             err << "Please specify a filename for the slave side"
       
    74                 << " with --output-file!";
       
    75             throwCommandException(err);
       
    76         } else {
       
    77             storeFileName = getOutputFile();
       
    78         }
       
    79     } else {
       
    80         file.open(args[0].c_str(), ifstream::in | ifstream::binary);
       
    81         if (file.fail()) {
       
    82             err << "Failed to open '" << args[0] << "'!";
       
    83             throwCommandException(err);
       
    84         }
       
    85         loadFoeData(&data, file);
       
    86         file.close();
       
    87         if (getOutputFile().empty()) {
       
    88             char *cpy = strdup(args[0].c_str()); // basename can modify
       
    89                                                  // the string contents
       
    90             storeFileName = basename(cpy);
       
    91             free(cpy);
       
    92         } else {
       
    93             storeFileName = getOutputFile();
       
    94         }
       
    95     }
       
    96 
       
    97     try {
       
    98         m.open(MasterDevice::ReadWrite);
       
    99     } catch (MasterDeviceException &e) {
       
   100         if (data.buffer_size)
       
   101             delete [] data.buffer;
       
   102         throw e;
       
   103     }
       
   104 
       
   105     slaves = selectedSlaves(m);
       
   106     if (slaves.size() != 1) {
       
   107         if (data.buffer_size)
       
   108             delete [] data.buffer;
       
   109         throwSingleSlaveRequired(slaves.size());
       
   110     }
       
   111     data.slave_position = slaves.front().position;
       
   112 
       
   113     // write data via foe to the slave
       
   114     data.offset = 0;
       
   115     strncpy(data.file_name, storeFileName.c_str(), sizeof(data.file_name));
       
   116 
       
   117     try {
       
   118         m.writeFoe(&data);
       
   119     } catch (MasterDeviceException &e) {
       
   120         if (data.buffer_size)
       
   121             delete [] data.buffer;
       
   122         if (data.abort_code) {
       
   123             err << "Failed to write via FoE: "
       
   124                 << errorString(data.abort_code);
       
   125             throwCommandException(err);
       
   126         } else {
       
   127             throw e;
       
   128         }
       
   129     }
       
   130 
       
   131     if (getVerbosity() == Verbose) {
       
   132         cerr << "FoE writing finished." << endl;
       
   133     }
       
   134 
       
   135     if (data.buffer_size)
       
   136         delete [] data.buffer;
       
   137 }
       
   138 
       
   139 /*****************************************************************************/
       
   140 
       
   141 void CommandFoeWrite::loadFoeData(
       
   142         ec_ioctl_slave_foe_t *data,
       
   143         const istream &in
       
   144         )
       
   145 {
       
   146     stringstream err;
       
   147     ostringstream tmp;
       
   148 
       
   149     tmp << in.rdbuf();
       
   150     string const &contents = tmp.str();
       
   151 
       
   152     if (getVerbosity() == Verbose) {
       
   153         cerr << "Read " << contents.size() << " bytes of FoE data." << endl;
       
   154     }
       
   155 
       
   156     data->buffer_size = contents.size();
       
   157 
       
   158     if (data->buffer_size) {
       
   159         // allocate buffer and read file into buffer
       
   160         data->buffer = new uint8_t[data->buffer_size];
       
   161         contents.copy((char *) data->buffer, contents.size());
       
   162     }
       
   163 }
       
   164 
       
   165 /*****************************************************************************/