Exemplo n.º 1
0
        internal static Stream GetPayloadStream(Stream stream)
        {
            using (ArFile archive = new ArFile(stream, leaveOpen: true))
            {
                while (archive.Read())
                {
                    if (archive.FileName.StartsWith("data.tar."))
                    {
                        var ext = Path.GetExtension(archive.FileName);
                        if (ext == ".gz")
                        {
                            return(new GZipDecompressor(archive.Open(), false));
                        }

                        if (ext == ".xz")
                        {
                            // For some reason it complains about corrupted data when we try to read using smaller chunks
                            var payload = new MemoryStream();
                            using (var xz = new XZInputStream(archive.Open()))
                            {
                                xz.CopyTo(payload);
                                payload.Seek(0, SeekOrigin.Begin);
                                return(payload);
                            }
                        }

                        throw new InvalidDataException("Don't know how to decompress " + archive.FileName);
                    }
                }

                throw new InvalidDataException("data.tar.?? not found");
            }
        }
Exemplo n.º 2
0
        public void ReadTarFileTest()
        {
            using (Stream stream = File.OpenRead("Deb/libplist3_1.12-3.1_amd64.deb"))
                using (ArFile arFile = new ArFile(stream, leaveOpen: true))
                {
                    // Skip the debian version
                    arFile.Read();

                    // This is the tar file
                    arFile.Read();

                    Collection <string>    filenames = new Collection <string>();
                    Collection <string>    contents  = new Collection <string>();
                    Collection <TarHeader> headers   = new Collection <TarHeader>();

                    using (Stream entryStream = arFile.Open())
                        using (GZipDecompressor decompressedStream = new GZipDecompressor(entryStream, leaveOpen: true))
                            using (TarFile tarFile = new TarFile(decompressedStream, leaveOpen: true))
                            {
                                while (tarFile.Read())
                                {
                                    filenames.Add(tarFile.FileName);
                                    headers.Add((TarHeader)tarFile.FileHeader);

                                    using (Stream data = tarFile.Open())
                                        using (StreamReader reader = new StreamReader(data))
                                        {
                                            contents.Add(reader.ReadToEnd());
                                        }
                                }
                            }
                }
        }
Exemplo n.º 3
0
        public void ReadTest()
        {
            using (Stream stream = File.OpenRead(@"Deb/libplist3_1.12-3.1_amd64.deb"))
                using (ArFile arFile = new ArFile(stream, leaveOpen: true))
                {
                    Collection <string>   filenames = new Collection <string>();
                    Collection <ArHeader> headers   = new Collection <ArHeader>();

                    while (arFile.Read())
                    {
                        filenames.Add(arFile.FileName);
                        headers.Add((ArHeader)arFile.FileHeader);

                        arFile.Skip();
                    }

                    Assert.Equal(
                        new string[]
                    {
                        "debian-binary",
                        "control.tar.gz",
                        "data.tar.xz"
                    },
                        filenames);
                }
        }
