/// <summary> /// Read the next 512 byte chunk of data as a tar header. /// </summary> /// <returns>A tar header structure. null if we have reached the end of the archive.</returns> protected TarHeader ReadHeader () { byte [] header = m_br.ReadBytes (512); // If there are no more bytes in the stream, return null header if (header.Length == 0) return null; // If we've reached the end of the archive we'll be in null block territory, which means // the next byte will be 0 if (header [0] == 0) return null; TarHeader tarHeader = new TarHeader (); // If we're looking at a GNU tar long link then extract the long name and pull up the next header if (header [156] == (byte)'L') { int longNameLength = ConvertOctalBytesToDecimal (header, 124, 11); tarHeader.FilePath = m_asciiEncoding.GetString (ReadData (longNameLength)); //MainConsole.Instance.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath); header = m_br.ReadBytes (512); } else { tarHeader.FilePath = m_asciiEncoding.GetString (header, 0, 100); tarHeader.FilePath = tarHeader.FilePath.Trim (m_nullCharArray); //MainConsole.Instance.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath); } tarHeader.FileSize = ConvertOctalBytesToDecimal (header, 124, 11); switch (header [156]) { case 0: tarHeader.EntryType = TarEntryType.TYPE_NORMAL_FILE; break; case (byte)'0': tarHeader.EntryType = TarEntryType.TYPE_NORMAL_FILE; break; case (byte)'1': tarHeader.EntryType = TarEntryType.TYPE_HARD_LINK; break; case (byte)'2': tarHeader.EntryType = TarEntryType.TYPE_SYMBOLIC_LINK; break; case (byte)'3': tarHeader.EntryType = TarEntryType.TYPE_CHAR_SPECIAL; break; case (byte)'4': tarHeader.EntryType = TarEntryType.TYPE_BLOCK_SPECIAL; break; case (byte)'5': tarHeader.EntryType = TarEntryType.TYPE_DIRECTORY; break; case (byte)'6': tarHeader.EntryType = TarEntryType.TYPE_FIFO; break; case (byte)'7': tarHeader.EntryType = TarEntryType.TYPE_CONTIGUOUS_FILE; break; } return tarHeader; }