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> /// Construct a TarEntry using the <paramref name="header">header</paramref> provided /// </summary> /// <param name="header">Header details for entry</param> public TarEntry(TarHeader header) { if (header == null) { throw new ArgumentNullException("TarHeader"); } this.header = (TarHeader)header.Clone(); }
/// <summary> /// Clone a TAR header. /// </summary> public object Clone() { TarHeader hdr = new TarHeader(); hdr.Name = Name; hdr.Mode = this.Mode; hdr.UserId = this.UserId; hdr.GroupId = this.GroupId; hdr.Size = this.Size; hdr.ModTime = this.ModTime; hdr.TypeFlag = this.TypeFlag; hdr.LinkName = this.LinkName; hdr.Magic = this.Magic; hdr.Version = this.Version; hdr.UserName = this.UserName; hdr.GroupName = this.GroupName; hdr.DevMajor = this.DevMajor; hdr.DevMinor = this.DevMinor; return hdr; }
public TarEntry GetNextEntry() { if (this.hasHitEOF) { return null; } if (this.currentEntry != null) { SkipToNextEntry(); } byte[] headerBuf = this.buffer.ReadBlock(); if (headerBuf == null) { this.hasHitEOF = true; } else if (TarBuffer.IsEndOfArchiveBlock(headerBuf)) { this.hasHitEOF = true; } if (this.hasHitEOF) { this.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.buffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GHDR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_XHDR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.TypeFlag != TarHeader.LF_NORMAL && header.TypeFlag != TarHeader.LF_OLDNORM && header.TypeFlag != TarHeader.LF_DIR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } if (this.entryFactory == null) { this.currentEntry = new TarEntry(headerBuf); if (longName != null) { currentEntry.Name = longName.ToString(); } } else { this.currentEntry = this.entryFactory.CreateEntry(headerBuf); } this.entryOffset = 0; this.entrySize = this.currentEntry.Size; } catch (InvalidHeaderException ex) { this.entrySize = 0; this.entryOffset = 0; this.currentEntry = null; string errorText = string.Format("Bad header in record {0} block {1} {2}", buffer.CurrentRecord, buffer.CurrentBlock, ex.Message); throw new InvalidHeaderException(errorText); } } return this.currentEntry; }
/// <summary> /// Add the checksum integer to header buffer. /// </summary> /// <param name = "value"></param> /// <param name = "buffer">The header buffer to set the checksum for</param> /// <param name = "offset">The offset into the buffer for the checksum</param> /// <param name = "length">The number of header bytes to update. /// It's formatted differently from the other fields: it has 6 digits, a /// null, then a space -- rather than digits, a space, then a null. /// The final space is already there, from checksumming /// </param> /// <returns>The modified buffer offset</returns> static int GetCheckSumOctalBytes(long value, byte[] buffer, int offset, int length) { TarHeader.GetOctalBytes(value, buffer, offset, length - 1); return(offset + length); }
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); }
/// <summary> /// TarHeaders can be cloned. /// </summary> public object Clone() { TarHeader hdr = new TarHeader(); hdr.name = (this.name == null) ? null : new StringBuilder(this.name.ToString()); hdr.mode = this.mode; hdr.userId = this.userId; hdr.groupId = this.groupId; hdr.size = this.size; hdr.modTime = this.modTime; hdr.checkSum = this.checkSum; hdr.typeFlag = this.typeFlag; hdr.linkName = (this.linkName == null) ? null : new StringBuilder(this.linkName.ToString()); hdr.magic = (this.magic == null) ? null : new StringBuilder(this.magic.ToString()); hdr.version = (this.version == null) ? null : new StringBuilder(this.version.ToString()); hdr.userName = (this.userName == null) ? null : new StringBuilder(this.userName.ToString()); hdr.groupName = (this.groupName == null) ? null : new StringBuilder(this.groupName.ToString()); hdr.devMajor = this.devMajor; hdr.devMinor = this.devMinor; return hdr; }
/// <summary> /// Fill in a TarHeader given only the entry's name. /// </summary> /// <param name="hdr"> /// The TarHeader to fill in. /// </param> /// <param name="name"> /// The tar entry name. /// </param> public void NameTarHeader(TarHeader hdr, string name) { bool isDir = name.EndsWith("/"); // -jr- this is true for BSD tar but not all others I think? hdr.checkSum = 0; hdr.name = new StringBuilder(name); // hdr.mode = isDir ? 040755 : 0100644; // TODO : I think I've seen these magics before ... hdr.mode = isDir ? 1003 : 33216; hdr.userId = 0; hdr.groupId = 0; hdr.size = 0; hdr.checkSum = 0; hdr.modTime = DateTime.UtcNow; // -jr- 24-Jan-2004 Unix times are in utc! // hdr.modTime = DateTime.Now; // (new java.util.Date()).getTime() / 1000; hdr.typeFlag = isDir ? TarHeader.LF_DIR : TarHeader.LF_NORMAL; hdr.linkName = new StringBuilder(String.Empty); hdr.userName = new StringBuilder(String.Empty); hdr.groupName = new StringBuilder(String.Empty); hdr.devMajor = 0; hdr.devMinor = 0; }
/// <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.currentEntry != null) { SkipToNextEntry(); } byte[] headerBuf = this.buffer.ReadBlock(); if (headerBuf == null) { this.hasHitEOF = true; } else if (buffer.IsEOFBlock(headerBuf)) { this.hasHitEOF = true; } if (this.hasHitEOF) { this.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.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 && header.TypeFlag != TarHeader.LF_DIR) { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } if (this.entryFactory == null) { this.currentEntry = new TarEntry(headerBuf); if (longName != null) { currentEntry.Name = longName.ToString(); } } else { this.currentEntry = this.entryFactory.CreateEntry(headerBuf); } // Magic was checked here for 'ustar' but there are multiple valid possibilities // so this is not done anymore. this.entryOffset = 0; // TODO: Review How do we resolve this discrepancy?! this.entrySize = this.currentEntry.Size; } catch (InvalidHeaderException ex) { this.entrySize = 0; this.entryOffset = 0; this.currentEntry = null; string errorText = string.Format("Bad header in record {0} block {1} {2}", buffer.CurrentRecord, buffer.CurrentBlock, ex.Message); throw new InvalidHeaderException(errorText); } } return this.currentEntry; }
public TarEntry GetNextEntry() { if (this.hasHitEOF) { return(null); } if (this.currentEntry != null) { SkipToNextEntry(); } byte[] headerBuf = this.buffer.ReadBlock(); if (headerBuf == null) { this.hasHitEOF = true; } else if (TarBuffer.IsEndOfArchiveBlock(headerBuf)) { this.hasHitEOF = true; } if (this.hasHitEOF) { this.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.buffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GHDR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_XHDR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } else if (header.TypeFlag != TarHeader.LF_NORMAL && header.TypeFlag != TarHeader.LF_OLDNORM && header.TypeFlag != TarHeader.LF_DIR) { SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } if (this.entryFactory == null) { this.currentEntry = new TarEntry(headerBuf); if (longName != null) { currentEntry.Name = longName.ToString(); } } else { this.currentEntry = this.entryFactory.CreateEntry(headerBuf); } this.entryOffset = 0; this.entrySize = this.currentEntry.Size; } catch (InvalidHeaderException ex) { this.entrySize = 0; this.entryOffset = 0; this.currentEntry = null; string errorText = string.Format("Bad header in record {0} block {1} {2}", buffer.CurrentRecord, buffer.CurrentBlock, ex.Message); throw new InvalidHeaderException(errorText); } } return(this.currentEntry); }
private static void GetCheckSumOctalBytes(long value, byte[] buffer, int offset, int length) { TarHeader.GetOctalBytes(value, buffer, offset, length - 1); }
public override bool Equals(object obj) { TarHeader tarHeader = obj as TarHeader; return(tarHeader != null && (this.name == tarHeader.name && this.mode == tarHeader.mode && this.UserId == tarHeader.UserId && this.GroupId == tarHeader.GroupId && this.Size == tarHeader.Size && this.ModTime == tarHeader.ModTime && this.Checksum == tarHeader.Checksum && this.TypeFlag == tarHeader.TypeFlag && this.LinkName == tarHeader.LinkName && this.Magic == tarHeader.Magic && this.Version == tarHeader.Version && this.UserName == tarHeader.UserName && this.GroupName == tarHeader.GroupName && this.DevMajor == tarHeader.DevMajor) && this.DevMinor == tarHeader.DevMinor); }
/// <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(nameof(entry)); } if (entry.TarHeader.Name.Length > TarHeader.NAMELEN) { var longHeader = new TarHeader(); longHeader.TypeFlag = TarHeader.LF_GNU_LONGNAME; longHeader.Name = longHeader.Name + "././@LongLink"; longHeader.Mode = 420;//644 by default longHeader.UserId = entry.UserId; longHeader.GroupId = entry.GroupId; longHeader.GroupName = entry.GroupName; longHeader.UserName = entry.UserName; longHeader.LinkName = ""; longHeader.Size = entry.TarHeader.Name.Length + 1; // Plus one to avoid dropping last char longHeader.WriteHeader(blockBuffer); buffer.WriteBlock(blockBuffer); // Add special long filename header block int nameCharIndex = 0; while (nameCharIndex < entry.TarHeader.Name.Length + 1 /* we've allocated one for the null char, now we must make sure it gets written out */) { Array.Clear(blockBuffer, 0, blockBuffer.Length); TarHeader.GetAsciiBytes(entry.TarHeader.Name, nameCharIndex, this.blockBuffer, 0, TarBuffer.BlockSize); // This func handles OK the extra char out of string length nameCharIndex += TarBuffer.BlockSize; buffer.WriteBlock(blockBuffer); } } entry.WriteEntryHeader(blockBuffer); buffer.WriteBlock(blockBuffer); currBytes = 0; currSize = entry.IsDirectory ? 0 : entry.Size; }
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); }
/// <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; }
/// <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> /// Construct an entry from an archive's header bytes. File is set /// to null. /// </summary> /// <param name = "headerBuffer"> /// The header bytes from a tar archive entry. /// </param> /// <param name = "nameEncoding"> /// The <see cref="Encoding"/> used for the Name fields, or null for ASCII only /// </param> public TarEntry(byte[] headerBuffer, Encoding nameEncoding) { header = new TarHeader(); header.ParseBuffer(headerBuffer, nameEncoding); }
/// <summary> /// Initialization code common to all pseudo constructors. /// </summary> void Initialize() { this.file = null; this.header = new TarHeader(); }
/// <summary> /// Parse TarHeader information from a header buffer. /// </summary> /// <param name = "header"> /// The tar entry header buffer to get information from. /// </param> public void ParseBuffer(byte[] header) { if (header == null) { throw new ArgumentNullException(nameof(header)); } int offset = 0; name = ParseName(header, offset, NAMELEN).ToString(); offset += NAMELEN; mode = (int)ParseOctal(header, offset, MODELEN); offset += MODELEN; UserId = (int)ParseOctal(header, offset, UIDLEN); offset += UIDLEN; GroupId = (int)ParseOctal(header, offset, GIDLEN); offset += GIDLEN; Size = ParseBinaryOrOctal(header, offset, SIZELEN); offset += SIZELEN; ModTime = GetDateTimeFromCTime(ParseOctal(header, offset, MODTIMELEN)); offset += MODTIMELEN; checksum = (int)ParseOctal(header, offset, CHKSUMLEN); offset += CHKSUMLEN; TypeFlag = header[offset++]; LinkName = ParseName(header, offset, NAMELEN).ToString(); offset += NAMELEN; Magic = ParseName(header, offset, MAGICLEN).ToString(); offset += MAGICLEN; if (Magic == "ustar") { Version = ParseName(header, offset, VERSIONLEN).ToString(); offset += VERSIONLEN; UserName = ParseName(header, offset, UNAMELEN).ToString(); offset += UNAMELEN; GroupName = ParseName(header, offset, GNAMELEN).ToString(); offset += GNAMELEN; DevMajor = (int)ParseOctal(header, offset, DEVLEN); offset += DEVLEN; DevMinor = (int)ParseOctal(header, offset, DEVLEN); offset += DEVLEN; string prefix = ParseName(header, offset, PREFIXLEN).ToString(); if (!string.IsNullOrEmpty(prefix)) { Name = prefix + '/' + Name; } } isChecksumValid = Checksum == TarHeader.MakeCheckSum(header); }
/// <summary> /// Convenience method that will modify an entry's name directly /// in place in an entry header buffer byte array. /// </summary> /// <param name="buffer"> /// The buffer containing the entry header to modify. /// </param> /// <param name="newName"> /// The new name to place into the header buffer. /// </param> static public void AdjustEntryName(byte[] buffer, string newName) { TarHeader.GetNameBytes(newName, buffer, 0, TarHeader.NAMELEN); }
public override bool Equals(object obj) { TarHeader header = obj as TarHeader; return((header != null) && ((((((this.name == header.name) && (this.mode == header.mode)) && ((this.UserId == header.UserId) && (this.GroupId == header.GroupId))) && (((this.Size == header.Size) && (this.ModTime == header.ModTime)) && ((this.Checksum == header.Checksum) && (this.TypeFlag == header.TypeFlag)))) && ((((this.LinkName == header.LinkName) && (this.Magic == header.Magic)) && ((this.Version == header.Version) && (this.UserName == header.UserName))) && ((this.GroupName == header.GroupName) && (this.DevMajor == header.DevMajor)))) && (this.DevMinor == header.DevMinor))); }
/// <summary> /// Initialise a default instance of <see cref="TarEntry"/>. /// </summary> private TarEntry() { header = new TarHeader(); }
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); }
/// <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.currentEntry != null) { SkipToNextEntry(); } byte[] headerBuf = this.buffer.ReadBlock(); if (headerBuf == null) { this.hasHitEOF = true; } else if (buffer.IsEOFBlock(headerBuf)) { this.hasHitEOF = true; } if (this.hasHitEOF) { this.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.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 && header.TypeFlag != TarHeader.LF_DIR) { // Ignore things we dont understand completely for now SkipToNextEntry(); headerBuf = this.buffer.ReadBlock(); } if (this.entryFactory == null) { this.currentEntry = new TarEntry(headerBuf); if (longName != null) { currentEntry.Name = longName.ToString(); } } else { this.currentEntry = this.entryFactory.CreateEntry(headerBuf); } // Magic was checked here for 'ustar' but there are multiple valid possibilities // so this is not done anymore. this.entryOffset = 0; // TODO: Review How do we resolve this discrepancy?! this.entrySize = this.currentEntry.Size; } catch (InvalidHeaderException ex) { this.entrySize = 0; this.entryOffset = 0; this.currentEntry = null; string errorText = string.Format("Bad header in record {0} block {1} {2}", buffer.CurrentRecord, buffer.CurrentBlock, ex.Message); throw new InvalidHeaderException(errorText); } } return(this.currentEntry); }
/// <summary> /// Convenience method that will modify an entry's name directly /// in place in an entry header buffer byte array. /// </summary> /// <param name="buffer"> /// The buffer containing the entry header to modify. /// </param> /// <param name="newName"> /// The new name to place into the header buffer. /// </param> static public void AdjustEntryName(byte[] buffer, string newName) { int offset = 0; TarHeader.GetNameBytes(newName, buffer, offset, TarHeader.NAMELEN); }
/// <summary> /// Fill in a TarHeader given only the entry's name. /// </summary> /// <param name="hdr"> /// The TarHeader to fill in. /// </param> /// <param name="name"> /// The tar entry name. /// </param> public void NameTarHeader(TarHeader hdr, string name) { bool isDir = name.EndsWith("/"); hdr.checkSum = 0; hdr.name = new StringBuilder(name); hdr.mode = isDir ? 1003 : 33216; hdr.userId = 0; hdr.groupId = 0; hdr.size = 0; hdr.checkSum = 0; hdr.modTime = DateTime.UtcNow; hdr.typeFlag = isDir ? TarHeader.LF_DIR : TarHeader.LF_NORMAL; hdr.linkName = new StringBuilder(String.Empty); hdr.userName = new StringBuilder(String.Empty); hdr.groupName = new StringBuilder(String.Empty); hdr.devMajor = 0; hdr.devMinor = 0; }
/// <summary> /// Fill in a TarHeader with information from a File. /// </summary> /// <param name="header"> /// The TarHeader to fill in. /// </param> /// <param name="file"> /// The file from which to get the header information. /// </param> public void GetFileTarHeader(TarHeader header, string file) { if ( header == null ) { throw new ArgumentNullException("header"); } if ( file == null ) { throw new ArgumentNullException("file"); } this.file = file; header.LinkName = String.Empty; /// <remarks> /// Needed to remove directory tree for ODIN sanity /// header.Name = name; /// </remarks> header.Name = Path.GetFileName(file); if (Directory.Exists(file)) { header.Mode = 1003; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_DIR; if ( (header.Name.Length == 0) || header.Name[header.Name.Length - 1] != '/') { header.Name = header.Name + "/"; } header.Size = 0; } else { header.Mode = 33216; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_NORMAL; header.Size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; } header.ModTime = System.IO.File.GetLastWriteTime(file.Replace('/', Path.DirectorySeparatorChar)).ToUniversalTime(); header.DevMajor = 0; header.DevMinor = 0; }
/// <summary> /// Construct an entry from an archive's header bytes. File is set /// to null. /// </summary> /// <param name = "headerBuffer"> /// The header bytes from a tar archive entry. /// </param> public TarEntry(byte[] headerBuffer) { header = new TarHeader(); header.ParseBuffer(headerBuffer); }
public void GetFileTarHeader(TarHeader header, string file) { if ( header == null ) { throw new ArgumentNullException("header"); } if ( file == null ) { throw new ArgumentNullException("file"); } this.file = file; string name = file; #if !NETCF_1_0 && !NETCF_2_0 if (name.IndexOf(Environment.CurrentDirectory) == 0) { name = name.Substring(Environment.CurrentDirectory.Length); } #endif name = name.Replace(Path.DirectorySeparatorChar, '/'); while (name.StartsWith("/")) { name = name.Substring(1); } header.LinkName = String.Empty; header.Name = name; if (Directory.Exists(file)) { header.Mode = 1003; header.TypeFlag = TarHeader.LF_DIR; if ( (header.Name.Length == 0) || header.Name[header.Name.Length - 1] != '/') { header.Name = header.Name + "/"; } header.Size = 0; } else { header.Mode = 33216; header.TypeFlag = TarHeader.LF_NORMAL; header.Size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; } header.ModTime = System.IO.File.GetLastWriteTime(file.Replace('/', Path.DirectorySeparatorChar)).ToUniversalTime(); header.DevMajor = 0; header.DevMinor = 0; }
/// <summary> /// Fill in a TarHeader given only the entry's name. /// </summary> /// <param name="hdr"> /// The TarHeader to fill in. /// </param> /// <param name="name"> /// The tar entry name. /// </param> public void NameTarHeader(TarHeader hdr, string name) { bool isDir = name.EndsWith("/"); hdr.Name = name; hdr.Mode = isDir ? 1003 : 33216; hdr.UserId = 0; hdr.GroupId = 0; hdr.Size = 0; hdr.ModTime = DateTime.UtcNow; hdr.TypeFlag = isDir ? TarHeader.LF_DIR : TarHeader.LF_NORMAL; hdr.LinkName = String.Empty; hdr.UserName = String.Empty; hdr.GroupName = String.Empty; hdr.DevMajor = 0; hdr.DevMinor = 0; }
/// <summary> /// Convenience method that will modify an entry's name directly /// in place in an entry header buffer byte array. /// </summary> /// <param name="outbuf"> /// The buffer containing the entry header to modify. /// </param> /// <param name="newName"> /// The new name to place into the header buffer. /// </param> public void AdjustEntryName(byte[] outbuf, string newName) { int offset = 0; offset = TarHeader.GetNameBytes(new StringBuilder(newName), outbuf, offset, TarHeader.NAMELEN); }
/// <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> /// Fill in a TarHeader with information from a File. /// </summary> /// <param name="hdr"> /// The TarHeader to fill in. /// </param> /// <param name="file"> /// The file from which to get the header information. /// </param> public void GetFileTarHeader(TarHeader hdr, string file) { this.file = file; // bugfix from torhovl from #D forum: string name = file; // -jr- 23-Jan-2004 HAK HAK HAK, GnuTar allows device names in path where the name is not local to the current directory if (Environment.CurrentDirectory == Path.GetDirectoryName(name)) { name = Path.GetFileName(name); } /* * if (Path.DirectorySeparatorChar == '\\') * { // check if the OS is Windows * // Strip off drive letters! * if (name.Length > 2) * { * char ch1 = name[0]; * char ch2 = name[1]; * * if (ch2 == ':' && Char.IsLetter(ch1)) * { * name = name.Substring(2); * } * } * } */ name = name.Replace(Path.DirectorySeparatorChar, '/').ToLower(); // No absolute pathnames // Windows (and Posix?) paths can start with UNC style "\\NetworkDrive\", // so we loop on starting /'s. while (name.StartsWith("/")) { name = name.Substring(1); } hdr.linkName = new StringBuilder(String.Empty); hdr.name = new StringBuilder(name); if (Directory.Exists(file)) { hdr.mode = 1003; // 01753 -jr- no octal constants!! 040755; // Magic number for security access for a UNIX filesystem hdr.typeFlag = TarHeader.LF_DIR; if (hdr.name.Length == 0 || hdr.name[hdr.name.Length - 1] != '/') { hdr.name.Append("/"); } hdr.size = 0; } else { hdr.mode = 33216; // 0100700 -jr- // 0100644; // Magic number for security access for a UNIX filesystem hdr.typeFlag = TarHeader.LF_NORMAL; hdr.size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; } // UNDONE When File lets us get the userName, use it! hdr.modTime = System.IO.File.GetLastWriteTimeUtc(file.Replace('/', Path.DirectorySeparatorChar)); // -jr- Unix times are in UTC hdr.checkSum = 0; hdr.devMajor = 0; hdr.devMinor = 0; }
public TarEntry(TarHeader header) { file = null; this.header = header; }
/// <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) { 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; } 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 && header.typeFlag != TarHeader.LF_DIR) { // 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 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); }
/// <summary> /// Fill in a TarHeader with information from a File. /// </summary> /// <param name="hdr"> /// The TarHeader to fill in. /// </param> /// <param name="file"> /// The file from which to get the header information. /// </param> public void GetFileTarHeader(TarHeader hdr, string file) { this.file = file; // bugfix from torhovl from #D forum: string name = file; // -jr- 23-Jan-2004 HAK HAK HAK, GnuTar allows device names in path where the name is not local to the current directory if (Environment.CurrentDirectory == Path.GetDirectoryName(name)) { name = Path.GetFileName(name); } /* if (Path.DirectorySeparatorChar == '\\') { // check if the OS is Windows // Strip off drive letters! if (name.Length > 2) { char ch1 = name[0]; char ch2 = name[1]; if (ch2 == ':' && Char.IsLetter(ch1)) { name = name.Substring(2); } } } */ name = name.Replace(Path.DirectorySeparatorChar, '/').ToLower(); // No absolute pathnames // Windows (and Posix?) paths can start with UNC style "\\NetworkDrive\", // so we loop on starting /'s. while (name.StartsWith("/")) { name = name.Substring(1); } hdr.linkName = new StringBuilder(String.Empty); hdr.name = new StringBuilder(name); if (Directory.Exists(file)) { hdr.mode = 1003; // 01753 -jr- no octal constants!! 040755; // Magic number for security access for a UNIX filesystem hdr.typeFlag = TarHeader.LF_DIR; if (hdr.name.Length == 0 || hdr.name[hdr.name.Length - 1] != '/') { hdr.name.Append("/"); } hdr.size = 0; } else { hdr.mode = 33216; // 0100700 -jr- // 0100644; // Magic number for security access for a UNIX filesystem hdr.typeFlag = TarHeader.LF_NORMAL; hdr.size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; } // UNDONE When File lets us get the userName, use it! hdr.modTime = System.IO.File.GetLastWriteTimeUtc(file.Replace('/', Path.DirectorySeparatorChar)); // -jr- Unix times are in UTC hdr.checkSum = 0; hdr.devMajor = 0; hdr.devMinor = 0; }
/// <summary> /// Construct a TarEntry using the <paramref name="header">header</paramref> provided /// </summary> /// <param name="header">Header details for entry</param> public TarEntry(TarHeader header) { file = null; this.header = header; }
/// <summary> /// Fill in a TarHeader with information from a File. /// </summary> /// <param name="header"> /// The TarHeader to fill in. /// </param> /// <param name="file"> /// The file from which to get the header information. /// </param> public void GetFileTarHeader(TarHeader header, string file) { if (header == null) { throw new ArgumentNullException("header"); } if (file == null) { throw new ArgumentNullException("file"); } this.file = file; // bugfix from torhovl from #D forum: string name = file; // 23-Jan-2004 GnuTar allows device names in path where the name is not local to the current directory if (name.IndexOf(Environment.CurrentDirectory, StringComparison.Ordinal) == 0) { name = name.Substring(Environment.CurrentDirectory.Length); } /* if (Path.DirectorySeparatorChar == '\\') { // check if the OS is Windows // Strip off drive letters! if (name.Length > 2) { char ch1 = name[0]; char ch2 = name[1]; if (ch2 == ':' && Char.IsLetter(ch1)) { name = name.Substring(2); } } } */ name = name.Replace(Path.DirectorySeparatorChar, '/'); // No absolute pathnames // Windows (and Posix?) paths can start with UNC style "\\NetworkDrive\", // so we loop on starting /'s. while (name.StartsWith("/", StringComparison.Ordinal)) { name = name.Substring(1); } header.LinkName = String.Empty; header.Name = name; if (Directory.Exists(file)) { header.Mode = 1003; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_DIR; if ((header.Name.Length == 0) || header.Name[header.Name.Length - 1] != '/') { header.Name = header.Name + "/"; } header.Size = 0; } else { header.Mode = 33216; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_NORMAL; header.Size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; } header.ModTime = System.IO.File.GetLastWriteTime(file.Replace('/', Path.DirectorySeparatorChar)).ToUniversalTime(); header.DevMajor = 0; header.DevMinor = 0; }
/// <summary> /// Initialization code common to all pseudo constructors. /// </summary> void Initialize() { file = null; header = new TarHeader(); }
public void HeaderEquality() { TarHeader h1 = new TarHeader(); TarHeader h2 = new TarHeader(); Assert.IsTrue(h1.Equals(h2)); h1.Name = "ABCDEFG"; Assert.IsFalse(h1.Equals(h2)); h2.Name = h1.Name; Assert.IsTrue(h1.Equals(h2)); h1.Mode = 33188; Assert.IsFalse(h1.Equals(h2)); h2.Mode = h1.Mode; Assert.IsTrue(h1.Equals(h2)); h1.UserId = 654; Assert.IsFalse(h1.Equals(h2)); h2.UserId = h1.UserId; Assert.IsTrue(h1.Equals(h2)); h1.GroupId = 654; Assert.IsFalse(h1.Equals(h2)); h2.GroupId = h1.GroupId; Assert.IsTrue(h1.Equals(h2)); h1.Size = 654; Assert.IsFalse(h1.Equals(h2)); h2.Size = h1.Size; Assert.IsTrue(h1.Equals(h2)); h1.ModTime = DateTime.Now; Assert.IsFalse(h1.Equals(h2)); h2.ModTime = h1.ModTime; Assert.IsTrue(h1.Equals(h2)); h1.TypeFlag = 165; Assert.IsFalse(h1.Equals(h2)); h2.TypeFlag = h1.TypeFlag; Assert.IsTrue(h1.Equals(h2)); h1.LinkName = "link"; Assert.IsFalse(h1.Equals(h2)); h2.LinkName = h1.LinkName; Assert.IsTrue(h1.Equals(h2)); h1.Magic = "ustar"; Assert.IsFalse(h1.Equals(h2)); h2.Magic = h1.Magic; Assert.IsTrue(h1.Equals(h2)); h1.Version = "1"; Assert.IsFalse(h1.Equals(h2)); h2.Version = h1.Version; Assert.IsTrue(h1.Equals(h2)); h1.UserName = "******"; Assert.IsFalse(h1.Equals(h2)); h2.UserName = h1.UserName; Assert.IsTrue(h1.Equals(h2)); h1.GroupName = "group"; Assert.IsFalse(h1.Equals(h2)); h2.GroupName = h1.GroupName; Assert.IsTrue(h1.Equals(h2)); h1.DevMajor = 165; Assert.IsFalse(h1.Equals(h2)); h2.DevMajor = h1.DevMajor; Assert.IsTrue(h1.Equals(h2)); h1.DevMinor = 164; Assert.IsFalse(h1.Equals(h2)); h2.DevMinor = h1.DevMinor; Assert.IsTrue(h1.Equals(h2)); }
/// <summary> /// Convenience method that will modify an entry's name directly /// in place in an entry header buffer byte array. /// </summary> /// <param name="outbuf"> /// The buffer containing the entry header to modify. /// </param> /// <param name="newName"> /// The new name to place into the header buffer. /// </param> public void AdjustEntryName(byte[] outbuf, string newName) { var offset = 0; TarHeader.GetNameBytes(newName, outbuf, offset, TarHeader.NAMELEN); }
/// <summary> /// Fill in a TarHeader given only the entry's name. /// </summary> /// <param name="header"> /// The TarHeader to fill in. /// </param> /// <param name="name"> /// The tar entry name. /// </param> static public void NameTarHeader(TarHeader header, string name) { if ( header == null ) { throw new ArgumentNullException("header"); } if ( name == null ) { throw new ArgumentNullException("name"); } bool isDir = name.EndsWith("/"); header.Name = name; header.Mode = isDir ? 1003 : 33216; header.UserId = 0; header.GroupId = 0; header.Size = 0; header.ModTime = DateTime.UtcNow; header.TypeFlag = isDir ? TarHeader.LF_DIR : TarHeader.LF_NORMAL; header.LinkName = String.Empty; header.UserName = String.Empty; header.GroupName = String.Empty; header.DevMajor = 0; header.DevMinor = 0; }
/// <summary> /// Fill in a TarHeader with information from a File. /// </summary> /// <param name="hdr"> /// The TarHeader to fill in. /// </param> /// <param name="file"> /// The file from which to get the header information. /// </param> public void GetFileTarHeader(TarHeader hdr, string file) { this.file = file; // bugfix from torhovl from #D forum: var name = file; #if !COMPACT_FRAMEWORK // 23-Jan-2004 GnuTar allows device names in path where the name is not local to the current directory if (name.IndexOf(Environment.CurrentDirectory) == 0) { name = name.Substring(Environment.CurrentDirectory.Length); } #endif /* * if (Path.DirectorySeparatorChar == '\\') * { // check if the OS is Windows * // Strip off drive letters! * if (name.Length > 2) * { * char ch1 = name[0]; * char ch2 = name[1]; * * if (ch2 == ':' && Char.IsLetter(ch1)) * { * name = name.Substring(2); * } * } * } */ name = name.Replace(Path.DirectorySeparatorChar, '/'); // No absolute pathnames // Windows (and Posix?) paths can start with UNC style "\\NetworkDrive\", // so we loop on starting /'s. while (name.StartsWith("/")) { name = name.Substring(1); } hdr.LinkName = String.Empty; hdr.Name = name; if (Directory.Exists(file)) { hdr.Mode = 1003; // Magic number for security access for a UNIX filesystem hdr.TypeFlag = TarHeader.LF_DIR; if (hdr.Name.Length == 0 || hdr.Name[hdr.Name.Length - 1] != '/') { hdr.Name = hdr.Name + "/"; } hdr.Size = 0; } else { hdr.Mode = 33216; // Magic number for security access for a UNIX filesystem hdr.TypeFlag = TarHeader.LF_NORMAL; hdr.Size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; } hdr.ModTime = System.IO.File.GetLastWriteTime(file.Replace('/', Path.DirectorySeparatorChar)).ToUniversalTime(); hdr.DevMajor = 0; hdr.DevMinor = 0; }
/// <summary> /// Fill in a TarHeader with information from a File. /// </summary> /// <param name="header"> /// The TarHeader to fill in. /// </param> /// <param name="file"> /// The file from which to get the header information. /// </param> public void GetFileTarHeader(TarHeader header, string file) { if (header == null) { throw new ArgumentNullException("header"); } if (file == null) { throw new ArgumentNullException("file"); } this.file = file; // bugfix from torhovl from #D forum: string name = file; // 23-Jan-2004 GnuTar allows device names in path where the name is not local to the current directory if (name.IndexOf(Directory.GetCurrentDirectory(), StringComparison.Ordinal) == 0) { name = name.Substring(Directory.GetCurrentDirectory().Length); } /* * if (Path.DirectorySeparatorChar == '\\') * { * // check if the OS is Windows * // Strip off drive letters! * if (name.Length > 2) * { * char ch1 = name[0]; * char ch2 = name[1]; * * if (ch2 == ':' && Char.IsLetter(ch1)) * { * name = name.Substring(2); * } * } * } */ name = name.Replace(Path.DirectorySeparatorChar, '/'); // No absolute pathnames // Windows (and Posix?) paths can start with UNC style "\\NetworkDrive\", // so we loop on starting /'s. while (name.StartsWith("/", StringComparison.Ordinal)) { name = name.Substring(1); } header.LinkName = String.Empty; header.Name = name; if (Directory.Exists(file)) { header.Mode = 1003; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_DIR; if ((header.Name.Length == 0) || header.Name[header.Name.Length - 1] != '/') { header.Name = header.Name + "/"; } header.Size = 0; } else { header.Mode = 33216; // Magic number for security access for a UNIX filesystem header.TypeFlag = TarHeader.LF_NORMAL; header.Size = new FileInfo(file.Replace('/', Path.DirectorySeparatorChar)).Length; } header.ModTime = System.IO.File.GetLastWriteTime(file.Replace('/', Path.DirectorySeparatorChar)).ToUniversalTime(); header.DevMajor = 0; header.DevMinor = 0; }