Explorar el Código

replace undefined behaviour with proper code

Missingmew hace 4 años
padre
commit
56295a8a80

+ 62 - 64
cli/include/cmdman.h

@@ -5,79 +5,77 @@
 
 #include <json/json.h>
 
+#include <map>
 #include <string>
 #include <vector>
-#include <map>
 
+using std::map;
 using std::string;
 using std::vector;
-using std::map;
 
 class CmdMan {
 public:
-	enum rettype { notsend, send, error, startlist, stoplist, close, seton };
-	struct CmdRet {
-		rettype type;
-		string msg;
-	};
-	
-	CmdMan(FileMan &fm);
-	~CmdMan();
-
-	// execute cmd with optional argument args, returns answer string
-	// if cmd unknown, returns error string
-	CmdRet execute(string cmd, vector<string> args);
-	CmdRet handle(Json::Value root);
-	
-	Json::CharReader* reader;
-	
+  enum rettype { notsend, send, error, startlist, stoplist, close, seton };
+  struct CmdRet {
+    rettype type;
+    string msg;
+  };
+
+  CmdMan(FileMan &fm);
+  ~CmdMan();
+
+  // execute cmd with optional argument args, returns answer string
+  // if cmd unknown, returns error string
+  CmdRet execute(string cmd, vector<string> args);
+  CmdRet handle(Json::Value root);
+
+  Json::CharReader *reader;
+
 private:
-	
-	Json::StreamWriterBuilder wbuilder;
-
-	string jsonerror;
-
-	FileMan &fileman;
-
-	map<string,CmdRet(CmdMan::*)(vector<string>)> execmap;
-	map<string,string> helpmap;
-	map<string,CmdRet(CmdMan::*)(Json::Value)> handlemap;
-
-	bool dologin, doversion;
-	
-
-	/* execute command descriptions and methods go here */
-	const string descHelp = "print available commands";
-	CmdRet cmdHelp(vector<string> args);
-	const string descStatus = "request status from server";
-	CmdRet cmdStatus(vector<string> args);
-	const string descDisconnect = "disconnect from server";
-	CmdRet cmdDisconnect(vector<string> args);
-	const string descPut = "upload file to server and add to queue";
-	CmdRet cmdPut(vector<string> args);
-	const string descGet = "retrieve file from server";
-	CmdRet cmdGet(vector<string> args);
-	const string descList = "list files available on server";
-	CmdRet cmdList(vector<string> args);
-	
-	/* internal execute commands */
-	CmdRet cmdVersion(vector<string> args);
-	CmdRet cmdLogin(vector<string> args);
-	CmdRet cmdPutdata(vector<string> args);
-	CmdRet cmdGetdata(vector<string> args);
-	CmdRet cmdListdata(vector<string> args);
-	
-	/* handle commands go here */
-	CmdRet handleStatus(Json::Value);
-	CmdRet handleClose(Json::Value);
-	CmdRet handlePut(Json::Value);
-	CmdRet handleGet(Json::Value);
-	CmdRet handleList(Json::Value);
-	CmdRet handlePutdata(Json::Value);
-	CmdRet handleGetdata(Json::Value);
-	CmdRet handleListdata(Json::Value);
-	CmdRet handleVersion(Json::Value);
-	CmdRet handleLogin(Json::Value);
+  Json::StreamWriterBuilder wbuilder;
+
+  string jsonerror;
+
+  FileMan &fileman;
+
+  map<string, CmdRet (CmdMan::*)(vector<string>)> execmap;
+  map<string, string> helpmap;
+  map<string, CmdRet (CmdMan::*)(Json::Value)> handlemap;
+
+  bool dologin, doversion;
+
+  /* execute command descriptions and methods go here */
+  const string descHelp = "print available commands";
+  CmdRet cmdHelp(vector<string> args);
+  const string descStatus = "request status from server";
+  CmdRet cmdStatus(vector<string> args);
+  const string descDisconnect = "disconnect from server";
+  CmdRet cmdDisconnect(vector<string> args);
+  const string descPut = "upload file to server and add to queue";
+  CmdRet cmdPut(vector<string> args);
+  const string descGet = "retrieve file from server";
+  CmdRet cmdGet(vector<string> args);
+  const string descList = "list files available on server";
+  CmdRet cmdList(vector<string> args);
+
+  /* internal execute commands */
+  CmdRet cmdVersion(vector<string> args);
+  CmdRet cmdLogin(vector<string> args);
+  CmdRet cmdPutdata(vector<string> args);
+  CmdRet cmdGetdata(vector<string> args);
+  CmdRet cmdListdata(vector<string> args);
+
+  /* handle commands go here */
+  CmdRet handleStatus(Json::Value);
+  CmdRet handleClose(Json::Value);
+  CmdRet handlePut(Json::Value);
+  CmdRet handleGet(Json::Value);
+  CmdRet handleList(Json::Value);
+  CmdRet handlePutdata(Json::Value);
+  CmdRet handleGetdata(Json::Value);
+  CmdRet handleListdata(Json::Value);
+  CmdRet handleVersion(Json::Value);
+  CmdRet handleLogin(Json::Value);
 };
 
 #endif

+ 56 - 55
cli/include/fileman.h

@@ -9,62 +9,63 @@
 
 class FileMan {
 private:
-	std::ifstream putfile;
-	std::ofstream getfile;
-	std::vector<std::string> listdata;
-	std::string getname, putname;
-	const unsigned int max_read_len = 8;
-	int putsize;
-	int putchunks;
-	int putchunksRemaining;
-	int getchunks;
-	int getchunksRemaining;
-	int listchunks;
-	int listchunksRemaining;
-
-	bool islisting;
+  std::ifstream putfile;
+  std::ofstream getfile;
+  std::vector<std::string> listdata;
+  std::string getname, putname;
+  const unsigned int max_read_len = 8;
+  int putsize;
+  int putchunks;
+  int putchunksRemaining;
+  int getchunks;
+  int getchunksRemaining;
+  int listchunks;
+  int listchunksRemaining;
+
+  bool islisting;
+
 public:
-	FileMan();
-	~FileMan();
-	
-	bool isGetting();
-	bool isPutting();
-	bool isListing();
-
-	bool openPut(const std::string &name);
-	bool openGet(const std::string &name);
-	bool openList();
-
-	void closePut();
-	void closeGet();
-	void closeList();
-
-	std::string getPutName();
-	std::string getGetName();
-
-	void cancelPut();
-	void cancelGet();
-	void cancelList();
-
-	std::vector<char> readPut();
-	void writeGet(std::vector<char> data);
-	
-	std::string readBase64();
-	void writeBase64(std::string data);
-	void putListData(std::vector<std::string> names);
-	std::vector<std::string> getListData();
-	
-	int getPutChunks();
-	int getGetChunks();
-	int getListChunks();
-	
-	int getPutRemainingChunks();
-	int getGetRemainingChunks();
-	int getListRemainingChunks();
-	
-	int getPutSize();
-	void setGetChunks(int chunks);
-	void setListChunks(int chunks);
+  FileMan();
+  ~FileMan();
+
+  bool isGetting();
+  bool isPutting();
+  bool isListing();
+
+  bool openPut(const std::string &name);
+  bool openGet(const std::string &name);
+  bool openList();
+
+  void closePut();
+  void closeGet();
+  void closeList();
+
+  std::string getPutName();
+  std::string getGetName();
+
+  void cancelPut();
+  void cancelGet();
+  void cancelList();
+
+  std::vector<char> readPut();
+  void writeGet(std::vector<char> data);
+
+  std::string readBase64();
+  void writeBase64(std::string data);
+  void putListData(std::vector<std::string> names);
+  std::vector<std::string> getListData();
+
+  int getPutChunks();
+  int getGetChunks();
+  int getListChunks();
+
+  int getPutRemainingChunks();
+  int getGetRemainingChunks();
+  int getListRemainingChunks();
+
+  int getPutSize();
+  void setGetChunks(int chunks);
+  void setListChunks(int chunks);
 };
 
 #endif

+ 61 - 59
cli/include/ioman.h

@@ -5,80 +5,82 @@
 #include "fileman.h"
 
 #include <boost/asio.hpp>
+#include <condition_variable>
+#include <mutex>
 #include <string>
 #include <thread>
-#include <mutex>
 #include <vector>
 
 using boost::asio::ip::tcp;
 
