X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;ds=sidebyside;f=recctrl%2Frecctrl.c;h=9240951f625aa9c24f62161b223ae13a220a2b52;hb=5e9aca2e8f33fe023b6b9da6df55642f96efcb50;hp=b0e7b9b2b4a467bb6abae9847401f6b1b85b9080;hpb=c325477904a47c61586ad9b756b9280c22351c6b;p=idzebra-moved-to-github.git diff --git a/recctrl/recctrl.c b/recctrl/recctrl.c index b0e7b9b..9240951 100644 --- a/recctrl/recctrl.c +++ b/recctrl/recctrl.c @@ -1,59 +1,228 @@ -/* - * 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.10 2004-09-28 12:52:03 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. + +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 +#include +#include #include -#include "rectext.h" -#include "recgrs.h" +#include -RecType recType_byName (const char *name, char *subType) +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) { - char *p; - char tmpname[256]; + 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 +#if HAVE_EXPAT_H + extern RecType idzebra_filter_grs_xml[]; + recTypeClass_add (&rts, idzebra_filter_grs_xml, nmem, 0); +#endif +#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_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; + + 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; +} - strcpy (tmpname, name); - if ((p = strchr (tmpname, '.'))) +static void recTypeClass_add (struct recTypeClass **rts, RecType *rt, + NMEM nmem, void *module_handle) +{ + while (*rt) { - *p = '\0'; - strcpy (subType, p+1); + 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)) +{ + for (; rtc; rtc = rtc->next) + (*cb)(cd, rtc->recType->name); +} + +void recTypeClass_destroy(RecTypeClass rtc) +{ + for (; rtc; rtc = rtc->next) + { + if (rtc->module_handle) + dlclose(rtc->module_handle); + } +} + +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 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; + } } - else - *subType = '\0'; - if (!strcmp (recTypeGrs->name, tmpname)) - return recTypeGrs; - if (!strcmp (recTypeText->name, tmpname)) - return recTypeText; - return NULL; + return 0; }