diff --git a/ATXCommon/FsUtils.cs b/ATXCommon/FsUtils.cs index 9a816efcc2581025bcca62bc84d487065daccd2b..3f537683accdbc0cbe077b6bf07c2c255725a1e7 100644 --- a/ATXCommon/FsUtils.cs +++ b/ATXCommon/FsUtils.cs @@ -200,5 +200,56 @@ namespace ATXCommon retval &= CheckForDirectory(Path.Combine(managed, "UNMATCHED")); return retval; } + + /// <summary> + /// Move all subdirectories of a given path into a destination directory. The destination + /// will be created if it doesn't exist yet. If a subdirectory of the same name already + /// exists in the destination, a timestamp-suffix is added to the new one. + /// </summary> + /// <param name="sourceDir">The source path as DirectoryInfo object.</param> + /// <param name="destPath">The destination path as a string.</param> + /// <param name="resetAcls">Whether to reset the ACLs on the moved subdirectories.</param> + /// <returns>True on success, false otherwise.</returns> + public static bool MoveAllSubDirs(DirectoryInfo sourceDir, string destPath, bool resetAcls = false) { + // TODO: check whether _transferState should be adjusted while moving dirs! + Log.Debug("MoveAllSubDirs: [{0}] to [{1}]", sourceDir.FullName, destPath); + try { + // make sure the target directory that should hold all subdirectories to + // be moved is existing: + if (string.IsNullOrEmpty(FsUtils.CreateNewDirectory(destPath, false))) { + Log.Warn("WARNING: destination path doesn't exist: {0}", destPath); + return false; + } + + foreach (var subDir in sourceDir.GetDirectories()) { + var target = Path.Combine(destPath, subDir.Name); + // make sure NOT to overwrite the subdirectories: + if (Directory.Exists(target)) + target += "_" + TimeUtils.Timestamp(); + Log.Debug(" - [{0}] > [{1}]", subDir.Name, target); + subDir.MoveTo(target); + + if (!resetAcls) + continue; + + try { + var acl = Directory.GetAccessControl(target); + acl.SetAccessRuleProtection(false, false); + Directory.SetAccessControl(target, acl); + Log.Debug("Successfully reset inherited ACLs on [{0}]", target); + } + catch (Exception ex) { + Log.Error("Error resetting inherited ACLs on [{0}]:\n{1}", + target, ex.Message); + } + } + } + catch (Exception ex) { + Log.Error("Error moving directories: [{0}] > [{1}]\n{2}", + sourceDir.FullName, destPath, ex.Message); + return false; + } + return true; + } } } diff --git a/AutoTx/AutoTx.cs b/AutoTx/AutoTx.cs index afac1d3816591f9ae0e75fceb0cde3054e6eea2b..f5b4eb873d87e9e757a621cc34348f94d1dfc127 100644 --- a/AutoTx/AutoTx.cs +++ b/AutoTx/AutoTx.cs @@ -618,8 +618,8 @@ namespace AutoTx Log.Debug("Finalizing transfer, cleaning up target storage location..."); var finalDst = DestinationPath(_status.CurrentTargetTmp); if (!string.IsNullOrWhiteSpace(finalDst)) { - if (MoveAllSubDirs(new DirectoryInfo(_status.CurrentTargetTmpFull()), - finalDst, true)) { + if (FsUtils.MoveAllSubDirs(new DirectoryInfo(_status.CurrentTargetTmpFull()), + finalDst, _config.EnforceInheritedACLs)) { _status.CurrentTargetTmp = ""; } } @@ -687,7 +687,7 @@ namespace AutoTx target, TimeUtils.Timestamp(), userDir.Name); - if (MoveAllSubDirs(userDir, targetDir)) + if (FsUtils.MoveAllSubDirs(userDir, targetDir)) return; errMsg = "unable to move " + userDir.FullName; } @@ -711,10 +711,10 @@ namespace AutoTx "DONE", sourceDirectory.Name, // the username directory TimeUtils.Timestamp()); - // writeLogDebug("MoveToGraceLocation: src(" + sourceDirectory.FullName + ") dst(" + dstPath + ")"); + Log.Trace("MoveToGraceLocation: src({0}) dst({1})", sourceDirectory.FullName, dstPath); try { - if (MoveAllSubDirs(sourceDirectory, dstPath)) { + if (FsUtils.MoveAllSubDirs(sourceDirectory, dstPath)) { // clean up the processing location: sourceDirectory.Delete(); if (sourceDirectory.Parent != null) @@ -732,56 +732,6 @@ namespace AutoTx Log.Error("MoveToGraceLocation() failed: {0}", errMsg); } - /// <summary> - /// Move all subdirectories of a given path into a destination directory. The destination - /// will be created if it doesn't exist yet. If a subdirectory of the same name already - /// exists in the destination, a timestamp-suffix is added to the new one. - /// </summary> - /// <param name="sourceDir">The source path as DirectoryInfo object.</param> - /// <param name="destPath">The destination path as a string.</param> - /// <param name="resetAcls">Whether to reset the ACLs on the moved subdirectories.</param> - /// <returns>True on success, false otherwise.</returns> - private bool MoveAllSubDirs(DirectoryInfo sourceDir, string destPath, bool resetAcls = false) { - // TODO: check whether _transferState should be adjusted while moving dirs! - Log.Debug("MoveAllSubDirs: [{0}] to [{1}]", sourceDir.FullName, destPath); - try { - // make sure the target directory that should hold all subdirectories to - // be moved is existing: - if (string.IsNullOrEmpty(FsUtils.CreateNewDirectory(destPath, false))) { - Log.Warn("WARNING: destination path doesn't exist: {0}", destPath); - return false; - } - - foreach (var subDir in sourceDir.GetDirectories()) { - var target = Path.Combine(destPath, subDir.Name); - // make sure NOT to overwrite the subdirectories: - if (Directory.Exists(target)) - target += "_" + TimeUtils.Timestamp(); - Log.Debug(" - [{0}] > [{1}]", subDir.Name, target); - subDir.MoveTo(target); - - if (resetAcls && _config.EnforceInheritedACLs) { - try { - var acl = Directory.GetAccessControl(target); - acl.SetAccessRuleProtection(false, false); - Directory.SetAccessControl(target, acl); - Log.Debug("Successfully reset inherited ACLs on [{0}]", target); - } - catch (Exception ex) { - Log.Error("Error resetting inherited ACLs on [{0}]:\n{1}", - target, ex.Message); - } - } - } - } - catch (Exception ex) { - Log.Error("Error moving directories: [{0}] > [{1}]\n{2}", - sourceDir.FullName, destPath, ex.Message); - return false; - } - return true; - } - /// <summary> /// Helper to create directories for all users that have one in the local /// user directory (C:\Users) AND in the DestinationDirectory.