Changeset 299

Show
Ignore:
Timestamp:
02/15/07 17:04:24 (1 year ago)
Author:
bart
Message:

Kick out the old filter implementation and use one based on fnmatch, this
breaks windows support. The plan is to include a bsd licensed fnmatch
implementation when a platform doesn't provide fnmatch. (read: when windows is
being used). Until some steps up to do this or we run into a machine with
windows and VC windows support wil be b0rked.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • eaccelerator/trunk/ChangeLog

    r298 r299  
    112007-02-15  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
    22 
    3         * Use emalloc for filter lists, mixing memory from two allocators is  
    4           enough. 
     3        * Kick out the old filter implementation and use one based on fnmatch, 
     4          this breaks windows support. The plan is to include a bsd licensed 
     5          fnmatch implementation when a platform doesn't provide fnmatch.  
     6          (read: when windows is being used). Until some steps up to do this  
     7          or we run into a machine with windows and VC windows support wil be  
     8          b0rked. 
    59 
    6102007-02-13  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
  • eaccelerator/trunk/eaccelerator.c

    r298 r299  
    4949#include <sys/types.h> 
    5050#include <sys/stat.h> 
     51#include <fnmatch.h> 
    5152#ifdef ZEND_WIN32 
    5253#  include "win32/time.h" 
     
    894895} 
    895896 
    896 /* 
    897  * Only files matching user specified conditions should be cached. 
    898  * 
    899  * TODO - check the algorithm (fl) 
    900  */ 
    901 static int match(const char* name, const char* pat) { 
    902   char p,k; 
    903   int ok, neg; 
    904    
    905   while (1) { 
    906     p = *pat++; 
    907     if (p == '\0') { 
    908       return (*name == '\0'); 
    909     } else if (p == '*') { 
    910       if (*pat == '\0') { 
    911         return 1; 
    912       } 
    913       do { 
    914         if (match(name, pat)) { 
    915           return 1; 
    916         } 
    917       } while (*name++ != '\0'); 
    918       return 0; 
    919     } else if (p == '?') { 
    920       if (*name++ == '\0') { 
    921         return 0; 
    922       } 
    923     } else if (p == '[') { 
    924       ok = 0; 
    925       if ((k = *name++) == '\0') { 
    926         return 0; 
    927       } 
    928       if ((neg = (*pat == '!')) != '\0') { 
    929         ++pat; 
    930       } 
    931       while ((p = *pat++) != ']') { 
    932         if (*pat == '-') { 
    933           if (p <= k && k <= pat[1]) { 
    934             ok = 1; 
    935           } 
    936           pat += 2; 
    937         } else { 
    938           if (p == '\\') { 
    939             p = *pat++; 
    940             if (p == '\0') { 
    941               p ='\\'; 
    942               pat--; 
    943             } 
    944           } 
    945           if (p == k) { 
    946             ok = 1; 
    947           } 
    948         } 
    949       } 
    950       if (ok == neg) { 
    951         return 0; 
    952       } 
    953     } else { 
    954       if (p == '\\') { 
    955         p = *pat++; 
    956         if (p == '\0') { 
    957           p ='\\'; 
    958           pat--; 
    959         } 
    960       } 
    961       if (*name++ != p) { 
    962         return 0; 
    963       } 
    964     } 
    965   } 
    966   return (*name == '\0'); 
    967 } 
    968  
    969 /* Check if the file is ok to cache */ 
    970 static int eaccelerator_ok_to_cache(char *realname TSRMLS_DC) { 
    971   ea_cond_entry *p; 
    972   int ok; 
    973   if (EAG(cond_list) == NULL) { 
    974     return 1; 
    975   } 
    976  
    977   /* if "realname" matches to any pattern started with "!" then ignore it */ 
    978   for (p = EAG(cond_list); p != NULL; p = p->next) { 
    979     if (p->not && match(realname, p->str)) { 
    980       return 0; 
    981     } 
    982   } 
    983  
    984   /* else if it matches to any pattern not started with "!" then accept it */ 
    985   ok = 1; 
    986   for (p = EAG(cond_list); p != NULL; p = p->next) { 
    987     if (!p->not) { 
    988       ok = 0; 
    989       if (match(realname, p->str)) { 
    990         return 1; 
    991       } 
    992     } 
    993   } 
    994   return ok; 
    995 } 
    996897 
    997898static int eaccelerator_stat(zend_file_handle *file_handle, 
     
    11571058} 
    11581059 
     1060static int ea_match(struct ea_pattern_t *list, const char *path) 
     1061{ 
     1062        struct ea_pattern_t *p; 
     1063        char result, positive; 
     1064 
     1065        // apply all patterns 
     1066        //  - when not patterns are given, *accept* 
     1067        //  - when a pattern with a ! matches, *reject* 
     1068        //  - when no negative pattern matches and a positive pattern match, *accept* 
     1069        //  - when no negative pattern matches and there are no possitive patterns, *accept* 
     1070        //  - *reject* 
     1071 
     1072        if (list == NULL) { 
     1073                // there are no patterns, accept 
     1074                return 1; 
     1075        } 
     1076 
     1077        result = 0; // there are patterns, so if no positive pattern matches, reject 
     1078        positive = 0; 
     1079        p = list; 
     1080        while (p != NULL) { 
     1081                if (p->pattern[0] == '!') { 
     1082                  if ((fnmatch((const char *)(p->pattern + 1), path, 0) == 0)) { 
     1083                                // a negative pattern matches, accept 
     1084                                return 0; 
     1085                        } 
     1086                } else { 
     1087                        result |= (fnmatch((const char *)p->pattern, path, 0) == 0); 
     1088                        positive = 1; 
     1089                } 
     1090                p = p->next; 
     1091        } 
     1092 
     1093  return result | !positive; 
     1094} 
     1095 
    11591096/* 
    11601097 * Intercept compilation of PHP file.  If we already have the file in 
     
    11931130  } 
    11941131 
    1195   ok_to_cache = eaccelerator_ok_to_cache(file_handle->filename TSRMLS_CC); 
     1132  ok_to_cache = ea_match(EAG(pattern_list), file_handle->filename); 
    11961133  
    11971134  // eAccelerator isn't working, so just compile the file 
     
    15211458} 
    15221459 
     1460/*  
     1461 * Parse a list of filters which is seperated by a " " 
     1462 */ 
     1463static struct ea_pattern_t *ea_parse_filter(char *filter) 
     1464{ 
     1465        char *saveptr, *token; 
     1466        struct ea_pattern_t *list_head, *p; 
     1467        size_t len; 
     1468 
     1469        // tokenize the filter string on a space 
     1470        list_head = NULL; 
     1471        p = NULL; 
     1472        while ((token = strtok_r(filter, " ", &saveptr)) != NULL) { 
     1473                filter = NULL; 
     1474                list_head = malloc(sizeof(struct ea_pattern_t)); 
     1475                memset(list_head, 0, sizeof(struct ea_pattern_t)); 
     1476 
     1477                len = strlen(token); 
     1478                list_head->pattern = malloc(len + 1); 
     1479                strncpy(list_head->pattern, token, len + 1);  
     1480                list_head->next = p; 
     1481                p = list_head; 
     1482        } 
     1483 
     1484        return list_head; 
     1485} 
     1486 
    15231487/******************************************************************************/ 
    15241488/* 
     
    15291493 */ 
    15301494PHP_INI_MH(eaccelerator_filter) { 
    1531   ea_cond_entry *p, *q; 
    1532   char *s = new_value; 
    1533   char *ss; 
    1534   int  not; 
    1535   for (p = EAG(cond_list); p != NULL; p = q) { 
    1536     q = p->next; 
    1537     if (p->str) { 
    1538       efree(p->str); 
    1539     } 
    1540     efree(p); 
    1541   } 
    1542   EAG(cond_list) = NULL; 
    1543   while (*s) { 
    1544     for (; *s == ' ' || *s == '\t'; s++) 
    1545       ; 
    1546     if (*s == 0) 
    1547       break; 
    1548     if (*s == '!') { 
    1549       s++; 
    1550       not = 1; 
    1551     } else { 
    1552       not = 0; 
    1553     } 
    1554     ss = s; 
    1555     for (; *s && *s != ' ' && *s != '\t'; s++) 
    1556       ; 
    1557     if ((s > ss) && *ss) { 
    1558       p = (ea_cond_entry *)emalloc(sizeof(ea_cond_entry)); 
    1559       if (p == NULL) 
    1560         break; 
    1561       p->not = not; 
    1562       p->len = s-ss; 
    1563       p->str = emalloc(p->len+1); 
    1564       memcpy(p->str, ss, p->len); 
    1565       p->str[p->len] = 0; 
    1566       p->next = EAG(cond_list); 
    1567       EAG(cond_list) = p; 
    1568     } 
    1569   } 
     1495  EAG(pattern_list) = ea_parse_filter(new_value); 
    15701496  return SUCCESS; 
    15711497} 
     
    17741700#endif 
    17751701 
    1776 static void eaccelerator_init_globals(zend_eaccelerator_globals *eaccelerator_globals
     1702static void eaccelerator_init_globals(zend_eaccelerator_globals *eag
    17771703{ 
    1778   eaccelerator_globals->used_entries      = NULL; 
    1779   eaccelerator_globals->enabled           = 1; 
    1780   eaccelerator_globals->cache_dir         = NULL; 
    1781   eaccelerator_globals->optimizer_enabled = 1; 
    1782   eaccelerator_globals->compiler          = 0; 
    1783   eaccelerator_globals->cond_list         = NULL; 
    1784   eaccelerator_globals->content_headers   = NULL; 
     1704        eag->used_entries = NULL; 
     1705        eag->enabled = 1; 
     1706        eag->cache_dir = NULL; 
     1707        eag->optimizer_enabled = 1; 
     1708        eag->compiler = 0; 
     1709        eag->content_headers = NULL; 
    17851710#ifdef WITH_EACCELERATOR_SESSIONS 
    1786   eaccelerator_globals->session           = NULL; 
    1787 #endif 
    1788   eaccelerator_globals->eaccelerator_log_file = '\000'; 
    1789   eaccelerator_globals->name_space        = '\000'; 
    1790   eaccelerator_globals->hostname[0]       = '\000'; 
    1791   eaccelerator_globals->in_request        = 0; 
    1792   eaccelerator_globals->allowed_admin_path= NULL; 
    1793 
    1794  
    1795 static void eaccelerator_globals_dtor(zend_eaccelerator_globals *eaccelerator_globals) 
     1711        eag->session = NULL; 
     1712#endif 
     1713        eag->eaccelerator_log_file = '\000'; 
     1714        eag->name_space = '\000'; 
     1715        eag->hostname[0] = '\000'; 
     1716        eag->in_request = 0; 
     1717        eag->allowed_admin_path= NULL; 
     1718        eag->pattern_list = NULL; 
     1719
     1720 
     1721static void eaccelerator_globals_dtor(zend_eaccelerator_globals *eag) 
    17961722{ 
    1797   ea_cond_entry *p, *q; 
    1798  
    1799   for (p = eaccelerator_globals->cond_list; p != NULL; p = q) { 
    1800     q = p->next; 
    1801     if (p->str) { 
    1802       efree(p->str); 
    1803     } 
    1804     efree(p); 
    1805   } 
    1806   eaccelerator_globals->cond_list = NULL; 
     1723        struct ea_pattern_t *p, *q; 
     1724 
     1725        /* free the list of patterns */ 
     1726        p = eag->pattern_list; 
     1727        while (p != NULL) { 
     1728                q = p; 
     1729                free(p->pattern); 
     1730                free(p); 
     1731                p = q->next; 
     1732        } 
     1733        eag->pattern_list = NULL; 
    18071734} 
    18081735 
  • eaccelerator/trunk/eaccelerator.h

    r286 r299  
    428428#endif 
    429429 
    430 /* 
    431  * conditional filter 
    432  */ 
    433 typedef struct _ea_cond_entry { 
    434         char *str; 
    435         int len; 
    436         zend_bool not; 
    437         struct _ea_cond_entry *next; 
    438 } ea_cond_entry; 
     430struct ea_pattern_t { 
     431  struct ea_pattern_t *next; 
     432  char *pattern; 
     433}; 
    439434 
    440435/* 
     
    461456HashTable restored; 
    462457zend_class_entry *class_entry; 
    463 ea_cond_entry *cond_list; 
    464458zend_uint refcount_helper; 
    465459char hostname[32]; 
     460struct ea_pattern_t *pattern_list; 
    466461#ifdef WITH_EACCELERATOR_CRASH_DETECTION 
    467462#ifdef SIGSEGV