From df8bf839ca3b7ce9a0ac6f1b645f27bdbc8509e5 Mon Sep 17 00:00:00 2001 From: David Wagner Date: Thu, 5 Dec 2013 19:07:08 +0100 Subject: remote-process: allow reading commands from stdin BZ: 154316 The remote-process utility was only able to send one command at a time. This patch adds a new usage: if the command is omitted, remote-process reads stdin and sends each line as commands. It stops whenever it encounters an error of any kind (internal or returned by the server). Example of the new usage: remote-process localhost 5000 < commands.txt Change-Id: I2478668807b5541544c5752e68e112c23c85af15 Signed-off-by: David Wagner --- remote-process/Android.mk | 3 + remote-process/main.cpp | 184 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 145 insertions(+), 42 deletions(-) (limited to 'remote-process') diff --git a/remote-process/Android.mk b/remote-process/Android.mk index 7cf3ba7..7d63eb5 100644 --- a/remote-process/Android.mk +++ b/remote-process/Android.mk @@ -19,6 +19,7 @@ common_c_includes := \ $(LOCAL_PATH)/../remote-processor/ common_shared_libraries := libremote-processor +common_static_libraries := libaudiocomms_naive_tokenizer ############################# # Target build @@ -38,6 +39,7 @@ LOCAL_C_INCLUDES += \ bionic/ LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) libstlport +LOCAL_STATIC_LIBRARIES := $(common_static_libraries) include $(BUILD_EXECUTABLE) @@ -59,5 +61,6 @@ LOCAL_C_INCLUDES += \ LOCAL_SHARED_LIBRARIES := $(foreach shared_library, $(common_shared_libraries), \ $(shared_library)_host) +LOCAL_STATIC_LIBRARIES := $(common_static_libraries) include $(BUILD_HOST_EXECUTABLE) diff --git a/remote-process/main.cpp b/remote-process/main.cpp index e2e372e..57dcfa9 100644 --- a/remote-process/main.cpp +++ b/remote-process/main.cpp @@ -23,23 +23,124 @@ * UPDATED: 2011-07-27 */ #include +#include +#include #include #include "RequestMessage.h" #include "AnswerMessage.h" #include "ConnectionSocket.h" +#include "NaiveTokenizer.h" using namespace std; +class CRequestMessageGenerator +{ +private: + istream& _input; // File to read the commands from + +public: + CRequestMessageGenerator(istream& input) : _input(input) {} + + enum EStatus { + OK, + STOP, + EMPTY_LINE, + ERROR + }; + + EStatus next(CRequestMessage& requestMessage) + { + string sLine; + char* pcLine; + char* pcLine_backup; // pcLine will be modified by NaiveTokenizer + // so we need to keep track of its original value + char* pcToken; + + // Read a single line from the input file + getline(_input, sLine); + if (_input.eof() && (_input.gcount() == 0)) { + return STOP; // No more commands + } + if (_input.fail()) { + return ERROR; // Error while reading file + } + + pcLine = strdup(sLine.c_str()); + pcLine_backup = pcLine; + if (!pcLine) { + return ERROR; + } + + // Set the first word as the command + pcToken = NaiveTokenizer::getNextToken(&pcLine); + if (!pcToken) { + free(pcLine_backup); + return EMPTY_LINE; + } + requestMessage.setCommand(pcToken); + + while ((pcToken = NaiveTokenizer::getNextToken(&pcLine)) != NULL) { + + // Add each word as arguments to the command + requestMessage.addArgument(pcToken); + } + + free(pcLine_backup); + + return OK; + } +}; + +bool sendAndDisplayCommand(CConnectionSocket &connectionSocket, CRequestMessage &requestMessage) +{ + if (!requestMessage.serialize(&connectionSocket, true)) { + + cerr << "Unable to send command to target" << endl; + return false; + } + + ///// Get answer + CAnswerMessage answerMessage; + if (!answerMessage.serialize(&connectionSocket, false)) { + + cerr << "No answer received from target" << endl; + return false; + } + + // Success? + if (!answerMessage.success()) { + + // Display error answer + cerr << answerMessage.getAnswer() << endl; + return false; + } + + // Display success answer + cout << answerMessage.getAnswer() << endl; + + return true; +} + // hostname port command [argument[s]] +// or +// hostname port < commands int main(int argc, char *argv[]) { + bool bFromStdin = false; // Read commands from stdin instead of arguments + // Enough args? - if (argc < 4) { + if (argc < 3) { cerr << "Missing arguments" << endl; - cerr << "Usage: " << argv[0] << " hostname port command [argument[s]]" << endl; - - return -1; + cerr << "Usage: " << endl; + cerr << "Send a single command:" << endl; + cerr << "\t" << argv[0] << " hostname port command [argument[s]]" << endl; + cerr << "Send several commands, read from stdin:" << endl; + cerr << "\t" << argv[0] << " hostname port" << endl; + + return 1; + } else if (argc < 4) { + bFromStdin = true; } // Get port number uint16_t uiPort = (uint16_t)strtoul(argv[2], NULL, 0); @@ -56,50 +157,49 @@ int main(int argc, char *argv[]) cerr << strError << endl; - return -2; + return 1; } - // Create command message - CRequestMessage requestMessage(argv[3]); - - // Add arguments - uint32_t uiArg; - - for (uiArg = 4; uiArg < (uint32_t)argc; uiArg++) { - - requestMessage.addArgument(argv[uiArg]); - } - - ///// Send command - if (!requestMessage.serialize(&connectionSocket, true)) { - - cerr << "Unable to send command to target" << endl; - - return -3; - } - - // Create answer message - CAnswerMessage answerMessage; - - ///// Get answer - if (!answerMessage.serialize(&connectionSocket, false)) { - - cerr << "No answer received from target" << endl; - - return -4; - } + if (bFromStdin) { + + CRequestMessageGenerator generator(cin); + CRequestMessage requestMessage; + CRequestMessageGenerator::EStatus status; + + while (true) { + status = generator.next(requestMessage); + + switch (status) { + case CRequestMessageGenerator::OK: + if (!sendAndDisplayCommand(connectionSocket, requestMessage)) { + return 1; + } + break; + case CRequestMessageGenerator::STOP: + return 0; + case CRequestMessageGenerator::ERROR: + cerr << "Error while reading the input" << endl; + return 1; + case CRequestMessageGenerator::EMPTY_LINE: + continue; + } + } + } else { + // Create command message + CRequestMessage requestMessage(argv[3]); - // Success? - if (!answerMessage.success()) { + // Add arguments + uint32_t uiArg; + for (uiArg = 4; uiArg < (uint32_t)argc; uiArg++) { - // Display error answer - cerr << answerMessage.getAnswer() << endl; - } else { + requestMessage.addArgument(argv[uiArg]); + } - // Display success answer - cout << answerMessage.getAnswer() << endl; + if (!sendAndDisplayCommand(connectionSocket, requestMessage)) { + return 1; + } } // Program status - return answerMessage.success() ? 0 : -5; + return 0; } -- cgit v1.1