From 9dee6257cbe03bac0e91145f57e7aa72c21ed358 Mon Sep 17 00:00:00 2001 From: rurban Date: Sat, 29 Oct 2005 09:00:05 +0000 Subject: [PATCH] This plugin displays the version, date, size, perms of an uploaded file. Only files relative and below to the uploads path can be handled. Usage: git-svn-id: svn://svn.code.sf.net/p/phpwiki/code/trunk@4923 96ab9672-09ca-45d6-a79d-3d69d39ca109 --- lib/plugin/FileInfo.php | 267 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 lib/plugin/FileInfo.php diff --git a/lib/plugin/FileInfo.php b/lib/plugin/FileInfo.php new file mode 100644 index 000000000..e95bfd4a9 --- /dev/null +++ b/lib/plugin/FileInfo.php @@ -0,0 +1,267 @@ + + * + * + * @author: ReiniUrban + */ + +class WikiPlugin_FileInfo +extends WikiPlugin +{ + function getName () { + return _("FileInfo"); + } + + function getDescription () { + return _("Display file information like version,size,date,... of uploaded files."); + } + + function getVersion() { + return preg_replace("/[Revision: $]/", '', + "\$Revision: 1.1 $"); + } + + function getDefaultArguments() { + return array( + 'file' => false, // relative path from PHPWIKI_DIR. (required) + 'display' => false, // version,size,date,mtime,owner,name,path,dirname,link. (required) + 'format' => false, // printf format string with %s only, all display modes + // from above vars return strings (optional) + ); + } + + function run($dbi, $argstr, &$request, $basepage) { + extract($this->getArgs($argstr, $request)); + if (!$file) + return $this->error(sprintf(_("A required argument '%s' is missing."), 'file')); + if (!$display) + return $this->error(sprintf(_("A required argument '%s' is missing."), 'display')); + + // sanify $file name + if (!file_exists($file)) { + return $this->warning("file \"$file\" not found"); + } + $realfile = realpath($file); + if (!string_starts_with($realfile, realpath(getUploadDataPath()))) + return $this->warning("invalid path \"$file\""); + else + $isuploaded = 1; + $s = array(); + $modes = explode(",", $display); + foreach ($modes as $mode) { + switch ($mode) { + case 'version': $s[] = $this->exeversion($file); break; + case 'size': $s[] = filesize($file); break; + case 'date': $s[] = strftime("%x %X", filemtime($file)); break; + case 'mtime': $s[] = filemtime($file); break; + case 'name': $s[] = basename($file); break; + case 'path': $s[] = $file; break; + case 'dirname': $s[] = dirname($file); break; + case 'magic': $s[] = $this->magic($file); break; + case 'mime-typ': $s[] = $this->mime_type($file); break; + case 'link': + if ($isuploaded) { + $s[] = "[Upload:".basename($file)."]"; + } else { + $s[] = "[".basename($file)."]"; + } + break; + default: + return $this->error(sprintf(_("Unsupported argument: %s=%s"), 'display', $mode)); + break; + } + } + if (!$format) { + $format = ''; + foreach ($s as $x) { $format .= " %s"; } + } + array_unshift($s, $format); + // $x, array($i,$j) => sprintf($x, $i, $j) + $result = call_user_func_array("sprintf", $s); + if (in_array('link', $modes)) { + require_once("lib/InlineParser.php"); + return TransformInline($result); + } else { + return $result; + } + } + + function magic($file) { + if (function_exists('finfo_file') or loadPhpExtension('fileinfo')) { + // Valid finfo_open (i.e. libmagic) options: + // FILEINFO_NONE | FILEINFO_SYMLINK | FILEINFO_MIME | FILEINFO_COMPRESS | FILEINFO_DEVICES | + // FILEINFO_CONTINUE | FILEINFO_PRESERVE_ATIME | FILEINFO_RAW + $f = finfo_open(/*FILEINFO_MIME*/); + $result = finfo_file(realpath($file)); + finfo_close($res); + return $result; + } + return ''; + } + + function mime_type($file) { + return ''; + } + + function exeversion($file) { + if (!isWindows()) return "?"; + if (class_exists('ffi') or loadPhpExtension('ffi')) + return $this->exeversion_ffi($file); + if (function_exists('res_list_type') or loadPhpExtension('win32std')) + return $this->exeversion_resopen($file); + return exeversion_showver($file); + return ''; + } + + // http://www.codeproject.com/dll/showver.asp + function exeversion_showver($file) { + $path = realpath($file); + $result = `showver $path`; + return "?"; + } + + function exeversion_ffi($file) { + if (!DEBUG) + return "?"; // not yet stable + + if (function_exists('ffi') or loadPhpExtension('ffi')) { + $win32_idl = " +struct VS_FIXEDFILEINFO { + DWORD dwSignature; + DWORD dwStrucVersion; + DWORD dwFileVersionMS; + DWORD dwFileVersionLS; + DWORD dwProductVersionMS; + DWORD dwProductVersionLS; + DWORD dwFileFlagsMask; + DWORD dwFileFlags; + DWORD dwFileOS; + DWORD dwFileType; + DWORD dwFileSubtype; + DWORD dwFileDateMS; + DWORD dwFileDateLS; +}; +struct VS_VERSIONINFO { struct VS_VERSIONINFO + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[1]; + WORD Padding1[1]; + VS_FIXEDFILEINFO Value; + WORD Padding2[1]; + WORD Children[1]; +}; +[lib='kernel32.dll'] DWORD GetFileVersionInfoSizeA(char *szFileName, DWORD *dwVerHnd); +[lib='kernel32.dll'] int GetFileVersionInfoA(char *sfnFile, DWORD dummy, DWORD size, struct VS_VERSIONINFO *pVer); +"; + $ffi = new ffi($win32_idl); + $dummy = 0; // &DWORD + $size = $ffi->GetFileVersionInfoSizeA($file, $dummy); + //$pVer = str_repeat($size+1); + $pVer = new ffi_struct($ffi, "VS_VERSIONINFO"); + if ($ffi->GetFileVersionInfoA($file, 0, $size, $pVer) + and $pVer->wValueLength) { + // analyze the VS_FIXEDFILEINFO(Value); + // $pValue = new ffi_struct($ffi, "VS_FIXEDFILEINFO"); + $pValue =& $pVer->Value; + return sprintf("%d.%d.%d.%d", + $pValue->dwFileVersionMS >> 16, + $pValue->dwFileVersionMS & 0xFFFF, + $pValue->dwFileVersionLS >> 16, + $pValue->dwFileVersionLS & 0xFFFF); + } + } + } + + // Read "RT_VERSION/VERSIONINFO" exe/dll resource info for MSWin32 binaries + // The "win32std" extension is not ready yet to pass back a VERSIONINFO struct + function exeversion_resopen($file) { + if (function_exists('res_list_type') or loadPhpExtension('win32std')) { + // See http://msdn.microsoft.com/workshop/networking/predefined/res.asp + $v = file_get_contents('res://'.realpath($file).urlencode('/RT_VERSION/#1')); + if ($v) { + // This is really a binary VERSIONINFO block, with lots of + // nul bytes (widechar) which cannot be transported as string. + return "$v"; + } + else { + $h = res_open(realpath($file)); + $v = res_get($h, 'RT_VERSION', 'FileVersion'); + res_close($h); + if ($v) return $v; + + $h = res_open(realpath($file)); + $v = res_get($h, '#1', 'RT_VERSION', 1); + res_close($h); + if ($v) return $v; + } + + /* The version consists of two 32-bit integers, defined by four 16-bit integers. + For example, "FILEVERSION 3,10,0,61" is translated into two doublewords: + 0x0003000a and 0x0000003d, in that order. */ +/* + $h = res_open(realpath($file)); + + echo "Res list of '$file': \n"; + $list= res_list_type($h, true); + if( $list===FALSE ) err( "Can't list type" ); + + for( $i= 0; $i \ No newline at end of file -- 2.45.0