bool SetTimestampsFromExtendedTimeStamp(IList <ExtraField> fields, UnixZipEntry entry) { if (fields == null || fields.Count == 0) { return(false); } DateTime modTime = DateTime.MinValue; DateTime accTime = DateTime.MinValue; DateTime createTime = DateTime.MinValue; ForEachExtraField(fields, true, (ExtraField ef) => SetExtendedTimeStampTimes(new ExtraField_ExtendedTimestamp(ef), ref modTime, ref accTime, ref createTime)); // Central directory field only has the modification time, if at all if (modTime == DateTime.MinValue) { ForEachExtraField(fields, false, (ExtraField ef) => SetExtendedTimeStampTimes(new ExtraField_ExtendedTimestamp(ef), ref modTime, ref accTime, ref createTime)); } // We reset the entry modification time only if we got a valid value since // that time is also set from the entry header in ZipEntry constructor - no // need to invalidate that value if we don't have anything better. if (modTime != DateTime.MinValue) { entry.ModificationTime = modTime; } // We don't care as much about the other times entry.AccessTime = accTime; entry.CreationTime = createTime; return(true); }
void SetIDS(IList <ExtraField> fields, UnixZipEntry entry, Func <ExtraField, ExtraField_UnixIDBase> fieldMaker) { if (fields == null || fields.Count == 0) { return; } if (fieldMaker == null) { throw new ArgumentNullException(nameof(fieldMaker)); } ForEachExtraField(fields, true, (ExtraField ef) => { var izef = fieldMaker(ef); if (!izef.DataValid) { return; } if (!entry.UID.HasValue && izef.UID.HasValue) { entry.UID = izef.UID; } if (!entry.GID.HasValue && izef.GID.HasValue) { entry.GID = izef.GID; } }); }
bool SetTimestampsFromInfoZipUnixOriginal(IList <ExtraField> fields, UnixZipEntry entry) { if (fields == null || fields.Count == 0) { return(false); } DateTime modTime = DateTime.MinValue; DateTime accTime = DateTime.MinValue; ForEachExtraField(fields, true, (ExtraField ef) => { var izef = new ExtraField_InfoZipUnixOriginal(ef); SetOriginalUnixTimeStampTimes(izef, ref modTime, ref accTime); if (izef.Length <= 4) { return; // No UID/GID } if (!entry.UID.HasValue && izef.UID.HasValue) { entry.UID = izef.UID; } if (!entry.GID.HasValue && izef.GID.HasValue) { entry.GID = izef.GID; } }); if (modTime == DateTime.MinValue) { ForEachExtraField(fields, false, (ExtraField ef) => SetOriginalUnixTimeStampTimes(new ExtraField_InfoZipUnixOriginal(ef), ref modTime, ref accTime)); } if (modTime != DateTime.MinValue) { entry.ModificationTime = modTime; } // We ignore ID/GID here because it's less important than timestamps which may be set from other // fields should this one lack any of them. return(modTime != DateTime.MinValue || accTime != DateTime.MinValue); }
FilePermissions GetUnixPermissions(UnixZipEntry entry) { uint xattr = (entry.ExternalAttributes >> 16) & 0xFFFF; FilePermissions mode = 0; var perms = (UnixExternalPermissions)(xattr & (uint)UnixExternalPermissions.IFMT); switch (perms) { case 0: case UnixExternalPermissions.IFREG: entry.IsDirectory = false; entry.IsSymlink = false; break; case UnixExternalPermissions.IFDIR: entry.IsDirectory = true; entry.IsSymlink = false; break; case UnixExternalPermissions.IFLNK: entry.IsSymlink = true; entry.IsDirectory = false; break; case UnixExternalPermissions.IFMT: // Some broken zip archives appear to have 0xF in this field, which corresponds to IFMT // We're going to assume it's a file entry.IsDirectory = false; entry.IsSymlink = false; return(FilePermissions.DEFFILEMODE); default: // TODO: implement support for the rest of file types // TODO: check what happens if zip with such files is unpacked on Windows throw new NotSupportedException($"Unsupported Permission {perms}. Files other than regular ones, directories and symlinks aren't supported yet"); } perms = (UnixExternalPermissions)(xattr & (uint)UnixExternalPermissions.IMODE); if (perms.HasFlag(UnixExternalPermissions.IRUSR)) { mode |= FilePermissions.S_IRUSR; } if (perms.HasFlag(UnixExternalPermissions.IRGRP)) { mode |= FilePermissions.S_IRGRP; } if (perms.HasFlag(UnixExternalPermissions.IROTH)) { mode |= FilePermissions.S_IROTH; } if (perms.HasFlag(UnixExternalPermissions.IWUSR)) { mode |= FilePermissions.S_IWUSR; } if (perms.HasFlag(UnixExternalPermissions.IWGRP)) { mode |= FilePermissions.S_IWGRP; } if (perms.HasFlag(UnixExternalPermissions.IWOTH)) { mode |= FilePermissions.S_IWOTH; } if (perms.HasFlag(UnixExternalPermissions.IXUSR)) { mode |= FilePermissions.S_IXUSR; } if (perms.HasFlag(UnixExternalPermissions.IXGRP)) { mode |= FilePermissions.S_IXGRP; } if (perms.HasFlag(UnixExternalPermissions.IXOTH)) { mode |= FilePermissions.S_IXOTH; } if (perms.HasFlag(UnixExternalPermissions.ISUID)) { mode |= FilePermissions.S_ISUID; } if (perms.HasFlag(UnixExternalPermissions.ISGID)) { mode |= FilePermissions.S_ISGID; } if (perms.HasFlag(UnixExternalPermissions.ISVTX)) { mode |= FilePermissions.S_ISVTX; } return(mode); }
void SetIDSFromInfoZipUnix3rdGeneration(IList <ExtraField> fields, UnixZipEntry entry) { SetIDS(fields, entry, (ExtraField ef) => new ExtraField_InfoZipUnix3rdGeneration(ef)); }
void SetIDSFromInfoZipUnixType2(IList <ExtraField> fields, UnixZipEntry entry) { SetIDS(fields, entry, (ExtraField ef) => new ExtraField_InfoZipUnixType2(ef)); }