This class represents an entry in a Tar archive. It consists of the entry's header, as well as the entry's File. Entries can be instantiated in one of three ways, depending on how they are to be used.

TarEntries that are created from the header bytes read from an archive are instantiated with the TarEntry( byte[] ) constructor. These entries will be used when extracting from or listing the contents of an archive. These entries have their header filled in using the header bytes. They also set the File to null, since they reference an archive entry not a file.

TarEntries that are created from files that are to be written into an archive are instantiated with the CreateEntryFromFile(string) pseudo constructor. These entries have their header filled in using the File's information. They also keep a reference to the File for convenience when writing entries.

Finally, TarEntries can be constructed from nothing but a name. This allows the programmer to construct the entry by hand, for instance when only an InputStream is available for writing to the archive, and the header information is constructed from other information. In this case the header fields are set to defaults and the File is set to null.

TarHeader
Example #1
1
 public static void MyLister(TarArchive ta, TarEntry te, string msg)
 {
     if (te.Size > 0)
     {
         Console.WriteLine(te.Name + " " + te.Size);
         totalsize = totalsize + 1;
     }
 }
Example #2
1
		private void WriteObjectToTar (TarOutputStream  tar_out,
					       FileSystemObject fso,
					       EventTracker     tracker)
		{
			MemoryStream memory = null;

			TarHeader header;
			header = new TarHeader ();

			StringBuilder name_builder;
			name_builder = new StringBuilder (fso.FullName);
			name_builder.Remove (0, this.FullName.Length+1);
			header.Name = name_builder.ToString ();

			header.ModTime = fso.Timestamp;
			if (fso is DirectoryObject) {
				header.Mode = 511; // 0777
				header.TypeFlag = TarHeader.LF_DIR;
				header.Size = 0;
			} else {
				header.Mode = 438; // 0666
				header.TypeFlag = TarHeader.LF_NORMAL;
				memory = new MemoryStream ();
				((FileObject) fso).AddToStream (memory, tracker);
				header.Size = memory.Length;
			}

			TarEntry entry;
			entry = new TarEntry (header);

			tar_out.PutNextEntry (entry);
			if (memory != null) {
				tar_out.Write (memory.ToArray (), 0, (int) memory.Length);
				memory.Close ();
			}
			tar_out.CloseEntry ();

			// If this is a directory, write out the children
			if (fso is DirectoryObject)
				foreach (FileSystemObject child in fso.Children)
					WriteObjectToTar (tar_out, child, tracker);
		}
Example #3
0
		/// <summary>
		/// Raises the ProgressMessage event
		/// </summary>
		/// <param name="entry">The <see cref="TarEntry">TarEntry</see> for this event</param>
		/// <param name="message">message for this event.  Null is no message</param>
		protected virtual void OnProgressMessageEvent(TarEntry entry, string message)
		{
		    ProgressMessageHandler handler = ProgressMessageEvent;
			if (handler != null) {
				handler(this, entry, message);
			}
		}
Example #4
0
        private void ExtractEntry(string destDir, TarEntry entry, ICSharpCode.SharpZipLib.Tar.TarInputStream stream) {
            string name = entry.Name;
            if (Path.IsPathRooted(name))
                name = name.Substring(Path.GetPathRoot(name).Length);
            name = name.Replace('/', Path.DirectorySeparatorChar);
            name = name.Substring(name.IndexOf(Path.DirectorySeparatorChar) + 1);

            string dest = Path.Combine(destDir, name);
            if (entry.IsDirectory)
                Directory.CreateDirectory(dest);
            else {
                Directory.CreateDirectory(Path.GetDirectoryName(dest));
                using (Stream outputStream = File.Create(dest)) {
                    stream.CopyEntryContents(outputStream);
                }
            }
        }
Example #5
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 (hasHitEOF)
            {
                return(null);
            }

            if (currentEntry != null)
            {
                SkipToNextEntry();
            }

            byte[] headerBuf = tarBuffer.ReadBlock();

            if (headerBuf == null)
            {
                hasHitEOF = true;
            }
            else if (TarBuffer.IsEndOfArchiveBlock(headerBuf))
            {
                hasHitEOF = true;
            }

            if (hasHitEOF)
            {
                currentEntry = null;
            }
            else
            {
                try {
                    TarHeader header = new TarHeader();
                    header.ParseBuffer(headerBuf);
                    if (!header.IsChecksumValid)
                    {
                        throw new TarException("Header checksum is invalid");
                    }
                    this.entryOffset = 0;
                    this.entrySize   = header.Size;

                    StringBuilder longName = null;

                    if (header.TypeFlag == TarHeader.LF_GNU_LONGNAME)
                    {
                        byte[] nameBuffer = new byte[TarBuffer.BlockSize];
                        long   numToRead  = this.entrySize;

                        longName = new StringBuilder();

                        while (numToRead > 0)
                        {
                            int numRead = this.Read(nameBuffer, 0, (numToRead > nameBuffer.Length ? nameBuffer.Length : (int)numToRead));

                            if (numRead == -1)
                            {
                                throw new InvalidHeaderException("Failed to read long name entry");
                            }

                            longName.Append(TarHeader.ParseName(nameBuffer, 0, numRead).ToString());
                            numToRead -= numRead;
                        }

                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    }
                    else if (header.TypeFlag == TarHeader.LF_GHDR)                          // POSIX global extended header
                    // Ignore things we dont understand completely for now
                    {
                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    }
                    else if (header.TypeFlag == TarHeader.LF_XHDR)                          // POSIX extended header
                    // Ignore things we dont understand completely for now
                    {
                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    }
                    else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR)
                    {
                        // TODO: could show volume name when verbose
                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    }
                    else if (header.TypeFlag != TarHeader.LF_NORMAL &&
                             header.TypeFlag != TarHeader.LF_OLDNORM &&
                             header.TypeFlag != TarHeader.LF_DIR)
                    {
                        // Ignore things we dont understand completely for now
                        SkipToNextEntry();
                        headerBuf = tarBuffer.ReadBlock();
                    }

                    if (entryFactory == null)
                    {
                        currentEntry = new TarEntry(headerBuf);
                        if (longName != null)
                        {
                            currentEntry.Name = longName.ToString();
                        }
                    }
                    else
                    {
                        currentEntry = entryFactory.CreateEntry(headerBuf);
                    }

                    // Magic was checked here for 'ustar' but there are multiple valid possibilities
                    // so this is not done anymore.

                    entryOffset = 0;

                    // TODO: Review How do we resolve this discrepancy?!
                    entrySize = this.currentEntry.Size;
                } catch (InvalidHeaderException ex) {
                    entrySize    = 0;
                    entryOffset  = 0;
                    currentEntry = null;
                    string errorText = string.Format("Bad header in record {0} block {1} {2}",
                                                     tarBuffer.CurrentRecord, tarBuffer.CurrentBlock, ex.Message);
                    throw new InvalidHeaderException(errorText);
                }
            }
            return(currentEntry);
        }
Example #6
0
        /// <summary>
        /// Write an entry to the archive. This method will call the putNextEntry
        /// and then write the contents of the entry, and finally call closeEntry()
        /// for entries that are files. For directories, it will call putNextEntry(),
        /// and then, if the recurse flag is true, process each entry that is a
        /// child of the directory.
        /// </summary>
        /// <param name="sourceEntry">
        /// The TarEntry representing the entry to write to the archive.
        /// </param>
        /// <param name="recurse">
        /// If true, process the children of directory entries.
        /// </param>
        void WriteEntryCore(TarEntry sourceEntry, bool recurse)
        {
            string tempFileName  = null;
            string entryFilename = sourceEntry.File;

            TarEntry entry = (TarEntry)sourceEntry.Clone();

            if (applyUserInfoOverrides)
            {
                entry.GroupId   = groupId;
                entry.GroupName = groupName;
                entry.UserId    = userId;
                entry.UserName  = userName;
            }

            OnProgressMessageEvent(entry, null);

            if (asciiTranslate && !entry.IsDirectory)
            {
                if (!IsBinary(entryFilename))
                {
                    tempFileName = Path.GetTempFileName();

                    using (StreamReader inStream = File.OpenText(entryFilename)) {
                        using (Stream outStream = File.Create(tempFileName)) {
                            while (true)
                            {
                                string line = inStream.ReadLine();
                                if (line == null)
                                {
                                    break;
                                }
                                byte[] data = Encoding.ASCII.GetBytes(line);
                                outStream.Write(data, 0, data.Length);
                                outStream.WriteByte((byte)'\n');
                            }

                            outStream.Flush();
                        }
                    }

                    entry.Size    = new FileInfo(tempFileName).Length;
                    entryFilename = tempFileName;
                }
            }

            string newName = null;

            if (rootPath != null)
            {
                if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
                {
                    newName = entry.Name.Substring(rootPath.Length + 1);
                }
            }

            if (pathPrefix != null)
            {
                newName = (newName == null) ? pathPrefix + "/" + entry.Name : pathPrefix + "/" + newName;
            }

            if (newName != null)
            {
                entry.Name = newName;
            }

            tarOut.PutNextEntry(entry);

            if (entry.IsDirectory)
            {
                if (recurse)
                {
                    TarEntry[] list = entry.GetDirectoryEntries();
                    for (int i = 0; i < list.Length; ++i)
                    {
                        WriteEntryCore(list[i], recurse);
                    }
                }
            }
            else
            {
                using (Stream inputStream = File.OpenRead(entryFilename)) {
                    byte[] localBuffer = new byte[32 * 1024];
                    while (true)
                    {
                        int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length);

                        if (numRead <= 0)
                        {
                            break;
                        }

                        tarOut.Write(localBuffer, 0, numRead);
                    }
                }

                if ((tempFileName != null) && (tempFileName.Length > 0))
                {
                    File.Delete(tempFileName);
                }

                tarOut.CloseEntry();
            }
        }
Example #7
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.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);
        }
