зеркало из https://github.com/mozilla/Negatus.git
Added push command. Added forgotten PullFileEventHandler files.
This commit is contained in:
Родитель
26a08159a3
Коммит
2d7da6b467
5
Makefile
5
Makefile
|
@ -6,12 +6,15 @@ SRCS=\
|
|||
src/Buffer.cpp \
|
||||
src/BufferedSocket.cpp \
|
||||
src/CommandEventHandler.cpp \
|
||||
src/Hash.cpp \
|
||||
src/Logging.cpp \
|
||||
src/PullFileEventHandler.cpp \
|
||||
src/PushFileEventHandler.cpp \
|
||||
src/Reactor.cpp \
|
||||
src/SocketAcceptor.cpp \
|
||||
src/Strings.cpp \
|
||||
src/SUTAgent.cpp
|
||||
src/SUTAgent.cpp \
|
||||
src/Subprocess.cpp
|
||||
|
||||
OBJS=$(subst .cpp,.o,$(SRCS))
|
||||
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "CommandEventHandler.h"
|
||||
#include "Hash.h"
|
||||
#include "Logging.h"
|
||||
#include "PullFileEventHandler.h"
|
||||
#include "PushFileEventHandler.h"
|
||||
#include "Strings.h"
|
||||
#include "Subprocess.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdint.h>
|
||||
|
@ -162,6 +165,8 @@ CommandEventHandler::handleLine(std::string line)
|
|||
result = ps(cl.args);
|
||||
else if (cl.cmd.compare("pull") == 0)
|
||||
result = pull(cl.args);
|
||||
else if (cl.cmd.compare("push") == 0)
|
||||
result = push(cl.args);
|
||||
else if (cl.cmd.compare("isDir") == 0)
|
||||
result = isDir(cl.args);
|
||||
else if (cl.cmd.compare("ls") == 0)
|
||||
|
@ -188,35 +193,6 @@ CommandEventHandler::sendPrompt()
|
|||
}
|
||||
|
||||
|
||||
FILE*
|
||||
CommandEventHandler::checkPopen(std::string cmd, std::string mode)
|
||||
{
|
||||
FILE *fp = popen(cmd.c_str(), mode.c_str());
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "Error on popen: %s, with mode %s.\n", cmd.c_str(),
|
||||
mode.c_str());
|
||||
exit(1);
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CommandEventHandler::getCmdOutput(std::string cmd)
|
||||
{
|
||||
FILE *fp = checkPopen(cmd, "r");
|
||||
char buffer[BUFSIZE];
|
||||
std::string output;
|
||||
|
||||
while (fgets(buffer, BUFSIZE, fp))
|
||||
output += std::string(buffer);
|
||||
|
||||
pclose(fp);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CommandEventHandler::readTextFile(std::string path)
|
||||
{
|
||||
|
@ -433,14 +409,12 @@ CommandEventHandler::hash(std::vector<std::string>& args)
|
|||
{
|
||||
if (args.size() < 1)
|
||||
return agentWarnInvalidNumArgs(1);
|
||||
const char *cpath = args[0].c_str();
|
||||
char buffer[BUFSIZE];
|
||||
std::string path = args[0];
|
||||
|
||||
if (PR_Access(cpath, PR_ACCESS_READ_OK) != PR_SUCCESS)
|
||||
return std::string("");
|
||||
if (PR_Access(path.c_str(), PR_ACCESS_READ_OK) != PR_SUCCESS)
|
||||
return std::string(agentWarn("cannot open file for reading"));
|
||||
|
||||
sprintf(buffer, "md5sum %s", cpath);
|
||||
return getCmdOutput(std::string(buffer));
|
||||
return fileHash(path) + std::string(ENDL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -573,6 +547,18 @@ CommandEventHandler::pull(std::vector<std::string>& args)
|
|||
}
|
||||
|
||||
|
||||
std::string
|
||||
CommandEventHandler::push(std::vector<std::string>& args)
|
||||
{
|
||||
if (args.size() < 2)
|
||||
return agentWarnInvalidNumArgs(2);
|
||||
std::string path(args[0]);
|
||||
PRUint64 size = PR_strtod(args[1].c_str(), NULL);
|
||||
mDataEventHandler = new PushFileEventHandler(mBufSocket, path, size);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
CommandEventHandler::isDir(std::vector<std::string>& args)
|
||||
{
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include "BufferedSocket.h"
|
||||
#include "EventHandler.h"
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
class CommandEventHandler: public EventHandler
|
||||
{
|
||||
public:
|
||||
|
@ -39,8 +37,6 @@ private:
|
|||
void sendPrompt();
|
||||
void do_rmdr(std::string path, std::ostringstream &out);
|
||||
|
||||
FILE *checkPopen(std::string cmd, std::string mode);
|
||||
std::string getCmdOutput(std::string cmd);
|
||||
std::string readTextFile(std::string path);
|
||||
int getFirstIntPos(char *str, int limit);
|
||||
std::string joinPaths(std::string p1, std::string p2);
|
||||
|
@ -64,6 +60,7 @@ private:
|
|||
std::string power(std::vector<std::string>& args);
|
||||
std::string ps(std::vector<std::string>& args);
|
||||
std::string pull(std::vector<std::string>& args);
|
||||
std::string push(std::vector<std::string>& args);
|
||||
std::string quit(std::vector<std::string>& args);
|
||||
std::string screen(std::vector<std::string>& args);
|
||||
std::string systime(std::vector<std::string>& args);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "Hash.h"
|
||||
#include "Subprocess.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
std::string
|
||||
fileHash(std::string path)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "md5sum " << path;
|
||||
std::string hash = getCmdOutput(ss.str());
|
||||
// strip everything past actual hash string
|
||||
return hash.substr(0, hash.find(" "));
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef negatus_hash_h
|
||||
#define negatus_hash_h
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string fileHash(std::string path);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,130 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "PullFileEventHandler.h"
|
||||
#include <sstream>
|
||||
#include <prerror.h>
|
||||
#include "BufferedSocket.h"
|
||||
#include "Logging.h"
|
||||
#include "Strings.h"
|
||||
|
||||
PullFileEventHandler::PullFileEventHandler(BufferedSocket& bufSocket,
|
||||
std::string path,
|
||||
PRUint64 start,
|
||||
PRUint64 size)
|
||||
: mBufSocket(bufSocket), mPath(path), mFile(NULL), mBytesRead(0), mSize(size),
|
||||
mTmpBuf(new char[BLOCK_SIZE])
|
||||
{
|
||||
if (PR_Access(path.c_str(), PR_ACCESS_EXISTS) != PR_SUCCESS)
|
||||
{
|
||||
mBufSocket.write(agentWarn("file does not exist"));
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (PR_Access(path.c_str(), PR_ACCESS_READ_OK) != PR_SUCCESS)
|
||||
{
|
||||
mBufSocket.write(agentWarn("insufficient permissions to read file"));
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
mFile = PR_Open(path.c_str(), PR_RDONLY, 0);
|
||||
if (!mFile)
|
||||
{
|
||||
mBufSocket.write(agentWarn("could not open file"));
|
||||
close();
|
||||
return;
|
||||
}
|
||||
PRFileInfo fileInfo;
|
||||
if (PR_GetOpenFileInfo(mFile, &fileInfo) != PR_SUCCESS)
|
||||
{
|
||||
mBufSocket.write(agentWarn("failed to read file info"));
|
||||
close();
|
||||
return;
|
||||
}
|
||||
if (fileInfo.size <= start)
|
||||
{
|
||||
mBufSocket.write(agentWarn("start position is at or past end of file"));
|
||||
close();
|
||||
return;
|
||||
}
|
||||
if (start > 0)
|
||||
{
|
||||
PRInt64 seekBytes = PR_Seek64(mFile, start, PR_SEEK_SET);
|
||||
if (seekBytes == -1)
|
||||
{
|
||||
mBufSocket.write(agentWarn("failed to seek"));
|
||||
close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mSize == 0)
|
||||
mSize = fileInfo.size - start;
|
||||
|
||||
std::stringstream out;
|
||||
out << path << "," << mSize << ENDL;
|
||||
mBufSocket.write(out.str());
|
||||
}
|
||||
|
||||
|
||||
PullFileEventHandler::~PullFileEventHandler()
|
||||
{
|
||||
delete[] mTmpBuf;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PullFileEventHandler::close()
|
||||
{
|
||||
EventHandler::close();
|
||||
if (mFile)
|
||||
{
|
||||
PR_Close(mFile);
|
||||
mFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PullFileEventHandler::getPollDescs(std::vector<PRPollDesc>& descs)
|
||||
{
|
||||
if (!mBufSocket.closed())
|
||||
{
|
||||
PRPollDesc desc;
|
||||
desc.fd = mBufSocket.fd();
|
||||
desc.in_flags = PR_POLL_WRITE;
|
||||
descs.push_back(desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PullFileEventHandler::handleEvent(PRPollDesc desc)
|
||||
{
|
||||
if (desc.fd != mBufSocket.fd())
|
||||
return;
|
||||
if (!(desc.out_flags & PR_POLL_WRITE))
|
||||
return;
|
||||
|
||||
PRUint32 blockSize = (mSize - mBytesRead) < BLOCK_SIZE ? mSize - mBytesRead
|
||||
: BLOCK_SIZE;
|
||||
|
||||
PRInt32 bytes = PR_Read(mFile, mTmpBuf, blockSize);
|
||||
if (bytes > 0)
|
||||
{
|
||||
mBytesRead += bytes;
|
||||
mBufSocket.write(mTmpBuf, bytes);
|
||||
}
|
||||
else if (bytes == 0)
|
||||
close();
|
||||
else if (bytes < 0)
|
||||
{
|
||||
// FIXME: log error
|
||||
close();
|
||||
}
|
||||
if (mSize == mBytesRead)
|
||||
close();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef negatus_pull_file_event_handler_h
|
||||
#define negatus_pull_file_event_handler_h
|
||||
|
||||
#include <string>
|
||||
#include <prio.h>
|
||||
#include "EventHandler.h"
|
||||
|
||||
#define BLOCK_SIZE 1024
|
||||
|
||||
class BufferedSocket;
|
||||
|
||||
class PullFileEventHandler: public EventHandler
|
||||
{
|
||||
public:
|
||||
PullFileEventHandler(BufferedSocket& bufSocket, std::string path,
|
||||
PRUint64 start, PRUint64 size);
|
||||
virtual ~PullFileEventHandler();
|
||||
|
||||
virtual void close();
|
||||
virtual void getPollDescs(std::vector<PRPollDesc>& descs);
|
||||
virtual void handleEvent(PRPollDesc desc);
|
||||
virtual std::string name() { return "PullFileEventHandler"; }
|
||||
|
||||
private:
|
||||
BufferedSocket& mBufSocket;
|
||||
std::string mPath;
|
||||
PRFileDesc* mFile;
|
||||
PRUint64 mBytesRead;
|
||||
PRUint64 mSize;
|
||||
char* mTmpBuf;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,81 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "PushFileEventHandler.h"
|
||||
#include "BufferedSocket.h"
|
||||
#include "Hash.h"
|
||||
#include "Logging.h"
|
||||
#include "Strings.h"
|
||||
|
||||
PushFileEventHandler::PushFileEventHandler(BufferedSocket& bufSocket,
|
||||
std::string path, PRUint64 size)
|
||||
: mBufSocket(bufSocket), mPath(path), mSize(size), mBytesWritten(0),
|
||||
mTmpBuf(new char[BLOCK_SIZE])
|
||||
{
|
||||
mFile = PR_Open(path.c_str(), PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
|
||||
PR_IRWXU | PR_IRWXG);
|
||||
if (!mFile)
|
||||
{
|
||||
mBufSocket.write(agentWarn("could not open file for writing"));
|
||||
close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PushFileEventHandler::~PushFileEventHandler()
|
||||
{
|
||||
delete[] mTmpBuf;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PushFileEventHandler::close()
|
||||
{
|
||||
EventHandler::close();
|
||||
if (mFile)
|
||||
{
|
||||
PR_Close(mFile);
|
||||
mFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PushFileEventHandler::getPollDescs(std::vector<PRPollDesc>& descs)
|
||||
{
|
||||
if (!mBufSocket.closed())
|
||||
{
|
||||
PRPollDesc desc;
|
||||
desc.fd = mBufSocket.fd();
|
||||
desc.in_flags = PR_POLL_READ;
|
||||
descs.push_back(desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PushFileEventHandler::handleEvent(PRPollDesc desc)
|
||||
{
|
||||
if (desc.fd != mBufSocket.fd())
|
||||
return;
|
||||
if (!(desc.out_flags & PR_POLL_READ))
|
||||
return;
|
||||
|
||||
PRUint32 blockSize = (mSize - mBytesWritten) < BLOCK_SIZE
|
||||
? mSize - mBytesWritten : BLOCK_SIZE;
|
||||
|
||||
PRUint32 bytes = mBufSocket.read(mTmpBuf, blockSize);
|
||||
if (bytes > 0)
|
||||
{
|
||||
PR_Write(mFile, mTmpBuf, bytes);
|
||||
mBytesWritten += bytes;
|
||||
}
|
||||
// a closed socket will be detected automatically by CommandEventHandler.
|
||||
if (mSize == mBytesWritten)
|
||||
{
|
||||
close();
|
||||
mBufSocket.write(std::string(ENDL) + fileHash(mPath) + std::string(ENDL));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef negatus_push_file_event_handler_h
|
||||
#define negatus_push_file_event_handler_h
|
||||
|
||||
#include <string>
|
||||
#include <prio.h>
|
||||
#include "EventHandler.h"
|
||||
|
||||
#define BLOCK_SIZE 1024
|
||||
|
||||
class BufferedSocket;
|
||||
|
||||
class PushFileEventHandler: public EventHandler
|
||||
{
|
||||
public:
|
||||
PushFileEventHandler(BufferedSocket& bufSocket, std::string path,
|
||||
PRUint64 size);
|
||||
virtual ~PushFileEventHandler();
|
||||
|
||||
virtual void close();
|
||||
virtual void getPollDescs(std::vector<PRPollDesc>& descs);
|
||||
virtual void handleEvent(PRPollDesc desc);
|
||||
virtual std::string name() { return "PushFileEventHandler"; }
|
||||
|
||||
private:
|
||||
BufferedSocket& mBufSocket;
|
||||
std::string mPath;
|
||||
PRFileDesc* mFile;
|
||||
PRUint64 mBytesWritten;
|
||||
PRUint64 mSize;
|
||||
char* mTmpBuf;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "Subprocess.h"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
FILE*
|
||||
checkPopen(std::string cmd, std::string mode)
|
||||
{
|
||||
FILE *fp = popen(cmd.c_str(), mode.c_str());
|
||||
if (!fp)
|
||||
{
|
||||
std::cerr << "Error on popen: " << cmd << " , with mode " << mode
|
||||
<< std::endl;
|
||||
return NULL;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
getCmdOutput(std::string cmd)
|
||||
{
|
||||
FILE *fp = checkPopen(cmd, "r");
|
||||
if (!fp)
|
||||
return "";
|
||||
char buffer[BUFSIZE];
|
||||
std::string output;
|
||||
|
||||
while (fgets(buffer, BUFSIZE, fp))
|
||||
output += std::string(buffer);
|
||||
|
||||
pclose(fp);
|
||||
return output;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef negatus_subprocess_h
|
||||
#define negatus_subprocess_h
|
||||
|
||||
#include <string>
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
FILE* checkPopen(std::string cmd, std::string mode);
|
||||
std::string getCmdOutput(std::string cmd);
|
||||
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче