Example #1
0
        protected override byte[] GetBuffer()
        {
            byte[] buffer = new byte[TarHeader.Length];

            TarHeader header = new TarHeader();
            header.FileName = _fileName;
            header.FileLength = _fileLength;
            header.WriteTo(buffer, 0);

            return buffer;
        }
Example #2
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);
		}
Example #3
0
		/// <summary>
		/// Initialise a default instance of <see cref="TarEntry"/>.
		/// </summary>
		private TarEntry()
		{
			header = new TarHeader();
		}
Example #4
0
		/// <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;
		}
Example #5
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;

#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);
			}

			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;
		}
        public override int Read(byte[] buffer, int offset, int count)
        {
            int origCount = count;

            while (count > 0)
            {
                if (currentEntryLength > 0 && currentEntryPosition >= currentEntryLength) // Next entry
                {
                    currentEntry++;
                    currentEntryPosition = 0;
                }
                if (currentEntry >= entries.Count) // End of archive, write zeros
                {
                    if (currentFile != null)
                    {
                        if (currentFileOwned)
                        {
                            currentFile.Dispose();
                        }
                        currentFile      = null;
                        currentFileOwned = false;
                    }
                    long l     = Math.Min(count, totalSize - position);
                    var  dummy = new byte[l];
                    Array.Copy(dummy, 0, buffer, offset, l);
                    count                -= (int)l;
                    position             += l;
                    currentEntryPosition += l;
                    offset               += (int)l;
                    break;
                }

                if (currentEntryPosition == 0) // New entry
                {
                    currentEntryLength = 512;
                    var header = new TarHeader();

                    var fileName = entries[currentEntry].FileName ?? entries[currentEntry].ExtInfo.FilePath;
                    if (fileName != LongLinkFlag)
                    {
                        header.FileName = fileName.Substring(rootDirectory.Length + 1).Replace(@"\", "/");
                    }

                    if (currentFile != null)
                    {
                        if (currentFileOwned)
                        {
                            currentFile.Dispose();
                        }
                        currentFile      = null;
                        currentFileOwned = false;
                    }

                    if (fileName == LongLinkFlag)
                    {
                        header.FileName = fileName;
                        header.FileMode = "0000000";
                        fileName        = (entries[currentEntry + 1].FileName ?? entries[currentEntry + 1].ExtInfo.FilePath).Substring(rootDirectory.Length + 1).Replace(@"\", "/");
                        var nameBuff = Encoding.UTF8.GetBytes(fileName);
                        currentFile = new MemoryStream(nameBuff.Length + 1);
                        currentFile.Write(nameBuff, 0, nameBuff.Length);
                        currentFile.WriteByte(0);
                        currentFile.Seek(0, SeekOrigin.Begin);
                        currentEntryLength += currentFile.Length;
                        if (currentFile.Length % 512 != 0)
                        {
                            currentEntryLength += 512 - (currentFile.Length % 512);
                        }
                        header.FileSize             = Convert.ToString(currentFile.Length, 8).PadLeft(11, '0');
                        header.LastModificationTime = "0".PadLeft(11, '0');
                        header.FileType             = 'L';
                    }
                    else if (!header.FileName.EndsWith("/")) // It's a file!
                    {
                        string   localFilePath = entries[currentEntry].FileName ?? entries[currentEntry].ExtInfo.LocalFilePath;
                        DateTime lastWriteTimeUtc;
                        if (localFilePath != null) // Standard file
                        {
                            currentFile      = new FileStream(localFilePath, FileMode.Open);
                            currentFileOwned = true;
                            lastWriteTimeUtc = new FileInfo(localFilePath).LastWriteTimeUtc;
                        }
                        else // file link
                        {
                            currentFile = entries[currentEntry].ExtInfo.FileStream ?? new MemoryStream();
                            try
                            {
                                currentFile.Position = 0;
                            }
                            catch { }
                            currentFileOwned = entries[currentEntry].ExtInfo.FileStream == null;
                            lastWriteTimeUtc = entries[currentEntry].ExtInfo.ModifiedTime;
                        }

                        header.FileMode     = "0100644";
                        currentEntryLength += currentFile.Length;
                        if (currentFile.Length % 512 != 0)
                        {
                            currentEntryLength += 512 - (currentFile.Length % 512);
                        }
                        header.FileSize             = Convert.ToString(currentFile.Length, 8).PadLeft(11, '0');
                        header.LastModificationTime = Convert.ToString(
                            (long)lastWriteTimeUtc.Subtract(new DateTime(1970, 1, 1)).TotalSeconds
                            , 8).PadLeft(11, '0');
                        header.FileType = '0';

                        this.currentFileName = header.FileName; // keep filename for advanced progress report
                    }
                    else if (header.FileName.EndsWith("/"))     // It's a directory...
                    {
                        DateTime lastWriteTimeUtc = entries[currentEntry].FileName != null ? new DirectoryInfo(entries[currentEntry].FileName).LastWriteTimeUtc : DateTime.UtcNow;
                        header.FileMode             = "0040755";
                        header.FileSize             = "".PadLeft(11, '0');
                        header.LastModificationTime = Convert.ToString(
                            (long)lastWriteTimeUtc.Subtract(new DateTime(1970, 1, 1)).TotalSeconds
                            , 8).PadLeft(11, '0');
                        header.FileType = '5';
                    }
                    header.OwnerID    = "0000000";
                    header.GroupID    = "0000000";
                    header.UstarMagic = "ustar  ";
                    //header.UstarVersion = new char[] {'0', '0'};
                    header.CalcChecksum();
                    currentHeader = header.GetBytes();
                }

                if (currentEntryPosition < 512) // Header
                {
                    long l = Math.Min(count, 512 - currentEntryPosition);
                    Array.Copy(currentHeader, currentEntryPosition, buffer, offset, l);
                    count                -= (int)l;
                    position             += l;
                    currentEntryPosition += l;
                    offset               += (int)l;
                }
                else // Data
                {
                    long l = Math.Min(count, currentEntryLength - currentEntryPosition);
                    currentFile.Read(buffer, offset, (int)l);
                    count                -= (int)l;
                    position             += l;
                    currentEntryPosition += l;
                    offset               += (int)l;
                }
            }
            OnReadProgress(Position, Length);
            OnAdvancedReadProgress(Position, Length, this.currentFileName);
            return(origCount - count);
        }
Example #7
0
 // Constructor called when reading a TarEntry from a TarReader.
 internal UstarTarEntry(TarHeader header, TarReader readerOfOrigin)
     : base(header, readerOfOrigin, TarEntryFormat.Ustar)
 {
 }
Example #8
0
 internal TarFilePart(TarHeader header, Stream seekableStream)
 {
     this.seekableStream = seekableStream;
     this.Header         = header;
 }
Example #9
0
        public override bool AddFile(string filename, string tar_filename = null)
        {
            /* No tar within tar. */
            Debug.Assert(tar_filename == null);

            /* The TAR-header, repeated for every file */


            /* Check if we already seen this file */
            if (FileIO._tar_list[(int)this.subdir].TryGetValue(filename, out var it) == false)
            {
                return(false);
            }

            var links = new Dictionary <string, string>();

            try
            {
                using (var f = new FileInfo(filename).OpenRead())
                {
                    FileIO._tar_list[(int)this.subdir][filename].filename = filename;
                    FileIO._tar_list[(int)this.subdir][filename].dirname  = null;
                    var dupped_filename = filename;
                    /// Temporary list to collect links

                    string name = null; //char[sizeof(th.prefix) + 1 + sizeof(th.name) + 1];
                    string link = null; //char link[sizeof(th.linkname) + 1];
                    string dest = null;
                    //char dest[sizeof(th.prefix) + 1 + sizeof(th.name) + 1 + 1 + sizeof(th.linkname) + 1];
                    var num = 0;
                    var pos = 0;


                    var buffer = new byte[TarHeader.HeaderSize];
                    for (;;)
                    {
                        // Note: feof() always returns 'false' after 'fseek()'. Cool, isn't it?
                        var num_bytes_read = f.Read(buffer, 1, TarHeader.HeaderSize);
                        if (num_bytes_read != TarHeader.HeaderSize)
                        {
                            break;
                        }
                        pos += num_bytes_read;

                        var th = new TarHeader(buffer);

                        /* Check if we have the new tar-format (ustar) or the old one (a lot of zeros after 'link' field) */
                        if (th.magic != "ustar" && th.magic != "")
                        {
                            /* If we have only zeros in the block, it can be an end-of-file indicator */
                            if (buffer.Any(b => b != 0))
                            {
                                continue;
                            }

                            Log.Debug($"The file '{filename}' isn't a valid tar-file");
                            f.Close();
                            return(false);
                        }

                        name = null;

                        /* The prefix contains the directory-name */
                        if (th.prefix != "")
                        {
                            name = th.prefix + Path.PathSeparator;
                        }

                        /* Copy the name of the file in a safe way at the end of 'name' */
                        name += th.name;

                        switch (th.typeflag)
                        {
                        case '\0':
                        case '0':
                        {
                            // regular file
                            /* Ignore empty files */
                            if (th.size == 0)
                            {
                                break;
                            }

                            if (name.Length == 0)
                            {
                                break;
                            }

                            /* Store this entry in the list */
                            var entry = new TarFileListEntry()
                            {
                                tar_filename = dupped_filename,
                                size         = th.size,
                                position     = pos
                            };

                            /* Convert to lowercase and our PATHSEPCHAR */
                            name = FileIO.SimplifyFileName(name);

                            Log.Debug($"Found file in tar: ${name} ({th.size} bytes, {pos} offset)");
                            if (FileIO._tar_filelist[(int)this.subdir].ContainsKey(name) == false)
                            {
                                FileIO._tar_filelist[(int)this.subdir].Add(name, entry);
                                num++;
                            }

                            break;
                        }

                        case '1':     // hard links
                        case '2':
                        {
                            // symbolic links
                            /* Copy the destination of the link in a safe way at the end of 'linkname' */
                            link = th.linkname;

                            if (name.Length == 0 || link.Length == 0)
                            {
                                break;
                            }

                            /* Convert to lowercase and our PATHSEPCHAR */
                            name = FileIO.SimplifyFileName(name);
                            link = FileIO.SimplifyFileName(link);

                            /* Only allow relative links */
                            if (link[0] == Path.PathSeparator)
                            {
                                Log.Debug($"Ignoring absolute link in tar: {name} . {link}");
                                break;
                            }

                            /* Process relative path.
                             * Note: The destination of links must not contain any directory-links. */
                            dest = name;
                            //var destIndex = dest.LastIndexOf(Path.PathSeparator);
                            var destpos = dest;
                            //if (destIndex >= 0)
                            //{
                            //    destpos = dest.Substring(destIndex + 1);
                            //}

                            //TODO THIS MAKES NO SENSE
                            var linkParts = link.Split(Path.PathSeparator);
                            foreach (var linkPart in linkParts)
                            {
                                if (linkPart == ".")
                                {
                                    /* Skip '.' (current dir) */
                                }
                                else if (linkPart == "..")
                                {
                                    /* level up */
                                    if (dest == "")
                                    {
                                        Log.Debug(
                                            $"Ignoring link pointing outside of data directory: {name} . {link}");
                                        break;
                                    }

                                    /* Truncate 'dest' after last PATHSEPCHAR.
                                     * This assumes that the truncated part is a real directory and not a link. */
                                    destpos = linkParts.Last();
                                    break;
                                }
                                else
                                {
                                    /* Append at end of 'dest' */
                                    if (destpos.Any())
                                    {
                                        destpos += Path.PathSeparator;
                                    }
                                    destpos = dest;
                                }

                                //if (destpos >= lastof(dest)) {
                                //	Log.Debug("The length of a link in tar-file '{filename}' is too large (malformed?)");
                                //	f.Close();
                                //	return false;
                                //}
                            }

                            /* Store links in temporary list */
                            Log.Debug($"Found link in tar: {name} . {dest}");
                            links.Add(name, dest);

                            break;
                        }

                        case '5':     // directory
                            /* Convert to lowercase and our PATHSEPCHAR */
                            name = FileIO.SimplifyFileName(name);

                            /* Store the first directory name we detect */
                            Log.Debug($"Found dir in tar: {name}");
                            if (FileIO._tar_list[(int)this.subdir][filename].dirname == null)
                            {
                                FileIO._tar_list[(int)this.subdir][filename].dirname = name;
                            }
                            break;

                        default:
                            /* Ignore other types */
                            break;
                        }

                        /* Skip to the next block.. */
                        //var skip = Align(th.size, 512);
                        if (f.Seek(th.size, SeekOrigin.Current) < 0)
                        {
                            Log.Debug($"The file '{filename}' can't be read as a valid tar-file");
                            f.Close();
                            return(false);
                        }
                        pos += th.size;
                    }

                    Log.Debug($"Found tar '{filename}' with {num} new files");
                    f.Close();
                }
            }
            catch (IOException ex)
            {
                /* Although the file has been found there can be
                 * a number of reasons we cannot open the file.
                 * Most common case is when we simply have not
                 * been given read access. */
                Log.Error(ex);
                return(false);
            }



            /* Resolve file links and store directory links.
             * We restrict usage of links to two cases:
             *  1) Links to directories:
             *      Both the source path and the destination path must NOT contain any further links.
             *      When resolving files at most one directory link is resolved.
             *  2) Links to files:
             *      The destination path must NOT contain any links.
             *      The source path may contain one directory link.
             */
            foreach (var link in links)
            {
                var src  = link.Key;
                var dest = link.Value;
                FileIO.TarAddLink(src, dest, this.subdir);
            }

            return(true);
        }
Example #10
0
 internal TarFilePart(TarHeader header, Stream seekableStream)
     : base(header.ArchiveEncoding)
 {
     _seekableStream = seekableStream;
     Header          = header;
 }
Example #11
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            int origCount = count;

            while (count > 0)
            {
                if (currentEntryLength > 0 && currentEntryPosition >= currentEntryLength) // Next entry
                {
                    currentEntry++;
                    currentEntryPosition = 0;
                }

                if (currentEntry >= entries.Count) // end of archive, write zeros
                {
                    if (currentFile != null)
                    {
                        currentFile.Dispose();
                        currentFile = null;
                    }
                    long l     = Math.Min(count, totalSize - position);
                    var  dummy = new byte[l];
                    Array.Copy(dummy, 0, buffer, offset, l);
                    count                -= (int)l;
                    position             += l;
                    currentEntryPosition += l;
                    offset               += (int)l;
                    break;
                }

                if (currentEntryPosition == 0) // New entry
                {
                    currentEntryLength = 512;
                    var header = new TarHeader();
                    if (entries[currentEntry] != LongLinkFlag)
                    {
                        header.FileName = entries[currentEntry].Substring(rootDirectory.Length + 1).Replace(@"\", "/");
                    }
                    if (currentFile != null)
                    {
                        currentFile.Dispose();
                        currentFile = null;
                    }
                    if (entries[currentEntry] == LongLinkFlag)
                    {
                        header.FileName = entries[currentEntry];
                        header.FileMode = "0000000";
                        var name     = entries[currentEntry + 1].Substring(rootDirectory.Length + 1).Replace(@"\", "/");
                        var nameBuff = Encoding.UTF8.GetBytes(name);
                        currentFile = new MemoryStream(nameBuff.Length + 1);
                        currentFile.Write(nameBuff, 0, nameBuff.Length);
                        currentFile.WriteByte(0);
                        currentFile.Seek(0, SeekOrigin.Begin);
                        currentEntryLength += currentFile.Length;
                        if (currentFile.Length % 512 != 0)
                        {
                            currentEntryLength += 512 - (currentFile.Length % 512);
                        }
                        header.FileSize             = Convert.ToString(currentFile.Length, 8).PadLeft(11, '0');
                        header.LastModificationTime = "0".PadLeft(11, '0');
                        header.FileType             = 'L';
                    }
                    else if (!header.FileName.EndsWith("/")) // It's a file!
                    {
                        currentFile         = new FileStream(entries[currentEntry], FileMode.Open);
                        header.FileMode     = "0100644";
                        currentEntryLength += currentFile.Length;
                        if (currentFile.Length % 512 != 0)
                        {
                            currentEntryLength += 512 - (currentFile.Length % 512);
                        }
                        header.FileSize             = Convert.ToString(currentFile.Length, 8).PadLeft(11, '0');
                        header.LastModificationTime = Convert.ToString(
                            (long)new FileInfo(entries[currentEntry]).LastWriteTimeUtc.Subtract(new DateTime(1970, 1, 1)).TotalSeconds
                            , 8).PadLeft(11, '0');
                        header.FileType = '0';
                    }
                    else if (header.FileName.EndsWith("/")) // It's a directory...
                    {
                        header.FileMode             = "0040755";
                        header.FileSize             = "".PadLeft(11, '0');
                        header.LastModificationTime = Convert.ToString(
                            (long)new DirectoryInfo(entries[currentEntry]).LastWriteTimeUtc.Subtract(new DateTime(1970, 1, 1)).TotalSeconds
                            , 8).PadLeft(11, '0');
                        header.FileType = '5';
                    }
                    header.OwnerID    = "0000000";
                    header.GroupID    = "0000000";
                    header.UstarMagic = "ustar  ";
                    //header.UstarVersion = new char[] {'0', '0'};
                    header.CalcChecksum();
                    currentHeader = header.getBytes();
                }

                if (currentEntryPosition < 512) // Header
                {
                    long l = Math.Min(count, 512 - currentEntryPosition);
                    Array.Copy(currentHeader, currentEntryPosition, buffer, offset, l);
                    count                -= (int)l;
                    position             += l;
                    currentEntryPosition += l;
                    offset               += (int)l;
                }
                else // Data
                {
                    long l = Math.Min(count, currentEntryLength - currentEntryPosition);
                    currentFile.Read(buffer, offset, (int)l);
                    count                -= (int)l;
                    position             += l;
                    currentEntryPosition += l;
                    offset               += (int)l;
                }
            }
            OnReadProgress(Position, Length);
            return(origCount - count);
        }
		/// <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(this.blockBuffer);
				this.buffer.WriteBlock(this.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;
		}
Example #13
0
 // Constructor used when reading an existing archive.
 internal V7TarEntry(TarHeader header, TarReader readerOfOrigin)
     : base(header, readerOfOrigin)
 {
 }
		/// <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;
		}
 internal TarFilePart(TarHeader header)
 {
     this.Header = header;
 }
Example #16
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)
		{
			if ( header == null )
			{
				throw new ArgumentNullException("header");
			}

			this.header = (TarHeader)header.Clone();
		}
Example #17
0
        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));
        }
Example #18
0
 // Constructor called when reading a TarEntry from a TarReader.
 internal GnuTarEntry(TarHeader header, TarReader readerOfOrigin)
     : base(header, readerOfOrigin, TarEntryFormat.Gnu)
 {
 }