Example #8
0
        private void ExtractEntry(string destDir, TarEntry entry)
        {
            this.OnProgressMessageEvent(entry, null);
            string name = entry.Name;

            if (Path.IsPathRooted(name))
            {
                name = name.Substring(Path.GetPathRoot(name).Length);
            }
            name = name.Replace('/', Path.DirectorySeparatorChar);
            string directoryName = Path.Combine(destDir, name);

            if (entry.IsDirectory)
            {
                EnsureDirectoryExists(directoryName);
            }
            else
            {
                EnsureDirectoryExists(Path.GetDirectoryName(directoryName));
                bool     flag = true;
                FileInfo info = new FileInfo(directoryName);
                if (info.Exists)
                {
                    if (this.keepOldFiles)
                    {
                        this.OnProgressMessageEvent(entry, "Destination file already exists");
                        flag = false;
                    }
                    else if ((info.Attributes & FileAttributes.ReadOnly) != 0)
                    {
                        this.OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
                        flag = false;
                    }
                }
                if (flag)
                {
                    bool   flag2  = false;
                    Stream stream = File.Create(directoryName);
                    if (this.asciiTranslate)
                    {
                        flag2 = !IsBinary(directoryName);
                    }
                    StreamWriter writer = null;
                    if (flag2)
                    {
                        writer = new StreamWriter(stream);
                    }
                    byte[] buffer = new byte[0x8000];
                    while (true)
                    {
                        int count = this.tarIn.Read(buffer, 0, buffer.Length);
                        if (count <= 0)
                        {
                            if (!flag2)
                            {
                                stream.Close();
                                break;
                            }
                            writer.Close();
                            return;
                        }
                        if (!flag2)
                        {
                            stream.Write(buffer, 0, count);
                            continue;
                        }
                        int index = 0;
                        for (int i = 0; i < count; i++)
                        {
                            if (buffer[i] == 10)
                            {
                                writer.WriteLine(Encoding.ASCII.GetString(buffer, index, i - index));
                                index = i + 1;
                            }
                        }
                    }
                }
            }
        }
Example #9
0
        /// <summary>
        /// Extract an entry from the archive. This method assumes that the
        /// tarIn stream has been properly set with a call to getNextEntry().
        /// </summary>
        /// <param name="destDir">
        /// The destination directory into which to extract.
        /// </param>
        /// <param name="entry">
        /// The TarEntry returned by tarIn.getNextEntry().
        /// </param>
        void ExtractEntry(string destDir, TarEntry entry)
        {
            if (this.verbose)
            {
                OnProgressMessageEvent(entry, null);
            }

            string name = entry.Name;

            name = name.Replace('/', Path.DirectorySeparatorChar);

            if (!destDir.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                destDir += Path.DirectorySeparatorChar;
            }

            string destFile = destDir + name;

            if (entry.IsDirectory)
            {
                EnsureDirectoryExists(destFile);
            }
            else
            {
                string parentDirectory = Path.GetDirectoryName(destFile);
                EnsureDirectoryExists(parentDirectory);

                if (this.keepOldFiles && File.Exists(destFile))
                {
                    if (this.verbose)
                    {
                        OnProgressMessageEvent(entry, "Destination file already exists");
                    }
                }
                else
                {
                    bool   asciiTrans   = false;
                    Stream outputStream = File.Create(destFile);
                    if (this.asciiTranslate)
                    {
                        asciiTrans = !IsBinary(destFile);
// original java sourcecode :
//						MimeType mime      = null;
//						string contentType = null;
//						try {
//							contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile );
//
//							mime = new MimeType(contentType);
//
//							if (mime.getPrimaryType().equalsIgnoreCase( "text" )) {
//							        asciiTrans = true;
//							} else if ( this.transTyper != null ) {
//							    if ( this.transTyper.isAsciiFile( entry.getName() ) ) {
//							        asciiTrans = true;
//							    }
//							}
//						} catch (MimeTypeParseException ex) {
//						}
//
//						if (this.debug) {
//							Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "'  ContentType='" + contentType + "'  PrimaryType='" + mime.getPrimaryType() + "'" );
//						}
                    }

                    StreamWriter outw = null;
                    if (asciiTrans)
                    {
                        outw = new StreamWriter(outputStream);
                    }

                    byte[] rdbuf = new byte[32 * 1024];

                    while (true)
                    {
                        int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length);

                        if (numRead <= 0)
                        {
                            break;
                        }

                        if (asciiTrans)
                        {
                            for (int off = 0, b = 0; b < numRead; ++b)
                            {
                                if (rdbuf[b] == 10)
                                {
                                    string s = Encoding.ASCII.GetString(rdbuf, off, (b - off));
                                    outw.WriteLine(s);
                                    off = b + 1;
                                }
                            }
                        }
                        else
                        {
                            outputStream.Write(rdbuf, 0, numRead);
                        }
                    }

                    if (asciiTrans)
                    {
                        outw.Close();
                    }
                    else
                    {
                        outputStream.Close();
                    }
                }
            }
        }
Example #10
0
        /// <summary>
        /// Extract an entry from the archive. This method assumes that the
        /// tarIn stream has been properly set with a call to GetNextEntry().
        /// </summary>
        /// <param name="destDir">
        /// The destination directory into which to extract.
        /// </param>
        /// <param name="entry">
        /// The TarEntry returned by tarIn.GetNextEntry().
        /// </param>
        /// <param name="allowParentTraversal">Allow parent directory traversal in file paths (e.g. ../file)</param>
        private void ExtractEntry(string destDir, TarEntry entry, bool allowParentTraversal)
        {
            OnProgressMessageEvent(entry, null);

            string name = entry.Name;

            if (Path.IsPathRooted(name))
            {
                // NOTE:
                // for UNC names...  \\machine\share\zoom\beet.txt gives \zoom\beet.txt
                name = name.Substring(Path.GetPathRoot(name).Length);
            }

            name = name.Replace('/', Path.DirectorySeparatorChar);

            string destFile = Path.Combine(destDir, name);

            if (!allowParentTraversal && !Path.GetFullPath(destFile).StartsWith(destDir, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new InvalidNameException("Parent traversal in paths is not allowed");
            }

            if (entry.IsDirectory)
            {
                EnsureDirectoryExists(destFile);
            }
            else
            {
                string parentDirectory = Path.GetDirectoryName(destFile);
                EnsureDirectoryExists(parentDirectory);

                bool process  = true;
                var  fileInfo = new FileInfo(destFile);
                if (fileInfo.Exists)
                {
                    if (keepOldFiles)
                    {
                        OnProgressMessageEvent(entry, "Destination file already exists");
                        process = false;
                    }
                    else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0)
                    {
                        OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
                        process = false;
                    }
                }

                if (process)
                {
                    using (var outputStream = File.Create(destFile))
                    {
                        if (this.asciiTranslate)
                        {
                            // May need to translate the file.
                            ExtractAndTranslateEntry(destFile, outputStream);
                        }
                        else
                        {
                            // If translation is disabled, just copy the entry across directly.
                            tarIn.CopyEntryContents(outputStream);
                        }
                    }
                }
            }
        }
Example #11
0
        private void WriteEntryCore(TarEntry sourceEntry, bool recurse)
        {
            //IL_00de: Unknown result type (might be due to invalid IL or missing references)
            string   text     = null;
            string   text2    = sourceEntry.File;
            TarEntry tarEntry = (TarEntry)sourceEntry.Clone();

            if (applyUserInfoOverrides)
            {
                tarEntry.GroupId   = groupId;
                tarEntry.GroupName = groupName;
                tarEntry.UserId    = userId;
                tarEntry.UserName  = userName;
            }
            OnProgressMessageEvent(tarEntry, null);
            if (asciiTranslate && !tarEntry.IsDirectory && !IsBinary(text2))
            {
                text = Path.GetTempFileName();
                StreamReader val = File.OpenText(text2);
                try
                {
                    Stream val2 = (Stream)(object)File.Create(text);
                    try
                    {
                        while (true)
                        {
                            string text3 = ((TextReader)val).ReadLine();
                            if (text3 == null)
                            {
                                break;
                            }
                            byte[] bytes = Encoding.get_ASCII().GetBytes(text3);
                            val2.Write(bytes, 0, bytes.Length);
                            val2.WriteByte((byte)10);
                        }
                        val2.Flush();
                    }
                    finally
                    {
                        ((global::System.IDisposable)val2)?.Dispose();
                    }
                }
                finally
                {
                    ((global::System.IDisposable)val)?.Dispose();
                }
                tarEntry.Size = new FileInfo(text).get_Length();
                text2         = text;
            }
            string text4 = null;

            if (rootPath != null && tarEntry.Name.StartsWith(rootPath))
            {
                text4 = tarEntry.Name.Substring(rootPath.get_Length() + 1);
            }
            if (pathPrefix != null)
            {
                text4 = ((text4 == null) ? (pathPrefix + "/" + tarEntry.Name) : (pathPrefix + "/" + text4));
            }
            if (text4 != null)
            {
                tarEntry.Name = text4;
            }
            tarOut.PutNextEntry(tarEntry);
            if (tarEntry.IsDirectory)
            {
                if (recurse)
                {
                    TarEntry[] directoryEntries = tarEntry.GetDirectoryEntries();
                    for (int i = 0; i < directoryEntries.Length; i++)
                    {
                        WriteEntryCore(directoryEntries[i], recurse);
                    }
                }
                return;
            }
            Stream val3 = (Stream)(object)File.OpenRead(text2);

            try
            {
                byte[] array = new byte[32768];
                while (true)
                {
                    int num = val3.Read(array, 0, array.Length);
                    if (num > 0)
                    {
                        ((Stream)tarOut).Write(array, 0, num);
                        continue;
                    }
                    break;
                }
            }
            finally
            {
                ((global::System.IDisposable)val3)?.Dispose();
            }
            if (text != null && text.get_Length() > 0)
            {
                File.Delete(text);
            }
            tarOut.CloseEntry();
        }
