<?php
-/////////////////////////////////////////////////
-// PukiWiki - Yet another WikiWikiWeb clone.
-//
-// $Id: online.inc.php,v 1.8 2004/03/18 10:02:13 arino Exp $
+// $Id: online.inc.php,v 1.9 2005/06/25 10:03:20 henoheno Exp $
+// Copyright (C)
+// 2002-2005 PukiWiki Developers Team
+// 2001-2002 Originally written by yu-ji
+// License: GPL v2 or (at your option) any later version
//
+// Online plugin -- Just show the number 'users-on-line'
+
+define('PLUGIN_ONLINE_TIMEOUT', 60 * 5); // Count users in N seconds
+
+// ----
+
+// List of 'IP-address|last-access-time(seconds)'
+define('PLUGIN_ONLINE_USER_LIST', COUNTER_DIR . 'user.dat');
+
+// Regex of 'IP-address|last-access-time(seconds)'
+define('PLUGIN_ONLINE_LIST_REGEX', '/^([^\|]+)\|([0-9]+)$/');
-// user list file
-define('USR_LST', COUNTER_DIR.'user.dat');
-// time out sec
-define('TIMEOUT', 300);
+function plugin_online_convert()
+{
+ return plugin_online_itself(0);
+}
function plugin_online_inline()
{
- return plugin_online_convert();
+ return plugin_online_itself(1);
}
-function plugin_online_convert()
+
+function plugin_online_itself($type = 0)
{
- if (!file_exists(USR_LST))
- {
- $nf = fopen(USR_LST, 'w');
- fclose($nf);
+ static $count, $result, $base;
+
+ if (! isset($count)) {
+ if (isset($_SERVER['REMOTE_ADDR'])) {
+ $host = & $_SERVER['REMOTE_ADDR'];
+ } else {
+ $host = '';
+ }
+
+ // Try read
+ if (plugin_online_check_online(& $count, $host)) {
+ $result = TRUE;
+ } else {
+ // Write
+ $result = plugin_online_sweep_records($host);
+ }
+ }
+
+ if ($result) {
+ return $count; // Integer
+ } else {
+ if (! isset($base)) $base = basename(PLUGIN_ONLINE_USER_LIST);
+ $error = '"COUNTER_DIR/' . $base . '" not writable';
+ if ($type == 0) {
+ $error = '#online: ' . $error . '<br />' . "\n";
+ } else {
+ $error = '&online: ' . $error . ';';
+ }
+ return $error; // String
}
- CheckUser($_SERVER['REMOTE_ADDR']);
- return UserCount();
}
-function CheckUser($addr)
+// Check I am already online (recorded and not time-out)
+// & $count == Number of online users
+function plugin_online_check_online(& $count, $host = '')
{
- $usr_arr = file(USR_LST);
- $fp = fopen(USR_LST, 'w');
+ if (! file_exists(PLUGIN_ONLINE_USER_LIST) &&
+ ! @touch(PLUGIN_ONLINE_USER_LIST))
+ return FALSE;
+
+ // Open
+ $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r');
+ if ($fp == FALSE) return FALSE;
set_file_buffer($fp, 0);
- flock($fp,LOCK_EX);
- rewind($fp);
- $now = UTIME;
- for ($i = 0; $i < count($usr_arr); $i++)
- {
- list($ip_addr,$tim_stmp) = explode('|', $usr_arr[$i]);
- if (($now - $tim_stmp) < TIMEOUT and $ip_addr != $addr)
- {
- fputs($fp, "$ip_addr|$tim_stmp");
- }
+
+ // Init
+ $count = 0;
+ $found = FALSE;
+ $matches = array();
+
+ flock($fp, LOCK_SH);
+
+ // Read
+ while (! feof($fp)) {
+ $line = fgets($fp, 512);
+ if ($line === FALSE) continue;
+
+ // Ignore invalid-or-outdated lines
+ if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $line, $matches) ||
+ ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME ||
+ $matches[2] > UTIME) continue;
+
+ ++$count;
+ if (! $found && $matches[1] == $host) $found = TRUE;
}
- fputs($fp, "$addr|$now\n");
- flock($fp,LOCK_UN);
- fclose($fp);
+
+ flock($fp, LOCK_UN);
+
+ if(! fclose($fp)) return FALSE;
+
+ if (! $found && $host != '') ++$count; // About you
+
+ return $found;
}
-function UserCount()
+// Cleanup outdated records, Add/Replace new record, Return the number of 'users in N seconds'
+// NOTE: Call this when plugin_online_check_online() returnes FALSE
+function plugin_online_sweep_records($host = '')
{
- return count(file(USR_LST));
+ // Open
+ $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r+');
+ if ($fp == FALSE) return FALSE;
+ set_file_buffer($fp, 0);
+
+ flock($fp, LOCK_EX);
+
+ // Read to check
+ $lines = @file(PLUGIN_ONLINE_USER_LIST);
+ if ($lines === FALSE) $lines = array();
+
+ // Need modify?
+ $line_count = $count = count($lines);
+ $matches = array();
+ $dirty = FALSE;
+ for ($i = 0; $i < $line_count; $i++) {
+ if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $lines[$i], $matches) ||
+ ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME ||
+ $matches[2] > UTIME ||
+ $matches[1] == $host) {
+ unset($lines[$i]); // Invalid or outdated or invalid date
+ --$count;
+ $dirty = TRUE;
+ }
+ }
+ if ($host != '' ) {
+ // Add new, at the top of the record
+ array_unshift($lines, strtr($host, "\n", '') . '|' . UTIME . "\n");
+ ++$count;
+ $dirty = TRUE;
+ }
+
+ if ($dirty) {
+ // Write
+ if (! ftruncate($fp, 0)) return FALSE;
+ rewind($fp);
+ fputs($fp, join('', $lines));
+ }
+
+ flock($fp, LOCK_UN);
+
+ if(! fclose($fp)) return FALSE;
+
+ return $count; // Number of lines == Number of users online
}
?>