// Temporary hack in place to build with GAC'd SharpZipLib on Windows static void SetAsciiTranslate(TarArchive archive) { #if WIN32 archive.SetAsciiTranslation(false); #else archive.AsciiTranslate = false; #endif }
/// <summary> /// Creates the tar file. /// </summary> protected override void ExecuteTask() { TarArchive archive = null; Stream outstream = null; Log(Level.Info, "Tarring {0} files to '{1}'.", TarFileSets.FileCount, DestFile.FullName); try { outstream = File.Create(DestFile.FullName); // wrap outputstream with corresponding compression method switch (CompressionMethod) { case TarCompressionMethod.GZip: outstream = new GZipOutputStream(outstream); break; case TarCompressionMethod.BZip2: outstream = new BZip2OutputStream(outstream); break; } // create tar archive archive = TarArchive.CreateOutputTarArchive(outstream, TarBuffer.DefaultBlockFactor); // do not use convert line endings of text files to \n, as this // converts all content to ASCII archive.SetAsciiTranslation(false); // process all filesets foreach (TarFileSet fileset in TarFileSets) { string basePath = fileset.BaseDirectory.FullName; if (Path.GetPathRoot(basePath) != basePath) { basePath = Path.GetDirectoryName(basePath + Path.DirectorySeparatorChar); } // add files to tar foreach (string file in fileset.FileNames) { // ensure file exists (in case "asis" was used) if (!File.Exists(file)) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, "File '{0}' does not exist.", file), Location); } // the filename of the tar entry string entryFileName; // the directory of the tar entry string entryDirName = string.Empty; // determine name of the tar entry if (file.StartsWith(basePath)) { entryFileName = file.Substring(basePath.Length); if (entryFileName.Length > 0 && entryFileName[0] == Path.DirectorySeparatorChar) { entryFileName = entryFileName.Substring(1); } // get directory part of entry entryDirName = Path.GetDirectoryName(entryFileName); // ensure directory separators are understood on linux if (Path.DirectorySeparatorChar == '\\') { entryDirName = entryDirName.Replace(@"\", "/"); } // get filename part of entry entryFileName = Path.GetFileName(entryFileName); } else { entryFileName = Path.GetFileName(file); } // add prefix if specified if (fileset.Prefix != null) { entryDirName = fileset.Prefix + entryDirName; } // ensure directory has trailing slash if (entryDirName.Length != 0) { if (!entryDirName.EndsWith("/")) { entryDirName += '/'; } // create directory entry in archive CreateDirectoryEntry(archive, entryDirName, fileset); } TarEntry entry = TarEntry.CreateEntryFromFile(file); entry.Name = entryDirName + entryFileName; entry.GroupId = fileset.Gid; entry.GroupName = fileset.GroupName; entry.UserId = fileset.Uid; entry.UserName = fileset.UserName; entry.TarHeader.Mode = fileset.FileMode; // write file to tar file archive.WriteEntry(entry, true); } // add (possibly empty) directories to zip if (IncludeEmptyDirs) { // add (possibly empty) directories to tar foreach (string directory in fileset.DirectoryNames) { // skip directories that are not located beneath the base // directory if (!directory.StartsWith(basePath) || directory.Length <= basePath.Length) { continue; } // determine tar entry name string entryName = directory.Substring(basePath.Length + 1); // add prefix if specified if (fileset.Prefix != null) { entryName = fileset.Prefix + entryName; } // ensure directory separators are understood on linux if (Path.DirectorySeparatorChar == '\\') { entryName = entryName.Replace(@"\", "/"); } if (!entryName.EndsWith("/")) { // trailing directory signals to #ziplib that we're // dealing with directory entry entryName += "/"; } // create directory entry in archive CreateDirectoryEntry(archive, entryName, fileset); } } } // close the tar archive archive.CloseArchive(); } catch (Exception ex) { // close the tar output stream if (outstream != null) { outstream.Close(); } // close the tar archive if (archive != null) { archive.CloseArchive(); } // delete the (possibly corrupt) tar file if (DestFile.Exists) { DestFile.Delete(); } throw new BuildException(string.Format(CultureInfo.InvariantCulture, "Tar file '{0}' could not be created.", DestFile.FullName), Location, ex); } }
public static void CreateArchive(ProgressMonitor mon, string folder, string targetFile) { string tf = Path.GetFileNameWithoutExtension(targetFile); if (tf.EndsWith(".tar")) { tf = Path.GetFileNameWithoutExtension(tf); } if (File.Exists(targetFile)) { File.Delete(targetFile); } using (Stream os = File.Create(targetFile)) { Stream outStream = os; // Create the zip file switch (GetArchiveExtension(targetFile)) { case ".tar.gz": outStream = new GZipOutputStream(outStream); goto case ".tar"; case ".tar.bz2": outStream = new BZip2OutputStream(outStream, 9); goto case ".tar"; case ".tar": TarArchive archive = TarArchive.CreateOutputTarArchive(outStream); archive.SetAsciiTranslation(false); archive.RootPath = folder; archive.ProgressMessageEvent += delegate(TarArchive ac, TarEntry e, string message) { if (message != null) { mon.Log.WriteLine(message); } }; foreach (FilePath f in GetFilesRec(new DirectoryInfo(folder))) { TarEntry entry = TarEntry.CreateEntryFromFile(f); entry.Name = f.ToRelative(folder); if (!Platform.IsWindows) { UnixFileInfo fi = new UnixFileInfo(f); entry.TarHeader.Mode = (int)fi.Protection; } else { entry.Name = entry.Name.Replace('\\', '/'); FilePermissions p = FilePermissions.S_IFREG | FilePermissions.S_IROTH | FilePermissions.S_IRGRP | FilePermissions.S_IRUSR; if (!new FileInfo(f).IsReadOnly) { p |= FilePermissions.S_IWUSR; } entry.TarHeader.Mode = (int)p; } archive.WriteEntry(entry, false); } // HACK: GNU tar expects to find a double zero record at the end of the archive. TarArchive only emits one. // This hack generates the second zero block. FieldInfo tarOutField = typeof(TarArchive).GetField("tarOut", BindingFlags.Instance | BindingFlags.NonPublic); if (tarOutField != null) { TarOutputStream tarOut = (TarOutputStream)tarOutField.GetValue(archive); tarOut.Finish(); } archive.CloseArchive(); break; case ".zip": ZipOutputStream zs = new ZipOutputStream(outStream); zs.SetLevel(5); byte[] buffer = new byte [8092]; foreach (FilePath f in GetFilesRec(new DirectoryInfo(folder))) { string name = f.ToRelative(folder); if (Platform.IsWindows) { name = name.Replace('\\', '/'); } ZipEntry infoEntry = new ZipEntry(name); zs.PutNextEntry(infoEntry); using (Stream s = File.OpenRead(f)) { int nr; while ((nr = s.Read(buffer, 0, buffer.Length)) > 0) { zs.Write(buffer, 0, nr); } } zs.CloseEntry(); } zs.Finish(); zs.Close(); break; default: mon.Log.WriteLine("Unsupported file format: " + Path.GetFileName(targetFile)); return; } } }
/// <summary> /// This is the "real" main. The class main() instantiates a tar object /// for the application and then calls this method. Process the arguments /// and perform the requested operation. /// </summary> public void InstanceMain(string[] argv) { TarArchive archive = null; int argIdx = this.ProcessArguments(argv); if (this.archiveName != null && !this.archiveName.Equals("-")) { if (operation == Operation.Create) { if (!Directory.Exists(Path.GetDirectoryName(archiveName))) { Console.Error.WriteLine("Directory for archive doesnt exist"); return; } } else { if (File.Exists(this.archiveName) == false) { Console.Error.WriteLine("File does not exist " + this.archiveName); return; } } } if (operation == Operation.Create) // WRITING { Stream outStream = Console.OpenStandardOutput(); if (this.archiveName != null && !this.archiveName.Equals("-")) { outStream = File.Create(archiveName); } if (outStream != null) { switch (this.compression) { case Compression.Compress: outStream = new DeflaterOutputStream(outStream); break; case Compression.Gzip: outStream = new GZipOutputStream(outStream); break; case Compression.Bzip2: outStream = new BZip2OutputStream(outStream, 9); break; } archive = TarArchive.CreateOutputTarArchive(outStream, this.blockingFactor); } } else // EXTRACTING OR LISTING { Stream inStream = Console.OpenStandardInput(); if (this.archiveName != null && !this.archiveName.Equals("-")) { inStream = File.OpenRead(archiveName); } if (inStream != null) { switch (this.compression) { case Compression.Compress: inStream = new InflaterInputStream(inStream); break; case Compression.Gzip: inStream = new GZipInputStream(inStream); break; case Compression.Bzip2: inStream = new BZip2InputStream(inStream); break; } archive = TarArchive.CreateInputTarArchive(inStream, this.blockingFactor); } } if (archive != null) // SET ARCHIVE OPTIONS { archive.SetKeepOldFiles(this.keepOldFiles); archive.SetAsciiTranslation(this.asciiTranslate); archive.SetUserInfo(this.userId, this.userName, this.groupId, this.groupName); } if (archive == null) { Console.Error.WriteLine("no processing due to errors"); } else if (operation == Operation.Create) // WRITING { if (verbose) { archive.ProgressMessageEvent += new ProgressMessageHandler(ShowTarProgressMessage); } for ( ; argIdx < argv.Length; ++argIdx) { string[] fileNames = GetFilesForSpec(argv[argIdx]); if (fileNames.Length > 0) { foreach (string name in fileNames) { TarEntry entry = TarEntry.CreateEntryFromFile(name); archive.WriteEntry(entry, true); } } else { Console.Error.Write("No files for " + argv[argIdx]); } } } else if (operation == Operation.List) // LISTING { archive.ProgressMessageEvent += new ProgressMessageHandler(ShowTarProgressMessage); archive.ListContents(); } else // EXTRACTING { string userDir = Environment.CurrentDirectory; if (verbose) { archive.ProgressMessageEvent += new ProgressMessageHandler(ShowTarProgressMessage); } if (userDir != null) { archive.ExtractContents(userDir); } } if (archive != null) // CLOSE ARCHIVE { archive.CloseArchive(); } }