X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=recctrl%2Frecctrl.c;h=5709d8c19b27b813fd1476ddccef6fdf98a43f30;hb=9b9f570a2960c2c8a7026b2faee943794b08ce49;hp=b0e7b9b2b4a467bb6abae9847401f6b1b85b9080;hpb=c325477904a47c61586ad9b756b9280c22351c6b;p=idzebra-moved-to-github.git diff --git a/recctrl/recctrl.c b/recctrl/recctrl.c index b0e7b9b..5709d8c 100644 --- a/recctrl/recctrl.c +++ b/recctrl/recctrl.c @@ -1,59 +1,278 @@ -/* - * Copyright (C) 1994-1996, Index Data I/S - * All rights reserved. - * Sebastian Hammer, Adam Dickmeiss - * - * $Log: recctrl.c,v $ - * 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.20 2005-04-28 08:20:40 adam 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 +#include + +struct recTypeClass { + RecType recType; + struct recTypeClass *next; + void *module_handle; +}; + +struct recTypeInstance { + RecType recType; + struct recTypeInstance *next; + int init_flag; + void *clientData; +}; + +struct recTypes { + data1_handle dh; + struct recTypeInstance *entries; +}; + +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; + const char *module_path = res_get_def(res, "modulePath", + DEFAULT_MODULE_PATH); + +#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_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; -#include -#include "rectext.h" -#include "recgrs.h" + 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) +{ + while (*rt) + { + struct recTypeClass *r = (struct recTypeClass *) + nmem_malloc (nmem, sizeof(*r)); + + r->next = *rts; + *rts = r; + + 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 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 + } +} -RecType recType_byName (const char *name, char *subType) +RecTypes recTypes_init(RecTypeClass rtc, data1_handle dh) { - char *p; - char tmpname[256]; - - strcpy (tmpname, name); - if ((p = strchr (tmpname, '.'))) - { - *p = '\0'; - strcpy (subType, p+1); - } - else - *subType = '\0'; - if (!strcmp (recTypeGrs->name, tmpname)) - return recTypeGrs; - if (!strcmp (recTypeText->name, tmpname)) - return recTypeText; - return NULL; + 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 recTypeInstance *rti; + + for (rti = rts->entries; rti; rti = rti->next) + { + if (rti->init_flag) + (*(rti->recType)->destroy)(rti->clientData); + } +} + +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 (!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) + (*(rti->recType)->config)(rti->clientData, res, name+slen); + return rti->recType; + } + } + return 0; }