cmdman.cpp 34 KB

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