Example #12
0
        private void ExtractEntry(string destDir, TarEntry entry)
        {
            //IL_005e: Unknown result type (might be due to invalid IL or missing references)
            //IL_0065: Expected O, but got Unknown
            //IL_0088: Unknown result type (might be due to invalid IL or missing references)
            //IL_008e: Unknown result type (might be due to invalid IL or missing references)
            //IL_00cc: Unknown result type (might be due to invalid IL or missing references)
            //IL_00d3: Expected O, but got Unknown
            OnProgressMessageEvent(entry, null);
            string text = entry.Name;

            if (Path.IsPathRooted(text))
            {
                text = text.Substring(Path.GetPathRoot(text).get_Length());
            }
            text = text.Replace('/', Path.DirectorySeparatorChar);
            string text2 = Path.Combine(destDir, text);

            if (entry.IsDirectory)
            {
                EnsureDirectoryExists(text2);
                return;
            }
            string directoryName = Path.GetDirectoryName(text2);

            EnsureDirectoryExists(directoryName);
            bool     flag = true;
            FileInfo val  = new FileInfo(text2);

            if (((FileSystemInfo)val).get_Exists())
            {
                if (keepOldFiles)
                {
                    OnProgressMessageEvent(entry, "Destination file already exists");
                    flag = false;
                }
                else if ((((FileSystemInfo)val).get_Attributes() & 1) != 0)
                {
                    OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
                    flag = false;
                }
            }
            if (!flag)
            {
                return;
            }
            bool   flag2 = false;
            Stream val2  = (Stream)(object)File.Create(text2);

            if (asciiTranslate)
            {
                flag2 = !IsBinary(text2);
            }
            StreamWriter val3 = null;

            if (flag2)
            {
                val3 = new StreamWriter(val2);
            }
            byte[] array = new byte[32768];
            while (true)
            {
                int num = ((Stream)tarIn).Read(array, 0, array.Length);
                if (num <= 0)
                {
                    break;
                }
                if (flag2)
                {
                    int num2 = 0;
                    for (int i = 0; i < num; i++)
                    {
                        if (array[i] == 10)
                        {
                            string @string = Encoding.get_ASCII().GetString(array, num2, i - num2);
                            ((TextWriter)val3).WriteLine(@string);
                            num2 = i + 1;
                        }
                    }
                }
                else
                {
                    val2.Write(array, 0, num);
                }
            }
            if (flag2)
            {
                ((TextWriter)val3).Close();
            }
            else
            {
                val2.Close();
            }
        }
Example #13
0
 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);
 }
Example #14
0
 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);
 }
Example #15
0
        private void WriteEntryCore(TarEntry sourceEntry, bool recurse)
        {
            string   text     = null;
            string   text2    = sourceEntry.File;
            TarEntry tarEntry = (TarEntry)sourceEntry.Clone();

            if (this.applyUserInfoOverrides)
            {
                tarEntry.GroupId   = this.groupId;
                tarEntry.GroupName = this.groupName;
                tarEntry.UserId    = this.userId;
                tarEntry.UserName  = this.userName;
            }
            this.OnProgressMessageEvent(tarEntry, null);
            if (this.asciiTranslate && !tarEntry.IsDirectory)
            {
                bool flag = !TarArchive.IsBinary(text2);
                if (flag)
                {
                    text = Path.GetTempFileName();
                    using (StreamReader streamReader = File.OpenText(text2))
                    {
                        using (Stream stream = File.Create(text))
                        {
                            for (;;)
                            {
                                string text3 = streamReader.ReadLine();
                                if (text3 == null)
                                {
                                    break;
                                }
                                byte[] bytes = Encoding.ASCII.GetBytes(text3);
                                stream.Write(bytes, 0, bytes.Length);
                                stream.WriteByte(10);
                            }
                            stream.Flush();
                        }
                    }
                    tarEntry.Size = new FileInfo(text).Length;
                    text2         = text;
                }
            }
            string text4 = null;

            if (this.rootPath != null && tarEntry.Name.StartsWith(this.rootPath))
            {
                text4 = tarEntry.Name.Substring(this.rootPath.Length + 1);
            }
            if (this.pathPrefix != null)
            {
                text4 = ((text4 == null) ? (this.pathPrefix + "/" + tarEntry.Name) : (this.pathPrefix + "/" + text4));
            }
            if (text4 != null)
            {
                tarEntry.Name = text4;
            }
            this.tarOut.PutNextEntry(tarEntry);
            if (tarEntry.IsDirectory)
            {
                if (recurse)
                {
                    TarEntry[] directoryEntries = tarEntry.GetDirectoryEntries();
                    for (int i = 0; i < directoryEntries.Length; i++)
                    {
                        this.WriteEntryCore(directoryEntries[i], recurse);
                    }
                    return;
                }
            }
            else
            {
                using (Stream stream2 = File.OpenRead(text2))
                {
                    int    num   = 0;
                    byte[] array = new byte[32768];
                    for (;;)
                    {
                        int num2 = stream2.Read(array, 0, array.Length);
                        if (num2 <= 0)
                        {
                            break;
                        }
                        this.tarOut.Write(array, 0, num2);
                        num += num2;
                    }
                }
                if (text != null && text.Length > 0)
                {
                    File.Delete(text);
                }
                this.tarOut.CloseEntry();
            }
        }
Example #16
0
        /// <summary>
        /// Extract an entry from the archive. This method assumes that the
        /// tarIn stream has been properly set with a call to getNextEntry().
        /// </summary>
        /// <param name="destDir">
        /// The destination directory into which to extract.
        /// </param>
        /// <param name="entry">
        /// The TarEntry returned by tarIn.getNextEntry().
        /// </param>
        void ExtractEntry(string destDir, TarEntry entry)
        {
            if (this.verbose)
            {
                OnProgressMessageEvent(entry, null);
            }

            string name = entry.Name;

            if (Path.IsPathRooted(name) == true)
            {
                // NOTE:
                // for UNC names...  \\machine\share\zoom\beet.txt gives \zoom\beet.txt
                name = name.Substring(Path.GetPathRoot(name).Length);
            }

            name = name.Replace('/', Path.DirectorySeparatorChar);

            string destFile = Path.Combine(destDir, name);

            if (entry.IsDirectory)
            {
                EnsureDirectoryExists(destFile);
            }
            else
            {
                string parentDirectory = Path.GetDirectoryName(destFile);
                EnsureDirectoryExists(parentDirectory);

                bool     process  = true;
                FileInfo fileInfo = new FileInfo(destFile);
                if (fileInfo.Exists)
                {
                    if (this.keepOldFiles)
                    {
                        OnProgressMessageEvent(entry, "Destination file already exists");
                        process = false;
                    }
                    else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0)
                    {
                        OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
                        process = false;
                    }
                }

                if (process)
                {
                    bool asciiTrans = false;
                    // TODO file may exist and be read-only at this point!
                    Stream outputStream = File.Create(destFile);
                    if (this.asciiTranslate)
                    {
                        asciiTrans = !IsBinary(destFile);
// TODO  do we need this stuff below?
// original java sourcecode :
//						MimeType mime      = null;
//						string contentType = null;
//						try {
//							contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile );
//
//							mime = new MimeType(contentType);
//
//							if (mime.getPrimaryType().equalsIgnoreCase( "text" )) {
//								asciiTrans = true;
//							} else if ( this.transTyper != null ) {
//								if ( this.transTyper.isAsciiFile( entry.getName() ) ) {
//									asciiTrans = true;
//								}
//							}
//						} catch (MimeTypeParseException ex) {
//						}
//
//						if (this.debug) {
//							Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "'  ContentType='" + contentType + "'  PrimaryType='" + mime.getPrimaryType() + "'" );
//						}
                    }

                    StreamWriter outw = null;
                    if (asciiTrans)
                    {
                        outw = new StreamWriter(outputStream);
                    }

                    byte[] rdbuf = new byte[32 * 1024];

                    while (true)
                    {
                        int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length);

                        if (numRead <= 0)
                        {
                            break;
                        }

                        if (asciiTrans)
                        {
                            for (int off = 0, b = 0; b < numRead; ++b)
                            {
                                if (rdbuf[b] == 10)
                                {
                                    string s = Encoding.ASCII.GetString(rdbuf, off, (b - off));
                                    outw.WriteLine(s);
                                    off = b + 1;
                                }
                            }
                        }
                        else
                        {
                            outputStream.Write(rdbuf, 0, numRead);
                        }
                    }

                    if (asciiTrans)
                    {
                        outw.Close();
                    }
                    else
                    {
                        outputStream.Close();
                    }
                }
            }
        }
