/// <summary> /// Adds the stream to the archive. /// </summary> /// <returns>A new ZipEntry for the stream</returns> /// <param name="stream">The stream to add to the archive.</param> /// <param name="archivePath">The fullpath for the entry in the archive</param> /// <param name="permissions">The permissions which the stream should have when extracted (Unix Only)</param> /// <param name="compressionMethod">The compression method to use</param> /// <param name="overwriteExisting">If true an existing entry will be overwritten. If false and an existing entry exists and error will be raised</param> public ZipEntry AddStream(Stream stream, string archivePath, EntryPermissions permissions = EntryPermissions.Default, CompressionMethod compressionMethod = CompressionMethod.Default, bool overwriteExisting = true) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } sources.Add(stream); string destPath = EnsureArchivePath(archivePath); var handle = GCHandle.Alloc(stream, GCHandleType.Normal); IntPtr h = GCHandle.ToIntPtr(handle); IntPtr source = Native.zip_source_function(archive, callback, h); long index = Native.zip_file_add(archive, destPath, source, overwriteExisting ? OperationFlags.Overwrite : OperationFlags.None); if (index < 0) { throw GetErrorException(); } if (Native.zip_set_file_compression(archive, (ulong)index, compressionMethod, 0) < 0) { throw GetErrorException(); } if (permissions == EntryPermissions.Default) { permissions = DefaultFilePermissions; } PlatformServices.Instance.SetEntryPermissions(this, (ulong)index, permissions, false); return(ReadEntry((ulong)index)); }
internal bool SetEntryUnixPermissions(ulong index, EntryPermissions requestedPermissions, UnixExternalPermissions unixPermissions) { var permissions = (uint)requestedPermissions | (uint)unixPermissions; int ret = Native.zip_file_set_external_attributes(ArchivePointer, index, OperationFlags.None, (byte)OperatingSystem.UNIX, permissions << 16); return(ret == 0); }
void AssertEntryIsValid(ZipEntry e, string expectedArchivePath, EntryPermissions permissions = EntryPermissions.Default, CompressionMethod compression = CompressionMethod.Store) { Assert.IsNotNull(e, $"ZipEntry for {expectedArchivePath} should not be null."); Assert.AreEqual(e.FullName, expectedArchivePath, $"Expected {expectedArchivePath} but got {e.FullName}"); Assert.AreEqual(e.CompressionMethod, compression, $"Expected {compression} but was {e.CompressionMethod} for {e.FullName}"); //Assert.AreEqual (e.CompressionMethod, permissions, $"Expected {permissions} but was {e.ExternalAttributes} for {e.FullName}"); }
bool SetEntryPermissions(ZipArchive archive, ulong index, EntryPermissions requestedPermissions, UnixExternalPermissions unixPermissions) { var unixArchive = archive as UnixZipArchive; if (unixArchive == null) { throw new InvalidOperationException("Expected instance of UnixZipArchive"); } return(unixArchive.SetEntryUnixPermissions(index, requestedPermissions, unixPermissions)); }
/// <summary> /// Adds the file to the archive. <paramref name="sourcePath"/> is either a relative or absolute /// path to the file to add to the archive. If <paramref name="sourcePath"/> is an absolute path, /// it will be converted to a relative one by removing the root of the path (<code>/</code> on Unix /// and <code>X://</code> on Windows) and stored using the resulting path in the archive. If, however, /// the <paramref name="archivePath"/> parameter is present it represents a full in-archive (that is - /// without the <code>/</code> or <code>X://</code> part) path of the file including the file name. /// </summary> /// <returns>The file.</returns> /// <param name="sourcePath">Source path.</param> /// <param name="archivePath">Path in the archive, including file name.</param> /// <param name="permissions">Permissions.</param> /// <param name="compressionMethod">Compression method.</param> /// <param name="overwriteExisting">Overwrite existing entries in the archive.</param> public ZipEntry AddFile(string sourcePath, string archivePath = null, EntryPermissions permissions = EntryPermissions.Default, CompressionMethod compressionMethod = CompressionMethod.Default, bool overwriteExisting = true) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("Must not be null or empty", nameof(sourcePath)); } bool isDir = PlatformServices.Instance.IsDirectory(this, sourcePath); if (permissions == EntryPermissions.Default) { permissions = PlatformServices.Instance.GetFilesystemPermissions(this, sourcePath); if (permissions == EntryPermissions.Default) { permissions = isDir ? DefaultDirectoryPermissions : DefaultFilePermissions; } } if (PlatformServices.Instance.IsRegularFile(this, sourcePath)) { return(AddStream(new FileStream(sourcePath, FileMode.Open, FileAccess.Read), archivePath ?? sourcePath, permissions, compressionMethod, overwriteExisting, modificationTime: File.GetLastWriteTimeUtc(sourcePath))); } string destPath = EnsureArchivePath(archivePath ?? sourcePath, isDir); long index = PlatformServices.Instance.StoreSpecialFile(this, sourcePath, archivePath, out compressionMethod); if (index < 0) { throw GetErrorException(); } if (Native.zip_set_file_compression(archive, (ulong)index, isDir ? CompressionMethod.Store : compressionMethod, 0) < 0) { throw GetErrorException(); } PlatformServices.Instance.SetEntryPermissions(this, sourcePath, (ulong)index, permissions); ZipEntry entry = ReadEntry((ulong)index); IList <ExtraField> fields = new List <ExtraField> (); ExtraField_ExtendedTimestamp timestamp = new ExtraField_ExtendedTimestamp(entry, 0, createTime: File.GetCreationTimeUtc(sourcePath), accessTime: File.GetLastAccessTimeUtc(sourcePath), modificationTime: File.GetLastWriteTimeUtc(sourcePath)); fields.Add(timestamp); if (!PlatformServices.Instance.WriteExtraFields(this, entry, fields)) { throw GetErrorException(); } return(entry); }
public ZipEntry CreateSymbolicLink(string linkName, string linkDestination, EntryPermissions requestedPermissions = EntryPermissions.Default, Encoding encoding = null) { ZipEntry entry = AddEntry(linkName, linkDestination, encoding ?? Encoding.UTF8, CompressionMethod.Store); if (entry == null) { return(null); } if (!SetEntryUnixPermissions(entry.Index, requestedPermissions == EntryPermissions.Default ? DefaultFilePermissions : requestedPermissions, UnixExternalPermissions.IFLNK)) { throw GetErrorException(); } // We read it again to update permissions, flags, extra fields etc return(ReadEntry(entry.Index)); }
public EntryPermissions GetFilesystemPermissions(ZipArchive archive, string path) { if (String.IsNullOrEmpty(path)) { throw new ArgumentException("must not be null or empty", nameof(path)); } EntryPermissions permissions = EntryPermissions.Default; if (!CallServices((IPlatformServices services) => services.GetFilesystemPermissions(archive, path, out permissions))) { return(EntryPermissions.Default); } return(permissions); }
/// <summary> /// Adds the file to archive directory. The file is added to either the root directory of /// the ZIP archive (if <paramref name="archiveDirectory"/> is <c>null</c> or empty) or to /// the directory named by <paramref name="archiveDirectory"/>. If <paramref name="useFileDirectory"/> /// is <c>true</c> the original file directory part is used to create the full path of the file /// in the archive. If <paramref name="useFileDirectory"/> is <c>false</c>, the original file directory /// part is ignored and the file is placed directly in <paramref name="archiveDirectory"/>. The original /// file name is always preserved, if you need to change it use <see cref="AddFile"/>. /// </summary> /// <returns>The file to add to an archive directory.</returns> /// <param name="sourcePath">Source file path.</param> /// <param name="archiveDirectory">Destination directory in the archive.</param> /// <param name="permissions">Entry permissions.</param> /// <param name="compressionMethod">Compression method.</param> /// <param name="overwriteExisting">If set to <c>true</c> overwrite existing entry in the archive.</param> /// <param name="useFileDirectory">If set to <c>true</c> use file directory part.</param> public ZipEntry AddFileToDirectory(string sourcePath, string archiveDirectory = null, EntryPermissions permissions = EntryPermissions.Default, CompressionMethod compressionMethod = CompressionMethod.Default, bool overwriteExisting = true, bool useFileDirectory = true) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("Must not be null or empty", nameof(sourcePath)); } string destDir = NormalizeArchivePath(true, archiveDirectory); string destFile = useFileDirectory ? GetRootlessPath(sourcePath) : Path.GetFileName(sourcePath); return(AddFile(sourcePath, String.IsNullOrEmpty(destDir) ? null : destDir + "/" + destFile, permissions, compressionMethod, overwriteExisting)); }
public void CreateDirectory(string directoryName, EntryPermissions permissions = EntryPermissions.Default) { string dir = EnsureArchivePath(directoryName, true); long index = Native.zip_dir_add(archive, dir, OperationFlags.None); if (index < 0) { throw GetErrorException(); } if (permissions == EntryPermissions.Default) { permissions = DefaultDirectoryPermissions; } PlatformServices.Instance.SetEntryPermissions(this, (ulong)index, permissions, true); }
public bool GetFilesystemPermissions(ZipArchive archive, string path, out EntryPermissions permissions) { permissions = EntryPermissions.Default; if (String.IsNullOrEmpty(path)) { return(false); } Stat sbuf; // Should we signal an error if stat fails? Is it important enough? if (Syscall.stat(path, out sbuf) == 0) { permissions = (EntryPermissions)(Utilities.GetFilePermissions(sbuf) & UnixExternalPermissions.IMODE); } return(true); }
public bool GetFilesystemPermissions(ZipArchive archive, string path, out EntryPermissions permissions) { permissions = EntryPermissions.Default; if (String.IsNullOrEmpty(path)) { return(false); } FileSystemInfo fi; if (File.Exists(path)) { fi = new FileInfo(path); } else if (Directory.Exists(path)) { fi = new DirectoryInfo(path); } else { return(false); } if (fi.Attributes == FileAttributes.Normal) { permissions = fi is FileInfo ? ZipArchive.DefaultFilePermissions : ZipArchive.DefaultDirectoryPermissions; return(true); } permissions = EntryPermissions.OwnerRead | EntryPermissions.GroupRead | EntryPermissions.WorldRead; if (!fi.Attributes.HasFlag(FileAttributes.ReadOnly)) { permissions |= EntryPermissions.OwnerWrite | EntryPermissions.GroupWrite; } if (fi is DirectoryInfo) { permissions |= EntryPermissions.OwnerExecute | EntryPermissions.GroupExecute | EntryPermissions.WorldExecute; } return(true); }
/// <summary> /// Adds the file to the archive. <paramref name="sourcePath"/> is either a relative or absolute /// path to the file to add to the archive. If <paramref name="sourcePath"/> is an absolute path, /// it will be converted to a relative one by removing the root of the path (<code>/</code> on Unix /// and <code>X://</code> on Windows) and stored using the resulting path in the archive. If, however, /// the <paramref name="archivePath"/> parameter is present it represents a full in-archive (that is - /// without the <code>/</code> or <code>X://</code> part) path of the file including the file name. /// </summary> /// <returns>The file.</returns> /// <param name="sourcePath">Source path.</param> /// <param name="archivePath">Path in the archive, including file name.</param> /// <param name="permissions">Permissions.</param> /// <param name="compressionMethod">Compression method.</param> /// <param name="overwriteExisting">Overwrite existing entries in the archive.</param> public ZipEntry AddFile(string sourcePath, string archivePath = null, EntryPermissions permissions = EntryPermissions.Default, CompressionMethod compressionMethod = CompressionMethod.Default, bool overwriteExisting = true) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("Must not be null or empty", nameof(sourcePath)); } bool isDir = PlatformServices.Instance.IsDirectory(this, sourcePath); if (permissions == EntryPermissions.Default) { permissions = PlatformServices.Instance.GetFilesystemPermissions(this, sourcePath); if (permissions == EntryPermissions.Default) { permissions = isDir ? DefaultDirectoryPermissions : DefaultFilePermissions; } } if (PlatformServices.Instance.IsRegularFile(this, sourcePath)) { return(AddStream(new FileStream(sourcePath, FileMode.Open, FileAccess.Read), archivePath ?? sourcePath, permissions, compressionMethod, overwriteExisting)); } string destPath = EnsureArchivePath(archivePath ?? sourcePath, isDir); long index = PlatformServices.Instance.StoreSpecialFile(this, sourcePath, archivePath, out compressionMethod); if (index < 0) { throw GetErrorException(); } if (Native.zip_set_file_compression(archive, (ulong)index, isDir ? CompressionMethod.Store : compressionMethod, 0) < 0) { throw GetErrorException(); } PlatformServices.Instance.SetEntryPermissions(this, sourcePath, (ulong)index, permissions); return(ReadEntry((ulong)index)); }
/// <summary> /// Adds the stream to the archive. /// </summary> /// <returns>A new ZipEntry for the stream</returns> /// <param name="stream">The stream to add to the archive.</param> /// <param name="archivePath">The fullpath for the entry in the archive</param> /// <param name="permissions">The permissions which the stream should have when extracted (Unix Only)</param> /// <param name="compressionMethod">The compression method to use</param> /// <param name="overwriteExisting">If true an existing entry will be overwritten. If false and an existing entry exists and error will be raised</param> public ZipEntry AddStream(Stream stream, string archivePath, EntryPermissions permissions = EntryPermissions.Default, CompressionMethod compressionMethod = CompressionMethod.Default, bool overwriteExisting = true, DateTime?modificationTime = null) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } sources.Add(stream); string destPath = EnsureArchivePath(archivePath); var handle = GCHandle.Alloc(stream, GCHandleType.Normal); IntPtr h = GCHandle.ToIntPtr(handle); IntPtr source = Native.zip_source_function(archive, callback, h); long index = Native.zip_file_add(archive, destPath, source, overwriteExisting ? OperationFlags.Overwrite : OperationFlags.None); if (index < 0) { throw GetErrorException(); } if (Native.zip_set_file_compression(archive, (ulong)index, compressionMethod, 0) < 0) { throw GetErrorException(); } if (permissions == EntryPermissions.Default) { permissions = DefaultFilePermissions; } PlatformServices.Instance.SetEntryPermissions(this, (ulong)index, permissions, false); ZipEntry entry = ReadEntry((ulong)index); IList <ExtraField> fields = new List <ExtraField> (); ExtraField_ExtendedTimestamp timestamp = new ExtraField_ExtendedTimestamp(entry, 0, modificationTime: modificationTime ?? DateTime.UtcNow); fields.Add(timestamp); if (!PlatformServices.Instance.WriteExtraFields(this, entry, fields)) { throw GetErrorException(); } return(entry); }
public bool SetEntryPermissions(ZipArchive archive, ulong index, EntryPermissions permissions, bool isDirectory) { return(true); }
/// <summary> /// Adds the byte[] data to the archive. /// </summary> /// <returns>The new ZipEntry for the data</returns> /// <param name="data">A byte[] array containing the data to add</param> /// <param name="archivePath">the full path for the entry in the archive.</param> /// <param name="permissions">The permissions which the stream should have when extracted (Unix Only)</param> /// <param name="compressionMethod">The compression method to use</param> /// <param name="overwriteExisting">If true an existing entry will be overwritten. If false and an existing entry exists and error will be raised</param> public ZipEntry AddEntry(byte[] data, string archivePath, EntryPermissions permissions = EntryPermissions.Default, CompressionMethod compressionMethod = CompressionMethod.Default, bool overwriteExisting = true) { return(AddStream(new MemoryStream(data), archivePath, permissions, compressionMethod, overwriteExisting)); }
public void SetEntryPermissions(ZipArchive archive, string sourcePath, ulong index, EntryPermissions permissions) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("must not be null or empty", nameof(sourcePath)); } CallServices((IPlatformServices services) => services.SetEntryPermissions(archive, sourcePath, index, permissions)); }
public void SetEntryPermissions(ZipArchive archive, ulong index, EntryPermissions permissions, bool isDirectory) { CallServices((IPlatformServices services) => services.SetEntryPermissions(archive, index, permissions, isDirectory)); }
public bool SetEntryPermissions(ZipArchive archive, string sourcePath, ulong index, EntryPermissions permissions) { return(true); }
public bool SetEntryPermissions(ZipArchive archive, ulong index, EntryPermissions requestedPermissions, bool isDirectory) { return(SetEntryPermissions(archive, index, requestedPermissions, isDirectory ? UnixExternalPermissions.IFDIR : UnixExternalPermissions.IFREG)); }
public bool SetEntryPermissions(ZipArchive zipArchive, string sourcePath, ulong index, EntryPermissions requestedPermissions) { var archive = zipArchive as UnixZipArchive; if (archive == null) { throw new ArgumentException("must be an instance of UnixZipArchive", nameof(zipArchive)); } UnixExternalPermissions ftype = UnixExternalPermissions.IFREG; if (!String.IsNullOrEmpty(sourcePath)) { UnixExternalPermissions ft; if (Utilities.GetFileType(sourcePath, !archive.UnixOptions.StoreSymlinks, out ft)) { ftype = ft; } } return(SetEntryPermissions(archive, index, requestedPermissions, ftype)); }