| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- <?php
- namespace PhpZip\Model\Extra\Fields;
- use PhpZip\Model\Extra\ZipExtraField;
- use PhpZip\Model\ZipEntry;
- /**
- * Info-ZIP Unix Extra Field (type 1):
- * ==================================.
- *
- * The following is the layout of the old Info-ZIP extra block for
- * Unix. It has been replaced by the extended-timestamp extra block
- * (0x5455) and the Unix type 2 extra block (0x7855).
- * (Last Revision 19970118)
- *
- * Local-header version:
- *
- * Value Size Description
- * ----- ---- -----------
- * (Unix1) 0x5855 Short tag for this extra block type ("UX")
- * TSize Short total data size for this block
- * AcTime Long time of last access (UTC/GMT)
- * ModTime Long time of last modification (UTC/GMT)
- * UID Short Unix user ID (optional)
- * GID Short Unix group ID (optional)
- *
- * Central-header version:
- *
- * Value Size Description
- * ----- ---- -----------
- * (Unix1) 0x5855 Short tag for this extra block type ("UX")
- * TSize Short total data size for this block
- * AcTime Long time of last access (GMT/UTC)
- * ModTime Long time of last modification (GMT/UTC)
- *
- * The file access and modification times are in standard Unix signed-
- * long format, indicating the number of seconds since 1 January 1970
- * 00:00:00. The times are relative to Coordinated Universal Time
- * (UTC), also sometimes referred to as Greenwich Mean Time (GMT). To
- * convert to local time, the software must know the local timezone
- * offset from UTC/GMT. The modification time may be used by non-Unix
- * systems to support inter-timezone freshening and updating of zip
- * archives.
- *
- * The local-header extra block may optionally contain UID and GID
- * info for the file. The local-header TSize value is the only
- * indication of this. Note that Unix UIDs and GIDs are usually
- * specific to a particular machine, and they generally require root
- * access to restore.
- *
- * This extra field type is obsolete, but it has been in use since
- * mid-1994. Therefore future archiving software should continue to
- * support it.
- */
- class OldUnixExtraField implements ZipExtraField
- {
- /** @var int Header id */
- const HEADER_ID = 0x5855;
- /** @var int|null Access timestamp */
- private $accessTime;
- /** @var int|null Modify timestamp */
- private $modifyTime;
- /** @var int|null User id */
- private $uid;
- /** @var int|null Group id */
- private $gid;
- /**
- * @param int|null $accessTime
- * @param int|null $modifyTime
- * @param int|null $uid
- * @param int|null $gid
- */
- public function __construct($accessTime, $modifyTime, $uid, $gid)
- {
- $this->accessTime = $accessTime;
- $this->modifyTime = $modifyTime;
- $this->uid = $uid;
- $this->gid = $gid;
- }
- /**
- * Returns the Header ID (type) of this Extra Field.
- * The Header ID is an unsigned short integer (two bytes)
- * which must be constant during the life cycle of this object.
- *
- * @return int
- */
- public function getHeaderId()
- {
- return self::HEADER_ID;
- }
- /**
- * Populate data from this array as if it was in local file data.
- *
- * @param string $buffer the buffer to read data from
- * @param ZipEntry|null $entry
- *
- * @return OldUnixExtraField
- */
- public static function unpackLocalFileData($buffer, ZipEntry $entry = null)
- {
- $length = \strlen($buffer);
- $accessTime = $modifyTime = $uid = $gid = null;
- if ($length >= 4) {
- $accessTime = unpack('V', $buffer)[1];
- }
- if ($length >= 8) {
- $modifyTime = unpack('V', substr($buffer, 4, 4))[1];
- }
- if ($length >= 10) {
- $uid = unpack('v', substr($buffer, 8, 2))[1];
- }
- if ($length >= 12) {
- $gid = unpack('v', substr($buffer, 10, 2))[1];
- }
- return new self($accessTime, $modifyTime, $uid, $gid);
- }
- /**
- * Populate data from this array as if it was in central directory data.
- *
- * @param string $buffer the buffer to read data from
- * @param ZipEntry|null $entry
- *
- * @return OldUnixExtraField
- */
- public static function unpackCentralDirData($buffer, ZipEntry $entry = null)
- {
- $length = \strlen($buffer);
- $accessTime = $modifyTime = null;
- if ($length >= 4) {
- $accessTime = unpack('V', $buffer)[1];
- }
- if ($length >= 8) {
- $modifyTime = unpack('V', substr($buffer, 4, 4))[1];
- }
- return new self($accessTime, $modifyTime, null, null);
- }
- /**
- * The actual data to put into local file data - without Header-ID
- * or length specifier.
- *
- * @return string the data
- */
- public function packLocalFileData()
- {
- $data = '';
- if ($this->accessTime !== null) {
- $data .= pack('V', $this->accessTime);
- if ($this->modifyTime !== null) {
- $data .= pack('V', $this->modifyTime);
- if ($this->uid !== null) {
- $data .= pack('v', $this->uid);
- if ($this->gid !== null) {
- $data .= pack('v', $this->gid);
- }
- }
- }
- }
- return $data;
- }
- /**
- * The actual data to put into central directory - without Header-ID or
- * length specifier.
- *
- * @return string the data
- */
- public function packCentralDirData()
- {
- $data = '';
- if ($this->accessTime !== null) {
- $data .= pack('V', $this->accessTime);
- if ($this->modifyTime !== null) {
- $data .= pack('V', $this->modifyTime);
- }
- }
- return $data;
- }
- /**
- * @return int|null
- */
- public function getAccessTime()
- {
- return $this->accessTime;
- }
- /**
- * @param int|null $accessTime
- */
- public function setAccessTime($accessTime)
- {
- $this->accessTime = $accessTime;
- }
- /**
- * @return \DateTimeInterface|null
- */
- public function getAccessDateTime()
- {
- try {
- return $this->accessTime === null ? null :
- new \DateTimeImmutable('@' . $this->accessTime);
- } catch (\Exception $e) {
- return null;
- }
- }
- /**
- * @return int|null
- */
- public function getModifyTime()
- {
- return $this->modifyTime;
- }
- /**
- * @param int|null $modifyTime
- */
- public function setModifyTime($modifyTime)
- {
- $this->modifyTime = $modifyTime;
- }
- /**
- * @return \DateTimeInterface|null
- */
- public function getModifyDateTime()
- {
- try {
- return $this->modifyTime === null ? null :
- new \DateTimeImmutable('@' . $this->modifyTime);
- } catch (\Exception $e) {
- return null;
- }
- }
- /**
- * @return int|null
- */
- public function getUid()
- {
- return $this->uid;
- }
- /**
- * @param int|null $uid
- */
- public function setUid($uid)
- {
- $this->uid = $uid;
- }
- /**
- * @return int|null
- */
- public function getGid()
- {
- return $this->gid;
- }
- /**
- * @param int|null $gid
- */
- public function setGid($gid)
- {
- $this->gid = $gid;
- }
- /**
- * @return string
- */
- public function __toString()
- {
- $args = [self::HEADER_ID];
- $format = '0x%04x OldUnix:';
- if (($modifyTime = $this->getModifyDateTime()) !== null) {
- $format .= ' Modify:[%s]';
- $args[] = $modifyTime->format(\DATE_ATOM);
- }
- if (($accessTime = $this->getAccessDateTime()) !== null) {
- $format .= ' Access:[%s]';
- $args[] = $accessTime->format(\DATE_ATOM);
- }
- if ($this->uid !== null) {
- $format .= ' UID=%d';
- $args[] = $this->uid;
- }
- if ($this->gid !== null) {
- $format .= ' GID=%d';
- $args[] = $this->gid;
- }
- return vsprintf($format, $args);
- }
- }
|