cmdman.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. #include "../include/cmdman.h"
  2. #include "../include/global.h"
  3. #include <iostream>
  4. CmdMan::CmdMan(FileMan &fm) : fileman(fm) {
  5. /* setup json stuff */
  6. Json::CharReaderBuilder rbuilder;
  7. wbuilder.settings_["indentation"] = "";
  8. reader = rbuilder.newCharReader();
  9. dologin = false;
  10. doversion = false;
  11. /* initialize execute command map */
  12. execmap["help"] = &CmdMan::cmdHelp;
  13. execmap["status"] = &CmdMan::cmdStatus;
  14. execmap["disconnect"] = &CmdMan::cmdDisconnect;
  15. execmap["put"] = &CmdMan::cmdPut;
  16. execmap["get"] = &CmdMan::cmdGet;
  17. execmap["list"] = &CmdMan::cmdList;
  18. execmap["version"] = &CmdMan::cmdVersion;
  19. execmap["login"] = &CmdMan::cmdLogin;
  20. execmap["putdata"] = &CmdMan::cmdPutdata;
  21. execmap["getdata"] = &CmdMan::cmdGetdata;
  22. /* initialize description map */
  23. helpmap["help"] = descHelp;
  24. helpmap["status"] = descStatus;
  25. helpmap["disconnect"] = descDisconnect;
  26. helpmap["put"] = descPut;
  27. helpmap["get"] = descGet;
  28. helpmap["list"] = descList;
  29. /* initialize handle command map */
  30. handlemap["status"] = &CmdMan::handleStatus;
  31. handlemap["close"] = &CmdMan::handleClose;
  32. handlemap["put"] = &CmdMan::handlePut;
  33. handlemap["get"] = &CmdMan::handleGet;
  34. handlemap["putdata"] = &CmdMan::handlePutdata;
  35. handlemap["getdata"] = &CmdMan::handleGetdata;
  36. handlemap["list"] = &CmdMan::handleList;
  37. handlemap["version"] = &CmdMan::handleVersion;
  38. handlemap["login"] = &CmdMan::handleLogin;
  39. }
  40. CmdMan::~CmdMan() { delete reader; }
  41. CmdMan::CmdRet CmdMan::cmdHelp(vector<string> args) {
  42. CmdRet retval;
  43. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  44. map<string, string>::iterator it;
  45. for (it = helpmap.begin(); it != helpmap.end(); it++) {
  46. retval.msg.append(it->first);
  47. retval.msg.append(" - ");
  48. retval.msg.append(it->second);
  49. retval.msg.append("\n");
  50. }
  51. retval.type = notsend;
  52. return retval;
  53. }
  54. CmdMan::CmdRet CmdMan::cmdStatus(vector<string> args) {
  55. CmdRet retval;
  56. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  57. Json::Value root;
  58. root["command"] = "status";
  59. retval.type = send;
  60. retval.msg = Json::writeString(wbuilder, root);
  61. return retval;
  62. }
  63. CmdMan::CmdRet CmdMan::cmdDisconnect(vector<string> args) {
  64. CmdRet retval;
  65. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  66. Json::Value root;
  67. root["command"] = "close";
  68. retval.type = send;
  69. retval.msg = Json::writeString(wbuilder, root);
  70. return retval;
  71. }
  72. CmdMan::CmdRet CmdMan::cmdPut(vector<string> args) {
  73. CmdRet retval;
  74. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  75. Json::Value root;
  76. bool opened = fileman.openPut(args[0]);
  77. if (opened) {
  78. root["command"] = "put";
  79. root["file"] = fileman.getPutName();
  80. root["size"] = fileman.getPutSize();
  81. root["chunks"] = fileman.getPutChunks();
  82. retval.type = send;
  83. retval.msg = Json::writeString(wbuilder, root);
  84. } else {
  85. retval.type = error;
  86. retval.msg = "couldnt open local file \"" + args[0] + "\"";
  87. }
  88. return retval;
  89. }
  90. CmdMan::CmdRet CmdMan::cmdPutdata(vector<string> args) {
  91. CmdRet retval;
  92. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  93. Json::Value root;
  94. root["command"] = "putdata";
  95. root["file"] = fileman.getPutName();
  96. root["cancel"] = false;
  97. root["data"] = fileman.readBase64();
  98. root["remaining"] =
  99. fileman
  100. .getPutRemainingChunks(); // number already decremented by readBase64
  101. retval.type = send;
  102. retval.msg = Json::writeString(wbuilder, root);
  103. return retval;
  104. }
  105. CmdMan::CmdRet CmdMan::cmdGet(vector<string> args) {
  106. CmdRet retval;
  107. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  108. Json::Value root;
  109. bool opened = fileman.openGet(args[0]);
  110. if (opened) {
  111. root["command"] = "get";
  112. root["file"] = fileman.getGetName();
  113. retval.type = send;
  114. retval.msg = Json::writeString(wbuilder, root);
  115. } else {
  116. retval.type = error;
  117. retval.msg = "local file \"" + args[0] + "\" already exists";
  118. }
  119. return retval;
  120. }
  121. CmdMan::CmdRet CmdMan::cmdGetdata(vector<string> args) {
  122. CmdRet retval;
  123. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  124. Json::Value root;
  125. root["command"] = "getdata";
  126. root["file"] = fileman.getGetName();
  127. root["chunk"] = fileman.getGetRemainingChunks();
  128. root["cancel"] = false;
  129. retval.type = send;
  130. retval.msg = Json::writeString(wbuilder, root);
  131. return retval;
  132. }
  133. CmdMan::CmdRet CmdMan::cmdList(vector<string> args) {
  134. CmdRet retval;
  135. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  136. Json::Value root;
  137. root["command"] = "list";
  138. retval.type = send;
  139. retval.msg = Json::writeString(wbuilder, root);
  140. return retval;
  141. }
  142. CmdMan::CmdRet CmdMan::cmdListdata(vector<string> args) {
  143. CmdRet retval;
  144. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  145. Json::Value root;
  146. root["command"] = "listdata";
  147. root["chunk"] = fileman.getListRemainingChunks();
  148. root["cancel"] = false;
  149. retval.type = send;
  150. retval.msg = Json::writeString(wbuilder, root);
  151. return retval;
  152. }
  153. CmdMan::CmdRet CmdMan::execute(string cmd, vector<string> args) {
  154. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  155. std::cerr << __PRETTY_FUNCTION__ << " using command \"" << cmd
  156. << "\" with arguments [ ";
  157. for (string s : args)
  158. std::cerr << s << " ";
  159. std::cerr << "]" << std::endl;
  160. map<string, CmdRet (CmdMan::*)(vector<string>)>::iterator it =
  161. execmap.find(cmd);
  162. string retmsg;
  163. if (it == execmap.end()) {
  164. return {error, string(__PRETTY_FUNCTION__) + " unknown command \"" + cmd +
  165. "\".\ntype help to list available commands."};
  166. }
  167. return (this->*(execmap[cmd]))(args);
  168. }
  169. /* internal commands */
  170. CmdMan::CmdRet CmdMan::cmdVersion(vector<string> args) {
  171. CmdRet retval;
  172. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  173. Json::Value root;
  174. root["version"] = protocolVersion;
  175. retval.type = send;
  176. retval.msg = Json::writeString(wbuilder, root);
  177. doversion = true;
  178. return retval;
  179. }
  180. CmdMan::CmdRet CmdMan::cmdLogin(vector<string> args) {
  181. CmdRet retval;
  182. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  183. Json::Value root;
  184. root["user"] = args[0];
  185. root["pass"] = args[1];
  186. root["login"] = true;
  187. root["cancel"] = false;
  188. retval.type = send;
  189. retval.msg = Json::writeString(wbuilder, root);
  190. dologin = true;
  191. return retval;
  192. }
  193. /*
  194. handlemap["status"] = &CmdMan::handleDefault;
  195. handlemap["disconnect"] = &CmdMan::handleDefault;
  196. handlemap["put"] = &CmdMan::handleDefault;
  197. handlemap["get"] = &CmdMan::handleDefault;
  198. handlemap["list"] = NULL;
  199. handlemap["version"] = NULL;
  200. handlemap["login"] = NULL;
  201. */
  202. CmdMan::CmdRet CmdMan::handle(Json::Value root) {
  203. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  204. if (doversion)
  205. root["command"] = "version";
  206. else if (dologin)
  207. root["command"] = "login";
  208. std::cerr << __PRETTY_FUNCTION__ << " using json" << std::endl
  209. << root << std::endl;
  210. string retmsg;
  211. map<string, CmdRet (CmdMan::*)(Json::Value)>::iterator it =
  212. handlemap.find(root["command"].asString());
  213. if (it == handlemap.end()) {
  214. return {error, string(__PRETTY_FUNCTION__) + " unknown command \"" +
  215. root["command"].asString() +
  216. "\".\nensure code is implemented."};
  217. }
  218. return (this->*(handlemap[root["command"].asString()]))(root);
  219. }
  220. CmdMan::CmdRet CmdMan::handleStatus(Json::Value root) {
  221. CmdRet retval;
  222. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  223. retval.type = notsend;
  224. retval.msg = root["response"].asString();
  225. return retval;
  226. }
  227. CmdMan::CmdRet CmdMan::handleClose(Json::Value root) {
  228. CmdRet retval;
  229. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  230. retval.type = close;
  231. retval.msg = root["response"].asString();
  232. return retval;
  233. }
  234. CmdMan::CmdRet CmdMan::handlePut(Json::Value root) {
  235. CmdRet retval;
  236. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  237. if (!root["accept"].asBool()) {
  238. retval.type = error;
  239. retval.msg = "File upload request failed: Server reports: " +
  240. root["error"].asString();
  241. } else if (root["file"].asString() != fileman.getPutName()) {
  242. retval.type = error;
  243. retval.msg = "File upload request failed: Server reports filename " +
  244. root["file"].asString() + " but actual filename is " +
  245. fileman.getPutName();
  246. } else {
  247. retval.type = send;
  248. retval.msg = "putdata";
  249. }
  250. return retval;
  251. }
  252. CmdMan::CmdRet CmdMan::handlePutdata(Json::Value root) {
  253. CmdRet retval;
  254. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  255. if (root["received"].asInt() != fileman.getPutRemainingChunks()) {
  256. // the number of remaining chunks received from the daemon does not equal
  257. // the number stored at the client side
  258. retval.type = error;
  259. retval.msg = std::string("File upload failed: Server reports number of "
  260. "remaining chunks as ") +
  261. std::to_string(root["received"].asInt()) +
  262. " but actual number is " +
  263. std::to_string(fileman.getPutRemainingChunks());
  264. fileman.cancelPut();
  265. } else if (root["cancel"].asBool()) {
  266. retval.type = error;
  267. retval.msg =
  268. "File upload cancelles: Server reports: " + root["error"].asString();
  269. fileman.cancelPut();
  270. } else if (root["file"].asString() != fileman.getPutName()) {
  271. retval.type = error;
  272. retval.msg = "File upload request failed: Server reports filename " +
  273. root["file"].asString() + " but actual filename is " +
  274. fileman.getPutName();
  275. fileman.cancelPut();
  276. } else {
  277. // sent successfully
  278. if (!root["received"].asInt()) {
  279. // everything sent
  280. retval.type = notsend;
  281. retval.msg = "succesfully uploaded file " + fileman.getPutName();
  282. fileman.closePut();
  283. } else {
  284. retval.type = send;
  285. retval.msg = "putdata";
  286. }
  287. }
  288. return retval;
  289. }
  290. CmdMan::CmdRet CmdMan::handleGet(Json::Value root) {
  291. CmdRet retval;
  292. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  293. if (!root["accept"].asBool()) {
  294. retval.type = error;
  295. retval.msg = "File download request failed: Server reports: " +
  296. root["error"].asString();
  297. } else if (root["file"].asString() != fileman.getGetName()) {
  298. retval.type = error;
  299. retval.msg = "File download request failed: Server reports filename " +
  300. root["file"].asString() + " but actual filename is " +
  301. fileman.getGetName();
  302. } else {
  303. fileman.setGetChunks(root["chunks"].asInt());
  304. retval.type = send;
  305. retval.msg = "getdata";
  306. }
  307. return retval;
  308. }
  309. CmdMan::CmdRet CmdMan::handleGetdata(Json::Value root) {
  310. CmdRet retval;
  311. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  312. // the passed number of recieved chunks should equal the number of sent chunks
  313. if (root["remaining"].asInt() != fileman.getGetRemainingChunks()) {
  314. retval.type = error;
  315. retval.msg = std::string("File download failed: Server reports number of "
  316. "remaining chunks as ") +
  317. std::to_string(root["remaining"].asInt()) +
  318. " but actual number is " +
  319. std::to_string(fileman.getGetRemainingChunks());
  320. fileman.cancelGet();
  321. } else if (root["cancel"].asBool()) {
  322. retval.type = error;
  323. retval.msg =
  324. "File download cancelled: Server reports: " + root["error"].asString();
  325. fileman.cancelGet();
  326. } else if (root["file"].asString() != fileman.getGetName()) {
  327. retval.type = error;
  328. retval.msg = "File download failed: Server reports filename " +
  329. root["file"].asString() + " but actual filename is " +
  330. fileman.getGetName();
  331. fileman.cancelGet();
  332. } else {
  333. fileman.writeBase64(root["data"].asString());
  334. // loaded successfully
  335. if (fileman.getGetRemainingChunks() < 0) {
  336. // everything sent
  337. retval.type = notsend;
  338. retval.msg = "succesfully downloaded file " + fileman.getGetName();
  339. fileman.closeGet();
  340. } else {
  341. retval.type = send;
  342. retval.msg = "getdata";
  343. }
  344. }
  345. return retval;
  346. }
  347. CmdMan::CmdRet CmdMan::handleList(Json::Value root) {
  348. CmdRet retval;
  349. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  350. if (!root["accept"].asBool()) {
  351. retval.type = error;
  352. retval.msg = "File listing request failed: Server reports: " +
  353. root["error"].asString();
  354. } else {
  355. fileman.setListChunks(root["chunks"].asInt());
  356. retval.type = send;
  357. retval.msg = "listdata";
  358. }
  359. return retval;
  360. }
  361. CmdMan::CmdRet CmdMan::handleListdata(Json::Value root) {
  362. CmdRet retval;
  363. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  364. vector<string> toadd;
  365. // the passed number of recieved chunks should equal the number of sent chunks
  366. if (root["remaining"].asInt() != fileman.getListRemainingChunks()) {
  367. retval.type = error;
  368. retval.msg = std::string("File listing failed: Server reports number of "
  369. "remaining chunks as ") +
  370. std::to_string(root["remaining"].asInt()) +
  371. " but actual number is " +
  372. std::to_string(fileman.getListRemainingChunks());
  373. fileman.cancelList();
  374. } else if (root["cancel"].asBool()) {
  375. retval.type = error;
  376. retval.msg =
  377. "File listing cancelled: Server reports: " + root["error"].asString();
  378. fileman.cancelList();
  379. } else {
  380. for (Json::Value i : root["names"])
  381. toadd.push_back(i.asString());
  382. fileman.putListData(toadd);
  383. // loaded successfully
  384. if (!fileman.getListRemainingChunks()) {
  385. // everything sent
  386. retval.type = notsend;
  387. retval.msg = "Files on server:\n";
  388. for (string s : fileman.getListData())
  389. retval.msg += s + "\n";
  390. fileman.closeList();
  391. } else {
  392. retval.type = send;
  393. retval.msg = "listdata";
  394. }
  395. }
  396. return retval;
  397. }
  398. CmdMan::CmdRet CmdMan::handleVersion(Json::Value root) {
  399. CmdRet retval;
  400. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  401. if (!root["accept"].asBool()) {
  402. retval.type = error;
  403. retval.msg = "Version check failed: Server reports " +
  404. root["version"].asString() + " but client is version " +
  405. protocolVersion;
  406. } else {
  407. retval.type = seton;
  408. retval.msg = "Version check ok.";
  409. doversion = false;
  410. }
  411. return retval;
  412. }
  413. CmdMan::CmdRet CmdMan::handleLogin(Json::Value root) {
  414. CmdRet retval;
  415. std::cerr << __PRETTY_FUNCTION__ << " begin" << std::endl;
  416. if (!root["accept"].asBool()) {
  417. retval.type = error;
  418. retval.msg = "Login failed: " + root["error"].asString();
  419. } else {
  420. retval.type = seton;
  421. retval.msg = "Login ok.";
  422. dologin = false;
  423. }
  424. return retval;
  425. }