X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=recctrl%2Frecctrl.c;h=2870cf36ef505268c484ce8272970bbddc2f25e3;hp=4c3a60544bf477b65233b8dc4a170975c78ccde0;hb=8ee402d79e37344b08c2b54ad45b50e8327a6c03;hpb=191ceffa0af0cc1048ef11a1bf92fece3210c879 diff --git a/recctrl/recctrl.c b/recctrl/recctrl.c index 4c3a605..2870cf3 100644 --- a/recctrl/recctrl.c +++ b/recctrl/recctrl.c @@ -1,5 +1,5 @@ -/* $Id: recctrl.c,v 1.6 2002-08-02 19:26:56 adam Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 +/* $Id: recctrl.c,v 1.7 2004-09-27 10:44:50 adam Exp $ + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Index Data Aps This file is part of the Zebra server. @@ -24,87 +24,207 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include +#include #include -#include "rectext.h" -#include "recgrs.h" +#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; + const char *module_path = res_get_def(res, "modulePath", + DEFAULT_MODULE_PATH); + + extern RecType idzebra_filter_grs_sgml[]; + recTypeClass_add (&rts, idzebra_filter_grs_sgml, nmem, 0); +#ifdef IDZEBRA_STATIC_TEXT + extern RecType idzebra_filter_text[]; + recTypeClass_add (&rts, idzebra_filter_text, nmem, 0); +#endif +#ifdef IDZEBRA_STATIC_GRS_XML + extern RecType idzebra_filter_grs_xml[]; + recTypeClass_add (&rts, idzebra_filter_grs_xml, nmem, 0); +#endif +#ifdef IDZEBRA_STATIC_GRS_REGX + extern RecType idzebra_filter_grs_regx[]; + recTypeClass_add (&rts, idzebra_filter_grs_regx, nmem, 0); +#endif +#ifdef IDZEBRA_STATIC_GRS_MARC + extern RecType idzebra_filter_grs_marc[]; + recTypeClass_add (&rts, idzebra_filter_grs_marc, nmem, 0); +#endif +#ifdef IDZEBRA_STATIC_GRS_PERL + extern RecType idzebra_filter_grs_perl[]; + recTypeClass_add (&rts, idzebra_filter_grs_perl, nmem, 0); +#endif +#ifdef IDZEBRA_STATIC_GRS_DANBIB + extern RecType idzebra_filter_grs_danbib[]; + recTypeClass_add (&rts, idzebra_filter_grs_danbib, nmem, 0); +#endif + + if (module_path) + { + DIR *dir = opendir(module_path); + yaz_log(LOG_LOG, "searching filters in %s", module_path); + if (dir) + { + struct dirent *de; - p->dh = dh; - p->entries = 0; - return p; + while ((de = readdir(dir))) + { + size_t dlen = strlen(de->d_name); + if ((de->d_type == DT_REG || de->d_type == DT_LNK) + && 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(LOG_LOG, "Loaded filter module %s", fname); + recTypeClass_add(&rts, fl, nmem, mod_p); + } + else if (mod_p) + { + const char *err = dlerror(); + yaz_log(LOG_WARN, "dlsym failed %s %s", + fname, err ? err : "none"); + dlclose(mod_p); + } + else + { + const char *err = dlerror(); + yaz_log(LOG_WARN, "dlopen failed %s %s", + fname, err ? err : "none"); + + } + } + } + closedir(dir); + } + } + return rts; } -void recTypes_destroy (RecTypes rts) +static void recTypeClass_add (struct recTypeClass **rts, RecType *rt, + NMEM nmem, void *module_handle) +{ + while (*rt) + { + struct recTypeClass *r = (struct recTypeClass *) + nmem_malloc (nmem, sizeof(*r)); + + r->next = *rts; + *rts = r; + + yaz_log(LOG_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 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->clientData); +void recTypeClass_destroy(RecTypeClass rtc) +{ + for (; rtc; rtc = rtc->next) + { + if (rtc->module_handle) + dlclose(rtc->module_handle); + } } -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 = (struct recTypeEntry *) - 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->clientData = 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 **clientDataP) +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->clientData = - (*(rte->recType)->init)(rte->recType); + rti->init_flag = 1; + rti->clientData = + (*(rti->recType)->init)(res, rti->recType); } - *clientDataP = rte->clientData; - 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); -}