2 * Copyright (C) 2007 by INdT
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 * @author Gustavo Sverzut Barbieri <gustavo.barbieri@openbossa.org>
30 #include "lightmediascanner.h"
31 #include "lightmediascanner_private.h"
32 #include "lightmediascanner_plugin.h"
34 #define DEFAULT_SLAVE_TIMEOUT 1000
35 #define DEFAULT_COMMIT_INTERVAL 100
38 _parser_load(struct parser *p, const char *so_path)
40 lms_plugin_t *(*plugin_open)(void);
43 memset(p, 0, sizeof(*p));
45 p->dl_handle = dlopen(so_path, RTLD_NOW | RTLD_LOCAL);
48 fprintf(stderr, "ERROR: could not dlopen() %s\n", errmsg);
52 plugin_open = dlsym(p->dl_handle, "lms_plugin_open");
55 fprintf(stderr, "ERROR: could not find plugin entry point %s\n",
60 p->so_path = strdup(so_path);
66 p->plugin = plugin_open();
68 fprintf(stderr, "ERROR: plugin \"%s\" failed to init.\n", so_path);
76 _parser_unload(struct parser *p)
82 if (p->plugin->close(p->plugin) != 0) {
83 fprintf(stderr, "ERROR: plugin \"%s\" failed to deinit.\n",
92 dlclose(p->dl_handle);
95 fprintf(stderr, "ERROR: could not dlclose() plugin \"%s\": %s\n",
108 /***********************************************************************
110 ***********************************************************************/
112 * Create new Light Media Scanner instance.
114 * @param db_path path to database file.
115 * @return allocated data on success or NULL on failure.
119 lms_new(const char *db_path)
123 lms = calloc(1, sizeof(lms_t));
129 lms->cs_conv = lms_charset_conv_new();
135 lms->commit_interval = DEFAULT_COMMIT_INTERVAL;
136 lms->slave_timeout = DEFAULT_SLAVE_TIMEOUT;
137 lms->db_path = strdup(db_path);
140 lms_charset_conv_free(lms->cs_conv);
149 * Free existing Light Media Scanner instance.
151 * @param lms previously allocated Light Media Scanner instance.
153 * @return On success 0 is returned.
164 if (lms->is_processing)
168 for (i = 0; i < lms->n_parsers; i++)
169 _parser_unload(lms->parsers + i);
175 lms_charset_conv_free(lms->cs_conv);
181 * Add parser plugin given it's shared object path.
183 * @param lms previously allocated Light Media Scanner instance.
184 * @param so_path path to shared object (usable by dlopen(3)).
186 * @return On success the LMS handle to plugin is returned, NULL on error.
190 lms_parser_add(lms_t *lms, const char *so_path)
192 struct parser *parser;
200 if (lms->is_processing) {
201 fprintf(stderr, "ERROR: do not add parsers while it's processing.\n");
205 lms->parsers = realloc(lms->parsers,
206 (lms->n_parsers + 1) * sizeof(struct parser));
212 parser = lms->parsers + lms->n_parsers;
213 if (_parser_load(parser, so_path) != 0) {
214 _parser_unload(parser);
219 return parser->plugin;
223 * Add parser plugin given it's name.
225 * This will look at default plugin path by the file named @p name (plus
226 * the required shared object extension).
228 * @param lms previously allocated Light Media Scanner instance.
229 * @param name plugin name.
231 * @return On success the LMS handle to plugin is returned, NULL on error.
235 lms_parser_find_and_add(lms_t *lms, const char *name)
237 char so_path[PATH_MAX];
244 snprintf(so_path, sizeof(so_path), "%s/%s.so", PLUGINSDIR, name);
245 return lms_parser_add(lms, so_path);
249 lms_parser_del_int(lms_t *lms, int i)
251 struct parser *parser;
253 parser = lms->parsers + i;
254 _parser_unload(parser);
257 if (lms->n_parsers == 0) {
264 dif = lms->n_parsers - i;
266 lms->parsers = memmove(parser, parser + 1,
267 dif * sizeof(struct parser));
269 lms->parsers = realloc(lms->parsers,
270 lms->n_parsers * sizeof(struct parser));
281 * Delete previously added parser, making it unavailable for future operations.
283 * @param lms previously allocated Light Media Scanner instance.
285 * @return On success 0 is returned.
289 lms_parser_del(lms_t *lms, lms_plugin_t *handle)
299 if (lms->is_processing) {
300 fprintf(stderr, "ERROR: do not del parsers while it's processing.\n");
304 for (i = 0; i < lms->n_parsers; i++)
305 if (lms->parsers[i].plugin == handle)
306 return lms_parser_del_int(lms, i);
312 * Checks if Light Media Scanner is being used in a processing operation lile
313 * lms_process() or lms_check().
315 * @param lms previously allocated Light Media Scanner instance.
317 * @return 1 if it is processing, 0 if it's not, -1 on error.
321 lms_is_processing(const lms_t *lms)
324 fprintf(stderr, "ERROR: lms_is_processing(NULL)\n");
328 return lms->is_processing;
332 * Get the database path given at creation time.
334 * @param lms previously allocated Light Media Scanner instance.
336 * @return path to database.
340 lms_get_db_path(const lms_t *lms)
343 fprintf(stderr, "ERROR: lms_get_db_path(NULL)\n");
351 * Get the maximum amount of milliseconds the slave can take to serve one file.
353 * If a slave takes more than this amount of milliseconds, it will be killed
354 * and the scanner will continue with the next file.
356 * @param lms previously allocated Light Media Scanner instance.
358 * @return -1 on error or time in milliseconds otherwise.
362 lms_get_slave_timeout(const lms_t *lms)
365 fprintf(stderr, "ERROR: lms_get_slave_timeout(NULL)\n");
369 return lms->slave_timeout;
373 * Set the maximum amount of milliseconds the slave can take to serve one file.
375 * If a slave takes more than this amount of milliseconds, it will be killed
376 * and the scanner will continue with the next file.
378 * @param lms previously allocated Light Media Scanner instance.
379 * @param ms time in milliseconds.
382 void lms_set_slave_timeout(lms_t *lms, int ms)
385 fprintf(stderr, "ERROR: lms_set_slave_timeout(NULL, %d)\n", ms);
389 lms->slave_timeout = ms;
393 * Get the number of files served between database transactions.
395 * This is used as an optimization to database access: doing database commits
396 * take some time and can slow things down too much, so you can choose to just
397 * commit after some number of files are processed, this is the commit_interval.
399 * @param lms previously allocated Light Media Scanner instance.
400 * @return (unsigned int)-1 on error, value otherwise.
404 lms_get_commit_interval(const lms_t *lms)
407 fprintf(stderr, "ERROR: lms_get_commit_interval(NULL)\n");
408 return (unsigned int)-1;
411 return lms->commit_interval;
415 * Set the number of files served between database transactions.
417 * This is used as an optimization to database access: doing database commits
418 * take some time and can slow things down too much, so you can choose to just
419 * commit after @p transactions files are processed.
421 * @param lms previously allocated Light Media Scanner instance.
422 * @param transactions number of files (transactions) to process between
427 lms_set_commit_interval(lms_t *lms, unsigned int transactions)
430 fprintf(stderr, "ERROR: lms_set_commit_interval(NULL, %u)\n",
435 lms->commit_interval = transactions;
439 * Register a new charset encoding to be used.
441 * All database text strings are in UTF-8, so one needs to register new
442 * encodings in order to convert to it.
444 * @param lms previously allocated Light Media Scanner instance.
445 * @param charset charset name as understood by iconv_open(3).
447 * @return On success 0 is returned.
451 lms_charset_add(lms_t *lms, const char *charset)
454 fprintf(stderr, "ERROR: lms_charset_add(NULL)\n");
458 return lms_charset_conv_add(lms->cs_conv, charset);
462 * Forget about registered charset encoding.
464 * All database text strings are in UTF-8, so one needs to register new
465 * encodings in order to convert to it.
467 * @param lms previously allocated Light Media Scanner instance.
468 * @param charset charset name as understood by iconv_open(3).
470 * @return On success 0 is returned.
474 lms_charset_del(lms_t *lms, const char *charset)
477 fprintf(stderr, "ERROR: lms_charset_del(NULL)\n");
481 return lms_charset_conv_del(lms->cs_conv, charset);