root/eaccelerator/tags/0.9.5-rc1/ea_info.c

Revision 237, 13.8 kB (checked in by bart, 2 years ago)

* Make clean routine support dir hashing. Again, this should be tested on win32!
* Use a define for the magic string in the eAccelerator file headers
* Bump up version to 0.9.5-rc1
* Put -O2 back on for -rc1

  • Property svn:keywords set to svn:eol-style
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | eAccelerator project                                                 |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 2004 - 2006 eAccelerator                               |
6    | http://eaccelerator.net                                                      |
7    +----------------------------------------------------------------------+
8    | This program is free software; you can redistribute it and/or        |
9    | modify it under the terms of the GNU General Public License          |
10    | as published by the Free Software Foundation; either version 2       |
11    | of the License, or (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    | You should have received a copy of the GNU General Public License    |
19    | along with this program; if not, write to the Free Software          |
20    | Foundation, Inc., 59 Temple Place - Suite 330, Boston,               |
21    | MA  02111-1307, USA.                                                 |
22    |                                                                      |
23    | A copy is availble at http://www.gnu.org/copyleft/gpl.txt            |
24    +----------------------------------------------------------------------+
25    $Id: $
26 */
27
28 #include "eaccelerator.h"
29 #include "eaccelerator_version.h"
30 #include "ea_info.h"
31 #include "mm.h"
32 #include "cache.h"
33 #include "zend.h"
34 #include "fopen_wrappers.h"
35 #include "debug.h"
36 #include <fcntl.h>
37
38 #ifndef O_BINARY
39 #  define O_BINARY 0
40 #endif
41
42 #ifdef WITH_EACCELERATOR_INFO
43
44 #define NOT_ADMIN_WARNING "This script isn't in the allowed_admin_path setting!"
45
46 extern eaccelerator_mm *eaccelerator_mm_instance;
47
48 /* {{{ isAdminAllowed(): check if the admin functions are allowed for the calling script */
49 static int isAdminAllowed(TSRMLS_D) {
50     const char *filename = zend_get_executed_filename(TSRMLS_C);
51     if (EAG(allowed_admin_path) && *EAG(allowed_admin_path)) {
52         char *path;
53         char *p;
54         char *next;
55
56         path = estrdup(EAG(allowed_admin_path));
57         p = path;
58
59         while (p && *p) {
60             next = strchr(p, DEFAULT_DIR_SEPARATOR);
61             if (next != NULL) {
62                 *next = '\0';
63                 ++next;
64             }
65            
66             if (!php_check_specific_open_basedir(p, filename TSRMLS_CC)) {
67                 efree(path);
68                 return 1;
69             }
70
71             p = next;
72         }
73         efree(path);
74         return 0;
75     }
76     return 0;
77 }
78 /* }}} */
79
80 /* {{{ clear_filecache(): Helper function to eaccelerator_clear which finds diskcache entries in the hashed dirs and removes them */
81 static void clear_filecache(const char* dir)
82 #ifndef ZEND_WIN32
83 {
84         DIR *dp;
85         struct dirent *entry;
86         char s[MAXPATHLEN];
87         struct stat dirstat;
88        
89         if ((dp = opendir(dir)) != NULL) {
90                 while ((entry = readdir(dp)) != NULL) {
91                         strncpy(s, dir, MAXPATHLEN - 1);
92                         strlcat(s, "/", MAXPATHLEN);
93                         strlcat(s, entry->d_name, MAXPATHLEN);
94                         if (strstr(entry->d_name, "eaccelerator") == entry->d_name) {
95                                 unlink(s);
96                         }
97                         if (stat(s, &dirstat) != -1) {
98                                 if (strcmp(entry->d_name, ".") == 0)
99                                         continue;
100                                 if (strcmp(entry->d_name, "..") == 0)
101                                         continue;
102                                 if (S_ISDIR(dirstat.st_mode)) {
103                                         clear_filecache(s);
104                                 }
105                         }
106                 }
107                 closedir (dp);
108         } else {
109                 ea_debug_error("[%s] Could not open cachedir %s\n", EACCELERATOR_EXTENSION_NAME, dir);
110         }
111 }
112 #else
113 {
114         HANDLE  hFind;
115     WIN32_FIND_DATA wfd;
116     char path[MAXPATHLEN];
117     size_t dirlen = strlen(dir);
118  
119     memcpy(path, dir, dirlen);
120     strcpy(path + dirlen++, "\\eaccelerator*");
121
122     hFind = FindFirstFile(path, &wfd);
123         if (hFind == INVALID_HANDLE_VALUE) {
124                 do {
125                         strcpy(path + dirlen, wfd.cFileName);
126                         if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) {
127                                 clear_filecache(path);
128                         } else if (!DeleteFile(path)) {
129                                 ea_debug_error("[%s] Can't delete file %s: error %d\n", EACCELERATOR_EXTENSION_NAME, path, GetLastError());
130                         }
131                 } while (FindNextFile(hFind, &wfd));
132         }
133     FindClose (hFind);
134 }
135 #endif
136 /* }}} */
137
138 /* {{{  clean_file: check if the given file is expired */
139 static inline void clean_file(char *file, time_t t)
140 {
141         int f;
142
143         if ((f = open(file, O_RDONLY | O_BINARY)) > 0) {
144                 mm_file_header hdr;
145                 EACCELERATOR_FLOCK (f, LOCK_SH);
146                 if (read(f, &hdr, sizeof(hdr)) != sizeof(hdr)
147                                 || strncmp (hdr.magic, EA_MAGIC,        8) != 0
148                                 || (hdr.mtime != 0 && hdr.mtime < t)) {
149                         EACCELERATOR_FLOCK (f, LOCK_UN);
150                         close (f);
151                         unlink (file);
152                 } else {
153                         EACCELERATOR_FLOCK (f, LOCK_UN);
154                         close (f);
155                 }
156         }
157 }
158 /* }}} */
159
160 /* {{{ clean_filecache(): Helper function for eaccelerator_clean, it will remove all expired entries from the user cache */
161 static void clean_filecache(const char* dir, time_t t)
162 #ifndef ZEND_WIN32
163 {
164         DIR *dp;
165         struct dirent *entry;
166         char s[MAXPATHLEN];
167         struct stat dirstat;
168        
169         if ((dp = opendir(dir)) != NULL) {
170                 while ((entry = readdir(dp)) != NULL) {
171                         strncpy(s, dir, MAXPATHLEN - 1);
172                         strlcat(s, "/", MAXPATHLEN);
173                         strlcat(s, entry->d_name, MAXPATHLEN);
174                         if (strstr(entry->d_name, "eaccelerator-user") == entry->d_name) {
175                                 clean_file(s, t);
176                         }
177                         if (stat(s, &dirstat) != -1) {
178                                 if (strcmp(entry->d_name, ".") == 0)
179                                         continue;
180                                 if (strcmp(entry->d_name, "..") == 0)
181                                         continue;
182                                 if (S_ISDIR(dirstat.st_mode)) {
183                                         clean_filecache(s, t);
184                                 }
185                         }
186                 }
187                 closedir (dp);
188         } else {
189                 ea_debug_error("[%s] Could not open cachedir %s\n", EACCELERATOR_EXTENSION_NAME, dir);
190         }
191 }
192 #else
193 {
194         HANDLE  hFind;
195     WIN32_FIND_DATA wfd;
196     char path[MAXPATHLEN];
197     size_t dirlen = strlen(dir);
198  
199     memcpy(path, dir, dirlen);
200     strcpy(path + dirlen++, "\\eaccelerator-user*");
201
202     hFind = FindFirstFile(path, &wfd);
203         if (hFind == INVALID_HANDLE_VALUE) {
204                 do {
205                         strcpy(path + dirlen, wfd.cFileName);
206                         if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) {
207                                 clear_filecache(path);
208                         } else {
209                                 clean_file(path, t);
210                         }
211                 } while (FindNextFile(hFind, &wfd));
212         }
213     FindClose (hFind);
214 }
215 #endif
216 /* }}} */
217
218 /* {{{ PHP_FUNCTION(eaccelerator_caching): enable or disable caching */
219 PHP_FUNCTION(eaccelerator_caching)
220 {
221     zend_bool enable;
222    
223         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &enable) == FAILURE)
224                 return;
225
226     if (isAdminAllowed(TSRMLS_C)) {
227         EACCELERATOR_UNPROTECT();
228         if (enable) {
229             eaccelerator_mm_instance->enabled = 1;
230         } else {
231             eaccelerator_mm_instance->enabled = 0;
232         }
233         EACCELERATOR_PROTECT();
234     } else {
235         zend_error(E_WARNING, NOT_ADMIN_WARNING);
236     }
237    
238     RETURN_NULL();
239 }
240 /* }}} */
241
242 /* {{{ PHP_FUNCTION(eaccelerator_optimizer): enable or disable optimizer */
243 #ifdef WITH_EACCELERATOR_OPTIMIZER
244 PHP_FUNCTION(eaccelerator_optimizer)
245 {
246     zend_bool enable;
247    
248         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &enable) == FAILURE)
249                 return;
250
251     if (isAdminAllowed(TSRMLS_C)) {
252         EACCELERATOR_UNPROTECT();
253         if (enable) {
254             eaccelerator_mm_instance->optimizer_enabled = 1;
255         } else {
256             eaccelerator_mm_instance->optimizer_enabled = 0;
257         }
258         EACCELERATOR_PROTECT();
259     } else {
260         zend_error(E_WARNING, NOT_ADMIN_WARNING);
261     }
262    
263     RETURN_NULL();
264 }
265 #endif
266 /* }}} */
267
268 /* {{{ PHP_FUNCTION(eaccelerator_clean): remove all expired scripts and data from shared memory and disk cache */
269 PHP_FUNCTION(eaccelerator_clean)
270 {
271         time_t t;
272
273     if (!isAdminAllowed(TSRMLS_C)) {
274         zend_error(E_WARNING, NOT_ADMIN_WARNING);
275         RETURN_NULL();
276     }
277
278         t = time (0);
279
280         /* Remove expired scripts from shared memory */
281         eaccelerator_prune (t);
282
283         /* Remove expired keys (session data, content) from disk cache */
284         clean_filecache(EAG(cache_dir), t);
285
286         /* Remove expired keys (session data, content) from shared memory */
287         eaccelerator_gc (TSRMLS_C);
288 }
289 /* }}} */
290
291 /* {{{ PHP_FUNCTION(eaccelerator_clear): remove all unused scripts and data from shared memory and disk cache */
292 PHP_FUNCTION(eaccelerator_clear)
293 {
294         unsigned int i;
295         mm_cache_entry *p;
296
297     if (!isAdminAllowed(TSRMLS_C)) {
298         zend_error(E_WARNING, NOT_ADMIN_WARNING);
299         RETURN_NULL();
300     }
301
302         EACCELERATOR_UNPROTECT ();
303         EACCELERATOR_LOCK_RW ();
304         for (i = 0; i < EA_HASH_SIZE; i++) {
305                 p = eaccelerator_mm_instance->hash[i];
306                 while (p != NULL) {
307                         mm_cache_entry *r = p;
308                         p = p->next;
309                         eaccelerator_mm_instance->hash_cnt--;
310                         if (r->use_cnt <= 0) {
311                                 eaccelerator_free_nolock (r);
312                         } else {
313                                 r->removed = 1;
314                                 r->next = eaccelerator_mm_instance->removed;
315                                 eaccelerator_mm_instance->removed = r;
316                                 eaccelerator_mm_instance->rem_cnt++;
317                         }
318                 }
319                 eaccelerator_mm_instance->hash[i] = NULL;
320         }
321         for (i = 0; i < EA_USER_HASH_SIZE; i++) {
322                 mm_user_cache_entry *p = eaccelerator_mm_instance->user_hash[i];
323                 while (p != NULL) {
324                         mm_user_cache_entry *r = p;
325                         p = p->next;
326                         eaccelerator_mm_instance->user_hash_cnt--;
327                         eaccelerator_free_nolock (r);
328                 }
329                 eaccelerator_mm_instance->user_hash[i] = NULL;
330         }
331         EACCELERATOR_UNLOCK_RW ();
332         EACCELERATOR_PROTECT ();
333
334         clear_filecache(EAG(cache_dir));
335        
336     RETURN_NULL();
337 }
338 /* }}} */
339
340 /* {{{ PHP_FUNCTION(eaccelerator_purge): remove all 'removed' scripts from shared memory */
341 PHP_FUNCTION(eaccelerator_purge)
342 {
343
344     if (!isAdminAllowed(TSRMLS_C)) {
345         zend_error(E_WARNING, NOT_ADMIN_WARNING);
346         RETURN_NULL();
347     }
348
349         if (eaccelerator_mm_instance != NULL) {
350                 mm_cache_entry *p, *q;
351                 EACCELERATOR_UNPROTECT();
352                 EACCELERATOR_LOCK_RW();
353                 p = eaccelerator_mm_instance->removed;
354                 eaccelerator_mm_instance->rem_cnt = 0;
355                 eaccelerator_mm_instance->removed = NULL;
356                 while (p != NULL) {
357                         q = p->next;
358                         eaccelerator_free_nolock(p);
359                         p = q;
360                 }
361                 EACCELERATOR_UNLOCK_RW();
362                 EACCELERATOR_PROTECT();
363         }
364     RETURN_NULL();
365 }
366 /* }}} */
367
368 /* {{{ PHP_FUNCTION(eaccelerator_info): get info about eaccelerator */
369 // returns info about eaccelerator as an array
370 // returhs the same as eaccelerator section in phpinfo
371 PHP_FUNCTION (eaccelerator_info)
372 {
373         unsigned int available;
374     char *shm, *sem;
375
376     shm = (char *)mm_shm_type();
377     sem = (char *)mm_sem_type();
378         available = mm_available (eaccelerator_mm_instance->mm);
379
380         // init return table
381         array_init(return_value);
382        
383         // put eaccelerator information
384         add_assoc_string(return_value, "version", EACCELERATOR_VERSION, 1);
385         add_assoc_string(return_value, "shm_type", shm, 1);
386     add_assoc_string(return_value, "sem_type", sem, 1);
387     add_assoc_string(return_value, "logo", EACCELERATOR_LOGO_GUID, 1);
388         add_assoc_bool(return_value, "cache", (EAG (enabled)
389                 && (eaccelerator_mm_instance != NULL)
390                 && eaccelerator_mm_instance->enabled) ? 1 : 0);
391         add_assoc_bool(return_value, "optimizer", (EAG (optimizer_enabled)
392                 && (eaccelerator_mm_instance != NULL)
393                 && eaccelerator_mm_instance->optimizer_enabled) ? 1 : 0);
394         add_assoc_long(return_value, "memorySize", eaccelerator_mm_instance->total);
395         add_assoc_long(return_value, "memoryAvailable", available);
396         add_assoc_long(return_value, "memoryAllocated", eaccelerator_mm_instance->total - available);
397         add_assoc_long(return_value, "cachedScripts", eaccelerator_mm_instance->hash_cnt);
398         add_assoc_long(return_value, "removedScripts", eaccelerator_mm_instance->rem_cnt);
399     add_assoc_long(return_value, "cachedKeys", eaccelerator_mm_instance->user_hash_cnt);
400
401         return;
402 }
403 /* }}} */
404
405 /* {{{ PHP_FUNCTION(eaccelerator_cached_scripts): Get an array with information about all cached scripts */
406 PHP_FUNCTION(eaccelerator_cached_scripts)
407 {
408     mm_cache_entry *p;
409     int i;
410
411     if (!isAdminAllowed(TSRMLS_C)) {
412         zend_error(E_WARNING, NOT_ADMIN_WARNING);
413         RETURN_NULL();
414     }
415
416     array_init(return_value);
417    
418     for (i = 0; i < EA_HASH_SIZE; i++) {
419         p = eaccelerator_mm_instance->hash[i];
420         while (p != NULL) {
421             zval *script;
422             MAKE_STD_ZVAL(script);
423             array_init(script);
424             add_assoc_string(script, "file", p->realfilename, 1);
425             add_assoc_long(script, "mtime", p->mtime);
426             add_assoc_long(script, "size", p->size);
427             add_assoc_long(script, "reloads", p->nreloads);
428             add_assoc_long(script, "usecount", p->use_cnt);
429             add_assoc_long(script, "hits", p->nhits);
430             add_next_index_zval(return_value, script);
431             p = p->next;
432         }
433     }
434     return;
435 }
436 /* }}} */
437
438 /* {{{ PHP_FUNCTION(eaccelerator_removed_scripts): Get a list of removed scripts */
439 PHP_FUNCTION(eaccelerator_removed_scripts)
440 {
441     mm_cache_entry *p;
442     zval *script;
443
444     if (!isAdminAllowed(TSRMLS_C)) {
445         zend_error(E_WARNING, NOT_ADMIN_WARNING);
446         RETURN_NULL();
447     }
448
449     MAKE_STD_ZVAL(script);
450     array_init(return_value);
451
452     p = eaccelerator_mm_instance->removed;
453     while (p != NULL) {
454         array_init(script);
455         add_assoc_string(script, "file", p->realfilename, 1);
456         add_assoc_long(script, "mtime", p->mtime);
457         add_assoc_long(script, "size", p->size);
458         add_assoc_long(script, "reloads", p->nreloads);
459         add_assoc_long(script, "usecount", p->use_cnt);
460         add_assoc_long(script, "hits", p->nhits);
461         add_next_index_zval(return_value, script);
462         p = p->next;
463     }
464     return;
465 }
466 /* }}} */
467
468 /* {{{ PHP_FUNCTION(eaccelerator_list_keys): returns list of keys in shared memory that matches actual hostname or namespace */
469 PHP_FUNCTION(eaccelerator_list_keys)
470 {
471         if (eaccelerator_list_keys(return_value TSRMLS_CC)) {
472                 return;
473         } else {
474         RETURN_NULL ();
475         }
476 }
477 /* }}} */
478
479 #endif
480
481 /*
482  * Local variables:
483  * tab-width: 4
484  * c-basic-offset: 4
485  * End:
486  * vim600: noet sw=4 ts=4 fdm=marker
487  * vim<600: noet sw=4 ts=4
488  */
489
Note: See TracBrowser for help on using the browser.