/********************************************************************** * * z3950_to_gsdl.cpp -- * Copyright (C) 2000 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include "z3950parser.h" #include "z3950server.h" #include "z3950_to_gsdl.h" // converts a char* to uppercase, I wouldn't be // writing this if I could find an existing // function to do it void toUpperString(char *&text) { for (int i = 0; text[i] != '\0'; i++) { text[i] = toupper(text[i]); } } text_t gsdlCollection::getName() { return name; } bool gsdlCollection::z3950Capeable() const { return z3950ready; } bool gsdlCollection::bib1_to_dc_mapping(text_t& filename) { ifstream inFile; int input_Bib1; text_t input_DCES; text_t input_Short; char* filename_cstr = filename.getcstr(); inFile.open(filename_cstr, ios::in); delete [] filename_cstr; if (!inFile) { return false; } const int BUFFERSIZE = 1024; char buffer[BUFFERSIZE]; // read in pairs of values (mappings from Bib-1 to DCES) while (!inFile.eof()) { char input_DCES_tmp[BUFFERSIZE]; inFile.getline(buffer, BUFFERSIZE, '\n'); if (buffer[0] == '#') { // ignore comments (# ...) continue; } sscanf(buffer,"%d %s",&input_Bib1, input_DCES_tmp); input_DCES = input_DCES_tmp; Bib1_to_DCES[input_Bib1] = input_DCES; if (z3950_verbosity_>2) { cerr << "(" << input_Bib1 << "/" << input_DCES << ") "; } } if (z3950_verbosity_>2) { cerr << endl; } inFile.close(); return true; } bool gsdlCollection::dc_to_short_mapping(text_t& filename, text_t& collectionName) { ifstream inFileBuild; text_t input_DCES; text_t input_Short; char* filename_cstr = filename.getcstr(); inFileBuild.open(filename_cstr, ios::in); delete [] filename_cstr; if (!inFileBuild) { if (z3950_verbosity_>2) { cerr << "Warning: Unable to open: " << filename << endl; cerr << " Collection " << collectionName << " might not be built" << endl; } return false; } const int BUFFERSIZE = 1024; char buffer[BUFFERSIZE]; // find the indexfieldmap line do { inFileBuild >> buffer; if (inFileBuild.eof()) { if (z3950_verbosity_>1) { cerr << "Warning: Did not find indexfieldmap in build.cfg for " << collectionName << endl; } return false; } } while (strcmp(buffer, "indexfieldmap") != 0); // at this stage, buffer contains "indexfieldmap", // if the file didn't contain it, would have returned above inFileBuild >> buffer; while (strstr(buffer, "->") != NULL) { // buffer contains a DCES->Short mapping input_DCES.clear(); input_Short.clear(); // copy in DCES int i; for (i = 0; buffer[i] != '-'; i++) { input_DCES.appendcarr(&(buffer[i]), 1); } // skip over "->" i+=2; // copy in Short for (; isalpha(buffer[i]); i++) { input_Short.appendcarr(&(buffer[i]), 1); } // add to map DCES_to_Short[input_DCES] = input_Short; if (z3950_verbosity_>1) { cerr << "<" << input_DCES << "/" << input_Short << "> "; } inFileBuild >> buffer; } inFileBuild.close(); if (z3950_verbosity_>1) { cerr << endl; } return true; } // converts a Bib1 field number to a short index name, // returns true if a mapping existed, false otherwise bool gsdlCollection::getFieldArg(int Bib1, text_t &Short) { if (Bib1_to_DCES.count(Bib1) < 1) return false; if (DCES_to_Short.count(Bib1_to_DCES[Bib1]) < 1) return false; Short = DCES_to_Short[Bib1_to_DCES[Bib1]]; return true; } gsdlCollection::~gsdlCollection(void) { //cerr << "gsdlCollection destructor called" << endl; } gsdlCollection::gsdlCollection(void) { //cerr << "gsdlCollection void constructor called" << endl; } gsdlCollection::gsdlCollection(text_t collectionName, text_t gsdlhome) { //char *filename_cstr; //ifstream inFile; //int inFileSize = 0; z3950ready = true; // int input_Bib1; //text_t input_DCES; //text_t input_Short; name = collectionName; // read in the cfg file for Bib1_to_DCES text_t col_filename = gsdlhome; col_filename = filename_cat(gsdlhome, "collect", collectionName, "etc", "bib1-mapping.txt"); if (!bib1_to_dc_mapping(col_filename)) { text_t site_filename = filename_cat(gsdlhome, "etc", "packages", "z3950", "bib1-mapping.txt"); if (!bib1_to_dc_mapping(site_filename)) { cerr << "Unable to find bib1 attribute mapping for " << collectionName << endl; cerr << "Looked for:\n " << col_filename << "\n " << site_filename << endl; z3950ready = false; return; } } // read in the cfg file for mapping Dublin Core to Short (internal name) text_t build_filename = filename_cat(gsdlhome, "collect", collectionName, "index", "build.cfg"); if (!dc_to_short_mapping(build_filename,collectionName)) { // explicitly check for error (in case in future more work is done after // this z3950ready = false; return; } } void z3950Server::openLogfile(text_t extension, ofstream &out) { char *cfilename; text_t filename; filename = filename_cat(gsdlhome, extension); cfilename = filename.getcstr(); out.open(cfilename); delete cfilename; } z3950Server::z3950Server(nullproto *protocol, text_t home) { text_t dirname; char * cdirname; if (home.empty()) { cerr << "Z3950Server Error: gsdlhome not set. \nPlease make sure" << " you have a valid gsdlsite.cfg file in the directory \n" << "you are running z3950server\n"; cerr << "Exiting..."<protocol = protocol; // initialise Yaz stuff for z39.50 server } bool z3950Server::initialise() { ofstream logout; int reply; comerror_t error = noError; // openLogfile does a filename_cat with this path, changing // the / appropriately. this->openLogfile("/etc/packages/z3950/z3950out.txt", logout); reply = protocol->init(error, logout); logout.close(); return (reply != 0 ? 1 : 0); } void z3950Server::configure(const text_t &key, const text_tarray &cfgline, comerror_t &err) { err = noError; // **** cerr << "Recieved " << key << " = "; for (int unsigned i=0; iconfigure(key, cfgline, err); } else if (key=="httpdomain") { // Only let gsdlhome through !!!! // **** cerr << "Supressing httpdomain" << endl; } else if (key=="httpprefix") { cerr << "Supressing httpprefix" << endl; } else { protocol->configure(key, cfgline,err); } } int z3950Server::run_z3950( int argc, char **argv ) { const int statserv_var = statserv_main(argc, argv, bend_init, bend_close); cerr << "statserv_main returns: " << statserv_var << endl; return statserv_var; }