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

Last change on this file since 3036 was 3036, checked in by jrm21, 22 years ago

text strings weren't being properly converted for file output via the
convertclass. Input is now properly set so that we don't get garbage output.

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