source: trunk/gsdl/src/recpt/receptionist.cpp@ 430

Last change on this file since 430 was 418, checked in by sjboddie, 25 years ago

-added collectinfo argument to some functions
-made some function prototypes virtual

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