Ignore:
Timestamp:
11/11/11 13:17:43 (20 months ago)
Author:
BrainSlayer
Message:

update proftp

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/router/proftpd/src/modules.c

    r14672 r17876  
    22 * ProFTPD - FTP server daemon 
    33 * Copyright (c) 1997, 1998 Public Flood Software 
    4  * Copyright (c) 2001-2008 The ProFTPD Project team 
     4 * Copyright (c) 2001-2010 The ProFTPD Project team 
    55 * 
    66 * This program is free software; you can redistribute it and/or modify 
     
    1616 * You should have received a copy of the GNU General Public License 
    1717 * along with this program; if not, write to the Free Software 
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA. 
     18 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. 
    1919 * 
    2020 * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu 
     
    2424 */ 
    2525 
    26 /* 
    27  * Module handling routines 
    28  * $Id: modules.c,v 1.58 2010/02/14 00:19:06 castaglia Exp $ 
     26/* Module handling routines 
     27 * $Id: modules.c,v 1.62 2011/05/23 21:22:24 castaglia Exp $ 
    2928 */ 
    3029 
    3130#include "conf.h" 
    32  
    33 /* This local structure vastly speeds up symbol lookups. */ 
    34 struct stash { 
    35   struct stash *next,*prev; 
    36   pool *sym_pool; 
    37   const char *sym_name; 
    38   pr_stash_type_t sym_type; 
    39   module *sym_module; 
    40  
    41   union { 
    42     conftable *sym_conf; 
    43     cmdtable *sym_cmd; 
    44     authtable *sym_auth; 
    45     cmdtable *sym_hook; 
    46     void *sym_generic; 
    47   } ptr; 
    48 }; 
    4931 
    5032extern module *static_modules[]; 
    5133extern module *loaded_modules; 
    5234 
    53 /* Symbol hashes for each type */ 
    54 static xaset_t *symbol_table[PR_TUNABLE_HASH_TABLE_SIZE]; 
    55 static pool *symbol_pool = NULL; 
    56 static struct stash *curr_sym = NULL; 
    57  
    5835/* Currently running module */ 
    5936module *curr_module = NULL; 
    60  
     37   
    6138/* Used to track the priority for loaded modules. */ 
    6239static unsigned int curr_module_pri = 0; 
    63  
    64 typedef struct mod_cb { 
    65   struct mod_cb *next, *prev; 
    66  
    67   int (*module_cb)(void); 
    68 } module_cb_t; 
    69  
    70 /* Symbol stash lookup code and management */ 
    71  
    72 static struct stash *sym_alloc(void) { 
    73   pool *sub_pool; 
    74   struct stash *sym; 
    75  
    76   /* XXX Use a smaller pool size, since there are lots of sub-pools allocated 
    77    * for Stash symbols.  The default pool size (PR_TUNABLE_POOL_SIZE, 512 
    78    * by default) is a bit large for symbols. 
    79    */ 
    80   sub_pool = pr_pool_create_sz(symbol_pool, 128); 
    81  
    82   sym = pcalloc(sub_pool, sizeof(struct stash)); 
    83   sym->sym_pool = sub_pool;  
    84   pr_pool_tag(sub_pool, "symbol"); 
    85  
    86   return sym; 
    87 } 
    88  
    89 static int sym_cmp(struct stash *s1, struct stash *s2) { 
    90   int res; 
    91  
    92   res = strcmp(s1->sym_name, s2->sym_name); 
    93  
    94   /* Higher priority modules must go BEFORE lower priority in the 
    95    * hash tables. 
    96    */ 
    97  
    98   if (res == 0) { 
    99     if (s1->sym_module != NULL && 
    100         s2->sym_module != NULL) { 
    101  
    102       if (s1->sym_module->priority > s2->sym_module->priority) { 
    103         return -1; 
    104       } 
    105      
    106       if (s1->sym_module->priority < s2->sym_module->priority) { 
    107         return 1; 
    108       } 
    109  
    110       return res; 
    111     } 
    112  
    113     if (s1->sym_module != NULL && 
    114         s2->sym_module == NULL) { 
    115       return -1; 
    116     } 
    117  
    118     if (s1->sym_module == NULL && 
    119         s2->sym_module != NULL) { 
    120       return 1; 
    121     } 
    122  
    123     /* Both sym_module fields are null. */ 
    124     return 0; 
    125   } 
    126  
    127   return res; 
    128 } 
    129  
    130 static int symtab_hash(const char *name) { 
    131   unsigned char *cp = NULL; 
    132   int total = 0; 
    133  
    134   if (!name) 
    135     return 0; 
    136  
    137   for (cp = (unsigned char *)name; *cp; cp++) 
    138     total += (int)*cp; 
    139  
    140   return (total < PR_TUNABLE_HASH_TABLE_SIZE ? total : 
    141     (total % PR_TUNABLE_HASH_TABLE_SIZE)); 
    142 } 
    143  
    144 int pr_stash_add_symbol(pr_stash_type_t sym_type, void *data) { 
    145   struct stash *sym = NULL; 
    146   int idx = 0; 
    147  
    148   if (!data) { 
    149     errno = EINVAL; 
    150     return -1; 
    151   } 
    152  
    153   switch (sym_type) { 
    154     case PR_SYM_CONF: 
    155       sym = sym_alloc(); 
    156       sym->sym_type = PR_SYM_CONF; 
    157       sym->sym_name = ((conftable *) data)->directive; 
    158       sym->sym_module = ((conftable *) data)->m; 
    159       sym->ptr.sym_conf = data; 
    160       break; 
    161  
    162     case PR_SYM_CMD: 
    163       sym = sym_alloc(); 
    164       sym->sym_type = PR_SYM_CMD; 
    165       sym->sym_name = ((cmdtable *) data)->command; 
    166       sym->sym_module = ((cmdtable *) data)->m; 
    167       sym->ptr.sym_cmd = data; 
    168       break; 
    169  
    170     case PR_SYM_AUTH: 
    171       sym = sym_alloc(); 
    172       sym->sym_type = PR_SYM_AUTH; 
    173       sym->sym_name = ((authtable *) data)->name; 
    174       sym->sym_module = ((authtable *) data)->m; 
    175       sym->ptr.sym_auth = data; 
    176       break; 
    177  
    178     case PR_SYM_HOOK: 
    179       sym = sym_alloc(); 
    180       sym->sym_type = PR_SYM_HOOK; 
    181       sym->sym_name = ((cmdtable *) data)->command; 
    182       sym->sym_module = ((cmdtable *) data)->m; 
    183       sym->ptr.sym_hook = data; 
    184       break; 
    185  
    186     default: 
    187       errno = ENOENT; 
    188       return -1; 
    189   } 
    190  
    191   /* XXX Should we check for null sym->sym_module as well? */ 
    192   if (sym->sym_name == NULL) { 
    193     destroy_pool(sym->sym_pool); 
    194     errno = EPERM; 
    195     return -1; 
    196   } 
    197  
    198   /* XXX Ugly hack to support mixed cases of directives in config files. */ 
    199   if (sym_type != PR_SYM_CONF) { 
    200     idx = symtab_hash(sym->sym_name); 
    201  
    202   } else { 
    203     register unsigned int i; 
    204     char buf[1024]; 
    205  
    206     memset(buf, '\0', sizeof(buf)); 
    207     sstrncpy(buf, sym->sym_name, sizeof(buf)-1); 
    208  
    209     for (i = 0; i < strlen(buf); i++) 
    210       buf[i] = tolower((int) buf[i]); 
    211  
    212     idx = symtab_hash(buf); 
    213   } 
    214  
    215   if (!symbol_table[idx]) { 
    216     symbol_table[idx] = xaset_create(symbol_pool, (XASET_COMPARE) sym_cmp); 
    217   } 
    218  
    219   xaset_insert_sort(symbol_table[idx], (xasetmember_t *) sym, TRUE); 
    220   return 0; 
    221 } 
    222  
    223 static struct stash *stash_lookup(pr_stash_type_t sym_type, 
    224     const char *name, int idx) { 
    225   struct stash *sym = NULL; 
    226  
    227   if (symbol_table[idx]) { 
    228     for (sym = (struct stash *) symbol_table[idx]->xas_list; sym; 
    229         sym = sym->next) 
    230       if (sym->sym_type == sym_type && 
    231           (!name || strcasecmp(sym->sym_name, name) == 0)) 
    232         break; 
    233   } 
    234  
    235   return sym; 
    236 } 
    237  
    238 static struct stash *stash_lookup_next(pr_stash_type_t sym_type, 
    239     const char *name, int idx, void *prev) { 
    240   struct stash *sym = NULL; 
    241   int last_hit = 0; 
    242  
    243   if (symbol_table[idx]) { 
    244     for (sym = (struct stash *) symbol_table[idx]->xas_list; sym; 
    245         sym = sym->next) { 
    246       if (last_hit && sym->sym_type == sym_type && 
    247           (!name || strcasecmp(sym->sym_name, name) == 0)) 
    248         break; 
    249       if (sym->ptr.sym_generic == prev) 
    250         last_hit++; 
    251     } 
    252   } 
    253  
    254   return sym; 
    255 } 
    256  
    257 void *pr_stash_get_symbol(pr_stash_type_t sym_type, const char *name, 
    258     void *prev, int *idx_cache) { 
    259   int idx; 
    260   struct stash *sym = NULL; 
    261  
    262   if (idx_cache && 
    263       *idx_cache != -1) { 
    264     idx = *idx_cache; 
    265  
    266   } else { 
    267  
    268     /* XXX Ugly hack to support mixed cases of directives in config files. */ 
    269     if (sym_type != PR_SYM_CONF) { 
    270       idx = symtab_hash(name); 
    271  
    272     } else { 
    273       register unsigned int i; 
    274       char buf[1024]; 
    275  
    276       memset(buf, '\0', sizeof(buf)); 
    277       sstrncpy(buf, name, sizeof(buf)-1); 
    278  
    279       for (i = 0; i < strlen(buf); i++) 
    280         buf[i] = tolower((int) buf[i]); 
    281  
    282       idx = symtab_hash(buf); 
    283     } 
    284  
    285     if (idx_cache) 
    286       *idx_cache = idx; 
    287   } 
    288  
    289   if (idx >= PR_TUNABLE_HASH_TABLE_SIZE) { 
    290     if (*idx_cache) 
    291       *idx_cache = -1; 
    292  
    293     errno = EINVAL; 
    294     return NULL; 
    295   } 
    296  
    297   if (prev) 
    298     curr_sym = sym = stash_lookup_next(sym_type, name, idx, prev); 
    299   else 
    300     curr_sym = sym = stash_lookup(sym_type, name, idx); 
    301  
    302   switch (sym_type) { 
    303     case PR_SYM_CONF: 
    304       if (sym) { 
    305         return sym->ptr.sym_conf; 
    306       } 
    307  
    308       errno = ENOENT; 
    309       return NULL; 
    310  
    311     case PR_SYM_CMD: 
    312       if (sym) { 
    313         return sym->ptr.sym_cmd; 
    314       } 
    315  
    316       errno = ENOENT; 
    317       return NULL; 
    318  
    319     case PR_SYM_AUTH: 
    320       if (sym) { 
    321         return sym->ptr.sym_auth; 
    322       } 
    323  
    324       errno = ENOENT; 
    325       return NULL; 
    326  
    327     case PR_SYM_HOOK: 
    328       if (sym) { 
    329         return sym->ptr.sym_hook; 
    330       } 
    331  
    332       errno = ENOENT; 
    333       return NULL; 
    334   } 
    335  
    336   errno = EINVAL; 
    337   return NULL; 
    338 } 
    339  
    340 int pr_stash_remove_symbol(pr_stash_type_t sym_type, const char *sym_name, 
    341     module *sym_module) { 
    342   int count = 0, symtab_idx = 0; 
    343  
    344   if (!sym_name) { 
    345     errno = EINVAL; 
    346     return -1; 
    347   } 
    348  
    349   /* XXX Ugly hack to support mixed cases of directives in config files. */ 
    350   if (sym_type != PR_SYM_CONF) { 
    351     symtab_idx = symtab_hash(sym_name); 
    352  
    353   } else { 
    354     register unsigned int i; 
    355     char buf[1024]; 
    356  
    357     memset(buf, '\0', sizeof(buf)); 
    358     sstrncpy(buf, sym_name, sizeof(buf)-1); 
    359  
    360     for (i = 0; i < strlen(buf); i++) 
    361       buf[i] = tolower((int) buf[i]); 
    362  
    363     symtab_idx = symtab_hash(buf); 
    364   } 
    365  
    366   switch (sym_type) { 
    367     case PR_SYM_CONF: { 
    368       int idx = -1; 
    369       conftable *tab; 
    370  
    371       tab = pr_stash_get_symbol(PR_SYM_CONF, sym_name, NULL, &idx); 
    372  
    373       while (tab) { 
    374         pr_signals_handle(); 
    375  
    376         /* Note: this works because of a hack: the symbol lookup functions 
    377          * set a static pointer, curr_sym, to point to the struct stash 
    378          * just looked up.  curr_sym will not be NULL if pr_stash_get_symbol() 
    379          * returns non-NULL. 
    380          */ 
    381  
    382         if (!sym_module || 
    383             curr_sym->sym_module == sym_module) { 
    384           xaset_remove(symbol_table[symtab_idx], (xasetmember_t *) curr_sym); 
    385           destroy_pool(curr_sym->sym_pool); 
    386           curr_sym = NULL; 
    387           tab = NULL; 
    388           count++; 
    389         } 
    390  
    391         tab = pr_stash_get_symbol(PR_SYM_CONF, sym_name, tab, &idx); 
    392       } 
    393  
    394       break; 
    395     } 
    396  
    397     case PR_SYM_CMD: { 
    398       int idx = -1; 
    399       cmdtable *tab; 
    400  
    401       tab = pr_stash_get_symbol(PR_SYM_CMD, sym_name, NULL, &idx); 
    402  
    403       while (tab) { 
    404         pr_signals_handle(); 
    405  
    406         /* Note: this works because of a hack: the symbol lookup functions 
    407          * set a static pointer, curr_sym, to point to the struct stash 
    408          * just looked up.   
    409          */ 
    410  
    411         if (!sym_module || 
    412             curr_sym->sym_module == sym_module) { 
    413           xaset_remove(symbol_table[symtab_idx], (xasetmember_t *) curr_sym); 
    414           destroy_pool(curr_sym->sym_pool); 
    415           tab = NULL; 
    416           count++; 
    417         } 
    418  
    419         tab = pr_stash_get_symbol(PR_SYM_CMD, sym_name, tab, &idx); 
    420       } 
    421  
    422       break; 
    423     } 
    424  
    425     case PR_SYM_AUTH: { 
    426       int idx = -1; 
    427       authtable *tab; 
    428  
    429       tab = pr_stash_get_symbol(PR_SYM_AUTH, sym_name, NULL, &idx); 
    430  
    431       while (tab) { 
    432         pr_signals_handle(); 
    433  
    434         /* Note: this works because of a hack: the symbol lookup functions 
    435          * set a static pointer, curr_sym, to point to the struct stash 
    436          * just looked up.   
    437          */ 
    438  
    439         if (!sym_module || 
    440             curr_sym->sym_module == sym_module) { 
    441           xaset_remove(symbol_table[symtab_idx], (xasetmember_t *) curr_sym); 
    442           destroy_pool(curr_sym->sym_pool); 
    443           tab = NULL; 
    444           count++; 
    445         } 
    446  
    447         tab = pr_stash_get_symbol(PR_SYM_AUTH, sym_name, tab, &idx); 
    448       } 
    449  
    450       break; 
    451     } 
    452  
    453     case PR_SYM_HOOK: { 
    454       int idx = -1; 
    455       cmdtable *tab; 
    456  
    457       tab = pr_stash_get_symbol(PR_SYM_HOOK, sym_name, NULL, &idx); 
    458  
    459       while (tab) { 
    460         pr_signals_handle(); 
    461  
    462         if (!sym_module || 
    463             curr_sym->sym_module == sym_module) { 
    464           xaset_remove(symbol_table[symtab_idx], (xasetmember_t *) curr_sym); 
    465           destroy_pool(curr_sym->sym_pool); 
    466           tab = NULL; 
    467           count++; 
    468         } 
    469  
    470         tab = pr_stash_get_symbol(PR_SYM_HOOK, sym_name, tab, &idx); 
    471       } 
    472  
    473       break; 
    474     } 
    475  
    476     default: 
    477       errno = EINVAL; 
    478       return -1; 
    479   } 
    480  
    481   return count; 
    482 } 
    483  
     40   
    48441modret_t *pr_module_call(module *m, modret_t *(*func)(cmd_rec *), 
    48542    cmd_rec *cmd) { 
     
    817374  } 
    818375 
     376  /* Remove any callbacks that the module may have registered, i.e.: 
     377   * 
     378   * ctrls 
     379   * events 
     380   * timers 
     381   * 
     382   * Ideally we would also automatically unregister other callbacks that 
     383   * the module may have registered, such as FSIO, NetIO, variables, and 
     384   * response handlers.  However, these APIs do not yet allow for 
     385   * removal of all callbacks for a given module. 
     386   */ 
     387 
     388#ifdef PR_USE_CTRLS 
     389  pr_ctrls_unregister(m, NULL); 
     390#endif /* PR_USE_CTRLS */ 
     391  pr_event_unregister(m, NULL, NULL); 
     392  pr_timer_remove(-1, m); 
     393 
    819394  return 0; 
    820395} 
     
    835410  return 0; 
    836411} 
    837  
    838 int init_stash(void) { 
    839   if (symbol_pool) 
    840     destroy_pool(symbol_pool); 
    841  
    842   symbol_pool = make_sub_pool(permanent_pool);  
    843   pr_pool_tag(symbol_pool, "Stash Pool"); 
    844   memset(symbol_table, '\0', sizeof(symbol_table)); 
    845  
    846   return 0; 
    847 } 
Note: See TracChangeset for help on using the changeset viewer.