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

Last change on this file since 28899 was 28899, checked in by ak19, 10 years ago

Third commit for security, for ensuring cgiargs macros are websafe. This time all the changes to the runtime action classes.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 38.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 << "<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>\"" << encodeForHTML(*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 \"" << encodeForHTML(arg_pr) << "\" with collection \""
550 << encodeForHTML(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 text_t errorpage_content;
822 char c;
823 errin.get(c);
824 while (!errin.eof ()) {
825 errorpage_content.push_back(c);
826 errin.get(c);
827 }
828 // need to ensure that error_log displayed from Admin pages is encoded/safe for an HTML context
829 errorpage += encodeForHTML(errorpage_content);
830
831 errorpage += "</pre>\n";
832 errin.close();
833 textout << outconvert << errorpage;
834
835 } else {
836 textout << outconvert << "Couldn't read error log, "
837 << errfilename << ".\n";
838 }
839
840 textout << outconvert << disp << "_status:infofooter_\n";
841}
842
843void statusaction::output_llssite (cgiargsclass &/*args*/, displayclass &disp,
844 outconvertclass &outconvert,
845 ostream &textout, ostream &logout) {
846
847 textout << outconvert << disp << "_status:infoheader_(llssite.cfg)\n";
848 textout << outconvert << "<h2>llssite.cfg</h2>\n";
849 logout << flush;
850
851#ifdef GSDL_LOCAL_LIBRARY
852 text_t llssite_cfg = filename_cat (gsdlhome, "llssite.cfg");
853#else
854 text_t llssite_cfg = filename_cat (gsdlhome, "llssite.cfg"); //"llssite.cfg";
855#endif
856
857 char *llssite_cfgc = llssite_cfg.getcstr();
858#ifdef GSDL_USE_IOS_H
859 ifstream llssitein (llssite_cfgc, ios::in | ios::nocreate);
860#else
861 ifstream llssitein (llssite_cfgc, ios::in);
862#endif
863
864 delete []llssite_cfgc;
865
866 if (llssitein) {
867 textout << "<p>The llssite.cfg configuration file contains the\n"
868 << "following information:\n\n";
869 text_t llssite = "<p><pre>\n";
870
871 char c;
872 llssitein.get(c);
873 while (!llssitein.eof ()) {
874 llssite.push_back(c);
875 llssitein.get(c);
876 }
877
878 llssite += "</pre>\n";
879 llssitein.close();
880 textout << outconvert << llssite;
881
882 } else {
883 textout << "Couldn't read llssite.cfg configuration file\n";
884 }
885
886 textout << outconvert << disp << "_status:infofooter_\n";
887}
888
889void statusaction::output_maincfg (cgiargsclass &/*args*/, displayclass &disp,
890 outconvertclass &outconvert,
891 ostream &textout, ostream &/*logout*/) {
892
893 text_t maincfgfile = filename_cat (dbhome, "etc", "main.cfg");
894
895 textout << outconvert << disp << "_status:infoheader_(main.cfg)\n"
896 << "<h2>main.cfg</h2>\n"
897 << "<p>The main configuration file, "
898 << dm_safe(maincfgfile) << ", contains the following information:<br>\n\n"
899 << "(Note that only users belonging to the \"administrator\" group "
900 << "may edit this file)<br>\n"
901 << "_status:maincfg_<br>\n"
902 << "_status:infofooter_\n";
903}
904
905void statusaction::change_maincfg (cgiargsclass &args, displayclass &disp,
906 outconvertclass &outconvert,
907 ostream &textout, ostream &logout) {
908
909 // write out the contents of the cfgfile argument to main.cfg
910 text_t cfgfile = filename_cat(gsdlhome, "etc", "main.cfg");
911 char *cfgfilec = cfgfile.getcstr();
912
913 int fd=open(cfgfilec, O_WRONLY | O_CREAT | O_TRUNC
914#if defined(__WIN32__)
915 | O_BINARY
916#endif
917 , 432);
918
919 if (fd != -1) {
920
921 int lock_val = 1;
922 GSDL_LOCK_FILE (fd);
923 if (lock_val != 0) {
924 logout << "statusaction::change_maincfg: Error: Couldn't lock file " << cfgfilec << "\n";
925 textout << outconvert << disp << "_status:changemaincfgfail_";
926 close (fd);
927 } else {
928 outconvertclass text_t2ascii;
929 text_t2ascii.setinput(&args["cfgfile"]);
930 size_t buffersize=args["cfgfile"].size();
931 char *buffer=new char[buffersize];
932 size_t num_chars;
933 convertclass::status_t status;
934 text_t2ascii.convert(buffer, buffersize, num_chars, status);
935 // ignore status - assume it is "finished" as buffer is big enough
936 write(fd, buffer, num_chars);
937 GSDL_UNLOCK_FILE (fd);
938 delete []buffer;
939 close (fd);
940 textout << outconvert << disp << "_status:changemaincfgsuccess_";
941 }
942 } else {
943 logout << "statusaction::change_maincfg: Error: Couldn't open file " << cfgfilec << "for writing\n";
944 textout << outconvert << disp << "_status:changemaincfgfail_";
945 }
946 delete []cfgfilec;
947}
948
949void statusaction::output_errorpage (outconvertclass &outconvert,
950 ostream &textout, ostream &/*logout*/,
951 text_t message) {
952 textout << outconvert
953 << "<html>\n"
954 << "<head>\n"
955 << "<title>Error</title>\n"
956 << "</head>\n"
957 << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
958 << "alink=\"#cc9900\" vlink=\"#666633\">\n"
959 << "<h2>Oops!</h2>\n"
960 << message
961 << "\n</body>\n"
962 << "</html>\n";
963 return;
964}
965
966
967
968statusaction::statusaction () {
969 disabled = true;
970 recpt = NULL;
971
972 // this action uses cgi variable "a"
973 cgiarginfo arg_ainfo;
974 arg_ainfo.shortname = "a";
975 arg_ainfo.longname = "action";
976 arg_ainfo.multiplechar = true;
977 arg_ainfo.multiplevalue = false;
978 arg_ainfo.defaultstatus = cgiarginfo::weak;
979 arg_ainfo.argdefault = "status";
980 arg_ainfo.savedarginfo = cgiarginfo::must;
981 argsinfo.addarginfo (NULL, arg_ainfo);
982
983 // "p" -- status page
984 arg_ainfo.shortname = "p";
985 arg_ainfo.longname = "page";
986 arg_ainfo.multiplechar = true;
987 arg_ainfo.multiplevalue = false;
988 arg_ainfo.defaultstatus = cgiarginfo::weak;
989 arg_ainfo.argdefault = "frameset";
990 arg_ainfo.savedarginfo = cgiarginfo::must;
991 argsinfo.addarginfo (NULL, arg_ainfo);
992
993 // "pr" -- protocol
994 arg_ainfo.shortname = "pr";
995 arg_ainfo.longname = "protocol";
996 arg_ainfo.multiplechar = true;
997 arg_ainfo.multiplevalue = false;
998 arg_ainfo.defaultstatus = cgiarginfo::none;
999 arg_ainfo.argdefault = g_EmptyText;
1000 arg_ainfo.savedarginfo = cgiarginfo::can;
1001 argsinfo.addarginfo (NULL, arg_ainfo);
1002
1003 arg_ainfo.shortname = "cfgfile";
1004 arg_ainfo.longname = "configuration file contents";
1005 arg_ainfo.multiplechar = true;
1006 arg_ainfo.multiplevalue = false;
1007 arg_ainfo.defaultstatus = cgiarginfo::weak;
1008 arg_ainfo.argdefault = g_EmptyText;
1009 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
1010 argsinfo.addarginfo (NULL, arg_ainfo);
1011}
1012
1013statusaction::~statusaction () {
1014}
1015
1016bool statusaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args,
1017 recptprotolistclass * /*protos*/, ostream &/*logout*/) {
1018
1019 // only users belonging to the "administrator" group may edit
1020 // the main.cfg file
1021 if (args["p"] == "maincfg" || args["p"] == "changemaincfg") {
1022 args["uan"] = "1";
1023 args["ug"] = "administrator";
1024 }
1025 return true;
1026}
1027
1028void statusaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
1029 response_t &response, text_t &response_data,
1030 ostream &/*logout*/) {
1031 response = content;
1032 response_data = "text/html";
1033}
1034
1035
1036void statusaction::define_internal_macros (displayclass &disp, cgiargsclass &args,
1037 recptprotolistclass * /*protos*/, ostream &logout) {
1038
1039 // define_internal_macros sets the following macros:
1040 // _maincfgfile_ the contents of the main.cfg configuration file
1041
1042 // _versionnnum_ greenstone version number (hard-coded)
1043
1044 disp.setmacro("versionnum", "status", GSDL_VERSION);
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", g_EmptyText);
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 == "errorlog") output_errorlog (args, disp, outconvert, textout, logout);
1138 else if (arg_p == "llssite") output_llssite (args, disp, outconvert, textout, logout);
1139 else if (arg_p == "maincfg") output_maincfg (args, disp, outconvert, textout, logout);
1140 else if (arg_p == "changemaincfg") change_maincfg (args, disp, outconvert, textout, logout);
1141 else {
1142 output_errorpage (outconvert, textout, logout,
1143 "Unknown page \"" + encodeForHTML(arg_p) + "\".\n");
1144 }
1145
1146 return true;
1147}
1148
1149void statusaction::configure (const text_t &key, const text_tarray &cfgline) {
1150 if ((key == "status") && (cfgline.size() == 1) &&
1151 (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
1152 disabled = false;
1153 } else {
1154 // call the parent class to deal with the things which
1155 // are not dealt with here
1156 action::configure (key, cfgline);
1157 }
1158}
1159
1160#endif //GSDL_USE_STATUS_ACTION
Note: See TracBrowser for help on using the repository browser.