Changeset 180 for trunk/sm/storage.c

Show
Ignore:
Timestamp:
28/04/07 23:56:58 (19 months ago)
Author:
smoku
Message:

Dynamically loading auth/reg/storage modules. Closes #52

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/sm/storage.c

    r156 r180  
    2626  */ 
    2727 
    28 /* these functions implement a multiplexor to get calls to the correct driver 
    29  * for the given type */ 
    30  
    3128#include "sm.h" 
    32  
    3329#include <ctype.h> 
    34  
    35 /* if you add a driver, you'll need to update these arrays */ 
    36 #ifdef STORAGE_DB 
    37 extern st_ret_t st_db_init(st_driver_t); 
    38 #endif 
    39 #ifdef STORAGE_FS 
    40 extern st_ret_t st_fs_init(st_driver_t); 
    41 #endif 
    42 #ifdef STORAGE_MYSQL 
    43 extern st_ret_t st_mysql_init(st_driver_t); 
    44 #endif 
    45 #ifdef STORAGE_PGSQL 
    46 extern st_ret_t st_pgsql_init(st_driver_t); 
    47 #endif 
    48 #ifdef STORAGE_ORACLE 
    49 extern st_ret_t st_oracle_init(st_driver_t); 
    50 #endif 
    51 #ifdef STORAGE_SQLITE 
    52 extern st_ret_t st_sqlite_init(st_driver_t); 
    53 #endif 
    54  
    55 static const char *st_driver_names[] = { 
    56 #ifdef STORAGE_DB 
    57     "db", 
    58 #endif 
    59 #ifdef STORAGE_FS 
    60     "fs", 
    61 #endif 
    62 #ifdef STORAGE_MYSQL 
    63     "mysql", 
    64 #endif 
    65 #ifdef STORAGE_PGSQL 
    66     "pgsql", 
    67 #endif 
    68 #ifdef STORAGE_ORACLE 
    69     "oracle", 
    70 #endif 
    71 #ifdef STORAGE_SQLITE 
    72     "sqlite", 
    73 #endif 
    74     NULL 
    75 }; 
    76  
    77 static st_driver_init_fn st_driver_inits[] = { 
    78 #ifdef STORAGE_DB 
    79     st_db_init, 
    80 #endif 
    81 #ifdef STORAGE_FS 
    82     st_fs_init, 
    83 #endif 
    84 #ifdef STORAGE_MYSQL 
    85     st_mysql_init, 
    86 #endif 
    87 #ifdef STORAGE_PGSQL 
    88     st_pgsql_init, 
    89 #endif 
    90 #ifdef STORAGE_ORACLE 
    91     st_oracle_init, 
    92 #endif 
    93 #ifdef STORAGE_SQLITE 
    94     st_sqlite_init, 
    95 #endif 
    96     NULL 
    97 }; 
     30#include <dlfcn.h> 
    9831 
    9932 
    10033storage_t storage_new(sm_t sm) { 
    10134    storage_t st; 
    102     int i, j; 
     35    int i; 
    10336    config_elem_t elem; 
    10437    char *type; 
     
    11750        for(i = 0; i < elem->nvalues; i++) { 
    11851            type = j_attr((const char **) elem->attrs[i], "type");  
    119             for(j = 0; st_driver_names[j] != NULL; j++) { 
    120                 if(strcmp(elem->values[i], st_driver_names[j]) == 0) { 
    121                     if(type == NULL) 
    122                         ret = storage_add_type(st, st_driver_names[j], NULL); 
    123                     else 
    124                         ret = storage_add_type(st, st_driver_names[j], type); 
    125                     /* Initialisation of storage type failed */ 
    126                     if (ret != st_SUCCESS) { 
    127                       free(st); 
    128                       return NULL; 
    129                     } 
    130                 } 
     52            ret = storage_add_type(st, elem->values[i], type); 
     53            /* Initialisation of storage type failed */ 
     54            if (ret != st_SUCCESS) { 
     55              free(st); 
     56              return NULL; 
    13157            } 
    13258        } 
     
    15581st_ret_t storage_add_type(storage_t st, const char *driver, const char *type) { 
    15682    st_driver_t drv; 
    157     st_driver_init_fn init = NULL; 
     83    st_driver_init_fn init_fn = NULL; 
     84    char mod_fullpath[PATH_MAX], *modules_path; 
    15885    int i; 
    15986    st_ret_t ret; 
     87    void *handle; 
    16088 
    16189    /* startup, see if we've already registered this type */ 
     
    178106    } 
    179107 
     108    /* set modules path */ 
     109    modules_path = config_get_one(st->sm->config, "storage.path", 0); 
     110 
    180111    /* get the driver */ 
    181112    drv = xhash_get(st->drivers, driver); 
     
    183114        log_debug(ZONE, "driver not loaded, trying to init"); 
    184115 
    185         /* find the init function */ 
    186         for(i = 0; st_driver_names[i] != NULL; i++) { 
    187             if(strcmp(driver, st_driver_names[i]) == 0) { 
    188                 init = st_driver_inits[i]; 
    189                 break; 
    190             } 
    191         } 
    192  
    193         /* d'oh */ 
    194         if(init == NULL) { 
    195             log_debug(ZONE, "no init function for driver '%s'", driver); 
    196  
     116        log_write(st->sm->log, LOG_INFO, "loading '%s' storage module", driver); 
     117#ifndef WIN32 
     118        if (modules_path != NULL) 
     119            snprintf(mod_fullpath, PATH_MAX, "%s/storage_%s.so", modules_path, driver); 
     120        else 
     121            snprintf(mod_fullpath, PATH_MAX, "%s/storage_%s.so", LIBRARY_DIR, driver); 
     122        handle = dlopen(mod_fullpath, RTLD_LAZY); 
     123        if (handle != NULL) 
     124            init_fn = dlsym(handle, "st_init"); 
     125#else 
     126        if (modules_path != NULL) 
     127            snprintf(mod_fullpath, PATH_MAX, "%s\\storage_%s.dll", modules_path, driver); 
     128        else 
     129            snprintf(mod_fullpath, PATH_MAX, "storage_%s.dll", driver); 
     130        handle = (void*) LoadLibrary(mod_fullpath); 
     131        if (handle != NULL) 
     132            init_fn = GetProcAddress((HMODULE) handle, "st_init"); 
     133#endif 
     134     
     135        if (handle != NULL && init_fn != NULL) { 
     136            log_debug(ZONE, "preloaded module '%s' (not initialized yet)", driver); 
     137        } else { 
     138#ifndef WIN32 
     139            log_write(st->sm->log, LOG_ERR, "failed loading storage module '%s' (%s)", driver, dlerror()); 
     140            if (handle != NULL) 
     141                dlclose(handle); 
     142#else 
     143            log_write(st->sm->log, LOG_ERR, "failed loading storage module '%s' (errcode: %x)", driver, GetLastError()); 
     144            if (handle != NULL) 
     145                FreeLibrary((HMODULE) handle); 
     146#endif 
    197147            return st_FAILED; 
    198148        } 
     
    207157 
    208158        /* init */ 
    209         if((init)(drv) == st_FAILED) { 
     159        if((init_fn)(drv) == st_FAILED) { 
    210160            log_write(st->sm->log, LOG_NOTICE, "initialisation of storage driver '%s' failed", driver); 
    211161            free(drv);