-#define BLOCKSIZE 8
-
 class IoMan {
 private:
-	boost::asio::io_service ios;
-	boost::asio::streambuf sendbuf;
-	boost::asio::streambuf recvbuf;
-	boost::system::error_code errcode;
-	tcp::socket *tcpsock;
-	std::string ipstring;
-	int port;
-	bool connected;
-	CmdMan cmdman;
-	FileMan fileman;
+  boost::asio::io_service ios;
+  boost::asio::streambuf sendbuf;
+  boost::asio::streambuf recvbuf;
+  boost::system::error_code errcode;
+  tcp::socket *tcpsock;
+  std::string ipstring;
+  int port;
+  bool connected;
+  CmdMan cmdman;
+  FileMan fileman;
+
+  /*
+  3 threads: handleinput, handlenetwork, handleresponse
+  */
+  std::thread tinput, tnetwork, tresponse;
+  std::mutex mainmutex, inputmutex, networkmutex, responsemutex;
+  bool runmain, runinput, runnetwork, runresponse;
+
+  std::vector<Json::Value> netinput;
+  std::vector<std::string> localinput;
+  std::mutex netmutex, localmutex;
+  std::condition_variable netcv, localcv;
+
+  /*
+  to be put elsewhere
+  */
+  Json::CharReader *reader;
+  Json::StreamWriterBuilder wbuilder;
+  string jsonerror;
+
+  void networkMain();
+  void inputMain();
+  void responseMain();
+
+  enum Status { off, on, err };
 
-	/*
-	3 threads: handleinput, handlenetwork, handleresponse
-	*/
-	std::thread tinput, tnetwork, tresponse;
-	bool runmain, runinput, runnetwork, runresponse;
+  Status versionstatus;
+  Status loginstatus;
+  std::mutex initmutex;
+  std::condition_variable initcv;
 
-	std::vector<Json::Value> netinput;
-	std::vector<std::string> localinput;
-	std::mutex netmutex, localmutex;
-	
-	/*
-	to be put elsewhere
-	*/
-	Json::CharReader* reader;
-	Json::StreamWriterBuilder wbuilder;
-	string jsonerror;
-	
-	void networkMain();
-	void inputMain();
-	void responseMain();
-	
-	enum Status { off, on, err };
-	
-	Status versionstatus;
-	Status loginstatus;
-	
-	bool startlist;
+  bool startlist;
 
 protected:
-	enum OutMsgType { normal, error, debug };
-	std::mutex msgmutex;
-	virtual void printMessage(std::string msg, OutMsgType type);
-	virtual void printWelcomeMessage() = 0;
-	virtual std::string getCmdPrompt() = 0;
-	virtual std::string getUserPrompt() = 0;
-	virtual std::string getPassPrompt() = 0;
+  enum OutMsgType { normal, error, debug };
+  std::mutex msgmutex;
+  virtual void printMessage(std::string msg, OutMsgType type);
+  virtual void printWelcomeMessage() = 0;
+  virtual std::string getCmdPrompt() = 0;
+  virtual std::string getUserPrompt() = 0;
+  virtual std::string getPassPrompt() = 0;
 
 public:
-	// Basic constructor
-	IoMan(char *ipcstring);
-	// destructor to clean up all generic stuff
-	~IoMan();
-	// enters loop to handle further interaction based on derived class
-	void run();
-	// setup stuff
-	bool init();
+  // Basic constructor
+  IoMan(char *ipcstring);
+  // destructor to clean up all generic stuff
+  ~IoMan();
+  // enters loop to handle further interaction based on derived class
+  void run();
+  // setup stuff
+  bool init();
 
-	// tries to establish connection, returns error string if applicable
-	bool connect();
-	// disconnect from server
-	void disconnect();
-	
+  // tries to establish connection, returns error string if applicable
+  bool connect();
+  // disconnect from server
+  void disconnect();
 };
 
 #endif

+ 8 - 8
cli/include/machineioman.h

@@ -5,16 +5,16 @@
 
 class MachineIoMan : public IoMan {
 public:
-	using IoMan::IoMan;
+  using IoMan::IoMan;
 
-	bool parseJson(Json::Value *root, string jsonstring);
-	bool handleJson(Json::Value root);
-	void printMessage(std::string msg, OutMsgType type);
-	void printWelcomeMessage();
+  bool parseJson(Json::Value *root, string jsonstring);
+  bool handleJson(Json::Value root);
+  void printMessage(std::string msg, OutMsgType type);
+  void printWelcomeMessage();
 
-	std::string getCmdPrompt();
-	std::string getUserPrompt();
-	std::string getPassPrompt();
+  std::string getCmdPrompt();
+  std::string getUserPrompt();
+  std::string getPassPrompt();
 };
 
 #endif

+ 8 - 8
cli/include/userioman.h

@@ -5,16 +5,16 @@
 
 class UserIoMan : public IoMan {
 public:
-	using IoMan::IoMan;
+  using IoMan::IoMan;
 
-	bool parseJson(Json::Value *root, string jsonstring);
-	bool handleJson(Json::Value root);
-	void printMessage(std::string msg, OutMsgType type);
-	void printWelcomeMessage();
+  bool parseJson(Json::Value *root, string jsonstring);
+  bool handleJson(Json::Value root);
+  void printMessage(std::string msg, OutMsgType type);
+  void printWelcomeMessage();
 
-	std::string getCmdPrompt();
-	std::string getUserPrompt();
-	std::string getPassPrompt();
+  std::string getCmdPrompt();
+  std::string getUserPrompt();
+  std::string getPassPrompt();
 };
 
 #endif

+ 405 - 369
cli/src/cmdman.cpp

@@ -1,452 +1,488 @@
-#include "../include/global.h"
 #include "../include/cmdman.h"
+#include "../include/global.h"
 
 #include <iostream>
 
 CmdMan::CmdMan(FileMan &fm) : fileman(fm) {
-	
-	/* setup json stuff */
+
+  /* setup json stuff */
   Json::CharReaderBuilder rbuilder;
   wbuilder.settings_["indentation"] = "";
   reader = rbuilder.newCharReader();
-	
-	dologin = false;
-	doversion = false;
-	
-	/* initialize execute command map */
-	execmap["help"] = &CmdMan::cmdHelp;
-	execmap["status"] = &CmdMan::cmdStatus;
-	execmap["disconnect"] = &CmdMan::cmdDisconnect;
-	execmap["put"] = &CmdMan::cmdPut;
-	execmap["get"] = &CmdMan::cmdGet;
-	execmap["list"] = &CmdMan::cmdList;
-	execmap["version"] = &CmdMan::cmdVersion;
-	execmap["login"] = &CmdMan::cmdLogin;
-	execmap["putdata"] = &CmdMan::cmdPutdata;
-	execmap["getdata"] = &CmdMan::cmdGetdata;
-	
-	/* initialize description map */
-	helpmap["help"] = descHelp;
-	helpmap["status"] = descStatus;
-	helpmap["disconnect"] = descDisconnect;
-	helpmap["put"] = descPut;
-	helpmap["get"] = descGet;
-	helpmap["list"] = descList;
-	
-	/* initialize handle command map */
-	handlemap["status"] = &CmdMan::handleStatus;
-	handlemap["close"] = &CmdMan::handleClose;
-	handlemap["put"] = &CmdMan::handlePut;
-	handlemap["get"] = &CmdMan::handleGet;
-	handlemap["putdata"] = &CmdMan::handlePutdata;
-	handlemap["getdata"] = &CmdMan::handleGetdata;
-	handlemap["list"] = &CmdMan::handleList;
-	handlemap["version"] = &CmdMan::handleVersion;
-	handlemap["login"] = &CmdMan::handleLogin;
-}
 
-CmdMan::~CmdMan() {
-	delete reader;
+  dologin = false;
+  doversion = false;
+
+  /* initialize execute command map */
+  execmap["help"] = &CmdMan::cmdHelp;
+  execmap["status"] = &CmdMan::cmdStatus;
+  execmap["disconnect"] = &CmdMan::cmdDisconnect;
+  execmap["put"] = &CmdMan::cmdPut;
+  execmap["get"] = &CmdMan::cmdGet;
+  execmap["list"] = &CmdMan::cmdList;
+  execmap["version"] = &CmdMan::cmdVersion;
+  execmap["login"] = &CmdMan::cmdLogin;
+  execmap["putdata"] = &CmdMan::cmdPutdata;
+  execmap["getdata"] = &CmdMan::cmdGetdata;
+
+  /* initialize description map */
+  helpmap["help"] = descHelp;
+  helpmap["status"] = descStatus;
+  helpmap["disconnect"] = descDisconnect;
+  helpmap["put"] = descPut;
+  helpmap["get"] = descGet;
+  helpmap["list"] = descList;
+
+  /* initialize handle command map */
+  handlemap["status"] = &CmdMan::handleStatus;
+  handlemap["close"] = &CmdMan::handleClose;
+  handlemap["put"] = &CmdMan::handlePut;
+  handlemap["get"] = &CmdMan::handleGet;
+  handlemap["putdata"] = &CmdMan::handlePutdata;
+  handlemap["getdata"] = &CmdMan::handleGetdata;
+  handlemap["list"] = &CmdMan::handleList;
+  handlemap["version"] = &CmdMan::handleVersion;
+  handlemap["login"] = &CmdMan::handleLogin;
 }
 
