Back to index

avfs  1.0.1
modload.c
Go to the documentation of this file.
00001 /*
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 1998  Miklos Szeredi <miklos@szeredi.hu>
00004 
00005     This program can be distributed under the terms of the GNU GPL.
00006     See the file COPYING.
00007 */
00008 #include "avfs.h"
00009 
00010 #include <dirent.h>
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <dlfcn.h>
00014 
00015 #define MAX_MODULENAME 32
00016 #define MODULEPREFIX "avfs_module_"
00017 #define MODULEPREFIXLEN 12
00018 
00019 struct vmodule {
00020     void *handle;
00021 };
00022 
00023 static void *load_module(const char *modname, const char *moduledir)
00024 {
00025     char *modpath;
00026     void *lib_handle;
00027 
00028     modpath = av_stradd(NULL, moduledir, "/", modname, NULL);
00029 
00030     lib_handle = dlopen(modpath, RTLD_NOW);
00031     if(lib_handle == NULL)
00032         av_log(AVLOG_ERROR, "load_module: %s", dlerror());
00033 
00034     av_free(modpath);
00035   
00036     return lib_handle;
00037 }
00038 
00039 static void delete_module(struct vmodule *module)
00040 {
00041     dlclose(module->handle);
00042 }
00043 
00044 static int init_module(void *lib_handle, const char *initname)
00045 {
00046     int (*initfunc) (struct vmodule *);
00047     struct vmodule *module;
00048     int res;
00049 
00050     initfunc = (int (*)(struct vmodule *)) dlsym(lib_handle, initname);
00051     if(initfunc == NULL) {
00052         av_log(AVLOG_ERROR, "init_module: %s", dlerror());
00053         return -EFAULT;
00054     }
00055 
00056     AV_NEW_OBJ(module, delete_module);
00057     module->handle = lib_handle;
00058 
00059     res = (*initfunc)(module);
00060     av_unref_obj(module);
00061     
00062     return res;
00063 }
00064 
00065 static char *get_modulename(const char *filename)
00066 {
00067     int i;
00068 
00069     if(strncmp(filename, MODULEPREFIX, MODULEPREFIXLEN) != 0)
00070         return NULL;
00071     
00072     filename += MODULEPREFIXLEN;
00073 
00074     for(i = 0; filename[i] && filename[i] != '.'; i++);
00075     if(strcmp(filename + i, ".so") != 0)
00076         return NULL;
00077 
00078     return  av_strndup(filename, i);
00079 }
00080 
00081 static void check_moduledir_entry(const char *moduledir, const char *filename)
00082 {            
00083     int res;
00084     char *modulename;
00085     void *lib_handle;
00086 
00087     modulename = get_modulename(filename);
00088     if(modulename == NULL)
00089         return;
00090 
00091     lib_handle = load_module(filename, moduledir);
00092     if(lib_handle != NULL) {
00093         char *initname;
00094         void *lib_handle = NULL;
00095 
00096         initname = av_stradd(NULL, "av_init_module_", modulename, NULL);
00097         res = init_module(lib_handle, initname);
00098         if(res < 0 && lib_handle != NULL)
00099             dlclose(lib_handle);
00100 
00101         av_free(initname);
00102     }
00103     av_free(modulename);
00104 }
00105 
00106 void av_init_dynamic_modules(void)
00107 {
00108     DIR *dirp;
00109     struct dirent *ent;
00110     char *moduledir;
00111 
00112     moduledir = av_get_config("moduledir");
00113     if(moduledir == NULL)
00114         return;
00115 
00116     dirp = opendir(moduledir);
00117     if(dirp != NULL) {
00118         while((ent = readdir(dirp)) != NULL)
00119             check_moduledir_entry(moduledir, ent->d_name);
00120 
00121         closedir(dirp);
00122     }
00123     av_free(moduledir);
00124 }
00125