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

Last change on this file since 7371 was 7371, checked in by mdewsnip, 20 years ago

(Human Info) Allow some actions to be easily switched off.

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