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

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

Made a few cosmetic changes to the "Administration" pages and added the
ability to view the last 100 lines of the usage log. This meant making a
change to the file_tail() function to allow for the very long lines that
occur in the log file.

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