cmdman.cpp 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. #include "../include/cmdman.h"
  2. #include "../include/global.h"
  3. #include <iostream>
  4. #define DEBUGPRINT(x) debugprintfunc(x)
  5. //~ #define DEBUGPRINT(x) std::cerr << x
  6. //~ #define DEBUGPRINT(x)
  7. CmdMan::CmdMan(FileMan &fm, void (*dpf)(string)) : fileman(fm) {
  8. /* setup json stuff */
  9. Json::CharReaderBuilder rbuilder;
  10. wbuilder.settings_["indentation"] = "";
  11. reader = rbuilder.newCharReader();
  12. currentState = connectionpossible;
  13. /* initialize execute command map */
  14. execmap["help"] = &CmdMan::cmdHelp;
  15. execmap["status"] = &CmdMan::cmdStatus;
  16. execmap["extendedstatus"] = &CmdMan::cmdExtendedstatus;
  17. execmap["disconnect"] = &CmdMan::cmdDisconnect;
  18. execmap["put"] = &CmdMan::cmdPut;
  19. execmap["get"] = &CmdMan::cmdGet;
  20. execmap["list"] = &CmdMan::cmdList;
  21. execmap["version"] = &CmdMan::cmdVersion;
  22. execmap["login"] = &CmdMan::cmdLogin;
  23. execmap["signup"] = &CmdMan::cmdSignup;
  24. execmap["putdata"] = &CmdMan::cmdPutdata;
  25. execmap["getdata"] = &CmdMan::cmdGetdata;
  26. execmap["listdata"] = &CmdMan::cmdListdata;
  27. execmap["head"] = &CmdMan::cmdHead;
  28. execmap["deletefile"] = &CmdMan::cmdDeletefile;
  29. execmap["deleteme"] = &CmdMan::cmdDeleteme;
  30. execmap["keyfile"] = &CmdMan::cmdKeyfile;
  31. execmap["closekey"] = &CmdMan::cmdClosekey;
  32. execmap["queue"] = &CmdMan::cmdQueue;
  33. execmap["dequeue"] = &CmdMan::cmdDequeue;
  34. execmap["notifications"] = &CmdMan::cmdNotifications;
  35. execmap["connect"] = &CmdMan::cmdConnect;
  36. execmap["exit"] = &CmdMan::cmdExit;
  37. /* initialize description map */
  38. helpmap["help"] = descHelp;
  39. helpmap["status"] = descStatus;
  40. helpmap["extendedstatus"] = descExtendedstatus;
  41. helpmap["disconnect"] = descDisconnect;
  42. helpmap["put"] = descPut;
  43. helpmap["get"] = descGet;
  44. helpmap["list"] = descList;
  45. helpmap["head"] = descHead;
  46. helpmap["login"] = descLogin;
  47. helpmap["signup"] = descSignup;
  48. helpmap["deletefile"] = descDeletefile;
  49. helpmap["deleteme"] = descDeleteme;
  50. helpmap["keyfile"] = descKeyfile;
  51. helpmap["closekey"] = descClosekey;
  52. helpmap["queue"] = descQueue;
  53. helpmap["dequeue"] = descDequeue;
  54. helpmap["notifications"] = descNotifications;
  55. helpmap["connect"] = descConnect;
  56. helpmap["exit"] = descExit;
  57. /* initialize handle command map */
  58. handlemap["status"] = &CmdMan::handleStatus;
  59. handlemap["extendedstatus"] = &CmdMan::handleExtendedstatus;
  60. handlemap["close"] = &CmdMan::handleClose;
  61. handlemap["put"] = &CmdMan::handlePut;
  62. handlemap["get"] = &CmdMan::handleGet;
  63. handlemap["putdata"] = &CmdMan::handlePutdata;
  64. handlemap["getdata"] = &CmdMan::handleGetdata;
  65. handlemap["list"] = &CmdMan::handleList;
  66. handlemap["version"] = &CmdMan::handleVersion;
  67. handlemap["login"] = &CmdMan::handleLogin;
  68. handlemap["signup"] = &CmdMan::handleSignup;
  69. handlemap["listdata"] = &CmdMan::handleListdata;
  70. handlemap["head"] = &CmdMan::handleHead;
  71. handlemap["deletefile"] = &CmdMan::handleDeletefile;
  72. handlemap["deleteme"] = &CmdMan::handleDeleteme;
  73. handlemap["queue"] = &CmdMan::handleQueue;
  74. handlemap["dequeue"] = &CmdMan::handleDequeue;
  75. handlemap["notifications"] = &CmdMan::handleNotifications;
  76. debugprintfunc = dpf;
  77. }
  78. CmdMan::~CmdMan() { delete reader; }
  79. void CmdMan::stateSetConnectionOk() { currentState = versionpossible; }
  80. CmdMan::CmdRet CmdMan::cmdHelp(vector<string> args) {
  81. CmdRet retval;
  82. Json::Value root, arr;
  83. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  84. map<string, string>::iterator it;
  85. root["command"] = "help";
  86. for (it = helpmap.begin(); it != helpmap.end(); it++) {
  87. arr.append(it->first + " - " + it->second);
  88. }
  89. root["names"] = arr;
  90. retval.type = print;
  91. retval.msg = root;
  92. return retval;
  93. }
  94. CmdMan::CmdRet CmdMan::cmdStatus(vector<string> args) {
  95. CmdRet retval;
  96. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  97. Json::Value root;
  98. root["command"] = "status";
  99. retval.type = send;
  100. retval.msg = root;
  101. return retval;
  102. }
  103. CmdMan::CmdRet CmdMan::cmdExtendedstatus(vector<string> args) {
  104. CmdRet retval;
  105. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  106. Json::Value root;
  107. root["command"] = "extendedstatus";
  108. retval.type = send;
  109. retval.msg = root;
  110. return retval;
  111. }
  112. CmdMan::CmdRet CmdMan::cmdDisconnect(vector<string> args) {
  113. CmdRet retval;
  114. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  115. Json::Value root;
  116. retval.type = send;
  117. if (currentState == loginpossible || currentState == disconnecttoexitearly) {
  118. // not logged in, send appropriate login message instead of normal close
  119. root["login"] = false;
  120. root["user"] = "";
  121. root["pass"] = "";
  122. root["cancel"] = true;
  123. retval.type |= close;
  124. if (currentState == disconnecttoexitearly) {
  125. retval.nextcommand = "exit";
  126. }
  127. currentState = connectionpossible;
  128. } else {
  129. root["command"] = "close";
  130. }
  131. retval.msg = root;
  132. return retval;
  133. }
  134. CmdMan::CmdRet CmdMan::cmdPut(vector<string> args) {
  135. CmdRet retval;
  136. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  137. Json::Value root;
  138. root["command"] = "put";
  139. if (args.size() < 1) {
  140. retval.type = error;
  141. root["accept"] = false;
  142. root["error"] = "not enough arguments, at least 1 argument required";
  143. } else {
  144. if (fileman.isPutting()) {
  145. retval.type = error;
  146. root["file"] = args[0];
  147. root["accept"] = false;
  148. root["error"] = "already putting file \"" + fileman.getPutName() + "\"";
  149. } else {
  150. bool opened = fileman.openPut(args[0]);
  151. if (opened) {
  152. root["file"] = fileman.getPutName();
  153. root["size"] = fileman.getPutSize();
  154. root["chunks"] = fileman.getPutChunks();
  155. retval.type = send;
  156. } else {
  157. retval.type = error;
  158. root["file"] = fileman.pathToFilename(args[0]);
  159. root["accept"] = false;
  160. root["error"] = "couldnt open local file \"" + args[0] + "\"";
  161. }
  162. }
  163. }
  164. retval.msg = root;
  165. return retval;
  166. }
  167. CmdMan::CmdRet CmdMan::cmdPutdata(vector<string> args) {
  168. CmdRet retval;
  169. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  170. Json::Value root;
  171. root["command"] = "putdata";
  172. if (!fileman.isPutting()) {
  173. root["error"] = "Client cannot handle input (received command \"putdata\").";
  174. retval.type = error;
  175. } else {
  176. root["file"] = fileman.getPutName();
  177. root["cancel"] = false;
  178. root["data"] = fileman.readBase64();
  179. root["remaining"] = fileman.getPutRemainingChunks(); // number already decremented by readBase64
  180. retval.type = send;
  181. }
  182. retval.msg = root;
  183. return retval;
  184. }
  185. CmdMan::CmdRet CmdMan::cmdGet(vector<string> args) {
  186. CmdRet retval;
  187. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  188. Json::Value root;
  189. root["command"] = "get";
  190. if (args.size() < 1) {
  191. retval.type = error;
  192. root["accept"] = false;
  193. root["error"] = "not enough arguments, at least 1 argument required";
  194. } else {
  195. if (fileman.isGetting()) {
  196. retval.type = error;
  197. root["file"] = args[0];
  198. root["accept"] = false;
  199. root["error"] = "already getting file \"" + fileman.getGetName() + "\"";
  200. } else {
  201. bool opened = fileman.openGet(args[0]);
  202. root["file"] = fileman.getGetName();
  203. if (opened) {
  204. root["file"] = fileman.getGetName();
  205. retval.type = send;
  206. } else {
  207. root["file"] = fileman.pathToFilename(args[0]);
  208. root["accept"] = false;
  209. root["error"] = "local file \"" + args[0] + "\" already exists";
  210. retval.type = error;
  211. }
  212. }
  213. }
  214. retval.msg = root;
  215. return retval;
  216. }
  217. CmdMan::CmdRet CmdMan::cmdGetdata(vector<string> args) {
  218. CmdRet retval;
  219. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  220. Json::Value root;
  221. root["command"] = "getdata";
  222. if (!fileman.isGetting()) {
  223. root["error"] = "Client cannot handle input (received command \"getdata\").";
  224. retval.type = error;
  225. } else {
  226. root["file"] = fileman.getGetName();
  227. root["chunk"] = fileman.getGetRemainingChunks();
  228. root["cancel"] = false;
  229. retval.type = send;
  230. }
  231. retval.msg = root;
  232. return retval;
  233. }
  234. CmdMan::CmdRet CmdMan::cmdList(vector<string> args) {
  235. CmdRet retval;
  236. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  237. Json::Value root;
  238. bool opened = fileman.openList();
  239. root["command"] = "list";
  240. if (opened) {
  241. retval.type = send;
  242. } else {
  243. retval.type = error;
  244. root["accept"] = false;
  245. root["names"] = "";
  246. root["error"] = "cannot list, already listing";
  247. }
  248. retval.msg = root;
  249. return retval;
  250. }
  251. CmdMan::CmdRet CmdMan::cmdListdata(vector<string> args) {
  252. CmdRet retval;
  253. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  254. Json::Value root;
  255. if (!fileman.isListing()) {
  256. root["command"] = "list";
  257. root["error"] = "Client cannot handle input (received command \"listdata\").";
  258. retval.type = error;
  259. } else {
  260. root["command"] = "listdata";
  261. root["chunk"] = fileman.getListRemainingChunks();
  262. root["cancel"] = false;
  263. retval.type = send;
  264. }
  265. retval.msg = root;
  266. return retval;
  267. }
  268. CmdMan::CmdRet CmdMan::cmdHead(vector<string> args) {
  269. CmdRet retval;
  270. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  271. Json::Value root;
  272. root["command"] = "head";
  273. if (args.size() < 1) {
  274. retval.type = error;
  275. root["accept"] = false;
  276. root["error"] = "not enough arguments, at least 1 argument required";
  277. } else {
  278. root["file"] = args[0];
  279. retval.type = send;
  280. }
  281. retval.msg = root;
  282. return retval;
  283. }
  284. CmdMan::CmdRet CmdMan::cmdDeletefile(vector<string> args) {
  285. CmdRet retval;
  286. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  287. Json::Value root;
  288. root["command"] = "deletefile";
  289. if (args.size() < 1) {
  290. retval.type = error;
  291. root["accept"] = false;
  292. root["error"] = "not enough arguments, at least 1 argument required";
  293. } else {
  294. root["file"] = args[0];
  295. retval.type = send;
  296. }
  297. retval.msg = root;
  298. return retval;
  299. }
  300. CmdMan::CmdRet CmdMan::cmdConnect(vector<string> args) {
  301. CmdRet retval;
  302. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  303. Json::Value root;
  304. root["command"] = "connect";
  305. if (args.size() < 1) {
  306. retval.type = error;
  307. root["error"] = "not enough arguments, at least 1 argument required";
  308. } else if (args.size() < 2) {
  309. retval.type = connect;
  310. root["address"] = args[0];
  311. root["port"] = 1234;
  312. } else {
  313. retval.type = connect;
  314. root["address"] = args[0];
  315. root["port"] = (unsigned int)stoul(args[1]);
  316. }
  317. retval.msg = root;
  318. return retval;
  319. }
  320. CmdMan::CmdRet CmdMan::execute(string cmd, vector<string> args) {
  321. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  322. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " using command \"" + cmd + "\" with arguments [ ");
  323. for (string s : args)
  324. DEBUGPRINT(s + " ");
  325. DEBUGPRINT("]");
  326. map<string, CmdRet (CmdMan::*)(vector<string>)>::iterator it = execmap.find(cmd);
  327. CmdRet retval;
  328. Json::Value root;
  329. root["command"] = cmd;
  330. if (it == execmap.end()) {
  331. retval.type = error;
  332. root["command"] = "error";
  333. root["error"] = string(__PRETTY_FUNCTION__) + " unknown command \"" + cmd + "\".\ntype help to list available commands.";
  334. retval.msg = root;
  335. return retval;
  336. } else if (!cmd.compare("help") || !cmd.compare("exit")) {
  337. // allow help and exit in all cases
  338. } else if (currentState == loginpossible || currentState == dologin || currentState == dosignup) {
  339. DEBUGPRINT("execute does login");
  340. DEBUGPRINT(string("comparison is ") +
  341. std::to_string(cmd.compare("login") && cmd.compare("signup") && cmd.compare("disconnect") && cmd.compare("help")));
  342. if (cmd.compare("login") && cmd.compare("signup") && cmd.compare("disconnect") && cmd.compare("help")) {
  343. retval.type = error;
  344. root["command"] = "error";
  345. root["error"] = string("Not logged in. Available commands are limited to ") + "login" + ", " + "signup" + " and " + "disconnect" + "\n" +
  346. "Use help for usage of these commands.";
  347. retval.msg = root;
  348. return retval;
  349. }
  350. } else if (currentState == versionpossible || currentState == doversion) {
  351. DEBUGPRINT("execute does version");
  352. DEBUGPRINT(string("comparison is ") + std::to_string(cmd.compare("version")));
  353. if (cmd.compare("version")) {
  354. retval.type = error;
  355. root["command"] = "error";
  356. root["error"] = string("Version not checked yet. No commands avalable.");
  357. retval.msg = root;
  358. return retval;
  359. }
  360. } else if (currentState == connectionpossible) {
  361. DEBUGPRINT("execute does connect");
  362. DEBUGPRINT(string("comparison is ") + std::to_string(cmd.compare("connect")));
  363. if (cmd.compare("version") && cmd.compare("connect")) {
  364. retval.type = error;
  365. root["command"] = "error";
  366. root["error"] = string("Not connected. Connect using \"connect ip [port]\".");
  367. retval.msg = root;
  368. return retval;
  369. }
  370. }
  371. return (this->*(execmap[cmd]))(args);
  372. }
  373. CmdMan::CmdRet CmdMan::cmdDeleteme(vector<string> args) {
  374. CmdRet retval;
  375. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  376. Json::Value root;
  377. root["command"] = "deleteme";
  378. if (args.size() < 1) {
  379. retval.type = error;
  380. root["accept"] = false;
  381. root["error"] = "not enough arguments, at least 1 argument required";
  382. } else {
  383. retval.type = send;
  384. root["pass"] = args[0];
  385. }
  386. retval.msg = root;
  387. return retval;
  388. }
  389. CmdMan::CmdRet CmdMan::cmdKeyfile(vector<string> args) {
  390. CmdRet retval;
  391. Json::Value root;
  392. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  393. root["command"] = "keyfile";
  394. if (args.size() < 1) {
  395. retval.type = error;
  396. root["accept"] = false;
  397. root["error"] = "not enough arguments, at least 1 argument required";
  398. } else {
  399. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " haveargs");
  400. if (!fileman.openKey(args[0])) {
  401. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " openkey fail");
  402. root["accept"] = false;
  403. root["file"] = args[0];
  404. root["error"] = string("couldnt open keyfile, openssl reports: ") + fileman.getOpensslError();
  405. retval.type = error;
  406. } else {
  407. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " openkey good");
  408. root["accept"] = true;
  409. root["file"] = args[0];
  410. retval.type = print;
  411. }
  412. }
  413. retval.msg = root;
  414. return retval;
  415. }
  416. CmdMan::CmdRet CmdMan::cmdClosekey(vector<string> args) {
  417. CmdRet retval;
  418. Json::Value root;
  419. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  420. root["command"] = "closekey";
  421. if (!fileman.closeKey()) {
  422. root["accept"] = false;
  423. root["error"] = "couldnt close keyfile. ensure no put or get is running";
  424. retval.type = error;
  425. } else {
  426. root["accept"] = true;
  427. retval.type = print;
  428. }
  429. retval.msg = root;
  430. return retval;
  431. }
  432. CmdMan::CmdRet CmdMan::cmdExit(vector<string> args) {
  433. CmdRet retval;
  434. Json::Value root;
  435. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  436. root["command"] = "exit";
  437. if (currentState != connectionpossible) {
  438. // we are connected, disconnect first
  439. retval.nextcommand = "disconnect";
  440. if (currentState == loginpossible)
  441. currentState = disconnecttoexitearly;
  442. else
  443. currentState = disconnecttoexit;
  444. retval.type = none;
  445. } else {
  446. retval.type = exit;
  447. }
  448. retval.msg = root;
  449. return retval;
  450. }
  451. /* login and signup commands */
  452. CmdMan::CmdRet CmdMan::cmdLogin(vector<string> args) {
  453. CmdRet retval;
  454. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  455. Json::Value root;
  456. if (args.size() < 2) {
  457. retval.type = error;
  458. root["command"] = "login";
  459. root["accept"] = false;
  460. root["error"] = "not enough arguments, at least 2 argument required";
  461. } else {
  462. if (currentState == loginpossible) {
  463. currentState = dologin;
  464. root["user"] = args[0];
  465. root["pass"] = args[1];
  466. root["login"] = true;
  467. root["cancel"] = false;
  468. retval.type = send;
  469. } else {
  470. root["command"] = "login";
  471. root["error"] = "Login not possible, because you already requested a login "
  472. "or you are logged in";
  473. root["accept"] = false;
  474. retval.type = error;
  475. }
  476. }
  477. retval.msg = root;
  478. return retval;
  479. }
  480. CmdMan::CmdRet CmdMan::cmdSignup(vector<string> args) {
  481. CmdRet retval;
  482. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  483. Json::Value root;
  484. if (args.size() < 2) {
  485. retval.type = error;
  486. root["command"] = "signup";
  487. root["accept"] = false;
  488. root["error"] = "not enough arguments, at least 2 argument required";
  489. } else {
  490. if (currentState == loginpossible) {
  491. currentState = dosignup;
  492. root["user"] = args[0];
  493. root["pass"] = args[1];
  494. root["login"] = false;
  495. root["cancel"] = false;
  496. retval.type = send;
  497. } else {
  498. root["command"] = "signup";
  499. root["error"] = "Signup not possible, because you already requested a "
  500. "login or you are logged in";
  501. root["accept"] = false;
  502. retval.type = error;
  503. }
  504. }
  505. retval.msg = root;
  506. return retval;
  507. }
  508. CmdMan::CmdRet CmdMan::cmdQueue(vector<string> args) {
  509. CmdRet retval;
  510. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  511. Json::Value root;
  512. root["command"] = "queue";
  513. if (args.size() < 1) {
  514. retval.type = error;
  515. root["accept"] = false;
  516. root["error"] = "not enough arguments, at least 1 argument required";
  517. } else {
  518. root["file"] = args[0];
  519. retval.type = send;
  520. }
  521. retval.msg = root;
  522. return retval;
  523. }
  524. CmdMan::CmdRet CmdMan::cmdDequeue(vector<string> args) {
  525. CmdRet retval;
  526. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  527. Json::Value root;
  528. root["command"] = "dequeue";
  529. if (args.size() < 1) {
  530. retval.type = error;
  531. root["accept"] = false;
  532. root["error"] = "not enough arguments, at least 1 argument required";
  533. } else {
  534. root["file"] = args[0];
  535. retval.type = send;
  536. }
  537. retval.msg = root;
  538. return retval;
  539. }
  540. /* internal commands */
  541. CmdMan::CmdRet CmdMan::cmdVersion(vector<string> args) {
  542. CmdRet retval;
  543. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  544. Json::Value root;
  545. if (currentState == versionpossible) {
  546. root["major"] = protocolMajorVersion;
  547. root["minor"] = protocolMinorVersion;
  548. retval.type = send;
  549. currentState = doversion;
  550. } else {
  551. retval.type = error;
  552. root["command"] = "error";
  553. root["error"] = "Executing version command not possible. Type help to list available commands.";
  554. }
  555. retval.msg = root;
  556. return retval;
  557. }
  558. CmdMan::CmdRet CmdMan::cmdNotifications(vector<string> args) {
  559. CmdRet retval;
  560. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  561. Json::Value root;
  562. root["command"] = "notifications";
  563. retval.type = send;
  564. retval.msg = root;
  565. return retval;
  566. }
  567. CmdMan::CmdRet CmdMan::handle(Json::Value root) {
  568. CmdRet retval;
  569. Json::Value output;
  570. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  571. if (currentState == doversion)
  572. root["command"] = "version";
  573. else if (currentState == dosignup)
  574. root["command"] = "signup";
  575. else if (currentState == dologin)
  576. root["command"] = "login";
  577. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " using json\n" + Json::writeString(wbuilder, root) + "\n");
  578. string retmsg;
  579. map<string, CmdRet (CmdMan::*)(Json::Value)>::iterator it = handlemap.find(root["command"].asString());
  580. if (it == handlemap.end()) {
  581. retval.type = error;
  582. output["command"] = "error";
  583. output["error"] = string(__PRETTY_FUNCTION__) + " unknown command \"" + root["command"].asString() + "\".\nEnsure code is implemented.";
  584. retval.msg = output;
  585. return retval;
  586. }
  587. return (this->*(handlemap[root["command"].asString()]))(root);
  588. }
  589. CmdMan::CmdRet CmdMan::handleStatus(Json::Value root) {
  590. CmdRet retval;
  591. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  592. retval.type = print;
  593. retval.msg = root;
  594. return retval;
  595. }
  596. CmdMan::CmdRet CmdMan::handleExtendedstatus(Json::Value root) {
  597. CmdRet retval;
  598. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  599. if (!root["accept"].asBool()) {
  600. retval.type = error;
  601. } else {
  602. retval.type = print;
  603. }
  604. retval.msg = root;
  605. return retval;
  606. }
  607. CmdMan::CmdRet CmdMan::handleClose(Json::Value root) {
  608. CmdRet retval;
  609. Json::Value output;
  610. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  611. output["command"] = "disconnect";
  612. output["accept"] = true;
  613. retval.type = close | print;
  614. retval.msg = output;
  615. if (currentState == disconnecttoexit) {
  616. retval.nextcommand = "exit";
  617. }
  618. currentState = connectionpossible;
  619. return retval;
  620. }
  621. CmdMan::CmdRet CmdMan::handlePut(Json::Value root) {
  622. CmdRet retval;
  623. Json::Value output;
  624. output["command"] = "put";
  625. output["file"] = fileman.getPutName();
  626. output["accept"] = false;
  627. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  628. if (!root["accept"].asBool()) {
  629. retval.type = error;
  630. output["error"] = "Server reports: " + root["error"].asString();
  631. fileman.cancelPut();
  632. } else if (!fileman.isPutting()) {
  633. retval.type = error;
  634. output["error"] = "Server responds to put message which was never sent.";
  635. } else if (root["file"].asString() != fileman.getPutName()) {
  636. retval.type = error;
  637. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getPutName();
  638. fileman.cancelPut();
  639. } else {
  640. output["accept"] = true;
  641. output["error"] = "";
  642. retval.type = print | send;
  643. retval.nextcommand = "putdata";
  644. }
  645. retval.msg = output;
  646. return retval;
  647. }
  648. CmdMan::CmdRet CmdMan::handlePutdata(Json::Value root) {
  649. CmdRet retval;
  650. Json::Value output;
  651. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  652. output["command"] = "putdata";
  653. output["file"] = fileman.getPutName();
  654. output["speed"] = 0.0f; // TODO
  655. output["cancel"] = true;
  656. if (root["cancel"].asBool()) {
  657. retval.type = error;
  658. output["error"] = "Server reports: " + root["error"].asString();
  659. fileman.cancelPut();
  660. } else if (!fileman.isPutting()) {
  661. retval.type = error;
  662. output["error"] = "Server responds to put message which was never sent.";
  663. } else if (root["received"].asInt() != fileman.getPutRemainingChunks()) {
  664. // the number of remaining chunks received from the daemon does not equal
  665. // the number stored at the client side
  666. retval.type = error;
  667. output["error"] = std::string("Server reports number of "
  668. "remaining chunks as ") +
  669. std::to_string(root["received"].asInt()) + " but actual number is " + std::to_string(fileman.getPutRemainingChunks());
  670. fileman.cancelPut();
  671. } else if (root["file"].asString() != fileman.getPutName()) {
  672. retval.type = error;
  673. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getPutName();
  674. fileman.cancelPut();
  675. } else {
  676. output["cancel"] = false;
  677. output["error"] = "";
  678. // sent successfully
  679. if (!root["received"].asInt()) {
  680. // everything sent
  681. retval.type = print;
  682. // TODO
  683. //~ retval.msg = "succesfully uploaded file " + fileman.getPutName();
  684. fileman.closePut();
  685. } else {
  686. retval.type = print | send;
  687. retval.nextcommand = "putdata";
  688. }
  689. }
  690. retval.msg = output;
  691. return retval;
  692. }
  693. CmdMan::CmdRet CmdMan::handleGet(Json::Value root) {
  694. CmdRet retval;
  695. Json::Value output;
  696. output["command"] = "get";
  697. output["file"] = fileman.getGetName();
  698. output["accept"] = false;
  699. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  700. if (!root["accept"].asBool()) {
  701. retval.type = error;
  702. output["error"] = "Server reports: " + root["error"].asString();
  703. fileman.cancelGet();
  704. } else if (!fileman.isGetting()) {
  705. retval.type = error;
  706. output["error"] = "Server responds to get message which was never sent.";
  707. } else if (root["file"].asString() != fileman.getGetName()) {
  708. retval.type = error;
  709. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getGetName();
  710. fileman.cancelGet();
  711. } else {
  712. fileman.setGetChunks(root["chunks"].asInt());
  713. output["accept"] = true;
  714. output["error"] = "";
  715. retval.type = print | send;
  716. retval.nextcommand = "getdata";
  717. }
  718. retval.msg = output;
  719. return retval;
  720. }
  721. CmdMan::CmdRet CmdMan::handleGetdata(Json::Value root) {
  722. CmdRet retval;
  723. Json::Value output;
  724. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  725. output["command"] = "getdata";
  726. output["file"] = fileman.getGetName();
  727. output["speed"] = 0.0f; // TODO
  728. output["cancel"] = true;
  729. if (root["cancel"].asBool()) {
  730. retval.type = error;
  731. output["error"] = "Server reports: " + root["error"].asString();
  732. fileman.cancelGet();
  733. } else if (!fileman.isGetting()) {
  734. retval.type = error;
  735. output["error"] = "Server responds to get message which was never sent.";
  736. } else if (root["remaining"].asInt() != fileman.getGetRemainingChunks()) {
  737. retval.type = error;
  738. output["error"] = std::string("Server reports number of remaining chunks as ") + std::to_string(root["remaining"].asInt()) + " but actual number is " +
  739. std::to_string(fileman.getGetRemainingChunks());
  740. fileman.cancelGet();
  741. } else if (root["file"].asString() != fileman.getGetName()) {
  742. retval.type = error;
  743. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getGetName();
  744. fileman.cancelGet();
  745. } else {
  746. output["cancel"] = false;
  747. output["error"] = "";
  748. fileman.writeBase64(root["data"].asString());
  749. // loaded successfully
  750. if (!root["remaining"].asInt()) {
  751. // everything received
  752. retval.type = print;
  753. //~ retval.msg = "succesfully downloaded file " + fileman.getGetName();
  754. fileman.closeGet();
  755. } else {
  756. retval.type = print | send;
  757. retval.nextcommand = "getdata";
  758. }
  759. }
  760. retval.msg = output;
  761. return retval;
  762. }
  763. CmdMan::CmdRet CmdMan::handleList(Json::Value root) {
  764. CmdRet retval;
  765. Json::Value output; // LOCALOUTPUT
  766. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  767. output["command"] = "list";
  768. output["names"] = "";
  769. if (!root["accept"].asBool()) {
  770. retval.type = error;
  771. output["accept"] = false;
  772. output["error"] = "Server reports: " + root["error"].asString();
  773. fileman.cancelList();
  774. } else if (root["items"].asInt() == 0) {
  775. retval.type = print;
  776. output["accept"] = false;
  777. output["error"] = "There are no files stored on the server.";
  778. fileman.closeList();
  779. } else if (!fileman.isListing()) {
  780. retval.type = error;
  781. output["accept"] = false;
  782. output["error"] = "Server responds to list message which was never sent.";
  783. } else {
  784. fileman.setListChunks(root["chunks"].asInt());
  785. retval.type = send;
  786. output["accept"] = true;
  787. retval.nextcommand = "listdata";
  788. }
  789. retval.msg = output;
  790. return retval;
  791. }
  792. CmdMan::CmdRet CmdMan::handleListdata(Json::Value root) {
  793. CmdRet retval;
  794. Json::Value output, arr;
  795. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  796. vector<string> toadd;
  797. output["command"] = "list";
  798. output["names"] = "";
  799. output["accept"] = false;
  800. if (root["cancel"].asBool()) {
  801. retval.type = error;
  802. output["error"] = "Server reports: " + root["error"].asString();
  803. fileman.cancelList();
  804. } else if (!fileman.isListing()) {
  805. retval.type = error;
  806. output["error"] = "Server responds to list message which was never sent.";
  807. } else if (root["remaining"].asInt() != fileman.getListRemainingChunks()) {
  808. // the passed number of recieved chunks should equal the number of sent chunks
  809. retval.type = error;
  810. output["error"] = std::string("Server reports number of "
  811. "remaining chunks as ") +
  812. std::to_string(root["remaining"].asInt()) + " but actual number is " + std::to_string(fileman.getListRemainingChunks());
  813. fileman.cancelList();
  814. } else {
  815. output["accept"] = true;
  816. for (Json::Value i : root["names"])
  817. toadd.push_back(i.asString());
  818. fileman.putListData(toadd);
  819. // loaded successfully
  820. if (root["remaining"] <= 0) {
  821. // everything sent
  822. retval.type = print;
  823. for (string s : fileman.getListData())
  824. arr.append(s);
  825. output["names"] = arr;
  826. fileman.closeList();
  827. } else {
  828. retval.type = send;
  829. retval.nextcommand = "listdata";
  830. }
  831. }
  832. retval.msg = output;
  833. return retval;
  834. }
  835. CmdMan::CmdRet CmdMan::handleVersion(Json::Value root) {
  836. CmdRet retval;
  837. Json::Value output; // LOCALOUTPUT
  838. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  839. output["command"] = "version";
  840. output["serverversion"] = std::to_string(root["major"].asInt()) + "." + std::to_string(root["minor"].asInt());
  841. output["clientversion"] = std::to_string(protocolMajorVersion) + "." + std::to_string(protocolMinorVersion);
  842. if (!root["accept"].asBool()) {
  843. retval.type = error | close;
  844. output["accept"] = false;
  845. currentState = connectionpossible;
  846. } else {
  847. retval.type = print;
  848. output["accept"] = true;
  849. currentState = loginpossible;
  850. }
  851. retval.msg = output;
  852. return retval;
  853. }
  854. CmdMan::CmdRet CmdMan::handleLogin(Json::Value root) {
  855. CmdRet retval;
  856. Json::Value output; // LOCALOUTPUT
  857. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  858. output["command"] = "login";
  859. if (!root["accept"].asBool()) {
  860. retval.type = error | close;
  861. output["error"] = root["error"].asString();
  862. output["accept"] = false;
  863. currentState = connectionpossible;
  864. } else {
  865. retval.type = print;
  866. output["error"] = "";
  867. output["accept"] = true;
  868. currentState = normal;
  869. }
  870. retval.msg = output;
  871. return retval;
  872. }
  873. CmdMan::CmdRet CmdMan::handleSignup(Json::Value root) {
  874. CmdRet retval;
  875. Json::Value output; // LOCALOUTPUT
  876. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  877. output["command"] = "signup";
  878. if (!root["accept"].asBool()) {
  879. retval.type = error;
  880. output["error"] = root["error"].asString();
  881. output["accept"] = false;
  882. currentState = loginpossible;
  883. } else {
  884. retval.type = print;
  885. output["error"] = "";
  886. output["accept"] = true;
  887. currentState = normal;
  888. }
  889. retval.msg = output;
  890. return retval;
  891. }
  892. CmdMan::CmdRet CmdMan::handleHead(Json::Value root) {
  893. CmdRet retval;
  894. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  895. if (!root["accept"].asBool()) {
  896. Json::Value output;
  897. output["command"] = "head";
  898. output["file"] = root["file"];
  899. output["error"] = "Server reports: " + root["error"].asString();
  900. output["accept"] = false;
  901. retval.type = error;
  902. retval.msg = output;
  903. } else {
  904. retval.type = print;
  905. retval.msg = root;
  906. }
  907. return retval;
  908. }
  909. CmdMan::CmdRet CmdMan::handleDeletefile(Json::Value root) {
  910. CmdRet retval;
  911. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  912. if (!root["accept"].asBool()) {
  913. Json::Value output;
  914. output["command"] = "deletefile";
  915. output["file"] = root["file"];
  916. output["error"] = "Server reports: " + root["error"].asString();
  917. output["accept"] = false;
  918. retval.type = error;
  919. retval.msg = output;
  920. } else {
  921. retval.type = print;
  922. retval.msg = root;
  923. }
  924. return retval;
  925. }
  926. CmdMan::CmdRet CmdMan::handleDeleteme(Json::Value root) {
  927. CmdRet retval;
  928. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  929. if (!root["accept"].asBool()) {
  930. retval.type = error;
  931. } else {
  932. retval.type = close | print;
  933. currentState = connectionpossible;
  934. }
  935. retval.msg = root;
  936. return retval;
  937. }
  938. CmdMan::CmdRet CmdMan::handleQueue(Json::Value root) {
  939. CmdRet retval;
  940. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  941. if (root["accept"].asBool()) {
  942. retval.type = print;
  943. } else {
  944. retval.type = error;
  945. }
  946. retval.msg = root;
  947. return retval;
  948. }
  949. CmdMan::CmdRet CmdMan::handleDequeue(Json::Value root) {
  950. CmdRet retval;
  951. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  952. if (root["accept"].asBool()) {
  953. retval.type = print;
  954. } else {
  955. retval.type = error;
  956. }
  957. retval.msg = root;
  958. return retval;
  959. }
  960. CmdMan::CmdRet CmdMan::handleNotifications(Json::Value root) {
  961. CmdRet retval;
  962. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  963. if (root["accept"].asBool()) {
  964. retval.type = print;
  965. } else {
  966. retval.type = error;
  967. }
  968. retval.msg = root;
  969. return retval;
  970. }