Example #17
0
 /// <summary>
 /// Determine if the given entry is a descendant of this entry.
 /// Descendancy is determined by the name of the descendant
 /// starting with this entry's name.
 /// </summary>
 /// <param name = "toTest">
 /// Entry to be checked as a descendent of this.
 /// </param>
 /// <returns>
 /// True if entry is a descendant of this.
 /// </returns>
 public bool IsDescendent(TarEntry toTest)
 {
     return(toTest == null ? throw new ArgumentNullException(nameof(toTest)) : toTest.Name.StartsWith(Name, StringComparison.Ordinal));
 }
        /// <summary>
        /// Write an entry to the archive. This method will call the putNextEntry
        /// and then write the contents of the entry, and finally call closeEntry()
        /// for entries that are files. For directories, it will call putNextEntry(),
        /// and then, if the recurse flag is true, process each entry that is a
        /// child of the directory.
        /// </summary>
        /// <param name="sourceEntry">
        /// The TarEntry representing the entry to write to the archive.
        /// </param>
        /// <param name="recurse">
        /// If true, process the children of directory entries.
        /// </param>
        void InternalWriteEntry(TarEntry sourceEntry, bool recurse)
        {
            bool asciiTrans = false;

            string tempFileName  = null;
            string entryFilename = sourceEntry.File;

            TarEntry entry = (TarEntry)sourceEntry.Clone();

            if (applyUserInfoOverrides)
            {
                entry.GroupId   = groupId;
                entry.GroupName = groupName;
                entry.UserId    = userId;
                entry.UserName  = userName;
            }

            OnProgressMessageEvent(entry, null);

            if (this.asciiTranslate && !entry.IsDirectory)
            {
                asciiTrans = !IsBinary(entryFilename);

                if (asciiTrans)
                {
                    tempFileName = Path.GetTempFileName();

                    StreamReader inStream  = File.OpenText(entryFilename);
                    Stream       outStream = File.Create(tempFileName);

                    while (true)
                    {
                        string line = inStream.ReadLine();
                        if (line == null)
                        {
                            break;
                        }
                        byte[] data = Encoding.ASCII.GetBytes(line);
                        outStream.Write(data, 0, data.Length);
                        outStream.WriteByte((byte)'\n');
                    }

                    inStream.Close();

                    outStream.Flush();
                    outStream.Close();

                    entry.Size = new FileInfo(tempFileName).Length;

                    entryFilename = tempFileName;
                }
            }

            string newName = null;

            if (this.rootPath != null)
            {
                if (entry.Name.StartsWith(this.rootPath))
                {
                    newName = entry.Name.Substring(this.rootPath.Length + 1);
                }
            }

            if (this.pathPrefix != null)
            {
                newName = (newName == null) ? this.pathPrefix + "/" + entry.Name : this.pathPrefix + "/" + newName;
            }

            if (newName != null)
            {
                entry.Name = newName;
            }

            this.tarOut.PutNextEntry(entry);

            if (entry.IsDirectory)
            {
                if (recurse)
                {
                    TarEntry[] list = entry.GetDirectoryEntries();
                    for (int i = 0; i < list.Length; ++i)
                    {
                        InternalWriteEntry(list[i], recurse);
                    }
                }
            }
            else
            {
                Stream inputStream = File.OpenRead(entryFilename);
                int    numWritten  = 0;
                byte[] eBuf        = new byte[32 * 1024];
                while (true)
                {
                    int numRead = inputStream.Read(eBuf, 0, eBuf.Length);

                    if (numRead <= 0)
                    {
                        break;
                    }

                    this.tarOut.Write(eBuf, 0, numRead);
                    numWritten += numRead;
                }

                inputStream.Close();

                if (tempFileName != null && tempFileName.Length > 0)
                {
                    File.Delete(tempFileName);
                }

                this.tarOut.CloseEntry();
            }
        }
Example #19
0
 public bool IsDescendent(TarEntry toTest) =>
 toTest?.Name.StartsWith(this.Name);
Example #20
0
        /// <summary>
        /// Write an entry to the archive. This method will call the putNextEntry
        /// and then write the contents of the entry, and finally call closeEntry()()
        /// for entries that are files. For directories, it will call putNextEntry(),
        /// and then, if the recurse flag is true, process each entry that is a
        /// child of the directory.
        /// </summary>
        /// <param name="entry">
        /// The TarEntry representing the entry to write to the archive.
        /// </param>
        /// <param name="recurse">
        /// If true, process the children of directory entries.
        /// </param>
        public void WriteEntry(TarEntry entry, bool recurse)
        {
            bool asciiTrans = false;

            string tempFileName = null;
            string eFile        = entry.File;

            // Work on a copy of the entry so we can manipulate it.
            // Note that we must distinguish how the entry was constructed.
            //
            if (eFile == null || eFile.Length == 0)
            {
                entry = TarEntry.CreateTarEntry(entry.Name);
            }
            else
            {
                //
                // The user may have explicitly set the entry's name to
                // something other than the file's path, so we must save
                // and restore it. This should work even when the name
                // was set from the File's name.
                //
                string saveName = entry.Name;
                entry      = TarEntry.CreateEntryFromFile(eFile);
                entry.Name = saveName;
            }

            if (this.verbose)
            {
                OnProgressMessageEvent(entry, null);
            }

            if (this.asciiTranslate && !entry.IsDirectory)
            {
                asciiTrans = !IsBinary(eFile);

// original java source :
//			        MimeType mime = null;
//			        string contentType = null;
//
//			        try {
//			            contentType = FileTypeMap.getDefaultFileTypeMap(). getContentType( eFile );
//
//			            mime = new MimeType( contentType );
//
//			            if ( mime.getPrimaryType().
//			                equalsIgnoreCase( "text" ) )
//			                {
//			                    asciiTrans = true;
//			                }
//			                else if ( this.transTyper != null )
//			                {
//			                    if ( this.transTyper.isAsciiFile( eFile ) )
//			                    {
//			                        asciiTrans = true;
//			                    }
//			                }
//			        } catch ( MimeTypeParseException ex )
//			        {
//	//		             IGNORE THIS ERROR...
//			        }
//
//		        if (this.debug) {
//		            Console.Error.WriteLine("CREATE TRANS? '" + asciiTrans + "'  ContentType='" + contentType + "'  PrimaryType='" + mime.getPrimaryType()+ "'" );
//		        }

                if (asciiTrans)
                {
                    tempFileName = Path.GetTempFileName();

                    StreamReader inStream  = File.OpenText(eFile);
                    Stream       outStream = new BufferedStream(File.Create(tempFileName));

                    while (true)
                    {
                        string line = inStream.ReadLine();
                        if (line == null)
                        {
                            break;
                        }
                        byte[] data = Encoding.ASCII.GetBytes(line);
                        outStream.Write(data, 0, data.Length);
                        outStream.WriteByte((byte)'\n');
                    }

                    inStream.Close();

                    outStream.Flush();
                    outStream.Close();

                    entry.Size = new FileInfo(tempFileName).Length;

                    eFile = tempFileName;
                }
            }

            string newName = null;

            if (this.rootPath != null)
            {
                if (entry.Name.StartsWith(this.rootPath))
                {
                    newName = entry.Name.Substring(this.rootPath.Length + 1);
                }
            }

            if (this.pathPrefix != null)
            {
                newName = (newName == null) ? this.pathPrefix + "/" + entry.Name : this.pathPrefix + "/" + newName;
            }

            if (newName != null)
            {
                entry.Name = newName;
            }

            this.tarOut.PutNextEntry(entry);

            if (entry.IsDirectory)
            {
                if (recurse)
                {
                    TarEntry[] list = entry.GetDirectoryEntries();
                    for (int i = 0; i < list.Length; ++i)
                    {
                        this.WriteEntry(list[i], recurse);
                    }
                }
            }
            else
            {
                Stream inputStream = File.OpenRead(eFile);
                int    numWritten  = 0;
                byte[] eBuf        = new byte[32 * 1024];
                while (true)
                {
                    int numRead = inputStream.Read(eBuf, 0, eBuf.Length);

                    if (numRead <= 0)
                    {
                        break;
                    }

                    this.tarOut.Write(eBuf, 0, numRead);
                    numWritten += numRead;
                }

//				Console.WriteLine("written " + numWritten + " bytes");

                inputStream.Close();

                if (tempFileName != null && tempFileName.Length > 0)
                {
                    File.Delete(tempFileName);
                }

                this.tarOut.CloseEntry();
            }
        }
Example #21
0
 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);
 }
Example #22
0
        private void WriteEntryCore(TarEntry sourceEntry, bool recurse)
        {
            string   path = null;
            string   str3;
            string   file  = sourceEntry.File;
            TarEntry entry = (TarEntry)sourceEntry.Clone();

            if (this.applyUserInfoOverrides)
            {
                entry.GroupId   = this.groupId;
                entry.GroupName = this.groupName;
                entry.UserId    = this.userId;
                entry.UserName  = this.userName;
            }
            this.OnProgressMessageEvent(entry, null);
            if (this.asciiTranslate && (!entry.IsDirectory && !IsBinary(file)))
            {
                path = Path.GetTempFileName();
                using (StreamReader reader = File.OpenText(file))
                {
                    Stream stream = File.Create(path);
                    while (true)
                    {
                        try
                        {
                            while (true)
                            {
                                string s = reader.ReadLine();
                                if (s == null)
                                {
                                    stream.Flush();
                                    entry.Size = new FileInfo(path).Length;
                                    file       = path;
                                    goto TR_0022;
                                }
                                else
                                {
                                    byte[] bytes = Encoding.ASCII.GetBytes(s);
                                    stream.Write(bytes, 0, bytes.Length);
                                    stream.WriteByte(10);
                                }
                                break;
                            }
                        }
                        finally
                        {
                            if (stream != null)
                            {
                                stream.Dispose();
                            }
                        }
                    }
                }
            }
TR_0022:
            str3 = null;
            if ((this.rootPath != null) && entry.Name.StartsWith(this.rootPath, StringComparison.OrdinalIgnoreCase))
            {
                str3 = entry.Name.Substring(this.rootPath.Length + 1);
            }
            if (this.pathPrefix != null)
            {
                str3 = (str3 == null) ? (this.pathPrefix + "/" + entry.Name) : (this.pathPrefix + "/" + str3);
            }
            if (str3 != null)
            {
                entry.Name = str3;
            }
            this.tarOut.PutNextEntry(entry);
            if (entry.IsDirectory)
            {
                if (recurse)
                {
                    TarEntry[] directoryEntries = entry.GetDirectoryEntries();
                    for (int i = 0; i < directoryEntries.Length; i++)
                    {
                        this.WriteEntryCore(directoryEntries[i], recurse);
                    }
                }
            }
            else
            {
                using (Stream stream2 = File.OpenRead(file))
                {
                    byte[] buffer = new byte[0x8000];
                    while (true)
                    {
                        int count = stream2.Read(buffer, 0, buffer.Length);
                        if (count <= 0)
                        {
                            break;
                        }
                        this.tarOut.Write(buffer, 0, count);
                    }
                }
                if ((path != null) && (path.Length > 0))
                {
                    File.Delete(path);
                }
                this.tarOut.CloseEntry();
            }
        }
