X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=lib%2Ffile.php;h=b90a2f8678de5b4eaf8b5801f7a14fbc90dcb7dd;hb=ef13260aa62b4b4d6d7da5f9c85a568eee44aa24;hp=c3092db3f963db066efae514a3331a5c6e988cff;hpb=9bd4b57f077fe193e6292d7dd632df8d6e48a952;p=pukiwiki%2Fpukiwiki.git diff --git a/lib/file.php b/lib/file.php index c3092db..b90a2f8 100644 --- a/lib/file.php +++ b/lib/file.php @@ -1,8 +1,8 @@ ' . "\n" . 'Maybe permission is not writable or filename is too long'); set_file_buffer($fp, 0); @@ -241,14 +298,15 @@ function file_write($dir, $page, $str, $notimestamp = FALSE) // Update RecentChanges (Add or renew the $page) if ($timestamp === FALSE) lastmodified_add($page); - // Execute $update_exec here - if ($update_exec) system($update_exec . ' > /dev/null &'); + // Command execution per update + if (defined('PKWK_UPDATE_EXEC') && PKWK_UPDATE_EXEC) + system(PKWK_UPDATE_EXEC . ' > /dev/null &'); } else if ($dir == DIFF_DIR && $notify) { if ($notify_diff_only) $str = preg_replace('/^[^-+].*\n/m', '', $str); $footer['ACTION'] = 'Page update'; $footer['PAGE'] = & $page; - $footer['URI'] = get_script_uri() . '?' . rawurlencode($page); + $footer['URI'] = get_script_uri() . '?' . pagename_urlencode($page); $footer['USER_AGENT'] = TRUE; $footer['REMOTE_ADDR'] = TRUE; pkwk_mail_notify($notify_subject, $str, $footer) or @@ -277,7 +335,7 @@ function add_recent($page, $recentpage, $subject = '', $limit = 0) // Add array_unshift($lines, '-' . format_date(UTIME) . ' - ' . $_page . - htmlspecialchars($subject) . "\n"); + htmlsc($subject) . "\n"); // Get latest $limit reports $lines = array_splice($lines, 0, $limit); @@ -285,7 +343,7 @@ function add_recent($page, $recentpage, $subject = '', $limit = 0) // Update $fp = fopen(get_filename($recentpage), 'w') or die_message('Cannot write page file ' . - htmlspecialchars($recentpage) . + htmlsc($recentpage) . '
Maybe permission is not writable or filename is too long'); set_file_buffer($fp, 0); flock($fp, LOCK_EX); @@ -299,12 +357,21 @@ function add_recent($page, $recentpage, $subject = '', $limit = 0) // Update PKWK_MAXSHOW_CACHE itself (Add or renew about the $page) (Light) // Use without $autolink -function lastmodified_add($page = '') +function lastmodified_add($update = '', $remove = '') { global $maxshow, $whatsnew, $autolink; + // AutoLink implimentation needs everything, for now + if ($autolink) { + put_lastmodified(); // Try to (re)create ALL + return; + } + + if (($update == '' || check_non_list($update)) && $remove == '') + return; // No need + $file = CACHE_DIR . PKWK_MAXSHOW_CACHE; - if ($autolink || ! file_exists($file)) { + if (! file_exists($file)) { put_lastmodified(); // Try to (re)create ALL return; } @@ -316,27 +383,40 @@ function lastmodified_add($page = '') set_file_buffer($fp, 0); flock($fp, LOCK_EX); - // Read + // Read (keep the order of the lines) $recent_pages = $matches = array(); foreach(file_head($file, $maxshow + PKWK_MAXSHOW_ALLOWANCE, FALSE) as $line) if (preg_match('/^([0-9]+)\t(.+)/', $line, $matches)) $recent_pages[$matches[2]] = $matches[1]; - // Remove if exists - if (isset($recent_pages[$page])) unset($recent_pages[$page]); + // Remove if it exists inside + if (isset($recent_pages[$update])) unset($recent_pages[$update]); + if (isset($recent_pages[$remove])) unset($recent_pages[$remove]); - // Add: array_unshift() - $recent_pages = array($page => get_filetime($page)) + $recent_pages; + // Add to the top: like array_unshift() + if ($update != '') + $recent_pages = array($update => get_filetime($update)) + $recent_pages; - // Write - ftruncate($fp, 0); - rewind($fp); - foreach ($recent_pages as $_page=>$time) - fputs($fp, $time . "\t" . $_page . "\n"); + // Check + $abort = count($recent_pages) < $maxshow; + + if (! $abort) { + // Write + ftruncate($fp, 0); + rewind($fp); + foreach ($recent_pages as $_page=>$time) + fputs($fp, $time . "\t" . $_page . "\n"); + } flock($fp, LOCK_UN); fclose($fp); + if ($abort) { + put_lastmodified(); // Try to (re)create ALL + return; + } + + // ---- // Update the page 'RecentChanges' @@ -347,16 +427,16 @@ function lastmodified_add($page = '') // Open pkwk_touch_file($file); $fp = fopen($file, 'r+') or - die_message('Cannot open ' . htmlspecialchars($whatsnew)); + die_message('Cannot open ' . htmlsc($whatsnew)); set_file_buffer($fp, 0); flock($fp, LOCK_EX); - // Write + // Recreate ftruncate($fp, 0); rewind($fp); foreach ($recent_pages as $_page=>$time) - fputs($fp, '-' . htmlspecialchars(format_date($time)) . - ' - ' . '[[' . htmlspecialchars($_page) . ']]' . "\n"); + fputs($fp, '-' . htmlsc(format_date($time)) . + ' - ' . '[[' . htmlsc($_page) . ']]' . "\n"); fputs($fp, '#norelated' . "\n"); // :) flock($fp, LOCK_UN); @@ -376,14 +456,22 @@ function put_lastmodified() // Check ALL filetime $recent_pages = array(); foreach($pages as $page) - if ($page != $whatsnew && ! check_non_list($page)) + if ($page !== $whatsnew && ! check_non_list($page)) $recent_pages[$page] = get_filetime($page); // Sort decending order of last-modification date arsort($recent_pages, SORT_NUMERIC); // Cut unused lines - $recent_pages = array_splice($recent_pages, 0, $maxshow + PKWK_MAXSHOW_ALLOWANCE); + // BugTrack2/179: array_splice() will break integer keys in hashtable + $count = $maxshow + PKWK_MAXSHOW_ALLOWANCE; + $_recent = array(); + foreach($recent_pages as $key=>$value) { + unset($recent_pages[$key]); + $_recent[$key] = $value; + if (--$count < 1) break; + } + $recent_pages = & $_recent; // Re-create PKWK_MAXSHOW_CACHE $file = CACHE_DIR . PKWK_MAXSHOW_CACHE; @@ -403,15 +491,15 @@ function put_lastmodified() $file = get_filename($whatsnew); pkwk_touch_file($file); $fp = fopen($file, 'r+') or - die_message('Cannot open ' . htmlspecialchars($whatsnew)); + die_message('Cannot open ' . htmlsc($whatsnew)); set_file_buffer($fp, 0); flock($fp, LOCK_EX); ftruncate($fp, 0); rewind($fp); foreach (array_keys($recent_pages) as $page) { $time = $recent_pages[$page]; - $s_lastmod = htmlspecialchars(format_date($time)); - $s_page = htmlspecialchars($page); + $s_lastmod = htmlsc(format_date($time)); + $s_page = htmlsc($page); fputs($fp, '-' . $s_lastmod . ' - [[' . $s_page . ']]' . "\n"); } fputs($fp, '#norelated' . "\n"); // :) @@ -463,21 +551,36 @@ function header_lastmod($page = NULL) } } +// Get a list of encoded files (must specify a directory and a suffix) +function get_existfiles($dir = DATA_DIR, $ext = '.txt') +{ + $aryret = array(); + $pattern = '/^(?:[0-9A-F]{2})+' . preg_quote($ext, '/') . '$/'; + + $dp = @opendir($dir) or die_message($dir . ' is not found or not readable.'); + while (($file = readdir($dp)) !== FALSE) { + if (preg_match($pattern, $file)) { + $aryret[] = $dir . $file; + } + } + closedir($dp); + + return $aryret; +} + // Get a page list of this wiki function get_existpages($dir = DATA_DIR, $ext = '.txt') { $aryret = array(); + $pattern = '/^((?:[0-9A-F]{2})+)' . preg_quote($ext, '/') . '$/'; - $pattern = '((?:[0-9A-F]{2})+)'; - if ($ext != '') $ext = preg_quote($ext, '/'); - $pattern = '/^' . $pattern . $ext . '$/'; - - $dp = @opendir($dir) or - die_message($dir . ' is not found or not readable.'); + $dp = @opendir($dir) or die_message($dir . ' is not found or not readable.'); $matches = array(); - while ($file = readdir($dp)) - if (preg_match($pattern, $file, $matches)) + while (($file = readdir($dp)) !== FALSE) { + if (preg_match($pattern, $file, $matches)) { $aryret[$file] = decode($matches[1]); + } + } closedir($dp); return $aryret; @@ -626,7 +729,7 @@ function get_readings() if($unknownPage || $deletedPage) { - asort($readings); // Sort by pronouncing(alphabetical/reading) order + asort($readings, SORT_STRING); // Sort by pronouncing(alphabetical/reading) order $body = ''; foreach ($readings as $page => $reading) $body .= '-[[' . $page . ']] ' . $reading . "\n"; @@ -644,19 +747,6 @@ function get_readings() return $readings; } -// Get a list of encoded files (must specify a directory and a suffix) -function get_existfiles($dir, $ext) -{ - $pattern = '/^(?:[0-9A-F]{2})+' . preg_quote($ext, '/') . '$/'; - $aryret = array(); - $dp = @opendir($dir) or die_message($dir . ' is not found or not readable.'); - while ($file = readdir($dp)) - if (preg_match($pattern, $file)) - $aryret[] = $dir . $file; - closedir($dp); - return $aryret; -} - // Get a list of related pages of the page function links_get_related($page) { @@ -666,7 +756,7 @@ function links_get_related($page) if (isset($links[$page])) return $links[$page]; // If possible, merge related pages generated by make_link() - $links[$page] = ($page == $vars['page']) ? $related : array(); + $links[$page] = ($page === $vars['page']) ? $related : array(); // Get repated pages from DB $links[$page] += links_get_related_db($vars['page']); @@ -692,12 +782,12 @@ function pkwk_chown($filename, $preserve_time = TRUE) $lockfile = CACHE_DIR . 'pkwk_chown.lock'; $flock = fopen($lockfile, 'a') or die('pkwk_chown(): fopen() failed for: CACHEDIR/' . - basename(htmlspecialchars($lockfile))); + basename(htmlsc($lockfile))); flock($flock, LOCK_EX) or die('pkwk_chown(): flock() failed for lock'); // Check owner $stat = stat($filename) or - die('pkwk_chown(): stat() failed for: ' . basename(htmlspecialchars($filename))); + die('pkwk_chown(): stat() failed for: ' . basename(htmlsc($filename))); if ($stat[4] === $php_uid) { // NOTE: Windows always here $result = TRUE; // Seems the same UID. Nothing to do @@ -708,7 +798,7 @@ function pkwk_chown($filename, $preserve_time = TRUE) // NOTE: Not 'r+'. Don't check write permission here $ffile = fopen($filename, 'r') or die('pkwk_chown(): fopen() failed for: ' . - basename(htmlspecialchars($filename))); + basename(htmlsc($filename))); // Try to chown by re-creating files // NOTE: @@ -748,7 +838,22 @@ function pkwk_touch_file($filename, $time = FALSE, $atime = FALSE) return $result; } else { die('pkwk_touch_file(): Invalid UID and (not writable for the directory or not a flie): ' . - htmlspecialchars(basename($filename))); + htmlsc(basename($filename))); } } -?> + +/** + * Lock-enabled file_get_contents + * + * Require: PHP5+ + */ +function pkwk_file_get_contents($filename) { + if (! file_exists($filename)) { + return false; + } + $fp = fopen($filename, 'rb'); + flock($fp, LOCK_SH); + $file = file_get_contents($filename); + flock($fp, LOCK_UN); + return $file; +}