· 11 years ago · Jul 20, 2015, 09:04 PM
1<?php
2/*
3 +----------------------------------------------------------------------+
4 | APC |
5 +----------------------------------------------------------------------+
6 | Copyright (c) 2006 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
16 | Authors: Ralf Becker <beckerr@php.net> |
17 | Rasmus Lerdorf <rasmus@php.net> |
18 | Ilia Alshanetsky <ilia@prohost.org> |
19 +----------------------------------------------------------------------+
20
21 All other licensing and usage conditions are those of the PHP Group.
22
23 */
24
25$VERSION='$Id: apc.php,v 3.65 2006/10/27 18:32:52 shire Exp $';
26
27////////// READ OPTIONAL CONFIGURATION FILE ////////////
28if (file_exists("apc.conf.php")) include("apc.conf.php");
29////////////////////////////////////////////////////////
30
31////////// BEGIN OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////
32
33defaults('USE_AUTHENTICATION',1); // Use (internal) authentication - best choice if
34 // no other authentication is available
35 // If set to 0:
36 // There will be no further authentication. You
37 // will have to handle this by yourself!
38 // If set to 1:
39 // You need to change ADMIN_PASSWORD to make
40 // this work!
41defaults('ADMIN_USERNAME','phpapc'); // Admin Username
42defaults('ADMIN_PASSWORD','phpapcvsapcu'); // Admin Password - CHANGE THIS TO ENABLE!!!
43
44// (beckerr) I'm using a clear text password here, because I've no good idea how to let
45// users generate a md5 or crypt password in a easy way to fill it in above
46
47//defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German
48defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US
49
50defaults('GRAPH_SIZE',200); // Image size
51
52////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
53
54
55// "define if not defined"
56function defaults($d,$v) {
57 if (!defined($d)) define($d,$v); // or just @define(...)
58}
59
60// rewrite $PHP_SELF to block XSS attacks
61//
62$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],'')) : '';
63$time = time();
64$host = getenv('HOSTNAME');
65if($host) { $host = '('.$host.')'; }
66
67// operation constants
68define('OB_HOST_STATS',1);
69define('OB_SYS_CACHE',2);
70define('OB_USER_CACHE',3);
71define('OB_SYS_CACHE_DIR',4);
72define('OB_VERSION_CHECK',9);
73
74// check validity of input variables
75$vardom=array(
76 'OB' => '/^\d+$/', // operational mode switch
77 'CC' => '/^[01]$/', // clear cache requested
78 'SH' => '/^[a-z0-9]+$/', // shared object description
79
80 'IMG' => '/^[123]$/', // image to generate
81 'LO' => '/^1$/', // login requested
82
83 'COUNT' => '/^\d+$/', // number of line displayed in list
84 'SCOPE' => '/^[AD]$/', // list view scope
85 'SORT1' => '/^[AHSMCDTZ]$/', // first sort key
86 'SORT2' => '/^[DA]$/', // second sort key
87 'AGGR' => '/^\d+$/', // aggregation by dir level
88 'SEARCH' => '/^.*$/' // aggregation by dir level
89);
90
91// default cache mode
92$cache_mode='opcode';
93
94// cache scope
95$scope_list=array(
96 'A' => 'cache_list',
97 'D' => 'deleted_list'
98);
99
100// handle POST and GET requests
101if (empty($_REQUEST)) {
102 if (!empty($_GET) && !empty($_POST)) {
103 $_REQUEST = array_merge($_GET, $_POST);
104 } else if (!empty($_GET)) {
105 $_REQUEST = $_GET;
106 } else if (!empty($_POST)) {
107 $_REQUEST = $_POST;
108 } else {
109 $_REQUEST = array();
110 }
111}
112
113// check parameter syntax
114foreach($vardom as $var => $dom) {
115 if (!isset($_REQUEST[$var])) {
116 $MYREQUEST[$var]=NULL;
117 } else if (!is_array($_REQUEST[$var]) && preg_match($dom,$_REQUEST[$var])) {
118 $MYREQUEST[$var]=$_REQUEST[$var];
119 } else {
120 $MYREQUEST[$var]=$_REQUEST[$var]=NULL;
121 }
122}
123
124// check parameter sematics
125if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE']="A";
126if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1']="H";
127if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D";
128if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS;
129if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20;
130if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A';
131
132$MY_SELF=
133 "$PHP_SELF".
134 "?SCOPE=".$MYREQUEST['SCOPE'].
135 "&SORT1=".$MYREQUEST['SORT1'].
136 "&SORT2=".$MYREQUEST['SORT2'].
137 "&COUNT=".$MYREQUEST['COUNT'];
138$MY_SELF_WO_SORT=
139 "$PHP_SELF".
140 "?SCOPE=".$MYREQUEST['SCOPE'].
141 "&COUNT=".$MYREQUEST['COUNT'];
142
143// authentication needed?
144//
145if (!USE_AUTHENTICATION) {
146 $AUTHENTICATED=1;
147} else {
148 $AUTHENTICATED=0;
149 if (ADMIN_PASSWORD!='password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) {
150
151 if (!isset($_SERVER['PHP_AUTH_USER']) ||
152 !isset($_SERVER['PHP_AUTH_PW']) ||
153 $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||
154 $_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
155 Header("WWW-Authenticate: Basic realm=\"APC Login\"");
156 Header("HTTP/1.0 401 Unauthorized");
157
158 echo <<<EOB
159 <html><body>
160 <h1>Rejected!</h1>
161 <big>Wrong Username or Password!</big><br/> <br/>
162 <big><a href='$PHP_SELF?OB={$MYREQUEST['OB']}'>Continue...</a></big>
163 </body></html>
164EOB;
165 exit;
166
167 } else {
168 $AUTHENTICATED=1;
169 }
170 }
171}
172
173// select cache mode
174if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) {
175 $cache_mode='user';
176}
177// clear cache
178if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) {
179 apc_clear_cache($cache_mode);
180}
181
182if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) {
183 echo "No cache info available. APC does not appear to be running.";
184 exit;
185}
186
187$cache_user = apc_cache_info('user', 1);
188$mem=apc_sma_info();
189if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear
190
191// don't cache this page
192//
193header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
194header("Cache-Control: post-check=0, pre-check=0", false);
195header("Pragma: no-cache"); // HTTP/1.0
196
197function duration($ts) {
198 global $time;
199 $years = (int)((($time - $ts)/(7*86400))/52.177457);
200 $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
201 $weeks = (int)(($rem)/(7*86400));
202 $days = (int)(($rem)/86400) - $weeks*7;
203 $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
204 $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
205 $str = '';
206 if($years==1) $str .= "$years year, ";
207 if($years>1) $str .= "$years years, ";
208 if($weeks==1) $str .= "$weeks week, ";
209 if($weeks>1) $str .= "$weeks weeks, ";
210 if($days==1) $str .= "$days day,";
211 if($days>1) $str .= "$days days,";
212 if($hours == 1) $str .= " $hours hour and";
213 if($hours>1) $str .= " $hours hours and";
214 if($mins == 1) $str .= " 1 minute";
215 else $str .= " $mins minutes";
216 return $str;
217}
218
219// create graphics
220//
221function graphics_avail() {
222 return extension_loaded('gd');
223}
224if (isset($MYREQUEST['IMG']))
225{
226 if (!graphics_avail()) {
227 exit(0);
228 }
229
230 function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
231 $r=$diameter/2;
232 $w=deg2rad((360+$start+($end-$start)/2)%360);
233
234
235 if (function_exists("imagefilledarc")) {
236 // exists only if GD 2.0.1 is avaliable
237 imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
238 imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
239 imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
240 } else {
241 imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
242 imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
243 imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
244 imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
245 imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
246 imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
247 }
248 if ($text) {
249 if ($placeindex>0) {
250 imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
251 imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
252
253 } else {
254 imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
255 }
256 }
257 }
258
259 function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) {
260 $r=$diameter/2;
261 $w=deg2rad((360+$start+($end-$start)/2)%360);
262
263 if ($placeindex>0) {
264 imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
265 imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
266
267 } else {
268 imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
269 }
270 }
271
272 function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
273 global $col_black;
274 $x1=$x+$w-1;
275 $y1=$y+$h-1;
276
277 imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
278 if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
279 else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
280 imagerectangle($im, $x, $y1, $x1, $y, $color1);
281 if ($text) {
282 if ($placeindex>0) {
283
284 if ($placeindex<16)
285 {
286 $px=5;
287 $py=$placeindex*12+6;
288 imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
289 imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
290 imagestring($im,2,$px,$py-6,$text,$color1);
291
292 } else {
293 if ($placeindex<31) {
294 $px=$x+40*2;
295 $py=($placeindex-15)*12+6;
296 } else {
297 $px=$x+40*2+100*intval(($placeindex-15)/15);
298 $py=($placeindex%15)*12+6;
299 }
300 imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
301 imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
302 imagestring($im,2,$px+2,$py-6,$text,$color1);
303 }
304 } else {
305 imagestring($im,4,$x+5,$y1-16,$text,$color1);
306 }
307 }
308 }
309
310
311 $size = GRAPH_SIZE; // image size
312 if ($MYREQUEST['IMG']==3)
313 $image = imagecreate(2*$size+150, $size+10);
314 else
315 $image = imagecreate($size+50, $size+10);
316
317 $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
318 $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
319 $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
320 $col_black = imagecolorallocate($image, 0, 0, 0);
321 imagecolortransparent($image,$col_white);
322
323 switch ($MYREQUEST['IMG']) {
324
325 case 1:
326 $s=$mem['num_seg']*$mem['seg_size'];
327 $a=$mem['avail_mem'];
328 $x=$y=$size/2;
329 $fuzz = 0.000001;
330
331 // This block of code creates the pie chart. It is a lot more complex than you
332 // would expect because we try to visualize any memory fragmentation as well.
333 $angle_from = 0;
334 $string_placement=array();
335 for($i=0; $i<$mem['num_seg']; $i++) {
336 $ptr = 0;
337 $free = $mem['block_lists'][$i];
338 foreach($free as $block) {
339 if($block['offset']!=$ptr) { // Used block
340 $angle_to = $angle_from+($block['offset']-$ptr)/$s;
341 if(($angle_to+$fuzz)>1) $angle_to = 1;
342 fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
343 if (($angle_to-$angle_from)>0.05) {
344 array_push($string_placement, array($angle_from,$angle_to));
345 }
346 $angle_from = $angle_to;
347 }
348 $angle_to = $angle_from+($block['size'])/$s;
349 if(($angle_to+$fuzz)>1) $angle_to = 1;
350 fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_green);
351 if (($angle_to-$angle_from)>0.05) {
352 array_push($string_placement, array($angle_from,$angle_to));
353 }
354 $angle_from = $angle_to;
355 $ptr = $block['offset']+$block['size'];
356 }
357 if ($ptr < $mem['seg_size']) { // memory at the end
358 $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s;
359 if(($angle_to+$fuzz)>1) $angle_to = 1;
360 fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red);
361 if (($angle_to-$angle_from)>0.05) {
362 array_push($string_placement, array($angle_from,$angle_to));
363 }
364 }
365 }
366 foreach ($string_placement as $angle) {
367 text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0])));
368 }
369 break;
370
371 case 2:
372 $s=$cache['num_hits']+$cache['num_misses'];
373 $a=$cache['num_hits'];
374
375 fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
376 fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
377 break;
378
379 case 3:
380 $s=$mem['num_seg']*$mem['seg_size'];
381 $a=$mem['avail_mem'];
382 $x=130;
383 $y=1;
384 $j=1;
385
386 // This block of code creates the bar chart. It is a lot more complex than you
387 // would expect because we try to visualize any memory fragmentation as well.
388 for($i=0; $i<$mem['num_seg']; $i++) {
389 $ptr = 0;
390 $free = $mem['block_lists'][$i];
391 foreach($free as $block) {
392 if($block['offset']!=$ptr) { // Used block
393 $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s;
394 if ($h>0) {
395 $j++;
396 if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($block['offset']-$ptr),$j);
397 else fill_box($image,$x,$y,50,$h,$col_black,$col_red);
398 }
399 $y+=$h;
400 }
401 $h=(GRAPH_SIZE-5)*($block['size'])/$s;
402 if ($h>0) {
403 $j++;
404 if($j<75) fill_box($image,$x,$y,50,$h,$col_black,$col_green,bsize($block['size']),$j);
405 else fill_box($image,$x,$y,50,$h,$col_black,$col_green);
406 }
407 $y+=$h;
408 $ptr = $block['offset']+$block['size'];
409 }
410 if ($ptr < $mem['seg_size']) { // memory at the end
411 $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s;
412 if ($h > 0) {
413 fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++);
414 }
415 }
416 }
417 break;
418 case 4:
419 $s=$cache['num_hits']+$cache['num_misses'];
420 $a=$cache['num_hits'];
421
422 fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s));
423 fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s));
424 break;
425
426 }
427 header("Content-type: image/png");
428 imagepng($image);
429 exit;
430}
431
432// pretty printer for byte values
433//
434function bsize($s) {
435 foreach (array('','K','M','G') as $i => $k) {
436 if ($s < 1024) break;
437 $s/=1024;
438 }
439 return sprintf("%5.1f %sBytes",$s,$k);
440}
441
442// sortable table header in "scripts for this host" view
443function sortheader($key,$name,$extra='') {
444 global $MYREQUEST, $MY_SELF_WO_SORT;
445
446 if ($MYREQUEST['SORT1']==$key) {
447 $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A';
448 }
449 return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=".$MYREQUEST['SORT2']."\">$name</a>";
450
451}
452
453// create menu entry
454function menu_entry($ob,$title) {
455 global $MYREQUEST,$MY_SELF;
456 if ($MYREQUEST['OB']!=$ob) {
457 return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>";
458 } else if (empty($MYREQUEST['SH'])) {
459 return "<li><span class=active>$title</span></li>";
460 } else {
461 return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>";
462 }
463}
464
465function put_login_link($s="Login")
466{
467 global $MY_SELF,$MYREQUEST,$AUTHENTICATED;
468 // needs ADMIN_PASSWORD to be changed!
469 //
470 if (!USE_AUTHENTICATION) {
471 return;
472 } else if (ADMIN_PASSWORD=='password')
473 {
474 print <<<EOB
475 <a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a>
476EOB;
477 } else if ($AUTHENTICATED) {
478 print <<<EOB
479 '{$_SERVER['PHP_AUTH_USER']}' logged in!
480EOB;
481 } else{
482 print <<<EOB
483 <a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a>
484EOB;
485 }
486}
487
488
489?>
490<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
491<html>
492<head><title>APC INFO <?php echo $host ?></title>
493<style><!--
494body { background:white; font-size:100.01%; margin:0; padding:0; }
495body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
496* html body {font-size:0.8em}
497* html p {font-size:0.8em}
498* html td {font-size:0.8em}
499* html th {font-size:0.8em}
500* html input {font-size:0.8em}
501* html submit {font-size:0.8em}
502td { vertical-align:top }
503a { color:black; font-weight:none; text-decoration:none; }
504a:hover { text-decoration:underline; }
505div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
506
507
508div.head div.login {
509 position:absolute;
510 right: 1em;
511 top: 1.2em;
512 color:white;
513 width:6em;
514 }
515div.head div.login a {
516 position:absolute;
517 right: 0em;
518 background:rgb(119,123,180);
519 border:solid rgb(102,102,153) 2px;
520 color:white;
521 font-weight:bold;
522 padding:0.1em 0.5em 0.1em 0.5em;
523 text-decoration:none;
524 }
525div.head div.login a:hover {
526 background:rgb(193,193,244);
527 }
528
529h1.apc { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
530* html h1.apc { margin-bottom:-7px; }
531h1.apc a:hover { text-decoration:none; color:rgb(90,90,90); }
532h1.apc div.logo span.logo {
533 background:rgb(119,123,180);
534 color:black;
535 border-right: solid black 1px;
536 border-bottom: solid black 1px;
537 font-style:italic;
538 font-size:1em;
539 padding-left:1.2em;
540 padding-right:1.2em;
541 text-align:right;
542 }
543h1.apc div.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
544h1.apc div.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
545h1.apc div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
546hr.apc {
547 background:white;
548 border-bottom:solid rgb(102,102,153) 1px;
549 border-style:none;
550 border-top:solid rgb(102,102,153) 10px;
551 height:12px;
552 margin:0;
553 margin-top:1px;
554 padding:0;
555}
556
557ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
558ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
559ol.menu a {
560 background:rgb(153,153,204);
561 border:solid rgb(102,102,153) 2px;
562 color:white;
563 font-weight:bold;
564 margin-right:0em;
565 padding:0.1em 0.5em 0.1em 0.5em;
566 text-decoration:none;
567 margin-left: 5px;
568 }
569ol.menu a.child_active {
570 background:rgb(153,153,204);
571 border:solid rgb(102,102,153) 2px;
572 color:white;
573 font-weight:bold;
574 margin-right:0em;
575 padding:0.1em 0.5em 0.1em 0.5em;
576 text-decoration:none;
577 border-left: solid black 5px;
578 margin-left: 0px;
579 }
580ol.menu span.active {
581 background:rgb(153,153,204);
582 border:solid rgb(102,102,153) 2px;
583 color:black;
584 font-weight:bold;
585 margin-right:0em;
586 padding:0.1em 0.5em 0.1em 0.5em;
587 text-decoration:none;
588 border-left: solid black 5px;
589 }
590ol.menu span.inactive {
591 background:rgb(193,193,244);
592 border:solid rgb(182,182,233) 2px;
593 color:white;
594 font-weight:bold;
595 margin-right:0em;
596 padding:0.1em 0.5em 0.1em 0.5em;
597 text-decoration:none;
598 margin-left: 5px;
599 }
600ol.menu a:hover {
601 background:rgb(193,193,244);
602 text-decoration:none;
603 }
604
605
606div.info {
607 background:rgb(204,204,204);
608 border:solid rgb(204,204,204) 1px;
609 margin-bottom:1em;
610 }
611div.info h2 {
612 background:rgb(204,204,204);
613 color:black;
614 font-size:1em;
615 margin:0;
616 padding:0.1em 1em 0.1em 1em;
617 }
618div.info table {
619 border:solid rgb(204,204,204) 1px;
620 border-spacing:0;
621 width:100%;
622 }
623div.info table th {
624 background:rgb(204,204,204);
625 color:white;
626 margin:0;
627 padding:0.1em 1em 0.1em 1em;
628 }
629div.info table th a.sortable { color:black; }
630div.info table tr.tr-0 { background:rgb(238,238,238); }
631div.info table tr.tr-1 { background:rgb(221,221,221); }
632div.info table td { padding:0.3em 1em 0.3em 1em; }
633div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
634div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
635div.info table td h3 {
636 color:black;
637 font-size:1.1em;
638 margin-left:-0.3em;
639 }
640
641div.graph { margin-bottom:1em }
642div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
643div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
644div.graph table td.td-0 { background:rgb(238,238,238); }
645div.graph table td.td-1 { background:rgb(221,221,221); }
646div.graph table td { padding:0.2em 1em 0.4em 1em; }
647
648div.div1,div.div2 { margin-bottom:1em; width:35em; }
649div.div3 { position:absolute; left:40em; top:1em; width:580px; }
650//div.div3 { position:absolute; left:37em; top:1em; right:1em; }
651
652div.sorting { margin:1.5em 0em 1.5em 2em }
653.center { text-align:center }
654.aright { position:absolute;right:1em }
655.right { text-align:right }
656.ok { color:rgb(0,200,0); font-weight:bold}
657.failed { color:rgb(200,0,0); font-weight:bold}
658
659span.box {
660 border: black solid 1px;
661 border-right:solid black 2px;
662 border-bottom:solid black 2px;
663 padding:0 0.5em 0 0.5em;
664 margin-right:1em;
665}
666span.green { background:#60F060; padding:0 0.5em 0 0.5em}
667span.red { background:#D06030; padding:0 0.5em 0 0.5em }
668
669div.authneeded {
670 background:rgb(238,238,238);
671 border:solid rgb(204,204,204) 1px;
672 color:rgb(200,0,0);
673 font-size:1.2em;
674 font-weight:bold;
675 padding:2em;
676 text-align:center;
677 }
678
679input {
680 background:rgb(153,153,204);
681 border:solid rgb(102,102,153) 2px;
682 color:white;
683 font-weight:bold;
684 margin-right:1em;
685 padding:0.1em 0.5em 0.1em 0.5em;
686 }
687//-->
688</style>
689</head>
690<body>
691<div class="head">
692 <h1 class="apc">
693 <div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APC">APC</a></span></div>
694 <div class="nameinfo">Opcode Cache</div>
695 </h1>
696 <div class="login">
697 <?php put_login_link(); ?>
698 </div>
699 <hr class="apc">
700</div>
701<?php
702
703
704// Display main Menu
705echo <<<EOB
706 <ol class=menu>
707 <li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li>
708EOB;
709echo
710 menu_entry(1,'View Host Stats'),
711 menu_entry(2,'System Cache Entries');
712if ($AUTHENTICATED) {
713 echo menu_entry(4,'Per-Directory Entries');
714}
715echo
716 menu_entry(3,'User Cache Entries'),
717 menu_entry(9,'Version Check');
718
719if ($AUTHENTICATED) {
720 echo <<<EOB
721 <li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascipt:return confirm('Are you sure?');">Clear $cache_mode Cache</a></li>
722EOB;
723}
724echo <<<EOB
725 </ol>
726EOB;
727
728
729// CONTENT
730echo <<<EOB
731 <div class=content>
732EOB;
733
734// MAIN SWITCH STATEMENT
735
736switch ($MYREQUEST['OB']) {
737
738
739
740
741
742// -----------------------------------------------
743// Host Stats
744// -----------------------------------------------
745case OB_HOST_STATS:
746 $mem_size = $mem['num_seg']*$mem['seg_size'];
747 $mem_avail= $mem['avail_mem'];
748 $mem_used = $mem_size-$mem_avail;
749 $seg_size = bsize($mem['seg_size']);
750 $req_rate = sprintf("%.2f",($cache['num_hits']+$cache['num_misses'])/($time-$cache['start_time']));
751 $hit_rate = sprintf("%.2f",($cache['num_hits'])/($time-$cache['start_time']));
752 $miss_rate = sprintf("%.2f",($cache['num_misses'])/($time-$cache['start_time']));
753 $insert_rate = sprintf("%.2f",($cache['num_inserts'])/($time-$cache['start_time']));
754 $req_rate_user = sprintf("%.2f",($cache_user['num_hits']+$cache_user['num_misses'])/($time-$cache_user['start_time']));
755 $hit_rate_user = sprintf("%.2f",($cache_user['num_hits'])/($time-$cache_user['start_time']));
756 $miss_rate_user = sprintf("%.2f",($cache_user['num_misses'])/($time-$cache_user['start_time']));
757 $insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time']));
758 $apcversion = phpversion('apc');
759 $phpversion = phpversion();
760 $number_files = $cache['num_entries'];
761 $size_files = bsize($cache['mem_size']);
762 $number_vars = $cache_user['num_entries'];
763 $size_vars = bsize($cache_user['mem_size']);
764 $i=0;
765 echo <<< EOB
766 <div class="info div1"><h2>General Cache Information</h2>
767 <table cellspacing=0><tbody>
768 <tr class=tr-0><td class=td-0>APC Version</td><td>$apcversion</td></tr>
769 <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
770EOB;
771
772 if(!empty($_SERVER['SERVER_NAME']))
773 echo "<tr class=tr-0><td class=td-0>APC Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n";
774 if(!empty($_SERVER['SERVER_SOFTWARE']))
775 echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n";
776
777 echo <<<EOB
778 <tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size
779 <br/> ({$cache['memory_type']} memory, {$cache['locking_type']} locking)
780 </td></tr>
781EOB;
782 echo '<tr class=tr-1><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$cache['start_time']),'</td></tr>';
783 echo '<tr class=tr-0><td class=td-0>Uptime</td><td>',duration($cache['start_time']),'</td></tr>';
784 echo '<tr class=tr-1><td class=td-0>File Upload Support</td><td>',$cache['file_upload_progress'],'</td></tr>';
785 echo <<<EOB
786 </tbody></table>
787 </div>
788
789 <div class="info div1"><h2>File Cache Information</h2>
790 <table cellspacing=0><tbody>
791 <tr class=tr-0><td class=td-0>Cached Files</td><td>$number_files ($size_files)</td></tr>
792 <tr class=tr-1><td class=td-0>Hits</td><td>{$cache['num_hits']}</td></tr>
793 <tr class=tr-0><td class=td-0>Misses</td><td>{$cache['num_misses']}</td></tr>
794 <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
795 <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
796 <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
797 <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate cache requests/second</td></tr>
798 <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['expunges']}</td></tr>
799 </tbody></table>
800 </div>
801
802 <div class="info div1"><h2>User Cache Information</h2>
803 <table cellspacing=0><tbody>
804 <tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr>
805 <tr class=tr-1><td class=td-0>Hits</td><td>{$cache_user['num_hits']}</td></tr>
806 <tr class=tr-0><td class=td-0>Misses</td><td>{$cache_user['num_misses']}</td></tr>
807 <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr>
808 <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr>
809 <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr>
810 <tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr>
811 <tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache_user['expunges']}</td></tr>
812
813 </tbody></table>
814 </div>
815
816 <div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody>
817EOB;
818
819 $j = 0;
820 foreach (ini_get_all('apc') as $k => $v) {
821 echo "<tr class=tr-$j><td class=td-0>",$k,"</td><td>",str_replace(',',',<br />',$v['local_value']),"</td></tr>\n";
822 $j = 1 - $j;
823 }
824
825 if($mem['num_seg']>1 || $mem['num_seg']==1 && count($mem['block_lists'][0])>1)
826 $mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>";
827 else
828 $mem_note = "Memory Usage";
829
830 echo <<< EOB
831 </tbody></table>
832 </div>
833
834 <div class="graph div3"><h2>Host Status Diagrams</h2>
835 <table cellspacing=0><tbody>
836EOB;
837 $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
838 echo <<<EOB
839 <tr>
840 <td class=td-0>$mem_note</td>
841 <td class=td-1>Hits & Misses</td>
842 </tr>
843EOB;
844
845 echo
846 graphics_avail() ?
847 '<tr>'.
848 "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF?IMG=1&$time\"></td>".
849 "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF?IMG=2&$time\"></td></tr>\n"
850 : "",
851 '<tr>',
852 '<td class=td-0><span class="green box"> </span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
853 '<td class=td-1><span class="green box"> </span>Hits: ',$cache['num_hits'].sprintf(" (%.1f%%)",$cache['num_hits']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n",
854 '</tr>',
855 '<tr>',
856 '<td class=td-0><span class="red box"> </span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
857 '<td class=td-1><span class="red box"> </span>Misses: ',$cache['num_misses'].sprintf(" (%.1f%%)",$cache['num_misses']*100/($cache['num_hits']+$cache['num_misses'])),"</td>\n";
858 echo <<< EOB
859 </tr>
860 </tbody></table>
861
862 <br/>
863 <h2>Detailed Memory Usage and Fragmentation</h2>
864 <table cellspacing=0><tbody>
865 <tr>
866 <td class=td-0 colspan=2><br/>
867EOB;
868
869 // Fragementation: (freeseg - 1) / total_seg
870 $nseg = $freeseg = $fragsize = $freetotal = 0;
871 for($i=0; $i<$mem['num_seg']; $i++) {
872 $ptr = 0;
873 foreach($mem['block_lists'][$i] as $block) {
874 if ($block['offset'] != $ptr) {
875 ++$nseg;
876 }
877 $ptr = $block['offset'] + $block['size'];
878 /* Only consider blocks <5M for the fragmentation % */
879 if($block['size']<(5*1024*1024)) $fragsize+=$block['size'];
880 $freetotal+=$block['size'];
881 }
882 $freeseg += count($mem['block_lists'][$i]);
883 }
884
885 if ($freeseg > 1) {
886 $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg);
887 } else {
888 $frag = "0%";
889 }
890
891 if (graphics_avail()) {
892 $size='width='.(2*GRAPH_SIZE+150).' height='.(GRAPH_SIZE+10);
893 echo <<<EOB
894 <img alt="" $size src="$PHP_SELF?IMG=3&$time">
895EOB;
896 }
897 echo <<<EOB
898 </br>Fragmentation: $frag
899 </td>
900 </tr>
901EOB;
902 if(isset($mem['adist'])) {
903 foreach($mem['adist'] as $i=>$v) {
904 $cur = pow(2,$i); $nxt = pow(2,$i+1)-1;
905 if($i==0) $range = "1";
906 else $range = "$cur - $nxt";
907 echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n";
908 }
909 }
910 echo <<<EOB
911 </tbody></table>
912 </div>
913EOB;
914
915 break;
916
917
918// -----------------------------------------------
919// User Cache Entries
920// -----------------------------------------------
921case OB_USER_CACHE:
922 if (!$AUTHENTICATED) {
923 echo '<div class="authneeded">You need to login to see the user values here!<br/> <br/>';
924 put_login_link("Login now!");
925 echo '</div>';
926 break;
927 }
928 $fieldname='info';
929 $fieldheading='User Entry Label';
930 $fieldkey='info';
931
932
933// -----------------------------------------------
934// System Cache Entries
935// -----------------------------------------------
936case OB_SYS_CACHE:
937 if (!isset($fieldname))
938 {
939 $fieldname='filename';
940 $fieldheading='Script Filename';
941 if(ini_get("apc.stat")) $fieldkey='inode';
942 else $fieldkey='filename';
943 }
944 if (!empty($MYREQUEST['SH']))
945 {
946 echo <<< EOB
947 <div class="info"><table cellspacing=0><tbody>
948 <tr><th>Attribute</th><th>Value</th></tr>
949EOB;
950
951 $m=0;
952 foreach($scope_list as $j => $list) {
953 foreach($cache[$list] as $i => $entry) {
954 if (md5($entry[$fieldkey])!=$MYREQUEST['SH']) continue;
955 foreach($entry as $k => $value) {
956 if (!$AUTHENTICATED) {
957 // hide all path entries if not logged in
958 $value=preg_replace('/^.*(\\/|\\\\)/','<i><hidden></i>/',$value);
959 }
960
961 if ($k == "num_hits") {
962 $value=sprintf("%s (%.2f%%)",$value,$value*100/$cache['num_hits']);
963 }
964 if ($k == 'deletion_time') {
965 if(!$entry['deletion_time']) $value = "None";
966 }
967 echo
968 "<tr class=tr-$m>",
969 "<td class=td-0>",ucwords(preg_replace("/_/"," ",$k)),"</td>",
970 "<td class=td-last>",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : $value,"</td>",
971 "</tr>";
972 $m=1-$m;
973 }
974 if($fieldkey=='info') {
975 echo "<tr class=tr-$m><td class=td-0>Stored Value</td><td class=td-last><pre>";
976 $output = var_export(apc_fetch($entry[$fieldkey]),true);
977 echo htmlspecialchars($output);
978 echo "</pre></td></tr>\n";
979 }
980 break;
981 }
982 }
983
984 echo <<<EOB
985 </tbody></table>
986 </div>
987EOB;
988 break;
989 }
990
991 $cols=6;
992 echo <<<EOB
993 <div class=sorting><form>Scope:
994 <input type=hidden name=OB value={$MYREQUEST['OB']}>
995 <select name=SCOPE>
996EOB;
997 echo
998 "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
999 "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
1000 "</select>",
1001 ", Sorting:<select name=SORT1>",
1002 "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Hits</option>",
1003 "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Size</option>",
1004 "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">$fieldheading</option>",
1005 "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Last accessed</option>",
1006 "<option value=M",$MYREQUEST['SORT1']=='M' ? " selected":"",">Last modified</option>",
1007 "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Created at</option>",
1008 "<option value=D",$MYREQUEST['SORT1']=='D' ? " selected":"",">Deleted at</option>";
1009 if($fieldname=='info') echo
1010 "<option value=D",$MYREQUEST['SORT1']=='T' ? " selected":"",">Timeout</option>";
1011 echo
1012 '</select>',
1013 '<select name=SORT2>',
1014 '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
1015 '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
1016 '</select>',
1017 '<select name=COUNT onChange="form.submit()">',
1018 '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
1019 '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
1020 '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
1021 '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
1022 '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
1023 '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
1024 '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
1025 '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
1026 '</select>',
1027 ' Search: <input name=SEARCH value="',$MYREQUEST['SEARCH'],'" type=text size=25/>',
1028 ' <input type=submit value="GO!">',
1029 '</form></div>',
1030
1031 '<div class="info"><table cellspacing=0><tbody>',
1032 '<tr>',
1033 '<th>',sortheader('S',$fieldheading, "&OB=".$MYREQUEST['OB']),'</th>',
1034 '<th>',sortheader('H','Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1035 '<th>',sortheader('Z','Size', "&OB=".$MYREQUEST['OB']),'</th>',
1036 '<th>',sortheader('A','Last accessed',"&OB=".$MYREQUEST['OB']),'</th>',
1037 '<th>',sortheader('M','Last modified',"&OB=".$MYREQUEST['OB']),'</th>',
1038 '<th>',sortheader('C','Created at', "&OB=".$MYREQUEST['OB']),'</th>';
1039
1040 if($fieldname=='info') {
1041 $cols+=2;
1042 echo '<th>',sortheader('T','Timeout',"&OB=".$MYREQUEST['OB']),'</th>';
1043 }
1044 echo '<th>',sortheader('D','Deleted at',"&OB=".$MYREQUEST['OB']),'</th></tr>';
1045
1046 // builds list with alpha numeric sortable keys
1047 //
1048 $list = array();
1049 foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) {
1050 switch($MYREQUEST['SORT1']) {
1051 case 'A': $k=sprintf('%015d-',$entry['access_time']); break;
1052 case 'H': $k=sprintf('%015d-',$entry['num_hits']); break;
1053 case 'Z': $k=sprintf('%015d-',$entry['mem_size']); break;
1054 case 'M': $k=sprintf('%015d-',$entry['mtime']); break;
1055 case 'C': $k=sprintf('%015d-',$entry['creation_time']); break;
1056 case 'T': $k=sprintf('%015d-',$entry['ttl']); break;
1057 case 'D': $k=sprintf('%015d-',$entry['deletion_time']); break;
1058 case 'S': $k=''; break;
1059 }
1060 if (!$AUTHENTICATED) {
1061 // hide all path entries if not logged in
1062 $list[$k.$entry[$fieldname]]=preg_replace('/^.*(\\/|\\\\)/','<i><hidden></i>/',$entry);
1063 } else {
1064 $list[$k.$entry[$fieldname]]=$entry;
1065 }
1066 }
1067
1068 if ($list) {
1069
1070 // sort list
1071 //
1072 switch ($MYREQUEST['SORT2']) {
1073 case "A": krsort($list); break;
1074 case "D": ksort($list); break;
1075 }
1076
1077 // output list
1078 $i=0;
1079 foreach($list as $k => $entry) {
1080 if(!$MYREQUEST['SEARCH'] || preg_match('/'.$MYREQUEST['SEARCH'].'/i', $entry[$fieldname]) != 0) {
1081 echo
1082 '<tr class=tr-',$i%2,'>',
1083 "<td class=td-0><a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&SH=",md5($entry[$fieldkey]),"\">",$entry[$fieldname],'</a></td>',
1084 '<td class="td-n center">',$entry['num_hits'],'</td>',
1085 '<td class="td-n right">',$entry['mem_size'],'</td>',
1086 '<td class="td-n center">',date(DATE_FORMAT,$entry['access_time']),'</td>',
1087 '<td class="td-n center">',date(DATE_FORMAT,$entry['mtime']),'</td>',
1088 '<td class="td-n center">',date(DATE_FORMAT,$entry['creation_time']),'</td>';
1089
1090 if($fieldname=='info') {
1091 if($entry['ttl'])
1092 echo '<td class="td-n center">'.$entry['ttl'].' seconds</td>';
1093 else
1094 echo '<td class="td-n center">None</td>';
1095 }
1096 echo
1097 '<td class="td-last center">',$entry['deletion_time'] ? date(DATE_FORMAT,$entry['deletion_time']) : '-','</td>',
1098 '</tr>';
1099 $i++;
1100 if ($i == $MYREQUEST['COUNT'])
1101 break;
1102 }
1103 }
1104
1105 } else {
1106 echo '<tr class=tr-0><td class="center" colspan=',$cols,'><i>No data</i></td></tr>';
1107 }
1108 echo <<< EOB
1109 </tbody></table>
1110EOB;
1111
1112 if ($list && $i < count($list)) {
1113 echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
1114 }
1115
1116 echo <<< EOB
1117 </div>
1118EOB;
1119 break;
1120
1121
1122// -----------------------------------------------
1123// Per-Directory System Cache Entries
1124// -----------------------------------------------
1125case OB_SYS_CACHE_DIR:
1126 if (!$AUTHENTICATED) {
1127 break;
1128 }
1129
1130 echo <<<EOB
1131 <div class=sorting><form>Scope:
1132 <input type=hidden name=OB value={$MYREQUEST['OB']}>
1133 <select name=SCOPE>
1134EOB;
1135 echo
1136 "<option value=A",$MYREQUEST['SCOPE']=='A' ? " selected":"",">Active</option>",
1137 "<option value=D",$MYREQUEST['SCOPE']=='D' ? " selected":"",">Deleted</option>",
1138 "</select>",
1139 ", Sorting:<select name=SORT1>",
1140 "<option value=H",$MYREQUEST['SORT1']=='H' ? " selected":"",">Total Hits</option>",
1141 "<option value=Z",$MYREQUEST['SORT1']=='Z' ? " selected":"",">Total Size</option>",
1142 "<option value=T",$MYREQUEST['SORT1']=='T' ? " selected":"",">Number of Files</option>",
1143 "<option value=S",$MYREQUEST['SORT1']=='S' ? " selected":"",">Directory Name</option>",
1144 "<option value=A",$MYREQUEST['SORT1']=='A' ? " selected":"",">Avg. Size</option>",
1145 "<option value=C",$MYREQUEST['SORT1']=='C' ? " selected":"",">Avg. Hits</option>",
1146 '</select>',
1147 '<select name=SORT2>',
1148 '<option value=D',$MYREQUEST['SORT2']=='D' ? ' selected':'','>DESC</option>',
1149 '<option value=A',$MYREQUEST['SORT2']=='A' ? ' selected':'','>ASC</option>',
1150 '</select>',
1151 '<select name=COUNT onChange="form.submit()">',
1152 '<option value=10 ',$MYREQUEST['COUNT']=='10' ? ' selected':'','>Top 10</option>',
1153 '<option value=20 ',$MYREQUEST['COUNT']=='20' ? ' selected':'','>Top 20</option>',
1154 '<option value=50 ',$MYREQUEST['COUNT']=='50' ? ' selected':'','>Top 50</option>',
1155 '<option value=100',$MYREQUEST['COUNT']=='100'? ' selected':'','>Top 100</option>',
1156 '<option value=150',$MYREQUEST['COUNT']=='150'? ' selected':'','>Top 150</option>',
1157 '<option value=200',$MYREQUEST['COUNT']=='200'? ' selected':'','>Top 200</option>',
1158 '<option value=500',$MYREQUEST['COUNT']=='500'? ' selected':'','>Top 500</option>',
1159 '<option value=0 ',$MYREQUEST['COUNT']=='0' ? ' selected':'','>All</option>',
1160 '</select>',
1161 ", Group By Dir Level:<select name=AGGR>",
1162 "<option value='' selected>None</option>";
1163 for ($i = 1; $i < 10; $i++)
1164 echo "<option value=$i",$MYREQUEST['AGGR']==$i ? " selected":"",">$i</option>";
1165 echo '</select>',
1166 ' <input type=submit value="GO!">',
1167 '</form></div>',
1168
1169 '<div class="info"><table cellspacing=0><tbody>',
1170 '<tr>',
1171 '<th>',sortheader('S','Directory Name', "&OB=".$MYREQUEST['OB']),'</th>',
1172 '<th>',sortheader('T','Number of Files',"&OB=".$MYREQUEST['OB']),'</th>',
1173 '<th>',sortheader('H','Total Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1174 '<th>',sortheader('Z','Total Size', "&OB=".$MYREQUEST['OB']),'</th>',
1175 '<th>',sortheader('C','Avg. Hits', "&OB=".$MYREQUEST['OB']),'</th>',
1176 '<th>',sortheader('A','Avg. Size', "&OB=".$MYREQUEST['OB']),'</th>',
1177 '</tr>';
1178
1179 // builds list with alpha numeric sortable keys
1180 //
1181 $tmp = $list = array();
1182 foreach($cache[$scope_list[$MYREQUEST['SCOPE']]] as $entry) {
1183 $n = dirname($entry['filename']);
1184 if ($MYREQUEST['AGGR'] > 0) {
1185 $n = preg_replace("!^(/?(?:[^/\\\\]+[/\\\\]){".($MYREQUEST['AGGR']-1)."}[^/\\\\]*).*!", "$1", $n);
1186 }
1187 if (!isset($tmp[$n])) {
1188 $tmp[$n] = array('hits'=>0,'size'=>0,'ents'=>0);
1189 }
1190 $tmp[$n]['hits'] += $entry['num_hits'];
1191 $tmp[$n]['size'] += $entry['mem_size'];
1192 ++$tmp[$n]['ents'];
1193 }
1194
1195 foreach ($tmp as $k => $v) {
1196 switch($MYREQUEST['SORT1']) {
1197 case 'A': $kn=sprintf('%015d-',$v['size'] / $v['ents']);break;
1198 case 'T': $kn=sprintf('%015d-',$v['ents']); break;
1199 case 'H': $kn=sprintf('%015d-',$v['hits']); break;
1200 case 'Z': $kn=sprintf('%015d-',$v['size']); break;
1201 case 'C': $kn=sprintf('%015d-',$v['hits'] / $v['ents']);break;
1202 case 'S': $kn = $k; break;
1203 }
1204 $list[$kn.$k] = array($k, $v['ents'], $v['hits'], $v['size']);
1205 }
1206
1207 if ($list) {
1208
1209 // sort list
1210 //
1211 switch ($MYREQUEST['SORT2']) {
1212 case "A": krsort($list); break;
1213 case "D": ksort($list); break;
1214 }
1215
1216 // output list
1217 $i = 0;
1218 foreach($list as $entry) {
1219 echo
1220 '<tr class=tr-',$i%2,'>',
1221 "<td class=td-0>",$entry[0],'</a></td>',
1222 '<td class="td-n center">',$entry[1],'</td>',
1223 '<td class="td-n center">',$entry[2],'</td>',
1224 '<td class="td-n center">',$entry[3],'</td>',
1225 '<td class="td-n center">',round($entry[2] / $entry[1]),'</td>',
1226 '<td class="td-n center">',round($entry[3] / $entry[1]),'</td>',
1227 '</tr>';
1228
1229 if (++$i == $MYREQUEST['COUNT']) break;
1230 }
1231
1232 } else {
1233 echo '<tr class=tr-0><td class="center" colspan=6><i>No data</i></td></tr>';
1234 }
1235 echo <<< EOB
1236 </tbody></table>
1237EOB;
1238
1239 if ($list && $i < count($list)) {
1240 echo "<a href=\"$MY_SELF&OB=",$MYREQUEST['OB'],"&COUNT=0\"><i>",count($list)-$i,' more available...</i></a>';
1241 }
1242
1243 echo <<< EOB
1244 </div>
1245EOB;
1246 break;
1247
1248// -----------------------------------------------
1249// Version check
1250// -----------------------------------------------
1251case OB_VERSION_CHECK:
1252 echo <<<EOB
1253 <div class="info"><h2>APC Version Information</h2>
1254 <table cellspacing=0><tbody>
1255 <tr>
1256 <th></th>
1257 </tr>
1258EOB;
1259
1260 $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss");
1261 if (!$rss) {
1262 echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>';
1263 } else {
1264 $apcversion = phpversion('apc');
1265
1266 preg_match('!<title>APC ([0-9.]+)</title>!', $rss, $match);
1267 echo '<tr class="tr-0 center"><td>';
1268 if (version_compare($apcversion, $match[1], '>=')) {
1269 echo '<div class="ok">You are running the latest version of APC ('.$apcversion.')</div>';
1270 $i = 3;
1271 } else {
1272 echo '<div class="failed">You are running an older version of APC ('.$apcversion.'),
1273 newer version '.$match[1].' is available at <a href="http://pecl.php.net/package/APC/'.$match[1].'">
1274 http://pecl.php.net/package/APC/'.$match[1].'</a>
1275 </div>';
1276 $i = -1;
1277 }
1278 echo '</td></tr>';
1279 echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>';
1280
1281 preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match);
1282 next($match[2]); next($match[2]);
1283
1284 while (list(,$v) = each($match[2])) {
1285 list(,$ver) = explode(' ', $v, 2);
1286 if ($i < 0 && version_compare($apcversion, $ver, '>=')) {
1287 break;
1288 } else if (!$i--) {
1289 break;
1290 }
1291 echo "<b><a href=\"http://pecl.php.net/package/APC/$ver\">".htmlspecialchars($v)."</a></b><br><blockquote>";
1292 echo nl2br(htmlspecialchars(current($match[2])))."</blockquote>";
1293 next($match[2]);
1294 }
1295 echo '</td></tr>';
1296 }
1297 echo <<< EOB
1298 </tbody></table>
1299 </div>
1300EOB;
1301 break;
1302
1303}
1304
1305echo <<< EOB
1306 </div>
1307EOB;
1308
1309?>
1310
1311<!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n"?> -->
1312</body>
1313</html>