X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=recctrl%2Frecctrl.c;h=410effc8ad2eae08515f4298b1eff2bd7a77c0c2;hb=ecb3935e78cd9bcfdebafdee0834cfb1060d7b5e;hp=4c3a60544bf477b65233b8dc4a170975c78ccde0;hpb=896c0427df9d8eff5de6a1735dcd992e067df844;p=idzebra-moved-to-github.git diff --git a/recctrl/recctrl.c b/recctrl/recctrl.c index 4c3a605..410effc 100644 --- a/recctrl/recctrl.c +++ b/recctrl/recctrl.c @@ -1,6 +1,6 @@ -/* $Id: recctrl.c,v 1.6 2002-08-02 19:26:56 adam Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 - Index Data Aps +/* $Id: recctrl.c,v 1.25 2006-05-10 08:13:28 adam Exp $ + Copyright (C) 1995-2006 + Index Data ApS This file is part of the Zebra server. @@ -24,87 +24,286 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#if HAVE_DLFCN_H +#include +#endif -#include -#include "rectext.h" -#include "recgrs.h" +#include +#include +#include -struct recTypeEntry { +struct recTypeClass { RecType recType; - struct recTypeEntry *next; + struct recTypeClass *next; + void *module_handle; +}; + +struct recTypeInstance { + RecType recType; + 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) { - RecTypes p = (RecTypes) nmem_malloc (data1_nmem_get (dh), sizeof(*p)); + struct recTypeClass *rts = 0; - p->dh = dh; - p->entries = 0; - return p; +#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 + return rts; } -void recTypes_destroy (RecTypes rts) +void recTypeClass_load_modules(RecTypeClass *rts, NMEM nmem, + const char *module_path) { - struct recTypeEntry *rte; +#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; - for (rte = rts->entries; rte; rte = rte->next) - if (rte->init_flag) - (*(rte->recType)->destroy)(rte->clientData); + 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 } -void recTypes_add_handler (RecTypes rts, RecType rt) +static void recTypeClass_add(struct recTypeClass **rts, RecType *rt, + NMEM nmem, void *module_handle) { - struct recTypeEntry *rte; + while (*rt) + { + struct recTypeClass *r = (struct recTypeClass *) + nmem_malloc (nmem, sizeof(*r)); + + r->next = *rts; + *rts = r; - rte = (struct recTypeEntry *) - nmem_malloc (data1_nmem_get (rts->dh), sizeof(*rte)); + 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; - rte->recType = rt; - rte->init_flag = 0; - rte->clientData = 0; - rte->next = rts->entries; - rts->entries = rte; + rt++; + } } -RecType recType_byName (RecTypes rts, const char *name, char *subType, - void **clientDataP) +void recTypeClass_info(RecTypeClass rtc, void *cd, + void (*cb)(void *cd, const char *s)) +{ + for (; rtc; rtc = rtc->next) + (*cb)(cd, rtc->recType->name); +} + +void recTypeClass_destroy(RecTypeClass rtc) +{ + for (; rtc; rtc = rtc->next) + { +#if HAVE_DLFCN_H + if (rtc->module_handle) + dlclose(rtc->module_handle); +#endif + } +} + +RecTypes recTypes_init(RecTypeClass rtc, data1_handle dh) +{ + RecTypes rts = (RecTypes) nmem_malloc(data1_nmem_get(dh), sizeof(*rts)); + + struct recTypeInstance **rti = &rts->entries; + + rts->dh = dh; + + 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; +} + +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) + { + rti->init_flag = 1; + rti->clientData = + (*(rti->recType)->init)(res, rti->recType); + } + *clientDataP = rti->clientData; + if (name[slen]) + slen++; /* skip . */ + + if (rti->recType->config) { - rte->init_flag = 1; - rte->clientData = - (*(rte->recType)->init)(rte->recType); + if ((*(rti->recType)->config) + (rti->clientData, res, name+slen) != ZEBRA_OK) + return 0; } - *clientDataP = rte->clientData; - return rte->recType; + return rti->recType; } + } return 0; } -void recTypes_default_handlers (RecTypes rts) -{ - recTypes_add_handler (rts, recTypeGrs); - recTypes_add_handler (rts, recTypeText); -} +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +