2 rcs_id('$Id: FileInfo.php,v 1.4 2005-10-29 14:18:47 rurban Exp $');
4 Copyright 2005 $ThePhpWikiProgrammingTeam
6 This file is part of PhpWiki.
8 PhpWiki is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 PhpWiki is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with PhpWiki; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * This plugin displays the version, date, size, perms of an uploaded file.
25 * Only files relative and below to the uploads path can be handled.
28 * <?plugin FileVersion file=uploads/setup.exe display=version,date ?>
29 * <?plugin FileVersion file=uploads/setup.exe display=name,version,date
30 * format="%s (version: %s, date: %s)" ?>
35 class WikiPlugin_FileInfo
42 function getDescription () {
43 return _("Display file information like version,size,date,... of uploaded files.");
46 function getVersion() {
47 return preg_replace("/[Revision: $]/", '',
51 function getDefaultArguments() {
53 'file' => false, // relative path from PHPWIKI_DIR. (required)
54 'display' => false, // version,size,date,mtime,owner,name,path,dirname,link. (required)
55 'format' => false, // printf format string with %s only, all display modes
56 // from above vars return strings (optional)
60 function run($dbi, $argstr, &$request, $basepage) {
61 extract($this->getArgs($argstr, $request));
63 return $this->error(sprintf(_("A required argument '%s' is missing."), 'file'));
65 return $this->error(sprintf(_("A required argument '%s' is missing."), 'display'));
70 if (!file_exists($file)) {
71 trigger_error("file \"$file\" not found", E_USER_WARNING);
73 $realfile = realpath($file);
74 if (!string_starts_with($realfile, realpath(getUploadDataPath())))
75 return $this->error("invalid path \"$file\"");
79 $modes = explode(",", $display);
80 foreach ($modes as $mode) {
82 case 'version': $s[] = $this->exeversion($file); break;
83 case 'size': $s[] = filesize($file); break;
84 case 'phonysize':$s[] = $this->phonysize(filesize($file)); break;
85 case 'date': $s[] = strftime("%x %X", filemtime($file)); break;
86 case 'mtime': $s[] = filemtime($file); break;
87 case 'name': $s[] = basename($file); break;
88 case 'path': $s[] = $file; break;
89 case 'dirname': $s[] = dirname($file); break;
90 case 'magic': $s[] = $this->magic($file); break;
91 case 'mime-typ': $s[] = $this->mime_type($file); break;
94 $s[] = "[Upload:".basename($file)."]";
96 $s[] = "[".basename($file)."]";
100 return $this->error(sprintf(_("Unsupported argument: %s=%s"), 'display', $mode));
107 foreach ($s as $x) { $format .= " %s"; }
109 array_unshift($s, $format);
110 // $x, array($i,$j) => sprintf($x, $i, $j)
111 $result = call_user_func_array("sprintf", $s);
112 if (in_array('link', $modes)) {
113 require_once("lib/InlineParser.php");
114 return TransformInline($result);
120 function magic($file) {
121 if (function_exists('finfo_file') or loadPhpExtension('fileinfo')) {
122 // Valid finfo_open (i.e. libmagic) options:
123 // FILEINFO_NONE | FILEINFO_SYMLINK | FILEINFO_MIME | FILEINFO_COMPRESS | FILEINFO_DEVICES |
124 // FILEINFO_CONTINUE | FILEINFO_PRESERVE_ATIME | FILEINFO_RAW
125 $f = finfo_open(/*FILEINFO_MIME*/);
126 $result = finfo_file(realpath($file));
133 function mime_type($file) {
137 function _formatsize ($n, $factor, $suffix = '') {
140 $n -= floor($factor * $b);
141 return number_format($b, $n ? 3 : 0). $suffix;
144 function phonysize ($a) {
145 $factor = 1024 * 1024 * 1000;
147 return $this->_formatsize($a, $factor, ' GB');
148 $factor = 1024 * 1000;
150 return $this->_formatsize($a, $factor, ' MB');
153 return $this->_formatsize($a, $factor, ' KB');
155 return $this->_formatsize($a, 1, ' byte');
160 function exeversion($file) {
161 if (!isWindows()) return "?";
162 if (class_exists('ffi') or loadPhpExtension('ffi'))
163 return $this->exeversion_ffi($file);
164 if (function_exists('res_list_type') or loadPhpExtension('win32std'))
165 return $this->exeversion_resopen($file);
166 return exeversion_showver($file);
170 // http://www.codeproject.com/dll/showver.asp
171 function exeversion_showver($file) {
172 $path = realpath($file);
173 $result = `showver $path`;
177 function exeversion_ffi($file) {
179 return "?"; // not yet stable
181 if (function_exists('ffi') or loadPhpExtension('ffi')) {
183 struct VS_FIXEDFILEINFO {
185 DWORD dwStrucVersion;
186 DWORD dwFileVersionMS;
187 DWORD dwFileVersionLS;
188 DWORD dwProductVersionMS;
189 DWORD dwProductVersionLS;
190 DWORD dwFileFlagsMask;
198 struct VS_VERSIONINFO { struct VS_VERSIONINFO
204 VS_FIXEDFILEINFO Value;
208 [lib='kernel32.dll'] DWORD GetFileVersionInfoSizeA(char *szFileName, DWORD *dwVerHnd);
209 [lib='kernel32.dll'] int GetFileVersionInfoA(char *sfnFile, DWORD dummy, DWORD size, struct VS_VERSIONINFO *pVer);
211 $ffi = new ffi($win32_idl);
212 $dummy = 0; // &DWORD
213 $size = $ffi->GetFileVersionInfoSizeA($file, $dummy);
214 //$pVer = str_repeat($size+1);
215 $pVer = new ffi_struct($ffi, "VS_VERSIONINFO");
216 if ($ffi->GetFileVersionInfoA($file, 0, $size, $pVer)
217 and $pVer->wValueLength) {
218 // analyze the VS_FIXEDFILEINFO(Value);
219 // $pValue = new ffi_struct($ffi, "VS_FIXEDFILEINFO");
220 $pValue =& $pVer->Value;
221 return sprintf("%d.%d.%d.%d",
222 $pValue->dwFileVersionMS >> 16,
223 $pValue->dwFileVersionMS & 0xFFFF,
224 $pValue->dwFileVersionLS >> 16,
225 $pValue->dwFileVersionLS & 0xFFFF);
230 // Read "RT_VERSION/VERSIONINFO" exe/dll resource info for MSWin32 binaries
231 // The "win32std" extension is not ready yet to pass back a VERSIONINFO struct
232 function exeversion_resopen($file) {
233 if (function_exists('res_list_type') or loadPhpExtension('win32std')) {
234 // See http://msdn.microsoft.com/workshop/networking/predefined/res.asp
235 $v = file_get_contents('res://'.realpath($file).urlencode('/RT_VERSION/#1'));
237 // This is really a binary VERSIONINFO block, with lots of
238 // nul bytes (widechar) which cannot be transported as string.
242 $h = res_open(realpath($file));
243 $v = res_get($h, 'RT_VERSION', 'FileVersion');
247 $h = res_open(realpath($file));
248 $v = res_get($h, '#1', 'RT_VERSION', 1);
253 /* The version consists of two 32-bit integers, defined by four 16-bit integers.
254 For example, "FILEVERSION 3,10,0,61" is translated into two doublewords:
255 0x0003000a and 0x0000003d, in that order. */
257 $h = res_open(realpath($file));
259 echo "Res list of '$file': \n";
260 $list= res_list_type($h, true);
261 if( $list===FALSE ) err( "Can't list type" );
263 for( $i= 0; $i<count($list); $i++ ) {
265 $res= res_list($h, $list[$i]);
266 for( $j= 0; $j<count($res); $j++ ) {
267 echo "\t".$res[$j]."\n";
270 echo "Res get: ".res_get( $h, 'A_TYPE', 'A_RC_NAME' )."\n\n";
285 $Log: not supported by cvs2svn $
286 Revision 1.3 2005/10/29 13:35:00 rurban
287 fix Log:, add chdir() if not in PHPWIKI_DIR, fix ->warning
297 // c-hanging-comment-ender-p: nil
298 // indent-tabs-mode: nil