123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- #include "../include/userioman.h"
- #include <iostream>
- #include <readline/readline.h>
- #include <vector>
- UserIoMan::UserIoMan(bool usessl, bool beverbose) : IoMan(usessl) {
- /* setup json stuff */
- Json::CharReaderBuilder rbuilder;
- wbuilder.settings_["indentation"] = "";
- reader = rbuilder.newCharReader();
- verbose = beverbose;
- /* initialize print command map */
- printmap["error"] = &UserIoMan::printError;
- printmap["connect"] = &UserIoMan::printConnect;
- printmap["help"] = &UserIoMan::printHelp;
- printmap["extendedstatus"] = &UserIoMan::printExtendedstatus;
- printmap["status"] = &UserIoMan::printStatus;
- printmap["disconnect"] = &UserIoMan::printDisconnect;
- printmap["put"] = &UserIoMan::printPut;
- printmap["get"] = &UserIoMan::printGet;
- printmap["list"] = &UserIoMan::printList;
- printmap["extendedlist"] = &UserIoMan::printExtendedlist;
- printmap["version"] = &UserIoMan::printVersion;
- printmap["login"] = &UserIoMan::printLogin;
- printmap["signup"] = &UserIoMan::printSignup;
- printmap["putdata"] = &UserIoMan::printPutdata;
- printmap["getdata"] = &UserIoMan::printGetdata;
- printmap["head"] = &UserIoMan::printHead;
- printmap["deletefile"] = &UserIoMan::printDeletefile;
- printmap["deleteme"] = &UserIoMan::printDeleteme;
- printmap["queue"] = &UserIoMan::printQueue;
- printmap["dequeue"] = &UserIoMan::printDequeue;
- printmap["keyfile"] = &UserIoMan::printKeyfile;
- printmap["closekey"] = &UserIoMan::printClosekey;
- printmap["notifications"] = &UserIoMan::printNotifications;
- }
- UserIoMan::~UserIoMan() { delete reader; }
- void UserIoMan::printMessage(std::string msg, OutMsgType type) {
- Json::Value root;
- msgmutex.lock();
- char *savedline = rl_copy_text(0, rl_end);
- int savedpoint = rl_point;
- rl_set_prompt("");
- rl_replace_line("", 0);
- rl_redisplay();
- switch (type) {
- case normal:
- case error: {
- // this should never happen outside of development
- if (!reader->parse(msg.c_str(), msg.c_str() + msg.size(), &root, &jsonerror)) {
- printMessage(string(__PRETTY_FUNCTION__) + " couldnt parse json data: " + jsonerror, debug);
- } else {
- printJson(root);
- }
- break;
- }
- case debug: {
- if (verbose)
- std::cerr << msg << std::endl;
- break;
- }
- }
- rl_set_prompt(getCmdPrompt().c_str());
- rl_replace_line(savedline, 0);
- rl_point = savedpoint;
- rl_redisplay();
- free(savedline);
- msgmutex.unlock();
- }
- void UserIoMan::printWelcomeMessage() {
- std::cout << "please login by entering \"login <username> <password>\" \nor "
- "sign up and log in with \"signup <username> <password>\""
- << std::endl;
- }
- std::string UserIoMan::getCmdPrompt() { return "ccats> "; }
- void UserIoMan::printJson(Json::Value root) {
- map<string, void (UserIoMan::*)(Json::Value)>::iterator it = printmap.find(root["command"].asString());
- if (it == printmap.end()) {
- // this should never happen outside of development
- printMessage(string(__PRETTY_FUNCTION__) + " unknown command \"" + root["command"].asString() + "\".\nensure code is implemented.", debug);
- return;
- }
- (this->*(printmap[root["command"].asString()]))(root);
- }
- void UserIoMan::printError(Json::Value root) { std::cout << "Error: " << root["error"].asString() << std::endl; }
- void UserIoMan::printConnect(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Couldnt connect to " << root["address"].asString() << ":" << root["port"].asUInt() << std::endl
- << "Reason: " << root["error"].asString() << std::endl;
- }
- }
- void UserIoMan::printHelp(Json::Value root) {
- std::cout << "Available commands are: " << std::endl;
- for (Json::Value i : root["names"])
- std::cout << i.asString() << std::endl;
- }
- void UserIoMan::printStatus(Json::Value root) { std::cout << "Server reports status: " << root["response"].asString() << std::endl; }
- void UserIoMan::printExtendedstatus(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Listing transfers failed. Server reports: " << root["error"].asString() << std::endl;
- } else {
- if (!root["transfersclientserver"].empty()) {
- std::cout << std::endl << "Transfers between clients and server:" << std::endl;
- /*
- * EXAMPLE:
- * type progress file
- * download 99% foobar.txt
- * upload 1% baz.html
- */
- std::cout << "type progress file" << std::endl;
- for (Json::Value val : root["transfersclientserver"]) {
- std::string type = val["upload"].asBool() ? "upload" : "download";
- std::string progress = std::to_string(val["progress"].asInt());
- std::string file = val["file"].asString();
- char output[21];
- std::snprintf(output, 21, "%-8s %7.7s%% ", type.c_str(), progress.c_str());
- std::cout << output << file << std::endl;
- }
- }
- if (!root["transfersserverserver"].empty()) {
- std::cout << std::endl << "Transfers between different servers:" << std::endl;
- /*
- * EXAMPLE:
- * type progress method bytes/sec file
- * download 99% method0000001 9000.01 foobar.txt
- * queued 1% urgent field 42.00 baz.html
- *
- * Too long method strings get truncated, unexpectedly high speeds are shown (with less pretty format), e.g.:
- *
- * download 95% too long stri 340282346638528859811704183484516925440.00 filename.zip
- */
- std::cout << "type progress method bytes/sec file" << std::endl;
- for (Json::Value val : root["transfersserverserver"]) {
- std::string type = val["type"].asString();
- std::string progress = std::to_string(val["progress"].asInt());
- std::string method = val["method"].asString();
- float speed = val["speed"].asFloat();
- std::string file = val["file"].asString();
- // size of 80 is just enough for maximum possible float value to fit as string
- char output[80];
- std::snprintf(output, 80, "%-8s %7.7s%% %-13.13s %15.2f ", type.c_str(), progress.c_str(), method.c_str(), speed);
- std::cout << output << file << std::endl;
- }
- }
- if (root["transfersclientserver"].empty() && root["transfersserverserver"].empty()) {
- std::cout << "No transfers running." << std::endl;
- } else {
- std::cout << std::endl;
- }
- }
- }
- void UserIoMan::printDisconnect(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Disconnect failed." << std::endl;
- } else {
- std::cout << "Disconnect successful." << std::endl;
- }
- }
- void UserIoMan::printPut(Json::Value root) {
- if (!root["accept"].asBool()) {
- if (root.isMember("file")) {
- std::cout << "Upload request for file " << root["file"].asString() << " failed: " << root["error"].asString() << std::endl;
- } else {
- std::cout << "Upload request failed: " << root["error"].asString() << std::endl;
- }
- } else
- std::cout << "Begin uploading file " << root["file"].asString() << std::endl;
- }
- void UserIoMan::printGet(Json::Value root) {
- if (!root["accept"].asBool()) {
- if (root.isMember("file")) {
- std::cout << "Download request for file " << root["file"].asString() << " failed: " << root["error"].asString() << std::endl;
- } else {
- std::cout << "Download request failed: " << root["error"].asString() << std::endl;
- }
- } else
- std::cout << "Begin downloading file " << root["file"].asString() << std::endl;
- }
- void UserIoMan::printList(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Listing files failed: " << root["error"].asString() << std::endl;
- } else {
- std::cout << "Listing files stored on server: " << std::endl;
- for (Json::Value i : root["names"])
- std::cout << i.asString() << std::endl;
- std::cout << "End of list." << std::endl;
- }
- }
- void UserIoMan::printExtendedlist(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Listing files failed: " << root["error"].asString() << std::endl;
- } else {
- if (!root["files"].empty()) {
- std::cout << "Files stored on server: " << std::endl;
- /*
- * EXAMPLE:
- * size (kBytes) decryptable file
- * 9000.01 yes foo.txt
- * 42.00 no baz.html
- * 0.02 plaintext bar.zip
- */
- std::cout << "size (kBytes) decryptable file" << std::endl;
- for (Json::Value val : root["files"]) {
- float size = val["size"].asFloat();
- std::string encrypted = val["encrypted"].asString();
- std::string decryptable;
- if (encrypted == "decryptable") {
- decryptable = "\033[32myes\033[0m "; // "yes" in green
- } else if (encrypted == "undecryptable") {
- decryptable = "\033[31mno\033[0m "; // "no" in red
- } else if (encrypted == "unknown") {
- decryptable = "unknown "; // "no" in red
- } else {
- decryptable = "plaintext ";
- }
- std::string progress = std::to_string(val["progress"].asInt());
- std::string file = val["name"].asString();
- char sizeString[44];
- std::snprintf(sizeString, 44, "%13.2f ", size);
- std::cout << sizeString << decryptable << file << std::endl;
- }
- } else {
- std::cout << "No files stored on server." << std::endl;
- }
- }
- }
- void UserIoMan::printVersion(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Version check failed. Server reports " << root["serverversion"].asString() << " but client is " << root["clientversion"].asString()
- << std::endl;
- } else
- std::cout << "Version check ok." << std::endl;
- }
- void UserIoMan::printLogin(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Login failed: " << root["error"].asString() << std::endl;
- } else
- std::cout << "Login ok." << std::endl;
- }
- void UserIoMan::printSignup(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Signup failed: " << root["error"].asString() << std::endl;
- } else
- std::cout << "Signup ok. You are now logged in." << std::endl;
- }
- void UserIoMan::printDeleteme(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "User deletion failed: " << root["error"].asString() << std::endl;
- } else
- std::cout << "User deletion ok. You are now disconnected from the server." << std::endl;
- }
- void UserIoMan::printPutdata(Json::Value root) {}
- void UserIoMan::printGetdata(Json::Value root) {}
- void UserIoMan::printListdata(Json::Value root) {}
- void UserIoMan::printHead(Json::Value root) {
- if (!root["accept"].asBool())
- std::cout << "Request of the first four bytes failed. " << root["error"].asString() << std::endl;
- else
- std::cout << "First four bytes of file " << root["file"].asString() << " are: " << root["data"].asString() << std::endl;
- }
- void UserIoMan::printDeletefile(Json::Value root) {
- if (!root["accept"].asBool())
- std::cout << "Deletion of file " << root["file"] << " failed. " << root["error"].asString() << std::endl;
- else
- std::cout << "File " << root["file"] << " deleted succesfully" << std::endl;
- }
- void UserIoMan::printKeyfile(Json::Value root) {
- if (!root["accept"].asBool())
- std::cout << "Couldnt select keyfile " << root["file"].asString() << ": " << root["error"].asString() << std::endl;
- else
- std::cout << "Using keyfile " << root["file"].asString() << std::endl;
- }
- void UserIoMan::printClosekey(Json::Value root) {
- if (!root["accept"].asBool())
- std::cout << "Failed to close key: " << root["error"].asString() << std::endl;
- else
- std::cout << "Key closed." << std::endl;
- }
- void UserIoMan::printQueue(Json::Value root) {
- if (!root["accept"].asBool())
- std::cout << "Queueing of file " << root["file"] << " failed. " << root["error"].asString() << std::endl;
- else
- std::cout << "File " << root["file"] << " queued succesfully" << std::endl;
- }
- void UserIoMan::printDequeue(Json::Value root) {
- if (!root["accept"].asBool())
- std::cout << "Dequeueing of file " << root["file"] << " failed. " << root["error"].asString() << std::endl;
- else
- std::cout << "File " << root["file"] << " dequeued succesfully" << std::endl;
- }
- void UserIoMan::printNotifications(Json::Value root) {
- if (!root["accept"].asBool()) {
- std::cout << "Failed to get notifications: " << root["error"].asString() << std::endl;
- } else {
- std::cout << "New notifications:" << std::endl;
- for (Json::Value i : root["messages"])
- std::cout << "\033[94m" << i.asString() << std::endl;
- std::cout << "\033[0m " << std::endl;
- }
- }
|