示例#1
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);
		}
		/// <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 (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) {  // 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;
		}
示例#3
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);
 }
示例#4
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 (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)                          // 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);
        }