Example #23
0
 /// <summary>
 /// Determine if the given entry is a descendant of this entry.
 /// Descendancy is determined by the name of the descendant
 /// starting with this entry's name.
 /// </summary>
 /// <param name = "desc">
 /// Entry to be checked as a descendent of this.
 /// </param>
 /// <returns>
 /// True if entry is a descendant of this.
 /// </returns>
 public bool IsDescendent(TarEntry desc)
 {
     return(desc.header.name.ToString().StartsWith(this.header.name.ToString()));
 }
Example #24
0
        /// <summary>
        /// Extract an entry from the archive. This method assumes that the
        /// tarIn stream has been properly set with a call to GetNextEntry().
        /// </summary>
        /// <param name="destDir">
        /// The destination directory into which to extract.
        /// </param>
        /// <param name="entry">
        /// The TarEntry returned by tarIn.GetNextEntry().
        /// </param>
        void ExtractEntry(string destDir, TarEntry entry)
        {
            OnProgressMessageEvent(entry, null);

            string name = entry.Name;

            if (Path.IsPathRooted(name))
            {
                // NOTE:
                // for UNC names...  \\machine\share\zoom\beet.txt gives \zoom\beet.txt
                name = name.Substring(Path.GetPathRoot(name).Length);
            }

            name = name.Replace('/', Path.DirectorySeparatorChar);

            string destFile = Path.Combine(destDir, name);

            if (entry.IsDirectory)
            {
                EnsureDirectoryExists(destFile);
            }
            else
            {
                string parentDirectory = Path.GetDirectoryName(destFile);
                EnsureDirectoryExists(parentDirectory);

                bool     process  = true;
                FileInfo fileInfo = new FileInfo(destFile);
                if (fileInfo.Exists)
                {
                    if (keepOldFiles)
                    {
                        OnProgressMessageEvent(entry, "Destination file already exists");
                        process = false;
                    }
                    else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0)
                    {
                        OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
                        process = false;
                    }
                }

                if (process)
                {
                    bool asciiTrans = false;

                    Stream outputStream = File.Create(destFile);
                    if (this.asciiTranslate)
                    {
                        asciiTrans = !IsBinary(destFile);
                    }

                    StreamWriter outw = null;
                    if (asciiTrans)
                    {
                        outw = new StreamWriter(outputStream);
                    }

                    byte[] rdbuf = new byte[32 * 1024];

                    while (true)
                    {
                        int numRead = tarIn.Read(rdbuf, 0, rdbuf.Length);

                        if (numRead <= 0)
                        {
                            break;
                        }

                        if (asciiTrans)
                        {
                            for (int off = 0, b = 0; b < numRead; ++b)
                            {
                                if (rdbuf[b] == 10)
                                {
                                    string s = Encoding.ASCII.GetString(rdbuf, off, (b - off));
                                    outw.WriteLine(s);
                                    off = b + 1;
                                }
                            }
                        }
                        else
                        {
                            outputStream.Write(rdbuf, 0, numRead);
                        }
                    }

                    if (asciiTrans)
                    {
                        outw.Close();
                    }
                    else
                    {
                        outputStream.Close();
                    }
                }
            }
        }
Example #25
0
        public override bool Equals(object obj)
        {
            TarEntry entry = obj as TarEntry;

            return((entry != null) && this.Name.Equals(entry.Name));
        }
Example #26
0
 /// <summary>
 /// Create a tar entry with details obtained from <paramref name="fileName">file</paramref>
 /// </summary>
 /// <param name="fileName">The name of the file to retrieve details from.</param>
 /// <returns>A new <see cref="TarEntry"/></returns>
 public TarEntry CreateEntryFromFile(string fileName)
 {
     return(TarEntry.CreateEntryFromFile(fileName));
 }
Example #27
0
 /// <summary>
 /// Determine if the given entry is a descendant of this entry.
 /// Descendancy is determined by the name of the descendant
 /// starting with this entry's name.
 /// </summary>
 /// <param name = "desc">
 /// Entry to be checked as a descendent of this.
 /// </param>
 /// <returns>
 /// True if entry is a descendant of this.
 /// </returns>
 public bool IsDescendent(TarEntry desc)
 {
     return(desc.Name.StartsWith(Name));
 }
Example #28
0
        private void ExtractEntry(string destDir, TarEntry entry)
        {
            this.OnProgressMessageEvent(entry, null);
            string text = entry.Name;

            if (Path.IsPathRooted(text))
            {
                text = text.Substring(Path.GetPathRoot(text).Length);
            }
            text = text.Replace('/', Path.DirectorySeparatorChar);
            string text2 = Path.Combine(destDir, text);

            if (entry.IsDirectory)
            {
                TarArchive.EnsureDirectoryExists(text2);
                return;
            }
            string directoryName = Path.GetDirectoryName(text2);

            TarArchive.EnsureDirectoryExists(directoryName);
            bool     flag     = true;
            FileInfo fileInfo = new FileInfo(text2);

            if (fileInfo.Exists)
            {
                if (this.keepOldFiles)
                {
                    this.OnProgressMessageEvent(entry, "Destination file already exists");
                    flag = false;
                }
                else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != (FileAttributes)0)
                {
                    this.OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
                    flag = false;
                }
            }
            if (flag)
            {
                bool   flag2  = false;
                Stream stream = File.Create(text2);
                if (this.asciiTranslate)
                {
                    flag2 = !TarArchive.IsBinary(text2);
                }
                StreamWriter streamWriter = null;
                if (flag2)
                {
                    streamWriter = new StreamWriter(stream);
                }
                byte[] array = new byte[32768];
                for (;;)
                {
                    int num = this.tarIn.Read(array, 0, array.Length);
                    if (num <= 0)
                    {
                        break;
                    }
                    if (flag2)
                    {
                        int num2 = 0;
                        for (int i = 0; i < num; i++)
                        {
                            if (array[i] == 10)
                            {
                                string @string = Encoding.ASCII.GetString(array, num2, i - num2);
                                streamWriter.WriteLine(@string);
                                num2 = i + 1;
                            }
                        }
                    }
                    else
                    {
                        stream.Write(array, 0, num);
                    }
                }
                if (flag2)
                {
                    streamWriter.Close();
                    return;
                }
                stream.Close();
            }
        }
Example #29
0
 /// <summary>
 /// Raises the ProgressMessage event
 /// </summary>
 /// <param name="entry">The <see cref="TarEntry">TarEntry</see> for this event</param>
 /// <param name="message">message for this event.  Null is no message</param>
 protected virtual void OnProgressMessageEvent(TarEntry entry, string message)
 {
     ProgressMessageEvent?.Invoke(this, entry, message);
 }
Example #30
0
		/// <summary>
		/// Determine if the given entry is a descendant of this entry.
		/// Descendancy is determined by the name of the descendant
		/// starting with this entry's name.
		/// </summary>
		/// <param name = "toTest">
		/// Entry to be checked as a descendent of this.
		/// </param>
		/// <returns>
		/// True if entry is a descendant of this.
		/// </returns>
		public bool IsDescendent(TarEntry toTest)
		{
			if ( toTest == null ) {
				throw new ArgumentNullException("toTest");
			}

			return toTest.Name.StartsWith(Name);
		}
Example #31
0
 protected override void PostCreate(TarEntry entry)
 {
     if (entry.Size > 0)
     {
         tfs.tis.Read(data = new byte[entry.Size], 0, (int)entry.Size);
     }
     else
         data = new byte[0];
 }
Example #32
0
            public static TarFileSystemInfo FromEntry(TarFileSystem tfs, TarEntry entry)
            {
                TarFileSystemInfo fsi;

                if (entry.IsDirectory)
                    fsi = new TarDirectoryInfo();
                else
                    fsi = new TarFileInfo();

                fsi.tfs = tfs;
                fsi.CreationTime = entry.ModTime;
                fsi.Exists = true;
                fsi.FullName = entry.Name;
                fsi.LastAccessTime = entry.ModTime;
                fsi.LastWriteTime = entry.ModTime;
                fsi.Name = entry.Name.PostLastCharacter('/');
                fsi.Extension = entry.IsDirectory ? string.Empty : fsi.Name.PostFirstCharacter('.', string.Empty);
                fsi.PostCreate(entry);

                return fsi;
            }
Example #33
0
 protected override void PostCreate(TarEntry entry)
 {
 }
Example #34
0
        /// <summary>
        /// Determine if the given entry is a descendant of this entry.
        /// Descendancy is determined by the name of the descendant
        /// starting with this entry's name.
        /// </summary>
        /// <param name = "toTest">
        /// Entry to be checked as a descendent of this.
        /// </param>
        /// <returns>
        /// True if entry is a descendant of this.
        /// </returns>
        public bool IsDescendent(TarEntry toTest)
        {
            if (toTest == null) {
                throw new ArgumentNullException("toTest");
            }

            return toTest.Name.StartsWith(Name, StringComparison.Ordinal);
        }
Example #35
0
 /// <summary>
 /// Create a <see cref="TarEntry"/> based on named
 /// </summary>
 /// <param name="name">The name to use for the entry</param>
 /// <returns>A new <see cref="TarEntry"/></returns>
 public TarEntry CreateEntry(string name)
 {
     return(TarEntry.CreateTarEntry(name));
 }
