src/lib/lightmediascanner.c

Go to the documentation of this file.
00001 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #include <dlfcn.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 
00030 #include "lightmediascanner.h"
00031 #include "lightmediascanner_private.h"
00032 #include "lightmediascanner_plugin.h"
00033 
00034 #define DEFAULT_SLAVE_TIMEOUT 1000
00035 #define DEFAULT_COMMIT_INTERVAL 100
00036 
00037 static int
00038 _parser_load(struct parser *p, const char *so_path)
00039 {
00040     lms_plugin_t *(*plugin_open)(void);
00041     char *errmsg;
00042 
00043     memset(p, 0, sizeof(*p));
00044 
00045     p->dl_handle = dlopen(so_path, RTLD_NOW | RTLD_LOCAL);
00046     errmsg = dlerror();
00047     if (errmsg) {
00048         fprintf(stderr, "ERROR: could not dlopen() %s\n", errmsg);
00049         return -1;
00050     }
00051 
00052     plugin_open = dlsym(p->dl_handle, "lms_plugin_open");
00053     errmsg = dlerror();
00054     if (errmsg) {
00055         fprintf(stderr, "ERROR: could not find plugin entry point %s\n",
00056                 errmsg);
00057         return -2;
00058     }
00059 
00060     p->so_path = strdup(so_path);
00061     if (!p->so_path) {
00062         perror("strdup");
00063         return -3;
00064     }
00065 
00066     p->plugin = plugin_open();
00067     if (!p->plugin) {
00068         fprintf(stderr, "ERROR: plugin \"%s\" failed to init.\n", so_path);
00069         return -4;
00070     }
00071 
00072     return 0;
00073 }
00074 
00075 static int
00076 _parser_unload(struct parser *p)
00077 {
00078     int r;
00079 
00080     r = 0;
00081     if (p->plugin) {
00082         if (p->plugin->close(p->plugin) != 0) {
00083             fprintf(stderr, "ERROR: plugin \"%s\" failed to deinit.\n",
00084                     p->so_path);
00085             r -= 1;
00086         }
00087     }
00088 
00089     if (p->dl_handle) {
00090         char *errmsg;
00091 
00092         dlclose(p->dl_handle);
00093         errmsg = dlerror();
00094         if (errmsg) {
00095             fprintf(stderr, "ERROR: could not dlclose() plugin \"%s\": %s\n",
00096                     errmsg, p->so_path);
00097             r -= 1;
00098         }
00099     }
00100 
00101     if (p->so_path)
00102         free(p->so_path);
00103 
00104     return r;
00105 }
00106 
00107 
00108 /***********************************************************************
00109  * Public API.
00110  ***********************************************************************/
00118 lms_t *
00119 lms_new(const char *db_path)
00120 {
00121     lms_t *lms;
00122 
00123     lms = calloc(1, sizeof(lms_t));
00124     if (!lms) {
00125         perror("calloc");
00126         return NULL;
00127     }
00128 
00129     lms->cs_conv = lms_charset_conv_new();
00130     if (!lms->cs_conv) {
00131         free(lms);
00132         return NULL;
00133     }
00134 
00135     lms->commit_interval = DEFAULT_COMMIT_INTERVAL;
00136     lms->slave_timeout = DEFAULT_SLAVE_TIMEOUT;
00137     lms->db_path = strdup(db_path);
00138     if (!lms->db_path) {
00139         perror("strdup");
00140         lms_charset_conv_free(lms->cs_conv);
00141         free(lms);
00142         return NULL;
00143     }
00144 
00145     return lms;
00146 }
00147 
00156 int
00157 lms_free(lms_t *lms)
00158 {
00159     int i;
00160 
00161     if (!lms)
00162         return 0;
00163 
00164     if (lms->is_processing)
00165         return -1;
00166 
00167     if (lms->parsers) {
00168         for (i = 0; i < lms->n_parsers; i++)
00169             _parser_unload(lms->parsers + i);
00170 
00171         free(lms->parsers);
00172     }
00173 
00174     free(lms->db_path);
00175     lms_charset_conv_free(lms->cs_conv);
00176     free(lms);
00177     return 0;
00178 }
00179 
00189 lms_plugin_t *
00190 lms_parser_add(lms_t *lms, const char *so_path)
00191 {
00192     struct parser *parser;
00193 
00194     if (!lms)
00195         return NULL;
00196 
00197     if (!so_path)
00198         return NULL;
00199 
00200     if (lms->is_processing) {
00201         fprintf(stderr, "ERROR: do not add parsers while it's processing.\n");
00202         return NULL;
00203     }
00204 
00205     lms->parsers = realloc(lms->parsers,
00206                            (lms->n_parsers + 1) * sizeof(struct parser));
00207     if (!lms->parsers) {
00208         perror("realloc");
00209         return NULL;
00210     }
00211 
00212     parser = lms->parsers + lms->n_parsers;
00213     if (_parser_load(parser, so_path) != 0) {
00214         _parser_unload(parser);
00215         return NULL;
00216     }
00217 
00218     lms->n_parsers++;
00219     return parser->plugin;
00220 }
00221 
00234 lms_plugin_t *
00235 lms_parser_find_and_add(lms_t *lms, const char *name)
00236 {
00237     char so_path[PATH_MAX];
00238 
00239     if (!lms)
00240         return NULL;
00241     if (!name)
00242         return NULL;
00243 
00244     snprintf(so_path, sizeof(so_path), "%s/%s.so", PLUGINSDIR, name);
00245     return lms_parser_add(lms, so_path);
00246 }
00247 
00248 int
00249 lms_parser_del_int(lms_t *lms, int i)
00250 {
00251     struct parser *parser;
00252 
00253     parser = lms->parsers + i;
00254     _parser_unload(parser);
00255     lms->n_parsers--;
00256 
00257     if (lms->n_parsers == 0) {
00258         free(lms->parsers);
00259         lms->parsers = NULL;
00260         return 0;
00261     } else {
00262         int dif;
00263 
00264         dif = lms->n_parsers - i;
00265         if (dif)
00266             lms->parsers = memmove(parser, parser + 1,
00267                                    dif * sizeof(struct parser));
00268 
00269         lms->parsers = realloc(lms->parsers,
00270                                lms->n_parsers * sizeof(struct parser));
00271         if (!lms->parsers) {
00272             lms->n_parsers = 0;
00273             return -1;
00274         }
00275 
00276         return 0;
00277     }
00278 }
00279 
00288 int
00289 lms_parser_del(lms_t *lms, lms_plugin_t *handle)
00290 {
00291     int i;
00292 
00293     if (!lms)
00294         return -1;
00295     if (!handle)
00296         return -2;
00297     if (!lms->parsers)
00298         return -3;
00299     if (lms->is_processing) {
00300         fprintf(stderr, "ERROR: do not del parsers while it's processing.\n");
00301         return -4;
00302     }
00303 
00304     for (i = 0; i < lms->n_parsers; i++)
00305         if (lms->parsers[i].plugin == handle)
00306             return lms_parser_del_int(lms, i);
00307 
00308     return -3;
00309 }
00310 
00320 int
00321 lms_is_processing(const lms_t *lms)
00322 {
00323     if (!lms) {
00324         fprintf(stderr, "ERROR: lms_is_processing(NULL)\n");
00325         return -1;
00326     }
00327 
00328     return lms->is_processing;
00329 }
00330 
00339 const char *
00340 lms_get_db_path(const lms_t *lms)
00341 {
00342     if (!lms) {
00343         fprintf(stderr, "ERROR: lms_get_db_path(NULL)\n");
00344         return NULL;
00345     }
00346 
00347     return lms->db_path;
00348 }
00349 
00361 int
00362 lms_get_slave_timeout(const lms_t *lms)
00363 {
00364     if (!lms) {
00365         fprintf(stderr, "ERROR: lms_get_slave_timeout(NULL)\n");
00366         return -1;
00367     }
00368 
00369     return lms->slave_timeout;
00370 }
00371 
00382 void lms_set_slave_timeout(lms_t *lms, int ms)
00383 {
00384     if (!lms) {
00385         fprintf(stderr, "ERROR: lms_set_slave_timeout(NULL, %d)\n", ms);
00386         return;
00387     }
00388 
00389     lms->slave_timeout = ms;
00390 }
00391 
00403 unsigned int
00404 lms_get_commit_interval(const lms_t *lms)
00405 {
00406     if (!lms) {
00407         fprintf(stderr, "ERROR: lms_get_commit_interval(NULL)\n");
00408         return (unsigned int)-1;
00409     }
00410 
00411     return lms->commit_interval;
00412 }
00413 
00426 void
00427 lms_set_commit_interval(lms_t *lms, unsigned int transactions)
00428 {
00429     if (!lms) {
00430         fprintf(stderr, "ERROR: lms_set_commit_interval(NULL, %u)\n",
00431                 transactions);
00432         return;
00433     }
00434 
00435     lms->commit_interval = transactions;
00436 }
00437 
00450 int
00451 lms_charset_add(lms_t *lms, const char *charset)
00452 {
00453     if (!lms) {
00454         fprintf(stderr, "ERROR: lms_charset_add(NULL)\n");
00455         return -1;
00456     }
00457 
00458     return lms_charset_conv_add(lms->cs_conv, charset);
00459 }
00460 
00473 int
00474 lms_charset_del(lms_t *lms, const char *charset)
00475 {
00476     if (!lms) {
00477         fprintf(stderr, "ERROR: lms_charset_del(NULL)\n");
00478         return -1;
00479     }
00480 
00481     return lms_charset_conv_del(lms->cs_conv, charset);
00482 }

Generated on Thu Dec 13 02:04:03 2007 for Light Media Scanner by  doxygen 1.5.2