X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=recctrl%2Frecctrl.c;h=e1d949b53d55df54f2cef3f9ba402eb3a9500b95;hb=6dfee19bc1cec29ff5ec5e9cd8021d1354a6126e;hp=cd4359b4b39fd59755b08b4aa550a991a10ba7da;hpb=75049be3951292bbbbd53d83ca38ccbd191e4b08;p=idzebra-moved-to-github.git diff --git a/recctrl/recctrl.c b/recctrl/recctrl.c index cd4359b..e1d949b 100644 --- a/recctrl/recctrl.c +++ b/recctrl/recctrl.c @@ -1,115 +1,287 @@ -/* - * Copyright (C) 1994-1998, Index Data - * All rights reserved. - * Sebastian Hammer, Adam Dickmeiss - * - * $Log: recctrl.c,v $ - * Revision 1.3 1998-10-16 08:14:36 adam - * Updated record control system. - * - * Revision 1.2 1996/10/29 14:03:16 adam - * Include zebrautl.h instead of alexutil.h. - * - * Revision 1.1 1996/10/11 10:57:24 adam - * New module recctrl. Used to manage records (extract/retrieval). - * - * Revision 1.5 1996/06/04 10:18:59 adam - * Minor changes - removed include of ctype.h. - * - * Revision 1.4 1995/12/04 17:59:24 adam - * More work on regular expression conversion. - * - * Revision 1.3 1995/12/04 14:22:30 adam - * Extra arg to recType_byName. - * Started work on new regular expression parsed input to - * structured records. - * - * Revision 1.2 1995/11/15 14:46:19 adam - * Started work on better record management system. - * - * Revision 1.1 1995/09/27 12:22:28 adam - * More work on extract in record control. - * Field name is not in isam keys but in prefix in dictionary words. - * - */ +/* $Id: recctrl.c,v 1.22 2005-12-05 12:18:41 marc Exp $ + Copyright (C) 1995-2005 + Index Data ApS + +This file is part of the Zebra server. + +Zebra is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +Zebra is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Zebra; see the file LICENSE.zebra. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. +*/ + + #include #include #include +#if HAVE_DLFCN_H +#include +#endif -#include -#include "rectext.h" -#include "recgrs.h" +#include +#include +#include + +struct recTypeClass { + RecType recType; + struct recTypeClass *next; + void *module_handle; +}; -struct recTypeEntry { +struct recTypeInstance { RecType recType; - struct recTypeEntry *next; + struct recTypeInstance *next; int init_flag; + void *clientData; }; struct recTypes { data1_handle dh; - struct recTypeEntry *entries; + struct recTypeInstance *entries; }; -RecTypes recTypes_init (data1_handle dh) +static void recTypeClass_add (struct recTypeClass **rts, RecType *rt, + NMEM nmem, void *module_handle); + +RecTypeClass recTypeClass_create (Res res, NMEM nmem) +{ + struct recTypeClass *rts = 0; +#if HAVE_DLFCN_H + const char *module_path = res_get_def(res, "modulePath", + DEFAULT_MODULE_PATH); +#endif + +#ifdef IDZEBRA_STATIC_GRS_SGML + if (1) + { + extern RecType idzebra_filter_grs_sgml[]; + recTypeClass_add (&rts, idzebra_filter_grs_sgml, nmem, 0); + } +#endif +#ifdef IDZEBRA_STATIC_TEXT + if (1) + { + extern RecType idzebra_filter_text[]; + recTypeClass_add (&rts, idzebra_filter_text, nmem, 0); + } +#endif +#ifdef IDZEBRA_STATIC_GRS_XML +#if HAVE_EXPAT_H + if (1) + { + extern RecType idzebra_filter_grs_xml[]; + recTypeClass_add (&rts, idzebra_filter_grs_xml, nmem, 0); + } +#endif +#endif +#ifdef IDZEBRA_STATIC_GRS_REGX + if (1) + { + extern RecType idzebra_filter_grs_regx[]; + recTypeClass_add (&rts, idzebra_filter_grs_regx, nmem, 0); + } +#endif +#ifdef IDZEBRA_STATIC_GRS_MARC + if (1) + { + extern RecType idzebra_filter_grs_marc[]; + recTypeClass_add (&rts, idzebra_filter_grs_marc, nmem, 0); + } +#endif +#ifdef IDZEBRA_STATIC_GRS_CSV + if (1) + { + extern RecType idzebra_filter_grs_csv[]; + recTypeClass_add (&rts, idzebra_filter_grs_csv, nmem, 0); + } +#endif +#ifdef IDZEBRA_STATIC_GRS_DANBIB + if (1) + { + extern RecType idzebra_filter_grs_danbib[]; + recTypeClass_add (&rts, idzebra_filter_grs_danbib, nmem, 0); + } +#endif +#ifdef IDZEBRA_STATIC_SAFARI + if (1) + { + extern RecType idzebra_filter_safari[]; + recTypeClass_add (&rts, idzebra_filter_safari, nmem, 0); + } +#endif +#ifdef IDZEBRA_STATIC_ALVIS +#if HAVE_XSLT + if (1) + { + extern RecType idzebra_filter_alvis[]; + recTypeClass_add (&rts, idzebra_filter_alvis, nmem, 0); + } +#endif +#endif +#ifdef IDZEBRA_STATIC_XSLT +#if HAVE_XSLT + if (1) + { + extern RecType idzebra_filter_xslt[]; + recTypeClass_add (&rts, idzebra_filter_xslt, nmem, 0); + } +#endif +#endif + +#if HAVE_DLFCN_H + if (module_path) + { + DIR *dir = opendir(module_path); + yaz_log(YLOG_LOG, "searching filters in %s", module_path); + if (dir) + { + struct dirent *de; + + while ((de = readdir(dir))) + { + size_t dlen = strlen(de->d_name); + if (dlen >= 5 && + !memcmp(de->d_name, "mod-", 4) && + !strcmp(de->d_name + dlen - 3, ".so")) + { + void *mod_p, *fl; + char fname[FILENAME_MAX*2+1]; + sprintf(fname, "%.*s/%.*s", + FILENAME_MAX, module_path, + FILENAME_MAX, de->d_name); + mod_p = dlopen(fname, RTLD_NOW|RTLD_GLOBAL); + if (mod_p && (fl = dlsym(mod_p, "idzebra_filter"))) + { + yaz_log(YLOG_LOG, "Loaded filter module %s", fname); + recTypeClass_add(&rts, fl, nmem, mod_p); + } + else if (mod_p) + { + const char *err = dlerror(); + yaz_log(YLOG_WARN, "dlsym failed %s %s", + fname, err ? err : "none"); + dlclose(mod_p); + } + else + { + const char *err = dlerror(); + yaz_log(YLOG_WARN, "dlopen failed %s %s", + fname, err ? err : "none"); + + } + } + } + closedir(dir); + } + } +#endif + return rts; +} + +static void recTypeClass_add (struct recTypeClass **rts, RecType *rt, + NMEM nmem, void *module_handle) { - RecTypes p = (RecTypes) nmem_malloc (data1_nmem_get (dh), sizeof(*p)); + while (*rt) + { + struct recTypeClass *r = (struct recTypeClass *) + nmem_malloc (nmem, sizeof(*r)); + + r->next = *rts; + *rts = r; - p->dh = dh; - p->entries = 0; - return p; + yaz_log(YLOG_LOG, "Adding filter %s", (*rt)->name); + r->module_handle = module_handle; + module_handle = 0; /* so that we only store module_handle once */ + r->recType = *rt; + + rt++; + } } -void recTypes_destroy (RecTypes rts) +void recTypeClass_info(RecTypeClass rtc, void *cd, + void (*cb)(void *cd, const char *s)) { - struct recTypeEntry *rte; + for (; rtc; rtc = rtc->next) + (*cb)(cd, rtc->recType->name); +} - for (rte = rts->entries; rte; rte = rte->next) - if (rte->init_flag) - (*(rte->recType)->destroy)(rte->recType); +void recTypeClass_destroy(RecTypeClass rtc) +{ + for (; rtc; rtc = rtc->next) + { +#if HAVE_DLFCN_H + if (rtc->module_handle) + dlclose(rtc->module_handle); +#endif + } } -void recTypes_add_handler (RecTypes rts, RecType rt) +RecTypes recTypes_init(RecTypeClass rtc, data1_handle dh) { - struct recTypeEntry *rte; + RecTypes rts = (RecTypes) nmem_malloc(data1_nmem_get(dh), sizeof(*rts)); - rte = nmem_malloc (data1_nmem_get (rts->dh), sizeof(*rte)); + struct recTypeInstance **rti = &rts->entries; + + rts->dh = dh; - rte->recType = rt; - rte->init_flag = 0; - rte->next = rts->entries; - rts->entries = rte; + for (; rtc; rtc = rtc->next) + { + *rti = nmem_malloc(data1_nmem_get(dh), sizeof(**rti)); + (*rti)->recType = rtc->recType; + (*rti)->init_flag = 0; + rti = &(*rti)->next; + } + *rti = 0; + return rts; } -RecType recType_byName (RecTypes rts, const char *name, char *subType) +void recTypes_destroy (RecTypes rts) { - struct recTypeEntry *rte; - char *p; - char tmpname[256]; + struct recTypeInstance *rti; - strcpy (tmpname, name); - if ((p = strchr (tmpname, '.'))) + for (rti = rts->entries; rti; rti = rti->next) { - *p = '\0'; - strcpy (subType, p+1); + if (rti->init_flag) + (*(rti->recType)->destroy)(rti->clientData); } - else - *subType = '\0'; - for (rte = rts->entries; rte; rte = rte->next) - if (!strcmp (rte->recType->name, tmpname)) +} + +RecType recType_byName (RecTypes rts, Res res, const char *name, + void **clientDataP) +{ + struct recTypeInstance *rti; + + for (rti = rts->entries; rti; rti = rti->next) + { + size_t slen = strlen(rti->recType->name); + if (!strncmp (rti->recType->name, name, slen) + && (name[slen] == '\0' || name[slen] == '.')) { - if (!rte->init_flag) + if (!rti->init_flag) { - rte->init_flag = 1; - (*(rte->recType)->init)(rte->recType); + rti->init_flag = 1; + rti->clientData = + (*(rti->recType)->init)(res, rti->recType); } - return rte->recType; + *clientDataP = rti->clientData; + if (name[slen]) + slen++; /* skip . */ + + if (rti->recType->config) + (*(rti->recType)->config)(rti->clientData, res, name+slen); + return rti->recType; } + } return 0; } -void recTypes_default_handlers (RecTypes rts) -{ - recTypes_add_handler (rts, recTypeGrs); - recTypes_add_handler (rts, recTypeText); -}