+CmdMan::~CmdMan() { delete reader; }
+
 CmdMan::CmdRet CmdMan::cmdHelp(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	map<string,string>::iterator it;
-	for(it = helpmap.begin(); it != helpmap.end(); it++) {
-		retval.msg.append(it->first);
-		retval.msg.append(" - ");
-		retval.msg.append(it->second);
-		retval.msg.append("\n");
-	}
-	retval.type = notsend;
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  map<string, string>::iterator it;
+  for (it = helpmap.begin(); it != helpmap.end(); it++) {
+    retval.msg.append(it->first);
+    retval.msg.append(" - ");
+    retval.msg.append(it->second);
+    retval.msg.append("\n");
+  }
+  retval.type = notsend;
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdStatus(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	root["command"] = "status";
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+  root["command"] = "status";
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdDisconnect(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	root["command"] = "close";
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+  root["command"] = "close";
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdPut(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	
-	bool opened = fileman.openPut(args[0]);
-	if(opened) {
-		root["command"] = "put";
-		root["file"] = fileman.getPutName();
-		root["size"] = fileman.getPutSize();
-		root["chunks"] = fileman.getPutChunks();
-		retval.type = send;
-		retval.msg = Json::writeString(wbuilder, root);
-	}
-	else {
-		retval.type = error;
-		retval.msg = "couldnt open local file \"" + args[0] + "\"";
-	}
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+
+  bool opened = fileman.openPut(args[0]);
+  if (opened) {
+    root["command"] = "put";
+    root["file"] = fileman.getPutName();
+    root["size"] = fileman.getPutSize();
+    root["chunks"] = fileman.getPutChunks();
+    retval.type = send;
+    retval.msg = Json::writeString(wbuilder, root);
+  } else {
+    retval.type = error;
+    retval.msg = "couldnt open local file \"" + args[0] + "\"";
+  }
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdPutdata(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	
-	root["command"] = "putdata";
-	root["file"] = fileman.getPutName();
-	root["cancel"] = false;
-	root["data"] = fileman.readBase64();
-	root["remaining"] = fileman.getPutRemainingChunks(); // number already decremented by readBase64
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-		
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+
+  root["command"] = "putdata";
+  root["file"] = fileman.getPutName();
+  root["cancel"] = false;
+  root["data"] = fileman.readBase64();
+  root["remaining"] =
+      fileman
+          .getPutRemainingChunks(); // number already decremented by readBase64
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdGet(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	
-	bool opened = fileman.openGet(args[0]);
-	if(opened) {
-		root["command"] = "get";
-		root["file"] = fileman.getGetName();
-		retval.type = send;
-		retval.msg = Json::writeString(wbuilder, root);
-	}
-	else {
-		retval.type = error;
-		retval.msg = "local file \"" + args[0] + "\" already exists";
-	}
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+
+  bool opened = fileman.openGet(args[0]);
+  if (opened) {
+    root["command"] = "get";
+    root["file"] = fileman.getGetName();
+    retval.type = send;
+    retval.msg = Json::writeString(wbuilder, root);
+  } else {
+    retval.type = error;
+    retval.msg = "local file \"" + args[0] + "\" already exists";
+  }
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdGetdata(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	
-	root["command"] = "getdata";
-	root["file"] = fileman.getGetName();
-	root["chunk"] = fileman.getGetRemainingChunks();
-	root["cancel"] = false;
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-		
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+
+  root["command"] = "getdata";
+  root["file"] = fileman.getGetName();
+  root["chunk"] = fileman.getGetRemainingChunks();
+  root["cancel"] = false;
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdList(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	root["command"] = "list";
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+  root["command"] = "list";
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdListdata(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	root["command"] = "listdata";
-	root["chunk"] = fileman.getListRemainingChunks();
-	root["cancel"] = false;
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+  root["command"] = "listdata";
+  root["chunk"] = fileman.getListRemainingChunks();
+  root["cancel"] = false;
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::execute(string cmd, vector<string> args) {
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	std::cerr << __PRETTY_FUNCTION__ << " using command \"" << cmd << "\" with arguments [ ";
-	for(string s : args) std::cerr << s << " ";
-	std::cerr << "]" << std::endl;
-	map<string,CmdRet(CmdMan::*)(vector<string>)>::iterator it = execmap.find(cmd);
-	string retmsg;
-	if(it == execmap.end()) {
-		return { error, string(__PRETTY_FUNCTION__) + " unknown command \"" + cmd + "\".\ntype help to list available commands." };
-	}
-	return (this->*(execmap[cmd]))(args);
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  std::cerr << __PRETTY_FUNCTION__ << " using command \"" << cmd
+            << "\" with arguments [ ";
+  for (string s : args)
+    std::cerr << s << " ";
+  std::cerr << "]" << std::endl;
+  map<string, CmdRet (CmdMan::*)(vector<string>)>::iterator it =
+      execmap.find(cmd);
+  string retmsg;
+  if (it == execmap.end()) {
+    return {error, string(__PRETTY_FUNCTION__) + " unknown command \"" + cmd +
+                       "\".\ntype help to list available commands."};
+  }
+  return (this->*(execmap[cmd]))(args);
 }
 
 /* internal commands */
 CmdMan::CmdRet CmdMan::cmdVersion(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	root["version"] = protocolVersion;
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-	
-	doversion = true;
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+  root["version"] = protocolVersion;
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  doversion = true;
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::cmdLogin(vector<string> args) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	Json::Value root;
-	root["user"] = args[0];
-	root["pass"] = args[1];
-	root["login"] = true;
-	root["cancel"] = false;
-	retval.type = send;
-	retval.msg = Json::writeString(wbuilder, root);
-	
-	dologin = true;
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  Json::Value root;
+  root["user"] = args[0];
+  root["pass"] = args[1];
+  root["login"] = true;
+  root["cancel"] = false;
+  retval.type = send;
+  retval.msg = Json::writeString(wbuilder, root);
+
+  dologin = true;
+
+  return retval;
 }
 
 /*
-	handlemap["status"] = &CmdMan::handleDefault;
-	handlemap["disconnect"] = &CmdMan::handleDefault;
-	handlemap["put"] = &CmdMan::handleDefault;
-	handlemap["get"] = &CmdMan::handleDefault;
-	handlemap["list"] = NULL;
-	handlemap["version"] = NULL;
-	handlemap["login"] = NULL;
+        handlemap["status"] = &CmdMan::handleDefault;
+        handlemap["disconnect"] = &CmdMan::handleDefault;
+        handlemap["put"] = &CmdMan::handleDefault;
+        handlemap["get"] = &CmdMan::handleDefault;
+        handlemap["list"] = NULL;
+        handlemap["version"] = NULL;
+        handlemap["login"] = NULL;
 */
 
 CmdMan::CmdRet CmdMan::handle(Json::Value root) {
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	if(doversion) root["command"] = "version";
-	else if (dologin) root["command"] = "login";
-	std::cerr << __PRETTY_FUNCTION__ << " using json" << std::endl << root << std::endl;
-	string retmsg;
-	map<string,CmdRet(CmdMan::*)(Json::Value)>::iterator it = handlemap.find(root["command"].asString());
-	if(it == handlemap.end()) {
-		return { error, string(__PRETTY_FUNCTION__) + " unknown command \"" + root["command"].asString() + "\".\nensure code is implemented." };
-	}
-	return (this->*(handlemap[root["command"].asString()]))(root);
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  if (doversion)
+    root["command"] = "version";
+  else if (dologin)
+    root["command"] = "login";
+  std::cerr << __PRETTY_FUNCTION__ << " using json" << std::endl
+            << root << std::endl;
+  string retmsg;
+  map<string, CmdRet (CmdMan::*)(Json::Value)>::iterator it =
+      handlemap.find(root["command"].asString());
+  if (it == handlemap.end()) {
+    return {error, string(__PRETTY_FUNCTION__) + " unknown command \"" +
+                       root["command"].asString() +
+                       "\".\nensure code is implemented."};
+  }
+  return (this->*(handlemap[root["command"].asString()]))(root);
 }
 
 CmdMan::CmdRet CmdMan::handleStatus(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	retval.type = notsend;
-	retval.msg = root["response"].asString();
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  retval.type = notsend;
+  retval.msg = root["response"].asString();
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handleClose(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	retval.type = close;
-	retval.msg = root["response"].asString();
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  retval.type = close;
+  retval.msg = root["response"].asString();
+
+  return retval;
 }
-	
 
 CmdMan::CmdRet CmdMan::handlePut(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	
-	if(!root["accept"].asBool()) {
-		retval.type = error;
-		retval.msg = "File upload request failed: Server reports: " + root["error"].asString();
-	} else if(root["file"].asString() != fileman.getPutName()) {
-		retval.type = error;
-		retval.msg = "File upload request failed: Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getPutName();
-	} else {
-		retval.type = send;
-		retval.msg = "putdata";
-	}
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+
+  if (!root["accept"].asBool()) {
+    retval.type = error;
+    retval.msg = "File upload request failed: Server reports: " +
+                 root["error"].asString();
+  } else if (root["file"].asString() != fileman.getPutName()) {
+    retval.type = error;
+    retval.msg = "File upload request failed: Server reports filename " +
+                 root["file"].asString() + " but actual filename is " +
+                 fileman.getPutName();
+  } else {
+    retval.type = send;
+    retval.msg = "putdata";
+  }
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handlePutdata(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	
-	if(root["received"].asInt() != fileman.getPutRemainingChunks()) {
-		// the number of remaining chunks received from the daemon does not equal the number stored at the client side		
-		retval.type = error;
-		retval.msg = std::string("File upload failed: Server reports number of remaining chunks as ") + std::to_string(root["received"].asInt()) + " but actual number is " + std::to_string(fileman.getPutRemainingChunks());
-		fileman.cancelPut();
-	} else if(root["cancel"].asBool()) {
-		retval.type = error;
-		retval.msg = "File upload cancelles: Server reports: " + root["error"].asString();
-		fileman.cancelPut();
-	} else if(root["file"].asString() != fileman.getPutName()) {
-		retval.type = error;
-		retval.msg = "File upload request failed: Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getPutName();
-		fileman.cancelPut();
-	} else {
-		// sent successfully
-		if(!root["received"].asInt()) {
-			// everything sent
-			retval.type = notsend;
-			retval.msg = "succesfully uploaded file " + fileman.getPutName();
-			fileman.closePut();
-		} else {
-			retval.type = send;
-			retval.msg = "putdata";
-		}
-	}
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+
+  if (root["received"].asInt() != fileman.getPutRemainingChunks()) {
+    // the number of remaining chunks received from the daemon does not equal
+    // the number stored at the client side
+    retval.type = error;
+    retval.msg = std::string("File upload failed: Server reports number of "
+                             "remaining chunks as ") +
+                 std::to_string(root["received"].asInt()) +
+                 " but actual number is " +
+                 std::to_string(fileman.getPutRemainingChunks());
+    fileman.cancelPut();
+  } else if (root["cancel"].asBool()) {
+    retval.type = error;
+    retval.msg =
+        "File upload cancelles: Server reports: " + root["error"].asString();
+    fileman.cancelPut();
+  } else if (root["file"].asString() != fileman.getPutName()) {
+    retval.type = error;
+    retval.msg = "File upload request failed: Server reports filename " +
+                 root["file"].asString() + " but actual filename is " +
+                 fileman.getPutName();
+    fileman.cancelPut();
+  } else {
+    // sent successfully
+    if (!root["received"].asInt()) {
+      // everything sent
+      retval.type = notsend;
+      retval.msg = "succesfully uploaded file " + fileman.getPutName();
+      fileman.closePut();
+    } else {
+      retval.type = send;
+      retval.msg = "putdata";
+    }
+  }
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handleGet(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	
-	if(!root["accept"].asBool()) {
-		retval.type = error;
-		retval.msg = "File download request failed: Server reports: " + root["error"].asString();
-	} else if(root["file"].asString() != fileman.getGetName()) {
-		retval.type = error;
-		retval.msg = "File download request failed: Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getGetName();
-	} else {
-		fileman.setGetChunks(root["chunks"].asInt());
-		retval.type = send;
-		retval.msg = "getdata";
-	}
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+
+  if (!root["accept"].asBool()) {
+    retval.type = error;
+    retval.msg = "File download request failed: Server reports: " +
+                 root["error"].asString();
+  } else if (root["file"].asString() != fileman.getGetName()) {
+    retval.type = error;
+    retval.msg = "File download request failed: Server reports filename " +
+                 root["file"].asString() + " but actual filename is " +
+                 fileman.getGetName();
+  } else {
+    fileman.setGetChunks(root["chunks"].asInt());
+    retval.type = send;
+    retval.msg = "getdata";
+  }
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handleGetdata(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	
-	// the passed number of recieved chunks should equal the number of sent chunks
-	if(root["remaining"].asInt() != fileman.getGetRemainingChunks()) {
-		retval.type = error;
-		retval.msg = std::string("File download failed: Server reports number of remaining chunks as ") + std::to_string(root["remaining"].asInt()) + " but actual number is " + std::to_string(fileman.getGetRemainingChunks());
-		fileman.cancelGet();
-	} else if(root["cancel"].asBool()) {
-		retval.type = error;
-		retval.msg = "File download cancelled: Server reports: " + root["error"].asString();
-		fileman.cancelGet();
-	} else if(root["file"].asString() != fileman.getGetName()) {
-		retval.type = error;
-		retval.msg = "File download failed: Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getGetName();
-		fileman.cancelGet();
-	} else {
-		fileman.writeBase64(root["data"].asString());
-		// loaded successfully
-		if(fileman.getGetRemainingChunks() < 0) {
-			// everything sent
-			retval.type = notsend;
-			retval.msg = "succesfully downloaded file " + fileman.getGetName();
-			fileman.closeGet();
-		} else {
-			retval.type = send;
-			retval.msg = "getdata";
-		}
-	}
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+
+  // the passed number of recieved chunks should equal the number of sent chunks
+  if (root["remaining"].asInt() != fileman.getGetRemainingChunks()) {
+    retval.type = error;
+    retval.msg = std::string("File download failed: Server reports number of "
+                             "remaining chunks as ") +
+                 std::to_string(root["remaining"].asInt()) +
+                 " but actual number is " +
+                 std::to_string(fileman.getGetRemainingChunks());
+    fileman.cancelGet();
+  } else if (root["cancel"].asBool()) {
+    retval.type = error;
+    retval.msg =
+        "File download cancelled: Server reports: " + root["error"].asString();
+    fileman.cancelGet();
+  } else if (root["file"].asString() != fileman.getGetName()) {
+    retval.type = error;
+    retval.msg = "File download failed: Server reports filename " +
+                 root["file"].asString() + " but actual filename is " +
+                 fileman.getGetName();
+    fileman.cancelGet();
+  } else {
+    fileman.writeBase64(root["data"].asString());
+    // loaded successfully
+    if (fileman.getGetRemainingChunks() < 0) {
+      // everything sent
+      retval.type = notsend;
+      retval.msg = "succesfully downloaded file " + fileman.getGetName();
+      fileman.closeGet();
+    } else {
+      retval.type = send;
+      retval.msg = "getdata";
+    }
+  }
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handleList(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	
-	if(!root["accept"].asBool()) {
-		retval.type = error;
-		retval.msg = "File listing request failed: Server reports: " + root["error"].asString();
-	} else {
-		fileman.setListChunks(root["chunks"].asInt());
-		retval.type = send;
-		retval.msg = "listdata";
-	}
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+
+  if (!root["accept"].asBool()) {
+    retval.type = error;
+    retval.msg = "File listing request failed: Server reports: " +
+                 root["error"].asString();
+  } else {
+    fileman.setListChunks(root["chunks"].asInt());
+    retval.type = send;
+    retval.msg = "listdata";
+  }
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handleListdata(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	vector<string> toadd;
-	
-	// the passed number of recieved chunks should equal the number of sent chunks
-	if(root["remaining"].asInt() != fileman.getListRemainingChunks()) {
-		retval.type = error;
-		retval.msg = std::string("File listing failed: Server reports number of remaining chunks as ") + std::to_string(root["remaining"].asInt()) + " but actual number is " + std::to_string(fileman.getListRemainingChunks());
-		fileman.cancelList();
-	} else if(root["cancel"].asBool()) {
-		retval.type = error;
-		retval.msg = "File listing cancelled: Server reports: " + root["error"].asString();
-		fileman.cancelList();
-	} else {
-		for(Json::Value i : root["names"]) toadd.push_back(i.asString());
-		fileman.putListData(toadd);
-		// loaded successfully
-		if(!fileman.getListRemainingChunks()) {
-			// everything sent
-			retval.type = notsend;
-			retval.msg = "Files on server:\n";
-			for(string s : fileman.getListData()) retval.msg += s + "\n";
-			fileman.closeList();
-		} else {
-			retval.type = send;
-			retval.msg = "listdata";
-		}
-	}
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+  vector<string> toadd;
+
+  // the passed number of recieved chunks should equal the number of sent chunks
+  if (root["remaining"].asInt() != fileman.getListRemainingChunks()) {
+    retval.type = error;
+    retval.msg = std::string("File listing failed: Server reports number of "
+                             "remaining chunks as ") +
+                 std::to_string(root["remaining"].asInt()) +
+                 " but actual number is " +
+                 std::to_string(fileman.getListRemainingChunks());
+    fileman.cancelList();
+  } else if (root["cancel"].asBool()) {
+    retval.type = error;
+    retval.msg =
+        "File listing cancelled: Server reports: " + root["error"].asString();
+    fileman.cancelList();
+  } else {
+    for (Json::Value i : root["names"])
+      toadd.push_back(i.asString());
+    fileman.putListData(toadd);
+    // loaded successfully
+    if (!fileman.getListRemainingChunks()) {
+      // everything sent
+      retval.type = notsend;
+      retval.msg = "Files on server:\n";
+      for (string s : fileman.getListData())
+        retval.msg += s + "\n";
+      fileman.closeList();
+    } else {
+      retval.type = send;
+      retval.msg = "listdata";
+    }
+  }
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handleVersion(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	
-	if(!root["accept"].asBool()) {
-		retval.type = error;
-		retval.msg = "Version check failed: Server reports " + root["version"].asString() + " but client is version " + protocolVersion;
-	}
-	else {
-		retval.type = seton;
-		retval.msg = "Version check ok.";
-		doversion = false;
-	}
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+
+  if (!root["accept"].asBool()) {
+    retval.type = error;
+    retval.msg = "Version check failed: Server reports " +
+                 root["version"].asString() + " but client is version " +
+                 protocolVersion;
+  } else {
+    retval.type = seton;
+    retval.msg = "Version check ok.";
+    doversion = false;
+  }
+
+  return retval;
 }
 
 CmdMan::CmdRet CmdMan::handleLogin(Json::Value root) {
-	CmdRet retval;
-	std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
-	
-	if(!root["accept"].asBool()) {
-		retval.type = error;
-		retval.msg = "Login failed: " + root["error"].asString();
-	}
-	else {
-		retval.type = seton;
-		retval.msg = "Login ok.";
-		dologin = false;
-	}
-	
-	return retval;
+  CmdRet retval;
+  std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
+
+  if (!root["accept"].asBool()) {
+    retval.type = error;
+    retval.msg = "Login failed: " + root["error"].asString();
+  } else {
+    retval.type = seton;
+    retval.msg = "Login ok.";
+    dologin = false;
+  }
+
+  return retval;
 }

+ 71 - 107
cli/src/fileman.cpp

@@ -1,166 +1,130 @@
 #include "../include/fileman.h"
 #include "../include/base64.h"
 
-FileMan::FileMan() {
-	islisting = false;
-}
+FileMan::FileMan() { islisting = false; }
 
 FileMan::~FileMan() {
-	cancelGet();
-	closePut();
+  cancelGet();
+  closePut();
 }
 
-bool FileMan::isGetting() {
-	return getfile.is_open();
-}
+bool FileMan::isGetting() { return getfile.is_open(); }
 
-bool FileMan::isPutting() {
-	return putfile.is_open();
-}
+bool FileMan::isPutting() { return putfile.is_open(); }
 
-bool FileMan::isListing() {
-	return islisting;
-}
+bool FileMan::isListing() { return islisting; }
 
 bool FileMan::openPut(const std::string &name) {
-	putname = name;
-	putfile.open(name, std::ios::ate | std::ios::binary);
-	if(putfile.is_open()) {
-		size_t size = putfile.tellg();
-		putsize = size;
-		putchunks = size / max_read_len + ((size % max_read_len) ? 1 : 0);
-		putchunksRemaining = putchunks;
-		putfile.seekg(std::ios::beg);
-		return true;
-	}
-	return false;
+  putname = name;
+  putfile.open(name, std::ios::ate | std::ios::binary);
+  if (putfile.is_open()) {
+    size_t size = putfile.tellg();
+    putsize = size;
+    putchunks = size / max_read_len + ((size % max_read_len) ? 1 : 0);
+    putchunksRemaining = putchunks;
+    putfile.seekg(std::ios::beg);
+    return true;
+  }
+  return false;
 }
 
 bool FileMan::openGet(const std::string &name) {
-	getname = name;
-	getchunks = 0;
-	getchunksRemaining = 0;
-	getfile.open(name, std::ios::app | std::ios::binary);
-	if(getfile.tellp() != std::ios::beg) {
-		closeGet();
-		return false;
-	}
-	return true;
+  getname = name;
+  getchunks = 0;
+  getchunksRemaining = 0;
+  getfile.open(name, std::ios::app | std::ios::binary);
+  if (getfile.tellp() != std::ios::beg) {
+    closeGet();
+    return false;
+  }
+  return true;
 }
 
 bool FileMan::openList() {
-	if(isListing()) {
-		return false;
-	}
-	listdata = std::vector<std::string>();
-	islisting = true;
-	return true;
+  if (isListing()) {
+    return false;
+  }
+  listdata = std::vector<std::string>();
+  islisting = true;
+  return true;
 }
 
-void FileMan::closePut() {
-	putfile.close();
-}
+void FileMan::closePut() { putfile.close(); }
 
-void FileMan::closeGet() {
-	getfile.close();
-}
+void FileMan::closeGet() { getfile.close(); }
 
-void FileMan::closeList() {
-	islisting = false;
-}
+void FileMan::closeList() { islisting = false; }
 
 void FileMan::cancelPut() {
-	if(isPutting()) {
-		closePut();
-	}
+  if (isPutting()) {
+    closePut();
+  }
 }
 
 void FileMan::cancelGet() {
-	if(isGetting()) {
-		closeGet();
-		std::remove(getname.c_str());
-	}
+  if (isGetting()) {
+    closeGet();
+    std::remove(getname.c_str());
+  }
 }
 
 void FileMan::cancelList() {
-	if(isListing()) {
-		closeList();
-	}
+  if (isListing()) {
+    closeList();
+  }
 }
 
 void FileMan::writeGet(const std::vector<char> data) {
-	getfile.write(data.data(), data.size());
-	getchunksRemaining--;
+  getfile.write(data.data(), data.size());
+  getchunksRemaining--;
 }
 
 void FileMan::writeBase64(std::string data) {
-	writeGet(base64::decodeVector(data));
+  writeGet(base64::decodeVector(data));
 }
 
 void FileMan::putListData(std::vector<std::string> names) {
-	listdata.insert(listdata.end(), names.begin(), names.end());
-	listchunksRemaining--;
+  listdata.insert(listdata.end(), names.begin(), names.end());
+  listchunksRemaining--;
 }
 
-std::vector<std::string> FileMan::getListData() {
-	return listdata;
-}
+std::vector<std::string> FileMan::getListData() { return listdata; }
 
-int FileMan::getGetChunks() {
-	return getchunks;
-}
+int FileMan::getGetChunks() { return getchunks; }
 
-int FileMan::getGetRemainingChunks() {
-	return getchunksRemaining;
-}
+int FileMan::getGetRemainingChunks() { return getchunksRemaining; }
 
 void FileMan::setGetChunks(int chunks) {
-	getchunks = chunks;
-	getchunksRemaining = chunks-1;
+  getchunks = chunks;
+  getchunksRemaining = chunks - 1;
 }
 
 void FileMan::setListChunks(int chunks) {
-	listchunks = chunks;
-	getchunksRemaining = chunks-1;
+  listchunks = chunks;
+  getchunksRemaining = chunks - 1;
 }
 
 std::vector<char> FileMan::readPut() {
-	char buf[max_read_len];
-	std::vector<char> data;
-	int read = putfile.readsome(buf, max_read_len);
-	data.assign(buf, buf+read);
-	putchunksRemaining--;
-	return data;
+  char buf[max_read_len];
+  std::vector<char> data;
+  int read = putfile.readsome(buf, max_read_len);
+  data.assign(buf, buf + read);
+  putchunksRemaining--;
+  return data;
 }
 
-std::string FileMan::readBase64() {
-	return base64::encodeVector(readPut());
-}
+std::string FileMan::readBase64() { return base64::encodeVector(readPut()); }
 
-std::string FileMan::getPutName() {
-	return putname;
-}
+std::string FileMan::getPutName() { return putname; }
 
-std::string FileMan::getGetName() {
-	return getname;
-}
+std::string FileMan::getGetName() { return getname; }
 
-int FileMan::getPutChunks() {
-	return putchunks;
-}
+int FileMan::getPutChunks() { return putchunks; }
 
-int FileMan::getPutRemainingChunks() {
-	return putchunksRemaining;
-}
+int FileMan::getPutRemainingChunks() { return putchunksRemaining; }
 
-int FileMan::getPutSize() {
-	return putsize;
-}
+int FileMan::getPutSize() { return putsize; }
 
-int FileMan::getListRemainingChunks() {
-	return listchunksRemaining;
-}
+int FileMan::getListRemainingChunks() { return listchunksRemaining; }
 
-int FileMan::getListChunks() {
-	return listchunks;
-}
+int FileMan::getListChunks() { return listchunks; }

+ 486 - 400
cli/src/ioman.cpp

@@ -1,5 +1,5 @@
-#include "../include/global.h"
 #include "../include/ioman.h"
+#include "../include/global.h"
 
 #include <boost/asio.hpp>
 #include <iostream>
@@ -14,49 +14,58 @@
 using std::string;
 using std::vector;
 
-using boost::asio::ip::tcp;
 using boost::asio::buffer;
+using boost::asio::ip::tcp;
 
 IoMan::IoMan(char *ipcstring) : cmdman(fileman) {
   ipstring = std::string(ipcstring);
   port = 1234;
   tcpsock = new tcp::socket(ios);
   connected = false;
-	
-	/* to be put elsewhere */
 
-	/* setup json stuff */
+  /* to be put elsewhere */
+
+  /* setup json stuff */
   Json::CharReaderBuilder rbuilder;
   wbuilder.settings_["indentation"] = "";
   reader = rbuilder.newCharReader();
-	runnetwork = false;
-	runinput = false;
-	runresponse = false;
-	startlist = false;
-	versionstatus = off;
-	loginstatus = off;
+  runnetwork = false;
+  runinput = false;
+  runresponse = false;
+  startlist = false;
+  versionstatus = off;
+  loginstatus = off;
 }
 
 IoMan::~IoMan() {
-	runnetwork = false;
-	runinput = false;
-	runresponse = false;
-	
-	tnetwork.join();
-	tinput.join();
-	tresponse.join();
-	
-	if(connected) {
-		disconnect();
-	}
-	
-	delete tcpsock;
-	delete reader;
-}
+  networkmutex.lock();
+  inputmutex.lock();
+  responsemutex.lock();
+  runnetwork = false;
+  runinput = false;
+  runresponse = false;
+  networkmutex.unlock();
+  inputmutex.unlock();
+  responsemutex.unlock();
 
-void IoMan::printMessage(string nouse, OutMsgType nouse2) {
+  initcv.notify_all();
+  localcv.notify_all();
+  netcv.notify_all();
+
+  tnetwork.join();
+  tinput.join();
+  tresponse.join();
+
+  if (connected) {
+    disconnect();
+  }
+
+  delete tcpsock;
+  delete reader;
 }
 
+void IoMan::printMessage(string nouse, OutMsgType nouse2) {}
+
 bool IoMan::connect() {
   tcp::endpoint *ep;
 
@@ -66,400 +75,477 @@ bool IoMan::connect() {
   printMessage("IoMan::connect() connecting to " + ipstring, debug);
   tcpsock->connect(*ep, errcode);
   if (errcode) {
-	  delete ep;
-	  printMessage("IoMan::connect() couldnt connect to " + ipstring + "\n" + errcode.message(), error);
-	return false;
+    delete ep;
+    printMessage("IoMan::connect() couldnt connect to " + ipstring + "\n" +
+                     errcode.message(),
+                 error);
+    return false;
   }
   connected = true;
   delete ep;
   return true;
 }
 
-
 void IoMan::disconnect() {
   printMessage("IoMan::disconnect()", debug);
-	tcpsock->close();
-	connected = false;
+  tcpsock->close();
+  connected = false;
 }
 
-
 bool IoMan::init() {
-	CmdMan::CmdRet ret;
-	string work;
-	Json::Value root;
-	
-	printMessage("IoMan::Init() begin", debug);
-	
-	if(!connect()) return false;
-	
-	printMessage("IoMan::Init() versioncheck", debug);
-	
-	localmutex.lock();
-	printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"), debug);
-	localinput.push_back("version " + protocolVersion);
-	localmutex.unlock();
-	printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"), debug);
-	
-	printMessage("IoMan::Init() begin", debug);
-	
-	runnetwork = true;
-	runinput = true;
-	runresponse = true;
-	
-	tnetwork = std::thread(&IoMan::networkMain, this);
-	tinput = std::thread(&IoMan::inputMain, this);
-	tresponse = std::thread(&IoMan::responseMain, this);
-	
-	while(versionstatus == off);
-	if(versionstatus == err) {
-		runnetwork = false;
-		runinput = false;
-		runresponse = false;
-		return false;
-	}
-	
-	printWelcomeMessage();
-	return true;
+  CmdMan::CmdRet ret;
+  string work;
+  Json::Value root;
+  std::unique_lock<std::mutex> ulock;
+
+  printMessage("IoMan::Init() begin", debug);
+
+  if (!connect())
+    return false;
+
+  printMessage("IoMan::Init() versioncheck", debug);
+
+  localmutex.lock();
+  printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"), debug);
+  localinput.push_back("version " + protocolVersion);
+  localmutex.unlock();
+  printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"),
+               debug);
+  localcv.notify_all();
+
+  printMessage("IoMan::Init() begin", debug);
+
+  runnetwork = true;
+  runinput = true;
+  runresponse = true;
+
+  tnetwork = std::thread(&IoMan::networkMain, this);
+  tinput = std::thread(&IoMan::inputMain, this);
+  tresponse = std::thread(&IoMan::responseMain, this);
+
+  ulock = std::unique_lock<std::mutex>(initmutex);
+  while (versionstatus == off) {
+    initcv.wait(ulock);
+  }
+  if (versionstatus == err) {
+    runnetwork = false;
+    runinput = false;
+    runresponse = false;
+    return false;
+  }
+  initmutex.unlock();
+  initcv.notify_all();
+
+  printWelcomeMessage();
+  return true;
 }
 
 void IoMan::networkMain() {
-	vector<Json::Value> toput;
-	char *recvjson;
-	Json::Value root;
-	unsigned int jsonsize, readsize;
-	
-	printMessage("IoMan::networkMain() begin", debug);
-	while(runnetwork) {
-		std::this_thread::yield();
-		std::this_thread::sleep_for(std::chrono::milliseconds(10));
-		/*
-		read from network until \n
-		try to parse json
-		- output error if not ok
-		store all ok json in local vector
-		
-		get networkmutex
-		put all local jsons into network vector
-		release networkmutex
-		*/
-		
-		// read from network
-		readsize = boost::asio::read_until(*tcpsock, recvbuf, '\n', errcode);
-		printMessage(string(__PRETTY_FUNCTION__) + string(" asio::read() ok ") + std::to_string(readsize), debug);
-		// printMessage(string("have ") + std::to_string(toprocess.size()) + string(" commands"), debug);
-		if (errcode && errcode != boost::asio::error::eof) {
-			printMessage("IoMan::networkMain() couldnt read json data\n" + errcode.message(), error);
-			continue;
-		}
-		if(!readsize) break;
-		recvjson = (char *)(boost::asio::buffer_cast<const char *>(recvbuf.data()));
-		recvjson[readsize] = 0;
-		while(strchr(recvjson, '\n')) {
-			// parse
-			jsonsize = strchr(recvjson, '\n') - recvjson + 1;
-			
-			printMessage(string(__PRETTY_FUNCTION__) + string(" found jsondata ") + string(recvjson), debug);
-			
-			if (!reader->parse(recvjson, recvjson + jsonsize, &root, &jsonerror)) {
-				printMessage("IoMan::networkMain() couldnt parse json data: " + jsonerror, error);
-				recvbuf.consume(jsonsize);
-				continue;
-			}
-			recvbuf.consume(jsonsize);
-			readsize -= jsonsize;
-			
-			printMessage(string(__PRETTY_FUNCTION__) + string(" remaining recvbuf ") + string(boost::asio::buffer_cast<const char *>(recvbuf.data())), debug);
-			
-			for(int i = 0; i < jsonsize; i++) recvjson++;
-			// store locally
-			toput.push_back(root);
-		}
-		
-		if(toput.size()){
-			// put into global vector
-			netmutex.lock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" get netmutex"), debug);
-			netinput.insert(netinput.end(), toput.begin(), toput.end());
-			netmutex.unlock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" release netmutex"), debug);
-		}
-		
-		// clean up local stuff
-		toput = vector<Json::Value>();
-		recvbuf.consume(readsize);
-	}
+  vector<Json::Value> toput;
+  char *recvjson;
+  Json::Value root;
+  unsigned int jsonsize, readsize;
+
+  printMessage("IoMan::networkMain() begin", debug);
+  networkmutex.lock();
+  while (runnetwork) {
+    networkmutex.unlock();
+    /*
+    read from network until \n
+    try to parse json
+    - output error if not ok
+    store all ok json in local vector
+
+    get networkmutex
+    put all local jsons into network vector
+    release networkmutex
+    */
+
+    // read from network
+    readsize = boost::asio::read_until(*tcpsock, recvbuf, '\n', errcode);
+    printMessage(string(__PRETTY_FUNCTION__) + string(" asio::read() ok ") +
+                     std::to_string(readsize),
+                 debug);
+    // printMessage(string("have ") + std::to_string(toprocess.size()) +
+    // string(" commands"), debug);
+    if (errcode && errcode != boost::asio::error::eof) {
+      printMessage("IoMan::networkMain() couldnt read json data\n" +
+                       errcode.message(),
+                   error);
+      continue;
+    }
+    if (!readsize)
+      break;
+    recvjson = (char *)(boost::asio::buffer_cast<const char *>(recvbuf.data()));
+    recvjson[readsize] = 0;
+    while (strchr(recvjson, '\n')) {
+      // parse
+      jsonsize = strchr(recvjson, '\n') - recvjson + 1;
+
+      printMessage(string(__PRETTY_FUNCTION__) + string(" found jsondata ") +
+                       string(recvjson),
+                   debug);
+
+      if (!reader->parse(recvjson, recvjson + jsonsize, &root, &jsonerror)) {
+        printMessage("IoMan::networkMain() couldnt parse json data: " +
+                         jsonerror,
+                     error);
+        recvbuf.consume(jsonsize);
+        continue;
+      }
+      recvbuf.consume(jsonsize);
+      readsize -= jsonsize;
+
+      printMessage(
+          string(__PRETTY_FUNCTION__) + string(" remaining recvbuf ") +
+              string(boost::asio::buffer_cast<const char *>(recvbuf.data())),
+          debug);
+
+      for (int i = 0; i < jsonsize; i++)
+        recvjson++;
+      // store locally
+      toput.push_back(root);
+    }
+
+    if (toput.size()) {
+      // put into global vector
+      netmutex.lock();
+      printMessage(string(__PRETTY_FUNCTION__) + string(" get netmutex"),
+                   debug);
+      netinput.insert(netinput.end(), toput.begin(), toput.end());
+      netmutex.unlock();
+      printMessage(string(__PRETTY_FUNCTION__) + string(" release netmutex"),
+                   debug);
+    }
+    netcv.notify_all();
+
+    // clean up local stuff
+    toput = vector<Json::Value>();
+    recvbuf.consume(readsize);
+    networkmutex.lock();
+  }
 }
 
 void IoMan::inputMain() {
-	vector<string> toprocess;
-	string command;
-	vector<string> args;
-	CmdMan::CmdRet cmdret;
-	
-	size_t prev, index, quot;
-	
-	printMessage("IoMan::inputMain() begin", debug);
-	while(runinput) {
-		std::this_thread::yield();
-		std::this_thread::sleep_for(std::chrono::milliseconds(10));
-		/*
-		get inputmutex
-		read all input vector into local vector
-		release inputmutex
-		
-		process inputs
-		send to server if required
-		*/
-		
-		// read into local vector
-		if(localinput.size()) {
-			localmutex.lock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" has localmutex"), debug);
-			toprocess = vector<string>(localinput);
-			localinput = vector<string>();
-			localmutex.unlock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"), debug);
-		}
-		
-		// printMessage(string("have ") + std::to_string(toprocess.size()) + string(" commands"), debug);
-		
-		// process
-		for(string cmd : toprocess) {
-			args = vector<string>();
-			
-			/* tokenize string into command and arguments vector*/
-			if((index = cmd.find(" ")) == string::npos) {
-				// only command no args
-				command = cmd;
-			}
-			else {
-				command = cmd.substr(0, index);
-				//~ index++;
-				
-				bool end_tokenizing = false;
-				while(!end_tokenizing) {
-					// find first char thats not a space
-					while(cmd[index] == ' ') {
-						index++;
-						
-						// bounds check
-						if(index == cmd.size()) end_tokenizing = true;
-					}
-					if(end_tokenizing) break;
-					
-					cmd = cmd.substr(index);
-					
-					if(cmd[0] == '\"') {
-						// quoted string
-						index = cmd.find("\"");
-						args.push_back(cmd.substr(1, index-1));
-						index++;
-						
-						/*
-						tokens.push_back(cmd.substr(0, ++index));
-						*/
-						
-						// char after closing quote should be space while within bounds
-						if(index == cmd.size()) end_tokenizing = true;
-					}
-					else {
-						// non-quoted string
-						index = cmd.find(" ");
-						if(index == string::npos) { // no spaces, last arg
-							args.push_back(cmd);
-							end_tokenizing = true;
-						}
-						else {
-							args.push_back(cmd.substr(0, index));
-						}
-					}
-				}
-			}
-			
-			cmdret = cmdman.execute(command, args);
-			
-			// determine wether to send something and do so if required
-			switch(cmdret.type) {
-				case CmdMan::rettype::send: {
-					printMessage("IoMan::inputMain() sending json \"" + cmdret.msg + "\"", debug);
-					boost::asio::write(*tcpsock, buffer(cmdret.msg + "\n"), errcode);
-					if (errcode) {
-						printMessage("IoMan::inputMain() couldnt send json data\n" + errcode.message() + "\n", error);
-						continue;
-					}
-					break;
-				}
-				case CmdMan::rettype::notsend: {
-					printMessage(cmdret.msg, normal);
-					break;
-				}
-				case CmdMan::rettype::error: {
-					printMessage(cmdret.msg, error);
-					break;
-				}
-			}
-		}
-		
-		// clean up local stuff
-		toprocess = vector<string>();
-	}
+  vector<string> toprocess;
+  string command;
+  vector<string> args;
+  CmdMan::CmdRet cmdret;
+  std::unique_lock<std::mutex> ulock;
+
+  size_t prev, index, quot;
+
+  printMessage("IoMan::inputMain() begin", debug);
+  inputmutex.lock();
+  while (runinput) {
+    inputmutex.unlock();
+    /*
+    get inputmutex
+    read all input vector into local vector
+    release inputmutex
+
+    process inputs
+    send to server if required
+    */
+
+    // read into local vector
+    ulock = std::unique_lock<std::mutex>(localmutex);
+    while (!localinput.size() && runinput) {
+      localcv.wait(ulock);
+    }
+    printMessage(string(__PRETTY_FUNCTION__) + string(" has localmutex"),
+                 debug);
+    toprocess = vector<string>(localinput);
+    localinput = vector<string>();
+    localmutex.unlock();
+    printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"),
+                 debug);
+    localcv.notify_all();
+
+    if (!runinput)
+      return;
+
+    // printMessage(string("have ") + std::to_string(toprocess.size()) +
+    // string(" commands"), debug);
+
+    // process
+    for (string cmd : toprocess) {
+      args = vector<string>();
+
+      /* tokenize string into command and arguments vector*/
+      if ((index = cmd.find(" ")) == string::npos) {
+        // only command no args
+        command = cmd;
+      } else {
+        command = cmd.substr(0, index);
+        //~ index++;
+
+        bool end_tokenizing = false;
+        while (!end_tokenizing) {
+          // find first char thats not a space
+          while (cmd[index] == ' ') {
+            index++;
+
+            // bounds check
+            if (index == cmd.size())
+              end_tokenizing = true;
+          }
+          if (end_tokenizing)
+            break;
+
+          cmd = cmd.substr(index);
+
+          if (cmd[0] == '\"') {
+            // quoted string
+            index = cmd.find("\"");
+            args.push_back(cmd.substr(1, index - 1));
+            index++;
+
+            /*
+            tokens.push_back(cmd.substr(0, ++index));
+            */
+
+            // char after closing quote should be space while within bounds
+            if (index == cmd.size())
+              end_tokenizing = true;
+          } else {
+            // non-quoted string
+            index = cmd.find(" ");
+            if (index == string::npos) { // no spaces, last arg
+              args.push_back(cmd);
+              end_tokenizing = true;
+            } else {
+              args.push_back(cmd.substr(0, index));
+            }
+          }
+        }
+      }
+
+      cmdret = cmdman.execute(command, args);
+
+      // determine wether to send something and do so if required
+      switch (cmdret.type) {
+      case CmdMan::rettype::send: {
+        printMessage("IoMan::inputMain() sending json \"" + cmdret.msg + "\"",
+                     debug);
+        boost::asio::write(*tcpsock, buffer(cmdret.msg + "\n"), errcode);
+        if (errcode) {
+          printMessage("IoMan::inputMain() couldnt send json data\n" +
+                           errcode.message() + "\n",
+                       error);
+          continue;
+        }
+        break;
+      }
+      case CmdMan::rettype::notsend: {
+        printMessage(cmdret.msg, normal);
+        break;
+      }
+      case CmdMan::rettype::error: {
+        printMessage(cmdret.msg, error);
+        break;
+      }
+      }
+    }
+
+    // clean up local stuff
+    toprocess = vector<string>();
+    inputmutex.lock();
+  }
 }
 
 void IoMan::responseMain() {
-	vector<Json::Value> toprocess;
-	vector<string> toput;
-	CmdMan::CmdRet cmdret;
-	
-	printMessage("IoMan::responseMain() begin", debug);
-	while(runresponse) {
-		std::this_thread::yield();
-		std::this_thread::sleep_for(std::chrono::milliseconds(10));
-		/*
-		get networkmutex
-		read all network vector into local vector
-		release networkmutex
-		
-		process all jsons
-		process putdata
-		process getdata
-		process listdata
-		
-		get inputmutex
-		place new commands into input vector
-		release inputmutex
-		*/
-		
-		// read into local vector
-		if(netinput.size()) {
-			netmutex.lock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" get netmutex"), debug);
-			toprocess = vector<Json::Value>(netinput);
-			netinput = vector<Json::Value>();
-			netmutex.unlock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" release netmutex"), debug);
-		}
-		
-		// process jsons
-		for(Json::Value root : toprocess) {
-			cmdret = cmdman.handle(root);
-			switch(cmdret.type) {
-				case CmdMan::rettype::startlist: {
-					startlist = true;
-					break;
-				}
-				case CmdMan::rettype::stoplist: {
-					startlist = false;
-					break;
-				}
-				case CmdMan::rettype::close: {
-					/* TODO i dunno */
-					runmain = false;
-					break;
-				}
-				case CmdMan::rettype::error: {
-					if(versionstatus == off) versionstatus = err;
-					else if(loginstatus == off) loginstatus = err;
-					printMessage(cmdret.msg, error);
-					break;
-				}
-				case CmdMan::rettype::seton: {
-					if(versionstatus == off) versionstatus = on;
-					else loginstatus = on;
-				}
-				case CmdMan::rettype::notsend: {
-					printMessage(cmdret.msg, normal);
-					break;
-				}
-				case CmdMan::rettype::send: {
-					toput.push_back(cmdret.msg);
-					break;
-				}
-			}
-		}
-		
-		if(toput.size()) {
-			// put new commands into global vector
-			localmutex.lock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"), debug);
-			localinput.insert(localinput.end(), toput.begin(), toput.end());
-			localmutex.unlock();
-			printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"), debug);
-		}
-		
-		// clean up local stuff
-		toprocess = vector<Json::Value>();
-		toput = vector<string>();
-	}
+  vector<Json::Value> toprocess;
+  vector<string> toput;
+  CmdMan::CmdRet cmdret;
+  std::unique_lock<std::mutex> ulock;
+
+  printMessage("IoMan::responseMain() begin", debug);
+  responsemutex.lock();
+  while (runresponse) {
+    responsemutex.unlock();
+    /*
+    get networkmutex
+    read all network vector into local vector
+    release networkmutex
+
+    process all jsons
+    process putdata
+    process getdata
+    process listdata
+
+    get inputmutex
+    place new commands into input vector
+    release inputmutex
+    */
+
+    // read into local vector
+    ulock = std::unique_lock<std::mutex>(netmutex);
+    while (!netinput.size() && runresponse) {
+      netcv.wait(ulock);
+    }
+    printMessage(string(__PRETTY_FUNCTION__) + string(" get netmutex"), debug);
+    toprocess = vector<Json::Value>(netinput);
+    netinput = vector<Json::Value>();
+    netmutex.unlock();
+    printMessage(string(__PRETTY_FUNCTION__) + string(" release netmutex"),
+                 debug);
+    netcv.notify_all();
+
+    if (!runresponse)
+      return;
+
+    // process jsons
+    for (Json::Value root : toprocess) {
+      cmdret = cmdman.handle(root);
+      switch (cmdret.type) {
+      case CmdMan::rettype::startlist: {
+        startlist = true;
+        break;
+      }
+      case CmdMan::rettype::stoplist: {
+        startlist = false;
+        break;
+      }
+      case CmdMan::rettype::close: {
+        /* TODO i dunno */
+        mainmutex.lock();
+        runmain = false;
+        mainmutex.unlock();
+        break;
+      }
+      case CmdMan::rettype::error: {
+        initmutex.lock();
+        if (versionstatus == off)
+          versionstatus = err;
+        else if (loginstatus == off)
+          loginstatus = err;
+        initmutex.unlock();
+        initcv.notify_all();
+        printMessage(cmdret.msg, error);
+        break;
+      }
+      case CmdMan::rettype::seton: {
+        initmutex.lock();
+        if (versionstatus == off)
+          versionstatus = on;
+        else
+          loginstatus = on;
+        initmutex.unlock();
+        initcv.notify_all();
+      }
+      case CmdMan::rettype::notsend: {
+        printMessage(cmdret.msg, normal);
+        break;
+      }
+      case CmdMan::rettype::send: {
+        toput.push_back(cmdret.msg);
+        break;
+      }
+      }
+    }
+
+    if (toput.size()) {
+      // put new commands into global vector
+      localmutex.lock();
+      printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"),
+                   debug);
+      localinput.insert(localinput.end(), toput.begin(), toput.end());
+      localmutex.unlock();
+      printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"),
+                   debug);
+    }
+    localcv.notify_all();
+
+    // clean up local stuff
+    toprocess = vector<Json::Value>();
+    toput = vector<string>();
+    responsemutex.lock();
+  }
 }
 
 void IoMan::run() {
-	printMessage("IoMan::run() begin", debug);
-	char *line = NULL, *user = NULL, *pass = NULL;
-	vector<string> tokens;
-	string work, command;
-	CmdMan::CmdRet cmdret;
-	Json::Value root;
-	
-	runmain = true;
-	
-	while(!user) {
-		user = readline(getUserPrompt().c_str());
-		printMessage("Using user: " + string(user), error);
-	}
-	while(!pass) {
-		pass = readline(getPassPrompt().c_str());
-		printMessage("Using pass: " + string(pass), error);
-	}
-	
-	printMessage("IoMan::run() login", debug);
-	
-	localmutex.lock();
-	printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"), debug);
-	localinput.push_back("login " + string(user) + " " + string(pass));
-	localmutex.unlock();
-	printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"), debug);
-	free(user);
-	free(pass);
-	
-	while(loginstatus == off);
-	if(loginstatus == err) return;
-	
-	while(runmain) {
-		free(line);
-		std::this_thread::yield();
-		std::this_thread::sleep_for(std::chrono::milliseconds(10));
-		
-		line = readline(getCmdPrompt().c_str());
-		
-		if(!runmain) break;
-
-		// if no input, do not add to history, and go to reading next line
-		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
-		if (tokens.size() < 1) {
-		  continue;
-		}
-
-		// add the line to history
-		add_history(line);
-		
-		localmutex.lock();
-		printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"), debug);
-		localinput.push_back(line);
-		localmutex.unlock();
-		printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"), debug);
-		
-		if(!connected) break;
-	}
-	
-	free(line);
+  printMessage("IoMan::run() begin", debug);
+  char *line = NULL, *user = NULL, *pass = NULL;
+  vector<string> tokens;
+  string work, command;
+  CmdMan::CmdRet cmdret;
+  Json::Value root;
+  std::unique_lock<std::mutex> ulock;
+
+  runmain = true;
+
+  while (!user) {
+    user = readline(getUserPrompt().c_str());
+    printMessage("Using user: " + string(user), error);
+  }
+  while (!pass) {
+    pass = readline(getPassPrompt().c_str());
+    printMessage("Using pass: " + string(pass), error);
+  }
+
+  printMessage("IoMan::run() login", debug);
+
+  localmutex.lock();
+  printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"), debug);
+  localinput.push_back("login " + string(user) + " " + string(pass));
+  localmutex.unlock();
+  printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"),
+               debug);
+  free(user);
+  free(pass);
+  localcv.notify_all();
+
+  ulock = std::unique_lock<std::mutex>(initmutex);
+  while (loginstatus == off) {
+    initcv.wait(ulock);
+  }
+  if (loginstatus == err)
+    return;
+  initcv.notify_all();
+
+  mainmutex.lock();
+  while (runmain) {
+    mainmutex.unlock();
+    free(line);
+
+    line = readline(getCmdPrompt().c_str());
+
+    if (!runmain)
+      break;
+
+    // if no input, do not add to history, and go to reading next line
+    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
+    if (tokens.size() < 1) {
+      continue;
+    }
+
+    // add the line to history
+    add_history(line);
+
+    localmutex.lock();
+    printMessage(string(__PRETTY_FUNCTION__) + string(" get localmutex"),
+                 debug);
+    localinput.push_back(line);
+    localmutex.unlock();
+    printMessage(string(__PRETTY_FUNCTION__) + string(" release localmutex"),
+                 debug);
+    localcv.notify_all();
+
+    if (!connected)
+      break;
+    mainmutex.lock();
+  }
+
+  free(line);
 }

+ 20 - 28
cli/src/machineioman.cpp

@@ -11,41 +11,33 @@
 using boost::asio::buffer;
 
 bool MachineIoMan::parseJson(Json::Value *root, string jsonstring) {
-	return false;
+  return false;
 }
 
-bool MachineIoMan::handleJson(Json::Value root) {
-	return false;
-}
+bool MachineIoMan::handleJson(Json::Value root) { return false; }
 
 void MachineIoMan::printMessage(std::string msg, OutMsgType type) {
-	switch(type) {
-		case normal: {
-			std::cout << msg << std::endl;
-			break;
-		}
-		case error: {
-			std::cout << msg << std::endl;
-			break;
-		}
-		case debug: {
-			std::cerr << msg << std::endl;
-			break;
-		}
-	}
+  switch (type) {
+  case normal: {
+    std::cout << msg << std::endl;
+    break;
+  }
+  case error: {
+    std::cout << msg << std::endl;
+    break;
+  }
+  case debug: {
+    std::cerr << msg << std::endl;
+    break;
+  }
+  }
 }
 
 void MachineIoMan::printWelcomeMessage() {
-	std::cout << "please enter user and password" << std::endl;
+  std::cout << "please enter user and password" << std::endl;
 }
 
-std::string MachineIoMan::getCmdPrompt() {
-	return "";
-}
+std::string MachineIoMan::getCmdPrompt() { return ""; }
 
-std::string MachineIoMan::getUserPrompt() {
-	return "";
-}
-std::string MachineIoMan::getPassPrompt() {
-	return "";
-}
+std::string MachineIoMan::getUserPrompt() { return ""; }
+std::string MachineIoMan::getPassPrompt() { return ""; }

+ 2 - 2
cli/src/main.cpp

@@ -67,8 +67,8 @@ int main(int argc, char **argv) {
   } else {
     ioman = new UserIoMan(argv[1]);
   }
-  if(ioman->init()) {
-	ioman->run();
+  if (ioman->init()) {
+    ioman->run();
   }
   delete ioman;
   std::printf("done\n");

+ 23 - 33
cli/src/userioman.cpp

@@ -8,49 +8,39 @@
 #include <readline/history.h>
 #include <readline/readline.h>
 
-#define BLOCKSIZE 8
-
 using boost::asio::buffer;
 
 bool UserIoMan::parseJson(Json::Value *root, string jsonstring) {
-	return false;
+  return false;
 }
 
-bool UserIoMan::handleJson(Json::Value root) {
-	return false;
-}
+bool UserIoMan::handleJson(Json::Value root) { return false; }
 
 void UserIoMan::printMessage(std::string msg, OutMsgType type) {
-	msgmutex.lock();
-	switch(type) {
-		case normal: {
-			std::cout << msg << std::endl;
-			break;
-		}
-		case error: {
-			std::cout << msg << std::endl;
-			break;
-		}
-		case debug: {
-			std::cerr << msg << std::endl;
-			break;
-		}
-	}
-	rl_redisplay();
-	msgmutex.unlock();
+  msgmutex.lock();
+  switch (type) {
+  case normal: {
+    std::cout << msg << std::endl;
+    break;
+  }
+  case error: {
+    std::cout << msg << std::endl;
+    break;
+  }
+  case debug: {
+    std::cerr << msg << std::endl;
+    break;
+  }
+  }
+  rl_redisplay();
+  msgmutex.unlock();
 }
 
 void UserIoMan::printWelcomeMessage() {
-	std::cout << "please enter user and password" << std::endl;
+  std::cout << "please enter user and password" << std::endl;
 }
 
-std::string UserIoMan::getCmdPrompt() {
-	return "ccats> ";
-}
+std::string UserIoMan::getCmdPrompt() { return "ccats> "; }
 
-std::string UserIoMan::getUserPrompt() {
-	return "User: ";
-}
-std::string UserIoMan::getPassPrompt() {
-	return "Pass: ";
-}
+std::string UserIoMan::getUserPrompt() { return "User: "; }
+std::string UserIoMan::getPassPrompt() { return "Pass: "; }

+ 1 - 1
gui/src/qmlhandler.cpp

@@ -94,7 +94,7 @@ void QMLHandler::readPipeLoop() {
     if (inPipeStatus.revents & POLLIN) {
       readOffset += read(inpipefd[0], buf + readOffset, 1);
 
-      if(buf[readOffset-1] == '\n') {
+      if (buf[readOffset - 1] == '\n') {
         pollCount = 10;
       } else {
         pollCount = 0;