PageRenderTime 65ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/dali/dfuplus/main.cpp

https://github.com/narpaldhillon/HPCC-Platform
C++ | 337 lines | 291 code | 26 blank | 20 comment | 47 complexity | 8645c5361d0fb729676f7b6f71a4ec3f MD5 | raw file
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #pragma warning (disable : 4786)
  15. #include <build-config.h>
  16. #include "daftcfg.hpp"
  17. #include "dfuerror.hpp"
  18. #include "dfuplus.hpp"
  19. #if defined( __linux__) || defined(__FreeBSD__)
  20. #include "termios.h"
  21. #endif
  22. void printVersion()
  23. {
  24. printf("DFU Version: %d %s\n", DAFT_VERSION, BUILD_TAG);
  25. }
  26. void handleSyntax()
  27. {
  28. StringBuffer out;
  29. out.append("Usage:\n");
  30. out.append(" dfuplus action=[spray|replicate|despray|copy|dkc|remove|rename|list|\n");
  31. out.append(" addsuper|removesuper|listsuper|copysuper|dafilesrv|\n");
  32. out.append(" savexml|add|status|abort|resubmit|monitor] {<options>}\n");
  33. out.append(" general options:\n");
  34. out.append(" server=<esp-server-url> \n");
  35. out.append(" username=<user-name>\n");
  36. out.append(" password=<password>\n");
  37. out.append(" overwrite=0|1\n");
  38. out.append(" replicate=1|0\n");
  39. out.append(" replicateoffset=N -- node relative offset to find replicate (default 1)\n");
  40. out.append(" partlist=<part-list> -- for one or more parts \n");
  41. out.append(" @filename -- read options from filename \n");
  42. out.append(" nowait=0|1 -- return immediately without waiting for completion.\n");
  43. out.append(" connect=<nn> -- restrict to nn connections at a time.\n");
  44. out.append(" transferbuffersize=<n> -- use buffer of size n bytes when transferring data.\n");
  45. out.append(" throttle=<nnn> -- restrict the entire transfer speed to nnn Mbits/second\n");
  46. out.append(" norecover=0|1 -- don't create or restore from recovery information\n");
  47. out.append(" nosplit=0|1 -- optional, don't split a file part to multiple target parts\n");
  48. out.append(" compress=0|1 -- optional, compress target\n");
  49. out.append(" encrypt=<password> -- optional, encrypt target\n");
  50. out.append(" decrypt=<password> -- optional, decrypt source\n");
  51. out.append(" push=0|1 -- optional override pull/push default\n");
  52. out.append(" jobname=<jobname> -- specify the jobname for spray, despray, dkc, copy, rename and replicate.\n");
  53. out.append(" spray options:\n");
  54. out.append(" srcip=<source-machine-ip>\n");
  55. out.append(" srcfile=<source-file-path>\n");
  56. out.append(" srcxml=<xml-file> -- replaces srcip and srcfile\n");
  57. out.append(" dstname=<destination-logical-name>\n");
  58. out.append(" dstcluster=<cluster-name>\n");
  59. out.append(" format=fixed|csv|xml|variable|recfmv|recfmvb\n");
  60. out.append(" prefix=filename{:length},filesize{:[B|L][1-8]}\n");
  61. out.append(" options for fixed:\n");
  62. out.append(" recordsize=<record-size>\n");
  63. out.append(" options for csv:\n");
  64. out.append(" encoding=ascii|utf8|utf8n|utf16|utf16le|utf16be|utf32|utf32le|utf32be -- optional, default is ascii\n");
  65. out.append(" maxrecordsize=<max-record-size> -- optional, default is 8192\n");
  66. out.append(" separator=<separator> -- optional, default is \\,\n");
  67. out.append(" terminator=<terminator> -- optional, default is \\r,\\r\\n\n");
  68. out.append(" quote=<quote> -- optional, default is '\n");
  69. out.append(" options for xml:\n");
  70. out.append(" rowtag=rowTag -- required\n");
  71. out.append(" encoding=utf8|utf8n|utf16|utf16le|utf16be|utf32|utf32le|utf32be -- optional, default is utf8\n");
  72. out.append(" maxrecordsize=<max-record-size> -- optional, default is 8192\n");
  73. out.append(" replicate options:\n");
  74. out.append(" srcname=<source-logical-name>\n");
  75. out.append(" cluster=<cluster-name> -- replicates to (additional) cluster\n");
  76. out.append(" repeatlast=0|1 -- repeats last part on every node (requires cluster)\n");
  77. out.append(" onlyrepeated=0|1 -- ignores parts not repeated (e.g. by repeatlast)\n");
  78. out.append(" despray options:\n");
  79. out.append(" srcname=<source-logical-name>\n");
  80. out.append(" dstip=<destination-machine-ip>\n");
  81. out.append(" dstfile=<destination-file-path>\n");
  82. out.append(" dstxml=<xml-file> -- replaces dstip and dstfile\n");
  83. out.append(" splitprefix=... use prefix (same format as /prefix) to split file up\n");
  84. out.append(" wrap=0|1 -- desprays as multiple files\n");
  85. out.append(" multicopy=0|1 -- each destination part gets whole file\n");
  86. out.append(" copy options:\n");
  87. out.append(" srcname=<source-logical-name>\n");
  88. out.append(" dstname=<destination-logical-name>\n");
  89. out.append(" dstcluster=<cluster-name>\n");
  90. out.append(" dstclusterroxie=No|Yes <destination cluster is a roxie cluster> -- optional\n");
  91. out.append(" srcdali=<foreign-dali-ip> -- optional\n");
  92. out.append(" srcusername=<username-for-accessing-srcdali> -- optional\n");
  93. out.append(" srcpassword=<password-for-accessing-srcdali> -- optional\n");
  94. out.append(" wrap=0|1 -- copies from a larger to smaller cluster without spliting parts\n");
  95. out.append(" diffkeysrc=<old-key-name> -- use keydiff/keypatch (src old name)\n");
  96. out.append(" diffkeydst=<old-key-name> -- use keydiff/keypatch (dst old name)\n");
  97. out.append(" multicopy=0|1 -- each destination part gets whole file\n");
  98. out.append(" dkc options:\n");
  99. out.append(" srcname=<source-logical-name>\n");
  100. out.append(" dstip=<destination-machine-ip>\n");
  101. out.append(" dstfile=<destination-file-path>\n");
  102. out.append(" remove options:\n");
  103. out.append(" name=<logical-name>\n");
  104. out.append(" names=<multiple-logical-names-separated-by-comma>\n");
  105. out.append(" namelist=<logical-name-list-in-file>\n");
  106. out.append(" nodelete=0|1 -- optional\n");
  107. out.append(" rename options:\n");
  108. out.append(" srcname=<source-logical-name>\n");
  109. out.append(" dstname=<destination-logical-name>\n");
  110. out.append(" list options:\n");
  111. out.append(" name=<logical-name-mask>\n");
  112. out.append(" saveto=<path and file name to save the result>\n");
  113. out.append(" (more to be defined)\n");
  114. out.append(" addsuper options:\n");
  115. out.append(" superfile=<logical-name>\n");
  116. out.append(" subfiles=<logical-name>{,<logical-name>} -- no spaces between logical-names.\n");
  117. out.append(" before=<logical-name> -- optional\n");
  118. out.append(" removesuper options:\n");
  119. out.append(" superfile=<logical-name>\n");
  120. out.append(" subfiles=<logical-name>{,<logical-name> -- optional. Can be *, which means all subfiles\n");
  121. out.append(" delete=1|0 -- optional. Whether or not actually remove the files.\n");
  122. out.append(" copysuper options:\n");
  123. out.append(" srcname=<source-super-name>\n");
  124. out.append(" dstname=<destination-super-name>\n");
  125. out.append(" dstcluster=<cluster-name>\n");
  126. out.append(" srcdali=<foreign-dali-ip>\n");
  127. out.append(" srcusername=<username-for-accessing-srcdali> -- optional\n");
  128. out.append(" srcpassword=<password-for-accessing-srcdali> -- optional\n");
  129. out.append(" listsuper options:\n");
  130. out.append(" superfile=<logical-name>\n");
  131. out.append(" savexml options:\n");
  132. out.append(" srcname=<source-logical-name>\n");
  133. out.append(" dstxml=<xml-file>\n");
  134. out.append(" add options:\n");
  135. out.append(" srcxml=<xml-file>\n");
  136. out.append(" dstname=<destination-logical-name>\n");
  137. out.append(" -- To add remote files from another dali directly, use these options instead of srcxml:\n");
  138. out.append(" srcname=<source-logical-name>\n");
  139. out.append(" srcdali=<source-dali-ip>\n");
  140. out.append(" srcusername=<user-name-for-source-dali>\n");
  141. out.append(" srcpassword=<password-for-source-dali>\n");
  142. out.append(" status options:\n");
  143. out.append(" wuid=<dfu-workunit-id>\n");
  144. out.append(" abort options:\n");
  145. out.append(" wuid=<dfu-workunit-id>\n");
  146. out.append(" resubmit options:\n");
  147. out.append(" wuid=<dfu-workunit-id>\n");
  148. out.append(" monitor options: \n");
  149. out.append(" event=<eventn-name> \n");
  150. out.append(" lfn=<logical-name> -- either specify lfn or ip/file\n");
  151. out.append(" ip=<ip-for-file>\n");
  152. out.append(" file=<filename>\n");
  153. out.append(" sub=0|1\n");
  154. out.append(" shotlimit=<number>\n");
  155. out.append(" dafilesrv options: \n");
  156. out.append(" idletimeout=<idle-timeout-secs> -- how long idle before stops \n");
  157. printf("%s",out.str());
  158. }
  159. bool build_globals(int argc, const char *argv[], IProperties * globals)
  160. {
  161. int i;
  162. for(i = 0; i < argc; i++)
  163. {
  164. if(argv[i] != NULL && argv[i][0] == '@' && argv[i][1] != '\0')
  165. {
  166. globals->loadFile(argv[i]+1);
  167. }
  168. }
  169. for (i = 1; i < argc; i++)
  170. {
  171. if (strchr(argv[i],'='))
  172. {
  173. globals->loadProp(argv[i]);
  174. }
  175. }
  176. StringBuffer tmp;
  177. if(globals->hasProp("encrypt")) {
  178. encrypt(tmp.clear(),globals->queryProp("encrypt") ); // basic encryption at this stage
  179. globals->setProp("encrypt",tmp.str());
  180. }
  181. if(globals->hasProp("decrypt")) {
  182. encrypt(tmp.clear(),globals->queryProp("decrypt") ); // basic encryption at this stage
  183. globals->setProp("decrypt",tmp.str());
  184. }
  185. return true;
  186. }
  187. void promptFor(const char *prompt, const char *prop, bool hide, IProperties * globals)
  188. {
  189. StringBuffer result;
  190. fprintf(stdout, "%s", prompt);
  191. fflush(stdout);
  192. if (hide)
  193. {
  194. #ifdef _WIN32
  195. HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
  196. DWORD dwInputMode;
  197. GetConsoleMode(hStdIn, &dwInputMode);
  198. SetConsoleMode(hStdIn, dwInputMode & ~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT);
  199. loop
  200. {
  201. /* read a character from the console input */
  202. char ch;
  203. DWORD dwRead;
  204. if (!ReadFile(hStdIn, &ch, sizeof(ch), &dwRead, NULL))
  205. break;
  206. if (ch == '\n' || ch=='\r' || !ch)
  207. break;
  208. result.append(ch);
  209. }
  210. SetConsoleMode(hStdIn, dwInputMode);
  211. #else
  212. int fn = fileno(stdin);
  213. #ifdef __linux__
  214. struct termio t;
  215. /* If ioctl fails, we're probably not connected to a terminal. */
  216. if(!ioctl(fn, TCGETA, &t))
  217. {
  218. t.c_lflag &= ~ECHO;
  219. ioctl(fn, TCSETA, &t);
  220. }
  221. #endif
  222. loop
  223. {
  224. char ch = fgetc(stdin);
  225. if (ch == '\n' || ch=='\r' || !ch)
  226. break;
  227. result.append(ch);
  228. }
  229. #ifdef __linux__
  230. if(!ioctl(fn, TCGETA, &t))
  231. {
  232. t.c_lflag |= ECHO;
  233. ioctl(fn, TCSETA, &t);
  234. }
  235. #endif
  236. #endif
  237. printf("\n");
  238. }
  239. else
  240. {
  241. char buf[100];
  242. if (fgets(buf, 100, stdin))
  243. result.append(buf);
  244. if (result.length() && result.charAt(result.length()-1)=='\n')
  245. result.remove(result.length()-1, 1);
  246. }
  247. globals->setProp(prop, result);
  248. }
  249. int main(int argc, const char* argv[])
  250. {
  251. InitModuleObjects();
  252. if ((argc >= 2) && ((stricmp(argv[1], "/version") == 0) || (stricmp(argv[1], "-version") == 0)))
  253. {
  254. printVersion();
  255. return 0;
  256. }
  257. Owned<IFile> inifile = createIFile("dfuplus.ini");
  258. if(argc < 2 && !(inifile->exists() && inifile->size() > 0))
  259. {
  260. handleSyntax();
  261. return 0;
  262. }
  263. if ((argc >= 2) && ((argv[1][0]=='/' || argv[1][0]=='-') && (argv[1][1]=='?' || argv[1][1]=='h')))
  264. {
  265. handleSyntax();
  266. return 0;
  267. }
  268. //queryLogMsgManager()->changeMonitorFilterOwn(queryStderrLogMsgHandler(), getPassNoneLogMsgFilter());
  269. Owned<IProperties> globals = createProperties("dfuplus.ini", true);
  270. if(!build_globals(argc, argv, globals))
  271. {
  272. fprintf(stderr, "ERROR: Invalid command syntax.\n");
  273. releaseAtoms();
  274. return DFUERR_InvalidCommandSyntax;
  275. }
  276. const char* action = globals->queryProp("action");
  277. if(!action || !*action)
  278. {
  279. handleSyntax();
  280. fprintf(stderr, "\nERROR: please specify one action");
  281. releaseAtoms();
  282. return DFUERR_TooFewArguments;
  283. }
  284. const char* server = globals->queryProp("server");
  285. if (!server || !*server) {
  286. if (stricmp(action,"dafilesrv")==0)
  287. globals->setProp("server","127.0.0.1"); // dummy
  288. else {
  289. fprintf(stderr, "ERROR: Esp server url not specified.\n");
  290. releaseAtoms();
  291. return DFUERR_TooFewArguments;
  292. }
  293. }
  294. try
  295. {
  296. Owned<CDfuPlusHelper> helper = new CDfuPlusHelper(LINK(globals.get()));
  297. helper->doit();
  298. }
  299. catch(IException* e)
  300. {
  301. StringBuffer errmsg;
  302. e->errorMessage(errmsg);
  303. fprintf(stderr, "%s\n", errmsg.str());
  304. }
  305. releaseAtoms();
  306. return 0;
  307. }