Exemplo n.º 4
0
        /// <summary>
        ///     Extracts an archive file created with GNU ar
        /// </summary>
        /// <param name="fileEntry"> </param>
        /// <returns> </returns>
        ///
        public IEnumerable <FileEntry> Extract(FileEntry fileEntry, ExtractorOptions options, ResourceGovernor governor)
        {
            IEnumerable <FileEntry>?fileEntries = null;

            try
            {
                fileEntries = ArFile.GetFileEntries(fileEntry, options, governor);
            }
            catch (Exception e)
            {
                Logger.Debug(Extractor.DEBUG_STRING, ArchiveFileType.AR, fileEntry.FullPath, string.Empty, e.GetType());
                if (e is OverflowException)
                {
                    throw;
                }
            }
            if (fileEntries != null)
            {
                if (options.Parallel)
                {
                    while (fileEntries.Any())
                    {
                        var tempStore       = new ConcurrentStack <FileEntry>();
                        var selectedEntries = fileEntries.Take(options.BatchSize);
                        selectedEntries.AsParallel().ForAll(arEntry =>
                        {
                            tempStore.PushRange(Context.ExtractFile(arEntry, options, governor).ToArray());
                        });

                        fileEntries = fileEntries.Skip(selectedEntries.Count());

                        while (tempStore.TryPop(out var result))
                        {
                            if (result != null)
                            {
                                yield return(result);
                            }
                        }
                    }
                }
                else
                {
                    foreach (var entry in fileEntries)
                    {
                        foreach (var extractedFile in Context.ExtractFile(entry, options, governor))
                        {
                            yield return(extractedFile);
                        }
                    }
                }
            }
            else
            {
                if (options.ExtractSelfOnFail)
                {
                    yield return(fileEntry);
                }
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Reads and parses the <c>debian-binary</c> file in the Debian archive.
 /// </summary>
 /// <param name="archive">
 /// The archive to update with the data read from the <c>debian-binary</c> file.
 /// </param>
 /// <param name="package">
 /// The package to update.
 /// </param>
 private static void ReadDebianBinary(ArFile archive, DebPackage package)
 {
     using (Stream stream = archive.Open())
         using (StreamReader reader = new StreamReader(stream))
         {
             var content = reader.ReadToEnd();
             package.PackageFormatVersion = new Version(content);
         }
 }
Exemplo n.º 6
0
 /// <summary>
 ///     Extracts an archive file created with GNU ar
 /// </summary>
 /// <param name="fileEntry"> </param>
 /// <returns> </returns>
 ///
 public async IAsyncEnumerable <FileEntry> ExtractAsync(FileEntry fileEntry, ExtractorOptions options, ResourceGovernor governor)
 {
     await foreach (var entry in ArFile.GetFileEntriesAsync(fileEntry, options, governor))
     {
         await foreach (var extractedFile in Context.ExtractAsync(entry, options, governor))
         {
             yield return(extractedFile);
         }
     }
 }
Exemplo n.º 7
0
 public void WriteTest()
 {
     using (Stream original = File.OpenRead("Deb/libplist3_1.12-3.1_amd64.deb"))
         using (Stream expected = File.OpenRead("Deb/libplist3_1.12-3.1_amd64.deb"))
             using (Stream actual = new MemoryStream())
                 using (Stream output = new ValidatingCompositeStream(null, actual, expected))
                 {
                     ArFileCreator.WriteMagic(output);
                     var input = new ArFile(original, true);
                     while (input.Read())
                     {
                         var header = (ArHeader)input.FileHeader;
                         var clone  = this.CloneHeader(header);
                         this.AssertCompareClonedHeader(header, clone);
                         using (var data = input.Open())
                         {
                             ArFileCreator.WriteEntry(output, clone, data);
                         }
                     }
                 }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Reads a <see cref="DebPackage"/> from a <see cref="Stream"/>.
        /// </summary>
        /// <param name="stream">
        /// The <see cref="Stream"/> from which to read the package.
        /// </param>
        /// <returns>
        /// A <see cref="DebPackage"/> which represents the package.
        /// </returns>
        public static async Task <DebPackage> Read(Stream stream)
        {
            DebPackage package = new DebPackage();

            using (ArFile archive = new ArFile(stream, leaveOpen: true))
            {
                while (archive.Read())
                {
                    if (archive.FileName == "debian-binary")
                    {
                        await ReadDebianBinary(archive, package);
                    }
                    else if (archive.FileName == "control.tar.gz")
                    {
                        await ReadControlArchive(archive, package);
                    }
                }
            }

            return(package);
        }
Exemplo n.º 9
0
        void Build()
        {
            int debberVer = 0;

            ini.GetValue("debber", "debber-version", ref debberVer);
            if (debberVer != 1)
            {
                throw new Exception("File requires a newer debber version. Please update!");
            }

            string binVer = ini.ReadSetting("debber", "debian-binary");

            if (binVer != "2.0")
            {
                throw new Exception("Invalid or unknown debian version!");
            }

            packageVersion = SemanticVersion.Parse(ini.ReadSetting("package", "version"));
            packageName    = ini.ReadSetting("package", "name");
            packageFile    = ini.ReadSetting("package", "output").Replace("{NAME}", packageName).Replace("{VERSION}", packageVersion.ToString());
            FileSystem.TouchFile(packageFile);

            SystemConsole.WriteLine("Create <cyan>data.tar.gz<default>...");
            byte[] data_tar_gz;
            using (MemoryStream ms = new MemoryStream())
            {
                TarWriter tarFile = new TarWriter(ms, true);
                foreach (string line in ini.ReadSection("data.tgz", true))
                {
                    string[] parts = line.Split(':');
                    if (parts.Length < 2)
                    {
                        continue;
                    }

                    switch (parts[0].Trim())
                    {
                    case "directory": PackDirectory(tarFile, parts[1]); break;

                    case "file": PackFiles(tarFile, parts); break;

                    default: throw new Exception(string.Format("Invalid setting {0} at [data.tgz]!", line));
                    }
                }
                tarFile.Close();
                data_tar_gz = ms.ToArray();
            }

            SystemConsole.WriteLine("Create <cyan>control.tar.gz<default>...");
            byte[] control_tar_gz;
            using (MemoryStream tarStream = new MemoryStream())
            {
                TarWriter tarFile = new TarWriter(tarStream, true);

                WriteControlFile(tarFile, "control", 640);
                #region md5sums
                using (MemoryStream ms = new MemoryStream())
                {
                    DataWriter writer = new DataWriter(ms);
                    foreach (KeyValuePair <string, string> md5sum in md5sums)
                    {
                        writer.Write(md5sum.Value);
                        writer.Write("  ");
                        writer.Write(md5sum.Key);
                        writer.Write("\n");
                    }
                    writer.Close();
                    SystemConsole.WriteLine("  file: <cyan>md5sums");
                    tarFile.AddFile("md5sums", ms.ToArray());
                }
                #endregion
                WriteControlFile(tarFile, "conffiles", 640);
                WriteControlFile(tarFile, "preinst", 700);
                WriteControlFile(tarFile, "postinst", 700);
                WriteControlFile(tarFile, "prerm", 700);
                WriteControlFile(tarFile, "postrm", 700);

                tarFile.Close();
                control_tar_gz = tarStream.ToArray();
            }

            using (MemoryStream ms = new MemoryStream())
            {
                var arFile = ArFile.CreateNewAr(ms);
                arFile.WriteHeader(ArHeader.CreateFile("debian-binary", 4));
                arFile.WriteData(Encoding.ASCII.GetBytes("2.0\n"));

                arFile.WriteHeader(ArHeader.CreateFile("control.tar.gz", control_tar_gz.Length));
                arFile.WriteData(control_tar_gz);

                arFile.WriteHeader(ArHeader.CreateFile("data.tar.gz", data_tar_gz.Length));
                arFile.WriteData(data_tar_gz);
                arFile.Close();

                File.WriteAllBytes(packageFile, ms.ToArray());
                SystemConsole.WriteLine("Completed <green>{0}<default> ...", packageFile);
            }
        }
Exemplo n.º 10
0
 /// <summary>
 /// Initializes a new instance.
 /// </summary>
 /// <param name="name">The name of the symbol.</param>
 /// <param name="file">The associated file entry this symbol is coming from <see cref="ArArchiveFile.Files"/>.</param>
 public ArSymbol(string name, ArFile file) : this()
 {
     Name = name;
     File = file;
 }
Exemplo n.º 11
0
        private static async Task ReadControlArchive(ArFile archive, DebPackage package)
        {
            package.ControlExtras = new Dictionary <string, DebPackageControlFileData>();
            package.Md5Sums       = new Dictionary <string, string>();
            using (Stream stream = archive.Open())
                using (GZipDecompressor decompressedStream = new GZipDecompressor(stream, leaveOpen: true))
                    using (TarFile tarFile = new TarFile(decompressedStream, leaveOpen: true))
                    {
                        while (tarFile.Read())
                        {
                            switch (tarFile.FileName)
                            {
                            case "./control":
                            case "control":
                                using (Stream controlFile = tarFile.Open())
                                {
                                    package.ControlFile = ControlFileParser.Read(controlFile);
                                }

                                break;

                            case "./md5sums":
                                using (var sums = new StreamReader(tarFile.Open()))
                                {
                                    string line;
                                    while ((line = await sums.ReadLineAsync()) != null)
                                    {
                                        var s = line.Split(new[] { "  " }, 2, StringSplitOptions.None);
                                        package.Md5Sums[s[1]] = s[0];
                                    }
                                }

                                break;

                            case "./preinst":
                                package.PreInstallScript = tarFile.ReadAsUtf8String();
                                break;

                            case "./postinst":
                                package.PostInstallScript = tarFile.ReadAsUtf8String();
                                break;

                            case "./prerm":
                                package.PreRemoveScript = tarFile.ReadAsUtf8String();
                                break;

                            case "./postrm":
                                package.PostRemoveScript = tarFile.ReadAsUtf8String();
                                break;

                            case "./":
                                tarFile.Skip();
                                break;

                            default:
                                package.ControlExtras[tarFile.FileName] = new DebPackageControlFileData
                                {
                                    Mode     = tarFile.FileHeader.FileMode,
                                    Contents = tarFile.ReadAsUtf8String()
                                };
                                break;
                            }
                        }
                    }
        }