source: trunk/gsdl/src/recpt/statusaction.cpp@ 2212

Last change on this file since 2212 was 2212, checked in by sjboddie, 23 years ago

Fixed a bug that was causing the local library server to attempt to write
files to gsdlhome (i.e. the cd-rom drive if served from a cd) under certain
circumstances.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 38.5 KB
Line 
1/**********************************************************************
2 *
3 * statusaction.cpp --
4 * Copyright (C) 1999 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 "statusaction.h"
27#include "fileutil.h"
28#include "htmlutils.h"
29#include "gsdltools.h"
30#include <assert.h>
31
32
33void statusaction::output_frameset (cgiargsclass &/*args*/, displayclass &disp,
34 outconvertclass &outconvert,
35 ostream &textout, ostream &/*logout*/) {
36 textout << outconvert << disp << "_status:frameset_\n";
37}
38
39void statusaction::output_select (cgiargsclass &/*args*/, displayclass &disp,
40 outconvertclass &outconvert,
41 ostream &textout, ostream &/*logout*/) {
42 textout << outconvert << disp << "_status:header_(selector)\n"
43 "_status:select_\n"
44 "_status:footer_\n";
45}
46
47void statusaction::output_welcome (cgiargsclass &/*args*/, recptprotolistclass *protos,
48 displayclass &disp, outconvertclass &outconvert,
49 ostream &textout, ostream &logout) {
50
51 if (recpt == NULL) return;
52
53 textout << outconvert << disp
54 << "_status:infoheader_(_titlewelcome_)\n"
55 << "_status:welcome_"
56 << "<center><table width=_pagewidth_>\n"
57 << "<th align=left>abbrev.</th><th align=left>collection</th>"
58 << "<th align=left>public?</th><th align=left>running?</th></tr>\n";
59
60 recptprotolistclass::iterator rprotolist_here = protos->begin();
61 recptprotolistclass::iterator rprotolist_end = protos->end();
62 while (rprotolist_here != rprotolist_end) {
63 if ((*rprotolist_here).p != NULL) {
64 comerror_t err;
65 text_t protoname = (*rprotolist_here).p->get_protocol_name(err);
66 text_tarray collist;
67 (*rprotolist_here).p->get_collection_list (collist, err, logout);
68 if (err == noError) {
69 text_tarray::iterator collist_here = collist.begin();
70 text_tarray::iterator collist_end = collist.end();
71
72 while (collist_here != collist_end) {
73
74 textout << outconvert << disp
75 << "<tr><td><a href=\"_gwcgi_?_optsite_e=_compressedoptions_&a=status&p=collectioninfo&pr="
76 << protoname
77 << "&c="
78 << *collist_here
79 << "\">"
80 << *collist_here
81 << "</a></td>";
82
83 ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
84 if (cinfo != NULL) {
85 text_t collname = *collist_here;
86 text_tmap::iterator it = cinfo->collectionmeta.find("collectionname");
87 if (it != cinfo->collectionmeta.end()) collname = (*it).second;
88
89 textout << "<td>";
90 if (cinfo->buildDate > 0)
91 textout << outconvert << disp
92 << "<a href=\"_httppagex_(about)&c=" << *collist_here
93 << "\" target=\\_top>";
94
95 textout << outconvert << disp << collname;
96
97 if (cinfo->buildDate > 0) textout << "</a>";
98
99 textout << "</td>";
100
101 if (cinfo->isPublic) textout << "<td>yes</td>";
102 else textout << "<td>no</td>";
103
104 if (cinfo->buildDate > 0)
105 textout << outconvert << "<td>yes</td>";
106 else
107 textout << "<td>no</td>";
108
109 } else {
110 textout << "<td></td><td></td><td></td>";
111 }
112
113 textout << "</tr>\n";
114 collist_here ++;
115 }
116 }
117 }
118 rprotolist_here ++;
119 }
120
121 textout << "</table></center>\n";
122 textout << outconvert << disp << "_status:infofooter_\n";
123}
124
125void statusaction::output_generalinfo (cgiargsclass &/*args*/, displayclass &disp,
126 outconvertclass &outconvert,
127 ostream &textout, ostream &/*logout*/) {
128 if (recpt == NULL) return;
129 const recptconf &rcinfo = recpt->get_configinfo ();
130
131 textout << outconvert << disp << "_status:infoheader_(General Information)\n";
132 textout << outconvert
133 << "<h2>General information</h2>\n"
134 << "<table>\n"
135 << "<tr valign=top><th>gsdlhome</th><td>\"" << rcinfo.gsdlhome
136 << "\"</td></tr>\n"
137 << "<tr valign=top><th>collection</th><td>\"" << rcinfo.collection
138 << "\"</td></tr>\n"
139 << "<tr valign=top><th>collectdir</th><td>\"" << rcinfo.collectdir
140 << "\"</td></tr>\n"
141 << "<tr valign=top><th>httpprefix</th><td>\"" << rcinfo.httpprefix
142 << "\"</td></tr>\n"
143 << "<tr valign=top><th>httpimg</th><td>\"" << rcinfo.httpimg
144 << "\"</td></tr>\n"
145 << "<tr valign=top><th>gwcgi</th><td>\"" << rcinfo.gwcgi
146 << "\"</td></tr>\n";
147
148 // macrofiles
149 textout << outconvert << "<tr valign=top><th>macrofiles</th><td>";
150 text_tset::const_iterator macrohere = rcinfo.macrofiles.begin ();
151 text_tset::const_iterator macroend = rcinfo.macrofiles.end ();
152 bool macrofirst = true;
153 while (macrohere != macroend) {
154 if (!macrofirst) textout << outconvert << ", ";
155 macrofirst = false;
156 textout << outconvert << "\"" << *macrohere << "\"";
157 macrohere++;
158 }
159 textout << outconvert << "</td></tr>\n";
160
161 // saveconf
162 textout << outconvert << "<tr valign=top><th>saveconf</th><td>\"" << rcinfo.saveconf
163 << "\"</td></tr>\n";
164
165 // usecookies
166 textout << outconvert << "<tr valign=top><th>usecookies</th><td>\"";
167 if (rcinfo.usecookies) textout << outconvert << "true";
168 else textout << outconvert << "false";
169 textout << outconvert << "\"</td></tr>\n";
170
171 // logcgiargs
172 textout << outconvert << "<tr valign=top><th>logcgiargs</th><td>\"";
173 if (rcinfo.logcgiargs) textout << outconvert << "true";
174 else textout << outconvert << "false";
175 textout << outconvert << "\"</td></tr>\n";
176
177 // pageparams
178 textout << outconvert << "<tr valign=top><th>pageparams</th><td>";
179 text_tmap::const_iterator params_here = rcinfo.pageparams.begin();
180 text_tmap::const_iterator params_end = rcinfo.pageparams.end();
181 bool params_first = true;
182 while (params_here != params_end) {
183 if (!params_first) textout << outconvert << ", ";
184 params_first = false;
185 textout << outconvert << "\"" << (*params_here).first << "\" != \""
186 << (*params_here).second << "\"";
187
188 params_here++;
189 }
190 textout << outconvert << "</td></tr>\n";
191
192 // macroprecedence
193 textout << outconvert << "<tr valign=top><th>macroprecedence</th><td>\"" << rcinfo.macroprecedence
194 << "\"</td></tr>\n";
195
196 // arguments
197 cgiargsinfoclass *rcargsinfo = recpt->get_cgiargsinfo_ptr ();
198 if (rcargsinfo != NULL) {
199 textout << outconvert << "<tr valign=top><th>arguments</th><td>";
200
201 cgiargsinfoclass::const_iterator argsinfohere = rcargsinfo->begin ();
202 cgiargsinfoclass::const_iterator argsinfoend = rcargsinfo->end ();
203 bool argsinfofirst = true;
204 while (argsinfohere != argsinfoend) {
205 if (!argsinfofirst) textout << outconvert << ", ";
206 argsinfofirst = false;
207 textout << outconvert << "\"" << (*argsinfohere).second.shortname << "\"";
208 argsinfohere++;
209 }
210
211 textout << outconvert << "</td></tr>\n";
212 }
213
214 // actions
215 actionmapclass *actions = recpt->get_actionmap_ptr();
216 if (actions != NULL) {
217 textout << outconvert << "<tr valign=top><th>actions</th><td>";
218
219 actionptrmap::iterator actionshere = actions->begin ();
220 actionptrmap::iterator actionsend = actions->end ();
221 bool actionsfirst = true;
222 while (actionshere != actionsend) {
223 if (!actionsfirst) textout << outconvert << ", ";
224 actionsfirst = false;
225 assert ((*actionshere).second.a != NULL);
226 if ((*actionshere).second.a != NULL) {
227 textout << outconvert << "\"" << (*actionshere).second.a->get_action_name() << "\"";
228 }
229 actionshere++;
230 }
231
232 textout << outconvert << "</td></tr>\n";
233 }
234
235 // browsers
236 browsermapclass *browsers = recpt->get_browsermap_ptr();
237 if (browsers != NULL) {
238 textout << outconvert << "<tr valign=top><th>browsers</th><td>";
239
240 browserptrmap::iterator browsershere = browsers->begin ();
241 browserptrmap::iterator browsersend = browsers->end ();
242 bool browsersfirst = true;
243 while (browsershere != browsersend) {
244 if (!browsersfirst) textout << outconvert << ", ";
245 browsersfirst = false;
246 assert ((*browsershere).second.b != NULL);
247 if ((*browsershere).second.b != NULL) {
248 textout << outconvert << "\"" << (*browsershere).second.b->get_browser_name() << "\"";
249 }
250 browsershere++;
251 }
252
253 textout << outconvert << "</td></tr>\n";
254 }
255
256 // protocols
257 recptprotolistclass *protocols = recpt->get_recptprotolist_ptr ();
258 if (protocols != NULL) {
259 textout << outconvert << "<tr valign=top><th>protocols</th><td>";
260
261 recptprotolistclass::iterator protohere = protocols->begin ();
262 recptprotolistclass::iterator protoend = protocols->end ();
263 bool protofirst = true;
264 while (protohere != protoend) {
265 comerror_t err;
266 if (!protofirst) textout << outconvert << ", ";
267 protofirst = false;
268 if ((*protohere).p != NULL) {
269 textout << outconvert << "\"" << (*protohere).p->get_protocol_name(err) << "\"";
270 }
271 protohere++;
272 }
273
274 textout << outconvert << "</td></tr>\n";
275 }
276
277 // converters
278 convertinfoclass *converters = recpt->get_convertinfo_ptr ();
279 if (converters != NULL) {
280 textout << outconvert << "<tr valign=top><th>converters</th><td>";
281
282 convertinfoclass::iterator converthere = converters->begin ();
283 convertinfoclass::iterator convertend = converters->end ();
284 bool convertfirst = true;
285 while (converthere != convertend) {
286 if (!convertfirst) textout << outconvert << ", ";
287 convertfirst = false;
288 textout << outconvert << "\"" << (*converthere).second.name << "\"";
289 converthere++;
290 }
291
292 textout << outconvert << "</td></tr>\n";
293 }
294
295 textout << outconvert << disp << "</table>\n_status:infofooter_\n";
296}
297
298void statusaction::output_argumentinfo (cgiargsclass &args, displayclass &disp,
299 outconvertclass &outconvert,
300 ostream &textout, ostream &/*logout*/) {
301 if (recpt == NULL) return;
302 cgiargsinfoclass *rcargsinfo = recpt->get_cgiargsinfo_ptr ();
303 if (rcargsinfo == NULL) return;
304
305 textout << outconvert << disp << "_status:infoheader_(Argument Information)\n";
306 textout << outconvert
307 << "<h2>Argument information</h2>\n"
308 << "<table>";
309
310 // argument information
311 textout << outconvert << "<tr valign=top><th>short name</th><th>long name</th>"
312 << "<th>multiple char?</th>"
313 << "<th>multiple value?</th>"
314 << "<th>default</th><th>default status</th><th>saved args</th>"
315 << "<th>current value</th></tr>\n";
316
317
318 cgiargsinfoclass::const_iterator argsinfohere = rcargsinfo->begin();
319 cgiargsinfoclass::const_iterator argsinfoend = rcargsinfo->end();
320 text_t *arg_value;
321 while (argsinfohere != argsinfoend) {
322 const cgiarginfo &ainfo = (*argsinfohere).second;
323 textout << outconvert
324 << "<tr valign=top><td>" << ainfo.shortname << "</td>\n";
325
326 textout << outconvert << "<td>" << ainfo.longname << "</td>\n";
327 if (ainfo.multiplechar) textout << outconvert << "<td>yes</td>\n";
328 else textout << outconvert << "<td>no</td>\n";
329 if (ainfo.multiplevalue) textout << outconvert << "<td>yes</td>\n";
330 else textout << outconvert << "<td>no</td>\n";
331 textout << outconvert << "<td>" << ainfo.argdefault << "</td>\n";
332 switch (ainfo.defaultstatus) {
333 case cgiarginfo::none: textout << outconvert << "<td>none</td>\n"; break;
334 case cgiarginfo::weak: textout << outconvert << "<td>weak</td>\n"; break;
335 case cgiarginfo::good: textout << outconvert << "<td>good</td>\n"; break;
336 case cgiarginfo::config: textout << outconvert << "<td>config</td>\n"; break;
337 case cgiarginfo::imperative: textout << outconvert << "<td>imperative</td>\n"; break;
338 }
339 switch (ainfo.savedarginfo) {
340 case cgiarginfo::mustnot: textout << outconvert << "<td>mustnot</td>\n"; break;
341 case cgiarginfo::can: textout << outconvert << "<td>can</td>\n"; break;
342 case cgiarginfo::must: textout << outconvert << "<td>must</td>\n"; break;
343 }
344
345 arg_value = args.getarg (ainfo.shortname);
346 if (arg_value == NULL) textout << outconvert << "<td></td></tr>\n";
347 else textout << outconvert << "<td>\"" << *arg_value << "\"</td></tr>\n";
348
349 argsinfohere ++;
350 }
351
352 textout << outconvert << disp << "</table>\n_status:infofooter_\n";
353}
354
355void statusaction::output_actioninfo (cgiargsclass &/*args*/, displayclass &disp,
356 outconvertclass &outconvert,
357 ostream &textout, ostream &/*logout*/) {
358 if (recpt == NULL) return;
359 actionmapclass *actions = recpt->get_actionmap_ptr();
360
361 textout << outconvert << disp << "_status:infoheader_(Action Information)\n";
362 textout << outconvert
363 << "<h2>Action information</h2>\n"
364 << "<table>";
365
366 // action information
367 if (actions != NULL) {
368 textout << outconvert
369 << "<tr><th>action name</th><th>cgi arguments</th></tr>\n";
370
371 actionptrmap::iterator actionshere = actions->begin ();
372 actionptrmap::iterator actionsend = actions->end ();
373 while (actionshere != actionsend) {
374 assert ((*actionshere).second.a != NULL);
375 if ((*actionshere).second.a != NULL) {
376 textout << outconvert
377 << "<tr><td>" << (*actionshere).second.a->get_action_name()
378 << "</td><td>";
379
380 cgiargsinfoclass argsinfo = (*actionshere).second.a->getargsinfo();
381 cgiargsinfoclass::const_iterator argsinfohere = argsinfo.begin ();
382 cgiargsinfoclass::const_iterator argsinfoend = argsinfo.end ();
383 bool aifirst = true;
384 while (argsinfohere != argsinfoend) {
385 if (!aifirst) textout << outconvert << ", ";
386 aifirst = false;
387 textout << outconvert << (*argsinfohere).second.shortname;
388 argsinfohere++;
389 }
390
391 textout << outconvert << "</td></tr>\n";
392 }
393 actionshere++;
394 }
395 }
396
397 textout << outconvert << disp << "</table>\n_status:infofooter_\n";
398}
399
400void statusaction::output_browserinfo (cgiargsclass &/*args*/, displayclass &disp,
401 outconvertclass &outconvert,
402 ostream &textout, ostream &/*logout*/) {
403 if (recpt == NULL) return;
404 browsermapclass *browsers = recpt->get_browsermap_ptr();
405
406 textout << outconvert << disp << "_status:infoheader_(Browser Information)\n";
407 textout << outconvert
408 << "<h2>Browser information</h2>\n"
409 << "<table>";
410
411 // browser information
412 if (browsers != NULL) {
413 textout << outconvert
414 << "<tr><th>browser name</th><th>default formatstring</th></tr>\n";
415
416 browserptrmap::iterator browsershere = browsers->begin ();
417 browserptrmap::iterator browsersend = browsers->end ();
418 while (browsershere != browsersend) {
419 assert ((*browsershere).second.b != NULL);
420 if ((*browsershere).second.b != NULL) {
421 textout << outconvert
422 << "<tr><td>" << (*browsershere).second.b->get_browser_name()
423 << "</td><td>" << html_safe ((*browsershere).second.b->get_default_formatstring())
424 << "</td></tr>\n";
425 }
426 browsershere++;
427 }
428 }
429
430 textout << outconvert << disp << "</table>\n_status:infofooter_\n";
431}
432
433void statusaction::output_protocolinfo (cgiargsclass &/*args*/, displayclass &disp,
434 outconvertclass &outconvert,
435 ostream &textout, ostream &logout) {
436 if (recpt == NULL) return;
437 const recptconf &rcinfo = recpt->get_configinfo ();
438 bool colspecific = !rcinfo.collection.empty();
439 bool unreachablecol = false;
440
441 recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr ();
442 if (rprotolist == NULL) return;
443
444 textout << outconvert << disp << "_status:infoheader_(Protocol Information)\n";
445 textout << outconvert
446 << "<h2>Protocol information</h2>\n"
447 << "<table>\n"
448 << "<tr><th>protocol</th><th>collections</th></tr>\n";
449
450 text_t protoname;
451 recptprotolistclass::iterator rprotolist_here = rprotolist->begin();
452 recptprotolistclass::iterator rprotolist_end = rprotolist->end();
453 while (rprotolist_here != rprotolist_end) {
454 if ((*rprotolist_here).p != NULL) {
455 comerror_t err;
456 protoname = (*rprotolist_here).p->get_protocol_name(err);
457 textout << outconvert
458 << "<tr><td>"
459 << protoname
460 << "</td><td>";
461
462 text_tarray collist;
463 (*rprotolist_here).p->get_collection_list (collist, err, logout);
464 if (err == noError) {
465 text_tarray::iterator collist_here = collist.begin();
466 text_tarray::iterator collist_end = collist.end();
467 bool first = true;
468 while (collist_here != collist_end) {
469 if (!first) textout << outconvert << ", ";
470 first = false;
471
472 if (colspecific && *collist_here != rcinfo.collection) {
473 unreachablecol = true;
474 textout << outconvert << "\"" << *collist_here << "\"";
475 } else {
476 textout << outconvert << disp
477 << "\"<a href=\"_gwcgi_?e=_compressedoptions_&a=status&p=collectioninfo&pr="
478 << protoname
479 << "&c="
480 << *collist_here
481 << "\">"
482 << *collist_here
483 << "</a>\"";
484 }
485
486 collist_here++;
487 }
488
489 } else {
490 textout << outconvert << "Error (" << get_comerror_string (err)
491 << ") while getting collect list\n";
492 }
493
494 textout << outconvert
495 << "</td></tr>\n";
496 }
497
498 rprotolist_here++;
499 }
500
501 textout << outconvert << "</table>\n";
502 if (unreachablecol) {
503 textout << outconvert
504 << "<b>Warning:</b> the receptionist is running in collection specific\n"
505 << "mode making some of the collections unreachable.\n";
506 }
507 textout << outconvert << disp << "_status:infofooter_\n";
508}
509
510void statusaction::output_collectioninfo (cgiargsclass &args, displayclass &disp,
511 outconvertclass &outconvert,
512 ostream &textout, ostream &logout) {
513 if (recpt == NULL) return;
514
515 textout << outconvert << disp << "_status:infoheader_(Collection info)\n";
516 textout << outconvert << "<h2>Collection info</h2>\n";
517
518 // get the list of protocols
519 recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr ();
520 if (rprotolist == NULL) return;
521
522 // look for the desired protocol
523 text_t &arg_pr = args["pr"];
524 text_t &arg_c = args["c"];
525 recptproto *rproto = NULL;
526 recptprotolistclass::iterator rprotolist_here = rprotolist->begin();
527 recptprotolistclass::iterator rprotolist_end = rprotolist->end();
528 while (rprotolist_here != rprotolist_end) {
529 rproto = (*rprotolist_here).p;
530 comerror_t err;
531 if (rproto != NULL && rproto->get_protocol_name(err) == arg_pr) {
532 // see if the protocol has the collection
533 bool hascollection;
534 rproto->has_collection (arg_c, hascollection, err, logout);
535 if (err == noError && hascollection) break;
536 }
537 rprotolist_here++;
538 }
539
540 if (rprotolist_here == rprotolist_end) {
541 textout << outconvert << "Protocol \"" << arg_pr << "\" with collection \""
542 << arg_c << "\" was not found\n";
543
544 } else {
545 // rproto can't be NULL to get here
546 ColInfoResponse_t *collectinfo = recpt->get_collectinfo_ptr (rproto, arg_c, logout);
547 if (collectinfo != NULL) {
548 textout << outconvert << "<table>\n"
549 << "<tr><th>collection name</th><td>\""
550 << collectinfo->shortInfo.name
551 << "\"</td></tr>\n"
552
553 << "<tr><th>host</th><td>\""
554 << collectinfo->shortInfo.host
555 << "\"</td></tr>\n"
556
557 << "<tr><th>port</th><td>\""
558 << collectinfo->shortInfo.port
559 << "\"</td></tr>\n"
560
561 << "<tr><th>is public?</th><td>";
562 if (collectinfo->isPublic) textout << outconvert << "true";
563 else textout << outconvert << "false";
564 textout << outconvert
565 << "</td></tr>\n"
566
567 << "<tr><th>is beta?</th><td>";
568 if (collectinfo->isBeta) textout << outconvert << "true";
569 else textout << outconvert << "false";
570 textout << outconvert
571 << "</td></tr>\n"
572
573 << "<tr><th>build date</th><td>\""
574 << collectinfo->buildDate
575 << "\"</td></tr>\n"
576
577 << "<tr><th>interface languages</th><td>";
578 text_tarray::iterator languages_here = collectinfo->languages.begin();
579 text_tarray::iterator languages_end = collectinfo->languages.end();
580 bool languages_first = true;
581 while (languages_here != languages_end) {
582 if (!languages_first) textout << outconvert << ", ";
583 languages_first = false;
584 textout << outconvert << "\"" << *languages_here << "\"";
585 languages_here++;
586 }
587
588 textout << "<tr><th valign=top>collection metadata</th><td><table>\n";
589 text_tmap::iterator meta_here = collectinfo->collectionmeta.begin();
590 text_tmap::iterator meta_end = collectinfo->collectionmeta.end();
591 while (meta_here != meta_end) {
592 textout << outconvert << "<tr><td>" << (*meta_here).first
593 << "</td><td>" << (*meta_here).second << "</td></tr>\n";
594 meta_here ++;
595 }
596 textout << "</table></td></tr>\n";
597
598 textout << "<tr><th valign=top>format info</th><td><table>\n";
599 text_tmap::iterator format_here = collectinfo->format.begin();
600 text_tmap::iterator format_end = collectinfo->format.end();
601 while (format_here != format_end) {
602 textout << outconvert << "<tr><td>" << (*format_here).first
603 << "</td><td>" << html_safe((*format_here).second) << "</td></tr>\n";
604 format_here ++;
605 }
606 textout << "</table></td></tr>\n";
607
608 textout << "<tr><th valign=top>building info</th><td><table>\n";
609 text_tmap::iterator building_here = collectinfo->building.begin();
610 text_tmap::iterator building_end = collectinfo->building.end();
611 while (building_here != building_end) {
612 textout << outconvert << "<tr><td>" << (*building_here).first
613 << "</td><td>" << (*building_here).second << "</td></tr>\n";
614 building_here ++;
615 }
616 textout << "</table></td></tr>\n";
617
618 textout << outconvert
619 << "</td></tr>\n"
620
621 << "<tr><th>number of documents</th><td>\""
622 << collectinfo->numDocs
623 << "\"</td></tr>\n"
624
625 << "<tr><th>number of sections</th><td>\""
626 << collectinfo->numSections
627 << "\"</td></tr>\n"
628
629 << "<tr><th>number of words</th><td>\""
630 << collectinfo->numWords
631 << "\"</td></tr>\n"
632
633 << "<tr><th>number of bytes</th><td>\""
634 << collectinfo->numBytes
635 << "\"</td></tr>\n"
636
637 << "<tr><th>preferred receptionist</th><td>\""
638 << collectinfo->receptionist
639 << "\"</td></tr>\n"
640
641 << "</table>";
642
643 } else {
644 textout << "ERROR (statusaction::output_collectioninfo): while getting collect information\n";
645 }
646
647
648 InfoFiltersResponse_t filterinfo;
649 InfoFilterOptionsRequest_t filteroptions_request;
650 InfoFilterOptionsResponse_t filteroptions;
651 comerror_t err;
652 rproto->get_filterinfo (arg_c, filterinfo, err, logout);
653 if (err == noError) {
654 text_tset::iterator filternames_here = filterinfo.filterNames.begin();
655 text_tset::iterator filternames_end = filterinfo.filterNames.end();
656 while (filternames_here != filternames_end) {
657 textout << outconvert
658 << "<hr>\n"
659 << "<h3>Filter options for \"" << (*filternames_here) << "\"</h3>\n"
660 << "<table>\n"
661 << "<tr><th>option name</th><th>type</th><th>repeatable</th>"
662 << "<th>default value</th><th>valid values</th></tr>\n";
663
664 filteroptions_request.clear();
665 filteroptions_request.filterName = *filternames_here;
666 rproto->get_filteroptions (arg_c, filteroptions_request,
667 filteroptions, err, logout);
668 if (err == noError) {
669 FilterOption_tmap::iterator filteropt_here =
670 filteroptions.filterOptions.begin();
671 FilterOption_tmap::iterator filteropt_end =
672 filteroptions.filterOptions.end();
673 while (filteropt_here != filteropt_end) {
674 textout << outconvert
675 << "<tr><td>\""
676 << (*filteropt_here).second.name
677 << "\"</td>\n"
678
679 << "<td>";
680 text_t type_string;
681 switch ((*filteropt_here).second.type) {
682 case FilterOption_t::booleant: type_string = "boolean"; break;
683 case FilterOption_t::integert: type_string = "integer"; break;
684 case FilterOption_t::enumeratedt: type_string = "enumerated"; break;
685 case FilterOption_t::stringt: type_string = "string"; break;
686 }
687 textout << outconvert
688 << type_string
689 << "</td>\n"
690
691 << "<td>";
692 text_t repeat_string;
693 switch ((*filteropt_here).second.repeatable) {
694 case FilterOption_t::onePerQuery: repeat_string = "one per query"; break;
695 case FilterOption_t::onePerTerm: repeat_string = "one per term"; break;
696 case FilterOption_t::nPerTerm: repeat_string = "n per term"; break;
697 }
698 textout << outconvert
699 << repeat_string
700 << "</td>\n"
701
702 << "<td>\""
703 << (*filteropt_here).second.defaultValue
704 << "\"</td>\n"
705
706 << "<td>";
707
708 text_tarray::iterator valid_here =
709 (*filteropt_here).second.validValues.begin();
710 text_tarray::iterator valid_end =
711 (*filteropt_here).second.validValues.end();
712 bool valid_first = true;
713 while (valid_here != valid_end) {
714 if (!valid_first) textout << outconvert << ", ";
715 valid_first = false;
716 textout << outconvert << "\"" << *valid_here << "\"";
717 valid_here++;
718 }
719 textout << outconvert
720 << "</td></tr>\n";
721
722 filteropt_here++;
723 }
724
725 textout << outconvert
726 << "</table>\n";
727
728 } else {
729 textout << outconvert << "Error (" << get_comerror_string (err)
730 << ") while getting filter option information\n";
731 }
732
733 filternames_here++;
734 }
735
736 } else {
737 textout << outconvert << "Error (" << get_comerror_string (err)
738 << ") while getting filter information\n";
739 }
740 }
741
742 textout << outconvert << disp << "_status:infofooter_\n";
743}
744
745void statusaction::output_usagelog (cgiargsclass &/*args*/, displayclass &disp,
746 outconvertclass &outconvert,
747 ostream &textout, ostream &/*logout*/) {
748
749 // output last 100 lines of usage.txt
750
751 text_t logfilename = filename_cat (gsdlhome, "etc", "usage.txt");
752
753 textout << outconvert << disp << "_status:infoheader_(Usage log)\n";
754 textout << outconvert << "<h2>Usage log</h2>\n";
755
756 textout << outconvert << "<p>The usage log, "
757 << logfilename << ", contains the\n"
758 << "following information:\n"
759 << "<p>(note that if this file is more than 100 lines long only the last 100 lines will\n"
760 << "be displayed on this page)\n\n"
761 << "<pre>\n";
762
763 // note that we're expecting lines to be no more than 1500 characters on
764 // average - should fix this file_tail() thing sometime
765 textout << outconvert << file_tail (logfilename, 100, 1500);
766
767 textout << outconvert << disp << "</pre>\n"
768 << "_status:infofooter_\n";
769}
770
771void statusaction::output_initlog (cgiargsclass &/*args*/, displayclass &disp,
772 outconvertclass &outconvert,
773 ostream &textout, ostream &/*logout*/) {
774
775 text_t initfilename = filename_cat (gsdlhome, "etc", "initout.txt");
776 char *cinitfilename = initfilename.getcstr();
777 if (cinitfilename == NULL) return;
778
779 textout << outconvert << disp << "_status:infoheader_(Init log)\n";
780 textout << outconvert << "<h2>Init log</h2>\n";
781
782#ifdef GSDL_USE_IOS_H
783 ifstream initin (cinitfilename, ios::in | ios::nocreate);
784#else
785 ifstream initin (cinitfilename, ios::in);
786#endif
787
788 delete cinitfilename;
789 if (initin) {
790 textout << outconvert << "<p>The initialisation error log, "
791 << initfilename << ", contains the\n";
792 textout << outconvert << "following information:\n\n";
793 text_t errorpage = "<p><pre>\n";
794
795 char c;
796 initin.get(c);
797 while (!initin.eof ()) {
798 errorpage.push_back(c);
799 initin.get(c);
800 }
801
802 errorpage += "</pre>\n";
803 initin.close();
804 textout << outconvert << errorpage;
805
806 } else {
807 textout << outconvert << "Couldn't read initialisation error log, "
808 << initfilename << ".\n";
809 }
810
811 textout << outconvert << disp << "_status:infofooter_\n";
812}
813
814void statusaction::output_errorlog (cgiargsclass &/*args*/, displayclass &disp,
815 outconvertclass &outconvert,
816 ostream &textout, ostream &logout) {
817
818 text_t errfilename = filename_cat (gsdlhome, "etc", "errout.txt");
819 char *cerrfilename = errfilename.getcstr();
820 if (cerrfilename == NULL) return;
821
822 textout << outconvert << disp << "_status:infoheader_(Error log)\n";
823 textout << outconvert << "<h2>Error log</h2>\n";
824 logout << flush;
825
826#ifdef GSDL_USE_IOS_H
827 ifstream errin (cerrfilename, ios::in | ios::nocreate);
828#else
829 ifstream errin (cerrfilename, ios::in);
830#endif
831
832 delete cerrfilename;
833 if (errin) {
834 textout << outconvert << "<p>The error log, "
835 << errfilename << ", contains the\n";
836 textout << outconvert << "following information:\n\n";
837 text_t errorpage = "<p><pre>\n";
838
839 char c;
840 errin.get(c);
841 while (!errin.eof ()) {
842 errorpage.push_back(c);
843 errin.get(c);
844 }
845
846 errorpage += "</pre>\n";
847 errin.close();
848 textout << outconvert << errorpage;
849
850 } else {
851 textout << outconvert << "Couldn't read error log, "
852 << errfilename << ".\n";
853 }
854
855 textout << outconvert << disp << "_status:infofooter_\n";
856}
857
858void statusaction::output_gsdlsite (cgiargsclass &/*args*/, displayclass &disp,
859 outconvertclass &outconvert,
860 ostream &textout, ostream &logout) {
861
862 textout << outconvert << disp << "_status:infoheader_(gsdlsite.cfg)\n";
863 textout << outconvert << "<h2>gsdlsite.cfg</h2>\n";
864 logout << flush;
865
866#ifdef GSDL_LOCAL_LIBRARY
867 text_t gsdlsite_cfg = filename_cat (gsdlhome, "gsdlsite.cfg");
868#else
869 text_t gsdlsite_cfg = "gsdlsite.cfg";
870#endif
871
872 char *gsdlsite_cfgc = gsdlsite_cfg.getcstr();
873#ifdef GSDL_USE_IOS_H
874 ifstream gsdlsitein (gsdlsite_cfgc, ios::in | ios::nocreate);
875#else
876 ifstream gsdlsitein (gsdlsite_cfgc, ios::in);
877#endif
878
879 delete gsdlsite_cfgc;
880
881 if (gsdlsitein) {
882 textout << "<p>The gsdlsite.cfg configuration file contains the\n"
883 << "following information:\n\n";
884 text_t gsdlsite = "<p><pre>\n";
885
886 char c;
887 gsdlsitein.get(c);
888 while (!gsdlsitein.eof ()) {
889 gsdlsite.push_back(c);
890 gsdlsitein.get(c);
891 }
892
893 gsdlsite += "</pre>\n";
894 gsdlsitein.close();
895 textout << outconvert << gsdlsite;
896
897 } else {
898 textout << "Couldn't read gsdlsite.cfg configuration file\n";
899 }
900
901 textout << outconvert << disp << "_status:infofooter_\n";
902}
903
904void statusaction::output_maincfg (cgiargsclass &/*args*/, displayclass &disp,
905 outconvertclass &outconvert,
906 ostream &textout, ostream &/*logout*/) {
907
908 text_t maincfgfile = filename_cat (gdbmhome, "etc", "main.cfg");
909
910 textout << outconvert << disp << "_status:infoheader_(main.cfg)\n"
911 << "<h2>main.cfg</h2>\n"
912 << "<p>The main configuration file, "
913 << dm_safe(maincfgfile) << ", contains the following information:<br>\n\n"
914 << "(Note that only users belonging to the \"administrator\" group "
915 << "may edit this file)<br>\n"
916 << "_status:maincfg_<br>\n"
917 << "_status:infofooter_\n";
918}
919
920void statusaction::change_maincfg (cgiargsclass &args, displayclass &disp,
921 outconvertclass &outconvert,
922 ostream &textout, ostream &logout) {
923
924 // write out the contents of the cfgfile argument to main.cfg
925 text_t cfgfile = filename_cat(gsdlhome, "etc", "main.cfg");
926 char *cfgfilec = cfgfile.getcstr();
927#ifdef __WIN32__
928 ofstream cfg_out (cfgfilec, ios::binary);
929#else
930 ofstream cfg_out (cfgfilec);
931#endif
932
933 if (cfg_out) {
934 // lock the file
935 int fd = GSDL_GET_FILEDESC(cfg_out);
936 int lock_val = 1;
937 GSDL_LOCK_FILE (fd);
938 if (lock_val != 0) {
939 logout << "statusaction::change_maincfg: Error: Couldn't lock file " << cfgfilec << "\n";
940 cfg_out.close();
941 textout << outconvert << disp << "_status:changemaincfgfail_";
942
943 } else {
944
945 outconvertclass text_t2ascii;
946 cfg_out << text_t2ascii << args["cfgfile"];
947 GSDL_UNLOCK_FILE (fd);
948 cfg_out.close();
949 textout << outconvert << disp << "_status:changemaincfgsuccess_";
950 }
951 } else {
952 logout << "statusaction::change_maincfg: Error: Couldn't open file " << cfgfilec << "for writing\n";
953 textout << outconvert << disp << "_status:changemaincfgfail_";
954 }
955}
956
957void statusaction::output_errorpage (outconvertclass &outconvert,
958 ostream &textout, ostream &/*logout*/,
959 text_t message) {
960 textout << outconvert
961 << "<html>\n"
962 << "<head>\n"
963 << "<title>Error</title>\n"
964 << "</head>\n"
965 << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
966 << "alink=\"#cc9900\" vlink=\"#666633\">\n"
967 << "<h2>Oops!</h2>\n"
968 << message
969 << "\n</body>\n"
970 << "</html>\n";
971 return;
972}
973
974
975
976statusaction::statusaction () {
977 disabled = true;
978 recpt = NULL;
979
980 // this action uses cgi variable "a"
981 cgiarginfo arg_ainfo;
982 arg_ainfo.shortname = "a";
983 arg_ainfo.longname = "action";
984 arg_ainfo.multiplechar = true;
985 arg_ainfo.defaultstatus = cgiarginfo::weak;
986 arg_ainfo.argdefault = "status";
987 arg_ainfo.savedarginfo = cgiarginfo::must;
988 argsinfo.addarginfo (NULL, arg_ainfo);
989
990 // "p" -- status page
991 arg_ainfo.shortname = "p";
992 arg_ainfo.longname = "page";
993 arg_ainfo.multiplechar = true;
994 arg_ainfo.defaultstatus = cgiarginfo::weak;
995 arg_ainfo.argdefault = "frameset";
996 arg_ainfo.savedarginfo = cgiarginfo::must;
997 argsinfo.addarginfo (NULL, arg_ainfo);
998
999 // "pr" -- protocol
1000 arg_ainfo.shortname = "pr";
1001 arg_ainfo.longname = "protocol";
1002 arg_ainfo.multiplechar = true;
1003 arg_ainfo.defaultstatus = cgiarginfo::none;
1004 arg_ainfo.argdefault = "";
1005 arg_ainfo.savedarginfo = cgiarginfo::can;
1006 argsinfo.addarginfo (NULL, arg_ainfo);
1007
1008 arg_ainfo.shortname = "cfgfile";
1009 arg_ainfo.longname = "configuration file contents";
1010 arg_ainfo.multiplechar = true;
1011 arg_ainfo.defaultstatus = cgiarginfo::weak;
1012 arg_ainfo.argdefault = "";
1013 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
1014 argsinfo.addarginfo (NULL, arg_ainfo);
1015}
1016
1017statusaction::~statusaction () {
1018}
1019
1020bool statusaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args,
1021 ostream &/*logout*/) {
1022
1023 // only users belonging to the "administrator" group may edit
1024 // the main.cfg file
1025 if (args["p"] == "maincfg" || args["p"] == "changemaincfg") {
1026 args["uan"] = "1";
1027 args["ug"] = "administrator";
1028 }
1029 return true;
1030}
1031
1032void statusaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
1033 response_t &response, text_t &response_data,
1034 ostream &/*logout*/) {
1035 response = content;
1036 response_data = "text/html";
1037}
1038
1039
1040void statusaction::define_internal_macros (displayclass &disp, cgiargsclass &args,
1041 recptprotolistclass * /*protos*/, ostream &logout) {
1042
1043 // define_internal_macros sets the following macros:
1044 // _maincfgfile_ the contents of the main.cfg configuration file
1045
1046 if (args["p"] == "maincfg") {
1047
1048 // read in main.cfg
1049 text_t maincfg = filename_cat(gsdlhome, "etc", "main.cfg");
1050 char *maincfgc = maincfg.getcstr();
1051
1052#ifdef GSDL_USE_IOS_H
1053 ifstream cfg_ifs (maincfgc, ios::in | ios::nocreate);
1054#else
1055 ifstream cfg_ifs (maincfgc, ios::in);
1056#endif
1057
1058 if (cfg_ifs) {
1059 text_t cfgtext;
1060 char c;
1061 cfg_ifs.get(c);
1062 while (!cfg_ifs.eof ()) {
1063 cfgtext.push_back(c);
1064 cfg_ifs.get(c);
1065 }
1066 cfg_ifs.close();
1067
1068 // define it as a macro
1069 disp.setmacro("maincfgfile", "status", dm_safe(cfgtext));
1070
1071 } else {
1072 logout << "statusaction::define_internal_macros: couldn't open configuration file ("
1073 << maincfgc << ") for reading\n";
1074 disp.setmacro("maincfgfile", "status", "");
1075 }
1076 delete maincfgc;
1077 }
1078}
1079
1080bool statusaction::do_action (cgiargsclass &args, recptprotolistclass *protos,
1081 browsermapclass * /*browsers*/, displayclass &disp,
1082 outconvertclass &outconvert, ostream &textout,
1083 ostream &logout) {
1084 // make sure the status function is enabled
1085 if (disabled) {
1086 textout << outconvert
1087 << "<html>\n"
1088 << "<head>\n"
1089 << "<title>Status disabled</title>\n"
1090 << "</head>\n"
1091 << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
1092 << "alink=\"#cc9900\" vlink=\"#666633\">\n"
1093 << "<h2>Facility disabled</h2>\n"
1094 << "Sorry, the Maintenance and Administration facility is currently disabled\n"
1095 << "\n</body>\n"
1096 << "</html>\n";
1097 return true;
1098 }
1099
1100 // make sure we know about a receptionist
1101 if (recpt == NULL) {
1102 output_errorpage (outconvert, textout, logout,
1103 "The status action does not contain information\n"
1104 "about any receptionists. The method set_receptionist\n"
1105 "was probably not called from the module which instantiated\n"
1106 "this status action.\n");
1107 return true;
1108 }
1109
1110 // check to make sure status.dm was read in
1111 const recptconf &rcinfo = recpt->get_configinfo ();
1112 text_tset::const_iterator macrohere = rcinfo.macrofiles.begin ();
1113 text_tset::const_iterator macroend = rcinfo.macrofiles.end ();
1114 while (macrohere != macroend) {
1115 if (*macrohere == "status.dm") break;
1116 macrohere++;
1117 }
1118 if (macrohere == macroend) {
1119 output_errorpage (outconvert, textout, logout,
1120 "The status.dm file was not read in. This macro file is\n"
1121 "needed to display configuration and status information.\n");
1122 return true;
1123 }
1124
1125 // output the required status page
1126 text_t &arg_p = args["p"];
1127 if (arg_p == "frameset") output_frameset (args, disp, outconvert, textout, logout);
1128 else if (arg_p == "select") output_select (args, disp, outconvert, textout, logout);
1129 else if (arg_p == "welcome") output_welcome (args, protos, disp, outconvert, textout, logout);
1130 else if (arg_p == "generalinfo") output_generalinfo (args, disp, outconvert, textout, logout);
1131 else if (arg_p == "argumentinfo") output_argumentinfo (args, disp, outconvert, textout, logout);
1132 else if (arg_p == "actioninfo") output_actioninfo (args, disp, outconvert, textout, logout);
1133 else if (arg_p == "browserinfo") output_browserinfo (args, disp, outconvert, textout, logout);
1134 else if (arg_p == "protocolinfo") output_protocolinfo (args, disp, outconvert, textout, logout);
1135 else if (arg_p == "collectioninfo") output_collectioninfo (args, disp, outconvert, textout, logout);
1136 else if (arg_p == "usagelog") output_usagelog (args, disp, outconvert, textout, logout);
1137 else if (arg_p == "initlog") output_initlog (args, disp, outconvert, textout, logout);
1138 else if (arg_p == "errorlog") output_errorlog (args, disp, outconvert, textout, logout);
1139 else if (arg_p == "gsdlsite") output_gsdlsite (args, disp, outconvert, textout, logout);
1140 else if (arg_p == "maincfg") output_maincfg (args, disp, outconvert, textout, logout);
1141 else if (arg_p == "changemaincfg") change_maincfg (args, disp, outconvert, textout, logout);
1142 else {
1143 output_errorpage (outconvert, textout, logout,
1144 "Unknown page \"" + arg_p + "\".\n");
1145 }
1146
1147 return true;
1148}
1149
1150void statusaction::configure (const text_t &key, const text_tarray &cfgline) {
1151 if ((key == "status") && (cfgline.size() == 1) &&
1152 (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
1153 disabled = false;
1154 } else {
1155 // call the parent class to deal with the things which
1156 // are not dealt with here
1157 action::configure (key, cfgline);
1158 }
1159}
Note: See TracBrowser for help on using the repository browser.