Example #36
0
		/// <summary>
		/// Write an entry to the archive. This method will call the putNextEntry
		/// and then write the contents of the entry, and finally call closeEntry()
		/// for entries that are files. For directories, it will call putNextEntry(),
		/// and then, if the recurse flag is true, process each entry that is a
		/// child of the directory.
		/// </summary>
		/// <param name="sourceEntry">
		/// The TarEntry representing the entry to write to the archive.
		/// </param>
		/// <param name="recurse">
		/// If true, process the children of directory entries.
		/// </param>
		public void WriteEntry(TarEntry sourceEntry, bool recurse)
		{
			if ( sourceEntry == null ) {
				throw new ArgumentNullException("sourceEntry");
			}
			
			if ( isDisposed ) {
				throw new ObjectDisposedException("TarArchive");
			}
			
			try
			{
				if ( recurse ) {
					TarHeader.SetValueDefaults(sourceEntry.UserId, sourceEntry.UserName,
											   sourceEntry.GroupId, sourceEntry.GroupName);
				}
				WriteEntryCore(sourceEntry, recurse);
			}
			finally
			{
				if ( recurse ) {
					TarHeader.RestoreSetValues();
				}
			}
		}
Example #37
0
		/// <summary>
		/// Raises the ProgressMessage event
		/// </summary>
		/// <param name="entry">TarEntry for this event</param>
		/// <param name="message">message for this event.  Null is no message</param>
		protected virtual void OnProgressMessageEvent(TarEntry entry, string message)
		{
			if (ProgressMessageEvent != null) {
				ProgressMessageEvent(this, entry, message);
			}
		}
Example #38
0
		/// <summary>
		/// Extract an entry from the archive. This method assumes that the
		/// tarIn stream has been properly set with a call to GetNextEntry().
		/// </summary>
		/// <param name="destDir">
		/// The destination directory into which to extract.
		/// </param>
		/// <param name="entry">
		/// The TarEntry returned by tarIn.GetNextEntry().
		/// </param>
		void ExtractEntry(string destDir, TarEntry entry)
		{
			OnProgressMessageEvent(entry, null);
			
			string name = entry.Name;
			
			if (Path.IsPathRooted(name)) {
				// NOTE:
				// for UNC names...  \\machine\share\zoom\beet.txt gives \zoom\beet.txt
				name = name.Substring(Path.GetPathRoot(name).Length);
			}
			
			name = name.Replace('/', Path.DirectorySeparatorChar);
			
			string destFile = Path.Combine(destDir, name);
			
			if (entry.IsDirectory) {
				EnsureDirectoryExists(destFile);
			} else {
				string parentDirectory = Path.GetDirectoryName(destFile);
				EnsureDirectoryExists(parentDirectory);
				
				bool process = true;
				FileInfo fileInfo = new FileInfo(destFile);
				if (fileInfo.Exists) {
					if (keepOldFiles) {
						OnProgressMessageEvent(entry, "Destination file already exists");
						process = false;
					} else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) {
						OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
						process = false;
					}
				}
				
				if (process) {
					bool asciiTrans = false;
					
					Stream outputStream = File.Create(destFile);
					if (this.asciiTranslate) {
						asciiTrans = !IsBinary(destFile);
					}
					
					StreamWriter outw = null;
					if (asciiTrans) {
						outw = new StreamWriter(outputStream);
					}
					
					byte[] rdbuf = new byte[32 * 1024];
					
					while (true) {
						int numRead = tarIn.Read(rdbuf, 0, rdbuf.Length);
						
						if (numRead <= 0) {
							break;
						}
						
						if (asciiTrans) {
							for (int off = 0, b = 0; b < numRead; ++b) {
								if (rdbuf[b] == 10) {
									string s = Encoding.ASCII.GetString(rdbuf, off, (b - off));
									outw.WriteLine(s);
									off = b + 1;
								}
							}
						} else {
							outputStream.Write(rdbuf, 0, numRead);
						}
					}
					
					if (asciiTrans) {
						outw.Close();
					} else {
						outputStream.Close();
					}
				}
			}
		}
		/// <summary>
		/// Extract an entry from the archive. This method assumes that the
		/// tarIn stream has been properly set with a call to getNextEntry().
		/// </summary>
		/// <param name="destDir">
		/// The destination directory into which to extract.
		/// </param>
		/// <param name="entry">
		/// The TarEntry returned by tarIn.getNextEntry().
		/// </param>
		void ExtractEntry(string destDir, TarEntry entry)
		{
			if (this.verbose) {
				OnProgressMessageEvent(entry, null);
			}
			
			string name = entry.Name;
			name = name.Replace('/', Path.DirectorySeparatorChar);
			
			if (!destDir.EndsWith(Path.DirectorySeparatorChar.ToString())) {
				destDir += Path.DirectorySeparatorChar;
			}
			
			string destFile = destDir + name;
			
			if (entry.IsDirectory) {
				EnsureDirectoryExists(destFile);
			} 
         else {
				string parentDirectory = Path.GetDirectoryName(destFile);
				EnsureDirectoryExists(parentDirectory);
				
				if (this.keepOldFiles && File.Exists(destFile)) {
					if (this.verbose) {
						OnProgressMessageEvent(entry, "Destination file already exists");
					}
				} 
            else {
					bool asciiTrans = false;
					Stream outputStream = File.Create(destFile);
					if (this.asciiTranslate) {
						asciiTrans = !IsBinary(destFile);
// original java sourcecode : 
//						MimeType mime      = null;
//						string contentType = null;
//						try {
//							contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile );
//							
//							mime = new MimeType(contentType);
//							
//							if (mime.getPrimaryType().equalsIgnoreCase( "text" )) {
//							    	asciiTrans = true;
//							} else if ( this.transTyper != null ) {
//							    if ( this.transTyper.isAsciiFile( entry.getName() ) ) {
//							    	asciiTrans = true;
//							    }
//							}
//						} catch (MimeTypeParseException ex) {
//						}
//						
//						if (this.debug) {
//							Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "'  ContentType='" + contentType + "'  PrimaryType='" + mime.getPrimaryType() + "'" );
//						}
					}
					
					StreamWriter outw = null;
					if (asciiTrans) {
						outw = new StreamWriter(outputStream);
					}
					
					byte[] rdbuf = new byte[32 * 1024];
					
					while (true) {
						int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length);
						
						if (numRead <= 0) {
							break;
						}
						
						if (asciiTrans) {
							for (int off = 0, b = 0; b < numRead; ++b) {
								if (rdbuf[b] == 10) {
									string s = Encoding.ASCII.GetString(rdbuf, off, (b - off));
									outw.WriteLine(s);
									off = b + 1;
								}
							}
						} 
                  else {
							outputStream.Write(rdbuf, 0, numRead);
						}
					}
					
					if (asciiTrans) {
						outw.Close();
					} 
               else {
						outputStream.Close();
					}
				}
			}
		}
		/// <summary>
		/// Write an entry to the archive. This method will call the putNextEntry
		/// and then write the contents of the entry, and finally call closeEntry()()
		/// for entries that are files. For directories, it will call putNextEntry(),
		/// and then, if the recurse flag is true, process each entry that is a
		/// child of the directory.
		/// </summary>
		/// <param name="entry">
		/// The TarEntry representing the entry to write to the archive.
		/// </param>
		/// <param name="recurse">
		/// If true, process the children of directory entries.
		/// </param>
		public void WriteEntry(TarEntry entry, bool recurse)
		{
			bool asciiTrans = false;
			
			string tempFileName = null;
			string eFile        = entry.File;
			
			// Work on a copy of the entry so we can manipulate it.
			// Note that we must distinguish how the entry was constructed.
			//
			if (eFile == null || eFile.Length == 0) {
				entry = TarEntry.CreateTarEntry(entry.Name);
			} 
         else {
				//
				// The user may have explicitly set the entry's name to
				// something other than the file's path, so we must save
				// and restore it. This should work even when the name
				// was set from the File's name.
				//
				string saveName = entry.Name;
				entry = TarEntry.CreateEntryFromFile(eFile);
				entry.Name = saveName;
			}
			
			if (this.verbose) {
				OnProgressMessageEvent(entry, null);
			}
			
			if (this.asciiTranslate && !entry.IsDirectory) {
				asciiTrans = !IsBinary(eFile);

// original java source :
//			    	MimeType mime = null;
//			    	string contentType = null;
//	
//			    	try {
//			    		contentType = FileTypeMap.getDefaultFileTypeMap(). getContentType( eFile );
//			    		
//			    		mime = new MimeType( contentType );
//			    		
//			    		if ( mime.getPrimaryType().
//			    		    equalsIgnoreCase( "text" ) )
//			    		    {
//			    		    	asciiTrans = true;
//			    		    }
//			    		    else if ( this.transTyper != null )
//			    		    {
//			    		    	if ( this.transTyper.isAsciiFile( eFile ) )
//			    		    	{
//			    		    		asciiTrans = true;
//			    		    	}
//			    		    }
//			    	} catch ( MimeTypeParseException ex )
//			    	{
//	//		    		 IGNORE THIS ERROR...
//			    	}
//		    	
//		    	if (this.debug) {
//		    		Console.Error.WriteLine("CREATE TRANS? '" + asciiTrans + "'  ContentType='" + contentType + "'  PrimaryType='" + mime.getPrimaryType()+ "'" );
//		    	}
		    	
		    	if (asciiTrans) {
		    		tempFileName = Path.GetTempFileName();
		    		
		    		StreamReader inStream  = File.OpenText(eFile);
		    		Stream       outStream = new BufferedStream(File.Create(tempFileName));
		    		
		    		while (true) {
		    			string line = inStream.ReadLine();
		    			if (line == null) {
		    				break;
		    			}
		    			byte[] data = Encoding.ASCII.GetBytes(line);
		    			outStream.Write(data, 0, data.Length);
		    			outStream.WriteByte((byte)'\n');
		    		}
		    		
		    		inStream.Close();

		    		outStream.Flush();
		    		outStream.Close();
		    		
		    		entry.Size = new FileInfo(tempFileName).Length;
		    		
		    		eFile = tempFileName;
		    	}
			}
		    
		    string newName = null;
		
			if (this.rootPath != null) {
				if (entry.Name.StartsWith(this.rootPath)) {
					newName = entry.Name.Substring(this.rootPath.Length + 1 );
				}
			}
			
			if (this.pathPrefix != null) {
				newName = (newName == null) ? this.pathPrefix + "/" + entry.Name : this.pathPrefix + "/" + newName;
			}
			
			if (newName != null) {
				entry.Name = newName;
			}
			
			this.tarOut.PutNextEntry(entry);
			
			if (entry.IsDirectory) {
				if (recurse) {
					TarEntry[] list = entry.GetDirectoryEntries();
					for (int i = 0; i < list.Length; ++i) {
						this.WriteEntry(list[i], recurse);
					}
				}
			}
         else {
				Stream inputStream = File.OpenRead(eFile);
				int numWritten = 0;
				byte[] eBuf = new byte[32 * 1024];
				while (true) {
					int numRead = inputStream.Read(eBuf, 0, eBuf.Length);
					
					if (numRead <=0) {
						break;
					}
					
					this.tarOut.Write(eBuf, 0, numRead);
					numWritten +=  numRead;
				}

//				Console.WriteLine("written " + numWritten + " bytes");
				
				inputStream.Close();
				
				if (tempFileName != null && tempFileName.Length > 0) {
					File.Delete(tempFileName);
				}
				
				this.tarOut.CloseEntry();
			}
		}
