cmdman.cpp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  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. cmdmutex.lock();
  366. map<string, CmdRet (CmdMan::*)(vector<string>)>::iterator execit = execmap.find(cmd);
  367. vector<string>::const_iterator alwaysit;
  368. vector<string>::const_iterator connectit;
  369. for (alwaysit = cmdAllowAlways.cbegin(); alwaysit != cmdAllowAlways.cend(); alwaysit++)
  370. if (*alwaysit == cmd)
  371. break;
  372. for (connectit = cmdAllowAfterConnect.cbegin(); connectit != cmdAllowAfterConnect.cend(); connectit++)
  373. if (*connectit == cmd)
  374. break;
  375. CmdRet retval;
  376. Json::Value root;
  377. root["command"] = cmd;
  378. if (execit == execmap.end()) {
  379. retval.type = error;
  380. root["command"] = "error";
  381. root["error"] = string(__PRETTY_FUNCTION__) + " unknown command \"" + cmd + "\".\ntype help to list available commands.";
  382. retval.msg = root;
  383. cmdmutex.unlock();
  384. return retval;
  385. } else if (alwaysit != cmdAllowAlways.cend()) {
  386. // Command should be usable in all cases
  387. } else if (currentState == loginpossible || currentState == dologin || currentState == dosignup) {
  388. DEBUGPRINT("execute does login");
  389. DEBUGPRINT(string("cmd is in usable commands ") + std::to_string(connectit != cmdAllowAfterConnect.end()));
  390. if (connectit == cmdAllowAfterConnect.cend()) {
  391. // Command was NOT in list of usable commands after login
  392. string allowedCommands;
  393. for (string s : cmdAllowAlways)
  394. allowedCommands += s + " ";
  395. for (string s : cmdAllowAfterConnect)
  396. allowedCommands += s + " ";
  397. retval.type = error;
  398. root["command"] = "error";
  399. root["error"] = string("Not logged in. Available commands are limited to ") + allowedCommands + "\n" + "Use help for usage of these commands.";
  400. retval.msg = root;
  401. cmdmutex.unlock();
  402. return retval;
  403. }
  404. } else if (currentState == versionpossible || currentState == doversion) {
  405. DEBUGPRINT("execute does version");
  406. DEBUGPRINT(string("comparison is ") + std::to_string(cmd.compare("version")));
  407. if (cmd.compare("version")) {
  408. retval.type = error;
  409. root["command"] = "error";
  410. root["error"] = string("Version not checked yet. No commands avalable.");
  411. retval.msg = root;
  412. cmdmutex.unlock();
  413. return retval;
  414. }
  415. } else if (currentState == connectionpossible) {
  416. DEBUGPRINT("execute does connect");
  417. DEBUGPRINT(string("comparison is ") + std::to_string(cmd.compare("connect")));
  418. if (cmd.compare("version") && cmd.compare("connect")) {
  419. retval.type = error;
  420. root["command"] = "error";
  421. root["error"] = string("Not connected. Connect using \"connect ip [port]\".");
  422. retval.msg = root;
  423. cmdmutex.unlock();
  424. return retval;
  425. }
  426. }
  427. retval = (this->*(execmap[cmd]))(args);
  428. cmdmutex.unlock();
  429. return retval;
  430. }
  431. CmdMan::CmdRet CmdMan::cmdDeleteme(vector<string> args) {
  432. CmdRet retval;
  433. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  434. Json::Value root;
  435. root["command"] = "deleteme";
  436. if (args.size() < 1) {
  437. retval.type = error;
  438. root["accept"] = false;
  439. root["error"] = "not enough arguments, at least 1 argument required";
  440. } else {
  441. retval.type = send;
  442. root["pass"] = args[0];
  443. }
  444. retval.msg = root;
  445. return retval;
  446. }
  447. CmdMan::CmdRet CmdMan::cmdKeyfile(vector<string> args) {
  448. CmdRet retval;
  449. Json::Value root;
  450. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  451. root["command"] = "keyfile";
  452. if (args.size() < 1) {
  453. retval.type = error;
  454. root["accept"] = false;
  455. root["error"] = "not enough arguments, at least 1 argument required";
  456. } else {
  457. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " haveargs");
  458. if (!fileman.openKey(args[0])) {
  459. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " openkey fail");
  460. root["accept"] = false;
  461. root["file"] = args[0];
  462. root["error"] = string("couldnt open keyfile, openssl reports: ") + fileman.getOpensslError();
  463. retval.type = error;
  464. } else {
  465. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " openkey good");
  466. root["accept"] = true;
  467. root["file"] = args[0];
  468. retval.type = print;
  469. }
  470. }
  471. retval.msg = root;
  472. return retval;
  473. }
  474. CmdMan::CmdRet CmdMan::cmdClosekey(vector<string> args) {
  475. CmdRet retval;
  476. Json::Value root;
  477. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  478. root["command"] = "closekey";
  479. if (!fileman.closeKey()) {
  480. root["accept"] = false;
  481. root["error"] = "couldnt close keyfile. ensure no put or get is running";
  482. retval.type = error;
  483. } else {
  484. root["accept"] = true;
  485. retval.type = print;
  486. }
  487. retval.msg = root;
  488. return retval;
  489. }
  490. CmdMan::CmdRet CmdMan::cmdExit(vector<string> args) {
  491. CmdRet retval;
  492. Json::Value root;
  493. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  494. root["command"] = "exit";
  495. if (currentState != connectionpossible) {
  496. // we are connected, disconnect first
  497. retval.nextcommand = "disconnect";
  498. if (currentState == loginpossible)
  499. currentState = disconnecttoexitearly;
  500. else
  501. currentState = disconnecttoexit;
  502. retval.type = none;
  503. } else {
  504. retval.type = exit;
  505. }
  506. retval.msg = root;
  507. return retval;
  508. }
  509. /* login and signup commands */
  510. CmdMan::CmdRet CmdMan::cmdLogin(vector<string> args) {
  511. CmdRet retval;
  512. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  513. Json::Value root;
  514. if (args.size() < 2) {
  515. retval.type = error;
  516. root["command"] = "login";
  517. root["accept"] = false;
  518. root["error"] = "not enough arguments, at least 2 argument required";
  519. } else {
  520. if (currentState == loginpossible) {
  521. currentState = dologin;
  522. root["user"] = args[0];
  523. root["pass"] = args[1];
  524. root["login"] = true;
  525. root["cancel"] = false;
  526. retval.type = send;
  527. } else {
  528. root["command"] = "login";
  529. root["error"] = "Login not possible, because you already requested a login "
  530. "or you are logged in";
  531. root["accept"] = false;
  532. retval.type = error;
  533. }
  534. }
  535. retval.msg = root;
  536. return retval;
  537. }
  538. CmdMan::CmdRet CmdMan::cmdSignup(vector<string> args) {
  539. CmdRet retval;
  540. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  541. Json::Value root;
  542. if (args.size() < 2) {
  543. retval.type = error;
  544. root["command"] = "signup";
  545. root["accept"] = false;
  546. root["error"] = "not enough arguments, at least 2 argument required";
  547. } else {
  548. if (currentState == loginpossible) {
  549. currentState = dosignup;
  550. root["user"] = args[0];
  551. root["pass"] = args[1];
  552. root["login"] = false;
  553. root["cancel"] = false;
  554. retval.type = send;
  555. } else {
  556. root["command"] = "signup";
  557. root["error"] = "Signup not possible, because you already requested a "
  558. "login or you are logged in";
  559. root["accept"] = false;
  560. retval.type = error;
  561. }
  562. }
  563. retval.msg = root;
  564. return retval;
  565. }
  566. CmdMan::CmdRet CmdMan::cmdQueue(vector<string> args) {
  567. CmdRet retval;
  568. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  569. Json::Value root;
  570. root["command"] = "queue";
  571. if (args.size() < 1) {
  572. retval.type = error;
  573. root["accept"] = false;
  574. root["error"] = "not enough arguments, at least 1 argument required";
  575. } else {
  576. root["file"] = args[0];
  577. retval.type = send;
  578. }
  579. retval.msg = root;
  580. return retval;
  581. }
  582. CmdMan::CmdRet CmdMan::cmdDequeue(vector<string> args) {
  583. CmdRet retval;
  584. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  585. Json::Value root;
  586. root["command"] = "dequeue";
  587. if (args.size() < 1) {
  588. retval.type = error;
  589. root["accept"] = false;
  590. root["error"] = "not enough arguments, at least 1 argument required";
  591. } else {
  592. root["file"] = args[0];
  593. retval.type = send;
  594. }
  595. retval.msg = root;
  596. return retval;
  597. }
  598. /* internal commands */
  599. CmdMan::CmdRet CmdMan::cmdVersion(vector<string> args) {
  600. CmdRet retval;
  601. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  602. Json::Value root;
  603. if (currentState == versionpossible) {
  604. root["major"] = protocolMajorVersion;
  605. root["minor"] = protocolMinorVersion;
  606. retval.type = send;
  607. currentState = doversion;
  608. } else {
  609. retval.type = error;
  610. root["command"] = "error";
  611. root["error"] = "Executing version command not possible. Type help to list available commands.";
  612. }
  613. retval.msg = root;
  614. return retval;
  615. }
  616. CmdMan::CmdRet CmdMan::cmdNotifications(vector<string> args) {
  617. CmdRet retval;
  618. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  619. Json::Value root;
  620. root["command"] = "notifications";
  621. retval.type = send;
  622. retval.msg = root;
  623. return retval;
  624. }
  625. CmdMan::CmdRet CmdMan::handle(Json::Value root) {
  626. CmdRet retval;
  627. Json::Value output;
  628. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  629. cmdmutex.lock();
  630. if (currentState == doversion)
  631. root["command"] = "version";
  632. else if (currentState == dosignup)
  633. root["command"] = "signup";
  634. else if (currentState == dologin)
  635. root["command"] = "login";
  636. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " using json\n" + Json::writeString(wbuilder, root) + "\n");
  637. string retmsg;
  638. map<string, CmdRet (CmdMan::*)(Json::Value)>::iterator it = handlemap.find(root["command"].asString());
  639. if (it == handlemap.end()) {
  640. retval.type = error;
  641. output["command"] = "error";
  642. output["error"] = string(__PRETTY_FUNCTION__) + " unknown command \"" + root["command"].asString() + "\".\nEnsure code is implemented.";
  643. retval.msg = output;
  644. cmdmutex.unlock();
  645. return retval;
  646. }
  647. retval = (this->*(handlemap[root["command"].asString()]))(root);
  648. cmdmutex.unlock();
  649. return retval;
  650. }
  651. CmdMan::CmdRet CmdMan::handleStatus(Json::Value root) {
  652. CmdRet retval;
  653. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  654. retval.type = print;
  655. retval.msg = root;
  656. return retval;
  657. }
  658. CmdMan::CmdRet CmdMan::handleExtendedstatus(Json::Value root) {
  659. CmdRet retval;
  660. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  661. if (!root["accept"].asBool()) {
  662. retval.type = error;
  663. } else {
  664. retval.type = print;
  665. }
  666. retval.msg = root;
  667. return retval;
  668. }
  669. CmdMan::CmdRet CmdMan::handleClose(Json::Value root) {
  670. CmdRet retval;
  671. Json::Value output;
  672. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  673. output["command"] = "disconnect";
  674. output["accept"] = true;
  675. retval.type = close | print;
  676. retval.msg = output;
  677. if (currentState == disconnecttoexit) {
  678. retval.nextcommand = "exit";
  679. }
  680. currentState = connectionpossible;
  681. return retval;
  682. }
  683. CmdMan::CmdRet CmdMan::handlePut(Json::Value root) {
  684. CmdRet retval;
  685. Json::Value output;
  686. output["command"] = "put";
  687. output["file"] = fileman.getPutName();
  688. output["accept"] = false;
  689. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  690. if (!root["accept"].asBool()) {
  691. retval.type = error;
  692. output["error"] = "Server reports: " + root["error"].asString();
  693. fileman.cancelPut();
  694. } else if (!fileman.isPutting()) {
  695. retval.type = error;
  696. output["error"] = "Server responds to put message which was never sent.";
  697. } else if (root["file"].asString() != fileman.getPutName()) {
  698. retval.type = error;
  699. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getPutName();
  700. fileman.cancelPut();
  701. } else {
  702. output["accept"] = true;
  703. output["error"] = "";
  704. retval.type = print | send;
  705. retval.nextcommand = "putdata";
  706. }
  707. retval.msg = output;
  708. return retval;
  709. }
  710. CmdMan::CmdRet CmdMan::handlePutdata(Json::Value root) {
  711. CmdRet retval;
  712. Json::Value output;
  713. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  714. output["command"] = "putdata";
  715. output["file"] = fileman.getPutName();
  716. output["speed"] = 0.0f; // TODO
  717. output["cancel"] = true;
  718. if (root["cancel"].asBool()) {
  719. retval.type = error;
  720. output["error"] = "Server reports: " + root["error"].asString();
  721. fileman.cancelPut();
  722. } else if (!fileman.isPutting()) {
  723. retval.type = error;
  724. output["error"] = "Server responds to put message which was never sent.";
  725. } else if (root["received"].asInt() != fileman.getPutRemainingChunks()) {
  726. // the number of remaining chunks received from the daemon does not equal
  727. // the number stored at the client side
  728. retval.type = error;
  729. output["error"] = std::string("Server reports number of "
  730. "remaining chunks as ") +
  731. std::to_string(root["received"].asInt()) + " but actual number is " + std::to_string(fileman.getPutRemainingChunks());
  732. fileman.cancelPut();
  733. } else if (root["file"].asString() != fileman.getPutName()) {
  734. retval.type = error;
  735. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getPutName();
  736. fileman.cancelPut();
  737. } else {
  738. output["cancel"] = false;
  739. output["error"] = "";
  740. // sent successfully
  741. if (!root["received"].asInt()) {
  742. // everything sent
  743. retval.type = print;
  744. // TODO
  745. //~ retval.msg = "succesfully uploaded file " + fileman.getPutName();
  746. fileman.closePut();
  747. } else {
  748. retval.type = print | send;
  749. retval.nextcommand = "putdata";
  750. }
  751. }
  752. retval.msg = output;
  753. return retval;
  754. }
  755. CmdMan::CmdRet CmdMan::handleGet(Json::Value root) {
  756. CmdRet retval;
  757. Json::Value output;
  758. output["command"] = "get";
  759. output["file"] = fileman.getGetName();
  760. output["accept"] = false;
  761. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  762. if (!root["accept"].asBool()) {
  763. retval.type = error;
  764. output["error"] = "Server reports: " + root["error"].asString();
  765. fileman.cancelGet();
  766. } else if (!fileman.isGetting()) {
  767. retval.type = error;
  768. output["error"] = "Server responds to get message which was never sent.";
  769. } else if (root["file"].asString() != fileman.getGetName()) {
  770. retval.type = error;
  771. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getGetName();
  772. fileman.cancelGet();
  773. } else {
  774. fileman.setGetChunks(root["chunks"].asInt());
  775. output["accept"] = true;
  776. output["error"] = "";
  777. retval.type = print | send;
  778. retval.nextcommand = "getdata";
  779. }
  780. retval.msg = output;
  781. return retval;
  782. }
  783. CmdMan::CmdRet CmdMan::handleGetdata(Json::Value root) {
  784. CmdRet retval;
  785. Json::Value output;
  786. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  787. output["command"] = "getdata";
  788. output["file"] = fileman.getGetName();
  789. output["speed"] = 0.0f; // TODO
  790. output["cancel"] = true;
  791. if (root["cancel"].asBool()) {
  792. retval.type = error;
  793. output["error"] = "Server reports: " + root["error"].asString();
  794. fileman.cancelGet();
  795. } else if (!fileman.isGetting()) {
  796. retval.type = error;
  797. output["error"] = "Server responds to get message which was never sent.";
  798. } else if (root["remaining"].asInt() != fileman.getGetRemainingChunks()) {
  799. retval.type = error;
  800. output["error"] = std::string("Server reports number of remaining chunks as ") + std::to_string(root["remaining"].asInt()) + " but actual number is " +
  801. std::to_string(fileman.getGetRemainingChunks());
  802. fileman.cancelGet();
  803. } else if (root["file"].asString() != fileman.getGetName()) {
  804. retval.type = error;
  805. output["error"] = "Server reports filename " + root["file"].asString() + " but actual filename is " + fileman.getGetName();
  806. fileman.cancelGet();
  807. } else {
  808. output["cancel"] = false;
  809. output["error"] = "";
  810. fileman.writeBase64(root["data"].asString());
  811. // loaded successfully
  812. if (!root["remaining"].asInt()) {
  813. // everything received
  814. retval.type = print;
  815. //~ retval.msg = "succesfully downloaded file " + fileman.getGetName();
  816. fileman.closeGet();
  817. } else {
  818. retval.type = print | send;
  819. retval.nextcommand = "getdata";
  820. }
  821. }
  822. retval.msg = output;
  823. return retval;
  824. }
  825. CmdMan::CmdRet CmdMan::handleList(Json::Value root) {
  826. CmdRet retval;
  827. Json::Value output; // LOCALOUTPUT
  828. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  829. output["command"] = "list";
  830. output["names"] = "";
  831. if (!root["accept"].asBool()) {
  832. retval.type = error;
  833. output["accept"] = false;
  834. output["error"] = "Server reports: " + root["error"].asString();
  835. fileman.cancelList();
  836. } else if (root["items"].asInt() == 0) {
  837. retval.type = print;
  838. output["accept"] = false;
  839. output["error"] = "There are no files stored on the server.";
  840. fileman.closeList();
  841. } else if (!fileman.isListingSimple()) {
  842. retval.type = error;
  843. output["accept"] = false;
  844. output["error"] = "Server responds to list message which was never sent.";
  845. } else {
  846. fileman.setListChunks(root["chunks"].asInt());
  847. retval.type = send;
  848. output["accept"] = true;
  849. retval.nextcommand = "listdata";
  850. }
  851. retval.msg = output;
  852. return retval;
  853. }
  854. CmdMan::CmdRet CmdMan::handleListdata(Json::Value root) {
  855. CmdRet retval;
  856. Json::Value output, arr;
  857. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  858. vector<Json::Value> toadd;
  859. output["command"] = "list";
  860. output["names"] = "";
  861. output["accept"] = false;
  862. if (root["cancel"].asBool()) {
  863. retval.type = error;
  864. output["error"] = "Server reports: " + root["error"].asString();
  865. fileman.cancelList();
  866. } else if (!fileman.isListingSimple()) {
  867. retval.type = error;
  868. output["error"] = "Server responds to list message which was never sent.";
  869. } else if (root["remaining"].asInt() != fileman.getListRemainingChunks()) {
  870. // the passed number of recieved chunks should equal the number of sent chunks
  871. retval.type = error;
  872. output["error"] = std::string("Server reports number of "
  873. "remaining chunks as ") +
  874. std::to_string(root["remaining"].asInt()) + " but actual number is " + std::to_string(fileman.getListRemainingChunks());
  875. fileman.cancelList();
  876. } else {
  877. output["accept"] = true;
  878. for (Json::Value i : root["names"])
  879. toadd.push_back(i);
  880. fileman.putListData(toadd);
  881. // loaded successfully
  882. if (root["remaining"] <= 0) {
  883. // everything sent
  884. retval.type = print;
  885. for (Json::Value s : fileman.getListData())
  886. arr.append(s.asString());
  887. output["names"] = arr;
  888. fileman.closeList();
  889. } else {
  890. retval.type = send;
  891. retval.nextcommand = "listdata";
  892. }
  893. }
  894. retval.msg = output;
  895. return retval;
  896. }
  897. CmdMan::CmdRet CmdMan::handleExtendedlist(Json::Value root) {
  898. CmdRet retval;
  899. Json::Value output, files; // LOCALOUTPUT
  900. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  901. output["command"] = "extendedlist";
  902. output["files"] = files;
  903. if (!root["accept"].asBool()) {
  904. retval.type = error;
  905. output["accept"] = false;
  906. output["error"] = "Server reports: " + root["error"].asString();
  907. fileman.cancelList();
  908. } else if (root["items"].asInt() == 0) {
  909. retval.type = print;
  910. output["accept"] = false;
  911. output["error"] = "There are no files stored on the server.";
  912. fileman.closeList();
  913. } else if (!fileman.isListingExtended()) {
  914. retval.type = error;
  915. output["accept"] = false;
  916. output["error"] = "Server responds to list message which was never sent.";
  917. } else {
  918. fileman.setListChunks(root["chunks"].asInt());
  919. retval.type = send;
  920. output["accept"] = true;
  921. retval.nextcommand = "extendedlistdata";
  922. }
  923. retval.msg = output;
  924. return retval;
  925. }
  926. CmdMan::CmdRet CmdMan::handleExtendedlistdata(Json::Value root) {
  927. CmdRet retval;
  928. Json::Value output, arr, files;
  929. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  930. vector<Json::Value> toadd;
  931. output["command"] = "extendedlist";
  932. output["files"] = files;
  933. output["accept"] = false;
  934. if (root["cancel"].asBool()) {
  935. retval.type = error;
  936. output["error"] = "Server reports: " + root["error"].asString();
  937. fileman.cancelList();
  938. } else if (!fileman.isListingExtended()) {
  939. retval.type = error;
  940. output["error"] = "Server responds to list message which was never sent.";
  941. } else if (root["remaining"].asInt() != fileman.getListRemainingChunks()) {
  942. // the passed number of recieved chunks should equal the number of sent chunks
  943. retval.type = error;
  944. output["error"] = std::string("Server reports number of "
  945. "remaining chunks as ") +
  946. std::to_string(root["remaining"].asInt()) + " but actual number is " + std::to_string(fileman.getListRemainingChunks());
  947. fileman.cancelList();
  948. } else {
  949. output["accept"] = true;
  950. for (Json::Value i : root["files"])
  951. toadd.push_back(i);
  952. fileman.putListData(toadd);
  953. // loaded successfully
  954. if (root["remaining"] <= 0) {
  955. // everything sent
  956. retval.type = print;
  957. for (Json::Value s : fileman.getListData())
  958. arr.append(s);
  959. output["files"] = arr;
  960. fileman.closeList();
  961. } else {
  962. retval.type = send;
  963. retval.nextcommand = "extendedlistdata";
  964. }
  965. }
  966. retval.msg = output;
  967. return retval;
  968. }
  969. CmdMan::CmdRet CmdMan::handleVersion(Json::Value root) {
  970. CmdRet retval;
  971. Json::Value output; // LOCALOUTPUT
  972. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  973. output["command"] = "version";
  974. output["serverversion"] = std::to_string(root["major"].asInt()) + "." + std::to_string(root["minor"].asInt());
  975. output["clientversion"] = std::to_string(protocolMajorVersion) + "." + std::to_string(protocolMinorVersion);
  976. if (!root["accept"].asBool()) {
  977. retval.type = error | close;
  978. output["accept"] = false;
  979. currentState = connectionpossible;
  980. } else {
  981. retval.type = print;
  982. output["accept"] = true;
  983. currentState = loginpossible;
  984. }
  985. retval.msg = output;
  986. return retval;
  987. }
  988. CmdMan::CmdRet CmdMan::handleLogin(Json::Value root) {
  989. CmdRet retval;
  990. Json::Value output; // LOCALOUTPUT
  991. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  992. output["command"] = "login";
  993. if (!root["accept"].asBool()) {
  994. retval.type = error | close;
  995. output["error"] = root["error"].asString();
  996. output["accept"] = false;
  997. currentState = connectionpossible;
  998. } else {
  999. retval.type = print;
  1000. output["error"] = "";
  1001. output["accept"] = true;
  1002. currentState = normal;
  1003. }
  1004. retval.msg = output;
  1005. return retval;
  1006. }
  1007. CmdMan::CmdRet CmdMan::handleSignup(Json::Value root) {
  1008. CmdRet retval;
  1009. Json::Value output; // LOCALOUTPUT
  1010. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  1011. output["command"] = "signup";
  1012. if (!root["accept"].asBool()) {
  1013. retval.type = error;
  1014. output["error"] = root["error"].asString();
  1015. output["accept"] = false;
  1016. currentState = loginpossible;
  1017. } else {
  1018. retval.type = print;
  1019. output["error"] = "";
  1020. output["accept"] = true;
  1021. currentState = normal;
  1022. }
  1023. retval.msg = output;
  1024. return retval;
  1025. }
  1026. CmdMan::CmdRet CmdMan::handleHead(Json::Value root) {
  1027. CmdRet retval;
  1028. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  1029. if (!root["accept"].asBool()) {
  1030. Json::Value output;
  1031. output["command"] = "head";
  1032. output["file"] = root["file"];
  1033. output["error"] = "Server reports: " + root["error"].asString();
  1034. output["accept"] = false;
  1035. retval.type = error;
  1036. retval.msg = output;
  1037. } else {
  1038. retval.type = print;
  1039. retval.msg = root;
  1040. }
  1041. return retval;
  1042. }
  1043. CmdMan::CmdRet CmdMan::handleDeletefile(Json::Value root) {
  1044. CmdRet retval;
  1045. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  1046. if (!root["accept"].asBool()) {
  1047. Json::Value output;
  1048. output["command"] = "deletefile";
  1049. output["file"] = root["file"];
  1050. output["error"] = "Server reports: " + root["error"].asString();
  1051. output["accept"] = false;
  1052. retval.type = error;
  1053. retval.msg = output;
  1054. } else {
  1055. retval.type = print;
  1056. retval.msg = root;
  1057. }
  1058. return retval;
  1059. }
  1060. CmdMan::CmdRet CmdMan::handleDeleteme(Json::Value root) {
  1061. CmdRet retval;
  1062. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  1063. if (!root["accept"].asBool()) {
  1064. retval.type = error;
  1065. } else {
  1066. retval.type = close | print;
  1067. currentState = connectionpossible;
  1068. }
  1069. retval.msg = root;
  1070. return retval;
  1071. }
  1072. CmdMan::CmdRet CmdMan::handleQueue(Json::Value root) {
  1073. CmdRet retval;
  1074. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  1075. if (root["accept"].asBool()) {
  1076. retval.type = print;
  1077. } else {
  1078. retval.type = error;
  1079. }
  1080. retval.msg = root;
  1081. return retval;
  1082. }
  1083. CmdMan::CmdRet CmdMan::handleDequeue(Json::Value root) {
  1084. CmdRet retval;
  1085. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  1086. if (root["accept"].asBool()) {
  1087. retval.type = print;
  1088. } else {
  1089. retval.type = error;
  1090. }
  1091. retval.msg = root;
  1092. return retval;
  1093. }
  1094. CmdMan::CmdRet CmdMan::handleNotifications(Json::Value root) {
  1095. CmdRet retval;
  1096. DEBUGPRINT(string(__PRETTY_FUNCTION__) + " begin");
  1097. if (root["accept"].asBool()) {
  1098. retval.type = print;
  1099. } else {
  1100. retval.type = error;
  1101. }
  1102. retval.msg = root;
  1103. return retval;
  1104. }