source: trunk/gsdl/src/colservr/z3950_to_gsdl.cpp@ 11984

Last change on this file since 11984 was 9926, checked in by davidb, 19 years ago

Introduction of Z39.50 Server code for Greenstone. Based on the work of
Chris Martin (2001 approx). Updated to work with newer version of YAZ
library.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/**********************************************************************
2 *
3 * z3950_to_gsdl.cpp --
4 * Copyright (C) 2000 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "z3950parser.h"
27#include "z3950server.h"
28#include "z3950_to_gsdl.h"
29
30// converts a char* to uppercase, I wouldn't be
31// writing this if I could find an existing
32// function to do it
33void toUpperString(char *&text)
34{
35 for (int i = 0; text[i] != '\0'; i++) {
36 text[i] = toupper(text[i]);
37 }
38}
39
40
41text_t gsdlCollection::getName()
42{
43 return name;
44}
45
46bool gsdlCollection::z3950Capeable() const
47{
48 return z3950ready;
49}
50
51
52bool gsdlCollection::bib1_to_dc_mapping(text_t& filename)
53{
54 ifstream inFile;
55 int input_Bib1;
56 text_t input_DCES;
57 text_t input_Short;
58
59 char* filename_cstr = filename.getcstr();
60 inFile.open(filename_cstr, ios::in);
61 delete [] filename_cstr;
62
63 if (!inFile) {
64 return false;
65 }
66
67 const int BUFFERSIZE = 1024;
68 char buffer[BUFFERSIZE];
69
70 // read in pairs of values (mappings from Bib-1 to DCES)
71 while (!inFile.eof()) {
72 char input_DCES_tmp[BUFFERSIZE];
73
74 inFile.getline(buffer, BUFFERSIZE, '\n');
75 if (buffer[0] == '#') {
76 // ignore comments (# ...)
77 continue;
78 }
79
80 sscanf(buffer,"%d %s",&input_Bib1, input_DCES_tmp);
81
82 input_DCES = input_DCES_tmp;
83
84 Bib1_to_DCES[input_Bib1] = input_DCES;
85
86 if (z3950_verbosity_>2) {
87 cerr << "(" << input_Bib1 << "/" << input_DCES << ") ";
88 }
89 }
90
91 if (z3950_verbosity_>2) {
92 cerr << endl;
93 }
94 inFile.close();
95
96 return true;
97}
98
99
100bool gsdlCollection::dc_to_short_mapping(text_t& filename,
101 text_t& collectionName)
102{
103 ifstream inFileBuild;
104 text_t input_DCES;
105 text_t input_Short;
106
107 char* filename_cstr = filename.getcstr();
108 inFileBuild.open(filename_cstr, ios::in);
109 delete [] filename_cstr;
110
111 if (!inFileBuild) {
112 if (z3950_verbosity_>2) {
113 cerr << "Warning: Unable to open: " << filename << endl;
114 cerr << " Collection " << collectionName << " might not be built" << endl;
115 }
116 return false;
117 }
118
119 const int BUFFERSIZE = 1024;
120 char buffer[BUFFERSIZE];
121
122 // find the indexfieldmap line
123 do {
124 inFileBuild >> buffer;
125 if (inFileBuild.eof()) {
126 if (z3950_verbosity_>1) {
127 cerr << "Warning: Did not find indexfieldmap in build.cfg for "
128 << collectionName << endl;
129 }
130 return false;
131 }
132 } while (strcmp(buffer, "indexfieldmap") != 0);
133
134 // at this stage, buffer contains "indexfieldmap",
135 // if the file didn't contain it, would have returned above
136 inFileBuild >> buffer;
137 while (strstr(buffer, "->") != NULL) {
138 // buffer contains a DCES->Short mapping
139 input_DCES.clear();
140 input_Short.clear();
141
142 // copy in DCES
143 int i;
144 for (i = 0; buffer[i] != '-'; i++) {
145 input_DCES.appendcarr(&(buffer[i]), 1);
146 }
147
148 // skip over "->"
149 i+=2;
150
151 // copy in Short
152 for (; isalpha(buffer[i]); i++) {
153 input_Short.appendcarr(&(buffer[i]), 1);
154 }
155
156 // add to map
157 DCES_to_Short[input_DCES] = input_Short;
158
159 if (z3950_verbosity_>1) {
160 cerr << "<" << input_DCES << "/" << input_Short << "> ";
161 }
162
163 inFileBuild >> buffer;
164 }
165
166 inFileBuild.close();
167
168 if (z3950_verbosity_>1) {
169 cerr << endl;
170 }
171
172 return true;
173}
174
175
176
177
178 // converts a Bib1 field number to a short index name,
179 // returns true if a mapping existed, false otherwise
180bool gsdlCollection::getFieldArg(int Bib1, text_t &Short)
181{
182 if (Bib1_to_DCES.count(Bib1) < 1) return false;
183 if (DCES_to_Short.count(Bib1_to_DCES[Bib1]) < 1) return false;
184 Short = DCES_to_Short[Bib1_to_DCES[Bib1]];
185 return true;
186}
187
188gsdlCollection::~gsdlCollection(void)
189{
190 //cerr << "gsdlCollection destructor called" << endl;
191}
192
193gsdlCollection::gsdlCollection(void)
194{
195 //cerr << "gsdlCollection void constructor called" << endl;
196}
197
198gsdlCollection::gsdlCollection(text_t collectionName, text_t gsdlhome)
199{
200
201 //char *filename_cstr;
202 //ifstream inFile;
203 //int inFileSize = 0;
204 z3950ready = true;
205
206 // int input_Bib1;
207 //text_t input_DCES;
208 //text_t input_Short;
209
210 name = collectionName;
211
212 // read in the cfg file for Bib1_to_DCES
213 text_t col_filename = gsdlhome;
214 col_filename.appendcstr("/collect/");
215 col_filename.append(collectionName);
216 col_filename.appendcstr("/etc/bib1_to_dces.cfg");
217
218 if (!bib1_to_dc_mapping(col_filename)) {
219 text_t site_filename = gsdlhome;
220 site_filename.appendcstr("/etc/bib1_to_dces.cfg");
221
222 if (!bib1_to_dc_mapping(site_filename)) {
223 cerr << "Unable to find bib1->dublin core mapping for "
224 << collectionName << endl;
225 cerr << "Looked for:\n " << col_filename << "\n "
226 << site_filename << endl;
227 z3950ready = false;
228 return;
229 }
230 }
231
232 // read in the cfg file for mapping Dublin Core to Short (internal name)
233 text_t build_filename = gsdlhome;
234 build_filename.appendcstr("/collect/");
235 build_filename.append(collectionName);
236 build_filename.appendcstr("/index/build.cfg");
237
238 if (!dc_to_short_mapping(build_filename,collectionName)) {
239 // explicitly check for error (in case in future more work is done after
240 // this
241 z3950ready = false;
242 return;
243 }
244
245}
246
247
248void z3950Server::openLogfile(text_t extension, ofstream &out)
249{
250 char *cfilename;
251 text_t filename;
252
253 filename = filename_cat(gsdlhome, extension);
254 cfilename = filename.getcstr();
255
256 out.open(cfilename);
257 delete cfilename;
258}
259
260z3950Server::z3950Server(nullproto *protocol, text_t home)
261{
262
263 text_t dirname;
264 char * cdirname;
265
266 cerr << "Z3950Server: gsdlhome = " << home << endl;
267
268 this->gsdlhome = home;
269 cerr << gsdlhome.getcstr() << endl;
270 dirname = filename_cat(gsdlhome, "/collect");
271 cdirname = dirname.getcstr();
272 if (!read_dir (cdirname, collections)) exit (1);
273 delete cdirname;
274
275 cerr << "Constructing set list server" << endl;
276 this->protocol = protocol;
277
278 // initialise Yaz stuff for z39.50 server
279}
280
281bool z3950Server::initialise()
282{
283 ofstream logout;
284 int reply;
285 comerror_t error = noError;
286
287 this->openLogfile("/etc/z3950out.txt", logout);
288 reply = protocol->init(error, logout);
289 logout.close();
290 return (reply != 0 ? 1 : 0);
291}
292
293void z3950Server::configure(const text_t &key, const text_tarray &cfgline,
294 comerror_t &err)
295{
296 err = noError;
297
298 // ****
299 cerr << "Recieved " << key << " = ";
300 for (int unsigned i=0; i<cfgline.size(); i++)
301 {
302 cout << cfgline[i] << " ";
303 }
304 cout << endl;
305
306 // DB // ****
307 if (key=="gsdlhome")
308 {
309 text_tarray cfgline;
310 cfgline.push_back (gsdlhome);
311 cerr << "Changing gsdlhome to " << gsdlhome << endl;
312 protocol->configure(key, cfgline, err);
313 }
314 else if (key=="httpdomain")
315 {
316 // Only let gsdlhome through !!!! // ****
317 cerr << "Supressing httpdomain" << endl;
318 }
319 else if (key=="httpprefix")
320 {
321 cerr << "Supressing httpprefix" << endl;
322 }
323 else
324 {
325 protocol->configure(key, cfgline,err);
326 }
327}
328
329int z3950Server::run_z3950( int argc, char **argv )
330{
331
332 const int statserv_var = statserv_main(argc, argv, bend_init, bend_close);
333 cerr << "statserv_main returns: " << statserv_var << endl;
334 return statserv_var;
335}
Note: See TracBrowser for help on using the repository browser.