public static void WriteEntryToFile(IEntry entry, string destinationFileName, ExtractionOptions options, Action <string, FileMode> openAndWrite) { if (entry.LinkTarget != null) { if (null == options.WriteSymbolicLink) { throw new ExtractionException("Entry is a symbolic link but ExtractionOptions.WriteSymbolicLink delegate is null"); } options.WriteSymbolicLink(destinationFileName, entry.LinkTarget); } else { FileMode fm = FileMode.Create; options = options ?? new ExtractionOptions() { Overwrite = true }; if (!options.Overwrite) { fm = FileMode.CreateNew; } openAndWrite(destinationFileName, fm); entry.PreserveExtractionOptions(destinationFileName, options); } }
/// <summary> /// Extract to specific directory, retaining filename /// </summary> public static void WriteEntryToDirectory(IEntry entry, string destinationDirectory, ExtractionOptions options = null, Action <string, ExtractionOptions> write = null) { string destinationFileName; string file = Path.GetFileName(entry.Key); string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory); options = options != null? options:new ExtractionOptions() { Overwrite = true }; if (options.ExtractFullPath) { string folder = Path.GetDirectoryName(entry.Key); string destdir = Path.GetFullPath( Path.Combine(fullDestinationDirectoryPath, folder) ); if (!Directory.Exists(destdir)) { if (!destdir.StartsWith(fullDestinationDirectoryPath)) { throw new ExtractionException("Entry is trying to create a directory outside of the destination directory."); } Directory.CreateDirectory(destdir); } destinationFileName = Path.Combine(destdir, file); } else { destinationFileName = Path.Combine(fullDestinationDirectoryPath, file); } if (!entry.IsDirectory) { destinationFileName = Path.GetFullPath(destinationFileName); if (!destinationFileName.StartsWith(fullDestinationDirectoryPath)) { throw new ExtractionException("Entry is trying to write a file outside of the destination directory."); } write(destinationFileName, options); } else if (options.ExtractFullPath && !Directory.Exists(destinationFileName)) { Directory.CreateDirectory(destinationFileName); } }
public static void WriteEntryToFile(IEntry entry, string destinationFileName, ExtractionOptions options, Action <string, FileMode> openAndWrite) { FileMode fm = FileMode.Create; options = options ?? new ExtractionOptions() { Overwrite = true }; if (!options.Overwrite) { fm = FileMode.CreateNew; } openAndWrite(destinationFileName, fm); entry.PreserveExtractionOptions(destinationFileName, options); }
internal static void PreserveExtractionOptions(this IEntry entry, string destinationFileName, ExtractionOptions options) { if (options.PreserveFileTime || options.PreserveAttributes) { FileInfo nf = new FileInfo(destinationFileName); if (!nf.Exists) { return; } // update file time to original packed time if (options.PreserveFileTime) { if (entry.CreatedTime.HasValue) { nf.CreationTime = entry.CreatedTime.Value; } if (entry.LastModifiedTime.HasValue) { nf.LastWriteTime = entry.LastModifiedTime.Value; } if (entry.LastAccessedTime.HasValue) { nf.LastAccessTime = entry.LastAccessedTime.Value; } } if (options.PreserveAttributes) { if (entry.Attrib.HasValue) { nf.Attributes = (FileAttributes)System.Enum.ToObject(typeof(FileAttributes), entry.Attrib.Value); } } options?.PostWriteHandler(entry, destinationFileName); } }
/// <summary> /// Extract to specific directory, retaining filename /// </summary> public static void WriteEntryToDirectory(IEntry entry, string destinationDirectory, ExtractionOptions options, Action <string, ExtractionOptions> write) { string destinationFileName; string file = Path.GetFileName(entry.Key); string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory); options = options ?? new ExtractionOptions() { Overwrite = true }; if (options.ExtractFullPath) { string folder = Path.GetDirectoryName(entry.Key); if (options.StripComponents.HasValue) { folder = folder.Trim(_PathComponentsSeparators); folder += '/'; var folderLength = folder.Length; var stripIndex = 0; for (int n = 0, c = options.StripComponents.Value; n < c; n++) { stripIndex = folder.IndexOfAny(_PathComponentsSeparators, stripIndex); if (stripIndex < 0) { return; // mimic tar --strip-components behavior, i.e. throw away content not deep enough } // consider multiple sequential path component separators as one stripIndex++; while (stripIndex < folderLength) { var strip = false; var chr = folder[stripIndex]; for (int i = 0; i < _PathComponentsSeparators.Length; i++) { if (chr == _PathComponentsSeparators[i]) { strip = true; break; } } if (strip) { stripIndex++; } else { break; } } } folder = folder.Substring(stripIndex).TrimEnd('/'); } string destdir = Path.GetFullPath( Path.Combine(fullDestinationDirectoryPath, folder) ); if (!Directory.Exists(destdir)) { if (!destdir.StartsWith(fullDestinationDirectoryPath)) { throw new ExtractionException("Entry is trying to create a directory outside of the destination directory."); } Directory.CreateDirectory(destdir); } destinationFileName = Path.Combine(destdir, file); } else { destinationFileName = Path.Combine(fullDestinationDirectoryPath, file); } if (!entry.IsDirectory) { destinationFileName = Path.GetFullPath(destinationFileName); if (!destinationFileName.StartsWith(fullDestinationDirectoryPath)) { throw new ExtractionException("Entry is trying to write a file outside of the destination directory."); } write(destinationFileName, options); } else if (options.ExtractFullPath && !Directory.Exists(destinationFileName)) { Directory.CreateDirectory(destinationFileName); } }
/// <summary> /// Extract to specific directory, retaining filename /// </summary> public static void WriteEntryToDirectory(IEntry entry, string destinationDirectory, ExtractionOptions options, Action <string, ExtractionOptions> write) { string destinationFileName; string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory); //check for trailing slash. if (fullDestinationDirectoryPath[fullDestinationDirectoryPath.Length - 1] != Path.DirectorySeparatorChar) { fullDestinationDirectoryPath += Path.DirectorySeparatorChar; } if (!Directory.Exists(fullDestinationDirectoryPath)) { throw new ExtractionException($"Directory does not exist to extract to: {fullDestinationDirectoryPath}"); } if (options == null) { options = new ExtractionOptions() { Overwrite = true } } ; string file = Path.GetFileName(entry.Key); if (options.ExtractFullPath) { string folder = Path.GetDirectoryName(entry.Key); string destdir = Path.GetFullPath(Path.Combine(fullDestinationDirectoryPath, folder)); if (!Directory.Exists(destdir)) { if (!destdir.StartsWith(fullDestinationDirectoryPath, StringComparison.Ordinal)) { throw new ExtractionException("Entry is trying to create a directory outside of the destination directory."); } Directory.CreateDirectory(destdir); } destinationFileName = Path.Combine(destdir, file); } else { destinationFileName = Path.Combine(fullDestinationDirectoryPath, file); } if (!entry.IsDirectory) { destinationFileName = Path.GetFullPath(destinationFileName); if (!destinationFileName.StartsWith(fullDestinationDirectoryPath, StringComparison.Ordinal)) { throw new ExtractionException("Entry is trying to write a file outside of the destination directory."); } write(destinationFileName, options); } else if (options.ExtractFullPath && !Directory.Exists(destinationFileName)) { Directory.CreateDirectory(destinationFileName); } }