Nessuna descrizione
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

module.archive.tar.php 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. /////////////////////////////////////////////////////////////////
  3. /// getID3() by James Heinrich <info@getid3.org> //
  4. // available at https://github.com/JamesHeinrich/getID3 //
  5. // or https://www.getid3.org //
  6. // or http://getid3.sourceforge.net //
  7. // see readme.txt for more details //
  8. /////////////////////////////////////////////////////////////////
  9. // //
  10. // module.archive.tar.php //
  11. // module for analyzing TAR files //
  12. // dependencies: NONE //
  13. // ///
  14. /////////////////////////////////////////////////////////////////
  15. // //
  16. // Module originally written by //
  17. // Mike Mozolin <teddybearØmail*ru> //
  18. // //
  19. /////////////////////////////////////////////////////////////////
  20. if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
  21. exit;
  22. }
  23. class getid3_tar extends getid3_handler
  24. {
  25. /**
  26. * @return bool
  27. */
  28. public function Analyze() {
  29. $info = &$this->getid3->info;
  30. $info['fileformat'] = 'tar';
  31. $info['tar']['files'] = array();
  32. $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155prefix';
  33. $null_512k = str_repeat("\x00", 512); // end-of-file marker
  34. $this->fseek(0);
  35. while (!feof($this->getid3->fp)) {
  36. $buffer = $this->fread(512);
  37. if (strlen($buffer) < 512) {
  38. break;
  39. }
  40. // check the block
  41. $checksum = 0;
  42. for ($i = 0; $i < 148; $i++) {
  43. $checksum += ord($buffer[$i]);
  44. }
  45. for ($i = 148; $i < 156; $i++) {
  46. $checksum += ord(' ');
  47. }
  48. for ($i = 156; $i < 512; $i++) {
  49. $checksum += ord($buffer[$i]);
  50. }
  51. $attr = unpack($unpack_header, $buffer);
  52. $name = (isset($attr['fname'] ) ? trim($attr['fname'] ) : '');
  53. $mode = octdec(isset($attr['mode'] ) ? trim($attr['mode'] ) : '');
  54. $uid = octdec(isset($attr['uid'] ) ? trim($attr['uid'] ) : '');
  55. $gid = octdec(isset($attr['gid'] ) ? trim($attr['gid'] ) : '');
  56. $size = octdec(isset($attr['size'] ) ? trim($attr['size'] ) : '');
  57. $mtime = octdec(isset($attr['mtime'] ) ? trim($attr['mtime'] ) : '');
  58. $chksum = octdec(isset($attr['chksum'] ) ? trim($attr['chksum'] ) : '');
  59. $typflag = (isset($attr['typflag']) ? trim($attr['typflag']) : '');
  60. $lnkname = (isset($attr['lnkname']) ? trim($attr['lnkname']) : '');
  61. $magic = (isset($attr['magic'] ) ? trim($attr['magic'] ) : '');
  62. $ver = (isset($attr['ver'] ) ? trim($attr['ver'] ) : '');
  63. $uname = (isset($attr['uname'] ) ? trim($attr['uname'] ) : '');
  64. $gname = (isset($attr['gname'] ) ? trim($attr['gname'] ) : '');
  65. $devmaj = octdec(isset($attr['devmaj'] ) ? trim($attr['devmaj'] ) : '');
  66. $devmin = octdec(isset($attr['devmin'] ) ? trim($attr['devmin'] ) : '');
  67. $prefix = (isset($attr['prefix'] ) ? trim($attr['prefix'] ) : '');
  68. if (($checksum == 256) && ($chksum == 0)) {
  69. // EOF Found
  70. break;
  71. }
  72. if ($prefix) {
  73. $name = $prefix.'/'.$name;
  74. }
  75. if ((preg_match('#/$#', $name)) && !$name) {
  76. $typeflag = 5;
  77. }
  78. if ($buffer == $null_512k) {
  79. // it's the end of the tar-file...
  80. break;
  81. }
  82. // Read to the next chunk
  83. $this->fseek($size, SEEK_CUR);
  84. $diff = $size % 512;
  85. if ($diff != 0) {
  86. // Padding, throw away
  87. $this->fseek((512 - $diff), SEEK_CUR);
  88. }
  89. // Protect against tar-files with garbage at the end
  90. if ($name == '') {
  91. break;
  92. }
  93. $info['tar']['file_details'][$name] = array (
  94. 'name' => $name,
  95. 'mode_raw' => $mode,
  96. 'mode' => self::display_perms($mode),
  97. 'uid' => $uid,
  98. 'gid' => $gid,
  99. 'size' => $size,
  100. 'mtime' => $mtime,
  101. 'chksum' => $chksum,
  102. 'typeflag' => self::get_flag_type($typflag),
  103. 'linkname' => $lnkname,
  104. 'magic' => $magic,
  105. 'version' => $ver,
  106. 'uname' => $uname,
  107. 'gname' => $gname,
  108. 'devmajor' => $devmaj,
  109. 'devminor' => $devmin
  110. );
  111. $info['tar']['files'] = getid3_lib::array_merge_clobber($info['tar']['files'], getid3_lib::CreateDeepArray($info['tar']['file_details'][$name]['name'], '/', $size));
  112. }
  113. return true;
  114. }
  115. /**
  116. * Parses the file mode to file permissions.
  117. *
  118. * @param int $mode
  119. *
  120. * @return string
  121. */
  122. public function display_perms($mode) {
  123. // Determine Type
  124. if ($mode & 0x1000) $type='p'; // FIFO pipe
  125. elseif ($mode & 0x2000) $type='c'; // Character special
  126. elseif ($mode & 0x4000) $type='d'; // Directory
  127. elseif ($mode & 0x6000) $type='b'; // Block special
  128. elseif ($mode & 0x8000) $type='-'; // Regular
  129. elseif ($mode & 0xA000) $type='l'; // Symbolic Link
  130. elseif ($mode & 0xC000) $type='s'; // Socket
  131. else $type='u'; // UNKNOWN
  132. // Determine permissions
  133. $owner['read'] = (($mode & 00400) ? 'r' : '-');
  134. $owner['write'] = (($mode & 00200) ? 'w' : '-');
  135. $owner['execute'] = (($mode & 00100) ? 'x' : '-');
  136. $group['read'] = (($mode & 00040) ? 'r' : '-');
  137. $group['write'] = (($mode & 00020) ? 'w' : '-');
  138. $group['execute'] = (($mode & 00010) ? 'x' : '-');
  139. $world['read'] = (($mode & 00004) ? 'r' : '-');
  140. $world['write'] = (($mode & 00002) ? 'w' : '-');
  141. $world['execute'] = (($mode & 00001) ? 'x' : '-');
  142. // Adjust for SUID, SGID and sticky bit
  143. if ($mode & 0x800) $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S';
  144. if ($mode & 0x400) $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S';
  145. if ($mode & 0x200) $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T';
  146. $s = sprintf('%1s', $type);
  147. $s .= sprintf('%1s%1s%1s', $owner['read'], $owner['write'], $owner['execute']);
  148. $s .= sprintf('%1s%1s%1s', $group['read'], $group['write'], $group['execute']);
  149. $s .= sprintf('%1s%1s%1s'."\n", $world['read'], $world['write'], $world['execute']);
  150. return $s;
  151. }
  152. /**
  153. * Converts the file type.
  154. *
  155. * @param string $typflag
  156. *
  157. * @return mixed|string
  158. */
  159. public function get_flag_type($typflag) {
  160. static $flag_types = array(
  161. '0' => 'LF_NORMAL',
  162. '1' => 'LF_LINK',
  163. '2' => 'LF_SYNLINK',
  164. '3' => 'LF_CHR',
  165. '4' => 'LF_BLK',
  166. '5' => 'LF_DIR',
  167. '6' => 'LF_FIFO',
  168. '7' => 'LF_CONFIG',
  169. 'D' => 'LF_DUMPDIR',
  170. 'K' => 'LF_LONGLINK',
  171. 'L' => 'LF_LONGNAME',
  172. 'M' => 'LF_MULTIVOL',
  173. 'N' => 'LF_NAMES',
  174. 'S' => 'LF_SPARSE',
  175. 'V' => 'LF_VOLHDR'
  176. );
  177. return (isset($flag_types[$typflag]) ? $flag_types[$typflag] : '');
  178. }
  179. }