CopyParam.cpp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Common.h"
  5. #include "Exceptions.h"
  6. #include "CopyParam.h"
  7. #include "HierarchicalStorage.h"
  8. #include "TextsCore.h"
  9. #include "Interface.h"
  10. //---------------------------------------------------------------------------
  11. const wchar_t * TransferModeNames[] = { L"binary", L"ascii", L"automatic" };
  12. const int TransferModeNamesCount = LENOF(TransferModeNames);
  13. //---------------------------------------------------------------------------
  14. __fastcall TCopyParamType::TCopyParamType()
  15. {
  16. Default();
  17. }
  18. //---------------------------------------------------------------------------
  19. __fastcall TCopyParamType::TCopyParamType(const TCopyParamType & Source)
  20. {
  21. Assign(&Source);
  22. }
  23. //---------------------------------------------------------------------------
  24. __fastcall TCopyParamType::~TCopyParamType()
  25. {
  26. }
  27. //---------------------------------------------------------------------------
  28. void __fastcall TCopyParamType::Default()
  29. {
  30. // when changing defaults, make sure GetInfoStr() can handle it
  31. FileNameCase = ncNoChange;
  32. PreserveReadOnly = false;
  33. PreserveTime = true;
  34. PreserveTimeDirs = false;
  35. Rights.Number = TRights::rfDefault;
  36. PreserveRights = false; // Was True until #106
  37. IgnorePermErrors = false;
  38. AsciiFileMask.Masks = L"*.*html; *.htm; *.txt; *.php; *.php3; *.cgi; *.c; *.cpp; *.h; *.pas; "
  39. "*.bas; *.tex; *.pl; *.js; .htaccess; *.xtml; *.css; *.cfg; *.ini; *.sh; *.xml";
  40. TransferMode = tmBinary;
  41. AddXToDirectories = true;
  42. ResumeSupport = rsSmart;
  43. ResumeThreshold = 100 * 1024; // (100 KB)
  44. InvalidCharsReplacement = TokenReplacement;
  45. LocalInvalidChars = ::LocalInvalidChars;
  46. CalculateSize = true;
  47. FileMask = AnyMask;
  48. IncludeFileMask.Masks = L"";
  49. TransferSkipList = NULL;
  50. TransferResumeFile = L"";
  51. ClearArchive = false;
  52. RemoveCtrlZ = false;
  53. RemoveBOM = false;
  54. CPSLimit = 0;
  55. NewerOnly = false;
  56. EncryptNewFiles = true;
  57. ExcludeHiddenFiles = false;
  58. }
  59. //---------------------------------------------------------------------------
  60. UnicodeString __fastcall TCopyParamType::GetInfoStr(
  61. UnicodeString Separator, int Attrs) const
  62. {
  63. UnicodeString Result;
  64. bool SomeAttrIncluded;
  65. UnicodeString ScriptArgs;
  66. bool NoScriptArgs;
  67. UnicodeString AssemblyCode;
  68. bool NoCodeProperties;
  69. DoGetInfoStr(
  70. Separator, Attrs, Result, SomeAttrIncluded,
  71. UnicodeString(), ScriptArgs, NoScriptArgs, TAssemblyLanguage(0), AssemblyCode, NoCodeProperties);
  72. return Result;
  73. }
  74. //---------------------------------------------------------------------------
  75. bool __fastcall TCopyParamType::AnyUsableCopyParam(int Attrs) const
  76. {
  77. UnicodeString Result;
  78. bool SomeAttrIncluded;
  79. UnicodeString ScriptArgs;
  80. bool NoScriptArgs;
  81. UnicodeString AssemblyCode;
  82. bool NoCodeProperties;
  83. DoGetInfoStr(
  84. L";", Attrs, Result, SomeAttrIncluded,
  85. UnicodeString(), ScriptArgs, NoScriptArgs, TAssemblyLanguage(0), AssemblyCode, NoCodeProperties);
  86. return SomeAttrIncluded;
  87. }
  88. //---------------------------------------------------------------------------
  89. UnicodeString __fastcall TCopyParamType::GenerateTransferCommandArgs(int Attrs, const UnicodeString & Link, bool & NoScriptArgs) const
  90. {
  91. UnicodeString Result;
  92. bool SomeAttrIncluded;
  93. UnicodeString ScriptArgs;
  94. UnicodeString AssemblyCode;
  95. bool NoCodeProperties;
  96. DoGetInfoStr(
  97. L";", Attrs, Result, SomeAttrIncluded,
  98. Link, ScriptArgs, NoScriptArgs, TAssemblyLanguage(0), AssemblyCode, NoCodeProperties);
  99. return ScriptArgs;
  100. }
  101. //---------------------------------------------------------------------------
  102. UnicodeString __fastcall TCopyParamType::GenerateAssemblyCode(
  103. TAssemblyLanguage Language, int Attrs, bool & NoCodeProperties) const
  104. {
  105. UnicodeString Result;
  106. bool SomeAttrIncluded;
  107. UnicodeString ScriptArgs;
  108. bool NoScriptArgs;
  109. UnicodeString AssemblyCode;
  110. DoGetInfoStr(L";", Attrs, Result, SomeAttrIncluded, UnicodeString(), ScriptArgs, NoScriptArgs, Language, AssemblyCode, NoCodeProperties);
  111. return AssemblyCode;
  112. }
  113. //---------------------------------------------------------------------------
  114. void __fastcall TCopyParamType::DoGetInfoStr(
  115. UnicodeString Separator, int Options,
  116. UnicodeString & Result, bool & SomeAttrIncluded,
  117. const UnicodeString & Link, UnicodeString & ScriptArgs, bool & NoScriptArgs, TAssemblyLanguage Language, UnicodeString & AssemblyCode,
  118. bool & NoCodeProperties) const
  119. {
  120. TCopyParamType Defaults;
  121. bool SomeAttrExcluded = false;
  122. NoScriptArgs = false;
  123. NoCodeProperties = false;
  124. SomeAttrIncluded = false;
  125. #define ADD(STR, EXCEPT) \
  126. if (FLAGCLEAR(Options, EXCEPT)) \
  127. { \
  128. AddToList(Result, (STR), Separator); \
  129. SomeAttrIncluded = true; \
  130. } \
  131. else \
  132. { \
  133. SomeAttrExcluded = true; \
  134. }
  135. bool AsciiFileMaskDiffers = (TransferMode == tmAutomatic) && !(AsciiFileMask == Defaults.AsciiFileMask);
  136. bool TransferModeDiffers = ((TransferMode != Defaults.TransferMode) || AsciiFileMaskDiffers);
  137. if (FLAGCLEAR(Options, cpaIncludeMaskOnly | cpaNoTransferMode))
  138. {
  139. // Adding Transfer type unconditionally
  140. bool FormatMask;
  141. int Ident;
  142. switch (TransferMode)
  143. {
  144. case tmBinary:
  145. FormatMask = false;
  146. Ident = 2;
  147. break;
  148. case tmAscii:
  149. FormatMask = false;
  150. Ident = 3;
  151. break;
  152. case tmAutomatic:
  153. default:
  154. FormatMask = !(AsciiFileMask == Defaults.AsciiFileMask);
  155. Ident = FormatMask ? 4 : 5;
  156. break;
  157. }
  158. UnicodeString S = FORMAT(LoadStrPart(COPY_INFO_TRANSFER_TYPE2, 1),
  159. (LoadStrPart(COPY_INFO_TRANSFER_TYPE2, Ident)));
  160. if (FormatMask)
  161. {
  162. S = FORMAT(S, (AsciiFileMask.Masks));
  163. }
  164. AddToList(Result, S, Separator);
  165. if (TransferModeDiffers)
  166. {
  167. ADD("", cpaIncludeMaskOnly | cpaNoTransferMode);
  168. ScriptArgs += RtfSwitchValue(TRANSFER_SWITCH, Link, TransferModeNames[TransferMode]);
  169. const wchar_t * TransferModeMembers[] = { L"Binary", L"Ascii", L"Automatic" };
  170. AssemblyCode += AssemblyProperty(
  171. Language, TransferOptionsClassName, L"TransferMode", L"TransferMode", TransferModeMembers[TransferMode], false);
  172. if (AsciiFileMaskDiffers)
  173. {
  174. NoScriptArgs = true;
  175. NoCodeProperties = true;
  176. }
  177. }
  178. }
  179. else
  180. {
  181. if (TransferModeDiffers)
  182. {
  183. SomeAttrExcluded = true;
  184. NoScriptArgs = true;
  185. NoCodeProperties = true;
  186. }
  187. }
  188. if (FileNameCase != Defaults.FileNameCase)
  189. {
  190. ADD(FORMAT(LoadStrPart(COPY_INFO_FILENAME, 1),
  191. (LoadStrPart(COPY_INFO_FILENAME, FileNameCase + 2))),
  192. cpaIncludeMaskOnly);
  193. NoScriptArgs = true;
  194. NoCodeProperties = true;
  195. }
  196. if ((InvalidCharsReplacement == NoReplacement) !=
  197. (Defaults.InvalidCharsReplacement == NoReplacement))
  198. {
  199. DebugAssert(InvalidCharsReplacement == NoReplacement);
  200. if (InvalidCharsReplacement == NoReplacement)
  201. {
  202. ADD(LoadStr(COPY_INFO_DONT_REPLACE_INV_CHARS), cpaIncludeMaskOnly);
  203. }
  204. NoScriptArgs = true;
  205. NoCodeProperties = true;
  206. }
  207. if ((PreserveRights != Defaults.PreserveRights) ||
  208. (PreserveRights &&
  209. ((Rights != Defaults.Rights) || (AddXToDirectories != Defaults.AddXToDirectories))))
  210. {
  211. const int Except = cpaIncludeMaskOnly | cpaNoRights;
  212. if (DebugAlwaysTrue(PreserveRights))
  213. {
  214. UnicodeString RightsStr = Rights.Text;
  215. if (AddXToDirectories)
  216. {
  217. RightsStr += L", " + LoadStr(COPY_INFO_ADD_X_TO_DIRS);
  218. }
  219. ADD(FORMAT(LoadStr(COPY_INFO_PERMISSIONS), (RightsStr)),
  220. Except);
  221. if (FLAGCLEAR(Options, Except))
  222. {
  223. ScriptArgs += RtfSwitchValue(PERMISSIONS_SWITCH, Link, Rights.Octal);
  224. const UnicodeString FilePermissionsClassName = L"FilePermissions";
  225. const bool Inline = true;
  226. UnicodeString FilePermissions =
  227. AssemblyNewClassInstanceStart(Language, FilePermissionsClassName, Inline) +
  228. AssemblyProperty(Language, FilePermissionsClassName, L"Octal", Rights.Octal, Inline) +
  229. AssemblyNewClassInstanceEnd(Language, Inline);
  230. AssemblyCode += AssemblyPropertyRaw(Language, TransferOptionsClassName, L"FilePermissions", FilePermissions, false);
  231. }
  232. }
  233. if ((AddXToDirectories != Defaults.AddXToDirectories) && FLAGCLEAR(Options, Except))
  234. {
  235. NoScriptArgs = true;
  236. NoCodeProperties = true;
  237. }
  238. }
  239. bool APreserveTimeDirs = PreserveTime && PreserveTimeDirs;
  240. if ((PreserveTime != Defaults.PreserveTime) || (APreserveTimeDirs != Defaults.PreserveTimeDirs))
  241. {
  242. bool AddPreserveTime = false;
  243. UnicodeString Str = LoadStr(PreserveTime ? COPY_INFO_TIMESTAMP : COPY_INFO_DONT_PRESERVE_TIME);
  244. const int ExceptDirs = cpaNoPreserveTimeDirs;
  245. if (APreserveTimeDirs != Defaults.PreserveTimeDirs)
  246. {
  247. if (DebugAlwaysTrue(PreserveTimeDirs))
  248. {
  249. if (FLAGCLEAR(Options, ExceptDirs))
  250. {
  251. Str = FMTLOAD(COPY_INFO_PRESERVE_TIME_DIRS, (Str));
  252. AddPreserveTime = true;
  253. }
  254. }
  255. ADD("", ExceptDirs);
  256. }
  257. const int Except = cpaIncludeMaskOnly | cpaNoPreserveTime;
  258. if (PreserveTime != Defaults.PreserveTime)
  259. {
  260. if (FLAGCLEAR(Options, Except))
  261. {
  262. AddPreserveTime = true;
  263. }
  264. ADD(L"", Except);
  265. }
  266. if (AddPreserveTime)
  267. {
  268. AddToList(Result, Str, Separator);
  269. }
  270. if (FLAGCLEAR(Options, Except))
  271. {
  272. if (PreserveTime)
  273. {
  274. if (PreserveTimeDirs && FLAGCLEAR(Options, ExceptDirs))
  275. {
  276. ScriptArgs += RtfSwitchValue(PRESERVETIME_SWITCH, Link, PRESERVETIMEDIRS_SWITCH_VALUE);
  277. NoCodeProperties = true;
  278. }
  279. else
  280. {
  281. DebugFail(); // should never get here
  282. ScriptArgs += RtfSwitch(PRESERVETIME_SWITCH, Link);
  283. }
  284. }
  285. else
  286. {
  287. ScriptArgs += RtfSwitch(NOPRESERVETIME_SWITCH, Link);
  288. AssemblyCode += AssemblyProperty(Language, TransferOptionsClassName, L"PreserveTimestamp", false, false);
  289. }
  290. }
  291. }
  292. if ((PreserveRights || PreserveTime) &&
  293. (IgnorePermErrors != Defaults.IgnorePermErrors))
  294. {
  295. if (DebugAlwaysTrue(IgnorePermErrors))
  296. {
  297. const int Except = cpaIncludeMaskOnly | cpaNoIgnorePermErrors;
  298. ADD(LoadStr(COPY_INFO_IGNORE_PERM_ERRORS), Except);
  299. if (FLAGCLEAR(Options, Except))
  300. {
  301. NoScriptArgs = true;
  302. NoCodeProperties = true;
  303. }
  304. }
  305. }
  306. if (PreserveReadOnly != Defaults.PreserveReadOnly)
  307. {
  308. if (DebugAlwaysTrue(PreserveReadOnly))
  309. {
  310. const int Except = cpaIncludeMaskOnly | cpaNoPreserveReadOnly;
  311. ADD(LoadStr(COPY_INFO_PRESERVE_READONLY), Except);
  312. if (FLAGCLEAR(Options, Except))
  313. {
  314. NoScriptArgs = true;
  315. NoCodeProperties = true;
  316. }
  317. }
  318. }
  319. if (CalculateSize != Defaults.CalculateSize)
  320. {
  321. if (DebugAlwaysTrue(!CalculateSize))
  322. {
  323. ADD(LoadStr(COPY_INFO_DONT_CALCULATE_SIZE), cpaIncludeMaskOnly);
  324. // Always false in scripting, in assembly controlled by use of FileTransferProgress
  325. }
  326. }
  327. if (ClearArchive != Defaults.ClearArchive)
  328. {
  329. if (DebugAlwaysTrue(ClearArchive))
  330. {
  331. const int Except = cpaIncludeMaskOnly | cpaNoClearArchive;
  332. ADD(LoadStr(COPY_INFO_CLEAR_ARCHIVE), Except);
  333. if (FLAGCLEAR(Options, Except))
  334. {
  335. NoScriptArgs = true;
  336. NoCodeProperties = true;
  337. }
  338. }
  339. }
  340. if ((TransferMode == tmAscii) || (TransferMode == tmAutomatic))
  341. {
  342. if (RemoveBOM != Defaults.RemoveBOM)
  343. {
  344. if (DebugAlwaysTrue(RemoveBOM))
  345. {
  346. const int Except = cpaIncludeMaskOnly | cpaNoRemoveBOM | cpaNoTransferMode;
  347. ADD(LoadStr(COPY_INFO_REMOVE_BOM), Except);
  348. if (FLAGCLEAR(Options, Except))
  349. {
  350. NoScriptArgs = true;
  351. NoCodeProperties = true;
  352. }
  353. }
  354. }
  355. if (RemoveCtrlZ != Defaults.RemoveCtrlZ)
  356. {
  357. if (DebugAlwaysTrue(RemoveCtrlZ))
  358. {
  359. const int Except = cpaIncludeMaskOnly | cpaNoRemoveCtrlZ | cpaNoTransferMode;
  360. ADD(LoadStr(COPY_INFO_REMOVE_CTRLZ), Except);
  361. if (FLAGCLEAR(Options, Except))
  362. {
  363. NoScriptArgs = true;
  364. NoCodeProperties = true;
  365. }
  366. }
  367. }
  368. }
  369. if (!(IncludeFileMask == Defaults.IncludeFileMask))
  370. {
  371. ADD(FORMAT(LoadStr(COPY_INFO_FILE_MASK), (IncludeFileMask.Masks)),
  372. cpaNoIncludeMask);
  373. ScriptArgs += RtfSwitch(FILEMASK_SWITCH, Link, IncludeFileMask.Masks);
  374. AssemblyCode += AssemblyProperty(Language, TransferOptionsClassName, L"FileMask", IncludeFileMask.Masks, false);
  375. }
  376. DebugAssert(FTransferSkipList.get() == NULL);
  377. DebugAssert(FTransferResumeFile.IsEmpty());
  378. if (CPSLimit > 0)
  379. {
  380. int LimitKB = int(CPSLimit / 1024);
  381. ADD(FMTLOAD(COPY_INFO_CPS_LIMIT2, (LimitKB)), cpaIncludeMaskOnly);
  382. ScriptArgs += RtfSwitch(SPEED_SWITCH, Link, LimitKB);
  383. AssemblyCode += AssemblyProperty(Language, TransferOptionsClassName, L"SpeedLimit", LimitKB, false);
  384. }
  385. if (NewerOnly != Defaults.NewerOnly)
  386. {
  387. if (DebugAlwaysTrue(NewerOnly))
  388. {
  389. const int Except = cpaIncludeMaskOnly | cpaNoNewerOnly;
  390. ADD(StripHotkey(LoadStr(COPY_PARAM_NEWER_ONLY)), Except);
  391. if (FLAGCLEAR(Options, Except))
  392. {
  393. ScriptArgs += RtfSwitch(NEWERONLY_SWICH, Link);
  394. NoCodeProperties = true;
  395. }
  396. }
  397. }
  398. if (EncryptNewFiles != Defaults.EncryptNewFiles)
  399. {
  400. if (!DebugAlwaysFalse(EncryptNewFiles))
  401. {
  402. const int Except = cpaIncludeMaskOnly | cpaNoEncryptNewFiles;
  403. ADD(StripHotkey(LoadStr(COPY_INFO_DONT_ENCRYPT_NEW_FILES)), Except);
  404. if (FLAGCLEAR(Options, Except))
  405. {
  406. NoScriptArgs = true;
  407. NoCodeProperties = true;
  408. }
  409. }
  410. }
  411. if (ExcludeHiddenFiles != Defaults.ExcludeHiddenFiles)
  412. {
  413. if (DebugAlwaysTrue(ExcludeHiddenFiles))
  414. {
  415. const int Except = cpaNoIncludeMask;
  416. ADD(StripHotkey(LoadStr(COPY_INFO_EXCLUDE_HIDDEN_FILES)), Except);
  417. if (FLAGCLEAR(Options, Except))
  418. {
  419. NoScriptArgs = true;
  420. NoCodeProperties = true;
  421. }
  422. }
  423. }
  424. bool ResumeThresholdDiffers = ((ResumeSupport == rsSmart) && (ResumeThreshold != Defaults.ResumeThreshold));
  425. if (((ResumeSupport != Defaults.ResumeSupport) || ResumeThresholdDiffers) &&
  426. (TransferMode != tmAscii) && FLAGCLEAR(Options, cpaNoResumeSupport))
  427. {
  428. UnicodeString Value;
  429. UnicodeString CodeState;
  430. int ResumeThresholdKB = (ResumeThreshold / 1024);
  431. switch (ResumeSupport)
  432. {
  433. case rsOff:
  434. Value = ToggleNames[ToggleOff];
  435. CodeState = L"Off";
  436. break;
  437. case rsOn:
  438. Value = ToggleNames[ToggleOn];
  439. CodeState = L"On";
  440. break;
  441. case rsSmart:
  442. Value = IntToStr(ResumeThresholdKB);
  443. break;
  444. }
  445. ScriptArgs += RtfSwitchValue(RESUMESUPPORT_SWITCH, Link, Value);
  446. const UnicodeString ResumeSupportClassName = L"TransferResumeSupport";
  447. const bool Inline = true;
  448. UnicodeString ResumeSupportCode =
  449. AssemblyNewClassInstanceStart(Language, ResumeSupportClassName, Inline);
  450. if (ResumeSupport == rsSmart)
  451. {
  452. ResumeSupportCode += AssemblyProperty(Language, ResumeSupportClassName, L"Threshold", ResumeThresholdKB, Inline);
  453. }
  454. else
  455. {
  456. ResumeSupportCode += AssemblyProperty(Language, ResumeSupportClassName, L"State", L"TransferResumeSupportState", CodeState, Inline);
  457. }
  458. ResumeSupportCode += AssemblyNewClassInstanceEnd(Language, Inline);
  459. AssemblyCode += AssemblyPropertyRaw(Language, TransferOptionsClassName, L"ResumeSupport", ResumeSupportCode, false);
  460. }
  461. if (SomeAttrExcluded)
  462. {
  463. Result += (Result.IsEmpty() ? UnicodeString() : Separator) +
  464. FORMAT(LoadStrPart(COPY_INFO_NOT_USABLE, 1),
  465. (LoadStrPart(COPY_INFO_NOT_USABLE, (SomeAttrIncluded ? 2 : 3))));
  466. }
  467. else if (Result.IsEmpty())
  468. {
  469. Result = LoadStr(COPY_INFO_DEFAULT);
  470. }
  471. #undef ADD
  472. }
  473. //---------------------------------------------------------------------------
  474. void __fastcall TCopyParamType::Assign(const TCopyParamType * Source)
  475. {
  476. DebugAssert(Source != NULL);
  477. #define COPY(Prop) Prop = Source->Prop
  478. COPY(FileNameCase);
  479. COPY(PreserveReadOnly);
  480. COPY(PreserveTime);
  481. COPY(PreserveTimeDirs);
  482. COPY(Rights);
  483. COPY(AsciiFileMask);
  484. COPY(TransferMode);
  485. COPY(AddXToDirectories);
  486. COPY(PreserveRights);
  487. COPY(IgnorePermErrors);
  488. COPY(ResumeSupport);
  489. COPY(ResumeThreshold);
  490. COPY(InvalidCharsReplacement);
  491. COPY(LocalInvalidChars);
  492. COPY(CalculateSize);
  493. COPY(FileMask);
  494. COPY(IncludeFileMask);
  495. COPY(TransferSkipList);
  496. COPY(TransferResumeFile);
  497. COPY(ClearArchive);
  498. COPY(RemoveCtrlZ);
  499. COPY(RemoveBOM);
  500. COPY(CPSLimit);
  501. COPY(NewerOnly);
  502. COPY(EncryptNewFiles);
  503. COPY(ExcludeHiddenFiles);
  504. #undef COPY
  505. }
  506. //---------------------------------------------------------------------------
  507. TCopyParamType & __fastcall TCopyParamType::operator =(const TCopyParamType & rhp)
  508. {
  509. Assign(&rhp);
  510. return *this;
  511. }
  512. //---------------------------------------------------------------------------
  513. void __fastcall TCopyParamType::SetLocalInvalidChars(UnicodeString value)
  514. {
  515. if (value != LocalInvalidChars)
  516. {
  517. FLocalInvalidChars = value;
  518. FTokenizibleChars = FLocalInvalidChars + TokenPrefix;
  519. }
  520. }
  521. //---------------------------------------------------------------------------
  522. bool __fastcall TCopyParamType::GetReplaceInvalidChars() const
  523. {
  524. return (InvalidCharsReplacement != NoReplacement);
  525. }
  526. //---------------------------------------------------------------------------
  527. void __fastcall TCopyParamType::SetReplaceInvalidChars(bool value)
  528. {
  529. if (ReplaceInvalidChars != value)
  530. {
  531. InvalidCharsReplacement = (value ? TokenReplacement : NoReplacement);
  532. }
  533. }
  534. //---------------------------------------------------------------------------
  535. UnicodeString __fastcall TCopyParamType::ValidLocalFileName(UnicodeString FileName) const
  536. {
  537. return ::ValidLocalFileName(FileName, InvalidCharsReplacement, FTokenizibleChars, LocalInvalidChars);
  538. }
  539. //---------------------------------------------------------------------------
  540. UnicodeString __fastcall TCopyParamType::RestoreChars(UnicodeString FileName) const
  541. {
  542. if (InvalidCharsReplacement == TokenReplacement)
  543. {
  544. wchar_t * InvalidChar = FileName.c_str();
  545. while ((InvalidChar = wcschr(InvalidChar, TokenPrefix)) != NULL)
  546. {
  547. int Index = InvalidChar - FileName.c_str() + 1;
  548. if (FileName.Length() >= Index + 2)
  549. {
  550. UnicodeString Hex = FileName.SubString(Index + 1, 2);
  551. wchar_t Char = static_cast<wchar_t>(HexToByte(Hex));
  552. if ((Char != L'\0') &&
  553. ((FTokenizibleChars.Pos(Char) > 0) ||
  554. (((Char == L' ') || (Char == L'.')) && (Index == FileName.Length() - 2))))
  555. {
  556. FileName[Index] = Char;
  557. FileName.Delete(Index + 1, 2);
  558. InvalidChar = FileName.c_str() + Index;
  559. }
  560. else if ((Hex == L"00") &&
  561. ((Index == FileName.Length() - 2) || (FileName[Index + 3] == L'.')) &&
  562. IsReservedName(FileName.SubString(1, Index - 1) + FileName.SubString(Index + 3, FileName.Length() - Index - 3 + 1)))
  563. {
  564. FileName.Delete(Index, 3);
  565. InvalidChar = FileName.c_str() + Index - 1;
  566. }
  567. else
  568. {
  569. InvalidChar++;
  570. }
  571. }
  572. else
  573. {
  574. InvalidChar++;
  575. }
  576. }
  577. }
  578. return FileName;
  579. }
  580. //---------------------------------------------------------------------------
  581. UnicodeString __fastcall TCopyParamType::ValidLocalPath(UnicodeString Path) const
  582. {
  583. UnicodeString Result;
  584. while (!Path.IsEmpty())
  585. {
  586. if (!Result.IsEmpty())
  587. {
  588. Result += L"\\";
  589. }
  590. Result += ValidLocalFileName(CutToChar(Path, L'\\', false));
  591. }
  592. return Result;
  593. }
  594. //---------------------------------------------------------------------------
  595. UnicodeString __fastcall TCopyParamType::ChangeFileName(UnicodeString FileName,
  596. TOperationSide Side, bool FirstLevel) const
  597. {
  598. if (FirstLevel)
  599. {
  600. FileName = MaskFileName(FileName, FileMask);
  601. }
  602. switch (FileNameCase) {
  603. case ncUpperCase: FileName = FileName.UpperCase(); break;
  604. case ncLowerCase: FileName = FileName.LowerCase(); break;
  605. case ncFirstUpperCase: FileName = FileName.SubString(1, 1).UpperCase() +
  606. FileName.SubString(2, FileName.Length()-1).LowerCase(); break;
  607. case ncLowerCaseShort:
  608. if ((FileName.Length() <= 12) && (FileName.Pos(L".") <= 9) &&
  609. (FileName == FileName.UpperCase()))
  610. {
  611. FileName = FileName.LowerCase();
  612. }
  613. break;
  614. case ncNoChange:
  615. default:
  616. /*nothing*/
  617. break;
  618. }
  619. if (Side == osRemote)
  620. {
  621. FileName = ValidLocalFileName(FileName);
  622. }
  623. else
  624. {
  625. FileName = RestoreChars(FileName);
  626. }
  627. return FileName;
  628. }
  629. //---------------------------------------------------------------------------
  630. bool __fastcall TCopyParamType::UseAsciiTransfer(UnicodeString FileName,
  631. TOperationSide Side, const TFileMasks::TParams & Params) const
  632. {
  633. switch (TransferMode)
  634. {
  635. case tmBinary: return false;
  636. case tmAscii: return true;
  637. case tmAutomatic: return AsciiFileMask.Matches(FileName, (Side == osLocal),
  638. false, &Params);
  639. default: DebugFail(); return false;
  640. }
  641. }
  642. //---------------------------------------------------------------------------
  643. TRights __fastcall TCopyParamType::RemoteFileRights(Integer Attrs) const
  644. {
  645. TRights R = Rights;
  646. if ((Attrs & faDirectory) && AddXToDirectories)
  647. R.AddExecute();
  648. return R;
  649. }
  650. //---------------------------------------------------------------------------
  651. UnicodeString __fastcall TCopyParamType::GetLogStr() const
  652. {
  653. wchar_t CaseC[] = L"NULFS";
  654. wchar_t ModeC[] = L"BAM";
  655. wchar_t ResumeC[] = L"YSN";
  656. // OpenArray (ARRAYOFCONST) supports only up to 19 arguments, so we had to split it
  657. return
  658. FORMAT(
  659. L" PrTime: %s%s; PrRO: %s; Rght: %s; PrR: %s (%s); FnCs: %s; RIC: %s; "
  660. "Resume: %s (%d); CalcS: %s; Mask: %s\n",
  661. (BooleanToEngStr(PreserveTime),
  662. UnicodeString(PreserveTime && PreserveTimeDirs ? L"+Dirs" : L""),
  663. BooleanToEngStr(PreserveReadOnly),
  664. Rights.Text,
  665. BooleanToEngStr(PreserveRights),
  666. BooleanToEngStr(IgnorePermErrors),
  667. CaseC[FileNameCase],
  668. CharToHex(InvalidCharsReplacement),
  669. ResumeC[ResumeSupport],
  670. (int)ResumeThreshold,
  671. BooleanToEngStr(CalculateSize),
  672. FileMask)) +
  673. FORMAT(
  674. L" TM: %s; ClAr: %s; RemEOF: %s; RemBOM: %s; CPS: %u; NewerOnly: %s; EncryptNewFiles: %s; ExcludeHiddenFiles: %s; InclM: %s; ResumeL: %d\n"
  675. " AscM: %s\n",
  676. (ModeC[TransferMode],
  677. BooleanToEngStr(ClearArchive),
  678. BooleanToEngStr(RemoveCtrlZ),
  679. BooleanToEngStr(RemoveBOM),
  680. int(CPSLimit),
  681. BooleanToEngStr(NewerOnly),
  682. BooleanToEngStr(EncryptNewFiles),
  683. BooleanToEngStr(ExcludeHiddenFiles),
  684. IncludeFileMask.Masks,
  685. ((FTransferSkipList.get() != NULL) ? FTransferSkipList->Count : 0) + (!FTransferResumeFile.IsEmpty() ? 1 : 0),
  686. AsciiFileMask.Masks));
  687. }
  688. //---------------------------------------------------------------------------
  689. int __fastcall TCopyParamType::LocalFileAttrs(const TRights & Rights) const
  690. {
  691. int Result = 0;
  692. if (PreserveReadOnly && !Rights.Right[TRights::rrUserWrite])
  693. {
  694. Result |= faReadOnly;
  695. }
  696. return Result;
  697. }
  698. //---------------------------------------------------------------------------
  699. bool __fastcall TCopyParamType::AllowResume(__int64 Size) const
  700. {
  701. switch (ResumeSupport)
  702. {
  703. case rsOn: return true;
  704. case rsOff: return false;
  705. case rsSmart: return (Size >= ResumeThreshold);
  706. default: DebugFail(); return false;
  707. }
  708. }
  709. //---------------------------------------------------------------------------
  710. bool __fastcall TCopyParamType::AllowAnyTransfer() const
  711. {
  712. return
  713. IncludeFileMask.Masks.IsEmpty() &&
  714. !ExcludeHiddenFiles &&
  715. ((FTransferSkipList.get() == NULL) || (FTransferSkipList->Count == 0)) &&
  716. FTransferResumeFile.IsEmpty();
  717. }
  718. //---------------------------------------------------------------------------
  719. bool __fastcall TCopyParamType::AllowTransfer(UnicodeString FileName,
  720. TOperationSide Side, bool Directory, const TFileMasks::TParams & Params, bool Hidden) const
  721. {
  722. bool Result = true;
  723. if (Hidden && ExcludeHiddenFiles)
  724. {
  725. Result = false;
  726. }
  727. else if (!IncludeFileMask.Masks.IsEmpty())
  728. {
  729. Result = IncludeFileMask.Matches(FileName, (Side == osLocal),
  730. Directory, &Params);
  731. }
  732. return Result;
  733. }
  734. //---------------------------------------------------------------------------
  735. bool __fastcall TCopyParamType::SkipTransfer(
  736. UnicodeString FileName, bool Directory) const
  737. {
  738. bool Result = false;
  739. // we deliberatelly do not filter directories, as path is added to resume list
  740. // when a transfer of file or directory is started,
  741. // so for directories we need to recurse and check every single file
  742. if (!Directory && (FTransferSkipList.get() != NULL))
  743. {
  744. Result = (FTransferSkipList->IndexOf(FileName) >= 0);
  745. }
  746. return Result;
  747. }
  748. //---------------------------------------------------------------------------
  749. bool __fastcall TCopyParamType::ResumeTransfer(UnicodeString FileName) const
  750. {
  751. // Returning true has the same effect as cpResume
  752. return
  753. (FileName == FTransferResumeFile) &&
  754. DebugAlwaysTrue(!FTransferResumeFile.IsEmpty());
  755. }
  756. //---------------------------------------------------------------------------
  757. TStrings * __fastcall TCopyParamType::GetTransferSkipList() const
  758. {
  759. return FTransferSkipList.get();
  760. }
  761. //---------------------------------------------------------------------------
  762. void __fastcall TCopyParamType::SetTransferSkipList(TStrings * value)
  763. {
  764. if ((value == NULL) || (value->Count == 0))
  765. {
  766. FTransferSkipList.reset(NULL);
  767. }
  768. else
  769. {
  770. FTransferSkipList.reset(new TStringList());
  771. FTransferSkipList->AddStrings(value);
  772. FTransferSkipList->Sorted = true;
  773. }
  774. }
  775. //---------------------------------------------------------------------------
  776. void __fastcall TCopyParamType::Load(THierarchicalStorage * Storage)
  777. {
  778. AddXToDirectories = Storage->ReadBool(L"AddXToDirectories", AddXToDirectories);
  779. AsciiFileMask.Masks = Storage->ReadString(L"Masks", AsciiFileMask.Masks);
  780. FileNameCase = (TFileNameCase)Storage->ReadInteger(L"FileNameCase", FileNameCase);
  781. PreserveReadOnly = Storage->ReadBool(L"PreserveReadOnly", PreserveReadOnly);
  782. PreserveTime = Storage->ReadBool(L"PreserveTime", PreserveTime);
  783. PreserveTimeDirs = Storage->ReadBool(L"PreserveTimeDirs", PreserveTimeDirs);
  784. PreserveRights = Storage->ReadBool(L"PreserveRights", PreserveRights);
  785. IgnorePermErrors = Storage->ReadBool(L"IgnorePermErrors", IgnorePermErrors);
  786. Rights.Text = Storage->ReadString(L"Text", Rights.Text);
  787. TransferMode = (TTransferMode)Storage->ReadInteger(L"TransferMode", TransferMode);
  788. ResumeSupport = (TResumeSupport)Storage->ReadInteger(L"ResumeSupport", ResumeSupport);
  789. ResumeThreshold = Storage->ReadInt64(L"ResumeThreshold", ResumeThreshold);
  790. InvalidCharsReplacement = (wchar_t)Storage->ReadInteger(L"ReplaceInvalidChars",
  791. (unsigned int)InvalidCharsReplacement);
  792. LocalInvalidChars = Storage->ReadString(L"LocalInvalidChars", LocalInvalidChars);
  793. CalculateSize = Storage->ReadBool(L"CalculateSize", CalculateSize);
  794. if (Storage->ValueExists(L"IncludeFileMask"))
  795. {
  796. IncludeFileMask.Masks = Storage->ReadString(L"IncludeFileMask", IncludeFileMask.Masks);
  797. }
  798. else if (Storage->ValueExists(L"ExcludeFileMask"))
  799. {
  800. UnicodeString ExcludeFileMask = Storage->ReadString(L"ExcludeFileMask", L"");
  801. if (!ExcludeFileMask.IsEmpty())
  802. {
  803. bool NegativeExclude = Storage->ReadBool(L"NegativeExclude", false);
  804. if (NegativeExclude)
  805. {
  806. IncludeFileMask.Masks = ExcludeFileMask;
  807. }
  808. // convert at least simple cases to new format
  809. else if (ExcludeFileMask.Pos(IncludeExcludeFileMasksDelimiter) == 0)
  810. {
  811. IncludeFileMask.Masks = UnicodeString(IncludeExcludeFileMasksDelimiter) + ExcludeFileMask;
  812. }
  813. }
  814. }
  815. TransferSkipList = NULL;
  816. TransferResumeFile = L"";
  817. ClearArchive = Storage->ReadBool(L"ClearArchive", ClearArchive);
  818. RemoveCtrlZ = Storage->ReadBool(L"RemoveCtrlZ", RemoveCtrlZ);
  819. RemoveBOM = Storage->ReadBool(L"RemoveBOM", RemoveBOM);
  820. CPSLimit = Storage->ReadInteger(L"CPSLimit", CPSLimit);
  821. NewerOnly = Storage->ReadBool(L"NewerOnly", NewerOnly);
  822. EncryptNewFiles = Storage->ReadBool(L"EncryptNewFiles", EncryptNewFiles);
  823. ExcludeHiddenFiles = Storage->ReadBool(L"ExcludeHiddenFiles", ExcludeHiddenFiles);
  824. }
  825. //---------------------------------------------------------------------------
  826. void __fastcall TCopyParamType::Save(THierarchicalStorage * Storage, const TCopyParamType * Defaults) const
  827. {
  828. // Same as in TSessionData::DoSave
  829. #define WRITE_DATA_EX(TYPE, NAME, PROPERTY, CONV) \
  830. if ((Defaults != NULL) && (CONV(Defaults->PROPERTY) == CONV(PROPERTY))) \
  831. { \
  832. Storage->DeleteValue(NAME); \
  833. } \
  834. else \
  835. { \
  836. Storage->Write ## TYPE(NAME, CONV(PROPERTY)); \
  837. }
  838. #define WRITE_DATA_CONV(TYPE, NAME, PROPERTY) WRITE_DATA_EX(TYPE, NAME, PROPERTY, WRITE_DATA_CONV_FUNC)
  839. #define WRITE_DATA(TYPE, PROPERTY) WRITE_DATA_EX(TYPE, TEXT(#PROPERTY), PROPERTY, )
  840. WRITE_DATA(Bool, AddXToDirectories);
  841. WRITE_DATA_EX(String, L"Masks", AsciiFileMask.Masks, );
  842. WRITE_DATA(Integer, FileNameCase);
  843. WRITE_DATA(Bool, PreserveReadOnly);
  844. WRITE_DATA(Bool, PreserveTime);
  845. WRITE_DATA(Bool, PreserveTimeDirs);
  846. WRITE_DATA(Bool, PreserveRights);
  847. WRITE_DATA(Bool, IgnorePermErrors);
  848. WRITE_DATA_EX(String, L"Text", Rights.Text, );
  849. WRITE_DATA(Integer, TransferMode);
  850. WRITE_DATA(Integer, ResumeSupport);
  851. WRITE_DATA(Int64, ResumeThreshold);
  852. #define WRITE_DATA_CONV_FUNC(X) (unsigned int)(X)
  853. WRITE_DATA_CONV(Integer, L"ReplaceInvalidChars", InvalidCharsReplacement);
  854. WRITE_DATA(String, LocalInvalidChars);
  855. WRITE_DATA(Bool, CalculateSize);
  856. WRITE_DATA_EX(String, L"IncludeFileMask", IncludeFileMask.Masks, );
  857. Storage->DeleteValue(L"ExcludeFileMask"); // obsolete
  858. Storage->DeleteValue(L"NegativeExclude"); // obsolete
  859. DebugAssert(FTransferSkipList.get() == NULL);
  860. DebugAssert(FTransferResumeFile.IsEmpty());
  861. WRITE_DATA(Bool, ClearArchive);
  862. WRITE_DATA(Bool, RemoveCtrlZ);
  863. WRITE_DATA(Bool, RemoveBOM);
  864. WRITE_DATA(Integer, CPSLimit);
  865. WRITE_DATA(Bool, NewerOnly);
  866. WRITE_DATA(Bool, EncryptNewFiles);
  867. WRITE_DATA(Bool, ExcludeHiddenFiles);
  868. }
  869. //---------------------------------------------------------------------------
  870. #define C(Property) (Property == rhp.Property)
  871. bool __fastcall TCopyParamType::operator==(const TCopyParamType & rhp) const
  872. {
  873. DebugAssert(FTransferSkipList.get() == NULL);
  874. DebugAssert(FTransferResumeFile.IsEmpty());
  875. DebugAssert(rhp.FTransferSkipList.get() == NULL);
  876. DebugAssert(rhp.FTransferResumeFile.IsEmpty());
  877. return
  878. C(AddXToDirectories) &&
  879. C(AsciiFileMask) &&
  880. C(FileNameCase) &&
  881. C(PreserveReadOnly) &&
  882. C(PreserveTime) &&
  883. C(PreserveTimeDirs) &&
  884. C(PreserveRights) &&
  885. C(IgnorePermErrors) &&
  886. C(Rights) &&
  887. C(TransferMode) &&
  888. C(ResumeSupport) &&
  889. C(ResumeThreshold) &&
  890. C(InvalidCharsReplacement) &&
  891. C(LocalInvalidChars) &&
  892. C(CalculateSize) &&
  893. C(IncludeFileMask) &&
  894. C(ClearArchive) &&
  895. C(RemoveCtrlZ) &&
  896. C(RemoveBOM) &&
  897. C(CPSLimit) &&
  898. C(NewerOnly) &&
  899. C(EncryptNewFiles) &&
  900. C(ExcludeHiddenFiles) &&
  901. true;
  902. }
  903. #undef C
  904. //---------------------------------------------------------------------------
  905. static bool __fastcall TryGetSpeedLimit(const UnicodeString & Text, unsigned long & Speed)
  906. {
  907. bool Result;
  908. if (AnsiSameText(Text, LoadStr(SPEED_UNLIMITED)))
  909. {
  910. Speed = 0;
  911. Result = true;
  912. }
  913. else
  914. {
  915. int SSpeed;
  916. Result = TryStrToInt(Text, SSpeed) && (SSpeed >= 0);
  917. if (Result)
  918. {
  919. Speed = SSpeed * 1024;
  920. }
  921. }
  922. return Result;
  923. }
  924. //---------------------------------------------------------------------------
  925. unsigned long __fastcall GetSpeedLimit(const UnicodeString & Text)
  926. {
  927. unsigned long Speed;
  928. if (!TryGetSpeedLimit(Text, Speed))
  929. {
  930. throw Exception(FMTLOAD(SPEED_INVALID, (Text)));
  931. }
  932. return Speed;
  933. }
  934. //---------------------------------------------------------------------------
  935. UnicodeString __fastcall SetSpeedLimit(unsigned long Limit)
  936. {
  937. UnicodeString Text;
  938. if (Limit == 0)
  939. {
  940. Text = LoadStr(SPEED_UNLIMITED);
  941. }
  942. else
  943. {
  944. Text = IntToStr(int(Limit / 1024));
  945. }
  946. return Text;
  947. }
  948. //---------------------------------------------------------------------------
  949. void __fastcall CopySpeedLimits(TStrings * Source, TStrings * Dest)
  950. {
  951. std::unique_ptr<TStringList> Temp(new TStringList());
  952. bool Unlimited = false;
  953. for (int Index = 0; Index < Source->Count; Index++)
  954. {
  955. UnicodeString Text = Source->Strings[Index];
  956. unsigned long Speed;
  957. bool Valid = TryGetSpeedLimit(Text, Speed);
  958. if ((!Valid || (Speed == 0)) && !Unlimited)
  959. {
  960. Temp->Add(LoadStr(SPEED_UNLIMITED));
  961. Unlimited = true;
  962. }
  963. else if (Valid && (Speed > 0))
  964. {
  965. Temp->Add(Text);
  966. }
  967. }
  968. if (!Unlimited)
  969. {
  970. Temp->Insert(0, LoadStr(SPEED_UNLIMITED));
  971. }
  972. Dest->Assign(Temp.get());
  973. }
  974. //---------------------------------------------------------------------------
  975. TOperationSide ReverseOperationSide(TOperationSide Side)
  976. {
  977. TOperationSide Result;
  978. switch (Side)
  979. {
  980. case osLocal:
  981. Result = osRemote;
  982. break;
  983. case osRemote:
  984. Result = osLocal;
  985. break;
  986. default:
  987. case osCurrent:
  988. DebugFail();
  989. Result = Side;
  990. break;
  991. }
  992. return Result;
  993. }