00001
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <errno.h>
00022
00023 #include <dlfcn.h>
00024 #include <dirent.h>
00025 #include <sys/stat.h>
00026
00027 #define _LIBRASCH_BUILD
00028 #include <ra_priv.h>
00029 #include <handle_plugin.h>
00030 #include <pl_general.h>
00031
00032
00042 int
00043 read_plugins(struct librasch *ra)
00044 {
00045 DIR *dir;
00046 struct dirent *dir_info;
00047 struct plugin_struct *phead = NULL;
00048 struct plugin_struct *pcurr = phead;
00049 char dir_locale[MAX_PATH_RA];
00050
00051 utf8_to_local(ra->config.plugin_dir, dir_locale, MAX_PATH_RA);
00052
00053 if ((dir = opendir(dir_locale)) == NULL)
00054 return -1;
00055
00056 while ((dir_info = readdir(dir)) != NULL)
00057 {
00058 char path[MAX_PATH_RA];
00059 struct stat s;
00060 struct plugin_struct *pnew;
00061
00062 sprintf(path, "%s%c%s", dir_locale, SEPERATOR, dir_info->d_name);
00063
00064 if (stat(path, &s) == -1)
00065 continue;
00066
00067
00068 if (S_ISDIR(s.st_mode))
00069 continue;
00070
00071
00072 pnew = dload_plugin(path);
00073 if (!pnew)
00074 {
00075 if (ra_print_debug_infos)
00076 fprintf(stderr, gettext("can't load %s: %s\n"), path, dlerror());
00077 continue;
00078 }
00079 pnew->ra = ra;
00080
00081 if (pcurr)
00082 {
00083 pcurr->next = pnew;
00084 pnew->prev = pcurr;
00085 pcurr = pcurr->next;
00086 }
00087 else
00088 phead = pcurr = pnew;
00089 }
00090 closedir(dir);
00091 ra->pl_head = phead;
00092
00093
00094 pcurr = phead;
00095 while (pcurr)
00096 {
00097 struct plugin_struct *p;
00098 int (*init)(struct librasch *, struct plugin_struct *);
00099
00100 init = (int(*)(struct librasch *, struct plugin_struct *))dlsym(pcurr->dl, INIT_PLUGIN_FUNC);
00101 if (!init)
00102 {
00103 if (ra_print_debug_infos)
00104 fprintf(stderr, gettext("error load plugin %s: %s\n"), pcurr->info.name, dlerror());
00105
00106 dlclose(pcurr->dl);
00107 if (pcurr->prev)
00108 pcurr->prev->next = pcurr->next;
00109 p = pcurr;
00110 free(p);
00111 pcurr = pcurr->next;
00112 continue;
00113 }
00114 if ((*init)(ra, pcurr) != 0)
00115 {
00116 if (ra_print_debug_infos)
00117 fprintf(stderr, gettext("error init plugin %s: %s\n"), pcurr->info.name, dlerror());
00118
00119 dlclose(pcurr->dl);
00120 if (pcurr->prev)
00121 pcurr->prev->next = pcurr->next;
00122 p = pcurr;
00123 free(p);
00124 pcurr = pcurr->next;
00125 continue;
00126 }
00127 pcurr = pcurr->next;
00128 }
00129
00130 return 0;
00131 }
00132
00133
00134
00141 struct plugin_struct *
00142 dload_plugin(char *file)
00143 {
00144 int ret = 0;
00145 struct plugin_struct *p;
00146 int (*load) (struct plugin_struct *);
00147
00148 p = malloc(sizeof(*p));
00149 if (!p)
00150 return NULL;
00151 memset(p, 0, sizeof(*p));
00152 p->handle_id = RA_HANDLE_PLUGIN;
00153
00154 p->dl = dlopen(file, RTLD_NOW);
00155 if (!p->dl)
00156 {
00157 if (ra_print_debug_infos)
00158 fprintf(stderr, gettext("dlopen() failed\n"));
00159
00160 free(p);
00161 return NULL;
00162 }
00163
00164 load = (int(*)(struct plugin_struct *))dlsym(p->dl, LOAD_PLUGIN_FUNC);
00165 if (!load)
00166 {
00167 if (ra_print_debug_infos)
00168 fprintf(stderr, gettext("dlsym() failed\n"));
00169
00170 dlclose(p->dl);
00171 free(p);
00172 return NULL;
00173 }
00174 if ((ret = (*load) (p)) != 0)
00175 {
00176 dlclose(p->dl);
00177 free(p);
00178 return NULL;
00179 }
00180
00181 if (!is_plugin_ok(p))
00182 {
00183 dlclose(p->dl);
00184 free(p);
00185 return NULL;
00186 }
00187
00188
00189 strncpy(p->info.file, file, MAX_PATH_RA);
00190 local_to_utf8_inplace(p->info.file, MAX_PATH_RA);
00191
00192 p->info.use_plugin = 1;
00193
00194 return p;
00195 }
00196
00197
00204 int
00205 is_plugin_ok(struct plugin_struct *p)
00206 {
00207
00208 return 1;
00209 }
00210
00211
00219 void
00220 close_plugins(struct plugin_struct *p)
00221 {
00222 struct plugin_struct *next;
00223 void (*close_func) ();
00224
00225 while (p)
00226 {
00227 if (p->info.res)
00228 ra_free_mem(p->info.res);
00229 if (p->info.opt)
00230 ra_free_mem(p->info.opt);
00231
00232 close_func = (void(*)())dlsym(p->dl, FINI_PLUGIN_FUNC);
00233 if (close_func)
00234 (*close_func) ();
00235 dlclose(p->dl);
00236 next = p->next;
00237 free(p);
00238 p = next;
00239 }
00240 }