Example #41
0
		/// <summary>
		/// Clone this tar entry.
		/// </summary>
		/// <returns>Returns a clone of this entry.</returns>
		public object Clone()
		{
			TarEntry entry = new TarEntry();
			entry.file = file;
			entry.header = (TarHeader)header.Clone();
			entry.Name = Name;
			return entry;
		}
Example #42
0
    /// <summary>
    /// Display progress information on console
    /// </summary>
    public void ShowTarProgressMessage(TarArchive archive, TarEntry entry, string message)
    {
        if (entry.TarHeader.TypeFlag != TarHeader.LF_NORMAL && entry.TarHeader.TypeFlag != TarHeader.LF_OLDNORM) {
            Console.WriteLine("Entry type " + (char)entry.TarHeader.TypeFlag + " found!");
        }

        if (message != null)
            Console.Write(entry.Name + " " + message);
        else {
            if (this.verbose) {
                string modeString = DecodeType(entry.TarHeader.TypeFlag, entry.Name.EndsWith("/")) + DecodeMode(entry.TarHeader.Mode);
                string userString = (entry.UserName == null || entry.UserName.Length == 0) ? entry.UserId.ToString() : entry.UserName;
                string groupString = (entry.GroupName == null || entry.GroupName.Length == 0) ? entry.GroupId.ToString() : entry.GroupName;

                Console.WriteLine(string.Format("{0} {1}/{2} {3,8} {4:yyyy-MM-dd HH:mm:ss} {5}", modeString, userString, groupString, entry.Size, entry.ModTime.ToLocalTime(), entry.Name));
            } else {
                Console.WriteLine(entry.Name);
            }
        }
    }
Example #43
0
        /// <summary>
        /// Get entries for all files present in this entries directory.
        /// If this entry doesnt represent a directory zero entries are returned.
        /// </summary>
        /// <returns>
        /// An array of TarEntry's for this entry's children.
        /// </returns>
        public TarEntry[] GetDirectoryEntries()
        {
            if ((file == null) || !Directory.Exists(file)) {
                return new TarEntry[0];
            }

            string[] list = Directory.GetFileSystemEntries(file);
            TarEntry[] result = new TarEntry[list.Length];

            for (int i = 0; i < list.Length; ++i) {
                result[i] = TarEntry.CreateEntryFromFile(list[i]);
            }

            return result;
        }
Example #44
0
        /// <summary>
        /// Extract an entry from the archive. This method assumes that the
        /// tarIn stream has been properly set with a call to getNextEntry().
        /// </summary>
        /// <param name="destDir">
        /// The destination directory into which to extract.
        /// </param>
        /// <param name="entry">
        /// The TarEntry returned by tarIn.getNextEntry().
        /// </param>
        void ExtractEntry(string destDir, TarEntry entry)
        {
            if (this.verbose) {
                OnProgressMessageEvent(entry, null);
            }

            string name = entry.Name;

            if (Path.IsPathRooted(name) == true) {
                // NOTE:
                // for UNC names...  \\machine\share\zoom\beet.txt gives \zoom\beet.txt
                name = name.Substring(Path.GetPathRoot(name).Length);
            }

            name = name.Replace('/', Path.DirectorySeparatorChar);

            string destFile = Path.Combine(destDir, name);

            if (entry.IsDirectory) {
                EnsureDirectoryExists(destFile);
            } else {
                string parentDirectory = Path.GetDirectoryName(destFile);
                EnsureDirectoryExists(parentDirectory);

                bool process = true;
                FileInfo fileInfo = new FileInfo(destFile);
                if (fileInfo.Exists) {
                    if (this.keepOldFiles) {
                        OnProgressMessageEvent(entry, "Destination file already exists");
                        process = false;
                    } else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0) {
                        OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
                        process = false;
                    }
                }

                if (process) {
                    bool asciiTrans = false;
                    // TODO file may exist and be read-only at this point!
                    Stream outputStream = File.Create(destFile);
                    if (this.asciiTranslate) {
                        asciiTrans = !IsBinary(destFile);
            // TODO  do we need this stuff below?
            // original java sourcecode :
            //						MimeType mime      = null;
            //						string contentType = null;
            //						try {
            //							contentType = FileTypeMap.getDefaultFileTypeMap().getContentType( destFile );
            //
            //							mime = new MimeType(contentType);
            //
            //							if (mime.getPrimaryType().equalsIgnoreCase( "text" )) {
            //								asciiTrans = true;
            //							} else if ( this.transTyper != null ) {
            //								if ( this.transTyper.isAsciiFile( entry.getName() ) ) {
            //									asciiTrans = true;
            //								}
            //							}
            //						} catch (MimeTypeParseException ex) {
            //						}
            //
            //						if (this.debug) {
            //							Console.Error.WriteLine(("EXTRACT TRANS? '" + asciiTrans + "'  ContentType='" + contentType + "'  PrimaryType='" + mime.getPrimaryType() + "'" );
            //						}
                    }

                    StreamWriter outw = null;
                    if (asciiTrans) {
                        outw = new StreamWriter(outputStream);
                    }

                    byte[] rdbuf = new byte[32 * 1024];

                    while (true) {
                        int numRead = this.tarIn.Read(rdbuf, 0, rdbuf.Length);

                        if (numRead <= 0) {
                            break;
                        }

                        if (asciiTrans) {
                            for (int off = 0, b = 0; b < numRead; ++b) {
                                if (rdbuf[b] == 10) {
                                    string s = Encoding.ASCII.GetString(rdbuf, off, (b - off));
                                    outw.WriteLine(s);
                                    off = b + 1;
                                }
                            }
                        } else {
                            outputStream.Write(rdbuf, 0, numRead);
                        }
                    }

                    if (asciiTrans) {
                        outw.Close();
                    } else {
                        outputStream.Close();
                    }
                }
            }
        }
		/// <summary>
		/// Determine if the given entry is a descendant of this entry.
		/// Descendancy is determined by the name of the descendant
		/// starting with this entry's name.
		/// </summary>
		/// <param name = "desc">
		/// Entry to be checked as a descendent of this.
		/// </param>
		/// <returns>
		/// True if entry is a descendant of this.
		/// </returns>
		public bool IsDescendent(TarEntry desc)
		{
			return desc.header.name.ToString().StartsWith(this.header.name.ToString());
		}
Example #46
0
 /// <summary>
 /// Construct an entry for a file. File is set to file, and the
 /// header is constructed from information from the file.
 /// </summary>
 /// <param name = "fileName">The file name that the entry represents.</param>
 /// <returns>Returns the newly created <see cref="TarEntry"/></returns>
 public static TarEntry CreateEntryFromFile(string fileName)
 {
     var entry = new TarEntry();
     entry.GetFileTarHeader(entry.header, fileName);
     return entry;
 }
		/// <summary>
		/// Put an entry on the output stream. This writes the entry's
		/// header and positions the output stream for writing
		/// the contents of the entry. Once this method is called, the
		/// stream is ready for calls to write() to write the entry's
		/// contents. Once the contents are written, closeEntry()
		/// <B>MUST</B> be called to ensure that all buffered data
		/// is completely written to the output stream.
		/// </summary>
		/// <param name="entry">
		/// The TarEntry to be written to the archive.
		/// </param>
		public void PutNextEntry(TarEntry entry)
		{
			if ( entry == null ) {
				throw new ArgumentNullException("entry");
			}

			if (entry.TarHeader.Name.Length >= TarHeader.NAMELEN) {
				TarHeader longHeader = new TarHeader();
				longHeader.TypeFlag = TarHeader.LF_GNU_LONGNAME;
				longHeader.Name = longHeader.Name + "././@LongLink";
				longHeader.UserId = 0;
				longHeader.GroupId = 0;
				longHeader.GroupName = "";
				longHeader.UserName = "";
				longHeader.LinkName = "";
                longHeader.Size = entry.TarHeader.Name.Length;

				longHeader.WriteHeader(blockBuffer);
				buffer.WriteBlock(blockBuffer);  // Add special long filename header block

				int nameCharIndex = 0;

				while (nameCharIndex < entry.TarHeader.Name.Length) {
					Array.Clear(blockBuffer, 0, blockBuffer.Length);
					TarHeader.GetAsciiBytes(entry.TarHeader.Name, nameCharIndex, this.blockBuffer, 0, TarBuffer.BlockSize);
					nameCharIndex += TarBuffer.BlockSize;
					buffer.WriteBlock(blockBuffer);
				}
			}
			
			entry.WriteEntryHeader(blockBuffer);
			buffer.WriteBlock(blockBuffer);
			
			currBytes = 0;
			
			currSize = entry.IsDirectory ? 0 : entry.Size;
		}
Example #48
0
		/// <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;
		}
