/// <summary> /// Enumerate through the files of a TAR and get a list of KVP names-byte arrays /// </summary> /// <param name="stream">The input tar stream</param> /// <param name="isTarGz">True if the input stream is a .tar.gz or .tgz</param> /// <returns>An enumerable containing each tar entry and it's contents</returns> public static IEnumerable <KeyValuePair <string, byte[]> > UnTar(Stream stream, bool isTarGz) { using (var tar = new TarInputStream(isTarGz ? (Stream) new GZipInputStream(stream) : stream)) { TarEntry entry; while ((entry = tar.GetNextEntry()) != null) { if (entry.IsDirectory) { continue; } using (var output = new MemoryStream()) { tar.CopyEntryContents(output); yield return(new KeyValuePair <string, byte[]>(entry.Name, output.ToArray())); } } } }
public bool SeekToEntry(string name) { TarEntry entry; while ((entry = _tar.GetNextEntry()) != null) { if (entry.IsDirectory || entry.TarHeader.TypeFlag == TarHeader.LF_LINK || entry.TarHeader.TypeFlag == TarHeader.LF_SYMLINK) { continue; } // remove root directory var entryName = entry.Name.AsSpan(entry.Name.IndexOf('/') + 1); if (entryName.Equals(name.AsSpan(), StringComparison.OrdinalIgnoreCase)) { return(true); } } return(false); }
private void ExtractTarByEntry(string tarFileName, string targetDir) { using (FileStream fsIn = new FileStream(tarFileName, FileMode.Open, FileAccess.Read)) { TarInputStream tarIn = new TarInputStream(fsIn); TarEntry tarEntry; while ((tarEntry = tarIn.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } // Converts the unix forward slashes in the filenames to windows backslashes // string name = tarEntry.Name.Replace('/', Path.DirectorySeparatorChar); // Remove any root e.g. '\' because a PathRooted filename defeats Path.Combine if (Path.IsPathRooted(name)) { name = name.Substring(Path.GetPathRoot(name).Length); } // Apply further name transformations here as necessary string outName = Path.Combine(targetDir, name); string directoryName = Path.GetDirectoryName(outName); Directory.CreateDirectory(directoryName); FileStream outStr = new FileStream(outName, FileMode.Create); tarIn.CopyEntryContents(outStr); outStr.Close(); // Set the modification date/time. This approach seems to solve timezone issues. DateTime myDt = DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc); File.SetLastWriteTime(outName, myDt); } tarIn.Close(); } }
private static async Task <int> ExtractTarGz(Stream stream, DocumentClient client, ILogger logger, string name) { int total = 0, errors = 0; logger.LogInformation($"Decompressing and extracting files from {name}..."); using (var sourceStream = new GZipInputStream(stream)) { using (TarInputStream tarIn = new TarInputStream(sourceStream)) { TarEntry tarEntry; while ((tarEntry = tarIn.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } byte[] bytes = null; var str = new MemoryStream(); tarIn.CopyEntryContents(str); bytes = str.ToArray(); var rslt = await processMessage(Encoding.UTF8.GetString(bytes), client, logger, tarEntry.Name, name); total++; if (!rslt) { errors++; //logger.LogTrace("Unable to process file: " + tarEntry.Name + " un-supported format!"); } if (total % 1000 == 0) { logger.LogTrace($"Processed {total} files with {errors} invalid files from archive {name}"); } } } } logger.LogInformation($"Processed {total} files with {errors} invalid files from archive {name}"); logger.LogTrace($"Processed {total} files with {errors} invalid files from archive {name}"); return(total); }
private static Dictionary <String, Byte[]> UnzipToMemory(Stream originalZipStream) { var result = new Dictionary <string, Byte[]>(); using (var stream = new MemoryStream()) { Stream gzipStream = new GZipInputStream(originalZipStream); TarInputStream tarStream = new TarInputStream(gzipStream); TarEntry tarEntry; while ((tarEntry = tarStream.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } string name = tarEntry.Name.Replace('/', Path.DirectorySeparatorChar); if (!name.EndsWith(".xml")) { continue; } if (Path.IsPathRooted(name)) { name = name.Substring(Path.GetPathRoot(name).Length); } using (var contentStream = new MemoryStream()) { tarStream.CopyEntryContents(contentStream); result.Add(name.ToLower(), contentStream.ToArray()); } } tarStream.Close(); } return(result); }
void TryLongName(string name) { var ms = new MemoryStream(); using (TarOutputStream tarOut = new TarOutputStream(ms)) { DateTime modTime = DateTime.Now; TarEntry entry = TarEntry.CreateTarEntry(name); tarOut.PutNextEntry(entry); } var ms2 = new MemoryStream(); ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms2.Seek(0, SeekOrigin.Begin); using (TarInputStream tarIn = new TarInputStream(ms2)) { TarEntry nextEntry = tarIn.GetNextEntry(); Assert.AreEqual(nextEntry.Name, name, "Name match failure"); } }
/// <summary> /// 获取.tar.gz文件列表 /// </summary> /// <param name="file">.tar.gz文件</param> /// <param name="encod">编码</param> /// <returns></returns> public static List <string> GetTarGZipFiles(string file, Encoding encod) { var list = new List <string>(); if (File.Exists(file)) { using (var fs = File.OpenRead(file)) using (var gz = new GZipInputStream(fs)) using (var tar = new TarInputStream(gz, encod)) { TarEntry entry; while (null != (entry = tar.GetNextEntry())) { if (string.Empty != entry.Name) { list.Add(entry.Name); } } } } return(list); }
private void LayerEntriesDo(Action <string, TarEntry> layerConsumer) { using (TarInputStream input = new TarInputStream(Files.NewInputStream(imageTar.ToPath()))) { TarEntry imageEntry; while ((imageEntry = input.GetNextEntry()) != null) { string imageEntryName = imageEntry.Name; // assume all .tar.gz files are layers if (imageEntry.IsFile() && imageEntryName.EndsWith(".tar.gz", StringComparison.Ordinal)) { TarInputStream layer = new TarInputStream(new GZipStream(input, CompressionMode.Decompress)); TarEntry layerEntry; while ((layerEntry = layer.GetNextEntry()) != null) { layerConsumer(imageEntryName, layerEntry); } } } } }
private ArchiveEntry GetNextEntryTar() { TarInputStream tar_stream = (TarInputStream)archive_stream; TarEntry tar_entry; do { tar_entry = tar_stream.GetNextEntry(); } while (tar_entry != null && tar_entry.IsDirectory); // End of the entries; if (tar_entry == null) { return(null); } ArchiveEntry entry = new ArchiveEntry(); entry.Name = tar_entry.Name; entry.Modified = tar_entry.ModTime; entry.Size = tar_entry.Size; // Only index smaller subfiles, to avoid filling /tmp if (entry.Size > MAX_SINGLE_FILE) { Log.Debug("Skipping over large file {0} in {1}", entry.Name, Indexable.DisplayUri.ToString()); return(entry); } entry.TempFile = StoreStreamInTempFile(archive_stream, GetExtension(entry.Name), entry.Modified); if (entry.TempFile != null) { entry.MimeType = XdgMime.GetMimeType(entry.TempFile); } return(entry); }
public static long ReadFileOrDirectoryFromStream(Stream stream, string pathToWrite, bool overwrite = true, bool closeStreamWhenComplete = true) { var tar = new TarInputStream(stream); tar.IsStreamOwner = closeStreamWhenComplete; long bytesRead = 0; // we can't use the simple ExtractContents because we need to be overwrite aware, // so we iterate instead TarEntry entry; while ((entry = tar.GetNextEntry()) != null) { var extractPath = Path.Combine(pathToWrite, entry.Name); if (entry.IsDirectory) { // we don't have to worry about writing over directories Directory.CreateDirectory(extractPath); } else { // if overwrite is on, use Create FileMode. If not, use CreateNew, which will throw // an IO error if the file already exists. using (var fs = new FileStream(extractPath, overwrite ? FileMode.Create : FileMode.CreateNew)) { tar.CopyEntryContents(fs); bytesRead += entry.Size; } } } tar.Close(); return(bytesRead); }
/// <summary> /// Helper if no other way to get file count for progress meter /// </summary> /// <param name="filename"></param> /// <returns></returns> int GetTarGzFileCount(string filename) { int count = 0; using (var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read)) using (var gzipStream = new GZipInputStream(fileStream)) using (var memoryStream = new MemoryStream()) { var tarStream = new TarInputStream(gzipStream); TarEntry tarEntry; while ((tarEntry = tarStream.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } count++; } } Thread.Sleep(300);//give time for OS to close before full processing return(count); }
public void Checksum() { var ms = new MemoryStream(); using (var tarOut = new TarOutputStream(ms, nameEncoding: null)) { var entry = TarEntry.CreateTarEntry("TestEntry"); entry.TarHeader.Mode = 12345; tarOut.PutNextEntry(entry); } var ms2 = new MemoryStream(); ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms2.Seek(0, SeekOrigin.Begin); TarEntry nextEntry; using (var tarIn = new TarInputStream(ms2, nameEncoding: null)) { nextEntry = tarIn.GetNextEntry(); Assert.IsTrue(nextEntry.TarHeader.IsChecksumValid, "Checksum should be valid"); } var ms3 = new MemoryStream(); ms3.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); ms3.Seek(0, SeekOrigin.Begin); ms3.Write(new byte[] { 34 }, 0, 1); ms3.Seek(0, SeekOrigin.Begin); using (var tarIn = new TarInputStream(ms3, nameEncoding: null)) { Assert.Throws <TarException>(() => tarIn.GetNextEntry(), "Checksum should be invalid"); } }
/// <summary> /// Adds a layer around a stream that isolates the <code>data.tar.gz</code> file from a TAR stream. /// </summary> /// <param name="stream">The TAR stream.</param> /// <returns>A stream representing the <code>data.tar.gz</code> data.</returns> /// <exception cref="IOException">The compressed stream contains invalid data.</exception> private static Stream GetPartialStream(Stream stream) { try { var tar = new TarInputStream(stream); while (true) { var entry = tar.GetNextEntry(); if (entry == null) { throw new IOException(Resources.RubyGemInvalid); } if (entry.Name == "data.tar.gz") { return(tar); } } } #region Error handling catch (SharpZipBaseException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(Resources.ArchiveInvalid, ex); } catch (InvalidDataException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(Resources.ArchiveInvalid, ex); } catch (ArgumentOutOfRangeException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(Resources.ArchiveInvalid, ex); } #endregion }
public void Test() { var stream = GetArchiveStream(); using var archive = new TarInputStream(stream, Encoding.UTF8); var normal = archive.GetNextEntry(); normal.Name.Should().Be("normal"); normal.ModTime.Should().Be(TestFile.DefaultLastWrite); normal.TarHeader.Mode.Should().Be(TarExtractor.DefaultMode); var executable = archive.GetNextEntry(); executable.Name.Should().Be("executable"); executable.ModTime.Should().Be(TestFile.DefaultLastWrite); executable.TarHeader.Mode.Should().Be(TarExtractor.DefaultMode | TarExtractor.ExecuteMode); var symlink = archive.GetNextEntry(); symlink.Name.Should().Be("symlink"); symlink.TarHeader.TypeFlag.Should().Be(TarHeader.LF_SYMLINK); var hardlink = archive.GetNextEntry(); hardlink.Name.Should().Be("hardlink"); hardlink.TarHeader.TypeFlag.Should().Be(TarHeader.LF_LINK); hardlink.TarHeader.LinkName.Should().Be("normal"); var directory = archive.GetNextEntry(); directory.Name.Should().Be("dir"); directory.IsDirectory.Should().BeTrue(); directory.TarHeader.Mode.Should().Be(TarExtractor.DefaultMode | TarExtractor.ExecuteMode); var sub = archive.GetNextEntry(); sub.Name.Should().Be("dir/sub"); sub.ModTime.Should().Be(TestFile.DefaultLastWrite); sub.TarHeader.Mode.Should().Be(TarExtractor.DefaultMode); }
protected override bool _Run() { try { switch (TargetContainer) { case ContainerType.InstructionSetContainer: if (!InstructionSet.InstructionSetContainer.ContainsKey(ContainerDataKey)) { throw new Exception("ContainerDataKey (" + ContainerDataKey + ") does not exist."); } _BData = InstructionSet.InstructionSetContainer[ContainerDataKey] as byte[]; break; case ContainerType.Session: if (!STEM.Sys.State.Containers.Session.ContainsKey(ContainerDataKey)) { throw new Exception("ContainerDataKey (" + ContainerDataKey + ") does not exist."); } _BData = STEM.Sys.State.Containers.Session[ContainerDataKey] as byte[]; break; case ContainerType.Cache: if (!STEM.Sys.State.Containers.Cache.ContainsKey(ContainerDataKey)) { throw new Exception("ContainerDataKey (" + ContainerDataKey + ") does not exist."); } _BData = STEM.Sys.State.Containers.Cache[ContainerDataKey] as byte[]; break; } if (_BData == null || _BData.Length == 0) { throw new Exception("ContainerDataKey (" + ContainerDataKey + ") has no data."); } Dictionary <string, byte[]> tData = new Dictionary <string, byte[]>(); using (MemoryStream s = new MemoryStream(_BData)) { using (TarInputStream tStream = new TarInputStream(s)) { tStream.IsStreamOwner = false; TarEntry e = null; while ((e = tStream.GetNextEntry()) != null) { if (!e.IsDirectory && e.Size > 0) { using (MemoryStream o = new MemoryStream()) { tStream.CopyEntryContents(o); o.Position = 0; tData[e.Name] = o.GetBuffer().Take((int)e.Size).ToArray(); } } else { tData[e.Name] = null; } break; } } } switch (TargetContainer) { case ContainerType.InstructionSetContainer: InstructionSet.InstructionSetContainer[ContainerDataKey] = tData; break; case ContainerType.Session: STEM.Sys.State.Containers.Session[ContainerDataKey] = tData; break; case ContainerType.Cache: STEM.Sys.State.Containers.Cache[ContainerDataKey] = tData; break; } } catch (Exception ex) { AppendToMessage(ex.Message); Exceptions.Add(ex); } return(Exceptions.Count == 0); }
private static void ParseTAR(TarDirectory root, TarInputStream input, string fullPath) { Dictionary <string, byte[]> dictionary = new Dictionary <string, byte[]>(); List <TarEntry> list = new List <TarEntry>(); List <TarDirectory> list2 = new List <TarDirectory>(); byte[] buffer = new byte[16384]; try { using (MemoryStream memoryStream = new MemoryStream()) { TarEntry nextEntry; while ((nextEntry = input.GetNextEntry()) != null) { ReadTarEntryData(input, memoryStream, buffer); dictionary.Add(nextEntry.Name, memoryStream.ToArray()); list.Add(nextEntry); memoryStream.Position = 0L; memoryStream.SetLength(0L); } } list2.Add(root); foreach (TarEntry item in list.Where((TarEntry e) => e.IsDirectory && !string.IsNullOrEmpty(e.Name))) { string str = FormatFolderPath(item.Name); list2.Add(new TarDirectory(fullPath + "/" + str, str)); } foreach (TarEntry item2 in list.Where((TarEntry e) => !e.IsDirectory)) { string b = FormatFolderPath(Path.GetDirectoryName(item2.Name)); TarDirectory tarDirectory = null; foreach (TarDirectory item3 in list2) { if (item3.inArchiveFullPath == b) { tarDirectory = item3; break; } } tarDirectory.files.Add(new TarFile(dictionary[item2.Name], fullPath + "/" + item2.Name, Path.GetFileName(item2.Name))); } foreach (TarDirectory item4 in list2) { if (string.IsNullOrEmpty(item4.inArchiveFullPath)) { continue; } string b2 = FormatFolderPath(Path.GetDirectoryName(item4.inArchiveFullPath)); TarDirectory tarDirectory2 = null; foreach (TarDirectory item5 in list2) { if (item5.inArchiveFullPath == b2) { tarDirectory2 = item5; break; } } tarDirectory2.subDirectories.Add(item4); } } finally { input.Close(); } }
/// <inheritdoc/> public override void Extract(IBuilder builder, Stream stream, string?subDir = null) { var symlinks = new List <(string path, string target)>(); var hardlinks = new List <(string path, string existingPath, bool executable)>(); try { using var tarStream = new TarInputStream(stream, Encoding.UTF8) { IsStreamOwner = false }; while (tarStream.GetNextEntry() is {} entry) { Handler.CancellationToken.ThrowIfCancellationRequested(); string?relativePath = NormalizePath(entry.Name, subDir); if (string.IsNullOrEmpty(relativePath)) { continue; } switch (entry.TarHeader.TypeFlag) { case TarHeader.LF_SYMLINK: symlinks.Add((relativePath, entry.TarHeader.LinkName)); break; case TarHeader.LF_LINK: string?targetPath = NormalizePath(entry.TarHeader.LinkName, subDir); if (string.IsNullOrEmpty(targetPath)) { throw new IOException($"The hardlink '{relativePath}' in the archive points to a non-existent file '{entry.TarHeader.LinkName}'."); } hardlinks.Add((relativePath, targetPath, IsExecutable(entry))); break; case TarHeader.LF_DIR: builder.AddDirectory(relativePath); break; case TarHeader.LF_NORMAL or TarHeader.LF_OLDNORM: builder.AddFile(relativePath, tarStream.WithLength(entry.Size), entry.TarHeader.ModTime, IsExecutable(entry)); break; default: throw new NotSupportedException($"Archive entry '{entry.Name}' has unsupported type: {entry.TarHeader.TypeFlag}"); } } foreach ((string path, string target) in symlinks) { builder.AddSymlink(path, target); } foreach ((string path, string existingPath, bool executable) in hardlinks) builder.AddHardlink(path, existingPath, executable); } #region Error handling catch (Exception ex) when(ex is SharpZipBaseException or InvalidDataException or ArgumentOutOfRangeException or IndexOutOfRangeException or { Message: "Data Error" })
/// <summary> /// Updates the supplied registry from the supplied zip file. /// This will *clear* the registry of available modules first. /// This does not *save* the registry. For that, you probably want Repo.Update /// </summary> internal static void UpdateRegistryFromTarGz(string path, Registry registry) { log.DebugFormat("Starting registry update from tar.gz file: \"{0}\".", path); // Open the gzip'ed file. using (Stream inputStream = File.OpenRead(path)) { // Create a gzip stream. using (GZipInputStream gzipStream = new GZipInputStream(inputStream)) { // Create a handle for the tar stream. using (TarInputStream tarStream = new TarInputStream(gzipStream)) { // Walk the archive, looking for .ckan files. const string filter = @"\.ckan$"; while (true) { TarEntry entry = tarStream.GetNextEntry(); // Check for EOF. if (entry == null) { break; } string filename = entry.Name; // Skip things we don't want. if (!Regex.IsMatch(filename, filter)) { log.DebugFormat("Skipping archive entry {0}", filename); continue; } log.DebugFormat("Reading CKAN data from {0}", filename); // Read each file into a buffer. int buffer_size; try { buffer_size = Convert.ToInt32(entry.Size); } catch (OverflowException) { log.ErrorFormat("Error processing {0}: Metadata size too large.", entry.Name); continue; } byte[] buffer = new byte[buffer_size]; tarStream.Read(buffer, 0, buffer_size); // Convert the buffer data to a string. string metadata_json = Encoding.ASCII.GetString(buffer); ProcessRegistryMetadataFromJSON(metadata_json, registry, filename); } } } } }
/// <summary> /// Decompress the source file containing the categories and the content of the blacklisted sites. /// </summary> /// <returns>True if decompressing process success efectively, otherwise false.</returns> private bool decompressSourceFile() { // Set the currentOperation to "decompressingSourceFile" clsSettings.serviceSettings.currentOperation = operationList.decompressingSourceFile; bool result = false; // Form the FileInfo variable with the file to decompress. FileInfo fileInfo = new FileInfo(string.Format("{0}{1}", clsSettings.serviceSettings.dataDirectory, clsSettings.serviceSettings.downloadedFileName)); if (!fileInfo.Exists) { clsSettings.serviceSettings.currentOperation = operationList.waitingForNextExecution; clsLogProcessing.WriteToEventLog(string.Format("El estado de operaciones ha cambiado a \"{0}\", porque durante la " + "operación \"{1}\" no se encontró el recurso (fichero) \"{2}\" como se esperaba, para ejecutar la descompresión " + "del mismo. Si esta es la primera vez que observa este error no se requiere intervención alguna por parte del usuario. " + "El sistema se encargará de procesar todas las operaciones desde el principio para obtener el fichero correspondiente.", operationList.waitingForNextExecution, operationList.decompressingSourceFile, fileInfo.FullName), EventLogEntryType.Error); return(false); } Stream inStream = File.OpenRead(fileInfo.FullName); // Extract try { // Extract TAR, GZipped File. TarArchive tarGZippedArchive = TarArchive.CreateInputTarArchive(new GZipStream(inStream, CompressionMode.Decompress)); tarGZippedArchive.ExtractContents(clsSettings.serviceSettings.dataDirectory.FullName); // Do some cleanup. tarGZippedArchive.Close(); if (tarGZippedArchive != null) { tarGZippedArchive = null; } result = true; } catch (System.Exception) { // Sometimes the file is opened weith decompressing software (sach as WinRar) and from that momento it's not a GZipped file anymore. // Extract TAR File /* THIS DOES NOT WORK. * TarArchive tarArchive = TarArchive.CreateInputTarArchive(inStream); * tarArchive.ExtractContents(clsSettings.serviceSettings.dataDirectory.FullName); * tarArchive.Close(); */ using (FileStream fsIn = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read)) { // The TarInputStream reads a UNIX tar archive as an InputStream. TarInputStream tarIn = new TarInputStream(fsIn); TarEntry tarEntry; while ((tarEntry = tarIn.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } // Converts the unix forward slashes in the filenames to windows backslashes. string name = tarEntry.Name.Replace('/', Path.DirectorySeparatorChar); // Apply further name transformations here as necessary string outName = Path.Combine(clsSettings.serviceSettings.dataDirectory.FullName, name); string directoryName = Path.GetDirectoryName(outName); Directory.CreateDirectory(directoryName); FileStream outStr = new FileStream(outName, FileMode.Create); tarIn.CopyEntryContents(outStr); // Do some cleanup. outStr.Close(); if (outStr != null) { outStr = null; } } // Do some cleanup. if (tarIn != null) { tarIn.Close(); tarIn = null; } if (fsIn != null) { fsIn.Close(); } } result = true; } finally { if (inStream != null) { inStream.Close(); inStream = null; } } return(result); }
/// <inheritdoc/> protected override void Execute() { State = TaskState.Data; try { if (!Directory.Exists(EffectiveTargetDir)) { Directory.CreateDirectory(EffectiveTargetDir); } TarEntry entry; while ((entry = _tarStream.GetNextEntry()) != null) { string relativePath = GetRelativePath(entry.Name); if (string.IsNullOrEmpty(relativePath)) { continue; } if (entry.IsDirectory) { CreateDirectory(relativePath, entry.TarHeader.ModTime); } else if (entry.TarHeader.TypeFlag == TarHeader.LF_LINK) { CreateHardlink(relativePath, entry.TarHeader.LinkName); } else if (entry.TarHeader.TypeFlag == TarHeader.LF_SYMLINK) { CreateSymlink(relativePath, entry.TarHeader.LinkName); } else { WriteFile(relativePath, entry.Size, entry.TarHeader.ModTime, _tarStream, IsExecutable(entry)); } UpdateProgress(); } SetDirectoryWriteTimes(); } #region Error handling catch (SharpZipBaseException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(Resources.ArchiveInvalid, ex); } catch (InvalidDataException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(Resources.ArchiveInvalid, ex); } catch (ArgumentOutOfRangeException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(Resources.ArchiveInvalid, ex); } #endregion State = TaskState.Complete; }
/// <summary> /// Extracts the tared files from the archive. /// NOTE: This is not the file last modified date but if the file has been modified then it /// should be later than any UnTared file date. /// </summary> /// <param name="dataFolder"> /// The data folder. /// </param> /// <param name="tarIn"> /// The tar in. /// </param> /// <param name="asciiTranslate"> /// if set to <c>true</c> [ASCII translate]. /// </param> /// <returns> /// True if the file is UnTARed correctly. /// </returns> public async Task ExtractTarIfNotModified(TarInputStream tarIn, bool asciiTranslate) { if (tarIn is null) { throw new ArgumentNullException(nameof(tarIn)); } TarEntry tarEntry = null; //FileInfo outFile = null; try { while ((tarEntry = tarIn.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } // Debug.WriteLine("Untaring " + tarEntry.Name); string outFileName = Path.GetFileName(tarEntry.Name); // Converts the unix forward slashes in the filenames to windows backslashes string tarName = tarEntry.Name.Replace('/', Path.DirectorySeparatorChar); // Remove any root e.g. '\' because a PathRooted filename defeats Path.Combine if (Path.IsPathRooted(tarName)) { tarName = tarName.Substring(Path.GetPathRoot(tarName).Length); } // Apply further name transformations here as necessary string filename = Path.GetFileName(tarName); string outName = Path.Combine(DataStore.AD.CurrentDataFolder.FullName, tarName); string relativePath = Path.GetDirectoryName(tarEntry.Name); string directoryName = Path.GetDirectoryName(outName); DirectoryInfo newFolder = null; if (relativePath.Length > 0) { newFolder = Directory.CreateDirectory(Path.Combine(DataStore.AD.CurrentDataFolder.FullName, relativePath)); } else { newFolder = DataStore.AD.CurrentDataFolder; } // Check if the folder was created successfully. if (newFolder == null) { // Skip this file. continue; } // Check file modification date if it exists bool okToCopyFlag = true; //// Android uses mimetypes and a type for .gramps files is not in the list TODO //// work how how to add it to the list .gramps are .gz to just rename for now //if (filename == "data.gramps") //{ // filename = CommonConstants.StorageGRAMPSFileName; //} // if tarEntry modtime is less than outFile datemodified // NOTE: This is not the file last modified date but if the file has been // modified then it should be later than any UnTared file date if (await StoreFolder.FolderFileExistsAsync(newFolder, filename).ConfigureAwait(false)) { FileInfoEx newFileName = await StoreFolder.FolderGetFileAsync(newFolder, filename).ConfigureAwait(false); //if (filename == "1024x768.png") //{ //} if (newFileName.Valid) { // TODO Check this compare date and tiem TODO Add delete existing files // option before extract if (tarEntry.ModTime.CompareTo(newFileName.FInfo.LastAccessTime) < 0) { okToCopyFlag = false; } if (newFileName.FInfo.LastWriteTimeUtc == tarEntry.ModTime) { okToCopyFlag = false; } } } if (okToCopyFlag) { if (filename == CommonConstants.StorageGRAMPSFileName) { } await DataStore.CN.ChangeLoadingMessage("Untaring file " + tarEntry.Name).ConfigureAwait(false); Stream outStr = await StoreFolder.FolderCreateFileAsync(newFolder, filename).ConfigureAwait(false); if (asciiTranslate) { CopyWithAsciiTranslate(tarIn, outStr); } else { tarIn.CopyEntryContents(outStr); } outStr.Flush(); outStr.Dispose(); // TODO check of modification date kept Set the modification date/time. This // approach seems to solve timezone issues. // outFile = await newFolder.TryGetItemAsync(filename); //// StorageFile tt = await newFolder.GetFileAsync(filename); // IDictionary<string, object> ttt = await // tt.Properties.RetrievePropertiesAsync(new List<string> { }); // foreach (var item in ttt) { Debug.WriteLine(item); } // BasicProperties outFileProperties = await outFile.GetBasicPropertiesAsync(); // var fileProperties = await file.Properties.RetrievePropertiesAsync( new // List { "System.GPS.Latitude", "System.GPS.Longitude" }); // var fileProperties = await outFileProperties.RetrievePropertiesAsync(new // List { }); // var propertyToSave = new List> { new // KeyValuePair("System.Photo.LensManufacturer", "Pentax") }; // await file.Properties.SavePropertiesAsync(propertyToSave); // var changes = new List<KeyValuePair<string, object>>(); // DateTime modDate = tarEntry.ModTime; // PropertySet t4 = new PropertySet(); // t4.Add("DateModified", modDate); // changes.Add(new KeyValuePair<string, object>("System.ExpandoProperties", t4)); // await tt.Properties.SavePropertiesAsync(changes); // changes.Add(new KeyValuePair<string, object>("System.ExpandoProperties", modDate)); // await tt.Properties.SavePropertiesAsync(ttt); // DateTime myDt = DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc); // t = null; // File.SetLastWriteTime(outName, modDate); // .SetLastWriteTime(t.CreateSafeFileHandle(), modDate); } else { // TODO write to the output log // await DataStore.CN.MinorStatusAdd("File " // + tarEntry.Name + " does not need to be unTARed as its modified date is // earlier than the one in the output folder").ConfigureAwait(false); } // Check file ceated successfully bool checkFileExistsFlag = await StoreFolder.FolderFileExistsAsync(newFolder, filename).ConfigureAwait(false); if (!checkFileExistsFlag) { DataStore.CN.NotifyError("Error UnTaring file: " + newFolder.FullName + "-" + filename + ". File not created. Perhaps the path is too long?"); // TODO copy dummy file in its place } } } catch (Exception ex) { // Handle disk full errors const int HR_ERROR_HANDLE_DISK_FULL = unchecked ((int)0x80070027); const int HR_ERROR_DISK_FULL = unchecked ((int)0x80070070); if (ex.HResult == HR_ERROR_HANDLE_DISK_FULL || ex.HResult == HR_ERROR_DISK_FULL) { DataStore.CN.NotifyException("UnTar Disk Full Exception working on " + tarEntry.Name, ex); } // Handle other errors if (tarEntry != null) { DataStore.CN.NotifyException("UnTar Exception working on " + tarEntry.Name, ex); throw; } else { DataStore.CN.NotifyException("UnTar tarEntry null Exception ", ex); throw; } } }
public static async Task UpdateRyujinx(UpdateDialog updateDialog, string downloadUrl) { // Empty update dir, although it shouldn't ever have anything inside it if (Directory.Exists(UpdateDir)) { Directory.Delete(UpdateDir, true); } Directory.CreateDirectory(UpdateDir); string updateFile = Path.Combine(UpdateDir, "update.bin"); // Download the update .zip updateDialog.MainText.Text = "Downloading Update..."; updateDialog.ProgressBar.Value = 0; updateDialog.ProgressBar.MaxValue = 100; using (WebClient client = new WebClient()) { client.DownloadProgressChanged += (_, args) => { updateDialog.ProgressBar.Value = args.ProgressPercentage; }; await client.DownloadFileTaskAsync(downloadUrl, updateFile); } // Extract Update updateDialog.MainText.Text = "Extracting Update..."; updateDialog.ProgressBar.Value = 0; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { using (Stream inStream = File.OpenRead(updateFile)) using (Stream gzipStream = new GZipInputStream(inStream)) using (TarInputStream tarStream = new TarInputStream(gzipStream)) { updateDialog.ProgressBar.MaxValue = inStream.Length; await Task.Run(() => { TarEntry tarEntry; while ((tarEntry = tarStream.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } string outPath = Path.Combine(UpdateDir, tarEntry.Name); Directory.CreateDirectory(Path.GetDirectoryName(outPath)); using (FileStream outStream = File.OpenWrite(outPath)) { tarStream.CopyEntryContents(outStream); } File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc)); TarEntry entry = tarEntry; Application.Invoke(delegate { updateDialog.ProgressBar.Value += entry.Size; }); } }); updateDialog.ProgressBar.Value = inStream.Length; } } else { using (Stream inStream = File.OpenRead(updateFile)) using (ZipFile zipFile = new ZipFile(inStream)) { updateDialog.ProgressBar.MaxValue = zipFile.Count; await Task.Run(() => { foreach (ZipEntry zipEntry in zipFile) { if (zipEntry.IsDirectory) { continue; } string outPath = Path.Combine(UpdateDir, zipEntry.Name); Directory.CreateDirectory(Path.GetDirectoryName(outPath)); using (Stream zipStream = zipFile.GetInputStream(zipEntry)) using (FileStream outStream = File.OpenWrite(outPath)) { zipStream.CopyTo(outStream); } File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc)); Application.Invoke(delegate { updateDialog.ProgressBar.Value++; }); } }); } } // Delete downloaded zip File.Delete(updateFile); string[] allFiles = Directory.GetFiles(HomeDir, "*", SearchOption.AllDirectories); updateDialog.MainText.Text = "Renaming Old Files..."; updateDialog.ProgressBar.Value = 0; updateDialog.ProgressBar.MaxValue = allFiles.Length; // Replace old files await Task.Run(() => { foreach (string file in allFiles) { if (!Path.GetExtension(file).Equals(".log")) { try { File.Move(file, file + ".ryuold"); Application.Invoke(delegate { updateDialog.ProgressBar.Value++; }); } catch { Logger.Warning?.Print(LogClass.Application, "Updater wasn't able to rename file: " + file); } } } Application.Invoke(delegate { updateDialog.MainText.Text = "Adding New Files..."; updateDialog.ProgressBar.Value = 0; updateDialog.ProgressBar.MaxValue = Directory.GetFiles(UpdatePublishDir, "*", SearchOption.AllDirectories).Length; }); MoveAllFilesOver(UpdatePublishDir, HomeDir, updateDialog); }); Directory.Delete(UpdateDir, true); updateDialog.MainText.Text = "Update Complete!"; updateDialog.SecondaryText.Text = "Do you want to restart Ryujinx now?"; updateDialog.Modal = true; updateDialog.ProgressBar.Hide(); updateDialog.YesButton.Show(); updateDialog.NoButton.Show(); }
public string FetchSnow(DateTime date, bool masked) { string url = makeURL(date, masked); string localFile = url.Substring(url.LastIndexOf("/") + 1); FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(url); FtpWebResponse ftpResponse = null; try { ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); } catch { throw new WebException("Cannot download file: " + url); } Stream ftpStream = null; int bufferSize = 2048; ftpStream = ftpResponse.GetResponseStream(); /* Open a File Stream to Write the Downloaded File */ FileStream localFileStream = new FileStream(localFile, FileMode.Create); /* Buffer for the Downloaded Data */ byte[] byteBuffer = new byte[bufferSize]; int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); /* Download the File by Writing the Buffered Data Until the Transfer is Complete */ try { while (bytesRead > 0) { localFileStream.Write(byteBuffer, 0, bytesRead); bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } /* Resource Cleanup */ localFileStream.Close(); ftpStream.Close(); ftpResponse.Close(); ftpRequest = null; string datFileName = null; string hdrFileName = null; //now untar the required files //the mask character indicates whether the data is whole area or u.s //only. string mask = "zz"; if (masked) { mask = "us"; } string sweStart = String.Format("{0}_ssmv11034tS__T0001TTNATS{1}{2}", mask, date.Year.ToString(), date.Month.ToString("00")); using (FileStream fsIn = new FileStream(localFile, FileMode.Open, FileAccess.Read)) { TarInputStream tarIn = new TarInputStream(fsIn); TarEntry tarEntry; while ((tarEntry = tarIn.GetNextEntry()) != null) { string tarEntryName = tarEntry.Name; if (tarEntryName.Contains(sweStart)) { FileStream outStr = new FileStream(tarEntryName, FileMode.Create); tarIn.CopyEntryContents(outStr); outStr.Close(); string unzippedFile = ExtractGZip(tarEntryName); if (unzippedFile.ToLower().EndsWith("dat")) { datFileName = unzippedFile; } if (unzippedFile.ToLower().EndsWith("hdr")) { hdrFileName = unzippedFile; } } } } return(datFileName); }
/// <summary> /// Returns available modules from the supplied tar.gz file. /// </summary> private static List <CkanModule> UpdateRegistryFromTarGz(string path, out SortedDictionary <string, int> downloadCounts) { log.DebugFormat("Starting registry update from tar.gz file: \"{0}\".", path); downloadCounts = null; List <CkanModule> modules = new List <CkanModule>(); // Open the gzip'ed file. using (Stream inputStream = File.OpenRead(path)) { // Create a gzip stream. using (GZipInputStream gzipStream = new GZipInputStream(inputStream)) { // Create a handle for the tar stream. using (TarInputStream tarStream = new TarInputStream(gzipStream)) { // Walk the archive, looking for .ckan files. const string filter = @"\.ckan$"; while (true) { TarEntry entry = tarStream.GetNextEntry(); // Check for EOF. if (entry == null) { break; } string filename = entry.Name; if (filename.EndsWith("download_counts.json")) { downloadCounts = JsonConvert.DeserializeObject <SortedDictionary <string, int> >( tarStreamString(tarStream, entry) ); continue; } else if (!Regex.IsMatch(filename, filter)) { // Skip things we don't want. log.DebugFormat("Skipping archive entry {0}", filename); continue; } log.DebugFormat("Reading CKAN data from {0}", filename); // Read each file into a buffer. string metadata_json = tarStreamString(tarStream, entry); CkanModule module = ProcessRegistryMetadataFromJSON(metadata_json, filename); if (module != null) { modules.Add(module); } } } } } return(modules); }
static ResourcesClass() { using (MemoryStream memStream = new MemoryStream(PatcherLib.Resources.Properties.Resources.ZippedResources, false)) using (GZipInputStream gzStream = new GZipInputStream(memStream)) using (TarInputStream tarStream = new TarInputStream(gzStream)) { var tempDefault = new Dictionary <string, IList <byte> >(); TarEntry entry; entry = tarStream.GetNextEntry(); while (entry != null) { if (entry.Size != 0) { byte[] bytes = new byte[entry.Size]; StreamUtils.ReadFully(tarStream, bytes); tempDefault[entry.Name] = bytes.AsReadOnly(); } entry = tarStream.GetNextEntry(); } DefaultZipFileContents = new PatcherLib.Datatypes.ReadOnlyDictionary <string, IList <byte> >(tempDefault); } string defaultsFile = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "Resources.zip"); if (File.Exists(defaultsFile)) { var tempContents = new Dictionary <string, IList <byte> >(); try { using (FileStream file = File.Open(defaultsFile, FileMode.Open, FileAccess.Read)) using (ZipInputStream zipStream = new ZipInputStream(file)) { ZipEntry entry = zipStream.GetNextEntry(); while (entry != null) { if (entry.Size != 0) { byte[] bytes = new byte[entry.Size]; StreamUtils.ReadFully(zipStream, bytes); tempContents[entry.Name] = bytes.AsReadOnly(); } entry = zipStream.GetNextEntry(); } foreach (KeyValuePair <string, IList <byte> > kvp in DefaultZipFileContents) { if (!tempContents.ContainsKey(kvp.Key)) { tempContents[kvp.Key] = kvp.Value; } } } ZipFileContents = new PatcherLib.Datatypes.ReadOnlyDictionary <string, IList <byte> >(tempContents); } catch (Exception) { ZipFileContents = DefaultZipFileContents; } } else { ZipFileContents = DefaultZipFileContents; } abilityFormulasDoc = ZipFileContents[Paths.AbilityFormulasXML].ToUTF8String().ToXmlDocument(); }
public static async Task <bool> Unpack(IFile file, IFolder folder, string name) { try { using (Stream s = await file.OpenAsync(FileAccess.Read)) { using (ZipFile zf = new ZipFile(s)) { IFolder target = await folder.CreateFolderAsync(name, CreationCollisionOption.GenerateUniqueName); zf.IsStreamOwner = true; foreach (ZipEntry entry in zf) { if (!entry.IsFile) { continue; } using (Stream ss = zf.GetInputStream(entry)) await Extract(ss, target, entry.Name); } return(true); } } } catch (Exception) { } try { using (Stream s = await file.OpenAsync(FileAccess.Read)) { using (TarInputStream zf = new TarInputStream(s)) { IFolder target = await folder.CreateFolderAsync(name, CreationCollisionOption.GenerateUniqueName); zf.IsStreamOwner = true; while (true) { TarEntry entry = zf.GetNextEntry(); if (entry == null) { break; } await Extract(zf, target, entry.Name); } return(true); } } } catch (Exception) { } try { using (Stream s = await file.OpenAsync(FileAccess.Read)) { using (BZip2InputStream zf = new BZip2InputStream(s)) { zf.IsStreamOwner = true; IFile target = await folder.CreateFileAsync(name, CreationCollisionOption.GenerateUniqueName); using (var stream = await target.OpenAsync(FileAccess.ReadAndWrite)) zf.CopyTo(stream); return(true); } } } catch (Exception) { } try { using (Stream s = await file.OpenAsync(FileAccess.Read)) { using (GZipInputStream zf = new GZipInputStream(s)) { zf.IsStreamOwner = true; IFile target = await folder.CreateFileAsync(name, CreationCollisionOption.GenerateUniqueName); using (var stream = await target.OpenAsync(FileAccess.ReadAndWrite)) zf.CopyTo(stream); return(true); } } } catch (Exception) { } return(false); }
/// <summary> /// Update sampctl /// </summary> /// <returns>"true" if sampctl is up to date, otherwise "false"</returns> public static bool Update() { bool ret = false; if (lastReleaseInfo == null) { if (File.Exists(SAMPCTLInfoPath)) { try { using (FileStream stream = File.Open(SAMPCTLInfoPath, FileMode.Open)) { lastReleaseInfo = serializer.ReadObject(stream) as GitHubLatestReleaseDataContract; } } catch (Exception e) { MessageBox.Show(e.Message, Translator.GetTranslation("SAMPCTL_ERROR_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); } } } if (latestReleaseInfo == null) { using (WebClientEx wc = new WebClientEx(3000)) { wc.Headers.Set(HttpRequestHeader.Accept, "application/json"); wc.Headers.Set(HttpRequestHeader.UserAgent, "Mozilla/3.0 (compatible; SA:MP launcher .NET)"); try { using (MemoryStream stream = new MemoryStream(wc.DownloadData(GitHubAPIURI))) { latestReleaseInfo = serializer.ReadObject(stream) as GitHubLatestReleaseDataContract; } } catch (Exception e) { MessageBox.Show(e.Message, Translator.GetTranslation("SAMPCTL_ERROR_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); } } } if (latestReleaseInfo != null) { bool download_file = ((lastReleaseInfo == null) ? true : ((lastReleaseInfo.TagName == latestReleaseInfo.TagName) ? (!(File.Exists(SAMPCTLDownloadPath))) : true)); if (download_file) { GitHubReleaseAssetDataContract asset = null; string sub_name = (Environment.Is64BitOperatingSystem ? "windows_amd64" : "windows_386"); foreach (GitHubReleaseAssetDataContract a in latestReleaseInfo.Assets) { if (a.Name.Contains(sub_name)) { asset = a; break; } } if (asset == null) { MessageBox.Show(Translator.GetTranslation("SAMPCTL_MISSING_ASSET"), Translator.GetTranslation("SAMPCTL_ERROR_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); } else { DownloadProgressForm dpf = new DownloadProgressForm(asset.BrowserDownloadURL, SAMPCTLArchiveFileName); ret = (dpf.ShowDialog() == DialogResult.OK); } } else { ret = true; } if (ret && (download_file ? true : (!(File.Exists(SAMPCTLPath))))) { try { if (File.Exists(SAMPCTLDownloadPath)) { using (FileStream archive_file_stream = File.Open(SAMPCTLDownloadPath, FileMode.Open)) { using (GZipInputStream gzip_stream = new GZipInputStream(archive_file_stream)) { using (TarInputStream tar_stream = new TarInputStream(gzip_stream)) { TarEntry tar_entry; while ((tar_entry = tar_stream.GetNextEntry()) != null) { if (!(tar_entry.IsDirectory)) { if (tar_entry.Name == SAMPCTLFileName) { if (File.Exists(SAMPCTLPath)) { File.Delete(SAMPCTLPath); } using (FileStream file_stream = File.Open(SAMPCTLPath, FileMode.Create)) { tar_stream.CopyEntryContents(file_stream); ret = true; } break; } } } } } } } else { ret = false; } if (!ret) { MessageBox.Show(Translator.GetTranslation("SAMPCTL_UNZIP_ERROR"), Translator.GetTranslation("SAMPCTL_ERROR_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception e) { MessageBox.Show(e.Message, Translator.GetTranslation("SAMPCTL_ERROR_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); } if (ret) { try { if (File.Exists(SAMPCTLInfoPath)) { File.Delete(SAMPCTLInfoPath); } using (FileStream stream = File.Open(SAMPCTLInfoPath, FileMode.Create)) { serializer.WriteObject(stream, latestReleaseInfo); } } catch (Exception e) { ret = false; MessageBox.Show(e.Message, Translator.GetTranslation("SAMPCTL_ERROR_TITLE"), MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } else { ret = true; } return(ret); }
/// <summary> /// /// </summary> /// <param name="driveLetter"></param> /// <param name="fileName"></param> /// <param name="eCompType"></param> /// <returns></returns> public bool WriteDrive(string driveLetter, string fileName, EnumCompressionType eCompType) { IsCancelling = false; var dtStart = DateTime.Now; if (!File.Exists(fileName)) { throw new ArgumentException(fileName + " doesn't exist"); } // // Get physical drive partition for logical partition // var physicalDrive = _diskAccess.GetPhysicalPathForLogicalPath(driveLetter); if (string.IsNullOrEmpty(physicalDrive)) { LogMsg(@"Error: Couldn't map partition to physical drive"); _diskAccess.UnlockDrive(); return(false); } // // Lock logical drive // var success = _diskAccess.LockDrive(driveLetter); if (!success) { LogMsg(@"Failed to lock drive"); return(false); } // // Get drive size // var driveSize = _diskAccess.GetDriveSize(physicalDrive); if (driveSize <= 0) { LogMsg(@"Failed to get device size"); _diskAccess.UnlockDrive(); return(false); } // // Open the physical drive // var physicalHandle = _diskAccess.Open(physicalDrive); if (physicalHandle == null) { LogMsg(@"Failed to open physical drive"); _diskAccess.UnlockDrive(); return(false); } var buffer = new byte[Globals.MaxBufferSize]; long offset = 0; var fileLength = new FileInfo(fileName).Length; var uncompressedlength = fileLength; var errored = true; using (var basefs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { Stream fs; switch (eCompType) { case EnumCompressionType.Zip: { var zipFile = new ZipFile(basefs); var ze = (from ZipEntry zipEntry in zipFile where zipEntry.IsFile select zipEntry).FirstOrDefault(); if (ze == null) { LogMsg(@"Error reading zip input stream"); goto readfail2; } var zis = zipFile.GetInputStream(ze); uncompressedlength = ze.Size; fs = zis; } break; case EnumCompressionType.Gzip: { var gzis = new GZipInputStream(basefs) { IsStreamOwner = true }; uncompressedlength = gzis.Length; fs = gzis; } break; case EnumCompressionType.Targzip: { var gzos = new GZipInputStream(basefs) { IsStreamOwner = true }; var tis = new TarInputStream(gzos); TarEntry tarEntry; do { tarEntry = tis.GetNextEntry(); } while (tarEntry.IsDirectory); uncompressedlength = tarEntry.Size; fs = tis; } break; default: // No compression - direct to file stream fs = basefs; uncompressedlength = fs.Length; break; } var bufferOffset = 0; using (var br = new BinaryReader(fs)) { while (offset < uncompressedlength && !IsCancelling) { // Note: There's a problem writing certain lengths to the underlying physical drive. // This appears when we try to read from a compressed stream as it gives us // "strange" lengths which then fail to be written via Writefile() so try to build // up a decent block of bytes here... int readBytes; do { readBytes = br.Read(buffer, bufferOffset, buffer.Length - bufferOffset); bufferOffset += readBytes; } while (bufferOffset < Globals.MaxBufferSize && readBytes != 0); int wroteBytes; var bytesToWrite = bufferOffset; var trailingBytes = 0; // Assume that the underlying physical drive will at least accept powers of two! if (!IsPowerOfTwo((ulong)bufferOffset)) { // Find highest bit (32-bit max) var highBit = 31; for (; ((bufferOffset & (1 << highBit)) == 0) && highBit >= 0; highBit--) { ; } // Work out trailing bytes after last power of two var lastPowerOf2 = 1 << highBit; bytesToWrite = lastPowerOf2; trailingBytes = bufferOffset - lastPowerOf2; } if (_diskAccess.Write(buffer, bytesToWrite, out wroteBytes) < 0) { LogMsg(@"Error writing data to drive: " + Marshal.GetHRForLastWin32Error()); goto readfail1; } if (wroteBytes != bytesToWrite) { LogMsg(@"Error writing data to drive - past EOF?"); goto readfail1; } // Move trailing bytes up - Todo: Suboptimal if (trailingBytes > 0) { Buffer.BlockCopy(buffer, bufferOffset - trailingBytes, buffer, 0, trailingBytes); bufferOffset = trailingBytes; } else { bufferOffset = 0; } offset += (uint)wroteBytes; var percentDone = (int)(100 * offset / uncompressedlength); var tsElapsed = DateTime.Now.Subtract(dtStart); var bytesPerSec = offset / tsElapsed.TotalSeconds; Progress(percentDone); LogMsg(@"Wrote " + percentDone + @"%, " + (offset / (1024 * 1024)) + @" MB / " + (uncompressedlength / (1024 * 1024) + " MB, " + string.Format("{0:F}", (bytesPerSec / (1024 * 1024))) + @" MB/sec, Elapsed time: " + tsElapsed.ToString(@"dd\.hh\:mm\:ss"))); } } } errored = false; readfail1: _diskAccess.Close(); readfail2: _diskAccess.UnlockDrive(); var tstotalTime = DateTime.Now.Subtract(dtStart); if (IsCancelling) { LogMsg("Cancelled"); } else { LogMsg("All Done - Wrote " + offset + " bytes. Elapsed time " + tstotalTime.ToString(@"dd\.hh\:mm\:ss")); } Progress(0); return(!errored); }
protected override void _Rollback() { try { if (_Files.Count > 0) { using (FileStream fs = File.Open(OutputFile, FileMode.Open, FileAccess.Read, FileShare.None)) { using (TarInputStream tStream = new TarInputStream(fs)) { tStream.IsStreamOwner = false; TarEntry e = null; while ((e = tStream.GetNextEntry()) != null) { if (!e.IsDirectory) { try { string file = _Files[e.Name]; if (!File.Exists(file)) { if (!Directory.Exists(STEM.Sys.IO.Path.GetDirectoryName(file))) { Directory.CreateDirectory(STEM.Sys.IO.Path.GetDirectoryName(file)); } using (FileStream s = File.Open(file, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None)) { tStream.CopyEntryContents(s); } File.SetLastWriteTimeUtc(file, e.ModTime); } } catch { } } else { try { if (!Directory.Exists(Path.Combine(SourcePath, e.Name))) { Directory.CreateDirectory(Path.Combine(SourcePath, e.Name)); } } catch { } } } } } if (File.Exists(OutputFile)) { File.Delete(OutputFile); } } } catch (Exception ex) { AppendToMessage(ex.ToString()); Exceptions.Add(ex); } }
private static async void InstallUpdate(UpdateDialog updateDialog, string updateFile) { // Extract Update updateDialog.MainText.Text = "Extracting Update..."; updateDialog.ProgressBar.Value = 0; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { using (Stream inStream = File.OpenRead(updateFile)) using (Stream gzipStream = new GZipInputStream(inStream)) using (TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII)) { updateDialog.ProgressBar.MaxValue = inStream.Length; await Task.Run(() => { TarEntry tarEntry; while ((tarEntry = tarStream.GetNextEntry()) != null) { if (tarEntry.IsDirectory) { continue; } string outPath = Path.Combine(UpdateDir, tarEntry.Name); Directory.CreateDirectory(Path.GetDirectoryName(outPath)); using (FileStream outStream = File.OpenWrite(outPath)) { tarStream.CopyEntryContents(outStream); } File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc)); TarEntry entry = tarEntry; Application.Invoke(delegate { updateDialog.ProgressBar.Value += entry.Size; }); } }); updateDialog.ProgressBar.Value = inStream.Length; } } else { using (Stream inStream = File.OpenRead(updateFile)) using (ZipFile zipFile = new ZipFile(inStream)) { updateDialog.ProgressBar.MaxValue = zipFile.Count; await Task.Run(() => { foreach (ZipEntry zipEntry in zipFile) { if (zipEntry.IsDirectory) { continue; } string outPath = Path.Combine(UpdateDir, zipEntry.Name); Directory.CreateDirectory(Path.GetDirectoryName(outPath)); using (Stream zipStream = zipFile.GetInputStream(zipEntry)) using (FileStream outStream = File.OpenWrite(outPath)) { zipStream.CopyTo(outStream); } File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc)); Application.Invoke(delegate { updateDialog.ProgressBar.Value++; }); } }); } } // Delete downloaded zip File.Delete(updateFile); List <string> allFiles = EnumerateFilesToDelete().ToList(); updateDialog.MainText.Text = "Renaming Old Files..."; updateDialog.ProgressBar.Value = 0; updateDialog.ProgressBar.MaxValue = allFiles.Count; // Replace old files await Task.Run(() => { foreach (string file in allFiles) { try { File.Move(file, file + ".ryuold"); Application.Invoke(delegate { updateDialog.ProgressBar.Value++; }); } catch { Logger.Warning?.Print(LogClass.Application, "Updater was unable to rename file: " + file); } } Application.Invoke(delegate { updateDialog.MainText.Text = "Adding New Files..."; updateDialog.ProgressBar.Value = 0; updateDialog.ProgressBar.MaxValue = Directory.GetFiles(UpdatePublishDir, "*", SearchOption.AllDirectories).Length; }); MoveAllFilesOver(UpdatePublishDir, HomeDir, updateDialog); }); Directory.Delete(UpdateDir, true); SetUnixPermissions(); updateDialog.MainText.Text = "Update Complete!"; updateDialog.SecondaryText.Text = "Do you want to restart Ryujinx now?"; updateDialog.Modal = true; updateDialog.ProgressBar.Hide(); updateDialog.YesButton.Show(); updateDialog.NoButton.Show(); }