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

Last change on this file since 39004 was 39000, checked in by kjdon, 7 weeks ago

the usecookies option has been renamed to usecookiesForUID to better reflect what it means. A new option usecookiesForE is added. If this is set to true (the default), then the e arg will be saved as a cookie, instead of being set into the various compressedoptions macros (which will now be empty). nzdl.org is getting hammered by bots, and one theory is that the e arg changes everytime so looks like a new page when its not.

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