1 |
<?php |
2 |
/* This file is part of BBClone (A PHP based Web Counter on Steroids) |
3 |
* |
4 |
* CVS FILE $Id: io.php,v 1.80 2011/12/30 23:03:47 joku Exp $ |
5 |
* |
6 |
* Copyright (C) 2001-2012, the BBClone Team (see doc/authors.txt for details) |
7 |
* |
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 |
?> |