1 |
matthys |
15 |
<?php |
2 |
|
|
/* This file is part of BBClone (A PHP based Web Counter on Steroids) |
3 |
|
|
* |
4 |
matthys |
16 |
* SVN FILE $Id$ |
5 |
matthys |
15 |
* |
6 |
matthys |
16 |
* Copyright (C) 2001-2013, the BBClone Team (see doc/authors.txt for details) |
7 |
matthys |
15 |
* |
8 |
|
|
* This program is free software: you can redistribute it and/or modify |
9 |
|
|
* it under the terms of the GNU General Public License as published by |
10 |
|
|
* the Free Software Foundation, either version 3 of the License, or |
11 |
|
|
* (at your option) any later version. |
12 |
|
|
* |
13 |
|
|
* This program is distributed in the hope that it will be useful, |
14 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
|
|
* GNU General Public License for more details. |
17 |
|
|
* |
18 |
|
|
* See doc/copying.txt for details |
19 |
|
|
*/ |
20 |
|
|
|
21 |
|
|
/////////////////////// |
22 |
|
|
// IO (Input/Output) // |
23 |
|
|
/////////////////////// |
24 |
|
|
|
25 |
|
|
// remove unwanted stuff from user input |
26 |
|
|
function bbc_clean($input, $sep = 0) { |
27 |
|
|
$sp = strpos($input, $sep); |
28 |
|
|
// only look for separator if really needed |
29 |
|
|
$input = (!empty($sep) && ($sp !== false)) ? substr($input, 0, $sp) : $input; |
30 |
|
|
$input = strip_tags(str_replace("\\", "/", stripslashes($input))); |
31 |
|
|
$input = trim(str_replace("$", "$", htmlspecialchars($input, ENT_QUOTES))); |
32 |
|
|
|
33 |
|
|
// Limit the maximum length to 512 chars |
34 |
|
|
return substr($input, 0, 512); |
35 |
|
|
} |
36 |
|
|
|
37 |
|
|
//initialize the bbc_marker class |
38 |
|
|
function bbc_exec_marker() { |
39 |
|
|
$bbc_marker = new bbc_marker; |
40 |
|
|
|
41 |
|
|
if ($bbc_marker->ignored === true) return bbc_msg(false, "i"); |
42 |
|
|
else $msg = $bbc_marker->bbc_write_entry(); |
43 |
|
|
|
44 |
|
|
switch ($msg[1]) { |
45 |
|
|
case "o": |
46 |
|
|
if (!defined("_OK")) define("_OK", 1); |
47 |
|
|
return bbc_msg($msg[0], "o"); |
48 |
|
|
case "l": |
49 |
|
|
return bbc_msg($msg[0], "l"); |
50 |
|
|
case "w": |
51 |
|
|
return bbc_msg($msg[0], "w"); |
52 |
|
|
default: |
53 |
|
|
return bbc_msg($msg[0]); |
54 |
|
|
} |
55 |
|
|
} |
56 |
|
|
|
57 |
|
|
// kill stats if desired |
58 |
|
|
function bbc_kill_stats() { |
59 |
|
|
global $BBC_ACCESS_FILE, $BBC_CACHE_PATH, $BBC_COUNTER_FILES, $BBC_COUNTER_PREFIX, $BBC_COUNTER_SUFFIX, |
60 |
|
|
$BBC_DEBUG, $BBC_LAST_FILE; |
61 |
|
|
|
62 |
|
|
for ($i = 0; $i < $BBC_COUNTER_FILES; $i++) { |
63 |
|
|
$file = $BBC_CACHE_PATH.$BBC_COUNTER_PREFIX.$i.$BBC_COUNTER_SUFFIX; |
64 |
|
|
|
65 |
|
|
fclose(fopen($file, "wb")); |
66 |
|
|
} |
67 |
|
|
|
68 |
|
|
fclose(fopen($BBC_ACCESS_FILE, "wb")); |
69 |
|
|
fclose(fopen($BBC_LAST_FILE, "wb")); |
70 |
|
|
} |
71 |
|
|
|
72 |
|
|
// Parse all counter files of var/ and return an array of N rows, |
73 |
|
|
// with N as amount of new connections, sorted in increasing time of connection. |
74 |
|
|
// The counters files are emptied afterwards. |
75 |
|
|
function bbc_counter_to_array() { |
76 |
|
|
global $BBC_CACHE_PATH, $BBC_COUNTER_PREFIX, $BBC_COUNTER_SUFFIX, $BBC_SEP, $BBC_COUNTER_COLUMNS, |
77 |
|
|
$BBC_COUNTER_COLUMN_NAMES, $BBC_COUNTER_FILES, $BBC_DEBUG; |
78 |
|
|
|
79 |
|
|
for ($i = 0, $nb_new_entry = 0; $i < $BBC_COUNTER_FILES; $i++) { |
80 |
|
|
$file = $BBC_CACHE_PATH.$BBC_COUNTER_PREFIX.$i.$BBC_COUNTER_SUFFIX; |
81 |
|
|
|
82 |
|
|
if (!is_readable($file)) { |
83 |
|
|
!empty($BBC_DEBUG) ? print(bbc_msg($file)) : ""; |
84 |
|
|
$no_acc = 1; |
85 |
|
|
continue; |
86 |
|
|
} |
87 |
|
|
|
88 |
|
|
$fp = fopen($file, "rb"); |
89 |
|
|
|
90 |
|
|
while (($line = fgetcsv($fp, 4096, $BBC_SEP)) !== false) { |
91 |
|
|
for ($j = 0, $max = count($line); $j < $max; $j++) $line[$j] = trim($line[$j]); |
92 |
|
|
// Avoiding ill formed counter file |
93 |
|
|
if ((empty($line[0])) || (!preg_match(":^[0-9]+$:",$line[0]))) continue; |
94 |
|
|
|
95 |
|
|
for ($k = 0; ($k < $BBC_COUNTER_COLUMNS); $k++) { |
96 |
|
|
$counter_array[$nb_new_entry][($BBC_COUNTER_COLUMN_NAMES[$k])] = $line[$k]; |
97 |
|
|
} |
98 |
|
|
$nb_new_entry++; |
99 |
|
|
} |
100 |
|
|
fclose($fp); |
101 |
|
|
|
102 |
|
|
// reset the counter files |
103 |
|
|
if (is_writable($file)) fclose(fopen($file, "wb")); |
104 |
|
|
else (empty($no_acc) && !empty($BBC_DEBUG)) ? print(bbc_msg($file, "w")) : ""; |
105 |
|
|
} |
106 |
|
|
if (!empty($counter_array)) usort($counter_array, "bbc_sort_time_sc"); |
107 |
|
|
return (empty($counter_array) ? array() : $counter_array); |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
function bbc_array_to_str(&$tab) { |
111 |
|
|
// This function return a string description of an array. |
112 |
|
|
// Format (_ == space): |
113 |
|
|
// |_array( |
114 |
|
|
// |__key1 => scal1, key2 => scal2, ... |
115 |
|
|
// |__key3 => |
116 |
|
|
// |___array( |
117 |
|
|
// |____key1 => scal1, ... |
118 |
|
|
// |___), |
119 |
|
|
// |__key4 => scal4, ... |
120 |
|
|
// |_) |
121 |
|
|
|
122 |
|
|
static $indent = ""; |
123 |
|
|
|
124 |
|
|
$oldindent = $indent; |
125 |
|
|
$indent .= " "; |
126 |
|
|
$sep = ""; |
127 |
|
|
|
128 |
|
|
$str = $indent."array(\n"; |
129 |
|
|
$last_is_array = false; |
130 |
|
|
$k = 0; |
131 |
|
|
|
132 |
|
|
reset($tab); |
133 |
|
|
|
134 |
|
|
while (list($key, $val) = each($tab)) { |
135 |
|
|
// The separator treatment |
136 |
|
|
if (($last_is_array) || (is_array($val) && ($k !== 0))) { |
137 |
|
|
$str .= $sep."\n"; |
138 |
|
|
} |
139 |
|
|
else $str .= $sep; |
140 |
|
|
|
141 |
|
|
// The key treatment |
142 |
|
|
if (preg_match(":^[0-9]+$:", $key)) { |
143 |
|
|
if ($key !== $k) { |
144 |
|
|
$str .= (((is_array($val)) || ($k === 0) || ($last_is_array)) ? "$indent " : "") |
145 |
|
|
."$key =>".((is_array($val)) ? "\n" : " "); |
146 |
|
|
} |
147 |
|
|
else $str .= ($k === 0) ? (is_array($val) ? "" : "$indent ") : ""; |
148 |
|
|
} |
149 |
|
|
else { |
150 |
|
|
$str .= (((is_array($val)) || ($k === 0) || ($last_is_array)) ? "$indent " : "") |
151 |
|
|
."\"$key\" =>".((is_array($val)) ? "\n" : " "); |
152 |
|
|
} |
153 |
|
|
|
154 |
|
|
// The value treatment |
155 |
|
|
$last_is_array = false; |
156 |
|
|
if (is_array($val)) { |
157 |
|
|
$str .= bbc_array_to_str($val); |
158 |
|
|
$last_is_array = true; |
159 |
|
|
$sep = ","; |
160 |
|
|
} |
161 |
|
|
else { |
162 |
|
|
$str .= (preg_match(":^[0-9]+$:", $val) ? $val : "\"$val\""); |
163 |
|
|
$sep = ", "; |
164 |
|
|
} |
165 |
|
|
$k++; |
166 |
|
|
} |
167 |
|
|
$str .= "\n$indent)"; |
168 |
|
|
$indent = $oldindent; |
169 |
|
|
return $str; |
170 |
|
|
} |
171 |
|
|
|
172 |
|
|
function bbc_ftok($file) { |
173 |
|
|
$stat = stat($file); |
174 |
|
|
$dev = decbin($stat[0]); |
175 |
|
|
$inode = decbin($stat[1]); |
176 |
|
|
|
177 |
|
|
foreach (array("dev", "inode") as $what) { |
178 |
|
|
$lim = ($what == "inode") ? 16 : 8; |
179 |
|
|
|
180 |
|
|
if ($$what < $lim) $$what = str_pad($$what, $lim, 0); |
181 |
|
|
elseif ($$what > $lim) $$what = substr($$what, -$lim); |
182 |
|
|
else continue; |
183 |
|
|
} |
184 |
|
|
return bindec("1111000".$dev.$inode); |
185 |
|
|
} |
186 |
|
|
|
187 |
|
|
// returns the lock id |
188 |
|
|
function bbc_semlock($file) { |
189 |
|
|
$id = sem_get(bbc_ftok($file), 1); |
190 |
|
|
|
191 |
|
|
sem_acquire($id); |
192 |
|
|
return $id; |
193 |
|
|
} |
194 |
|
|
|
195 |
|
|
// write data, returns file pointer on success else false |
196 |
|
|
function bbc_begin_write($file, $data) { |
197 |
|
|
$fp = defined("_BBC_DIO") ? dio_open($file, O_RDWR | O_APPEND) : fopen($file, "rb+"); |
198 |
|
|
|
199 |
|
|
if (defined("_BBC_DIO") && (dio_fcntl($fp, F_SETLK, 1) !== -1)) { |
200 |
|
|
dio_seek($fp, 0); |
201 |
|
|
dio_truncate($fp, 0); |
202 |
|
|
dio_write($fp, $data); |
203 |
|
|
return $fp; |
204 |
|
|
} |
205 |
|
|
elseif (defined("_BBC_SEM") ? ($id = bbc_semlock($file)) : flock($fp, LOCK_EX)) { |
206 |
|
|
rewind($fp); |
207 |
|
|
fwrite($fp, $data); |
208 |
|
|
fflush($fp); |
209 |
|
|
ftruncate($fp, ftell($fp)); |
210 |
|
|
return (defined("_BBC_SEM") ? array($fp, $id) : $fp); |
211 |
|
|
} |
212 |
|
|
else { |
213 |
|
|
defined("_BBC_DIO") ? dio_close($fp) : fclose($fp); |
214 |
|
|
return false; |
215 |
|
|
} |
216 |
|
|
} |
217 |
|
|
|
218 |
|
|
// finish writing to a file |
219 |
|
|
function bbc_end_write($fp) { |
220 |
|
|
if (defined("_BBC_SEM") ? ((!is_array($fp)) || ($fp[0] === false)) : ($fp === false)) return false; |
221 |
|
|
|
222 |
|
|
if (defined("_BBC_DIO")) { |
223 |
|
|
dio_fcntl($fp, F_SETLK, 0); |
224 |
|
|
dio_close($fp); |
225 |
|
|
} |
226 |
|
|
else { |
227 |
|
|
defined("_BBC_SEM") ? sem_release($fp[1]) : flock($fp, LOCK_UN); |
228 |
|
|
fclose(defined("_BBC_SEM") ? $fp[0] : $fp); |
229 |
|
|
} |
230 |
|
|
return true; |
231 |
|
|
} |
232 |
|
|
?> |