Ejemplo n.º 1
0
        /// <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));
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
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}");
 }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 8
0
        /// <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));
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        /// <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));
        }
Ejemplo n.º 13
0
        /// <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);
        }
Ejemplo n.º 14
0
 public bool SetEntryPermissions(ZipArchive archive, ulong index, EntryPermissions permissions, bool isDirectory)
 {
     return(true);
 }
Ejemplo n.º 15
0
 /// <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));
 }
Ejemplo n.º 16
0
        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));
        }
Ejemplo n.º 17
0
 public void SetEntryPermissions(ZipArchive archive, ulong index, EntryPermissions permissions, bool isDirectory)
 {
     CallServices((IPlatformServices services) => services.SetEntryPermissions(archive, index, permissions, isDirectory));
 }
Ejemplo n.º 18
0
 public bool SetEntryPermissions(ZipArchive archive, string sourcePath, ulong index, EntryPermissions permissions)
 {
     return(true);
 }
Ejemplo n.º 19
0
 public bool SetEntryPermissions(ZipArchive archive, ulong index, EntryPermissions requestedPermissions, bool isDirectory)
 {
     return(SetEntryPermissions(archive, index, requestedPermissions, isDirectory ? UnixExternalPermissions.IFDIR : UnixExternalPermissions.IFREG));
 }
Ejemplo n.º 20
0
        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));
        }