PageRenderTime 65ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/lib/upgrade.php

https://bitbucket.org/DennisSchulmeister/www-wikiberd
PHP | 1594 lines | 1531 code | 18 blank | 45 comment | 19 complexity | 4fdbf75845b56f121431f32fc7efe691 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php
  2. /*
  3. This include() script adds missing PHP functions to earlier interpreter
  4. versions, so you can make downwards compatible scripts without having
  5. to stick to the least common denominator. It only defines the ones that
  6. are really missing - the faster native functions will be used whenever
  7. available.
  8. - many of the emulation functions are one-liners
  9. - a few features have been added that never made it into one of the
  10. official versions (CVS code and the ever-absent "gzdecode" and
  11. "file_put_contents" for example)
  12. - a few very extravagant functions (array_u?diff*_u*assoc?) and other
  13. extensions have been separated out into ext/
  14. - the advanced OO-capabilities and language syntax extensions of PHP5
  15. and ZE2 cannot seriously be emulated here, this script only takes care
  16. of procedural interfaces
  17. - with only this part loaded, you get "PHP 4.1 COMPATIBILITY"
  18. - this is PuplicDomain (no copyright, no license, no warranty) so you
  19. can melt it into anything, regardless of your preferred license (you
  20. may strip this paragraph and turn it all into GPL, BSD, GNU LGPL,
  21. Artistic, MPL, PHP license, M$ EULA, or whatever you like best)
  22. Get update notes via "http://freshmeat.net/projects/upgradephp" or
  23. google for it. Any contribution is appreciated. <milky*users新f搖et>
  24. */
  25. #------------------------------------------------------------------ CVS ---
  26. // most of this appeared in 5.0
  27. // ...
  28. #------------------------------------------------------------------ 6.0 ---
  29. // following functions were never implemented in PHP
  30. #-- inflates a string enriched with gzip headers
  31. # (this is the logical counterpart to gzencode(), but don't tell anyone!)
  32. if (!function_exists("gzdecode")) {
  33. function gzdecode($data, $maxlen=NULL) {
  34. #-- decode header
  35. $len = strlen($data);
  36. if ($len < 20) {
  37. return;
  38. }
  39. $head = substr($data, 0, 10);
  40. $head = unpack("n1id/C1cm/C1flg/V1mtime/C1xfl/C1os", $head);
  41. list($ID, $CM, $FLG, $MTIME, $XFL, $OS) = array_values($head);
  42. $FTEXT = 1<<0;
  43. $FHCRC = 1<<1;
  44. $FEXTRA = 1<<2;
  45. $FNAME = 1<<3;
  46. $FCOMMENT = 1<<4;
  47. $head = unpack("V1crc/V1isize", substr($data, $len-8, 8));
  48. list($CRC32, $ISIZE) = array_values($head);
  49. #-- check gzip stream identifier
  50. if ($ID != 0x1f8b) {
  51. trigger_error("gzdecode: not in gzip format", E_USER_WARNING);
  52. return;
  53. }
  54. #-- check for deflate algorithm
  55. if ($CM != 8) {
  56. trigger_error("gzdecode: cannot decode anything but deflated streams", E_USER_WARNING);
  57. return;
  58. }
  59. #-- start of data, skip bonus fields
  60. $s = 10;
  61. if ($FLG & $FEXTRA) {
  62. $s += $XFL;
  63. }
  64. if ($FLG & $FNAME) {
  65. $s = strpos($data, "\000", $s) + 1;
  66. }
  67. if ($FLG & $FCOMMENT) {
  68. $s = strpos($data, "\000", $s) + 1;
  69. }
  70. if ($FLG & $FHCRC) {
  71. $s += 2; // cannot check
  72. }
  73. #-- get data, uncompress
  74. $data = substr($data, $s, $len-$s);
  75. if ($maxlen) {
  76. $data = gzinflate($data, $maxlen);
  77. return($data); // no checks(?!)
  78. }
  79. else {
  80. $data = gzinflate($data);
  81. }
  82. #-- check+fin
  83. $chk = crc32($data);
  84. if ($CRC32 != $chk) {
  85. trigger_error("gzdecode: checksum failed (real$chk != comp$CRC32)", E_USER_WARNING);
  86. }
  87. elseif ($ISIZE != strlen($data)) {
  88. trigger_error("gzdecode: stream size mismatch", E_USER_WARNING);
  89. }
  90. else {
  91. return($data);
  92. }
  93. }
  94. }
  95. #-- get all already made headers(),
  96. # CANNOT be emulated, because output buffering functions
  97. # already swallow up any sent http header
  98. if (!function_exists("ob_get_headers")) {
  99. function ob_get_headers() {
  100. return (array)NULL;
  101. }
  102. }
  103. #-- encodes required named XML entities, like htmlentities(),
  104. # but does not re-encode numeric &#xxxx; character references
  105. # - could screw up scripts which then implement this themselves
  106. # - doesn't fix bogus or invalid numeric entities
  107. if (!function_exists("xmlentities")) {
  108. function xmlentities($str) {
  109. return strtr($str, array(
  110. "&#"=>"&#", "&"=>"&amp;", "'"=>"&apos;",
  111. "<"=>"&lt;", ">"=>"&gt;", "\""=>"&quot;",
  112. ));
  113. }
  114. }
  115. #------------------------------------------------------------------ 5.0 ---
  116. # set_exception_handler - unimpl.
  117. # restore_exception_handler - unimpl.
  118. # debug_print_backtrace - unimpl.
  119. # class_implements - unimplementable
  120. # proc_terminate - unimpl?
  121. # proc_get_status - unimpl.
  122. # --
  123. # proc_nice
  124. # dns_get_record
  125. # date_sunrise - undoc.
  126. # date_sunset - undoc.
  127. #-- constant: end of line
  128. if (!defined("PHP_EOL")) {
  129. define("PHP_EOL", ( (DIRECTORY_SEPARATOR == "\\") ?"\015\012" :(strncmp(PHP_OS,"D",1)?"\012":"\015") ) ); #"
  130. }
  131. #-- case-insensitive string search function,
  132. # - finds position of first occourence of a string c-i
  133. # - parameters identical to strpos()
  134. if (!function_exists("stripos")) {
  135. function stripos($haystack, $needle, $offset=NULL) {
  136. #-- simply lowercase args
  137. $haystack = strtolower($haystack);
  138. $needle = strtolower($needle);
  139. #-- search
  140. $pos = strpos($haystack, $needle, $offset);
  141. return($pos);
  142. }
  143. }
  144. #-- case-insensitive string search function
  145. # - but this one starts from the end of string (right to left)
  146. # - offset can be negative or positive
  147. if (!function_exists("strripos")) {
  148. function strripos($haystack, $needle, $offset=NULL) {
  149. #-- lowercase incoming strings
  150. $haystack = strtolower($haystack);
  151. $needle = strtolower($needle);
  152. #-- [-]$offset tells to ignore a few string bytes,
  153. # we simply cut a bit from the right
  154. if (isset($offset) && ($offset < 0)) {
  155. $haystack = substr($haystack, 0, strlen($haystack) - 1);
  156. }
  157. #-- let PHP do it
  158. $pos = strrpos($haystack, $needle);
  159. #-- [+]$offset => ignore left haystack bytes
  160. if (isset($offset) && ($offset > 0) && ($pos > $offset)) {
  161. $pos = false;
  162. }
  163. #-- result
  164. return($pos);
  165. }
  166. }
  167. #-- case-insensitive version of str_replace
  168. if (!function_exists("str_ireplace")) {
  169. function str_ireplace($search, $replace, $subject, $count=NULL) {
  170. #-- call ourselves recursively, if parameters are arrays/lists
  171. if (is_array($search)) {
  172. $replace = array_values($replace);
  173. foreach (array_values($search) as $i=>$srch) {
  174. $subject = str_ireplace($srch, $replace[$i], $subject);
  175. }
  176. }
  177. #-- sluice replacement strings through the Perl-regex module
  178. # (faster than doing it by hand)
  179. else {
  180. $replace = addcslashes($replace, "$\\");
  181. $search = "{" . preg_quote($search) . "}i";
  182. $subject = preg_replace($search, $replace, $subject);
  183. }
  184. #-- result
  185. return($subject);
  186. }
  187. }
  188. #-- performs a http HEAD request
  189. if (!function_exists("get_headers")) {
  190. function get_headers($url, $parse=0) {
  191. #-- extract URL parts ($host, $port, $path, ...)
  192. $c = parse_url($url);
  193. extract($c);
  194. if (!isset($port)) {
  195. $port = 80;
  196. }
  197. #-- try to open TCP connection
  198. $f = fsockopen($host, $port, $errno, $errstr, $timeout=15);
  199. if (!$f) {
  200. return;
  201. }
  202. #-- send request header
  203. socket_set_blocking($f, true);
  204. fwrite($f, "HEAD $path HTTP/1.0\015\012"
  205. . "Host: $host\015\012"
  206. . "Connection: close\015\012"
  207. . "Accept: */*, xml/*\015\012"
  208. . "User-Agent: ".trim(ini_get("user_agent"))."\015\012"
  209. . "\015\012");
  210. #-- read incoming lines
  211. $ls = array();
  212. while ( !feof($f) && ($line = trim(fgets($f, 1<<16))) ) {
  213. #-- read header names to make result an hash (names in array index)
  214. if ($parse) {
  215. if ($l = strpos($line, ":")) {
  216. $name = substr($line, 0, $l);
  217. $value = trim(substr($line, $l + 1));
  218. #-- merge headers
  219. if (isset($ls[$name])) {
  220. $ls[$name] .= ", $value";
  221. }
  222. else {
  223. $ls[$name] = $value;
  224. }
  225. }
  226. #-- HTTP response status header as result[0]
  227. else {
  228. $ls[] = $line;
  229. }
  230. }
  231. #-- unparsed header list (numeric indices)
  232. else {
  233. $ls[] = $line;
  234. }
  235. }
  236. #-- close TCP connection and give result
  237. fclose($f);
  238. return($ls);
  239. }
  240. }
  241. #-- list of already/potentially sent HTTP responsee headers(),
  242. # CANNOT be implemented (except for Apache module maybe)
  243. if (!function_exists("headers_list")) {
  244. function headers_list() {
  245. trigger_error("headers_list(): not supported by this PHP version", E_USER_WARNING);
  246. return (array)NULL;
  247. }
  248. }
  249. #-- write formatted string to stream/file,
  250. # arbitrary numer of arguments
  251. if (!function_exists("fprintf")) {
  252. function fprintf(/*...*/) {
  253. $args = func_get_args();
  254. $stream = array_shift($args);
  255. return fwrite($stream, call_user_func_array("sprintf", $args));
  256. }
  257. }
  258. #-- write formatted string to stream, args array
  259. if (!function_exists("vfprintf")) {
  260. function vfprintf($stream, $format, $args=NULL) {
  261. return fwrite($stream, vsprintf($format, $args));
  262. }
  263. }
  264. #-- splits a string in evenly sized chunks
  265. # and returns this as array
  266. if (!function_exists("str_split")) {
  267. function str_split($str, $chunk=1) {
  268. $r = array();
  269. #-- return back as one chunk completely, if size chosen too low
  270. if ($chunk < 1) {
  271. $r[] = $str;
  272. }
  273. #-- add substrings to result array until subject strings end reached
  274. else {
  275. $len = strlen($str);
  276. for ($n=0; $n<$len; $n+=$chunk) {
  277. $r[] = substr($str, $n, $chunk);
  278. }
  279. }
  280. return($r);
  281. }
  282. }
  283. #-- constructs a QUERY_STRING (application/x-www-form-urlencoded format, non-raw)
  284. # from a nested array/hash with name=>value pairs
  285. # - only first two args are part of the original API - rest used for recursion
  286. if (!function_exists("http_build_query")) {
  287. function http_build_query($data, $int_prefix="", $subarray_pfix="", $level=0) {
  288. #-- empty starting string
  289. $s = "";
  290. ($SEP = ini_get("arg_separator.output")) or ($SEP = "&");
  291. #-- traverse hash/array/list entries
  292. foreach ($data as $index=>$value) {
  293. #-- add sub_prefix for subarrays (happens for recursed innovocation)
  294. if ($subarray_pfix) {
  295. if ($level) {
  296. $index = "[" . $index . "]";
  297. }
  298. $index = $subarray_pfix . $index;
  299. }
  300. #-- add user-specified prefix for integer-indices
  301. elseif (is_int($index) && strlen($int_prefix)) {
  302. $index = $int_prefix . $index;
  303. }
  304. #-- recurse for sub-arrays
  305. if (is_array($value)) {
  306. $s .= http_build_query($value, "", $index, $level + 1);
  307. }
  308. else { // or just literal URL parameter
  309. $s .= $SEP . $index . "=" . urlencode($value);
  310. }
  311. }
  312. #-- remove redundant "&" from first round (-not checked above to simplifiy loop)
  313. if (!$subarray_pfix) {
  314. $s = substr($s, strlen($SEP));
  315. }
  316. #-- return result / to previous array level and iteration
  317. return($s);
  318. }
  319. }
  320. #-- transform into 3to4 uuencode
  321. # - this is the bare encoding, not the uu file format
  322. if (!function_exists("convert_uuencode")) {
  323. function convert_uuencode($data) {
  324. #-- init vars
  325. $out = "";
  326. $line = "";
  327. $len = strlen($data);
  328. # $data .= "\252\252\252"; // PHP and uuencode(1) use some special garbage??, looks like "\000"* and "`\n`" simply appended
  329. #-- canvass source string
  330. for ($n=0; $n<$len; ) {
  331. #-- make 24-bit integer from first three bytes
  332. $x = (ord($data[$n++]) << 16)
  333. + (ord($data[$n++]) << 8)
  334. + (ord($data[$n++]) << 0);
  335. #-- disperse that into 4 ascii characters
  336. $line .= chr( 32 + (($x >> 18) & 0x3f) )
  337. . chr( 32 + (($x >> 12) & 0x3f) )
  338. . chr( 32 + (($x >> 6) & 0x3f) )
  339. . chr( 32 + (($x >> 0) & 0x3f) );
  340. #-- cut lines, inject count prefix before each
  341. if (($n % 45) == 0) {
  342. $out .= chr(32 + 45) . "$line\n";
  343. $line = "";
  344. }
  345. }
  346. #-- throw last line, +length prefix
  347. if ($trail = ($len % 45)) {
  348. $out .= chr(32 + $trail) . "$line\n";
  349. }
  350. // uuencode(5) doesn't tell so, but spaces are replaced with the ` char in most implementations
  351. $out = strtr("$out \n", " ", "`");
  352. return($out);
  353. }
  354. }
  355. #-- decodes uuencoded() data again
  356. if (!function_exists("convert_uudecode")) {
  357. function convert_uudecode($data) {
  358. #-- prepare
  359. $out = "";
  360. $data = strtr($data, "`", " ");
  361. #-- go through lines
  362. foreach(explode("\n", ltrim($data)) as $line) {
  363. if (!strlen($line)) {
  364. break; // end reached
  365. }
  366. #-- current line length prefix
  367. unset($num);
  368. $num = ord($line{0}) - 32;
  369. if (($num <= 0) || ($num > 62)) { // 62 is the maximum line length
  370. break; // according to uuencode(5), so we stop here too
  371. }
  372. $line = substr($line, 1);
  373. #-- prepare to decode 4-char chunks
  374. $add = "";
  375. for ($n=0; strlen($add)<$num; ) {
  376. #-- merge 24 bit integer from the 4 ascii characters (6 bit each)
  377. $x = ((ord($line[$n++]) - 32) << 18)
  378. + ((ord($line[$n++]) - 32) << 12) // were saner with "& 0x3f"
  379. + ((ord($line[$n++]) - 32) << 6)
  380. + ((ord($line[$n++]) - 32) << 0);
  381. #-- reconstruct the 3 original data chars
  382. $add .= chr( ($x >> 16) & 0xff )
  383. . chr( ($x >> 8) & 0xff )
  384. . chr( ($x >> 0) & 0xff );
  385. }
  386. #-- cut any trailing garbage (last two decoded chars may be wrong)
  387. $out .= substr($add, 0, $num);
  388. $line = "";
  389. }
  390. return($out);
  391. }
  392. }
  393. #-- return array of filenames in a given directory
  394. # (only works for local files)
  395. if (!function_exists("scandir")) {
  396. function scandir($dirname, $desc=0) {
  397. #-- check for file:// protocol, others aren't handled
  398. if (strpos($dirname, "file://") === 0) {
  399. $dirname = substr($dirname, 7);
  400. if (strpos($dirname, "localh") === 0) {
  401. $dirname = substr($dirname, strpos($dirname, "/"));
  402. }
  403. }
  404. #-- directory reading handle
  405. if ($dh = opendir($dirname)) {
  406. $ls = array();
  407. while ($fn = readdir($dh)) {
  408. $ls[] = $fn; // add to array
  409. }
  410. closedir($dh);
  411. #-- sort filenames
  412. if ($desc) {
  413. rsort($ls);
  414. }
  415. else {
  416. sort($ls);
  417. }
  418. return $ls;
  419. }
  420. #-- failure
  421. return false;
  422. }
  423. }
  424. #-- like date(), but returns an integer for given one-letter format parameter
  425. if (!function_exists("idate")) {
  426. function idate($formatchar, $timestamp=NULL) {
  427. #-- reject non-simple type parameters
  428. if (strlen($formatchar) != 1) {
  429. return false;
  430. }
  431. #-- get current time, if not given
  432. if (!isset($timestamp)) {
  433. $timestamp = time();
  434. }
  435. #-- get and turn into integer
  436. $str = date($formatchar, $timestamp);
  437. return (int)$str;
  438. }
  439. }
  440. #-- combined sleep() and usleep()
  441. if (!function_exists("time_nanosleep")) {
  442. function time_nanosleep($sec, $nano) {
  443. sleep($sec);
  444. usleep($nano);
  445. }
  446. }
  447. #-- search first occourence of any of the given chars, returns rest of haystack
  448. # (char_list must be a string for compatibility with the real PHP func)
  449. if (!function_exists("strpbrk")) {
  450. function strpbrk($haystack, $char_list) {
  451. #-- prepare
  452. $len = strlen($char_list);
  453. $min = strlen($haystack);
  454. #-- check with every symbol from $char_list
  455. for ($n = 0; $n < $len; $n++) {
  456. $l = strpos($haystack, $char_list{$n});
  457. #-- get left-most occourence
  458. if (($l !== false) && ($l < $min)) {
  459. $min = $l;
  460. }
  461. }
  462. #-- result
  463. if ($min) {
  464. return(substr($haystack, $min));
  465. }
  466. else {
  467. return(false);
  468. }
  469. }
  470. }
  471. #-- logo image activation URL query strings (gaga feature)
  472. if (!function_exists("php_real_logo_guid")) {
  473. function php_real_logo_guid() { return php_logo_guid(); }
  474. function php_egg_logo_guid() { return zend_logo_guid(); }
  475. }
  476. #-- no need to implement this
  477. # (there aren't interfaces in PHP4 anyhow)
  478. if (!function_exists("get_declared_interfaces")) {
  479. function get_declared_interfaces() {
  480. trigger_error("get_declared_interfaces(): Current script won't run reliably with PHP4.", E_USER_WARNING);
  481. return( (array)NULL );
  482. }
  483. }
  484. #-- creates an array from lists of $keys and $values
  485. # (both should have same number of entries)
  486. if (!function_exists("array_combine")) {
  487. function array_combine($keys, $values) {
  488. #-- convert input arrays into lists
  489. $keys = array_values($keys);
  490. $values = array_values($values);
  491. $r = array();
  492. #-- one from each
  493. foreach ($values as $i=>$val) {
  494. if ($key = $keys[$i]) {
  495. $r[$key] = $val;
  496. }
  497. else {
  498. $r[] = $val; // useless, PHP would have long aborted here
  499. }
  500. }
  501. return($r);
  502. }
  503. }
  504. #-- apply userfunction to each array element (descending recursively)
  505. # use it like: array_walk_recursive($_POST, "stripslashes");
  506. # - $callback can be static function name or object/method, class/method
  507. if (!function_exists("array_walk_recursive")) {
  508. function array_walk_recursive(&$input, $callback, $userdata=NULL) {
  509. #-- each entry
  510. foreach ($input as $key=>$value) {
  511. #-- recurse for sub-arrays
  512. if (is_array($value)) {
  513. array_walk_recursive($input[$key], $callback, $userdata);
  514. }
  515. #-- $callback handles scalars
  516. else {
  517. call_user_func_array($callback, array(&$input[$key], $key, $userdata) );
  518. }
  519. }
  520. // no return value
  521. }
  522. }
  523. #-- complicated wrapper around substr() and and strncmp()
  524. if (!function_exists("substr_compare")) {
  525. function substr_compare($haystack, $needle, $offset=0, $len=0, $ci=0) {
  526. #-- check params
  527. if ($len <= 0) { // not well documented
  528. $len = strlen($needle);
  529. if (!$len) { return(0); }
  530. }
  531. #-- length exception
  532. if ($len + $offset >= strlen($haystack)) {
  533. trigger_error("substr_compare: given length exceeds main_str", E_USER_WARNING);
  534. return(false);
  535. }
  536. #-- cut
  537. if ($offset) {
  538. $haystack = substr($haystack, $offset, $len);
  539. }
  540. #-- case-insensitivity
  541. if ($ci) {
  542. $haystack = strtolower($haystack);
  543. $needle = strtolower($needle);
  544. }
  545. #-- do
  546. return(strncmp($haystack, $needle, $len));
  547. }
  548. }
  549. #-- stub, returns empty list as usual;
  550. # you must load "ext/spl.php" beforehand to get this
  551. if (!function_exists("spl_classes")) {
  552. function spl_classes() {
  553. trigger_error("spl_classes(): not built into this PHP version");
  554. return (array)NULL;
  555. }
  556. }
  557. #-- gets you list of class names the given objects class was derived from, slow
  558. if (!function_exists("class_parents")) {
  559. function class_parents($obj) {
  560. #-- first get full list
  561. $all = get_declared_classes();
  562. $r = array();
  563. #-- filter out
  564. foreach ($all as $potential_parent) {
  565. if (is_subclass_of($obj, $potential_parent)) {
  566. $r[$potential_parent] = $potential_parent;
  567. }
  568. }
  569. return($r);
  570. }
  571. }
  572. #-- an alias
  573. if (!function_exists("session_commit") && function_exists("session_write_close")) {
  574. function session_commit() {
  575. // simple
  576. session_write_close();
  577. }
  578. }
  579. #-- aliases
  580. if (!function_exists("dns_check_record")) {
  581. function dns_check_record($host, $type=NULL) {
  582. // synonym to
  583. return checkdnsrr($host, $type);
  584. }
  585. }
  586. if (!function_exists("dns_get_mx")) {
  587. function dns_get_mx($host, $mx) {
  588. $args = func_get_args();
  589. // simple alias - except the optional, but referenced third parameter
  590. if ($args[2]) {
  591. $w = & $args[2];
  592. }
  593. else {
  594. $w = false;
  595. }
  596. return getmxrr($host, $mx, $w);
  597. }
  598. }
  599. #-- setrawcookie(),
  600. # can this be emulated 100% exactly?
  601. if (!function_exists("setrawcookie")) {
  602. // we output everything directly as HTTP header(), PHP doesn't seem
  603. // to manage an internal cookie list anyhow
  604. function setrawcookie($name, $value=NULL, $expire=NULL, $path=NULL, $domain=NULL, $secure=0) {
  605. if (isset($value) && strpbrk($value, ",; \r\t\n\f\014\013")) {
  606. trigger_error("setrawcookie: value may not contain any of ',; \r\n' and some other control chars; thrown away", E_USER_WARNING);
  607. }
  608. else {
  609. $h = "Set-Cookie: $name=$value"
  610. . ($expire ? "; expires=" . gmstrftime("%a, %d-%b-%y %H:%M:%S %Z", $expire) : "")
  611. . ($path ? "; path=$path": "")
  612. . ($domain ? "; domain=$domain" : "")
  613. . ($secure ? "; secure" : "");
  614. header($h);
  615. }
  616. }
  617. }
  618. #-- write-at-once file access (counterpart to file_get_contents)
  619. if (!function_exists("file_put_contents")) {
  620. function file_put_contents($filename, $data, $flags=0, $resource=NULL) {
  621. #-- prepare
  622. $mode = ($flags & FILE_APPEND ? "a" : "w" ) ."b";
  623. $incl = $flags & FILE_USE_INCLUDE_PATH;
  624. $length = strlen($data);
  625. #-- open for writing
  626. $f = fopen($filename, $mode, $incl);
  627. if ($f) {
  628. $written = fwrite($f, $data);
  629. fclose($f);
  630. #-- only report success, if completely saved
  631. return($length == $written);
  632. }
  633. }
  634. }
  635. #-- file-related constants
  636. if (!defined("FILE_APPEND")) {
  637. define("FILE_USE_INCLUDE_PATH", 1);
  638. define("FILE_IGNORE_NEW_LINES", 2);
  639. define("FILE_SKIP_EMPTY_LINES", 4);
  640. define("FILE_APPEND", 8);
  641. define("FILE_NO_DEFAULT_CONTEXT", 16);
  642. }
  643. #-- more new constants for 5.0
  644. if (!defined("E_STRICT")) {
  645. define("E_STRICT", 2048); // _STRICT is a special case of _NOTICE (_DEBUG)
  646. # PHP_CONFIG_FILE_SCAN_DIR
  647. }
  648. #-- array count_recursive()
  649. if (!defined("COUNT_RECURSIVE")) {
  650. define("COUNT_NORMAL", 0); // count($array, 0);
  651. define("COUNT_RECURSIVE", 1); // not supported
  652. }
  653. #-- we introduce a new function, because we cannot emulate the
  654. # newly introduced second parameter to count()
  655. if (!function_exists("count_recursive")) {
  656. function count_recursive($array, $mode=1) {
  657. if (!$mode) {
  658. return(count($array));
  659. }
  660. else {
  661. $c = count($array);
  662. foreach ($array as $sub) {
  663. if (is_array($sub)) {
  664. $c += count_recursive($sub);
  665. }
  666. }
  667. return($c);
  668. }
  669. }
  670. }
  671. #------------------------------------------------------------------ 4.3 ---
  672. # money_format - unimpl?
  673. # sha1, sha1_file - too much code to pack it into here; and this
  674. # has already been implemented elsewhere, btw
  675. #-- simplified file read-at-once function
  676. if (!function_exists("file_get_contents")) {
  677. function file_get_contents($filename, $use_include_path=1) {
  678. #-- open file, let fopen() report error
  679. $f = fopen($filename, "rb", $use_include_path);
  680. if (!$f) { return; }
  681. #-- read max 2MB
  682. $content = fread($f, 1<<21);
  683. fclose($f);
  684. return($content);
  685. }
  686. }
  687. #-- shell-like filename matching (* and ? globbing characters)
  688. if (!function_exists("fnmatch")) {
  689. #-- associated constants
  690. define("FNM_PATHNAME", 1<<0); // no wildcard ever matches a "/"
  691. define("FNM_NOESCAPE", 1<<1); // backslash can't escape meta chars
  692. define("FNM_PERIOD", 1<<2); // leading dot must be given explicit
  693. define("FNM_LEADING_DIR", 1<<3); // not in PHP
  694. define("FNM_CASEFOLD", 0x50); // match case-insensitive
  695. define("FNM_EXTMATCH", 1<<5); // not in PHP
  696. #-- implementation
  697. function fnmatch($pattern, $str, $flags=0x0000) {
  698. #-- 'hidden' files
  699. if ($flags & FNM_PERIOD) {
  700. if (($str[0] == ".") && ($pattern[0] != ".")) {
  701. return(false); // abort early
  702. }
  703. }
  704. #-- case-insensitivity
  705. $rxci = "";
  706. if ($flags & FNM_CASEFOLD) {
  707. $rxci = "i";
  708. }
  709. #-- handline of pathname separators (/)
  710. $wild = ".";
  711. if ($flags & FNM_PATHNAME) {
  712. $wild = "[^/".DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR."]";
  713. }
  714. #-- check for cached regular expressions
  715. static $cmp = array();
  716. if (isset($cmp["$pattern+$flags"])) {
  717. $rx = $cmp["$pattern+$flags"];
  718. }
  719. #-- convert filename globs into regex
  720. else {
  721. $rx = preg_quote($pattern);
  722. $rx = strtr($rx, array(
  723. "\\*"=>"$wild*?", "\\?"=>"$wild", "\\["=>"[", "\\]"=>"]",
  724. ));
  725. $rx = "{^" . $rx . "$}" . $rxci;
  726. #-- cache
  727. if (count($cmp) >= 50) {
  728. $cmp = array(); // free
  729. }
  730. $cmp["$pattern+$flags"] = $rx;
  731. }
  732. #-- compare
  733. return(preg_match($rx, $str));
  734. }
  735. }
  736. #-- file search and name matching (with shell patterns)
  737. if (!function_exists("glob")) {
  738. #-- introduced constants
  739. define("GLOB_MARK", 1<<0);
  740. define("GLOB_NOSORT", 1<<1);
  741. define("GLOB_NOCHECK", 1<<2);
  742. define("GLOB_NOESCAPE", 1<<3);
  743. define("GLOB_BRACE", 1<<4);
  744. define("GLOB_ONLYDIR", 1<<5);
  745. define("GLOB_NOCASE", 1<<6);
  746. define("GLOB_DOTS", 1<<7);
  747. // unlikely to work under Win(?), without replacing the explode() with
  748. // a preg_split() incorporating the native DIRECTORY_SEPARATOR as well
  749. #-- implementation
  750. function glob($pattern, $flags=0x0000) {
  751. $ls = array();
  752. $rxci = ($flags & GLOB_NOCASE) ? "i" : "";
  753. #echo "\n=> glob($pattern)...\n";
  754. #-- transform glob pattern into regular expression
  755. # (similar to fnmatch() but still different enough to require a second func)
  756. if ($pattern) {
  757. #-- look at each directory/fn spec part separately
  758. $parts2 = explode("/", $pattern);
  759. $pat = preg_quote($pattern);
  760. $pat = strtr($pat, array("\\*"=>".*?", "\\?"=>".?"));
  761. if ($flags ^ GLOB_NOESCAPE) {
  762. // uh, oh, ouuch - the above is unclean enough...
  763. }
  764. if ($flags ^ GLOB_BRACE) {
  765. $pat = preg_replace("/\{(.+?)\}/e", 'strtr("[$1]", ",", "")', $pat);
  766. }
  767. $parts = explode("/", $pat);
  768. #echo "parts == ".implode(" // ", $parts) . "\n";
  769. $lasti = count($parts) - 1;
  770. $dn = "";
  771. foreach ($parts as $i=>$p) {
  772. #-- basedir included (yet no pattern matching necessary)
  773. if (!strpos($p, "*?") && (strpos($p, ".?")===false)) {
  774. $dn .= $parts2[$i] . ($i!=$lasti ? "/" : "");
  775. #echo "skip:$i, cause no pattern matching char found -> only a basedir spec\n";
  776. continue;
  777. }
  778. #-- start reading dir + match filenames against current pattern
  779. if ($dh = opendir($dn ?$dn:'.')) {
  780. $with_dot = ($p[1]==".") || ($flags & GLOB_DOTS);
  781. #echo "part:$i:$p\n";
  782. #echo "reading dir \"$dn\"\n";
  783. while ($fn = readdir($dh)) {
  784. if (preg_match("\007^$p$\007$rxci", $fn)) {
  785. #-- skip over 'hidden' files
  786. if (($fn[0] == ".") && !$with_dot) {
  787. continue;
  788. }
  789. #-- add filename only if last glob/pattern part
  790. if ($i==$lasti) {
  791. if (is_dir("$dn$fn")) {
  792. if ($flags & GLOB_ONLYDIR) {
  793. continue;
  794. }
  795. if ($flags & GLOB_MARK) {
  796. $fn .= "/";
  797. }
  798. }
  799. #echo "adding '$fn' for dn=$dn to list\n";
  800. $ls[] = "$dn$fn";
  801. }
  802. #-- initiate a subsearch, merge result list in
  803. elseif (is_dir("$dn$fn")) {
  804. // add reamaining search patterns to current basedir
  805. $remaind = implode("/", array_slice($parts2, $i+1));
  806. $ls = array_merge($ls, glob("$dn$fn/$remaind", $flags));
  807. }
  808. }
  809. }
  810. closedir($dh);
  811. #-- prevent scanning a 2nd part/dir in same glob() instance:
  812. break;
  813. }
  814. #-- given dirname doesn't exist
  815. else {
  816. return($ls);
  817. }
  818. }// foreach $parts
  819. }
  820. #-- return result list
  821. if (!$ls && ($flags & GLOB_NOCHECK)) {
  822. $ls[] = $pattern;
  823. }
  824. if ($flags ^ GLOB_NOSORT) {
  825. sort($ls);
  826. }
  827. #print_r($ls);
  828. #echo "<=\n";
  829. return($ls);
  830. }
  831. } //@FIX: fully comment, remove debugging code (- as soon as it works ;)
  832. #-- redundant alias for isset()
  833. if (!function_exists("array_key_exists")) {
  834. function array_key_exists($key, $search) {
  835. return isset($search[$key]);
  836. }
  837. }
  838. #-- who could need that?
  839. if (!function_exists("array_intersect_assoc")) {
  840. function array_intersect_assoc( /*array, array, array...*/ ) {
  841. #-- parameters, prepare
  842. $in = func_get_args();
  843. $cmax = count($in);
  844. $whatsleftover = array();
  845. #-- walk through each array pair
  846. # (take first as checklist)
  847. foreach ($in[0] as $i => $v) {
  848. for ($c = 1; $c < $cmax; $c++) {
  849. #-- remove entry, as soon as it isn't present
  850. # in one of the other arrays
  851. if (!isset($in[$c][$i]) || (@$in[$c][$i] !== $v)) {
  852. continue 2;
  853. }
  854. }
  855. #-- it was found in all other arrays
  856. $whatsleftover[$i] = $v;
  857. }
  858. return $whatsleftover;
  859. }
  860. }
  861. #-- the opposite of the above
  862. if (!function_exists("array_diff_assoc")) {
  863. function array_diff_assoc( /*array, array, array...*/ ) {
  864. #-- params
  865. $in = func_get_args();
  866. $diff = array();
  867. #-- compare each array with primary/first
  868. foreach ($in[0] as $i=>$v) {
  869. for ($c=1; $c<count($in); $c++) {
  870. #-- skip as soon as it matches with entry in another array
  871. if (isset($in[$c][$i]) && ($in[$c][$i] == $v)) {
  872. continue 2;
  873. }
  874. }
  875. #-- else
  876. $diff[$i] = $v;
  877. }
  878. return $diff;
  879. }
  880. }
  881. #-- opposite of htmlentities
  882. if (!function_exists("html_entity_decode")) {
  883. function html_entity_decode($string, $quote_style=ENT_COMPAT, $charset="ISO-8859-1") {
  884. //@FIX: we fall short on anything other than Latin-1
  885. $y = array_flip(get_html_translation_table(HTML_ENTITIES, $quote_style));
  886. return strtr($string, $y);
  887. }
  888. }
  889. #-- extracts single words from a string
  890. if (!function_exists("str_word_count")) {
  891. function str_word_count($string, $result=0) {
  892. #-- let someone else do the work
  893. preg_match_all('/([\w](?:[-\'\w]?[\w]+)*)/', $string, $uu);
  894. #-- return full word list
  895. if ($result == 1) {
  896. return($uu[1]);
  897. }
  898. #-- array() of $pos=>$word entries
  899. elseif ($result >= 2) {
  900. $r = array();
  901. $l = 0;
  902. foreach ($uu[1] as $word) {
  903. $l = strpos($string, $word, $l);
  904. $r[$l] = $word;
  905. $l += strlen($word); // speed up next search
  906. }
  907. return($r);
  908. }
  909. #-- only count
  910. else {
  911. return(count($uu[1]));
  912. }
  913. }
  914. }
  915. #-- creates a permutation of the given strings characters
  916. # (let's hope the random number generator was alread initialized)
  917. if (!function_exists("str_shuffle")) {
  918. function str_shuffle($str) {
  919. $r = "";
  920. #-- cut string down with every iteration
  921. while (strlen($str)) {
  922. $n = strlen($str) - 1;
  923. if ($n) {
  924. $n = rand(0, $n); // glibcs` rand is ok since 2.1 at least
  925. }
  926. #-- cut out elected char, add to result string
  927. $r .= $str{$n};
  928. $str = substr($str, 0, $n) . substr($str, $n + 1);
  929. }
  930. return($r);
  931. }
  932. }
  933. #-- simple shorthands
  934. if (!function_exists("get_include_path")) {
  935. function get_include_path() {
  936. return(get_cfg_var("include_path"));
  937. }
  938. function set_include_path($new) {
  939. return ini_set("include_path", $new);
  940. }
  941. function restore_include_path() {
  942. ini_restore("include_path");
  943. }
  944. }
  945. #-- constants for 4.3
  946. if (!defined("PATH_SEPARATOR")) {
  947. define("PATH_SEPARATOR", ((DIRECTORY_SEPARATOR=='\\') ? ';' :':'));
  948. define("PHP_SHLIB_SUFFIX", ((DIRECTORY_SEPARATOR=='\\') ? 'dll' :'so'));
  949. }
  950. if (!defined("PHP_SAPI")) {
  951. define("PHP_SAPI", php_sapi_name());
  952. }
  953. #-- not identical to what PHP reports (it seems to `which` for itself)
  954. if (!defined("PHP_PREFIX") && isset($_ENV["_"])) {
  955. define("PHP_PREFIX", substr($_ENV["_"], 0, strpos($_ENV["_"], "bin/")));
  956. }
  957. #------------------------------------------------------------------ 4.2 ---
  958. # almost complete!?
  959. #-- shy away from this one - it was broken in all real PHP4.2 versions, and
  960. # this function emulation script won't change that
  961. if (!function_exists("str_rot13")) {
  962. function str_rot13($str) {
  963. static $from = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  964. static $to = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm";
  965. return strtr($str, $from, $to);
  966. }
  967. }
  968. #-- well, if you need it
  969. if (!function_exists("array_change_key_case")) {
  970. #-- introduced constants
  971. define("CASE_LOWER", 0);
  972. define("CASE_UPPER", 1);
  973. #-- implementation
  974. function array_change_key_case($array, $case=CASE_LOWER) {
  975. #-- loop through
  976. foreach ($array as $i=>$v) {
  977. #-- do anything for strings only
  978. if (is_string($i)) {
  979. unset($array[$i]);
  980. $i = ($case==CASE_LOWER) ? strtolower($i) : strtoupper($i);
  981. $array[$i] = $v;
  982. }
  983. // non-recursive
  984. }
  985. return($array);
  986. }
  987. }
  988. #-- create fixed-length array made up of $value data
  989. if (!function_exists("array_fill")) {
  990. function array_fill($start_index, $num, $value) {
  991. #-- params
  992. $r = array();
  993. $i = $start_index;
  994. $end = $num + $start_index;
  995. #-- append
  996. for (; $i < $end; $i++)
  997. {
  998. $r[$i] = $value;
  999. }
  1000. return($r);
  1001. }
  1002. }
  1003. #-- split an array into evenly sized parts
  1004. if (!function_exists("array_chunk")) {
  1005. function array_chunk($input, $size, $preserve_keys=false) {
  1006. #-- array for chunked output
  1007. $r = array();
  1008. $n = -1; // chunk index
  1009. #-- enum input array blocks
  1010. foreach ($input as $i=>$v) {
  1011. #-- new chunk
  1012. if (($n < 0) || (count($r[$n]) == $size)) {
  1013. $n++;
  1014. $r[$n] = array();
  1015. }
  1016. #-- add input value into current [$n] chunk
  1017. if ($preserve_keys) {
  1018. $r[$n][$i] = $v;
  1019. }
  1020. else {
  1021. $r[$n][] = $v;
  1022. }
  1023. }
  1024. return($r);
  1025. }
  1026. }
  1027. #-- convenience wrapper
  1028. if (!function_exists("md5_file")) {
  1029. function md5_file($filename, $raw_output=false) {
  1030. #-- read file, apply hash function
  1031. $data = file_get_contents($filename, "rb");
  1032. $r = md5($data);
  1033. $data = NULL;
  1034. #-- transform? and return
  1035. if ($raw_output) {
  1036. $r = pack("H*", $r);
  1037. }
  1038. return $r;
  1039. }
  1040. }
  1041. #-- object type checking
  1042. if (!function_exists("is_a")) {
  1043. function is_a($obj, $classname) {
  1044. #-- lowercase everything for comparison
  1045. $classnaqme = strtolower($classname);
  1046. $obj_class = strtolower(get_class($obj));
  1047. #-- two possible checks
  1048. return ($obj_class == $classname) or is_subclass_of($obj, $classname);
  1049. }
  1050. }
  1051. #-- floating point modulo
  1052. if (!function_exists("fmod")) {
  1053. function fmod($x, $y) {
  1054. $r = $x / $y;
  1055. $r -= (int)$r;
  1056. $r *= $y;
  1057. return($r);
  1058. }
  1059. }
  1060. #-- makes float variable from string
  1061. if (!function_exists("floatval")) {
  1062. function floatval($str) {
  1063. $str = ltrim($str);
  1064. return (float)$str;
  1065. }
  1066. }
  1067. #-- floats
  1068. if (!function_exists("is_infinite")) {
  1069. #-- constants as-is
  1070. define("NAN", "NAN");
  1071. define("INF", "INF"); // there is also "-INF"
  1072. #-- simple checks
  1073. function is_infinite($f) {
  1074. $s = (string)$f;
  1075. return( ($s=="INF") || ($s=="-INF") );
  1076. }
  1077. function is_nan($f) {
  1078. $s = (string)$f;
  1079. return( $s=="NAN" );
  1080. }
  1081. function is_finite($f) {
  1082. $s = (string)$f;
  1083. return( !strpos($s, "N") );
  1084. }
  1085. }
  1086. #-- throws value-instantiation PHP-code for given variable
  1087. # (a bit different from the standard, was intentional for its orig use)
  1088. if (!function_exists("var_export")) {
  1089. function var_export($var, $return=false, $indent="", $output="") {
  1090. #-- output as in-class variable definitions
  1091. if (is_object($var)) {
  1092. $output = "class " . get_class($var) . " {\n";
  1093. foreach (((array)$var) as $id=>$var) {
  1094. $output .= " var \$$id = " . var_export($var, true) . ";\n";
  1095. }
  1096. $output .= "}";
  1097. }
  1098. #-- array constructor
  1099. elseif (is_array($var)) {
  1100. foreach ($var as $id=>$next) {
  1101. if ($output) $output .= ",\n";
  1102. else $output = "array(\n";
  1103. $output .= $indent . ' '
  1104. . (is_numeric($id) ? $id : '"'.addslashes($id).'"')
  1105. . ' => ' . var_export($next, true, "$indent ");
  1106. }
  1107. if (empty($output)) $output = "array(";
  1108. $output .= "\n{$indent})";
  1109. #if ($indent == "") $output .= ";";
  1110. }
  1111. #-- literals
  1112. elseif (is_numeric($var)) {
  1113. $output = "$var";
  1114. }
  1115. elseif (is_bool($var)) {
  1116. $output = $var ? "true" : "false";
  1117. }
  1118. else {
  1119. $output = "'" . preg_replace("/([\\\\\'])/", '\\\\$1', $var) . "'";
  1120. }
  1121. #-- done
  1122. if ($return) {
  1123. return($output);
  1124. }
  1125. else {
  1126. print($output);
  1127. }
  1128. }
  1129. }
  1130. #-- strcmp() variant that respects locale setting,
  1131. # existed since PHP 4.0.5, but under Win32 first since 4.3.2
  1132. if (!function_exists("strcoll")) {
  1133. function strcoll($str1, $str2) {
  1134. return strcmp($str1, $str2);
  1135. }
  1136. }
  1137. #------------------------------------------------------------------ 4.1 ---
  1138. # nl_langinfo - unimpl?
  1139. # getmygid
  1140. # version_compare
  1141. #
  1142. # See also "ext/math41.php" for some more (rarely used mathematical funcs).
  1143. #-- aliases (an earlier fallen attempt to unify PHP function names)
  1144. if (!function_exists("diskfreespace")) {
  1145. function diskfreespace() {
  1146. return disk_free_sapce();
  1147. }
  1148. function disktotalspace() {
  1149. return disk_total_sapce();
  1150. }
  1151. }
  1152. #-- variable count of arguments (in array list) printf variant
  1153. if (!function_exists("vprintf")) {
  1154. function vprintf($format, $args=NULL) {
  1155. call_user_func_array("fprintf", get_func_args());
  1156. }
  1157. }
  1158. #-- same as above, but doesn't output directly and returns formatted string
  1159. if (!function_exists("vsprintf")) {
  1160. function vsprintf($format, $args=NULL) {
  1161. $args = array_merge(array($format), array_values((array)$args));
  1162. return call_user_func_array("sprintf", $args);
  1163. }
  1164. }
  1165. #-- can be used to simulate a register_globals=on environment
  1166. if (!function_exists("import_request_variables")) {
  1167. function import_request_variables($types="GPC", $pfix="") {
  1168. #-- associate abbreviations to global var names
  1169. $alias = array(
  1170. "G" => "_GET",
  1171. "P" => "_POST",
  1172. "C" => "_COOKIE",
  1173. "S" => "_SERVER", // non-standard
  1174. "E" => "_ENV", // non-standard
  1175. );
  1176. #-- alias long names (PHP < 4.0.6)
  1177. if (!isset($_REQUEST)) {
  1178. $_GET = & $HTTP_GET_VARS;
  1179. $_POST = & $HTTP_POST_VARS;
  1180. $_COOKIE = & $HTTP_COOKIE_VARS;
  1181. }
  1182. #-- copy
  1183. for ($i=0; $i<strlen($types); $i++) {
  1184. if ($FROM = $alias[strtoupper($c)]) {
  1185. foreach ($$FROM as $key=>$val) {
  1186. if (!isset($GLOBALS[$pfix.$key])) {
  1187. $GLOBALS[$pfix . $key] = $val;
  1188. }
  1189. }
  1190. }
  1191. }
  1192. // done
  1193. }
  1194. }
  1195. // a few mathematical functions follow
  1196. // (wether we should really emulate them is a different question)
  1197. #-- me has no idea what this function means
  1198. if (!function_exists("hypot")) {
  1199. function hypot($num1, $num2) {
  1200. return sqrt($num1*$num1 + $num2*$num2); // as per PHP manual ;)
  1201. }
  1202. }
  1203. #-- more accurate logarithm func, but we cannot simulate it
  1204. # (too much work, too slow in PHP)
  1205. if (!function_exists("log1p")) {
  1206. function log1p($x) {
  1207. return( log(1+$x) );
  1208. }
  1209. #-- same story for:
  1210. function expm1($x) {
  1211. return( exp($x)-1 );
  1212. }
  1213. }
  1214. #-- as per PHP manual
  1215. if (!function_exists("sinh")) {
  1216. function sinh($f) {
  1217. return( (exp($f) - exp(-$f)) / 2 );
  1218. }
  1219. function cosh($f) {
  1220. return( (exp($f) + exp(-$f)) / 2 );
  1221. }
  1222. function tanh($f) {
  1223. return( sinh($f) / cosh($f) ); // ok, that one makes sense again :)
  1224. }
  1225. }
  1226. #-- these look a bit more complicated
  1227. if (!function_exists("asinh")) {
  1228. function asinh($x) {
  1229. return( log($x + sqrt($x*$x+1)) );
  1230. }
  1231. function acosh($x) {
  1232. return( log($x + sqrt($x*$x-1)) );
  1233. }
  1234. function atanh($x) {
  1235. return( log1p( 2*$x / (1-$x) ) / 2 );
  1236. }
  1237. }
  1238. #-- HMAC from RFC2104, but see also PHP_Compat and Crypt_HMAC
  1239. if (!function_exists("mhash")) {
  1240. #-- constants
  1241. define("MHASH_CRC32", 0);
  1242. define("MHASH_MD5", 1); // RFC1321
  1243. define("MHASH_SHA1", 2); // RFC3174
  1244. define("MHASH_TIGER", 7);
  1245. define("MHASH_MD4", 16); // RFC1320
  1246. define("MHASH_SHA256", 17);
  1247. define("MHASH_ADLER32", 18);
  1248. #-- implementation
  1249. function mhash($hashtype, $text, $key) {
  1250. #-- hash function
  1251. static $hash_funcs = array(
  1252. MHASH_CRC32 => "crc32", // needs dechex()ing here
  1253. MHASH_MD5 => "md5",
  1254. MHASH_SHA1 => "sha1",
  1255. );
  1256. if (!($func = $hash_funcs[$hashtype]) || !function_exists($func)) {
  1257. return trigger_error("mhash: cannot use hash algorithm #$hashtype/$func", E_USER_ERROR);
  1258. }
  1259. if (!$key) {
  1260. trigger_error("mhash: called without key", E_USER_WARNING);
  1261. }
  1262. #-- params
  1263. $bsize = 64; // fixed size
  1264. #-- pad key
  1265. if (strlen($key) > $bsize) { // hash key, when it's too long
  1266. $key = $func($key);
  1267. $key = pack("H*", $key); // binarify
  1268. }
  1269. $key = str_pad($key, $bsize, "\0"); // fill up with NULs (1)
  1270. #-- prepare inner and outer padding stream
  1271. $ipad = str_pad("", $bsize, "6"); // %36
  1272. $opad = str_pad("", $bsize, "\\"); // %5C
  1273. #-- call hash func // php can XOR strings for us
  1274. $dgst = pack("H*", $func( ($key ^ $ipad) . $text )); // (2,3,4)
  1275. $dgst = pack("H*", $func( ($key ^ $opad) . $dgst )); // (5,6,7)
  1276. return($dgst);
  1277. }
  1278. }
  1279. #-- other stuff
  1280. /*
  1281. removed funcs??
  1282. [18] => leak
  1283. */
  1284. #-- pre-4.1 -- end
  1285. // no need to implement anything below that, because such old versions
  1286. // will be incompatbile anyhow (- none of the newer superglobals known),
  1287. // but see also "ext/old"
  1288. ?>