Home | History | Annotate | Download | only in remote-process
      1 /*
      2  * Copyright (c) 2011-2014, Intel Corporation
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without modification,
      6  * are permitted provided that the following conditions are met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright notice, this
      9  * list of conditions and the following disclaimer.
     10  *
     11  * 2. Redistributions in binary form must reproduce the above copyright notice,
     12  * this list of conditions and the following disclaimer in the documentation and/or
     13  * other materials provided with the distribution.
     14  *
     15  * 3. Neither the name of the copyright holder nor the names of its contributors
     16  * may be used to endorse or promote products derived from this software without
     17  * specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
     23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 #include <iostream>
     31 #include <string>
     32 #include <cstring>
     33 #include <stdlib.h>
     34 #include "RequestMessage.h"
     35 #include "AnswerMessage.h"
     36 #include "ConnectionSocket.h"
     37 #include "NaiveTokenizer.h"
     38 
     39 using namespace std;
     40 
     41 class CRequestMessageGenerator
     42 {
     43 private:
     44     istream& _input; // File to read the commands from
     45 
     46 public:
     47     CRequestMessageGenerator(istream& input) : _input(input) {}
     48 
     49     enum EStatus {
     50         OK,
     51         STOP,
     52         EMPTY_LINE,
     53         ERROR
     54     };
     55 
     56     EStatus next(CRequestMessage& requestMessage)
     57     {
     58         string sLine;
     59         char* pcLine;
     60         char* pcLine_backup; // pcLine will be modified by NaiveTokenizer
     61                              // so we need to keep track of its original value
     62         char* pcToken;
     63 
     64         // Read a single line from the input file
     65         getline(_input, sLine);
     66         if (_input.eof() && (_input.gcount() == 0)) {
     67             return STOP; // No more commands
     68         }
     69         if (_input.fail()) {
     70             return ERROR; // Error while reading file
     71         }
     72 
     73         pcLine = strdup(sLine.c_str());
     74         pcLine_backup = pcLine;
     75         if (!pcLine) {
     76             return ERROR;
     77         }
     78 
     79         // Set the first word as the command
     80         pcToken = NaiveTokenizer::getNextToken(&pcLine);
     81         if (!pcToken) {
     82             free(pcLine_backup);
     83             return EMPTY_LINE;
     84         }
     85         requestMessage.setCommand(pcToken);
     86 
     87         while ((pcToken = NaiveTokenizer::getNextToken(&pcLine)) != NULL) {
     88 
     89             // Add each word as arguments to the command
     90             requestMessage.addArgument(pcToken);
     91         }
     92 
     93         free(pcLine_backup);
     94 
     95         return OK;
     96     }
     97 };
     98 
     99 bool sendAndDisplayCommand(CConnectionSocket &connectionSocket, CRequestMessage &requestMessage)
    100 {
    101     string strError;
    102 
    103     if (requestMessage.serialize(&connectionSocket, true, strError)
    104             != CRequestMessage::success) {
    105 
    106         cerr << "Unable to send command to target: " << strError << endl;
    107         return false;
    108     }
    109 
    110     ///// Get answer
    111     CAnswerMessage answerMessage;
    112     if (answerMessage.serialize(&connectionSocket, false, strError)
    113             != CRequestMessage::success) {
    114 
    115         cerr << "Unable to received answer from target: " << strError << endl;
    116         return false;
    117     }
    118 
    119     // Success?
    120     if (!answerMessage.success()) {
    121 
    122         // Display error answer
    123         cerr << answerMessage.getAnswer() << endl;
    124         return false;
    125     }
    126 
    127     // Display success answer
    128     cout << answerMessage.getAnswer() << endl;
    129 
    130     return true;
    131 }
    132 
    133 // hostname port command [argument[s]]
    134 // or
    135 // hostname port < commands
    136 int main(int argc, char *argv[])
    137 {
    138     bool bFromStdin = false; // Read commands from stdin instead of arguments
    139 
    140     // Enough args?
    141     if (argc < 3) {
    142 
    143         cerr << "Missing arguments" << endl;
    144         cerr << "Usage: " << endl;
    145         cerr << "Send a single command:" << endl;
    146         cerr << "\t" << argv[0] << " hostname port command [argument[s]]" << endl;
    147         cerr << "Send several commands, read from stdin:" << endl;
    148         cerr << "\t" << argv[0] << " hostname port" << endl;
    149 
    150         return 1;
    151     } else if (argc < 4) {
    152         bFromStdin = true;
    153     }
    154     // Get port number
    155     uint16_t uiPort = (uint16_t)strtoul(argv[2], NULL, 0);
    156 
    157     // Connect to target
    158     CConnectionSocket connectionSocket;
    159 
    160     string strError;
    161     // Connect
    162     if (!connectionSocket.connect(argv[1], uiPort, strError)) {
    163 
    164         cerr << strError << endl;
    165 
    166         return 1;
    167     }
    168 
    169     if (bFromStdin) {
    170 
    171         CRequestMessageGenerator generator(cin);
    172         CRequestMessage requestMessage;
    173         CRequestMessageGenerator::EStatus status;
    174 
    175         while (true) {
    176             status = generator.next(requestMessage);
    177 
    178             switch (status) {
    179             case CRequestMessageGenerator::OK:
    180                 if (!sendAndDisplayCommand(connectionSocket, requestMessage)) {
    181                     return 1;
    182                 }
    183                 break;
    184             case CRequestMessageGenerator::STOP:
    185                 return 0;
    186             case CRequestMessageGenerator::ERROR:
    187                 cerr << "Error while reading the input" << endl;
    188                 return 1;
    189             case CRequestMessageGenerator::EMPTY_LINE:
    190                 continue;
    191             }
    192         }
    193     } else {
    194         // Create command message
    195         CRequestMessage requestMessage(argv[3]);
    196 
    197         // Add arguments
    198         uint32_t uiArg;
    199         for (uiArg = 4; uiArg < (uint32_t)argc; uiArg++) {
    200 
    201             requestMessage.addArgument(argv[uiArg]);
    202         }
    203 
    204         if (!sendAndDisplayCommand(connectionSocket, requestMessage)) {
    205             return 1;
    206         }
    207     }
    208 
    209     // Program status
    210     return 0;
    211 }
    212