/// <summary>Adds a file to the tar Archive</summary> /// <param name="fullName">The file to add to the archive</param><param name="directory"></param> public void AddFile(string fullName, string directory = null) { if (string.IsNullOrEmpty(directory)) { directory = Path.GetDirectoryName(fullName); } // is it a symlink (ReparsePoint)? FileAttributes a = File.GetAttributes(fullName); if ((a & FileAttributes.ReparsePoint) != 0) { this.AddSymlink(fullName); return; } if (this.TarOptions.StatusWriter != null) { this.TarOptions.StatusWriter.WriteLine("{0}", fullName); } HeaderBlock hb = HeaderBlock.CreateHeaderBlock(); string file = Path.Combine(directory, Path.GetFileName(fullName)); if (file == fullName) { file = Path.GetFileName(fullName); } hb.InsertName(file, fullName); hb.TypeFlag = (byte)TarEntryType.File; // 0 + (byte)'0' ; var fi = new FileInfo(fullName); hb.SetSize((int)fi.Length); hb.SetChksum(); byte[] block = this.Serializer.RawSerialize(hb); this.outFS.Write(block, 0, block.Length); using (FileStream fs = File.Open(fullName, FileMode.Open, FileAccess.Read)) { Array.Clear(block, 0, block.Length); while (fs.Read(block, 0, block.Length) > 0) { this.outFS.Write(block, 0, block.Length); // not n!! Array.Clear(block, 0, block.Length); } } }
/// <summary>Adds a symbolic link to a Tar archive</summary> /// <param name="name">The filename of the symbolic link</param> private void AddSymlink(string name) { if (this.TarOptions.StatusWriter != null) { this.TarOptions.StatusWriter.WriteLine("{0}", name); } // add the block for the symlink, right here. HeaderBlock hb = HeaderBlock.CreateHeaderBlock(); hb.InsertName(name, null); hb.InsertLinkName(name); hb.TypeFlag = (byte)TarEntryType.SymbolicLink; hb.SetSize(0); hb.SetChksum(); byte[] block = this.Serializer.RawSerialize(hb); this.outFS.Write(block, 0, block.Length); }
/// <summary>Adds a directory to the tar archive</summary> /// <param name="dirName">The path to the directory</param><param name="parent"></param> public void AddDirectory(string dirName, string parent = null) { if (parent == null) { parent = dirName; } // insure trailing slash if (!dirName.EndsWith(Path.DirectorySeparatorChar.ToString())) { dirName += Path.DirectorySeparatorChar; } if (this.TarOptions.StatusWriter != null) { this.TarOptions.StatusWriter.WriteLine("{0}", dirName); } string dir = dirName.Replace(parent, null).TrimSlash(); if (dir != string.Empty) { // add the block for the dir, right here. HeaderBlock hb = HeaderBlock.CreateHeaderBlock(); hb.InsertName(dir, dirName); hb.TypeFlag = 5 + (byte)'0'; hb.SetSize(0); // some impls use agg size of all files contained hb.SetChksum(); byte[] block = this.Serializer.RawSerialize(hb); this.outFS.Write(block, 0, block.Length); } // add the files: string[] filenames = Directory.GetFiles(dirName); foreach (string filename in filenames) { this.AddFile(filename, dir); } // add the subdirectories: string[] dirnames = Directory.GetDirectories(dirName); foreach (string d in dirnames) { // handle reparse points FileAttributes a = File.GetAttributes(d); if ((a & FileAttributes.ReparsePoint) == 0) { // not a symlink this.AddDirectory(d, Path.GetDirectoryName(dirName)); } else if (this.TarOptions.FollowSymLinks) { // isa symlink, and we want to follow it this.AddDirectory(d, Path.GetDirectoryName(dirName)); } else { // not following symlinks; add it this.AddSymlink(d); } } }