Example #49
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 (hasHitEOF) {
                return null;
            }

            if (currentEntry != null) {
                SkipToNextEntry();
            }

            byte[] headerBuf = tarBuffer.ReadBlock();

            if (headerBuf == null) {
                hasHitEOF = true;
            } else
                hasHitEOF |= TarBuffer.IsEndOfArchiveBlock(headerBuf);

            if (hasHitEOF) {
                currentEntry = null;
            } else {
                try {
                    var header = new TarHeader();
                    header.ParseBuffer(headerBuf);
                    if (!header.IsChecksumValid) {
                        throw new TarException("Header checksum is invalid");
                    }
                    this.entryOffset = 0;
                    this.entrySize = header.Size;

                    StringBuilder longName = null;

                    if (header.TypeFlag == TarHeader.LF_GNU_LONGNAME) {

                        byte[] nameBuffer = new byte[TarBuffer.BlockSize];
                        long numToRead = this.entrySize;

                        longName = new StringBuilder();

                        while (numToRead > 0) {
                            int numRead = this.Read(nameBuffer, 0, (numToRead > nameBuffer.Length ? nameBuffer.Length : (int)numToRead));

                            if (numRead == -1) {
                                throw new InvalidHeaderException("Failed to read long name entry");
                            }

                            longName.Append(TarHeader.ParseName(nameBuffer, 0, numRead).ToString());
                            numToRead -= numRead;
                        }

                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    } else if (header.TypeFlag == TarHeader.LF_GHDR) {  // POSIX global extended header
                                                                        // Ignore things we dont understand completely for now
                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    } else if (header.TypeFlag == TarHeader.LF_XHDR) {  // POSIX extended header
                                                                        // Ignore things we dont understand completely for now
                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    } else if (header.TypeFlag == TarHeader.LF_GNU_VOLHDR) {
                        // TODO: could show volume name when verbose
                        SkipToNextEntry();
                        headerBuf = this.tarBuffer.ReadBlock();
                    } else if (header.TypeFlag != TarHeader.LF_NORMAL &&
                               header.TypeFlag != TarHeader.LF_OLDNORM &&
                               header.TypeFlag != TarHeader.LF_LINK &&
                               header.TypeFlag != TarHeader.LF_SYMLINK &&
                               header.TypeFlag != TarHeader.LF_DIR) {
                        // Ignore things we dont understand completely for now
                        SkipToNextEntry();
                        headerBuf = tarBuffer.ReadBlock();
                    }

                    if (entryFactory == null) {
                        currentEntry = new TarEntry(headerBuf);
                        if (longName != null) {
                            currentEntry.Name = longName.ToString();
                        }
                    } else {
                        currentEntry = entryFactory.CreateEntry(headerBuf);
                    }

                    // Magic was checked here for 'ustar' but there are multiple valid possibilities
                    // so this is not done anymore.

                    entryOffset = 0;

                    // TODO: Review How do we resolve this discrepancy?!
                    entrySize = this.currentEntry.Size;
                } catch (InvalidHeaderException ex) {
                    entrySize = 0;
                    entryOffset = 0;
                    currentEntry = null;
                    string errorText = string.Format("Bad header in record {0} block {1} {2}",
                        tarBuffer.CurrentRecord, tarBuffer.CurrentBlock, ex.Message);
                    throw new InvalidHeaderException(errorText);
                }
            }
            return currentEntry;
        }
Example #50
0
		/// <summary>
		/// Write an entry to the archive. This method will call the putNextEntry
		/// and then write the contents of the entry, and finally call closeEntry()
		/// for entries that are files. For directories, it will call putNextEntry(),
		/// and then, if the recurse flag is true, process each entry that is a
		/// child of the directory.
		/// </summary>
		/// <param name="sourceEntry">
		/// The TarEntry representing the entry to write to the archive.
		/// </param>
		/// <param name="recurse">
		/// If true, process the children of directory entries.
		/// </param>
		void WriteEntryCore(TarEntry sourceEntry, bool recurse)
		{
			string tempFileName = null;
			string entryFilename   = sourceEntry.File;
			
			TarEntry entry = (TarEntry)sourceEntry.Clone();

			if ( applyUserInfoOverrides ) {
				entry.GroupId = groupId;
				entry.GroupName = groupName;
				entry.UserId = userId;
				entry.UserName = userName;
			}
			
			OnProgressMessageEvent(entry, null);
			
			if (asciiTranslate && !entry.IsDirectory) {

				if (!IsBinary(entryFilename)) {
					tempFileName = Path.GetTempFileName();
					
					using (StreamReader inStream  = File.OpenText(entryFilename)) {
						using (Stream outStream = File.Create(tempFileName)) {
						
							while (true) {
								string line = inStream.ReadLine();
								if (line == null) {
									break;
								}
								byte[] data = Encoding.ASCII.GetBytes(line);
								outStream.Write(data, 0, data.Length);
								outStream.WriteByte((byte)'\n');
							}
							
							outStream.Flush();
						}
					}
					
					entry.Size = new FileInfo(tempFileName).Length;
					entryFilename = tempFileName;
				}
			}
			
			string newName = null;
		
			if (rootPath != null) {
				if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) {
					newName = entry.Name.Substring(rootPath.Length + 1 );
				}
			}
			
			if (pathPrefix != null) {
				newName = (newName == null) ? pathPrefix + "/" + entry.Name : pathPrefix + "/" + newName;
			}
			
			if (newName != null) {
				entry.Name = newName;
			}
			
			tarOut.PutNextEntry(entry);
			
			if (entry.IsDirectory) {
				if (recurse) {
					TarEntry[] list = entry.GetDirectoryEntries();
					for (int i = 0; i < list.Length; ++i) {
						WriteEntryCore(list[i], recurse);
					}
				}
			}
			else {
				using (Stream inputStream = File.OpenRead(entryFilename)) {
					byte[] localBuffer = new byte[32 * 1024];
					while (true) {
						int numRead = inputStream.Read(localBuffer, 0, localBuffer.Length);
						
						if (numRead <=0) {
							break;
						}
						
						tarOut.Write(localBuffer, 0, numRead);
					}
				}
				
				if ( (tempFileName != null) && (tempFileName.Length > 0) ) {
					File.Delete(tempFileName);
				}
				
				tarOut.CloseEntry();
			}
		}
Example #51
0
		void EntryCounter(TarArchive archive, TarEntry entry, string message)
		{
			entryCount++;
		}
Example #52
0
		/// <summary>
		/// Construct an entry with only a <paramref name="name">name</paramref>.
		/// This allows the programmer to construct the entry's header "by hand". 
		/// </summary>
		/// <param name="name">The name to use for the entry</param>
		/// <returns>Returns the newly created <see cref="TarEntry"/></returns>
		public static TarEntry CreateTarEntry(string name)
		{
			TarEntry entry = new TarEntry();
			TarEntry.NameTarHeader(entry.header, name);
			return entry;
		}
Example #53
0
        public void CloningAndUniqueness()
		{
			// Partial test of cloning for TarHeader and TarEntry
			TarEntry e = TarEntry.CreateTarEntry("ohsogood");
			e.GroupId = 47;
			e.GroupName = "GroupName";
			e.ModTime = DateTime.Now;
			e.Size = 123234;

			TarHeader headerE = e.TarHeader;

			headerE.DevMajor = 99;
			headerE.DevMinor = 98;
			headerE.LinkName = "LanceLink";

			TarEntry d = (TarEntry)e.Clone();

			Assert.AreEqual(d.File, e.File);
			Assert.AreEqual(d.GroupId, e.GroupId);
			Assert.AreEqual(d.GroupName, e.GroupName);
			Assert.AreEqual(d.IsDirectory, e.IsDirectory);
			Assert.AreEqual(d.ModTime, e.ModTime);
			Assert.AreEqual(d.Size, e.Size);

			TarHeader headerD = d.TarHeader;

			Assert.AreEqual(headerE.Checksum, headerD.Checksum);
			Assert.AreEqual(headerE.LinkName, headerD.LinkName);

			Assert.AreEqual(99, headerD.DevMajor);
			Assert.AreEqual(98, headerD.DevMinor);

			Assert.AreEqual("LanceLink", headerD.LinkName);

			TarEntry entryf = new TarEntry(headerD);

			headerD.LinkName = "Something different";

			Assert.AreNotEqual(headerD.LinkName, entryf.TarHeader.LinkName, "Entry headers should be unique");
		}
Example #54
-1
        /// <inheritdoc/>
        protected override void HandleFile(FileInfo file, bool executable = false)
        {
            #region Sanity checks
            if (file == null) throw new ArgumentNullException(nameof(file));
            #endregion

            var entry = new TarEntry(new TarHeader
            {
                Name = file.RelativeTo(SourceDirectory),
                ModTime = file.LastWriteTimeUtc,
                Mode = (executable ? TarExtractor.DefaultMode | TarExtractor.ExecuteMode : TarExtractor.DefaultMode)
            });

            var hardlinkTarget = _previousFiles.FirstOrDefault(previousFile => FileUtils.AreHardlinked(previousFile.FullName, file.FullName));
            if (hardlinkTarget != null)
            {
                entry.TarHeader.TypeFlag = TarHeader.LF_LINK;
                entry.TarHeader.LinkName = hardlinkTarget.RelativeTo(SourceDirectory);
                _tarStream.PutNextEntry(entry);
            }
            else
            {
                _previousFiles.Add(file);

                entry.Size = file.Length;
                _tarStream.PutNextEntry(entry);
                using (var stream = file.OpenRead())
                    stream.CopyToEx(_tarStream);
            }
            _tarStream.CloseEntry();
        }
Example #55
-1
        public override bool HasNext()
        {
            tarEntry = tarStream.GetNextEntry();

            if (tarEntry == null)
                return false;

            return true;
        }
Example #56
-1
 protected abstract void PostCreate(TarEntry entry);