source: trunk/gsdl/src/recpt/cgiwrapper.cpp@ 1089

Last change on this file since 1089 was 1089, checked in by sjboddie, 24 years ago

tidied up error messaging and set up some debugging info to be output
when running library from command line

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 22.2 KB
Line 
1/**********************************************************************
2 *
3 * cgiwrapper.cpp -- output pages using the cgi protocol
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 * $Id: cgiwrapper.cpp 1089 2000-04-14 02:52:06Z sjboddie $
25 *
26 *********************************************************************/
27
28/*
29 $Log$
30 Revision 1.23 2000/04/14 02:52:05 sjboddie
31 tidied up error messaging and set up some debugging info to be output
32 when running library from command line
33
34 Revision 1.22 2000/02/21 21:56:46 sjboddie
35 gsdlhome now comes from gsdlsite.cfg
36
37 Revision 1.21 2000/01/25 22:45:59 sjboddie
38 few changes to get fastcgi to work properly
39
40 Revision 1.20 1999/09/07 04:56:53 sjboddie
41 added GPL notice
42
43 Revision 1.19 1999/09/02 00:24:36 rjmcnab
44 fixed bug in getting POST arguments
45
46 Revision 1.18 1999/08/20 01:02:07 sjboddie
47 added some usage logging
48
49 Revision 1.17 1999/07/15 06:03:15 rjmcnab
50 Moved the adding of the actions to librarymain so that they can be
51 overriden easily.
52
53 Revision 1.16 1999/07/14 08:31:05 rjmcnab
54 Fixed a small bug in the POST implementation.
55
56 Revision 1.15 1999/07/13 23:32:17 rjmcnab
57 Added authenaction and usersaction
58
59 Revision 1.14 1999/07/11 01:03:37 rjmcnab
60 Added ability to receive POST cgi form data.
61
62 Revision 1.13 1999/06/24 05:12:18 sjboddie
63 lots of small changes
64
65 Revision 1.12 1999/04/30 01:59:40 sjboddie
66 lots of stuff - getting documentaction working (documentaction replaces
67 old browseaction)
68
69 Revision 1.11 1999/03/25 03:12:01 sjboddie
70
71 subjectbrowseaction was replaced with browseaction
72
73 Revision 1.10 1999/03/05 03:53:54 sjboddie
74
75 fixed some bugs
76
77 Revision 1.9 1999/03/04 22:38:21 sjboddie
78
79 Added subjectbrowseaction. - Doesn't do anything yet.
80
81 Revision 1.8 1999/02/28 20:00:13 rjmcnab
82
83
84 Fixed a few things.
85
86 Revision 1.7 1999/02/21 22:33:53 rjmcnab
87
88 Lots of stuff :-)
89
90 Revision 1.6 1999/02/12 02:40:17 sjboddie
91
92 Added page action
93
94 Revision 1.5 1999/02/11 01:24:04 rjmcnab
95
96 Fixed a few compiler warnings.
97
98 Revision 1.4 1999/02/08 01:28:01 rjmcnab
99
100 Got the receptionist producing something using the statusaction.
101
102 Revision 1.3 1999/02/05 10:42:44 rjmcnab
103
104 Continued working on receptionist
105
106 Revision 1.2 1999/02/04 10:00:56 rjmcnab
107
108 Developed the idea of an "action" and having them define the cgi arguments
109 which they need and how those cgi arguments function.
110
111 Revision 1.1 1999/02/04 01:16:17 rjmcnab
112
113 Initial revision.
114
115 Revision 1.5 1999/01/19 01:38:18 rjmcnab
116
117 Made the source more portable.
118
119 Revision 1.4 1999/01/12 01:51:04 rjmcnab
120
121 Standard header.
122
123 */
124
125
126#include "gsdlconf.h"
127#include "cgiwrapper.h"
128#include "recptconfig.h"
129#include "fileutil.h"
130#include <stdlib.h>
131#include <assert.h>
132
133#if defined(GSDL_USE_OBJECTSPACE)
134# include <ospace/std/iostream>
135# include <ospace/std/fstream>
136#elif defined(GSDL_USE_IOS_H)
137# include <iostream.h>
138# include <fstream.h>
139#else
140# include <iostream>
141# include <fstream>
142#endif
143
144#ifdef USE_FASTCGI
145#include "fcgiapp.h"
146#endif
147
148
149#ifdef USE_FASTCGI
150// used to output the text from receptionist
151class fcgistreambuf : public streambuf {
152public:
153 fcgistreambuf ();
154 int sync ();
155 int overflow (int ch);
156 int underflow () {return EOF;}
157
158 void fcgisbreset() {fcgx_stream = NULL; other_ostream = NULL;};
159 void set_fcgx_stream(FCGX_Stream *newone) {fcgx_stream=newone;};
160 void set_other_ostream(ostream *newone) {other_ostream=newone;};
161
162private:
163 FCGX_Stream *fcgx_stream;
164 ostream *other_ostream;
165};
166
167fcgistreambuf::fcgistreambuf() {
168 fcgisbreset();
169 if (base() == ebuf()) allocate();
170 setp (base(), ebuf());
171};
172
173int fcgistreambuf::sync () {
174 if ((fcgx_stream != NULL) &&
175 (FCGX_PutStr (pbase(), out_waiting(), fcgx_stream) < 0)) {
176 fcgx_stream = NULL;
177 }
178
179 if (other_ostream != NULL) {
180 char *thepbase=pbase();
181 for (int i=0;i<out_waiting();i++) (*other_ostream).put(thepbase[i]);
182 }
183
184 setp (pbase(), epptr());
185
186 return 0;
187}
188
189int fcgistreambuf::overflow (int ch) {
190 if (sync () == EOF) return EOF;
191 if (ch != EOF) sputc (ch);
192 return 0;
193}
194
195#endif
196
197static void format_error_string (text_t &errorpage, const text_t &errortext, bool debug) {
198
199 errorpage.clear();
200
201 if (debug) {
202 errorpage += "\n";
203 errorpage += "ERROR: " + errortext;
204 errorpage += "\n";
205
206 } else {
207
208 errorpage += "Content-type: text/html\n\n";
209
210 errorpage += "<html>\n";
211 errorpage += "<head>\n";
212 errorpage += "<title>Error</title>\n";
213 errorpage += "</head>\n";
214 errorpage += "<body>\n";
215 errorpage += "<h2>Oops!</h2>\n";
216 errorpage += errortext;
217 errorpage += "</body>\n";
218 errorpage += "</html>\n";
219 }
220}
221
222static void page_errorcollect (const text_t &gsdlhome, text_t &errorpage, bool debug) {
223
224 text_t collectdir = filename_cat (gsdlhome, "collect");
225
226 text_t errortext = "No valid collections were found: Check that your collect directory\n";
227 errortext += "(" + collectdir + ") is readable and contains at least one valid collection.\n";
228 errortext += "Note that modelcol is NOT a valid collection.\n";
229 errortext += "If the path to your collect directory is wrong edit the 'gsdlhome' field\n";
230 errortext += "in your gsdlsite.cfg configuration file.\n";
231
232 format_error_string (errorpage, errortext, debug);
233}
234
235static void page_errorsitecfg (text_t &errorpage, bool debug, int mode) {
236
237 text_t errortext;
238
239 if (mode == 0) {
240 errortext += "The gsdlsite.cfg configuration file could not be found. This file\n";
241 errortext += "should contain configuration information relating to this site's setup.\n";
242 errortext += "gsdlsite.cfg should reside in the same directory as this executable file.\n";
243 } else if (mode == 1) {
244 errortext += "The gsdlsite.cfg configuration file does not contain a valid gsdlhome entry.\n";
245 errortext += "gsdlsite.cfg resides in the same directory as this executable.\n";
246 }
247
248 format_error_string (errorpage, errortext, debug);
249}
250
251
252static void page_errormaincfg (const text_t &gsdlhome, const text_t &collection,
253 bool debug, text_t &errorpage) {
254
255 text_t errortext;
256
257 if (collection.empty()) {
258 text_t main_cfg_file = filename_cat (gsdlhome, "etc", "main.cfg");
259 errortext += "The main.cfg configuration file could not be found. This file\n";
260 errortext += "should contain configuration information relating to the\n";
261 errortext += "setup of the interface. As this receptionist is not being run\n";
262 errortext += "in collection specific mode the file should reside at\n";
263 errortext += main_cfg_file + ".\n";
264 } else {
265 text_t collect_cfg_file = filename_cat (gsdlhome, "collect", collection, "etc", "collect.cfg");
266 text_t main_collect_cfg_file = filename_cat (gsdlhome, "etc", "collect.cfg");
267 text_t main_cfg_file = filename_cat (gsdlhome, "etc", "main.cfg");
268 errortext += "Either the collect.cfg or main.cfg configuration file could\n";
269 errortext += "not be found. This file should contain configuration information\n";
270 errortext += "relating to the setup of the interface. As this receptionist is\n";
271 errortext += "being run in collection specific mode the file should reside\n";
272 errortext += "at either " + collect_cfg_file + ",\n";
273 errortext += main_collect_cfg_file + " or " + main_cfg_file + ".\n";
274 }
275
276 format_error_string (errorpage, errortext, debug);
277}
278
279
280static void page_errorinit (const text_t &gsdlhome, bool debug, text_t &errorpage) {
281
282 text_t errortext = "An error occurred during the initialisation of the Greenstone Digital\n";
283 errortext += "Library software. It is likely that the software has not been setup\n";
284 errortext += "correctly.\n";
285
286 text_t init_file = filename_cat (gsdlhome, "etc", "initout.txt");
287 char *ifile = init_file.getcstr();
288 ifstream initin (ifile);
289 delete ifile;
290 if (initin) {
291 errortext += "The initialisation error log, " + init_file + ", contains the\n";
292 errortext += "following information:\n\n";
293 if (!debug) errortext += "<pre>\n";
294
295 char c;
296 initin.get(c);
297 while (!initin.eof ()) {
298 errortext.push_back(c);
299 initin.get(c);
300 }
301
302 if (!debug) errortext += "</pre>\n";
303
304 initin.close();
305
306 } else {
307 errortext += "Please consult " + init_file + " for more information.\n";
308 }
309
310 format_error_string (errorpage, errortext, debug);
311}
312
313static void page_errorparseargs (const text_t &gsdlhome, bool debug, text_t &errorpage) {
314
315 text_t errortext = "An error occurred during the parsing of the cgi arguments.\n";
316
317 text_t error_file = filename_cat (gsdlhome, "etc", "errout.txt");
318 char *efile = error_file.getcstr();
319 ifstream errin (efile);
320 delete efile;
321 if (errin) {
322 errortext += "The error log, " + error_file + ", contains the\n";
323 errortext += "following information:\n\n";
324 if (!debug) errortext += "<pre>\n";
325
326 char c;
327 errin.get(c);
328 while (!errin.eof ()) {
329 errortext.push_back(c);
330 errin.get(c);
331 }
332 if (!debug) errortext += "</pre>\n";
333 errin.close();
334
335 } else {
336 errortext += "Please consult " + error_file + " for more information.\n";
337 }
338
339 format_error_string (errorpage, errortext, debug);
340}
341
342static void page_errorcgipage (const text_t &gsdlhome, bool debug, text_t &errorpage) {
343
344 text_t errortext = "An error occurred during the construction of the cgi page.\n";
345
346 text_t error_file = filename_cat (gsdlhome, "etc", "errout.txt");
347 char *efile = error_file.getcstr();
348 ifstream errin (efile);
349 delete efile;
350 if (errin) {
351 errortext += "The error log, " + error_file + ", contains the\n";
352 errortext += "following information:\n\n";
353 if (!debug) errortext += "<pre>\n";
354
355 char c;
356 errin.get(c);
357 while (!errin.eof ()) {
358 errortext.push_back(c);
359 errin.get(c);
360 }
361 if (!debug) errortext += "</pre>\n";
362 errin.close();
363
364 } else {
365 errortext += "Please consult " + error_file + " for more information.\n";
366 }
367
368 format_error_string (errorpage, errortext, debug);
369}
370
371static void print_debug_info (receptionist &recpt) {
372
373 outconvertclass text_t2ascii;
374 recptconf configinfo = recpt.get_configinfo ();
375 text_t etc_dir = filename_cat (configinfo.gsdlhome, "etc");
376
377 cout << "\n";
378 cout << text_t2ascii
379 << "------------------------------------------------------------\n"
380 << "Configuration and initialization completed successfully.\n"
381 << " Note that more debug information may be available in the\n"
382 << " initialization and error logs initout.txt and errout.txt\n"
383 << " in " << etc_dir << ".\n"
384 << "------------------------------------------------------------\n\n";
385
386 bool colspec = false;
387 if (configinfo.collection.empty()) {
388 cout << "Receptionist is running in general mode.\n";
389 } else {
390 cout << text_t2ascii
391 << "Receptionist is running in collection specific mode.\n"
392 << " collection=" << configinfo.collection << "\n"
393 << " collection directory=" << configinfo.collectdir << "\n";
394 colspec = true;
395 }
396
397 cout << text_t2ascii << "gsdlhome=" << configinfo.gsdlhome << "\n";
398 if (!configinfo.gdbmhome.empty())
399 cout << text_t2ascii << "gdbmhome=" << configinfo.gdbmhome << "\n";
400 cout << text_t2ascii << "httpprefix=" << configinfo.httpprefix << "\n";
401 cout << text_t2ascii << "httpimg=" << configinfo.httpimg << "\n";
402 cout << text_t2ascii << "gwcgi=" << configinfo.gwcgi << "\n"
403 << " Note that unless gwcgi has been set from a configuration\n"
404 << " file it is dependant on environment variables set by your\n"
405 << " webserver. It may not therefore be the same value when run\n"
406 << " from the command line as it would be when run from your\n"
407 << " web server.\n";
408 if (configinfo.usecookies)
409 cout << "cookies are enabled\n";
410 else
411 cout << "cookies are disabled\n";
412 if (configinfo.logcgiargs)
413 cout << "logging is enabled\n";
414 else
415 cout << "logging is disabled\n";
416 cout << "------------------------------------------------------------\n\n";
417
418 text_tset::const_iterator this_mfile = configinfo.macrofiles.begin();
419 text_tset::const_iterator end_mfile = configinfo.macrofiles.end();
420 cout << "Macro Files:\n"
421 << "------------\n";
422 text_t mfile;
423 bool found;
424 while (this_mfile != end_mfile) {
425 cout << text_t2ascii << *this_mfile;
426 int spaces = (22 - (*this_mfile).size());
427 if (spaces < 2) spaces = 2;
428 text_t outspaces;
429 for (int i = 0; i < spaces; i++) outspaces.push_back (' ');
430 cout << text_t2ascii << outspaces;
431
432 found = false;
433 if (colspec) {
434 // collection specific - try collectdir/macros first
435 mfile = filename_cat (configinfo.collectdir, "macros", *this_mfile);
436 if (file_exists (mfile)) {
437 cout << text_t2ascii << "found (" << mfile << ")\n";
438 found = true;
439 }
440 }
441
442 if (!found) {
443 // try main macro directory
444 mfile = filename_cat (configinfo.gsdlhome, "macros", *this_mfile);
445 if (file_exists (mfile)) {
446 cout << text_t2ascii << "found (" << mfile << ")\n";
447 found = true;
448 }
449 }
450
451 if (!found)
452 cout << text_t2ascii << "NOT FOUND\n";
453
454 this_mfile ++;
455 }
456
457 cout << "------------------------------------------------------------\n\n"
458 << "Collections:\n"
459 << "------------\n"
460 << " Note that collections will only appear as being built if\n"
461 << " their build.cfg files exist, are readable, contain a valid\n"
462 << " builddate field (i.e. > 0), and are in the collection's\n"
463 << " index directory (i.e. NOT the building directory)\n\n";
464
465 recptprotolistclass *protos = recpt.get_recptprotolist_ptr();
466 recptprotolistclass::iterator rprotolist_here = protos->begin();
467 recptprotolistclass::iterator rprotolist_end = protos->end();
468 while (rprotolist_here != rprotolist_end) {
469 if ((*rprotolist_here).p != NULL) {
470
471 text_tarray collist;
472 comerror_t err;
473 (*rprotolist_here).p->get_collection_list (collist, err, cerr);
474 if (err == noError) {
475 text_tarray::iterator collist_here = collist.begin();
476 text_tarray::iterator collist_end = collist.end();
477
478 while (collist_here != collist_end) {
479
480 cout << text_t2ascii << *collist_here;
481
482 int spaces = (22 - (*collist_here).size());
483 if (spaces < 2) spaces = 2;
484 text_t outspaces;
485 for (int i = 0; i < spaces; i++) outspaces.push_back (' ');
486 cout << text_t2ascii << outspaces;
487
488 ColInfoResponse_t cinfo;
489 (*rprotolist_here).p->get_collectinfo (*collist_here, cinfo, err, cerr);
490 if (err == noError) {
491 if (cinfo.isPublic) cout << "public ";
492 else cout << "private";
493
494 if (cinfo.buildDate > 0) cout << " built ";
495 else cout << " requires building";
496 }
497
498 cout << "\n";
499
500 collist_here ++;
501 }
502 }
503 }
504 rprotolist_here ++;
505 }
506
507 cout << "------------------------------------------------------------\n";
508 cout << "------------------------------------------------------------\n\n";
509 cout << "receptionist running in command line debug mode\n";
510 cout << "enter cgi arguments as name=value pairs (e.g. 'a=p&p=home'):\n";
511
512}
513
514// cgiwrapper does everything necessary to output a page
515// using the cgi protocol. If this is being run for a particular
516// collection then "collection" should be set, otherwise it
517// should equal "".
518void cgiwrapper (receptionist &recpt, text_t collection) {
519
520 int numrequests = 0;
521 bool debug = false;
522 recptconf configinfo = recpt.get_configinfo ();
523
524 // find out whether this is being run as a cgi-script
525 // or a fastcgi script
526#ifdef USE_FASTCGI
527 fcgistreambuf outbuf;
528 int isfastcgi = !FCGX_IsCGI();
529 FCGX_Stream *fcgiin, *fcgiout, *fcgierr;
530 FCGX_ParamArray fcgienvp;
531#else
532 int isfastcgi = 0;
533#endif
534
535 // get the query string if it is not being run as a fastcgi
536 // script
537 text_t argstr = "";
538 cgiargsclass args;
539 char *aURIStr;
540 if (!isfastcgi) {
541 char *request_method_str = getenv("REQUEST_METHOD");
542 char *content_length_str = getenv("CONTENT_LENGTH");
543 if (request_method_str != NULL && strcmp(request_method_str, "POST") == 0 &&
544 content_length_str != NULL) {
545 // POST form data
546 int content_length = text_t(content_length_str).getint();
547 if (content_length > 0) {
548 char c;
549 do {
550 cin.get(c);
551 if (cin.eof()) break;
552 argstr.push_back (c);
553 content_length--;
554 } while (content_length > 0);
555 }
556
557 } else {
558 aURIStr = getenv("QUERY_STRING");
559 if ((request_method_str != NULL && strcmp(request_method_str, "GET") == 0)
560 || aURIStr != NULL) {
561 // GET form data
562 if (aURIStr != NULL) argstr = aURIStr;
563 } else {
564 // debugging from command line
565 debug = true;
566 }
567 }
568 }
569
570 if (debug) cout << "Configuring Greenstone...\n";
571
572
573 // init stuff - we can't output error pages directly with
574 // fastcgi so the pages are stored until we can output them
575 text_t errorpage;
576 outconvertclass text_t2ascii;
577
578 // set defaults
579 int maxrequests = 10000;
580 recpt.configure ("collection", collection);
581 recpt.configure ("httpimg", "/gsdl/images");
582 char *script_name = getenv("SCRIPT_NAME");
583 if (script_name != NULL) recpt.configure("gwcgi", script_name);
584 else recpt.configure("gwcgi", "/cgi-bin/gw");
585
586 // read in the configuration files.
587 text_t gsdlhome;
588 if (!site_cfg_read (recpt, gsdlhome, maxrequests)) {
589 // couldn't find the site configuration file
590 page_errorsitecfg (errorpage, debug, 0);
591 } else if (gsdlhome.empty()) {
592 // no gsdlhome in gsdlsite.cfg
593 page_errorsitecfg (errorpage, debug, 1);
594 } else if (!main_cfg_read (recpt, gsdlhome, collection)) {
595 // couldn't find the main configuration file
596 page_errormaincfg (gsdlhome, collection, debug, errorpage);
597 } else if (configinfo.collectinfo.empty()) {
598 // don't have any collections
599 page_errorcollect (gsdlhome, errorpage, debug);
600 }
601
602 if (errorpage.empty()) {
603
604 // initialise the library software
605 if (debug) cout << "Initializing...\n";
606
607 text_t init_file = filename_cat (gsdlhome, "etc", "initout.txt");
608 char *iout = init_file.getcstr();
609 ofstream initout (iout);
610 delete iout;
611 if (!recpt.init(initout)) {
612 // an error occurred during the initialisation
613 initout.close();
614 page_errorinit(gsdlhome, debug, errorpage);
615 }
616 initout.close();
617 }
618
619 if (debug && errorpage.empty()) {
620 // get query string from command line
621 print_debug_info (recpt);
622 char cinURIStr[1024];
623 cin.get(cinURIStr, 1024);
624 argstr = cinURIStr;
625 }
626
627 // cgi scripts only deal with one request
628 if (!isfastcgi) maxrequests = 1;
629
630 // Page-request loop. If this is not being run as a fastcgi
631 // process then only one request will be processed and then
632 // the process will exit.
633 while (numrequests < maxrequests) {
634#ifdef USE_FASTCGI
635 if (isfastcgi) {
636 if (FCGX_Accept(&fcgiin, &fcgiout, &fcgierr, &fcgienvp) < 0) break;
637 aURIStr = FCGX_GetParam("QUERY_STRING", fcgienvp);
638 if (aURIStr != NULL) argstr = aURIStr;
639 else argstr = "";
640 }
641#endif
642
643 // get output streams ready
644#ifdef USE_FASTCGI
645 outbuf.fcgisbreset ();
646 if (isfastcgi) outbuf.set_fcgx_stream (fcgiout);
647 else outbuf.set_other_ostream (&cout);
648 ostream pageout (&outbuf);
649#else
650#define pageout cout
651#endif
652
653 // if using fastcgi we'll load environment into a map,
654 // otherwise simply pass empty map (can't get environment
655 // variables using getenv() while using FCGX versions
656 // of fastcgi - at least I can't ;-) - Stefan)
657 text_tmap fastcgienv;
658#ifdef USE_FASTCGI
659 if (isfastcgi) {
660 for(; *fcgienvp != NULL; fcgienvp++) {
661 text_t fvalue = *fcgienvp;
662 text_t::const_iterator begin = fvalue.begin();
663 text_t::const_iterator end = fvalue.end();
664 text_t::const_iterator equals_sign = findchar (begin, end, '=');
665 if (equals_sign != end)
666 fastcgienv[substr(begin, equals_sign)] = substr(equals_sign+1, end);
667 }
668 }
669#endif
670
671 // temporarily need to configure gwcgi here when using fastcgi as I can't
672 // get it to pass the SCRIPT_NAME environment variable to the initial
673 // environment (if anyone can work out how to do this using the apache
674 // server, let me know). Note that this overrides the gwcgi field in
675 // site.cfg (which it shouldn't do) but I can't at present set gwcgi
676 // from site.cfg as I have old receptionists laying around that wouldn't
677 // appreciate it. The following 5 lines of code should be deleted once
678 // I either a: get the server to pass SCRIPT_NAME at initialization
679 // time or b: convert all the collections using old receptionists over
680 // to this version and uncomment gwcgi in the site.cfg file -- Stefan.
681#ifdef USE_FASTCGI
682 if (isfastcgi) {
683 recpt.configure("gwcgi", fastcgienv["SCRIPT_NAME"]);
684 }
685#endif
686
687
688 if (errorpage.empty()) {
689 text_t error_file = filename_cat (gsdlhome, "etc", "errout.txt");
690 char *eout = error_file.getcstr();
691 ofstream errout (eout);
692 delete eout;
693 cerr = errout;
694
695 // parse the cgi arguments and produce the resulting page if there
696 // has been no errors so far
697 if (!recpt.parse_cgi_args (argstr, args, errout, fastcgienv)) {
698 errout.close ();
699 page_errorparseargs(gsdlhome, debug, errorpage);
700 } else {
701 if (!recpt.produce_cgi_page (args, pageout, errout, fastcgienv)) {
702 errout.close ();
703 page_errorcgipage(gsdlhome, debug, errorpage);
704 }
705 recpt.log_cgi_args (args, errout, fastcgienv);
706 errout.close ();
707 }
708 }
709 // there was an error, output the error page
710 if (!errorpage.empty()) {
711 pageout << text_t2ascii << errorpage;
712 errorpage.clear();
713 numrequests = maxrequests; // make this the last page
714 }
715 pageout << flush;
716
717 // finish with the output streams
718#ifdef USE_FASTCGI
719 if (isfastcgi) FCGX_Finish();
720#endif
721
722 numrequests++;
723 }
724
725 return;
726}
727
Note: See TracBrowser for help on using the repository browser.