OSDN Git Service

BugTrack2/122: tempnam() fails when open_basedir is specified in php.ini
[pukiwiki/pukiwiki.git] / plugin / online.inc.php
1 <?php
2 // $Id: online.inc.php,v 1.9 2005/06/25 10:03:20 henoheno Exp $
3 // Copyright (C)
4 //   2002-2005 PukiWiki Developers Team
5 //   2001-2002 Originally written by yu-ji
6 // License: GPL v2 or (at your option) any later version
7 //
8 // Online plugin -- Just show the number 'users-on-line'
9
10 define('PLUGIN_ONLINE_TIMEOUT', 60 * 5); // Count users in N seconds
11
12 // ----
13
14 // List of 'IP-address|last-access-time(seconds)'
15 define('PLUGIN_ONLINE_USER_LIST', COUNTER_DIR . 'user.dat');
16
17 // Regex of 'IP-address|last-access-time(seconds)'
18 define('PLUGIN_ONLINE_LIST_REGEX', '/^([^\|]+)\|([0-9]+)$/');
19
20 function plugin_online_convert()
21 {
22         return plugin_online_itself(0);
23 }
24
25 function plugin_online_inline()
26 {
27         return plugin_online_itself(1);
28 }
29
30 function plugin_online_itself($type = 0)
31 {
32         static $count, $result, $base;
33
34         if (! isset($count)) {
35                 if (isset($_SERVER['REMOTE_ADDR'])) {
36                         $host  = & $_SERVER['REMOTE_ADDR'];
37                 } else {
38                         $host  = '';
39                 }
40
41                 // Try read
42                 if (plugin_online_check_online(& $count, $host)) {
43                         $result = TRUE;
44                 } else {
45                         // Write
46                         $result = plugin_online_sweep_records($host);
47                 }
48         }
49
50         if ($result) {
51                 return $count; // Integer
52         } else {
53                 if (! isset($base)) $base = basename(PLUGIN_ONLINE_USER_LIST);
54                 $error = '"COUNTER_DIR/' . $base . '" not writable';
55                 if ($type == 0) {
56                         $error = '#online: ' . $error . '<br />' . "\n";
57                 } else {
58                         $error = '&online: ' . $error . ';';
59                 }
60                 return $error; // String
61         }
62 }
63
64 // Check I am already online (recorded and not time-out)
65 // & $count == Number of online users
66 function plugin_online_check_online(& $count, $host = '')
67 {
68         if (! file_exists(PLUGIN_ONLINE_USER_LIST) &&
69             ! @touch(PLUGIN_ONLINE_USER_LIST))
70                 return FALSE;
71
72         // Open
73         $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r');
74         if ($fp == FALSE) return FALSE;
75         set_file_buffer($fp, 0);
76
77         // Init
78         $count   = 0;
79         $found   = FALSE;
80         $matches = array();
81
82         flock($fp, LOCK_SH);
83
84         // Read
85         while (! feof($fp)) {
86                 $line = fgets($fp, 512);
87                 if ($line === FALSE) continue;
88
89                 // Ignore invalid-or-outdated lines
90                 if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $line, $matches) ||
91                     ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME ||
92                     $matches[2] > UTIME) continue;
93
94                 ++$count;
95                 if (! $found && $matches[1] == $host) $found = TRUE;
96         }
97
98         flock($fp, LOCK_UN);
99
100         if(! fclose($fp)) return FALSE;
101
102         if (! $found && $host != '') ++$count; // About you
103
104         return $found;
105 }
106
107 // Cleanup outdated records, Add/Replace new record, Return the number of 'users in N seconds'
108 // NOTE: Call this when plugin_online_check_online() returnes FALSE
109 function plugin_online_sweep_records($host = '')
110 {
111         // Open
112         $fp = @fopen(PLUGIN_ONLINE_USER_LIST, 'r+');
113         if ($fp == FALSE) return FALSE;
114         set_file_buffer($fp, 0);
115
116         flock($fp, LOCK_EX);
117
118         // Read to check
119         $lines = @file(PLUGIN_ONLINE_USER_LIST);
120         if ($lines === FALSE) $lines = array();
121
122         // Need modify?
123         $line_count = $count = count($lines);
124         $matches = array();
125         $dirty   = FALSE;
126         for ($i = 0; $i < $line_count; $i++) {
127                 if (! preg_match(PLUGIN_ONLINE_LIST_REGEX, $lines[$i], $matches) ||
128                     ($matches[2] + PLUGIN_ONLINE_TIMEOUT) <= UTIME ||
129                     $matches[2] > UTIME ||
130                     $matches[1] == $host) {
131                         unset($lines[$i]); // Invalid or outdated or invalid date
132                         --$count;
133                         $dirty = TRUE;
134                 }
135         }
136         if ($host != '' ) {
137                 // Add new, at the top of the record
138                 array_unshift($lines, strtr($host, "\n", '') . '|' . UTIME . "\n");
139                 ++$count;
140                 $dirty = TRUE;
141         }
142
143         if ($dirty) {
144                 // Write
145                 if (! ftruncate($fp, 0)) return FALSE;
146                 rewind($fp);
147                 fputs($fp, join('', $lines));
148         }
149
150         flock($fp, LOCK_UN);
151
152         if(! fclose($fp)) return FALSE;
153
154         return $count; // Number of lines == Number of users online
155 }
156 ?>