source: main/trunk/greenstone2/runtime-src/src/recpt/statusaction.cpp@ 24874

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