1 | /**********************************************************************
|
---|
2 | *
|
---|
3 | * receptionist.cpp -- a web interface for the gsdl
|
---|
4 | * Copyright (C) 1999 The New Zealand Digital Library Project
|
---|
5 | *
|
---|
6 | * PUT COPYRIGHT NOTICE HERE
|
---|
7 | *
|
---|
8 | * $Id: receptionist.cpp 173 1999-02-28 20:00:19Z rjmcnab $
|
---|
9 | *
|
---|
10 | *********************************************************************/
|
---|
11 |
|
---|
12 | /*
|
---|
13 | $Log$
|
---|
14 | Revision 1.9 1999/02/28 20:00:16 rjmcnab
|
---|
15 |
|
---|
16 |
|
---|
17 | Fixed a few things.
|
---|
18 |
|
---|
19 | Revision 1.8 1999/02/25 21:58:59 rjmcnab
|
---|
20 |
|
---|
21 | Merged sources.
|
---|
22 |
|
---|
23 | Revision 1.7 1999/02/21 22:33:55 rjmcnab
|
---|
24 |
|
---|
25 | Lots of stuff :-)
|
---|
26 |
|
---|
27 | Revision 1.6 1999/02/11 01:24:05 rjmcnab
|
---|
28 |
|
---|
29 | Fixed a few compiler warnings.
|
---|
30 |
|
---|
31 | Revision 1.5 1999/02/08 01:28:02 rjmcnab
|
---|
32 |
|
---|
33 | Got the receptionist producing something using the statusaction.
|
---|
34 |
|
---|
35 | Revision 1.4 1999/02/05 10:42:46 rjmcnab
|
---|
36 |
|
---|
37 | Continued working on receptionist
|
---|
38 |
|
---|
39 | Revision 1.3 1999/02/04 10:00:56 rjmcnab
|
---|
40 |
|
---|
41 | Developed the idea of an "action" and having them define the cgi arguments
|
---|
42 | which they need and how those cgi arguments function.
|
---|
43 |
|
---|
44 | Revision 1.2 1999/02/04 01:17:27 rjmcnab
|
---|
45 |
|
---|
46 | Got it outputing something.
|
---|
47 |
|
---|
48 |
|
---|
49 | */
|
---|
50 |
|
---|
51 |
|
---|
52 | #include "receptionist.h"
|
---|
53 | #include "fileutil.h"
|
---|
54 | #include "cgiutils.h"
|
---|
55 | #include <assert.h>
|
---|
56 | #include <time.h>
|
---|
57 |
|
---|
58 |
|
---|
59 |
|
---|
60 | // configure should be called for each line in the
|
---|
61 | // configuration files to configure the receptionist and everything
|
---|
62 | // it contains. The configuration should take place after everything
|
---|
63 | // has been added but before the initialisation.
|
---|
64 | void receptionist::configure (const text_t &key, const text_tarray &cfgline) {
|
---|
65 | // configure the receptionist
|
---|
66 | if (cfgline.size() >= 1) {
|
---|
67 | if (key == "gsdlhome") configinfo.gsdlhome = cfgline[0];
|
---|
68 | else if (key == "collection") configinfo.collection = cfgline[0];
|
---|
69 | else if (key == "collectdir") configinfo.collectdir = cfgline[0];
|
---|
70 | else if (key == "httpimg") configinfo.httpimg = cfgline[0];
|
---|
71 | else if (key == "gwcgi") configinfo.gwcgi = cfgline[0];
|
---|
72 | else if (key == "macrofiles") configinfo.macrofiles = cfgline;
|
---|
73 | else if (key == "saveconf") configinfo.saveconf = cfgline[0];
|
---|
74 | }
|
---|
75 |
|
---|
76 | // configure the actions
|
---|
77 | actionptrmap::iterator actionhere = actions.begin ();
|
---|
78 | actionptrmap::iterator actionend = actions.end ();
|
---|
79 |
|
---|
80 | while (actionhere != actionend) {
|
---|
81 | assert ((*actionhere).second.a != NULL);
|
---|
82 | if ((*actionhere).second.a != NULL)
|
---|
83 | (*actionhere).second.a->configure(key, cfgline);
|
---|
84 |
|
---|
85 | actionhere++;
|
---|
86 | }
|
---|
87 |
|
---|
88 | // configure the protocols
|
---|
89 | recptprotolistclass::iterator protohere = protocols.begin ();
|
---|
90 | recptprotolistclass::iterator protoend = protocols.end ();
|
---|
91 |
|
---|
92 | while (protohere != protoend) {
|
---|
93 | assert ((*protohere).p != NULL);
|
---|
94 | if ((*protohere).p != NULL)
|
---|
95 | (*protohere).p->configure(key, cfgline);
|
---|
96 |
|
---|
97 | protohere++;
|
---|
98 | }
|
---|
99 | }
|
---|
100 |
|
---|
101 | void receptionist::configure (const text_t &key, const text_t &value) {
|
---|
102 | text_tarray cfgline;
|
---|
103 | cfgline.push_back (value);
|
---|
104 | configure(key, cfgline);
|
---|
105 | }
|
---|
106 |
|
---|
107 |
|
---|
108 | // init should be called after all the actions, protocols, and
|
---|
109 | // converters have been added to the receptionist and after everything
|
---|
110 | // has been configured but before any pages are created.
|
---|
111 | // It returns true on success and false on failure. If false is
|
---|
112 | // returned getpage should not be called (without producing
|
---|
113 | // meaningless output), instead an error page should be
|
---|
114 | // produced by the calling code.
|
---|
115 | bool receptionist::init (ostream &logout) {
|
---|
116 | // first configure collectdir
|
---|
117 | text_t thecollectdir = configinfo.gsdlhome;
|
---|
118 | if (!configinfo.collection.empty()) {
|
---|
119 | // collection specific mode
|
---|
120 | if (!configinfo.collectdir.empty()) {
|
---|
121 | // has already been configured
|
---|
122 | thecollectdir = configinfo.collectdir;
|
---|
123 | } else {
|
---|
124 | // decide where collectdir is by searching for collect.cfg
|
---|
125 | // look in $GSDLHOME/collect/collection-name/etc/collect.cfg and
|
---|
126 | // then $GSDLHOME/etc/collect.cfg
|
---|
127 | text_t thecollectdir = filename_cat (configinfo.gsdlhome, "collect");
|
---|
128 | thecollectdir = filename_cat (thecollectdir, configinfo.collection);
|
---|
129 | text_t filename = filename_cat (thecollectdir, "etc");
|
---|
130 | filename = filename_cat (filename, "collect.cfg");
|
---|
131 | if (!file_exists(filename)) thecollectdir = configinfo.gsdlhome;
|
---|
132 | }
|
---|
133 | }
|
---|
134 | configure("collectdir", thecollectdir);
|
---|
135 |
|
---|
136 | // read in the macro files
|
---|
137 | if (!read_macrofiles (logout)) return false;
|
---|
138 |
|
---|
139 | // defined the main cgi arguments
|
---|
140 | if (!define_mainargs (logout)) return false;
|
---|
141 |
|
---|
142 | // there must be at least one action defined
|
---|
143 | if (actions.empty()) {
|
---|
144 | logout << "Error: no actions have been added to the receptionist\n";
|
---|
145 | return false;
|
---|
146 | }
|
---|
147 |
|
---|
148 | // add the cgi arguments from the actions
|
---|
149 | actionptrmap::iterator here = actions.begin ();
|
---|
150 | actionptrmap::iterator end = actions.end ();
|
---|
151 | while (here != end) {
|
---|
152 | assert ((*here).second.a != NULL);
|
---|
153 | if ((*here).second.a != NULL) {
|
---|
154 | if (!argsinfo.addarginfo (&logout, (*here).second.a->getargsinfo()))
|
---|
155 | return false;
|
---|
156 | }
|
---|
157 | here++;
|
---|
158 | }
|
---|
159 |
|
---|
160 | // create a saveconf string if there isn't one already
|
---|
161 | if (configinfo.saveconf.empty())
|
---|
162 | configinfo.saveconf = create_save_conf_str (argsinfo, logout);
|
---|
163 |
|
---|
164 | // check the saveconf string
|
---|
165 | if (!check_save_conf_str (configinfo.saveconf, argsinfo, logout))
|
---|
166 | return false;
|
---|
167 |
|
---|
168 | // set a random seed
|
---|
169 | srand (time(NULL));
|
---|
170 |
|
---|
171 | // make the output converters remove all the zero-width spaces
|
---|
172 | convertinfoclass::iterator converthere = converters.begin ();
|
---|
173 | convertinfoclass::iterator convertend = converters.end ();
|
---|
174 | text_t defaultconvertname;
|
---|
175 | while (converthere != convertend) {
|
---|
176 | assert ((*converthere).second.outconverter != NULL);
|
---|
177 | if ((*converthere).second.outconverter != NULL) {
|
---|
178 | (*converthere).second.outconverter->set_rzws(1);
|
---|
179 | if (defaultconvertname.empty())
|
---|
180 | defaultconvertname = (*converthere).second.name;
|
---|
181 | }
|
---|
182 | converthere++;
|
---|
183 | }
|
---|
184 |
|
---|
185 | // set default converter if no good one has been defined
|
---|
186 | if (!defaultconvertname.empty()) {
|
---|
187 | cgiarginfo *ainfo = argsinfo.getarginfo ("w");
|
---|
188 | if ((ainfo != NULL) && (ainfo->defaultstatus < cgiarginfo::good)) {
|
---|
189 | ainfo->defaultstatus = cgiarginfo::good;
|
---|
190 | ainfo->argdefault = defaultconvertname;
|
---|
191 | }
|
---|
192 | }
|
---|
193 |
|
---|
194 | // init the actions
|
---|
195 | actionptrmap::iterator actionhere = actions.begin ();
|
---|
196 | actionptrmap::iterator actionend = actions.end ();
|
---|
197 | while (actionhere != actionend) {
|
---|
198 | if (((*actionhere).second.a == NULL) ||
|
---|
199 | !(*actionhere).second.a->init(logout)) return false;
|
---|
200 | actionhere++;
|
---|
201 | }
|
---|
202 |
|
---|
203 | // init the protocols
|
---|
204 | recptprotolistclass::iterator protohere = protocols.begin ();
|
---|
205 | recptprotolistclass::iterator protoend = protocols.end ();
|
---|
206 | while (protohere != protoend) {
|
---|
207 | if (((*protohere).p == NULL) ||
|
---|
208 | !(*protohere).p->init(logout)) return false;
|
---|
209 | protohere++;
|
---|
210 | }
|
---|
211 |
|
---|
212 | return true;
|
---|
213 | }
|
---|
214 |
|
---|
215 |
|
---|
216 | // parse_cgi_args parses cgi arguments into an argument class.
|
---|
217 | // This function should be called for each page request. It returns false
|
---|
218 | // if there was a major problem with the cgi arguments.
|
---|
219 | bool receptionist::parse_cgi_args (const text_t &argstr, cgiargsclass &args,
|
---|
220 | ostream &logout) {
|
---|
221 | outconvertclass text_t2ascii;
|
---|
222 |
|
---|
223 | // get an initial list of cgi arguments
|
---|
224 | args.clear();
|
---|
225 | split_cgi_args (argstr, args);
|
---|
226 |
|
---|
227 | // expand the compressed argument (if there was one)
|
---|
228 | if (!expand_save_args (argsinfo, configinfo.saveconf, args, logout)) return false;
|
---|
229 |
|
---|
230 | // add the defaults
|
---|
231 | add_default_args (argsinfo, args, logout);
|
---|
232 |
|
---|
233 | // check the main cgi arguments
|
---|
234 | if (!check_mainargs (args, logout)) return false;
|
---|
235 |
|
---|
236 | // check the arguments for the action
|
---|
237 | action *a = actions.getaction (args["a"]);
|
---|
238 | if (a != NULL) {
|
---|
239 | if (!a->check_cgiargs (args, logout)) return false;
|
---|
240 | } else {
|
---|
241 | // the action was not found!!
|
---|
242 | logout << text_t2ascii << "Error: the action \"" << args["a"]
|
---|
243 | << "\" could not be found.\n";
|
---|
244 | return false;
|
---|
245 | }
|
---|
246 |
|
---|
247 | // get the input encoding
|
---|
248 | text_t &arg_w = args["w"];
|
---|
249 | inconvertclass defaultinconvert;
|
---|
250 | inconvertclass *inconvert = converters.get_inconverter (arg_w);
|
---|
251 | if (inconvert == NULL) inconvert = &defaultinconvert;
|
---|
252 |
|
---|
253 | // see if the next page will have a different encoding
|
---|
254 | if (args.getarg("nw") != NULL) args["w"] = args["nw"];
|
---|
255 |
|
---|
256 | // convert arguments which aren't in unicode to unicode
|
---|
257 | args_tounicode (args, *inconvert);
|
---|
258 |
|
---|
259 | return true;
|
---|
260 | }
|
---|
261 |
|
---|
262 |
|
---|
263 | // produce_cgi_page will call get_cgihead_info and
|
---|
264 | // produce_content in the appropriate way to output a cgi header and
|
---|
265 | // the page content (if needed). If a page could not be created it
|
---|
266 | // will return false
|
---|
267 | bool receptionist::produce_cgi_page (cgiargsclass &args, ostream &contentout,
|
---|
268 | ostream &logout) {
|
---|
269 | outconvertclass text_t2ascii;
|
---|
270 |
|
---|
271 | response_t response;
|
---|
272 | text_t response_data;
|
---|
273 |
|
---|
274 | // produce cgi header
|
---|
275 | get_cgihead_info (args, response, response_data, logout);
|
---|
276 | if (response == location) {
|
---|
277 | // I've forgotten how to do this :-/
|
---|
278 | return true;
|
---|
279 | } else if (response == content) {
|
---|
280 | // content response
|
---|
281 | contentout << text_t2ascii << "Content-type: " << response_data << "\n\n";
|
---|
282 | } else {
|
---|
283 | // unknown response
|
---|
284 | logout << "Error: get_cgihead_info returned an unknown response type.\n";
|
---|
285 | return false;
|
---|
286 | }
|
---|
287 |
|
---|
288 | // produce cgi page
|
---|
289 | if (!produce_content (args, contentout, logout)) return false;
|
---|
290 |
|
---|
291 | // flush contentout
|
---|
292 | contentout << flush;
|
---|
293 | return true;
|
---|
294 | }
|
---|
295 |
|
---|
296 |
|
---|
297 | // get_cgihead_info determines the cgi header information for
|
---|
298 | // a set of cgi arguments. If response contains location then
|
---|
299 | // response_data contains the redirect address. If reponse
|
---|
300 | // contains content then reponse_data contains the content-type.
|
---|
301 | // Note that images can now be produced by the receptionist.
|
---|
302 | void receptionist::get_cgihead_info (cgiargsclass &args, response_t &response,
|
---|
303 | text_t &response_data, ostream &logout) {
|
---|
304 | outconvertclass text_t2ascii;
|
---|
305 |
|
---|
306 | // get the action
|
---|
307 | action *a = actions.getaction (args["a"]);
|
---|
308 | if (a != NULL) {
|
---|
309 | a->get_cgihead_info (args, response, response_data, logout);
|
---|
310 |
|
---|
311 | } else {
|
---|
312 | // the action was not found!!
|
---|
313 | logout << text_t2ascii << "Error receptionist::get_cgihead_info: the action \""
|
---|
314 | << args["a"] << "\" could not be found.\n";
|
---|
315 | response = content;
|
---|
316 | response_data = "text/html";
|
---|
317 | }
|
---|
318 | }
|
---|
319 |
|
---|
320 |
|
---|
321 | // produce the page content
|
---|
322 | bool receptionist::produce_content (cgiargsclass &args, ostream &contentout,
|
---|
323 | ostream &logout) {
|
---|
324 | // decide on the output conversion class
|
---|
325 | text_t &arg_w = args["w"];
|
---|
326 | rzwsoutconvertclass defaultoutconverter;
|
---|
327 | rzwsoutconvertclass *outconverter = converters.get_outconverter (arg_w);
|
---|
328 | if (outconverter == NULL) outconverter = &defaultoutconverter;
|
---|
329 | outconverter->reset();
|
---|
330 |
|
---|
331 | // decide on the protocol used for communicating with
|
---|
332 | // the collection server
|
---|
333 | recptproto *collectproto = NULL;
|
---|
334 | if (!args["c"].empty()) {
|
---|
335 | collectproto = protocols.getrecptproto (args["c"], logout);
|
---|
336 | }
|
---|
337 |
|
---|
338 | // produce the page using the desired action
|
---|
339 | action *a = actions.getaction (args["a"]);
|
---|
340 | if (a != NULL) {
|
---|
341 | if (a->uses_display(args)) prepare_page (a, args, collectproto, disp, logout);
|
---|
342 | if (!a->do_action (args, collectproto, disp, (*outconverter), contentout, logout))
|
---|
343 | return false;
|
---|
344 |
|
---|
345 | } else {
|
---|
346 | // the action was not found!!
|
---|
347 | outconvertclass text_t2ascii;
|
---|
348 |
|
---|
349 | logout << text_t2ascii << "Error receptionist::produce_content: the action \""
|
---|
350 | << args["a"] << "\" could not be found.\n";
|
---|
351 |
|
---|
352 | contentout << (*outconverter)
|
---|
353 | << "<html>\n"
|
---|
354 | << "<head>\n"
|
---|
355 | << "<title>Error</title>\n"
|
---|
356 | << "</head>\n"
|
---|
357 | << "<body>\n"
|
---|
358 | << "<h2>Oops!</h2>\n"
|
---|
359 | << "Undefined Page. The action \""
|
---|
360 | << args["a"] << "\" could not be found.\n"
|
---|
361 | << "</body>\n"
|
---|
362 | << "</html>\n";
|
---|
363 | }
|
---|
364 |
|
---|
365 | return true;
|
---|
366 | }
|
---|
367 |
|
---|
368 |
|
---|
369 | // returns the compressed argument ("e") corresponding to the argument
|
---|
370 | // list. This can be used to save preferences between sessions.
|
---|
371 | text_t receptionist::get_compressed_arg (const cgiargsclass &/*args*/) {
|
---|
372 | return "";
|
---|
373 | }
|
---|
374 |
|
---|
375 |
|
---|
376 | // will read in all the macro files. If one is not found an
|
---|
377 | // error message will be written to logout and the method will
|
---|
378 | // return false.
|
---|
379 | bool receptionist::read_macrofiles (ostream &logout) {
|
---|
380 | outconvertclass text_t2ascii;
|
---|
381 |
|
---|
382 | // redirect the error output to logout
|
---|
383 | disp.setlogout (&logout);
|
---|
384 |
|
---|
385 | // load up the default macro files, the collection directory
|
---|
386 | // is searched first for the file (if this is being used in
|
---|
387 | // collection specific mode) and then the main directory
|
---|
388 | text_t colmacrodir = filename_cat (configinfo.collectdir, "macros");
|
---|
389 | text_t gsdlmacrodir = filename_cat (configinfo.gsdlhome, "macros");
|
---|
390 | text_tarray::iterator arrhere = configinfo.macrofiles.begin();
|
---|
391 | text_tarray::iterator arrend = configinfo.macrofiles.end();
|
---|
392 | text_t filename;
|
---|
393 | while (arrhere != arrend) {
|
---|
394 | // filename is used as a flag to indicate whether
|
---|
395 | // the macro file has been found
|
---|
396 | filename.clear();
|
---|
397 |
|
---|
398 | // try in the collection directory if this is being
|
---|
399 | // run in collection specific mode
|
---|
400 | if (!configinfo.collection.empty()) {
|
---|
401 | filename = filename_cat (colmacrodir, *arrhere);
|
---|
402 | if (!file_exists (filename)) filename.clear ();
|
---|
403 | }
|
---|
404 |
|
---|
405 | // if we haven't found the macro file yet try in
|
---|
406 | // the main macro directory
|
---|
407 | if (filename.empty()) {
|
---|
408 | filename = filename_cat (gsdlmacrodir, *arrhere);
|
---|
409 | if (!file_exists (filename)) filename.clear ();
|
---|
410 | }
|
---|
411 |
|
---|
412 | // see if we found the file or not
|
---|
413 | if (filename.empty()) {
|
---|
414 | logout << text_t2ascii
|
---|
415 | << "Error: the macro file \"" << *arrhere << "\" could not be found.\n";
|
---|
416 | if (configinfo.collection.empty()) {
|
---|
417 | logout << text_t2ascii
|
---|
418 | << "It should be in " << gsdlmacrodir << ".\n\n";
|
---|
419 | } else {
|
---|
420 | logout << text_t2ascii
|
---|
421 | << "It should be in either " << colmacrodir << " or in "
|
---|
422 | << gsdlmacrodir << ".\n\n";
|
---|
423 | }
|
---|
424 | return false;
|
---|
425 |
|
---|
426 | } else { // found the file
|
---|
427 | disp.loaddefaultmacros(filename);
|
---|
428 | }
|
---|
429 |
|
---|
430 | arrhere++;
|
---|
431 | }
|
---|
432 |
|
---|
433 | // success
|
---|
434 | return true;
|
---|
435 | }
|
---|
436 |
|
---|
437 |
|
---|
438 | // Will define the main general arguments used by the receptionist.
|
---|
439 | // If an error occurs a message will be written to logout and the
|
---|
440 | // method will return false.
|
---|
441 | bool receptionist::define_mainargs (ostream &logout) {
|
---|
442 | // create a list of cgi arguments
|
---|
443 | cgiarginfo ainfo;
|
---|
444 |
|
---|
445 | ainfo.shortname = "e";
|
---|
446 | ainfo.longname = "compressed arguments";
|
---|
447 | ainfo.multiplechar = true;
|
---|
448 | ainfo.defaultstatus = cgiarginfo::good;
|
---|
449 | ainfo.argdefault = "";
|
---|
450 | ainfo.savedarginfo = cgiarginfo::mustnot;
|
---|
451 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
452 |
|
---|
453 | ainfo.shortname = "a";
|
---|
454 | ainfo.longname = "action";
|
---|
455 | ainfo.multiplechar = true;
|
---|
456 | ainfo.defaultstatus = cgiarginfo::none;
|
---|
457 | ainfo.argdefault = "";
|
---|
458 | ainfo.savedarginfo = cgiarginfo::must;
|
---|
459 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
460 |
|
---|
461 | // w=western
|
---|
462 | ainfo.shortname = "w";
|
---|
463 | ainfo.longname = "encoding";
|
---|
464 | ainfo.multiplechar = true;
|
---|
465 | ainfo.defaultstatus = cgiarginfo::weak;
|
---|
466 | ainfo.argdefault = "w";
|
---|
467 | ainfo.savedarginfo = cgiarginfo::must;
|
---|
468 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
469 |
|
---|
470 | ainfo.shortname = "nw";
|
---|
471 | ainfo.longname = "new encoding";
|
---|
472 | ainfo.multiplechar = true;
|
---|
473 | ainfo.defaultstatus = cgiarginfo::none;
|
---|
474 | ainfo.argdefault = "";
|
---|
475 | ainfo.savedarginfo = cgiarginfo::mustnot;
|
---|
476 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
477 |
|
---|
478 | ainfo.shortname = "c";
|
---|
479 | ainfo.longname = "collection";
|
---|
480 | ainfo.multiplechar = true;
|
---|
481 | if (configinfo.collection.empty()) {
|
---|
482 | ainfo.defaultstatus = cgiarginfo::none;
|
---|
483 | ainfo.argdefault = "";
|
---|
484 | ainfo.savedarginfo = cgiarginfo::must;
|
---|
485 | } else {
|
---|
486 | ainfo.defaultstatus = cgiarginfo::good;
|
---|
487 | ainfo.argdefault = configinfo.collection;
|
---|
488 | ainfo.savedarginfo = cgiarginfo::can;
|
---|
489 | }
|
---|
490 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
491 |
|
---|
492 | // 0=text+graphics, 1=text
|
---|
493 | ainfo.shortname = "v";
|
---|
494 | ainfo.longname = "version";
|
---|
495 | ainfo.multiplechar = false;
|
---|
496 | ainfo.defaultstatus = cgiarginfo::weak;
|
---|
497 | ainfo.argdefault = "0";
|
---|
498 | ainfo.savedarginfo = cgiarginfo::can;
|
---|
499 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
500 |
|
---|
501 | // 0=normal, 1=big
|
---|
502 | ainfo.shortname = "f";
|
---|
503 | ainfo.longname = "query box size";
|
---|
504 | ainfo.multiplechar = false;
|
---|
505 | ainfo.defaultstatus = cgiarginfo::weak;
|
---|
506 | ainfo.argdefault = "0";
|
---|
507 | ainfo.savedarginfo = cgiarginfo::can;
|
---|
508 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
509 |
|
---|
510 | // the interface language name should use the ISO 639
|
---|
511 | // standard
|
---|
512 | ainfo.shortname = "l";
|
---|
513 | ainfo.longname = "interface language";
|
---|
514 | ainfo.multiplechar = true;
|
---|
515 | ainfo.defaultstatus = cgiarginfo::weak;
|
---|
516 | ainfo.argdefault = "en";
|
---|
517 | ainfo.savedarginfo = cgiarginfo::must;
|
---|
518 | if (!argsinfo.addarginfo (&logout, ainfo)) return false;
|
---|
519 |
|
---|
520 | return true;
|
---|
521 | }
|
---|
522 |
|
---|
523 |
|
---|
524 | // check_mainargs will check all the main arguments. If a major
|
---|
525 | // error is found it will return false and no cgi page should
|
---|
526 | // be created using the arguments.
|
---|
527 | bool receptionist::check_mainargs (cgiargsclass &args, ostream &/*logout*/) {
|
---|
528 | // if this receptionist is running in collection dependant mode
|
---|
529 | // then it should always set the collection argument to the
|
---|
530 | // collection
|
---|
531 | if (!configinfo.collection.empty()) args["c"] = configinfo.collection;
|
---|
532 |
|
---|
533 | // argument "v" can only be 0 or 1. Use the default value
|
---|
534 | // if it is out of range
|
---|
535 | int arg_v = args.getintarg ("v");
|
---|
536 | if (arg_v != 0 && arg_v != 1) {
|
---|
537 | cgiarginfo *vinfo = argsinfo.getarginfo ("v");
|
---|
538 | if (vinfo != NULL) args["v"] = vinfo->argdefault;
|
---|
539 | }
|
---|
540 |
|
---|
541 | // argument "f" can only be 0 or 1. Use the default value
|
---|
542 | // if it is out of range
|
---|
543 | int arg_f = args.getintarg ("f");
|
---|
544 | if (arg_f != 0 && arg_f != 1) {
|
---|
545 | cgiarginfo *finfo = argsinfo.getarginfo ("f");
|
---|
546 | if (finfo != NULL) args["f"] = finfo->argdefault;
|
---|
547 | }
|
---|
548 |
|
---|
549 | return true;
|
---|
550 | }
|
---|
551 |
|
---|
552 | // prepare_page sets up page parameters, sets display macros
|
---|
553 | // and opens the page ready for output
|
---|
554 | void receptionist::prepare_page (action *a, cgiargsclass &args, recptproto */*collectproto*/,
|
---|
555 | displayclass &disp, ostream &logout) {
|
---|
556 |
|
---|
557 | // set up page parameters
|
---|
558 | text_t pageparams;
|
---|
559 |
|
---|
560 | bool first = true;
|
---|
561 | if (!args["c"].empty()) {
|
---|
562 | pageparams += "collection=" + args["c"]; first = false;}
|
---|
563 | if (args.getintarg("u") == 1)
|
---|
564 | if (first) {pageparams += "style=htmlonly"; first = false;}
|
---|
565 | else pageparams += ",style=htmlonly";
|
---|
566 | if (args.getintarg("v") == 1)
|
---|
567 | if (first) {pageparams += "version=text"; first = false;}
|
---|
568 | else pageparams += ",version=text";
|
---|
569 | if (args.getintarg("f") == 1)
|
---|
570 | if (first) {pageparams += ",queryversion=big"; first = false;}
|
---|
571 | else pageparams += ",queryversion=big";
|
---|
572 | if (args["l"] != "en")
|
---|
573 | if (first) pageparams += ",language=" + args["l"];
|
---|
574 | else pageparams += ",language=" + args["l"];
|
---|
575 |
|
---|
576 | // open the page
|
---|
577 | disp.openpage(pageparams, MACROPRECEDENCE);
|
---|
578 |
|
---|
579 |
|
---|
580 | // define general macros
|
---|
581 | define_general_macros (disp, args, logout);
|
---|
582 |
|
---|
583 |
|
---|
584 | // define external macros for each action
|
---|
585 | actionptrmap::iterator actionhere = actions.begin ();
|
---|
586 | actionptrmap::iterator actionend = actions.end ();
|
---|
587 |
|
---|
588 | while (actionhere != actionend) {
|
---|
589 | assert ((*actionhere).second.a != NULL);
|
---|
590 | if ((*actionhere).second.a != NULL)
|
---|
591 | (*actionhere).second.a->define_external_macros (disp, args, logout);
|
---|
592 | actionhere++;
|
---|
593 | }
|
---|
594 |
|
---|
595 |
|
---|
596 | // define internal macros for the current action
|
---|
597 | a->define_internal_macros (disp, args, logout);
|
---|
598 | }
|
---|
599 |
|
---|
600 | void receptionist::define_general_macros (displayclass &disp, cgiargsclass &args,
|
---|
601 | ostream &/*logout*/) {
|
---|
602 |
|
---|
603 | disp.setmacro ("gwcgi", "Global", configinfo.gwcgi);
|
---|
604 | disp.setmacro ("httpimg", "Global", configinfo.httpimg);
|
---|
605 | disp.setmacro("compressedoptions", "Global", get_compressed_arg(args));
|
---|
606 |
|
---|
607 | // set _cgiargX_ macros for each cgi argument
|
---|
608 | cgiargsclass::const_iterator argshere = args.begin();
|
---|
609 | cgiargsclass::const_iterator argsend = args.end();
|
---|
610 | while (argshere != argsend) {
|
---|
611 | disp.setmacro ("cgiarg" + (*argshere).first, "Global", (*argshere).second);
|
---|
612 | argshere ++;
|
---|
613 | }
|
---|
614 | }
|
---|