|
@@ -1,11 +1,11 @@
|
|
|
#include "../include/useriomanager.hpp"
|
|
|
-#include "../include/commands.hpp"
|
|
|
#include "../include/base64.hpp"
|
|
|
+#include "../include/commands.hpp"
|
|
|
|
|
|
-#include <iostream>
|
|
|
+#include <boost/algorithm/string.hpp>
|
|
|
#include <fstream>
|
|
|
+#include <iostream>
|
|
|
#include <vector>
|
|
|
-#include <boost/algorithm/string.hpp>
|
|
|
|
|
|
#include <readline/history.h>
|
|
|
#include <readline/readline.h>
|
|
@@ -19,10 +19,10 @@ void UserIoManager::run() {
|
|
|
|
|
|
bool keep_reading = true;
|
|
|
COMMANDID cmd;
|
|
|
-
|
|
|
+
|
|
|
char *line = NULL;
|
|
|
std::vector<std::string> tokens;
|
|
|
-
|
|
|
+
|
|
|
while (keep_reading) {
|
|
|
free(line);
|
|
|
|
|
@@ -33,360 +33,364 @@ void UserIoManager::run() {
|
|
|
if (strlen(line) == 0) {
|
|
|
continue;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// split input line into tokens
|
|
|
- boost::algorithm::split(tokens, std::string(line), boost::algorithm::is_any_of(" "), boost::algorithm::token_compress_on);
|
|
|
-
|
|
|
- // if input contains only spaces, do not add to history, and go to reading next line
|
|
|
+ boost::algorithm::split(tokens, std::string(line),
|
|
|
+ boost::algorithm::is_any_of(" "),
|
|
|
+ boost::algorithm::token_compress_on);
|
|
|
+
|
|
|
+ // if input contains only spaces, do not add to history, and go to reading
|
|
|
+ // next line
|
|
|
if (tokens.size() < 1) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
// add the line to history
|
|
|
add_history(line);
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
// check for passed command
|
|
|
cmd = getCmdIdFromString(tokens[0].c_str());
|
|
|
|
|
|
switch (cmd) {
|
|
|
- case CMD_STATUS: {
|
|
|
-
|
|
|
- boost::asio::streambuf recvbuf;
|
|
|
- Json::Value root, checkok;
|
|
|
- const char *recvjson;
|
|
|
-
|
|
|
- // ask for status
|
|
|
- root["command"] = "status";
|
|
|
- boost::asio::write(*tcpsock, buffer(Json::writeString(wbuilder, root)),
|
|
|
- errcode);
|
|
|
- if (errcode) {
|
|
|
- std::cerr << "couldnt send status query to server " << ipstring
|
|
|
- << std::endl
|
|
|
- << errcode.message() << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // recieve answer to status query
|
|
|
- boost::asio::read(*tcpsock, recvbuf, boost::asio::transfer_at_least(1),
|
|
|
- errcode);
|
|
|
- if (errcode && errcode != boost::asio::error::eof) {
|
|
|
- std::cerr << "couldnt recieve status from " << ipstring << std::endl
|
|
|
- << errcode.message() << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // parse json
|
|
|
- recvjson = boost::asio::buffer_cast<const char *>(recvbuf.data());
|
|
|
- if (!reader->parse(recvjson, recvjson + recvbuf.size(), &root,
|
|
|
- &jsonerror)) {
|
|
|
- std::cerr << "couldnt parse recieved json" << std::endl
|
|
|
- << jsonerror << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // remove processed data from recvbuf
|
|
|
- recvbuf.consume(recvbuf.size());
|
|
|
-
|
|
|
- // check if received answer to right query
|
|
|
- checkok = root["command"];
|
|
|
-
|
|
|
- if (checkok.asString().compare("status") != 0) {
|
|
|
- std::cerr << "command check failed. client sent command \"status\""
|
|
|
- << std::endl
|
|
|
- << "server replied to command \"" << checkok << "\""
|
|
|
- << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- } else {
|
|
|
- std::cout << "server replied with status: " << root["response"]
|
|
|
- << std::endl;
|
|
|
- }
|
|
|
-
|
|
|
- break;
|
|
|
- }
|
|
|
- case CMD_PUT: {
|
|
|
-
|
|
|
- if(tokens.size() < 2) {
|
|
|
- std::cerr << "no file specified" << std::endl;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- boost::asio::streambuf recvbuf;
|
|
|
- Json::Value root, ackRecv;
|
|
|
-
|
|
|
- std::fstream fs;
|
|
|
- fs.open(tokens[1].c_str(), std::fstream::in | std::fstream::binary);
|
|
|
-
|
|
|
- if(!fs.is_open()) {
|
|
|
- std::cerr << "couldnt open file " << tokens[1] << std::endl;
|
|
|
- break;
|
|
|
- }
|
|
|
- // determine file size
|
|
|
- fs.seekg(0, fs.end);
|
|
|
- int filelen = fs.tellg();
|
|
|
- fs.seekg(0, fs.beg);
|
|
|
-
|
|
|
- // determine file name
|
|
|
- std::vector<std::string> path;
|
|
|
- boost::algorithm::split(path, tokens[1], boost::algorithm::is_any_of("/"), boost::algorithm::token_compress_on);
|
|
|
- std::string filename = path.back();
|
|
|
-
|
|
|
-
|
|
|
- // send first query to server
|
|
|
- root["command"] = "put";
|
|
|
- root["file"] = filename;
|
|
|
- root["size"] = filelen;
|
|
|
-
|
|
|
- std::cout << root << std::endl;
|
|
|
-
|
|
|
- if(!sendJson(root)){
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
- std::cout << "sent request to server " << ipstring << std::endl;
|
|
|
-
|
|
|
- if(!receiveJson(recvbuf)){
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(!parseJson(&root, recvbuf)){
|
|
|
- std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- std::cout << root << std::endl;
|
|
|
-
|
|
|
- if(!root["accept"].asBool()){
|
|
|
- std::cerr << "server did not accept request" << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- std::cout << "request successful, beginning to send file to " << ipstring << std::endl;
|
|
|
-
|
|
|
-
|
|
|
- // determine number of chunks
|
|
|
- int size_remainder = filelen % BLOCKSIZE;
|
|
|
- int chunks = filelen / BLOCKSIZE + ((size_remainder > 0)?1:0);
|
|
|
-
|
|
|
- char readbuf[BLOCKSIZE];
|
|
|
-
|
|
|
- // send file
|
|
|
- root = Json::Value();
|
|
|
- root["command"] = "put";
|
|
|
- root["cancel"] = false;
|
|
|
-
|
|
|
-
|
|
|
- while(chunks > 0){
|
|
|
- chunks--;
|
|
|
- if(!chunks & (size_remainder != 0)) { // size_remainder is the size of the last chunk if it's not 0
|
|
|
- fs.read(readbuf, size_remainder);
|
|
|
- root["data"] = base64::encodeVector(std::vector<char>(readbuf, readbuf+size_remainder*sizeof(char)));
|
|
|
- } else { // not last chunk or last chunk has full length
|
|
|
- fs.read(readbuf, BLOCKSIZE);
|
|
|
- root["data"] = base64::encodeVector(std::vector<char>(readbuf, readbuf+BLOCKSIZE*sizeof(char)));
|
|
|
- }
|
|
|
- root["remaining"] = chunks;
|
|
|
-
|
|
|
- std::cout << root << std::endl;
|
|
|
-
|
|
|
- if(!sendJson(root)){
|
|
|
- std::cerr << "couldn't send file, " << chunks+1 << " chunks not sent" << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if(!receiveJson(recvbuf)){
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(!parseJson(&ackRecv, recvbuf)){
|
|
|
- std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
- continue;
|
|
|
- }
|
|
|
- // TODO: check for cancel answer
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- fs.close();
|
|
|
- std::cout << "successfully sent file to " << ipstring << std::endl;
|
|
|
-
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- case CMD_GET: {
|
|
|
-
|
|
|
- if(tokens.size() < 2) {
|
|
|
- std::cerr << "no file specified" << std::endl;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- boost::asio::streambuf recvbuf;
|
|
|
- Json::Value root, recvAck;
|
|
|
-
|
|
|
- // send first query to server
|
|
|
- root["command"] = "get";
|
|
|
- root["file"] = tokens[1];
|
|
|
-
|
|
|
- std::cout << root << std::endl;
|
|
|
-
|
|
|
- if(!sendJson(root)){
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
- std::cout << "sent request to server " << ipstring << std::endl;
|
|
|
-
|
|
|
- if(!receiveJson(recvbuf)){
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(!parseJson(&root, recvbuf)){
|
|
|
- std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- std::cout << root << std::endl;
|
|
|
-
|
|
|
- if(!root["accept"].asBool()){
|
|
|
- std::cerr << "server did not accept request" << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- std::cout << "request successful, beginning to receive file from " << ipstring << std::endl;
|
|
|
-
|
|
|
- // open file stream
|
|
|
- std::fstream fs;
|
|
|
- fs.open(tokens[1].c_str(), std::fstream::out | std::fstream::trunc | std::fstream::binary);
|
|
|
- std::vector<char> writebuf;
|
|
|
-
|
|
|
- // number of remaining chunks, dummy value to entry loop
|
|
|
- int remaining = std::numeric_limits<int>::max();
|
|
|
- int recvCount = 0;
|
|
|
-
|
|
|
- std::cout << "foobar" << std::endl;
|
|
|
-
|
|
|
- while(remaining > 0){
|
|
|
-
|
|
|
- std::cout << "foobar0" << std::endl;
|
|
|
-
|
|
|
- if(!receiveJson(recvbuf)){
|
|
|
- keep_reading = false;
|
|
|
-
|
|
|
- std::cout << "fail1" << std::endl;
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- std::cout << "foobar1" << std::endl;
|
|
|
-
|
|
|
- if(!parseJson(&root, recvbuf)){
|
|
|
- std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
- std::cout << "foobar2" << std::endl;
|
|
|
- std::cout << root << std::endl;
|
|
|
-
|
|
|
- if(root["cancel"].asBool()){
|
|
|
- std::cerr << "server cancelled recieving file" << std::endl;
|
|
|
- keep_reading = false;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- writebuf = base64::decodeVector(root["data"].asString());
|
|
|
- fs.write(writebuf.data(), writebuf.size());
|
|
|
- remaining = root["remaining"].asInt();
|
|
|
-
|
|
|
- std::cout << "remaining == " << remaining << std::endl;
|
|
|
-
|
|
|
- recvAck["received"] = recvCount++;
|
|
|
-
|
|
|
- if(!sendJson(recvAck)){
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- fs.close();
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- case CMD_LIST: {
|
|
|
- boost::asio::streambuf recvbuf;
|
|
|
- Json::Value root, recv;
|
|
|
- // const char *recvjson;
|
|
|
-
|
|
|
- int chunks, rec = 0;
|
|
|
- root["command"] = "list";
|
|
|
- if(!sendJson(root)) {
|
|
|
- std::cerr << "couldn't send json" << std::endl;
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(!receiveJson(recvbuf)) {
|
|
|
- std::cerr << "couldn't receive json" << std::endl;
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(!parseJson(&recv, recvbuf)) {
|
|
|
- std::cerr << "couldn't parse json" << std::endl;
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if(recv["accept"].asBool()) {
|
|
|
- // ACK?
|
|
|
- root["command"] = "list";
|
|
|
- root["cancel"] = false;
|
|
|
- chunks = std::numeric_limits<int>::max();
|
|
|
- while(chunks) {
|
|
|
- if(!receiveJson(recvbuf)) {
|
|
|
- std::cerr << "couldn't receive json" << std::endl;
|
|
|
- break;
|
|
|
- }
|
|
|
- if(!parseJson(&recv, recvbuf)) {
|
|
|
- std::cerr << "couldn't parse json" << std::endl;
|
|
|
- break;
|
|
|
- }
|
|
|
- // dump received data
|
|
|
- if(recv["names"].isArray()) {
|
|
|
- for(Json::Value name : recv["names"]){
|
|
|
- std::cout << name.asString();
|
|
|
- }
|
|
|
- } else {
|
|
|
- std::cerr << "should have recieved an array of files, but did not receive an array" << std::endl;
|
|
|
- }
|
|
|
- chunks = recv["remaining"].asInt();
|
|
|
- root["received"] = rec;
|
|
|
- if(!sendJson(root)) {
|
|
|
- // couldnt ACK
|
|
|
- break;
|
|
|
- }
|
|
|
- rec++;
|
|
|
- }
|
|
|
- } else {
|
|
|
- std::cerr << "server refused listing" << std::endl;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- case CMD_DISCONNECT: {
|
|
|
- std::printf("disconnecting\n");
|
|
|
- keep_reading = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- default: {
|
|
|
- std::printf("unknown command %s\n", line);
|
|
|
- }
|
|
|
- case CMD_HELP: {
|
|
|
- std::printf("\n");
|
|
|
- std::printf("AVAILABLE COMMANDS are:\n");
|
|
|
- printCmds();
|
|
|
- break;
|
|
|
- }
|
|
|
+ case CMD_STATUS: {
|
|
|
+
|
|
|
+ boost::asio::streambuf recvbuf;
|
|
|
+ Json::Value root, checkok;
|
|
|
+ const char *recvjson;
|
|
|
+
|
|
|
+ // ask for status
|
|
|
+ root["command"] = "status";
|
|
|
+ boost::asio::write(*tcpsock, buffer(Json::writeString(wbuilder, root)),
|
|
|
+ errcode);
|
|
|
+ if (errcode) {
|
|
|
+ std::cerr << "couldnt send status query to server " << ipstring
|
|
|
+ << std::endl
|
|
|
+ << errcode.message() << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // recieve answer to status query
|
|
|
+ boost::asio::read(*tcpsock, recvbuf, boost::asio::transfer_at_least(1),
|
|
|
+ errcode);
|
|
|
+ if (errcode && errcode != boost::asio::error::eof) {
|
|
|
+ std::cerr << "couldnt recieve status from " << ipstring << std::endl
|
|
|
+ << errcode.message() << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // parse json
|
|
|
+ recvjson = boost::asio::buffer_cast<const char *>(recvbuf.data());
|
|
|
+ if (!reader->parse(recvjson, recvjson + recvbuf.size(), &root,
|
|
|
+ &jsonerror)) {
|
|
|
+ std::cerr << "couldnt parse recieved json" << std::endl
|
|
|
+ << jsonerror << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // remove processed data from recvbuf
|
|
|
+ recvbuf.consume(recvbuf.size());
|
|
|
+
|
|
|
+ // check if received answer to right query
|
|
|
+ checkok = root["command"];
|
|
|
+
|
|
|
+ if (checkok.asString().compare("status") != 0) {
|
|
|
+ std::cerr << "command check failed. client sent command \"status\""
|
|
|
+ << std::endl
|
|
|
+ << "server replied to command \"" << checkok << "\""
|
|
|
+ << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ std::cout << "server replied with status: " << root["response"]
|
|
|
+ << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CMD_PUT: {
|
|
|
+
|
|
|
+ if (tokens.size() < 2) {
|
|
|
+ std::cerr << "no file specified" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ boost::asio::streambuf recvbuf;
|
|
|
+ Json::Value root, ackRecv;
|
|
|
+
|
|
|
+ std::fstream fs;
|
|
|
+ fs.open(tokens[1].c_str(), std::fstream::in | std::fstream::binary);
|
|
|
+
|
|
|
+ if (!fs.is_open()) {
|
|
|
+ std::cerr << "couldnt open file " << tokens[1] << std::endl;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // determine file size
|
|
|
+ fs.seekg(0, fs.end);
|
|
|
+ int filelen = fs.tellg();
|
|
|
+ fs.seekg(0, fs.beg);
|
|
|
+
|
|
|
+ // determine file name
|
|
|
+ std::vector<std::string> path;
|
|
|
+ boost::algorithm::split(path, tokens[1], boost::algorithm::is_any_of("/"),
|
|
|
+ boost::algorithm::token_compress_on);
|
|
|
+ std::string filename = path.back();
|
|
|
+
|
|
|
+ // send first query to server
|
|
|
+ root["command"] = "put";
|
|
|
+ root["file"] = filename;
|
|
|
+ root["size"] = filelen;
|
|
|
+
|
|
|
+ std::cout << root << std::endl;
|
|
|
+
|
|
|
+ if (!sendJson(root)) {
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ std::cout << "sent request to server " << ipstring << std::endl;
|
|
|
+
|
|
|
+ if (!receiveJson(recvbuf)) {
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!parseJson(&root, recvbuf)) {
|
|
|
+ std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout << root << std::endl;
|
|
|
+
|
|
|
+ if (!root["accept"].asBool()) {
|
|
|
+ std::cerr << "server did not accept request" << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout << "request successful, beginning to send file to " << ipstring
|
|
|
+ << std::endl;
|
|
|
+
|
|
|
+ // determine number of chunks
|
|
|
+ int size_remainder = filelen % BLOCKSIZE;
|
|
|
+ int chunks = filelen / BLOCKSIZE + ((size_remainder > 0) ? 1 : 0);
|
|
|
+
|
|
|
+ char readbuf[BLOCKSIZE];
|
|
|
+
|
|
|
+ // send file
|
|
|
+ root = Json::Value();
|
|
|
+ root["command"] = "put";
|
|
|
+ root["cancel"] = false;
|
|
|
+
|
|
|
+ while (chunks > 0) {
|
|
|
+ chunks--;
|
|
|
+ if (!chunks &
|
|
|
+ (size_remainder !=
|
|
|
+ 0)) { // size_remainder is the size of the last chunk if it's not 0
|
|
|
+ fs.read(readbuf, size_remainder);
|
|
|
+ root["data"] = base64::encodeVector(std::vector<char>(
|
|
|
+ readbuf, readbuf + size_remainder * sizeof(char)));
|
|
|
+ } else { // not last chunk or last chunk has full length
|
|
|
+ fs.read(readbuf, BLOCKSIZE);
|
|
|
+ root["data"] = base64::encodeVector(
|
|
|
+ std::vector<char>(readbuf, readbuf + BLOCKSIZE * sizeof(char)));
|
|
|
+ }
|
|
|
+ root["remaining"] = chunks;
|
|
|
+
|
|
|
+ std::cout << root << std::endl;
|
|
|
+
|
|
|
+ if (!sendJson(root)) {
|
|
|
+ std::cerr << "couldn't send file, " << chunks + 1
|
|
|
+ << " chunks not sent" << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!receiveJson(recvbuf)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!parseJson(&ackRecv, recvbuf)) {
|
|
|
+ std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // TODO: check for cancel answer
|
|
|
+ }
|
|
|
+
|
|
|
+ fs.close();
|
|
|
+ std::cout << "successfully sent file to " << ipstring << std::endl;
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CMD_GET: {
|
|
|
+
|
|
|
+ if (tokens.size() < 2) {
|
|
|
+ std::cerr << "no file specified" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ boost::asio::streambuf recvbuf;
|
|
|
+ Json::Value root, recvAck;
|
|
|
+
|
|
|
+ // send first query to server
|
|
|
+ root["command"] = "get";
|
|
|
+ root["file"] = tokens[1];
|
|
|
+
|
|
|
+ std::cout << root << std::endl;
|
|
|
+
|
|
|
+ if (!sendJson(root)) {
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ std::cout << "sent request to server " << ipstring << std::endl;
|
|
|
+
|
|
|
+ if (!receiveJson(recvbuf)) {
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!parseJson(&root, recvbuf)) {
|
|
|
+ std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout << root << std::endl;
|
|
|
+
|
|
|
+ if (!root["accept"].asBool()) {
|
|
|
+ std::cerr << "server did not accept request" << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout << "request successful, beginning to receive file from "
|
|
|
+ << ipstring << std::endl;
|
|
|
+
|
|
|
+ // open file stream
|
|
|
+ std::fstream fs;
|
|
|
+ fs.open(tokens[1].c_str(),
|
|
|
+ std::fstream::out | std::fstream::trunc | std::fstream::binary);
|
|
|
+ std::vector<char> writebuf;
|
|
|
+
|
|
|
+ // number of remaining chunks, dummy value to entry loop
|
|
|
+ int remaining = std::numeric_limits<int>::max();
|
|
|
+ int recvCount = 0;
|
|
|
+
|
|
|
+ std::cout << "foobar" << std::endl;
|
|
|
+
|
|
|
+ while (remaining > 0) {
|
|
|
+
|
|
|
+ std::cout << "foobar0" << std::endl;
|
|
|
+
|
|
|
+ if (!receiveJson(recvbuf)) {
|
|
|
+ keep_reading = false;
|
|
|
+
|
|
|
+ std::cout << "fail1" << std::endl;
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::cout << "foobar1" << std::endl;
|
|
|
+
|
|
|
+ if (!parseJson(&root, recvbuf)) {
|
|
|
+ std::cerr << "received invalid JSON from server" << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ std::cout << "foobar2" << std::endl;
|
|
|
+ std::cout << root << std::endl;
|
|
|
+
|
|
|
+ if (root["cancel"].asBool()) {
|
|
|
+ std::cerr << "server cancelled recieving file" << std::endl;
|
|
|
+ keep_reading = false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ writebuf = base64::decodeVector(root["data"].asString());
|
|
|
+ fs.write(writebuf.data(), writebuf.size());
|
|
|
+ remaining = root["remaining"].asInt();
|
|
|
+
|
|
|
+ std::cout << "remaining == " << remaining << std::endl;
|
|
|
+
|
|
|
+ recvAck["received"] = recvCount++;
|
|
|
+
|
|
|
+ if (!sendJson(recvAck)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fs.close();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CMD_LIST: {
|
|
|
+ boost::asio::streambuf recvbuf;
|
|
|
+ Json::Value root, recv;
|
|
|
+ // const char *recvjson;
|
|
|
+
|
|
|
+ int chunks, rec = 0;
|
|
|
+ root["command"] = "list";
|
|
|
+ if (!sendJson(root)) {
|
|
|
+ std::cerr << "couldn't send json" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!receiveJson(recvbuf)) {
|
|
|
+ std::cerr << "couldn't receive json" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!parseJson(&recv, recvbuf)) {
|
|
|
+ std::cerr << "couldn't parse json" << std::endl;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (recv["accept"].asBool()) {
|
|
|
+ // ACK?
|
|
|
+ root["command"] = "list";
|
|
|
+ root["cancel"] = false;
|
|
|
+ chunks = std::numeric_limits<int>::max();
|
|
|
+ while (chunks) {
|
|
|
+ if (!receiveJson(recvbuf)) {
|
|
|
+ std::cerr << "couldn't receive json" << std::endl;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (!parseJson(&recv, recvbuf)) {
|
|
|
+ std::cerr << "couldn't parse json" << std::endl;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // dump received data
|
|
|
+ if (recv["names"].isArray()) {
|
|
|
+ for (Json::Value name : recv["names"]) {
|
|
|
+ std::cout << name.asString();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ std::cerr << "should have recieved an array of files, but did not "
|
|
|
+ "receive an array"
|
|
|
+ << std::endl;
|
|
|
+ }
|
|
|
+ chunks = recv["remaining"].asInt();
|
|
|
+ root["received"] = rec;
|
|
|
+ if (!sendJson(root)) {
|
|
|
+ // couldnt ACK
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ rec++;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ std::cerr << "server refused listing" << std::endl;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case CMD_DISCONNECT: {
|
|
|
+ std::printf("disconnecting\n");
|
|
|
+ keep_reading = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ std::printf("unknown command %s\n", line);
|
|
|
+ }
|
|
|
+ case CMD_HELP: {
|
|
|
+ std::printf("\n");
|
|
|
+ std::printf("AVAILABLE COMMANDS are:\n");
|
|
|
+ printCmds();
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
std::printf("\n");
|
|
|
}
|