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