public static void MyLister(TarArchive ta, TarEntry te, string msg) { if (te.Size > 0) { Console.WriteLine(te.Name + " " + te.Size); totalsize = totalsize + 1; } }
private void WriteObjectToTar (TarOutputStream tar_out, FileSystemObject fso, EventTracker tracker) { MemoryStream memory = null; TarHeader header; header = new TarHeader (); StringBuilder name_builder; name_builder = new StringBuilder (fso.FullName); name_builder.Remove (0, this.FullName.Length+1); header.Name = name_builder.ToString (); header.ModTime = fso.Timestamp; if (fso is DirectoryObject) { header.Mode = 511; // 0777 header.TypeFlag = TarHeader.LF_DIR; header.Size = 0; } else { header.Mode = 438; // 0666 header.TypeFlag = TarHeader.LF_NORMAL; memory = new MemoryStream (); ((FileObject) fso).AddToStream (memory, tracker); header.Size = memory.Length; } TarEntry entry; entry = new TarEntry (header); tar_out.PutNextEntry (entry); if (memory != null) { tar_out.Write (memory.ToArray (), 0, (int) memory.Length); memory.Close (); } tar_out.CloseEntry (); // If this is a directory, write out the children if (fso is DirectoryObject) foreach (FileSystemObject child in fso.Children) WriteObjectToTar (tar_out, child, tracker); }
/// <summary> /// Raises the ProgressMessage event /// </summary> /// <param name="entry">The <see cref="TarEntry">TarEntry</see> for this event</param> /// <param name="message">message for this event. Null is no message</param> protected virtual void OnProgressMessageEvent(TarEntry entry, string message) { ProgressMessageHandler handler = ProgressMessageEvent; if (handler != null) { handler(this, entry, message); } }
private void ExtractEntry(string destDir, TarEntry entry, ICSharpCode.SharpZipLib.Tar.TarInputStream stream) { string name = entry.Name; if (Path.IsPathRooted(name)) name = name.Substring(Path.GetPathRoot(name).Length); name = name.Replace('/', Path.DirectorySeparatorChar); name = name.Substring(name.IndexOf(Path.DirectorySeparatorChar) + 1); string dest = Path.Combine(destDir, name); if (entry.IsDirectory) Directory.CreateDirectory(dest); else { Directory.CreateDirectory(Path.GetDirectoryName(dest)); using (Stream outputStream = File.Create(dest)) { stream.CopyEntryContents(outputStream); } } }
/// <summary> /// Get the next entry in this tar archive. This will skip /// over any remaining data in the current entry, if there /// is one, and place the input stream at the header of the /// next entry, and read the header and instantiate a new /// TarEntry from the header bytes and return that entry. /// If there are no more entries in the archive, null will /// be returned to indicate that the end of the archive has /// been reached. /// </summary> /// <returns> /// The next TarEntry in the archive, or null. /// </returns> public TarEntry GetNextEntry() { if (hasHitEOF) { return(null); } if (currentEntry != null) { SkipToNextEntry(); } byte[] headerBuf = tarBuffer.ReadBlock(); if (headerBuf == null) { hasHitEOF = true; } else if (TarBuffer.IsEndOfArchiveBlock(headerBuf)) { hasHitEOF = true; } if (hasHitEOF) { currentEntry = null; } else { try { TarHeader header = new TarHeader(); header.ParseBuffer(headerBuf); if (!header.IsChecksumValid) { throw new TarException("Header checksum is invalid"); } this.entryOffset = 0; this.entrySize = header.Size; StringBuilder longName = null; if (header.TypeFlag == TarHeader.LF_GNU_LONGNAME) { byte[] nameBuffer = new byte[TarBuffer.BlockSize]; long numToRead = this.entrySize; longName = new StringBuilder(); while (numToRead > 0) { int numRead = this.Read(nameBuffer, 0, (numToRead > nameBuffer.Length ? nameBuffer.Length : (int)numToRead)); if (numRead == -1) { throw new InvalidHeaderException("Failed to read long name entry"); } longName.Append(TarHeader.ParseName(nameBuffer, 0, numRead).ToString()); numToRead -= numRead; } SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GHDR) // POSIX global extended header // Ignore things we dont understand completely for now { SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_XHDR) // POSIX extended header // Ignore things we dont understand completely for now { SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR) { // TODO: could show volume name when verbose SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag != TarHeader.LF_NORMAL && header.TypeFlag != TarHeader.LF_OLDNORM && header.TypeFlag != TarHeader.LF_DIR) { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = tarBuffer.ReadBlock(); } if (entryFactory == null) { currentEntry = new TarEntry(headerBuf); if (longName != null) { currentEntry.Name = longName.ToString(); } } else { currentEntry = entryFactory.CreateEntry(headerBuf); } // Magic was checked here for 'ustar' but there are multiple valid possibilities // so this is not done anymore. entryOffset = 0; // TODO: Review How do we resolve this discrepancy?! entrySize = this.currentEntry.Size; } catch (InvalidHeaderException ex) { entrySize = 0; entryOffset = 0; currentEntry = null; string errorText = string.Format("Bad header in record {0} block {1} {2}", tarBuffer.CurrentRecord, tarBuffer.CurrentBlock, ex.Message); throw new InvalidHeaderException(errorText); } } return(currentEntry); }
/// <summary> /// Write an entry to the archive. This method will call the putNextEntry /// and then write the contents of the entry, and finally call closeEntry() /// for entries that are files. For directories, it will call putNextEntry(), /// and then, if the recurse flag is true, process each entry that is a /// child of the directory. /// </summary> /// <param name="sourceEntry"> /// The TarEntry representing the entry to write to the archive. /// </param> /// <param name="recurse"> /// If true, process the children of directory entries. /// </param> void WriteEntryCore(TarEntry sourceEntry, bool recurse) { string tempFileName = null; string entryFilename = sourceEntry.File; TarEntry entry = (TarEntry)sourceEntry.Clone(); if (applyUserInfoOverrides) { entry.GroupId = groupId; entry.GroupName = groupName; entry.UserId = userId; entry.UserName = userName; } OnProgressMessageEvent(entry, null); if (asciiTranslate && !entry.IsDirectory) { if (!IsBinary(entryFilename)) { tempFileName = Path.GetTempFileName(); using (StreamReader inStream = File.OpenText(entryFilename)) { using (Stream outStream = File.Create(tempFileName)) { while (true) { string line = inStream.ReadLine(); if (line == null) { break; } byte[] data = Encoding.ASCII.GetBytes(line); outStream.Write(data, 0, data.Length); outStream.WriteByte((byte)'\n'); } outStream.Flush(); } } entry.Size = new FileInfo(tempFileName).Length; entryFilename = tempFileName; } } string newName = null; if (rootPath != null) { if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) { newName = entry.Name.Substring(rootPath.Length + 1); } } if (pathPrefix != null) { newName = (newName == null) ? pathPrefix + "/" + entry.Name : pathPrefix + "/" + newName; } if (newName != null) { entry.Name = newName; } tarOut.PutNextEntry(entry); if (entry.IsDirectory) { if (recurse) { TarEntry[] list = entry.GetDirectoryEntries(); for (int i = 0; i < list.Length; ++i) { WriteEntryCore(list[i], recurse); } } } else { using (Stream inputStream = File.OpenRead(entryFilename)) { byte[] localBuffer = new byte[32 * 1024]; while (true) { int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length); if (numRead <= 0) { break; } tarOut.Write(localBuffer, 0, numRead); } } if ((tempFileName != null) && (tempFileName.Length > 0)) { File.Delete(tempFileName); } tarOut.CloseEntry(); } }
/// <summary> /// Get the next entry in this tar archive. This will skip /// over any remaining data in the current entry, if there /// is one, and place the input stream at the header of the /// next entry, and read the header and instantiate a new /// TarEntry from the header bytes and return that entry. /// If there are no more entries in the archive, null will /// be returned to indicate that the end of the archive has /// been reached. /// </summary> /// <returns> /// The next TarEntry in the archive, or null. /// </returns> public TarEntry GetNextEntry() { if (this.hasHitEOF) { return(null); } if (this.currEntry != null) { SkipToNextEntry(); } byte[] headerBuf = this.buffer.ReadBlock(); if (headerBuf == null) { if (this.debug) { //Console.WriteLine.WriteLine("READ NULL BLOCK"); } this.hasHitEOF = true; } else if (this.buffer.IsEOFBlock(headerBuf)) { if (this.debug) { //Console.WriteLine.WriteLine( "READ EOF BLOCK" ); } this.hasHitEOF = true; } if (this.hasHitEOF) { this.currEntry = null; } else { try { TarHeader header = new TarHeader(); header.ParseBuffer(headerBuf); this.entryOffset = 0; this.entrySize = (int)header.size; StringBuilder longName = null; if (header.typeFlag == TarHeader.LF_GNU_LONGNAME) { Console.WriteLine("TarInputStream: Long name found '" + header.name + "' size = " + header.size); // DEBUG byte[] nameBuffer = new byte[TarBuffer.BlockSize]; int numToRead = this.entrySize; longName = new StringBuilder(); while (numToRead > 0) { int numRead = this.Read(nameBuffer, 0, (numToRead > nameBuffer.Length ? nameBuffer.Length : numToRead)); if (numRead == -1) { throw new InvalidHeaderException("Failed to read long name entry"); } longName.Append(TarHeader.ParseName(nameBuffer, 0, numRead).ToString()); numToRead -= numRead; } Console.WriteLine("TarInputStream: Long name is '" + longName.ToString()); // DEBUG SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.typeFlag == TarHeader.LF_GHDR) // POSIX global extended header { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.typeFlag == TarHeader.LF_XHDR) // POSIX extended header { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.typeFlag == TarHeader.LF_GNU_VOLHDR) { // TODO could show volume name when verbose? SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.typeFlag != TarHeader.LF_NORMAL && header.typeFlag != TarHeader.LF_OLDNORM) { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } if (this.eFactory == null) { this.currEntry = new TarEntry(headerBuf); if (longName != null) { this.currEntry.TarHeader.name.Length = 0; this.currEntry.TarHeader.name.Append(longName.ToString()); } } else { this.currEntry = this.eFactory.CreateEntry(headerBuf); } // TODO -jr- ustar is not the only magic possible by any means // tar, xtar, ... if (!(headerBuf[257] == 'u' && headerBuf[258] == 's' && headerBuf[259] == 't' && headerBuf[260] == 'a' && headerBuf[261] == 'r')) { throw new InvalidHeaderException("header magic is not 'ustar', but '" + headerBuf[257] + headerBuf[258] + headerBuf[259] + headerBuf[260] + headerBuf[261] + "', or (dec) " + ((int)headerBuf[257]) + ", " + ((int)headerBuf[258]) + ", " + ((int)headerBuf[259]) + ", " + ((int)headerBuf[260]) + ", " + ((int)headerBuf[261])); } if (this.debug) { //Console.WriteLine.WriteLine("TarInputStream: SET CURRENTRY '" + this.currEntry.Name + "' size = " + this.currEntry.Size); } this.entryOffset = 0; // TODO REVIEW How do we resolve this discrepancy?! this.entrySize = (int)this.currEntry.Size; } catch (InvalidHeaderException ex) { this.entrySize = 0; this.entryOffset = 0; this.currEntry = null; throw new InvalidHeaderException("bad header in record " + this.buffer.GetCurrentBlockNum() + " block " + this.buffer.GetCurrentBlockNum() + ", " + ex.Message); } } return(this.currEntry); }
private void ExtractEntry(string destDir, TarEntry entry) { this.OnProgressMessageEvent(entry, null); string name = entry.Name; if (Path.IsPathRooted(name)) { name = name.Substring(Path.GetPathRoot(name).Length); } name = name.Replace('/', Path.DirectorySeparatorChar); string directoryName = Path.Combine(destDir, name); if (entry.IsDirectory) { EnsureDirectoryExists(directoryName); } else { EnsureDirectoryExists(Path.GetDirectoryName(directoryName)); bool flag = true; FileInfo info = new FileInfo(directoryName); if (info.Exists) { if (this.keepOldFiles) { this.OnProgressMessageEvent(entry, "Destination file already exists"); flag = false; } else if ((info.Attributes & FileAttributes.ReadOnly) != 0) { this.OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); flag = false; } } if (flag) { bool flag2 = false; Stream stream = File.Create(directoryName); if (this.asciiTranslate) { flag2 = !IsBinary(directoryName); } StreamWriter writer = null; if (flag2) { writer = new StreamWriter(stream); } byte[] buffer = new byte[0x8000]; while (true) { int count = this.tarIn.Read(buffer, 0, buffer.Length); if (count <= 0) { if (!flag2) { stream.Close(); break; } writer.Close(); return; } if (!flag2) { stream.Write(buffer, 0, count); continue; } int index = 0; for (int i = 0; i < count; i++) { if (buffer[i] == 10) { writer.WriteLine(Encoding.ASCII.GetString(buffer, index, i - index)); index = i + 1; } } } } } }
/// <summary> /// Extract an entry from the archive. This method assumes that the /// tarIn stream has been properly set with a call to getNextEntry(). /// </summary> /// <param name="destDir"> /// The destination directory into which to extract. /// </param> /// <param name="entry"> /// The TarEntry returned by tarIn.getNextEntry(). /// </param> void ExtractEntry(string destDir, TarEntry entry) { if (this.verbose) { OnProgressMessageEvent(entry, null); } string name = entry.Name; name = name.Replace('/', Path.DirectorySeparatorChar); if (!destDir.EndsWith(Path.DirectorySeparatorChar.ToString())) { destDir += Path.DirectorySeparatorChar; } string destFile = destDir + name; if (entry.IsDirectory) { EnsureDirectoryExists(destFile); } else { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); if (this.keepOldFiles && File.Exists(destFile)) { if (this.verbose) { OnProgressMessageEvent(entry, "Destination file already exists"); } } else { bool asciiTrans = false; Stream outputStream = File.Create(destFile); if (this.asciiTranslate) { asciiTrans = !IsBinary(destFile); // original java sourcecode : // MimeType mime = null; // string contentType = null; // try { // contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile ); // // mime = new MimeType(contentType); // // if (mime.getPrimaryType().equalsIgnoreCase( "text" )) { // asciiTrans = true; // } else if ( this.transTyper != null ) { // if ( this.transTyper.isAsciiFile( entry.getName() ) ) { // asciiTrans = true; // } // } // } catch (MimeTypeParseException ex) { // } // // if (this.debug) { // Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "' ContentType='" + contentType + "' PrimaryType='" + mime.getPrimaryType() + "'" ); // } } StreamWriter outw = null; if (asciiTrans) { outw = new StreamWriter(outputStream); } byte[] rdbuf = new byte[32 * 1024]; while (true) { int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length); if (numRead <= 0) { break; } if (asciiTrans) { for (int off = 0, b = 0; b < numRead; ++b) { if (rdbuf[b] == 10) { string s = Encoding.ASCII.GetString(rdbuf, off, (b - off)); outw.WriteLine(s); off = b + 1; } } } else { outputStream.Write(rdbuf, 0, numRead); } } if (asciiTrans) { outw.Close(); } else { outputStream.Close(); } } } }
/// <summary> /// Extract an entry from the archive. This method assumes that the /// tarIn stream has been properly set with a call to GetNextEntry(). /// </summary> /// <param name="destDir"> /// The destination directory into which to extract. /// </param> /// <param name="entry"> /// The TarEntry returned by tarIn.GetNextEntry(). /// </param> /// <param name="allowParentTraversal">Allow parent directory traversal in file paths (e.g. ../file)</param> private void ExtractEntry(string destDir, TarEntry entry, bool allowParentTraversal) { OnProgressMessageEvent(entry, null); string name = entry.Name; if (Path.IsPathRooted(name)) { // NOTE: // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt name = name.Substring(Path.GetPathRoot(name).Length); } name = name.Replace('/', Path.DirectorySeparatorChar); string destFile = Path.Combine(destDir, name); if (!allowParentTraversal && !Path.GetFullPath(destFile).StartsWith(destDir, StringComparison.InvariantCultureIgnoreCase)) { throw new InvalidNameException("Parent traversal in paths is not allowed"); } if (entry.IsDirectory) { EnsureDirectoryExists(destFile); } else { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); bool process = true; var fileInfo = new FileInfo(destFile); if (fileInfo.Exists) { if (keepOldFiles) { OnProgressMessageEvent(entry, "Destination file already exists"); process = false; } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) { OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); process = false; } } if (process) { using (var outputStream = File.Create(destFile)) { if (this.asciiTranslate) { // May need to translate the file. ExtractAndTranslateEntry(destFile, outputStream); } else { // If translation is disabled, just copy the entry across directly. tarIn.CopyEntryContents(outputStream); } } } } }
private void WriteEntryCore(TarEntry sourceEntry, bool recurse) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) string text = null; string text2 = sourceEntry.File; TarEntry tarEntry = (TarEntry)sourceEntry.Clone(); if (applyUserInfoOverrides) { tarEntry.GroupId = groupId; tarEntry.GroupName = groupName; tarEntry.UserId = userId; tarEntry.UserName = userName; } OnProgressMessageEvent(tarEntry, null); if (asciiTranslate && !tarEntry.IsDirectory && !IsBinary(text2)) { text = Path.GetTempFileName(); StreamReader val = File.OpenText(text2); try { Stream val2 = (Stream)(object)File.Create(text); try { while (true) { string text3 = ((TextReader)val).ReadLine(); if (text3 == null) { break; } byte[] bytes = Encoding.get_ASCII().GetBytes(text3); val2.Write(bytes, 0, bytes.Length); val2.WriteByte((byte)10); } val2.Flush(); } finally { ((global::System.IDisposable)val2)?.Dispose(); } } finally { ((global::System.IDisposable)val)?.Dispose(); } tarEntry.Size = new FileInfo(text).get_Length(); text2 = text; } string text4 = null; if (rootPath != null && tarEntry.Name.StartsWith(rootPath)) { text4 = tarEntry.Name.Substring(rootPath.get_Length() + 1); } if (pathPrefix != null) { text4 = ((text4 == null) ? (pathPrefix + "/" + tarEntry.Name) : (pathPrefix + "/" + text4)); } if (text4 != null) { tarEntry.Name = text4; } tarOut.PutNextEntry(tarEntry); if (tarEntry.IsDirectory) { if (recurse) { TarEntry[] directoryEntries = tarEntry.GetDirectoryEntries(); for (int i = 0; i < directoryEntries.Length; i++) { WriteEntryCore(directoryEntries[i], recurse); } } return; } Stream val3 = (Stream)(object)File.OpenRead(text2); try { byte[] array = new byte[32768]; while (true) { int num = val3.Read(array, 0, array.Length); if (num > 0) { ((Stream)tarOut).Write(array, 0, num); continue; } break; } } finally { ((global::System.IDisposable)val3)?.Dispose(); } if (text != null && text.get_Length() > 0) { File.Delete(text); } tarOut.CloseEntry(); }
private void ExtractEntry(string destDir, TarEntry entry) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown OnProgressMessageEvent(entry, null); string text = entry.Name; if (Path.IsPathRooted(text)) { text = text.Substring(Path.GetPathRoot(text).get_Length()); } text = text.Replace('/', Path.DirectorySeparatorChar); string text2 = Path.Combine(destDir, text); if (entry.IsDirectory) { EnsureDirectoryExists(text2); return; } string directoryName = Path.GetDirectoryName(text2); EnsureDirectoryExists(directoryName); bool flag = true; FileInfo val = new FileInfo(text2); if (((FileSystemInfo)val).get_Exists()) { if (keepOldFiles) { OnProgressMessageEvent(entry, "Destination file already exists"); flag = false; } else if ((((FileSystemInfo)val).get_Attributes() & 1) != 0) { OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); flag = false; } } if (!flag) { return; } bool flag2 = false; Stream val2 = (Stream)(object)File.Create(text2); if (asciiTranslate) { flag2 = !IsBinary(text2); } StreamWriter val3 = null; if (flag2) { val3 = new StreamWriter(val2); } byte[] array = new byte[32768]; while (true) { int num = ((Stream)tarIn).Read(array, 0, array.Length); if (num <= 0) { break; } if (flag2) { int num2 = 0; for (int i = 0; i < num; i++) { if (array[i] == 10) { string @string = Encoding.get_ASCII().GetString(array, num2, i - num2); ((TextWriter)val3).WriteLine(@string); num2 = i + 1; } } } else { val2.Write(array, 0, num); } } if (flag2) { ((TextWriter)val3).Close(); } else { val2.Close(); } }
public TarEntry GetNextEntry() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown if (hasHitEOF) { return(null); } if (currentEntry != null) { SkipToNextEntry(); } byte[] array = tarBuffer.ReadBlock(); if (array == null) { hasHitEOF = true; } else if (TarBuffer.IsEndOfArchiveBlock(array)) { hasHitEOF = true; } if (hasHitEOF) { currentEntry = null; } else { try { TarHeader tarHeader = new TarHeader(); tarHeader.ParseBuffer(array); if (!tarHeader.IsChecksumValid) { throw new TarException("Header checksum is invalid"); } entryOffset = 0L; entrySize = tarHeader.Size; StringBuilder val = null; if (tarHeader.TypeFlag == 76) { byte[] array2 = new byte[512]; long num = entrySize; val = new StringBuilder(); while (num > 0) { int num2 = ((Stream)this).Read(array2, 0, (int)((num > array2.Length) ? array2.Length : num)); if (num2 == -1) { throw new InvalidHeaderException("Failed to read long name entry"); } val.Append(((object)TarHeader.ParseName(array2, 0, num2)).ToString()); num -= num2; } SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag == 103) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag == 120) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag == 86) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag != 48 && tarHeader.TypeFlag != 0 && tarHeader.TypeFlag != 53) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } if (entryFactory == null) { currentEntry = new TarEntry(array); if (val != null) { currentEntry.Name = ((object)val).ToString(); } } else { currentEntry = entryFactory.CreateEntry(array); } entryOffset = 0L; entrySize = currentEntry.Size; } catch (InvalidHeaderException ex) { entrySize = 0L; entryOffset = 0L; currentEntry = null; string message = $"Bad header in record {tarBuffer.CurrentRecord} block {tarBuffer.CurrentBlock} {((global::System.Exception)(object)ex).get_Message()}"; throw new InvalidHeaderException(message); } } return(currentEntry); }
public TarEntry GetNextEntry() { if (hasHitEOF) { return(null); } if (currentEntry != null) { SkipToNextEntry(); } byte[] array = tarBuffer.ReadBlock(); if (array == null) { hasHitEOF = true; } else if (TarBuffer.IsEndOfArchiveBlock(array)) { hasHitEOF = true; } if (hasHitEOF) { currentEntry = null; } else { try { TarHeader tarHeader = new TarHeader(); tarHeader.ParseBuffer(array); if (!tarHeader.IsChecksumValid) { throw new TarException("Header checksum is invalid"); } entryOffset = 0L; entrySize = tarHeader.Size; StringBuilder stringBuilder = null; if (tarHeader.TypeFlag == 76) { byte[] array2 = new byte[512]; long num = entrySize; stringBuilder = new StringBuilder(); while (num > 0) { int num2 = Read(array2, 0, (int)((num > array2.Length) ? array2.Length : num)); if (num2 == -1) { throw new InvalidHeaderException("Failed to read long name entry"); } stringBuilder.Append(TarHeader.ParseName(array2, 0, num2).ToString()); num -= num2; } SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag == 103) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag == 120) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag == 86) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } else if (tarHeader.TypeFlag != 48 && tarHeader.TypeFlag != 0 && tarHeader.TypeFlag != 53) { SkipToNextEntry(); array = tarBuffer.ReadBlock(); } if (entryFactory == null) { currentEntry = new TarEntry(array); if (stringBuilder != null) { currentEntry.Name = stringBuilder.ToString(); } } else { currentEntry = entryFactory.CreateEntry(array); } entryOffset = 0L; entrySize = currentEntry.Size; } catch (InvalidHeaderException ex) { entrySize = 0L; entryOffset = 0L; currentEntry = null; string message = $"Bad header in record {tarBuffer.CurrentRecord} block {tarBuffer.CurrentBlock} {ex.Message}"; throw new InvalidHeaderException(message); } } return(currentEntry); }
private void WriteEntryCore(TarEntry sourceEntry, bool recurse) { string text = null; string text2 = sourceEntry.File; TarEntry tarEntry = (TarEntry)sourceEntry.Clone(); if (this.applyUserInfoOverrides) { tarEntry.GroupId = this.groupId; tarEntry.GroupName = this.groupName; tarEntry.UserId = this.userId; tarEntry.UserName = this.userName; } this.OnProgressMessageEvent(tarEntry, null); if (this.asciiTranslate && !tarEntry.IsDirectory) { bool flag = !TarArchive.IsBinary(text2); if (flag) { text = Path.GetTempFileName(); using (StreamReader streamReader = File.OpenText(text2)) { using (Stream stream = File.Create(text)) { for (;;) { string text3 = streamReader.ReadLine(); if (text3 == null) { break; } byte[] bytes = Encoding.ASCII.GetBytes(text3); stream.Write(bytes, 0, bytes.Length); stream.WriteByte(10); } stream.Flush(); } } tarEntry.Size = new FileInfo(text).Length; text2 = text; } } string text4 = null; if (this.rootPath != null && tarEntry.Name.StartsWith(this.rootPath)) { text4 = tarEntry.Name.Substring(this.rootPath.Length + 1); } if (this.pathPrefix != null) { text4 = ((text4 == null) ? (this.pathPrefix + "/" + tarEntry.Name) : (this.pathPrefix + "/" + text4)); } if (text4 != null) { tarEntry.Name = text4; } this.tarOut.PutNextEntry(tarEntry); if (tarEntry.IsDirectory) { if (recurse) { TarEntry[] directoryEntries = tarEntry.GetDirectoryEntries(); for (int i = 0; i < directoryEntries.Length; i++) { this.WriteEntryCore(directoryEntries[i], recurse); } return; } } else { using (Stream stream2 = File.OpenRead(text2)) { int num = 0; byte[] array = new byte[32768]; for (;;) { int num2 = stream2.Read(array, 0, array.Length); if (num2 <= 0) { break; } this.tarOut.Write(array, 0, num2); num += num2; } } if (text != null && text.Length > 0) { File.Delete(text); } this.tarOut.CloseEntry(); } }
/// <summary> /// Extract an entry from the archive. This method assumes that the /// tarIn stream has been properly set with a call to getNextEntry(). /// </summary> /// <param name="destDir"> /// The destination directory into which to extract. /// </param> /// <param name="entry"> /// The TarEntry returned by tarIn.getNextEntry(). /// </param> void ExtractEntry(string destDir, TarEntry entry) { if (this.verbose) { OnProgressMessageEvent(entry, null); } string name = entry.Name; if (Path.IsPathRooted(name) == true) { // NOTE: // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt name = name.Substring(Path.GetPathRoot(name).Length); } name = name.Replace('/', Path.DirectorySeparatorChar); string destFile = Path.Combine(destDir, name); if (entry.IsDirectory) { EnsureDirectoryExists(destFile); } else { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); bool process = true; FileInfo fileInfo = new FileInfo(destFile); if (fileInfo.Exists) { if (this.keepOldFiles) { OnProgressMessageEvent(entry, "Destination file already exists"); process = false; } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) { OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); process = false; } } if (process) { bool asciiTrans = false; // TODO file may exist and be read-only at this point! Stream outputStream = File.Create(destFile); if (this.asciiTranslate) { asciiTrans = !IsBinary(destFile); // TODO do we need this stuff below? // original java sourcecode : // MimeType mime = null; // string contentType = null; // try { // contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile ); // // mime = new MimeType(contentType); // // if (mime.getPrimaryType().equalsIgnoreCase( "text" )) { // asciiTrans = true; // } else if ( this.transTyper != null ) { // if ( this.transTyper.isAsciiFile( entry.getName() ) ) { // asciiTrans = true; // } // } // } catch (MimeTypeParseException ex) { // } // // if (this.debug) { // Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "' ContentType='" + contentType + "' PrimaryType='" + mime.getPrimaryType() + "'" ); // } } StreamWriter outw = null; if (asciiTrans) { outw = new StreamWriter(outputStream); } byte[] rdbuf = new byte[32 * 1024]; while (true) { int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length); if (numRead <= 0) { break; } if (asciiTrans) { for (int off = 0, b = 0; b < numRead; ++b) { if (rdbuf[b] == 10) { string s = Encoding.ASCII.GetString(rdbuf, off, (b - off)); outw.WriteLine(s); off = b + 1; } } } else { outputStream.Write(rdbuf, 0, numRead); } } if (asciiTrans) { outw.Close(); } else { outputStream.Close(); } } } }
/// <summary> /// Determine if the given entry is a descendant of this entry. /// Descendancy is determined by the name of the descendant /// starting with this entry's name. /// </summary> /// <param name = "toTest"> /// Entry to be checked as a descendent of this. /// </param> /// <returns> /// True if entry is a descendant of this. /// </returns> public bool IsDescendent(TarEntry toTest) { return(toTest == null ? throw new ArgumentNullException(nameof(toTest)) : toTest.Name.StartsWith(Name, StringComparison.Ordinal)); }
/// <summary> /// Write an entry to the archive. This method will call the putNextEntry /// and then write the contents of the entry, and finally call closeEntry() /// for entries that are files. For directories, it will call putNextEntry(), /// and then, if the recurse flag is true, process each entry that is a /// child of the directory. /// </summary> /// <param name="sourceEntry"> /// The TarEntry representing the entry to write to the archive. /// </param> /// <param name="recurse"> /// If true, process the children of directory entries. /// </param> void InternalWriteEntry(TarEntry sourceEntry, bool recurse) { bool asciiTrans = false; string tempFileName = null; string entryFilename = sourceEntry.File; TarEntry entry = (TarEntry)sourceEntry.Clone(); if (applyUserInfoOverrides) { entry.GroupId = groupId; entry.GroupName = groupName; entry.UserId = userId; entry.UserName = userName; } OnProgressMessageEvent(entry, null); if (this.asciiTranslate && !entry.IsDirectory) { asciiTrans = !IsBinary(entryFilename); if (asciiTrans) { tempFileName = Path.GetTempFileName(); StreamReader inStream = File.OpenText(entryFilename); Stream outStream = File.Create(tempFileName); while (true) { string line = inStream.ReadLine(); if (line == null) { break; } byte[] data = Encoding.ASCII.GetBytes(line); outStream.Write(data, 0, data.Length); outStream.WriteByte((byte)'\n'); } inStream.Close(); outStream.Flush(); outStream.Close(); entry.Size = new FileInfo(tempFileName).Length; entryFilename = tempFileName; } } string newName = null; if (this.rootPath != null) { if (entry.Name.StartsWith(this.rootPath)) { newName = entry.Name.Substring(this.rootPath.Length + 1); } } if (this.pathPrefix != null) { newName = (newName == null) ? this.pathPrefix + "/" + entry.Name : this.pathPrefix + "/" + newName; } if (newName != null) { entry.Name = newName; } this.tarOut.PutNextEntry(entry); if (entry.IsDirectory) { if (recurse) { TarEntry[] list = entry.GetDirectoryEntries(); for (int i = 0; i < list.Length; ++i) { InternalWriteEntry(list[i], recurse); } } } else { Stream inputStream = File.OpenRead(entryFilename); int numWritten = 0; byte[] eBuf = new byte[32 * 1024]; while (true) { int numRead = inputStream.Read(eBuf, 0, eBuf.Length); if (numRead <= 0) { break; } this.tarOut.Write(eBuf, 0, numRead); numWritten += numRead; } inputStream.Close(); if (tempFileName != null && tempFileName.Length > 0) { File.Delete(tempFileName); } this.tarOut.CloseEntry(); } }
public bool IsDescendent(TarEntry toTest) => toTest?.Name.StartsWith(this.Name);
/// <summary> /// Write an entry to the archive. This method will call the putNextEntry /// and then write the contents of the entry, and finally call closeEntry()() /// for entries that are files. For directories, it will call putNextEntry(), /// and then, if the recurse flag is true, process each entry that is a /// child of the directory. /// </summary> /// <param name="entry"> /// The TarEntry representing the entry to write to the archive. /// </param> /// <param name="recurse"> /// If true, process the children of directory entries. /// </param> public void WriteEntry(TarEntry entry, bool recurse) { bool asciiTrans = false; string tempFileName = null; string eFile = entry.File; // Work on a copy of the entry so we can manipulate it. // Note that we must distinguish how the entry was constructed. // if (eFile == null || eFile.Length == 0) { entry = TarEntry.CreateTarEntry(entry.Name); } else { // // The user may have explicitly set the entry's name to // something other than the file's path, so we must save // and restore it. This should work even when the name // was set from the File's name. // string saveName = entry.Name; entry = TarEntry.CreateEntryFromFile(eFile); entry.Name = saveName; } if (this.verbose) { OnProgressMessageEvent(entry, null); } if (this.asciiTranslate && !entry.IsDirectory) { asciiTrans = !IsBinary(eFile); // original java source : // MimeType mime = null; // string contentType = null; // // try { // contentType = FileTypeMap.getDefaultFileTypeMap(). getContentType( eFile ); // // mime = new MimeType( contentType ); // // if ( mime.getPrimaryType(). // equalsIgnoreCase( "text" ) ) // { // asciiTrans = true; // } // else if ( this.transTyper != null ) // { // if ( this.transTyper.isAsciiFile( eFile ) ) // { // asciiTrans = true; // } // } // } catch ( MimeTypeParseException ex ) // { // // IGNORE THIS ERROR... // } // // if (this.debug) { // Console.Error.WriteLine("CREATE TRANS? '" + asciiTrans + "' ContentType='" + contentType + "' PrimaryType='" + mime.getPrimaryType()+ "'" ); // } if (asciiTrans) { tempFileName = Path.GetTempFileName(); StreamReader inStream = File.OpenText(eFile); Stream outStream = new BufferedStream(File.Create(tempFileName)); while (true) { string line = inStream.ReadLine(); if (line == null) { break; } byte[] data = Encoding.ASCII.GetBytes(line); outStream.Write(data, 0, data.Length); outStream.WriteByte((byte)'\n'); } inStream.Close(); outStream.Flush(); outStream.Close(); entry.Size = new FileInfo(tempFileName).Length; eFile = tempFileName; } } string newName = null; if (this.rootPath != null) { if (entry.Name.StartsWith(this.rootPath)) { newName = entry.Name.Substring(this.rootPath.Length + 1); } } if (this.pathPrefix != null) { newName = (newName == null) ? this.pathPrefix + "/" + entry.Name : this.pathPrefix + "/" + newName; } if (newName != null) { entry.Name = newName; } this.tarOut.PutNextEntry(entry); if (entry.IsDirectory) { if (recurse) { TarEntry[] list = entry.GetDirectoryEntries(); for (int i = 0; i < list.Length; ++i) { this.WriteEntry(list[i], recurse); } } } else { Stream inputStream = File.OpenRead(eFile); int numWritten = 0; byte[] eBuf = new byte[32 * 1024]; while (true) { int numRead = inputStream.Read(eBuf, 0, eBuf.Length); if (numRead <= 0) { break; } this.tarOut.Write(eBuf, 0, numRead); numWritten += numRead; } // Console.WriteLine("written " + numWritten + " bytes"); inputStream.Close(); if (tempFileName != null && tempFileName.Length > 0) { File.Delete(tempFileName); } this.tarOut.CloseEntry(); } }
public TarEntry GetNextEntry() { if (this.hasHitEOF) { return(null); } if (this.currentEntry != null) { this.SkipToNextEntry(); } byte[] block = this.tarBuffer.ReadBlock(); if (block == null) { this.hasHitEOF = true; } else if (TarBuffer.IsEndOfArchiveBlock(block)) { this.hasHitEOF = true; } if (this.hasHitEOF) { this.currentEntry = null; } else { try { TarHeader header = new TarHeader(); header.ParseBuffer(block); if (!header.IsChecksumValid) { throw new TarException("Header checksum is invalid"); } this.entryOffset = 0L; this.entrySize = header.Size; StringBuilder builder = null; if (header.TypeFlag == 0x4c) { byte[] buffer = new byte[0x200]; long entrySize = this.entrySize; builder = new StringBuilder(); while (entrySize > 0L) { int length = this.Read(buffer, 0, (entrySize > buffer.Length) ? buffer.Length : ((int)entrySize)); if (length == -1) { throw new InvalidHeaderException("Failed to read long name entry"); } builder.Append(TarHeader.ParseName(buffer, 0, length).ToString()); entrySize -= length; } this.SkipToNextEntry(); block = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == 0x67) { this.SkipToNextEntry(); block = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == 120) { this.SkipToNextEntry(); block = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == 0x56) { this.SkipToNextEntry(); block = this.tarBuffer.ReadBlock(); } else if (((header.TypeFlag != 0x30) && (header.TypeFlag != 0)) && (header.TypeFlag != 0x35)) { this.SkipToNextEntry(); block = this.tarBuffer.ReadBlock(); } if (this.entryFactory == null) { this.currentEntry = new TarEntry(block); if (builder != null) { this.currentEntry.Name = builder.ToString(); } } else { this.currentEntry = this.entryFactory.CreateEntry(block); } this.entryOffset = 0L; this.entrySize = this.currentEntry.Size; } catch (InvalidHeaderException exception) { this.entrySize = 0L; this.entryOffset = 0L; this.currentEntry = null; throw new InvalidHeaderException(string.Format("Bad header in record {0} block {1} {2}", this.tarBuffer.CurrentRecord, this.tarBuffer.CurrentBlock, exception.Message)); } } return(this.currentEntry); }
private void WriteEntryCore(TarEntry sourceEntry, bool recurse) { string path = null; string str3; string file = sourceEntry.File; TarEntry entry = (TarEntry)sourceEntry.Clone(); if (this.applyUserInfoOverrides) { entry.GroupId = this.groupId; entry.GroupName = this.groupName; entry.UserId = this.userId; entry.UserName = this.userName; } this.OnProgressMessageEvent(entry, null); if (this.asciiTranslate && (!entry.IsDirectory && !IsBinary(file))) { path = Path.GetTempFileName(); using (StreamReader reader = File.OpenText(file)) { Stream stream = File.Create(path); while (true) { try { while (true) { string s = reader.ReadLine(); if (s == null) { stream.Flush(); entry.Size = new FileInfo(path).Length; file = path; goto TR_0022; } else { byte[] bytes = Encoding.ASCII.GetBytes(s); stream.Write(bytes, 0, bytes.Length); stream.WriteByte(10); } break; } } finally { if (stream != null) { stream.Dispose(); } } } } } TR_0022: str3 = null; if ((this.rootPath != null) && entry.Name.StartsWith(this.rootPath, StringComparison.OrdinalIgnoreCase)) { str3 = entry.Name.Substring(this.rootPath.Length + 1); } if (this.pathPrefix != null) { str3 = (str3 == null) ? (this.pathPrefix + "/" + entry.Name) : (this.pathPrefix + "/" + str3); } if (str3 != null) { entry.Name = str3; } this.tarOut.PutNextEntry(entry); if (entry.IsDirectory) { if (recurse) { TarEntry[] directoryEntries = entry.GetDirectoryEntries(); for (int i = 0; i < directoryEntries.Length; i++) { this.WriteEntryCore(directoryEntries[i], recurse); } } } else { using (Stream stream2 = File.OpenRead(file)) { byte[] buffer = new byte[0x8000]; while (true) { int count = stream2.Read(buffer, 0, buffer.Length); if (count <= 0) { break; } this.tarOut.Write(buffer, 0, count); } } if ((path != null) && (path.Length > 0)) { File.Delete(path); } this.tarOut.CloseEntry(); } }
/// <summary> /// Determine if the given entry is a descendant of this entry. /// Descendancy is determined by the name of the descendant /// starting with this entry's name. /// </summary> /// <param name = "desc"> /// Entry to be checked as a descendent of this. /// </param> /// <returns> /// True if entry is a descendant of this. /// </returns> public bool IsDescendent(TarEntry desc) { return(desc.header.name.ToString().StartsWith(this.header.name.ToString())); }
/// <summary> /// Extract an entry from the archive. This method assumes that the /// tarIn stream has been properly set with a call to GetNextEntry(). /// </summary> /// <param name="destDir"> /// The destination directory into which to extract. /// </param> /// <param name="entry"> /// The TarEntry returned by tarIn.GetNextEntry(). /// </param> void ExtractEntry(string destDir, TarEntry entry) { OnProgressMessageEvent(entry, null); string name = entry.Name; if (Path.IsPathRooted(name)) { // NOTE: // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt name = name.Substring(Path.GetPathRoot(name).Length); } name = name.Replace('/', Path.DirectorySeparatorChar); string destFile = Path.Combine(destDir, name); if (entry.IsDirectory) { EnsureDirectoryExists(destFile); } else { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); bool process = true; FileInfo fileInfo = new FileInfo(destFile); if (fileInfo.Exists) { if (keepOldFiles) { OnProgressMessageEvent(entry, "Destination file already exists"); process = false; } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) { OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); process = false; } } if (process) { bool asciiTrans = false; Stream outputStream = File.Create(destFile); if (this.asciiTranslate) { asciiTrans = !IsBinary(destFile); } StreamWriter outw = null; if (asciiTrans) { outw = new StreamWriter(outputStream); } byte[] rdbuf = new byte[32 * 1024]; while (true) { int numRead = tarIn.Read(rdbuf, 0, rdbuf.Length); if (numRead <= 0) { break; } if (asciiTrans) { for (int off = 0, b = 0; b < numRead; ++b) { if (rdbuf[b] == 10) { string s = Encoding.ASCII.GetString(rdbuf, off, (b - off)); outw.WriteLine(s); off = b + 1; } } } else { outputStream.Write(rdbuf, 0, numRead); } } if (asciiTrans) { outw.Close(); } else { outputStream.Close(); } } } }
public override bool Equals(object obj) { TarEntry entry = obj as TarEntry; return((entry != null) && this.Name.Equals(entry.Name)); }
/// <summary> /// Create a tar entry with details obtained from <paramref name="fileName">file</paramref> /// </summary> /// <param name="fileName">The name of the file to retrieve details from.</param> /// <returns>A new <see cref="TarEntry"/></returns> public TarEntry CreateEntryFromFile(string fileName) { return(TarEntry.CreateEntryFromFile(fileName)); }
/// <summary> /// Determine if the given entry is a descendant of this entry. /// Descendancy is determined by the name of the descendant /// starting with this entry's name. /// </summary> /// <param name = "desc"> /// Entry to be checked as a descendent of this. /// </param> /// <returns> /// True if entry is a descendant of this. /// </returns> public bool IsDescendent(TarEntry desc) { return(desc.Name.StartsWith(Name)); }
private void ExtractEntry(string destDir, TarEntry entry) { this.OnProgressMessageEvent(entry, null); string text = entry.Name; if (Path.IsPathRooted(text)) { text = text.Substring(Path.GetPathRoot(text).Length); } text = text.Replace('/', Path.DirectorySeparatorChar); string text2 = Path.Combine(destDir, text); if (entry.IsDirectory) { TarArchive.EnsureDirectoryExists(text2); return; } string directoryName = Path.GetDirectoryName(text2); TarArchive.EnsureDirectoryExists(directoryName); bool flag = true; FileInfo fileInfo = new FileInfo(text2); if (fileInfo.Exists) { if (this.keepOldFiles) { this.OnProgressMessageEvent(entry, "Destination file already exists"); flag = false; } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != (FileAttributes)0) { this.OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); flag = false; } } if (flag) { bool flag2 = false; Stream stream = File.Create(text2); if (this.asciiTranslate) { flag2 = !TarArchive.IsBinary(text2); } StreamWriter streamWriter = null; if (flag2) { streamWriter = new StreamWriter(stream); } byte[] array = new byte[32768]; for (;;) { int num = this.tarIn.Read(array, 0, array.Length); if (num <= 0) { break; } if (flag2) { int num2 = 0; for (int i = 0; i < num; i++) { if (array[i] == 10) { string @string = Encoding.ASCII.GetString(array, num2, i - num2); streamWriter.WriteLine(@string); num2 = i + 1; } } } else { stream.Write(array, 0, num); } } if (flag2) { streamWriter.Close(); return; } stream.Close(); } }
/// <summary> /// Raises the ProgressMessage event /// </summary> /// <param name="entry">The <see cref="TarEntry">TarEntry</see> for this event</param> /// <param name="message">message for this event. Null is no message</param> protected virtual void OnProgressMessageEvent(TarEntry entry, string message) { ProgressMessageEvent?.Invoke(this, entry, message); }
/// <summary> /// Determine if the given entry is a descendant of this entry. /// Descendancy is determined by the name of the descendant /// starting with this entry's name. /// </summary> /// <param name = "toTest"> /// Entry to be checked as a descendent of this. /// </param> /// <returns> /// True if entry is a descendant of this. /// </returns> public bool IsDescendent(TarEntry toTest) { if ( toTest == null ) { throw new ArgumentNullException("toTest"); } return toTest.Name.StartsWith(Name); }
protected override void PostCreate(TarEntry entry) { if (entry.Size > 0) { tfs.tis.Read(data = new byte[entry.Size], 0, (int)entry.Size); } else data = new byte[0]; }
public static TarFileSystemInfo FromEntry(TarFileSystem tfs, TarEntry entry) { TarFileSystemInfo fsi; if (entry.IsDirectory) fsi = new TarDirectoryInfo(); else fsi = new TarFileInfo(); fsi.tfs = tfs; fsi.CreationTime = entry.ModTime; fsi.Exists = true; fsi.FullName = entry.Name; fsi.LastAccessTime = entry.ModTime; fsi.LastWriteTime = entry.ModTime; fsi.Name = entry.Name.PostLastCharacter('/'); fsi.Extension = entry.IsDirectory ? string.Empty : fsi.Name.PostFirstCharacter('.', string.Empty); fsi.PostCreate(entry); return fsi; }
protected override void PostCreate(TarEntry entry) { }
/// <summary> /// Determine if the given entry is a descendant of this entry. /// Descendancy is determined by the name of the descendant /// starting with this entry's name. /// </summary> /// <param name = "toTest"> /// Entry to be checked as a descendent of this. /// </param> /// <returns> /// True if entry is a descendant of this. /// </returns> public bool IsDescendent(TarEntry toTest) { if (toTest == null) { throw new ArgumentNullException("toTest"); } return toTest.Name.StartsWith(Name, StringComparison.Ordinal); }
/// <summary> /// Create a <see cref="TarEntry"/> based on named /// </summary> /// <param name="name">The name to use for the entry</param> /// <returns>A new <see cref="TarEntry"/></returns> public TarEntry CreateEntry(string name) { return(TarEntry.CreateTarEntry(name)); }
/// <summary> /// Write an entry to the archive. This method will call the putNextEntry /// and then write the contents of the entry, and finally call closeEntry() /// for entries that are files. For directories, it will call putNextEntry(), /// and then, if the recurse flag is true, process each entry that is a /// child of the directory. /// </summary> /// <param name="sourceEntry"> /// The TarEntry representing the entry to write to the archive. /// </param> /// <param name="recurse"> /// If true, process the children of directory entries. /// </param> public void WriteEntry(TarEntry sourceEntry, bool recurse) { if ( sourceEntry == null ) { throw new ArgumentNullException("sourceEntry"); } if ( isDisposed ) { throw new ObjectDisposedException("TarArchive"); } try { if ( recurse ) { TarHeader.SetValueDefaults(sourceEntry.UserId, sourceEntry.UserName, sourceEntry.GroupId, sourceEntry.GroupName); } WriteEntryCore(sourceEntry, recurse); } finally { if ( recurse ) { TarHeader.RestoreSetValues(); } } }
/// <summary> /// Raises the ProgressMessage event /// </summary> /// <param name="entry">TarEntry for this event</param> /// <param name="message">message for this event. Null is no message</param> protected virtual void OnProgressMessageEvent(TarEntry entry, string message) { if (ProgressMessageEvent != null) { ProgressMessageEvent(this, entry, message); } }
/// <summary> /// Extract an entry from the archive. This method assumes that the /// tarIn stream has been properly set with a call to GetNextEntry(). /// </summary> /// <param name="destDir"> /// The destination directory into which to extract. /// </param> /// <param name="entry"> /// The TarEntry returned by tarIn.GetNextEntry(). /// </param> void ExtractEntry(string destDir, TarEntry entry) { OnProgressMessageEvent(entry, null); string name = entry.Name; if (Path.IsPathRooted(name)) { // NOTE: // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt name = name.Substring(Path.GetPathRoot(name).Length); } name = name.Replace('/', Path.DirectorySeparatorChar); string destFile = Path.Combine(destDir, name); if (entry.IsDirectory) { EnsureDirectoryExists(destFile); } else { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); bool process = true; FileInfo fileInfo = new FileInfo(destFile); if (fileInfo.Exists) { if (keepOldFiles) { OnProgressMessageEvent(entry, "Destination file already exists"); process = false; } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) { OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); process = false; } } if (process) { bool asciiTrans = false; Stream outputStream = File.Create(destFile); if (this.asciiTranslate) { asciiTrans = !IsBinary(destFile); } StreamWriter outw = null; if (asciiTrans) { outw = new StreamWriter(outputStream); } byte[] rdbuf = new byte[32 * 1024]; while (true) { int numRead = tarIn.Read(rdbuf, 0, rdbuf.Length); if (numRead <= 0) { break; } if (asciiTrans) { for (int off = 0, b = 0; b < numRead; ++b) { if (rdbuf[b] == 10) { string s = Encoding.ASCII.GetString(rdbuf, off, (b - off)); outw.WriteLine(s); off = b + 1; } } } else { outputStream.Write(rdbuf, 0, numRead); } } if (asciiTrans) { outw.Close(); } else { outputStream.Close(); } } } }
/// <summary> /// Extract an entry from the archive. This method assumes that the /// tarIn stream has been properly set with a call to getNextEntry(). /// </summary> /// <param name="destDir"> /// The destination directory into which to extract. /// </param> /// <param name="entry"> /// The TarEntry returned by tarIn.getNextEntry(). /// </param> void ExtractEntry(string destDir, TarEntry entry) { if (this.verbose) { OnProgressMessageEvent(entry, null); } string name = entry.Name; name = name.Replace('/', Path.DirectorySeparatorChar); if (!destDir.EndsWith(Path.DirectorySeparatorChar.ToString())) { destDir += Path.DirectorySeparatorChar; } string destFile = destDir + name; if (entry.IsDirectory) { EnsureDirectoryExists(destFile); } else { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); if (this.keepOldFiles && File.Exists(destFile)) { if (this.verbose) { OnProgressMessageEvent(entry, "Destination file already exists"); } } else { bool asciiTrans = false; Stream outputStream = File.Create(destFile); if (this.asciiTranslate) { asciiTrans = !IsBinary(destFile); // original java sourcecode : // MimeType mime = null; // string contentType = null; // try { // contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile ); // // mime = new MimeType(contentType); // // if (mime.getPrimaryType().equalsIgnoreCase( "text" )) { // asciiTrans = true; // } else if ( this.transTyper != null ) { // if ( this.transTyper.isAsciiFile( entry.getName() ) ) { // asciiTrans = true; // } // } // } catch (MimeTypeParseException ex) { // } // // if (this.debug) { // Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "' ContentType='" + contentType + "' PrimaryType='" + mime.getPrimaryType() + "'" ); // } } StreamWriter outw = null; if (asciiTrans) { outw = new StreamWriter(outputStream); } byte[] rdbuf = new byte[32 * 1024]; while (true) { int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length); if (numRead <= 0) { break; } if (asciiTrans) { for (int off = 0, b = 0; b < numRead; ++b) { if (rdbuf[b] == 10) { string s = Encoding.ASCII.GetString(rdbuf, off, (b - off)); outw.WriteLine(s); off = b + 1; } } } else { outputStream.Write(rdbuf, 0, numRead); } } if (asciiTrans) { outw.Close(); } else { outputStream.Close(); } } } }
/// <summary> /// Write an entry to the archive. This method will call the putNextEntry /// and then write the contents of the entry, and finally call closeEntry()() /// for entries that are files. For directories, it will call putNextEntry(), /// and then, if the recurse flag is true, process each entry that is a /// child of the directory. /// </summary> /// <param name="entry"> /// The TarEntry representing the entry to write to the archive. /// </param> /// <param name="recurse"> /// If true, process the children of directory entries. /// </param> public void WriteEntry(TarEntry entry, bool recurse) { bool asciiTrans = false; string tempFileName = null; string eFile = entry.File; // Work on a copy of the entry so we can manipulate it. // Note that we must distinguish how the entry was constructed. // if (eFile == null || eFile.Length == 0) { entry = TarEntry.CreateTarEntry(entry.Name); } else { // // The user may have explicitly set the entry's name to // something other than the file's path, so we must save // and restore it. This should work even when the name // was set from the File's name. // string saveName = entry.Name; entry = TarEntry.CreateEntryFromFile(eFile); entry.Name = saveName; } if (this.verbose) { OnProgressMessageEvent(entry, null); } if (this.asciiTranslate && !entry.IsDirectory) { asciiTrans = !IsBinary(eFile); // original java source : // MimeType mime = null; // string contentType = null; // // try { // contentType = FileTypeMap.getDefaultFileTypeMap(). getContentType( eFile ); // // mime = new MimeType( contentType ); // // if ( mime.getPrimaryType(). // equalsIgnoreCase( "text" ) ) // { // asciiTrans = true; // } // else if ( this.transTyper != null ) // { // if ( this.transTyper.isAsciiFile( eFile ) ) // { // asciiTrans = true; // } // } // } catch ( MimeTypeParseException ex ) // { // // IGNORE THIS ERROR... // } // // if (this.debug) { // Console.Error.WriteLine("CREATE TRANS? '" + asciiTrans + "' ContentType='" + contentType + "' PrimaryType='" + mime.getPrimaryType()+ "'" ); // } if (asciiTrans) { tempFileName = Path.GetTempFileName(); StreamReader inStream = File.OpenText(eFile); Stream outStream = new BufferedStream(File.Create(tempFileName)); while (true) { string line = inStream.ReadLine(); if (line == null) { break; } byte[] data = Encoding.ASCII.GetBytes(line); outStream.Write(data, 0, data.Length); outStream.WriteByte((byte)'\n'); } inStream.Close(); outStream.Flush(); outStream.Close(); entry.Size = new FileInfo(tempFileName).Length; eFile = tempFileName; } } string newName = null; if (this.rootPath != null) { if (entry.Name.StartsWith(this.rootPath)) { newName = entry.Name.Substring(this.rootPath.Length + 1 ); } } if (this.pathPrefix != null) { newName = (newName == null) ? this.pathPrefix + "/" + entry.Name : this.pathPrefix + "/" + newName; } if (newName != null) { entry.Name = newName; } this.tarOut.PutNextEntry(entry); if (entry.IsDirectory) { if (recurse) { TarEntry[] list = entry.GetDirectoryEntries(); for (int i = 0; i < list.Length; ++i) { this.WriteEntry(list[i], recurse); } } } else { Stream inputStream = File.OpenRead(eFile); int numWritten = 0; byte[] eBuf = new byte[32 * 1024]; while (true) { int numRead = inputStream.Read(eBuf, 0, eBuf.Length); if (numRead <=0) { break; } this.tarOut.Write(eBuf, 0, numRead); numWritten += numRead; } // Console.WriteLine("written " + numWritten + " bytes"); inputStream.Close(); if (tempFileName != null && tempFileName.Length > 0) { File.Delete(tempFileName); } this.tarOut.CloseEntry(); } }
/// <summary> /// Clone this tar entry. /// </summary> /// <returns>Returns a clone of this entry.</returns> public object Clone() { TarEntry entry = new TarEntry(); entry.file = file; entry.header = (TarHeader)header.Clone(); entry.Name = Name; return entry; }
/// <summary> /// Display progress information on console /// </summary> public void ShowTarProgressMessage(TarArchive archive, TarEntry entry, string message) { if (entry.TarHeader.TypeFlag != TarHeader.LF_NORMAL && entry.TarHeader.TypeFlag != TarHeader.LF_OLDNORM) { Console.WriteLine("Entry type " + (char)entry.TarHeader.TypeFlag + " found!"); } if (message != null) Console.Write(entry.Name + " " + message); else { if (this.verbose) { string modeString = DecodeType(entry.TarHeader.TypeFlag, entry.Name.EndsWith("/")) + DecodeMode(entry.TarHeader.Mode); string userString = (entry.UserName == null || entry.UserName.Length == 0) ? entry.UserId.ToString() : entry.UserName; string groupString = (entry.GroupName == null || entry.GroupName.Length == 0) ? entry.GroupId.ToString() : entry.GroupName; Console.WriteLine(string.Format("{0} {1}/{2} {3,8} {4:yyyy-MM-dd HH:mm:ss} {5}", modeString, userString, groupString, entry.Size, entry.ModTime.ToLocalTime(), entry.Name)); } else { Console.WriteLine(entry.Name); } } }
/// <summary> /// Get entries for all files present in this entries directory. /// If this entry doesnt represent a directory zero entries are returned. /// </summary> /// <returns> /// An array of TarEntry's for this entry's children. /// </returns> public TarEntry[] GetDirectoryEntries() { if ((file == null) || !Directory.Exists(file)) { return new TarEntry[0]; } string[] list = Directory.GetFileSystemEntries(file); TarEntry[] result = new TarEntry[list.Length]; for (int i = 0; i < list.Length; ++i) { result[i] = TarEntry.CreateEntryFromFile(list[i]); } return result; }
/// <summary> /// Extract an entry from the archive. This method assumes that the /// tarIn stream has been properly set with a call to getNextEntry(). /// </summary> /// <param name="destDir"> /// The destination directory into which to extract. /// </param> /// <param name="entry"> /// The TarEntry returned by tarIn.getNextEntry(). /// </param> void ExtractEntry(string destDir, TarEntry entry) { if (this.verbose) { OnProgressMessageEvent(entry, null); } string name = entry.Name; if (Path.IsPathRooted(name) == true) { // NOTE: // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt name = name.Substring(Path.GetPathRoot(name).Length); } name = name.Replace('/', Path.DirectorySeparatorChar); string destFile = Path.Combine(destDir, name); if (entry.IsDirectory) { EnsureDirectoryExists(destFile); } else { string parentDirectory = Path.GetDirectoryName(destFile); EnsureDirectoryExists(parentDirectory); bool process = true; FileInfo fileInfo = new FileInfo(destFile); if (fileInfo.Exists) { if (this.keepOldFiles) { OnProgressMessageEvent(entry, "Destination file already exists"); process = false; } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) { OnProgressMessageEvent(entry, "Destination file already exists, and is read-only"); process = false; } } if (process) { bool asciiTrans = false; // TODO file may exist and be read-only at this point! Stream outputStream = File.Create(destFile); if (this.asciiTranslate) { asciiTrans = !IsBinary(destFile); // TODO do we need this stuff below? // original java sourcecode : // MimeType mime = null; // string contentType = null; // try { // contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile ); // // mime = new MimeType(contentType); // // if (mime.getPrimaryType().equalsIgnoreCase( "text" )) { // asciiTrans = true; // } else if ( this.transTyper != null ) { // if ( this.transTyper.isAsciiFile( entry.getName() ) ) { // asciiTrans = true; // } // } // } catch (MimeTypeParseException ex) { // } // // if (this.debug) { // Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "' ContentType='" + contentType + "' PrimaryType='" + mime.getPrimaryType() + "'" ); // } } StreamWriter outw = null; if (asciiTrans) { outw = new StreamWriter(outputStream); } byte[] rdbuf = new byte[32 * 1024]; while (true) { int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length); if (numRead <= 0) { break; } if (asciiTrans) { for (int off = 0, b = 0; b < numRead; ++b) { if (rdbuf[b] == 10) { string s = Encoding.ASCII.GetString(rdbuf, off, (b - off)); outw.WriteLine(s); off = b + 1; } } } else { outputStream.Write(rdbuf, 0, numRead); } } if (asciiTrans) { outw.Close(); } else { outputStream.Close(); } } } }
/// <summary> /// Determine if the given entry is a descendant of this entry. /// Descendancy is determined by the name of the descendant /// starting with this entry's name. /// </summary> /// <param name = "desc"> /// Entry to be checked as a descendent of this. /// </param> /// <returns> /// True if entry is a descendant of this. /// </returns> public bool IsDescendent(TarEntry desc) { return desc.header.name.ToString().StartsWith(this.header.name.ToString()); }
/// <summary> /// Construct an entry for a file. File is set to file, and the /// header is constructed from information from the file. /// </summary> /// <param name = "fileName">The file name that the entry represents.</param> /// <returns>Returns the newly created <see cref="TarEntry"/></returns> public static TarEntry CreateEntryFromFile(string fileName) { var entry = new TarEntry(); entry.GetFileTarHeader(entry.header, fileName); return entry; }
/// <summary> /// Put an entry on the output stream. This writes the entry's /// header and positions the output stream for writing /// the contents of the entry. Once this method is called, the /// stream is ready for calls to write() to write the entry's /// contents. Once the contents are written, closeEntry() /// <B>MUST</B> be called to ensure that all buffered data /// is completely written to the output stream. /// </summary> /// <param name="entry"> /// The TarEntry to be written to the archive. /// </param> public void PutNextEntry(TarEntry entry) { if ( entry == null ) { throw new ArgumentNullException("entry"); } if (entry.TarHeader.Name.Length >= TarHeader.NAMELEN) { TarHeader longHeader = new TarHeader(); longHeader.TypeFlag = TarHeader.LF_GNU_LONGNAME; longHeader.Name = longHeader.Name + "././@LongLink"; longHeader.UserId = 0; longHeader.GroupId = 0; longHeader.GroupName = ""; longHeader.UserName = ""; longHeader.LinkName = ""; longHeader.Size = entry.TarHeader.Name.Length; longHeader.WriteHeader(blockBuffer); buffer.WriteBlock(blockBuffer); // Add special long filename header block int nameCharIndex = 0; while (nameCharIndex < entry.TarHeader.Name.Length) { Array.Clear(blockBuffer, 0, blockBuffer.Length); TarHeader.GetAsciiBytes(entry.TarHeader.Name, nameCharIndex, this.blockBuffer, 0, TarBuffer.BlockSize); nameCharIndex += TarBuffer.BlockSize; buffer.WriteBlock(blockBuffer); } } entry.WriteEntryHeader(blockBuffer); buffer.WriteBlock(blockBuffer); currBytes = 0; currSize = entry.IsDirectory ? 0 : entry.Size; }
/// <summary> /// Put an entry on the output stream. This writes the entry's /// header and positions the output stream for writing /// the contents of the entry. Once this method is called, the /// stream is ready for calls to write() to write the entry's /// contents. Once the contents are written, closeEntry() /// <B>MUST</B> be called to ensure that all buffered data /// is completely written to the output stream. /// </summary> /// <param name="entry"> /// The TarEntry to be written to the archive. /// </param> public void PutNextEntry(TarEntry entry) { if (entry.TarHeader.name.Length > TarHeader.NAMELEN) { TarHeader longHeader = new TarHeader(); longHeader.typeFlag = TarHeader.LF_GNU_LONGNAME; longHeader.name.Append("././@LongLink"); longHeader.userId = 0; longHeader.groupId = 0; longHeader.groupName.Length = 0; longHeader.userName.Length = 0; longHeader.linkName.Length = 0; longHeader.size = entry.TarHeader.name.Length; Console.WriteLine("TarOutputStream: PutNext entry Long name found size = " + longHeader.size); // DEBUG longHeader.WriteHeader(this.blockBuf); this.buffer.WriteBlock(this.blockBuf); // Add special long filename header block int nameCharIndex = 0; while (nameCharIndex < entry.TarHeader.name.Length) { TarHeader.GetNameBytes(entry.TarHeader.name, nameCharIndex, this.blockBuf, 0, TarBuffer.BlockSize); nameCharIndex += TarBuffer.BlockSize; this.buffer.WriteBlock(this.blockBuf); } } entry.WriteEntryHeader(this.blockBuf); this.buffer.WriteBlock(this.blockBuf); this.currBytes = 0; this.currSize = entry.IsDirectory ? 0 : (int)entry.Size; }
/// <summary> /// Get the next entry in this tar archive. This will skip /// over any remaining data in the current entry, if there /// is one, and place the input stream at the header of the /// next entry, and read the header and instantiate a new /// TarEntry from the header bytes and return that entry. /// If there are no more entries in the archive, null will /// be returned to indicate that the end of the archive has /// been reached. /// </summary> /// <returns> /// The next TarEntry in the archive, or null. /// </returns> public TarEntry GetNextEntry() { if (hasHitEOF) { return null; } if (currentEntry != null) { SkipToNextEntry(); } byte[] headerBuf = tarBuffer.ReadBlock(); if (headerBuf == null) { hasHitEOF = true; } else hasHitEOF |= TarBuffer.IsEndOfArchiveBlock(headerBuf); if (hasHitEOF) { currentEntry = null; } else { try { var header = new TarHeader(); header.ParseBuffer(headerBuf); if (!header.IsChecksumValid) { throw new TarException("Header checksum is invalid"); } this.entryOffset = 0; this.entrySize = header.Size; StringBuilder longName = null; if (header.TypeFlag == TarHeader.LF_GNU_LONGNAME) { byte[] nameBuffer = new byte[TarBuffer.BlockSize]; long numToRead = this.entrySize; longName = new StringBuilder(); while (numToRead > 0) { int numRead = this.Read(nameBuffer, 0, (numToRead > nameBuffer.Length ? nameBuffer.Length : (int)numToRead)); if (numRead == -1) { throw new InvalidHeaderException("Failed to read long name entry"); } longName.Append(TarHeader.ParseName(nameBuffer, 0, numRead).ToString()); numToRead -= numRead; } SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GHDR) { // POSIX global extended header // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_XHDR) { // POSIX extended header // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR) { // TODO: could show volume name when verbose SkipToNextEntry(); headerBuf = this.tarBuffer.ReadBlock(); } else if (header.TypeFlag != TarHeader.LF_NORMAL && header.TypeFlag != TarHeader.LF_OLDNORM && header.TypeFlag != TarHeader.LF_LINK && header.TypeFlag != TarHeader.LF_SYMLINK && header.TypeFlag != TarHeader.LF_DIR) { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = tarBuffer.ReadBlock(); } if (entryFactory == null) { currentEntry = new TarEntry(headerBuf); if (longName != null) { currentEntry.Name = longName.ToString(); } } else { currentEntry = entryFactory.CreateEntry(headerBuf); } // Magic was checked here for 'ustar' but there are multiple valid possibilities // so this is not done anymore. entryOffset = 0; // TODO: Review How do we resolve this discrepancy?! entrySize = this.currentEntry.Size; } catch (InvalidHeaderException ex) { entrySize = 0; entryOffset = 0; currentEntry = null; string errorText = string.Format("Bad header in record {0} block {1} {2}", tarBuffer.CurrentRecord, tarBuffer.CurrentBlock, ex.Message); throw new InvalidHeaderException(errorText); } } return currentEntry; }
/// <summary> /// Write an entry to the archive. This method will call the putNextEntry /// and then write the contents of the entry, and finally call closeEntry() /// for entries that are files. For directories, it will call putNextEntry(), /// and then, if the recurse flag is true, process each entry that is a /// child of the directory. /// </summary> /// <param name="sourceEntry"> /// The TarEntry representing the entry to write to the archive. /// </param> /// <param name="recurse"> /// If true, process the children of directory entries. /// </param> void WriteEntryCore(TarEntry sourceEntry, bool recurse) { string tempFileName = null; string entryFilename = sourceEntry.File; TarEntry entry = (TarEntry)sourceEntry.Clone(); if ( applyUserInfoOverrides ) { entry.GroupId = groupId; entry.GroupName = groupName; entry.UserId = userId; entry.UserName = userName; } OnProgressMessageEvent(entry, null); if (asciiTranslate && !entry.IsDirectory) { if (!IsBinary(entryFilename)) { tempFileName = Path.GetTempFileName(); using (StreamReader inStream = File.OpenText(entryFilename)) { using (Stream outStream = File.Create(tempFileName)) { while (true) { string line = inStream.ReadLine(); if (line == null) { break; } byte[] data = Encoding.ASCII.GetBytes(line); outStream.Write(data, 0, data.Length); outStream.WriteByte((byte)'\n'); } outStream.Flush(); } } entry.Size = new FileInfo(tempFileName).Length; entryFilename = tempFileName; } } string newName = null; if (rootPath != null) { if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) { newName = entry.Name.Substring(rootPath.Length + 1 ); } } if (pathPrefix != null) { newName = (newName == null) ? pathPrefix + "/" + entry.Name : pathPrefix + "/" + newName; } if (newName != null) { entry.Name = newName; } tarOut.PutNextEntry(entry); if (entry.IsDirectory) { if (recurse) { TarEntry[] list = entry.GetDirectoryEntries(); for (int i = 0; i < list.Length; ++i) { WriteEntryCore(list[i], recurse); } } } else { using (Stream inputStream = File.OpenRead(entryFilename)) { byte[] localBuffer = new byte[32 * 1024]; while (true) { int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length); if (numRead <=0) { break; } tarOut.Write(localBuffer, 0, numRead); } } if ( (tempFileName != null) && (tempFileName.Length > 0) ) { File.Delete(tempFileName); } tarOut.CloseEntry(); } }
void EntryCounter(TarArchive archive, TarEntry entry, string message) { entryCount++; }
/// <summary> /// Construct an entry with only a <paramref name="name">name</paramref>. /// This allows the programmer to construct the entry's header "by hand". /// </summary> /// <param name="name">The name to use for the entry</param> /// <returns>Returns the newly created <see cref="TarEntry"/></returns> public static TarEntry CreateTarEntry(string name) { TarEntry entry = new TarEntry(); TarEntry.NameTarHeader(entry.header, name); return entry; }
public void CloningAndUniqueness() { // Partial test of cloning for TarHeader and TarEntry TarEntry e = TarEntry.CreateTarEntry("ohsogood"); e.GroupId = 47; e.GroupName = "GroupName"; e.ModTime = DateTime.Now; e.Size = 123234; TarHeader headerE = e.TarHeader; headerE.DevMajor = 99; headerE.DevMinor = 98; headerE.LinkName = "LanceLink"; TarEntry d = (TarEntry)e.Clone(); Assert.AreEqual(d.File, e.File); Assert.AreEqual(d.GroupId, e.GroupId); Assert.AreEqual(d.GroupName, e.GroupName); Assert.AreEqual(d.IsDirectory, e.IsDirectory); Assert.AreEqual(d.ModTime, e.ModTime); Assert.AreEqual(d.Size, e.Size); TarHeader headerD = d.TarHeader; Assert.AreEqual(headerE.Checksum, headerD.Checksum); Assert.AreEqual(headerE.LinkName, headerD.LinkName); Assert.AreEqual(99, headerD.DevMajor); Assert.AreEqual(98, headerD.DevMinor); Assert.AreEqual("LanceLink", headerD.LinkName); TarEntry entryf = new TarEntry(headerD); headerD.LinkName = "Something different"; Assert.AreNotEqual(headerD.LinkName, entryf.TarHeader.LinkName, "Entry headers should be unique"); }
/// <inheritdoc/> protected override void HandleFile(FileInfo file, bool executable = false) { #region Sanity checks if (file == null) throw new ArgumentNullException(nameof(file)); #endregion var entry = new TarEntry(new TarHeader { Name = file.RelativeTo(SourceDirectory), ModTime = file.LastWriteTimeUtc, Mode = (executable ? TarExtractor.DefaultMode | TarExtractor.ExecuteMode : TarExtractor.DefaultMode) }); var hardlinkTarget = _previousFiles.FirstOrDefault(previousFile => FileUtils.AreHardlinked(previousFile.FullName, file.FullName)); if (hardlinkTarget != null) { entry.TarHeader.TypeFlag = TarHeader.LF_LINK; entry.TarHeader.LinkName = hardlinkTarget.RelativeTo(SourceDirectory); _tarStream.PutNextEntry(entry); } else { _previousFiles.Add(file); entry.Size = file.Length; _tarStream.PutNextEntry(entry); using (var stream = file.OpenRead()) stream.CopyToEx(_tarStream); } _tarStream.CloseEntry(); }
public override bool HasNext() { tarEntry = tarStream.GetNextEntry(); if (tarEntry == null) return false; return true; }
protected abstract void PostCreate(TarEntry entry);