source: trunk/gsdl/src/w32server/cgiwrapper.cpp@ 1615

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

Minor change to allow collection specific receptionists to be created
using the local library code.

  • 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 -- windows local library cgiwrapper
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "text_t.h"
27
28#include <windows.h>
29#include <string.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <assert.h>
33#include <direct.h>
34#include "cgiwrapper.h"
35#include "netio.h"
36#include "wincgiutils.h"
37#include "settings.h"
38#include "fileutil.h"
39
40#include "gsdlconf.h"
41#include "recptconfig.h"
42
43#if defined (GSDL_USE_OBJECTSPACE)
44#include <ospace\std\iostream>
45#include <ospace\std\fstream>
46#elif defined (GSDL_USE_IOS_H)
47#include <iostream.h>
48#include <fstream.h>
49#else
50#include <iostream>
51#include <fstream>
52#endif
53
54#include "receptionist.h"
55#include "nullproto.h"
56#include "collectserver.h"
57#include "infodbclass.h"
58#include "mggdbmsource.h"
59#include "mgsearch.h"
60
61// actions
62#include "statusaction.h"
63#include "pageaction.h"
64#include "pingaction.h"
65#include "queryaction.h"
66#include "documentaction.h"
67#include "tipaction.h"
68#include "authenaction.h"
69#include "usersaction.h"
70#include "extlinkaction.h"
71#include "delhistoryaction.h"
72#include "collectoraction.h"
73
74// browsers
75#include "vlistbrowserclass.h"
76#include "hlistbrowserclass.h"
77#include "datelistbrowserclass.h"
78#include "invbrowserclass.h"
79#include "pagedbrowserclass.h"
80#include "htmlbrowserclass.h"
81
82// filters
83#include "filter.h"
84#include "browsefilter.h"
85#include "mgqueryfilter.h"
86#include "phrasequeryfilter.h"
87
88// the number of times the library has been accessed
89int libaccessnum = 0;
90
91// used to output the text from receptionist
92class textstreambuf : public streambuf
93{
94public:
95 textstreambuf ();
96 int sync ();
97 int overflow (int ch);
98 int underflow () {return EOF;}
99
100 void tsbreset() {RInfo=NULL;casostr=NULL;}
101 void setrequestinfo (RequestInfoT *theRInfo) {RInfo=theRInfo;}
102 void cascadeoutput (ostream *thecasostr) {casostr=thecasostr;}
103
104private:
105 RequestInfoT *RInfo;
106 ostream *casostr;
107#if !defined (GSDL_USE_IOS_H)
108 char buffer[256];
109#endif
110};
111
112textstreambuf::textstreambuf() {
113 tsbreset();
114#if !defined (GSDL_USE_IOS_H)
115 setp (&buffer[0], &buffer[255]);
116#else
117 if (base() == ebuf()) allocate();
118 setp (base(), ebuf());
119#endif
120};
121
122int textstreambuf::sync () {
123 if ((RInfo != NULL) &&
124 (Send_String_N(pbase(), pptr()-pbase(), RInfo) < 0)) {
125 RInfo = NULL;
126 }
127
128 if (casostr != NULL) {
129 char *thepbase=pbase();
130 for (int i=0;i<(pptr()-pbase());i++) (*casostr).put(thepbase[i]);
131 }
132
133 setp (pbase(), epptr());
134
135 return 0;
136}
137
138int textstreambuf::overflow (int ch) {
139 if (sync () == EOF) return EOF;
140 if (ch != EOF) sputc (ch);
141 return 0;
142}
143
144
145// used to output all the log and error messages
146// from receptionist
147class logstreambuf : public streambuf
148{
149public:
150 logstreambuf ();
151 int sync ();
152 int overflow (int ch);
153 int underflow () {return EOF;}
154
155#if !defined (GSDL_USE_IOS_H)
156private:
157 char buffer[256];
158#endif
159};
160
161logstreambuf::logstreambuf () {
162#if !defined (GSDL_USE_IOS_H)
163 setp (&buffer[0], &buffer[255]);
164#else
165 if (base() == ebuf()) allocate();
166 setp (base(), ebuf());
167#endif
168}
169
170int logstreambuf::sync () {
171 if (gsdl_keep_log || gsdl_show_console) {
172 log_message ("LOCAL LIB MESSAGE: ");
173 log_message_N (pbase(), pptr()-pbase());
174 }
175
176 setp (pbase(), epptr());
177 return 0;
178}
179
180int logstreambuf::overflow (int ch) {
181 if (sync () == EOF) return EOF;
182 if (ch != EOF) sputc (ch);
183 return 0;
184}
185
186
187
188#ifndef MAX_FILENAME_SIZE
189#define MAX_FILENAME_SIZE 2048
190#endif
191
192
193receptionist recpt;
194nullproto nproto;
195textstreambuf textstream;
196logstreambuf logstream;
197DWORD lastlibaccesstime;
198DWORD baseavailvirtual;
199
200static void page_errormaincfg (const text_t &gsdlhome, const text_t &collection) {
201
202 if (collection.empty()) {
203 text_t message = "Error\n\n"
204 "The main.cfg configuration file could not be found. This file\n"
205 "should contain configuration information relating to the\n"
206 "setup of the interface. As this program is not being run\n"
207 "in collection specific mode the file should reside at\n" +
208 gsdlhome + "\\etc\\main.cfg.\n";
209
210 MessageBox(NULL, message.getcstr(),
211 "Greenstone Digital Library Software"
212 ,MB_OK|MB_SYSTEMMODAL);
213 } else {
214 text_t message = "Neither the collect.cfg or main.cfg configuration files could\n"
215 "be found. This file should contain configuration information\n"
216 "relating to the setup of the interface. As this cgi script is\n"
217 "being run in collection specific mode the file should reside\n"
218 "at either " + gsdlhome + "\\collect\\" + collection + "\\etc\\collect.cfg,\n" +
219 gsdlhome + "\\etc\\collect.cfg or " + gsdlhome + "\\etc\\main.cfg.\n";
220
221 MessageBox(NULL, message.getcstr(),
222 "Greenstone Digital Library Software"
223 ,MB_OK|MB_SYSTEMMODAL);
224 }
225}
226
227static void page_errorinit (const text_t &/*gsdlhome*/) {
228
229 text_t message = "Error\n\n"
230 "An error occurred during the initialisation of the Greenstone Digital\n"
231 "Library software. It is likely that the software has not been setup\n"
232 "correctly.\n";
233
234 MessageBox(NULL, message.getcstr(),
235 "Greenstone Digital Library Software"
236 ,MB_OK|MB_SYSTEMMODAL);
237}
238
239static void page_errorparseargs (const text_t &gsdlhome) {
240
241 text_t message = "Error\n\n"
242 "An error occurred during the parsing of the cgi arguments.\n";
243
244 MessageBox(NULL, message.getcstr(),
245 "Greenstone Digital Library Software"
246 ,MB_OK|MB_SYSTEMMODAL);
247}
248
249static void page_errorcgipage (const text_t &gsdlhome) {
250
251 text_t message = "Error\n\n"
252 "An error occurred during the construction of the cgi page.\n";
253
254 MessageBox(NULL, message.getcstr(),
255 "Greenstone Digital Library Software"
256 ,MB_OK|MB_SYSTEMMODAL);
257}
258
259// returns 0 if the directories can't be found
260// and the user wants to quit (it returns 1
261// if everything is ok)
262int checkdir (const text_t &thedir) {
263 UINT curerrormode;
264 int drive = _getdrive();
265 char cwd[1024];
266 char rootpath[4];
267 UINT drivetype;
268 char *cstrthedir = thedir.getcstr();
269 int returnvalue = 1;
270
271 // make sure no rude error messages are presented to the user
272 curerrormode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
273
274 // get the drive name
275 if (thedir.size() >= 2 && thedir[1] == ':') {
276 if (thedir[0] >= 'a' && thedir[0] <= 'z') {
277 drive = thedir[0] - 'a' + 1;
278
279 } else if (thedir[0] >= 'A' && thedir[0] <= 'Z') {
280 drive = thedir[0] - 'A' + 1;
281 }
282 }
283
284 // find the drive type
285 rootpath[0] = drive + 'A' - 1;
286 rootpath[1] = ':';
287 rootpath[2] = '\\';
288 rootpath[3] = '\0';
289 drivetype = GetDriveType (rootpath);
290
291 // try and set this directory to be the current working
292 // directory
293 _getcwd(cwd, 1024);
294 while (_chdir(cstrthedir) != 0) {
295 // failed
296 if (drivetype == DRIVE_CDROM) {
297 // message to insert the cdrom
298 if (MessageBox (NULL,
299 "Please insert the Greenstone Digital Library\n"
300 "CD-ROM into the CD-ROM drive and press 'OK'.\n\n"
301 "If you don't have the CD-ROM press 'Cancel' to exit\n"
302 "this program.", "Greenstone Digital Library Software",
303 MB_OKCANCEL | MB_TASKMODAL) == IDCANCEL) {
304
305 returnvalue = 0;
306 break;
307 }
308
309 } else {
310 // message saying that the system was unable
311 // to find a certain directory
312 text_t message = "Failed to find the directory:\n\n" + thedir;
313 message += "\n\n"
314 "This directory is needed for the successful operation\n"
315 "of this software. Make sure it hasn't been deleted or\n"
316 "moved, and restart the software. You may need to\n"
317 "reinstall this software to correct the problem.";
318 char *cstrmessage = message.getcstr();
319
320 MessageBox (NULL, cstrmessage, "Greenstone Digital Library Software",
321 MB_OK | MB_TASKMODAL);
322
323 delete cstrmessage;
324
325 returnvalue = 0;
326 break;
327 }
328 }
329
330 // revert to the previous error and cwd states
331 _chdir(cwd);
332 SetErrorMode(curerrormode);
333
334 // free the allocated C string
335 delete cstrthedir;
336
337 return returnvalue;
338}
339
340
341// c-string version of checkdir for the outside
342// world
343int cstrcheckdir (char *cstrthedir) {
344 return checkdir (cstrthedir);
345}
346
347
348// returns 1 if successful, 0 if unsuccessful
349int gsdl_init () {
350#if defined (GSDL_USE_IOS_H)
351 cerr = &logstream;
352 cout = &textstream;
353#else
354 cerr.rdbuf(&logstream);
355 cout.rdbuf(&textstream);
356#endif
357
358 // collection should be set to "" unless in collection specific mode -
359 // changing this to the name of the collection should be all that's
360 // required to create a collection specific receptionist
361 text_t collection = "";
362 text_tset gsdlhomes;
363 text_tarray collections;
364 colinfo_tmap::const_iterator this_info = gsdl_collectinfo.begin();
365 colinfo_tmap::const_iterator end_info = gsdl_collectinfo.end();
366
367 // note the current time
368 lastlibaccesstime = GetTickCount();
369
370 // before we do the init we should make sure
371 // that we can find the relevant directories
372 if (!checkdir (gsdl_gsdlhome + "\\")) return 0;
373 if (!checkdir (gsdl_gsdlhome + "\\macros\\")) return 0;
374
375 if (collection.empty()) {
376
377 // get all collections from each gsdlhome (this relies
378 // on there not being more than one collection with the same
379 // name)
380 read_dir (filename_cat (gsdl_gsdlhome, "collect"), collections);
381 gsdlhomes.insert (gsdl_gsdlhome);
382 while (this_info != end_info) {
383 if (gsdlhomes.find ((*this_info).second.gsdl_gsdlhome) == gsdlhomes.end()) {
384 read_dir (filename_cat ((*this_info).second.gsdl_gsdlhome, "collect"), collections);
385 gsdlhomes.insert ((*this_info).second.gsdl_gsdlhome);
386 }
387 this_info ++;
388 }
389 } else {
390 collections.push_back (collection);
391 gsdlhomes.insert (gsdl_gsdlhome);
392 }
393
394 text_tarray::const_iterator thiscol = collections.begin();
395 text_tarray::const_iterator endcol = collections.end();
396
397 while (thiscol != endcol) {
398
399 // this memory is created but never destroyed
400 // we're also not doing any error checking to make sure we didn't
401 // run out of memory
402 collectserver *cserver = new collectserver();
403 gdbmclass *gdbmhandler = new gdbmclass();
404 mgsearchclass *mgsearch = new mgsearchclass();
405
406 // add a null filter
407 filterclass *filter = new filterclass();
408 cserver->add_filter (filter);
409
410 // add a browse filter
411 browsefilterclass *browsefilter = new browsefilterclass();
412 browsefilter->set_gdbmptr (gdbmhandler);
413 cserver->add_filter (browsefilter);
414
415 // add a query filter
416 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
417 queryfilter->set_gdbmptr (gdbmhandler);
418 queryfilter->set_mgsearchptr (mgsearch);
419 cserver->add_filter (queryfilter);
420
421 // add an mg and gdbm source
422 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass();
423 mggdbmsource->set_gdbmptr (gdbmhandler);
424 mggdbmsource->set_mgsearchptr (mgsearch);
425 cserver->add_source (mggdbmsource);
426
427 // inform collection server and everything it contains about
428 // its collection name
429 cserver->configure ("collection", *thiscol);
430
431 nproto.add_collectserver (cserver);
432
433 thiscol ++;
434 }
435
436 // add the protocol to the receptionist
437 recpt.add_protocol (&nproto);
438
439 // add other converters
440 utf8inconvertclass *utf8inconvert = new utf8inconvertclass();
441 utf8outconvertclass *utf8outconvert = new utf8outconvertclass();
442 recpt.add_converter ("u", utf8inconvert, utf8outconvert);
443
444 mapinconvertclass *gbinconvert = new mapinconvertclass();
445 gbinconvert->setmapfile (gsdl_gsdlhome, "gbku", 0x25a1);
446 mapoutconvertclass *gboutconvert = new mapoutconvertclass();
447 gboutconvert->setmapfile (gsdl_gsdlhome, "ugbk", 0xa1f5);
448 recpt.add_converter ("g", gbinconvert, gboutconvert);
449
450 // the list of actions.
451 statusaction *astatusaction = new statusaction();
452 astatusaction->set_receptionist (&recpt);
453 recpt.add_action (astatusaction);
454
455 pageaction *apageaction = new pageaction();
456 apageaction->set_receptionist (&recpt);
457 recpt.add_action (apageaction);
458
459 pingaction *apingaction = new pingaction();
460 recpt.add_action (apingaction);
461
462 tipaction *atipaction = new tipaction();
463 recpt.add_action (atipaction);
464
465 queryaction *aqueryaction = new queryaction();
466 aqueryaction->set_receptionist (&recpt);
467 recpt.add_action (aqueryaction);
468
469 documentaction *adocumentaction = new documentaction();
470 adocumentaction->set_receptionist (&recpt);
471 recpt.add_action (adocumentaction);
472
473 usersaction *ausersaction = new usersaction();
474 recpt.add_action (ausersaction);
475
476 extlinkaction *anextlinkaction = new extlinkaction();
477 recpt.add_action (anextlinkaction);
478
479 collectoraction *acollectoraction = new collectoraction();
480 acollectoraction->set_receptionist (&recpt);
481 recpt.add_action (acollectoraction);
482
483 authenaction *aauthenaction = new authenaction();
484 aauthenaction->set_receptionist(&recpt);
485 recpt.add_action (aauthenaction);
486
487 delhistoryaction *adelhistoryaction = new delhistoryaction();
488 recpt.add_action (adelhistoryaction);
489
490
491 // list of browsers
492 vlistbrowserclass *avlistbrowserclass = new vlistbrowserclass();
493 recpt.add_browser (avlistbrowserclass);
494 recpt.setdefaultbrowser ("VList");
495
496 hlistbrowserclass *ahlistbrowserclass = new hlistbrowserclass();
497 recpt.add_browser (ahlistbrowserclass);
498
499 datelistbrowserclass *adatelistbrowserclass = new datelistbrowserclass();
500 recpt.add_browser (adatelistbrowserclass);
501
502 invbrowserclass *ainvbrowserclass = new invbrowserclass();
503 recpt.add_browser (ainvbrowserclass);
504
505 pagedbrowserclass *apagedbrowserclass = new pagedbrowserclass();
506 recpt.add_browser (apagedbrowserclass);
507
508 htmlbrowserclass *ahtmlbrowserclass = new htmlbrowserclass();
509 recpt.add_browser (ahtmlbrowserclass);
510
511 // set defaults
512 recpt.configure ("gsdlhome", gsdl_gsdlhome);
513 recpt.configure ("collection", collection);
514
515 int maxrequests = 1;
516 text_tset seenhomes;
517 this_info = gsdl_collectinfo.begin();
518
519 // configure any collections with gsdlhome (or gdbmhome)
520 // different from the default
521 while (this_info != end_info) {
522 if (((*this_info).second.gsdl_gsdlhome != gsdl_gsdlhome) ||
523 ((*this_info).second.gsdl_gdbmhome != gsdl_gdbmhome) &&
524 (seenhomes.find ((*this_info).second.gsdl_gsdlhome +
525 (*this_info).second.gsdl_gdbmhome) == seenhomes.end())) {
526 text_tarray tmpconf;
527 tmpconf.push_back ((*this_info).first);
528 tmpconf.push_back ((*this_info).second.gsdl_gsdlhome);
529 tmpconf.push_back ((*this_info).second.gsdl_gdbmhome);
530 recpt.configure ("collectinfo", tmpconf);
531 seenhomes.insert ((*this_info).second.gsdl_gsdlhome +
532 (*this_info).second.gsdl_gdbmhome);
533 }
534 this_info ++;
535 }
536
537 // read in config files of each gsdlhome (in no particular order)
538 // those read in last will override those read earlier
539 // collections being used together in this way should be
540 // careful not to have main.cfg files that might
541 // screw with each other.
542 text_tset::const_iterator thome = gsdlhomes.begin();
543 text_tset::const_iterator ehome = gsdlhomes.end();
544 while (thome != ehome) {
545 if (!main_cfg_read (recpt, *thome, collection)) {
546 // couldn't find the main configuration file
547 page_errormaincfg (*thome, collection);
548 return 0;
549 }
550 thome ++;
551 }
552
553 // w32server relies on gwcgi being set to "gw"
554 recpt.configure ("gwcgi", "gw");
555
556 // initialise the library software
557 if (!recpt.init(cerr)) {
558 // an error occurred during the initialisation
559 page_errorinit(gsdl_gsdlhome);
560 return 0;
561 }
562
563 // get memory information
564 MEMORYSTATUS memstatus;
565 memstatus.dwLength = sizeof(MEMORYSTATUS);
566 GlobalMemoryStatus(&memstatus);
567 baseavailvirtual = memstatus.dwAvailVirtual; // save for later comparison
568
569 return 1;
570}
571
572
573static void rememberpref (char *tailstr) {
574
575 // gsdl_enterlib = tailstr;
576}
577
578
579static void send_file_from_disk(char *filename,
580 RequestInfoT *RInfo,
581 RequestFieldsT *RFields)
582{
583 int len, nr; char *tail, *kind;
584 FILE *thefile;
585
586 // select appropriate mime type from file name
587 len = strlen(filename);
588 while (len > 0 && filename[len-1] != '.') len--;
589 kind = "unknown";
590 if (len > 0) {
591 tail = &filename[len];
592 if (stricmp("gif",tail) == 0) kind = "image/gif";
593 else if (stricmp("jpg",tail) == 0 ||
594 stricmp("jpeg",tail) == 0) kind = "image/jpeg";
595 else if (stricmp("htm",tail) == 0 ||
596 stricmp("html",tail) == 0) kind = "text/html";
597 }
598
599 // set up file name
600 text_t filenamet = text_t(gsdl_gsdlhome) + filename;
601 text_t::iterator here = filenamet.begin();
602 text_t::iterator end = filenamet.end();
603 while (here != end) {
604 if (*here == '/') *here = '\\';
605 here ++;
606 }
607
608 filename = filenamet.getcstr();
609
610 // try to open it
611 thefile = fopen(filename, "rb");
612 if (thefile == NULL) {
613 log_message("file not found\n");
614 send_retrieve_error(404, "File not found",
615 "Could not find the local file requested", RInfo);
616 return;
617 }
618
619 char buffer[2048];
620 // send back required information
621 if (send_header(kind, RInfo) >= 0) {
622 if (strcmpi(RFields->MethodStr, "HEAD") != 0) {
623 for (;;) {
624 nr = fread(buffer, 1, 2048, thefile);
625 if (nr <= 0) break;
626 if (SendData(RInfo->ClientSocket,
627 (BYTE *)buffer, nr,
628 RInfo->ThreadNum) < 0) break;
629 }
630 }
631 }
632 fclose(thefile);
633}
634
635static void handle_library_request(char *TailStr, RequestInfoT *RInfo,
636 RequestFieldsT *RequestFields) {
637 // check for a "?" at the start of the tail string
638 if (*TailStr == '?') TailStr++;
639
640 outconvertclass text_t2ascii;
641
642 // parse the cgi arguments and produce the resulting page if there
643 // has been no errors so far
644 cgiargsclass args;
645 text_tmap empty; // don't use this (it's for fastcgi on unix)
646 if (!recpt.parse_cgi_args (TailStr, args, cerr, empty)) {
647 page_errorparseargs(gsdl_gsdlhome);
648 return;
649 }
650
651 // produce cgi header
652 response_t response;
653 text_t response_data;
654
655 recpt.get_cgihead_info (args, response, response_data, cerr, empty);
656
657 if (response == location) {
658 // location response
659 response_data = "@" + recpt.expandmacros (response_data, args, cerr);
660 char *response_data_c = response_data.getcstr();
661 send_header(response_data_c, RInfo);
662 delete response_data_c;
663 return;
664 } else if (response == content) {
665 // content response
666 char *response_data_c = response_data.getcstr();
667 if (send_header(response_data_c, RInfo) < 0) {
668 delete response_data_c;
669 return;
670 }
671 delete response_data_c;
672 } else {
673 // unknown response
674 cerr << "Error: get_cgihead_info returned an unknown response type.\n";
675 return;
676 }
677
678 textstream.tsbreset();
679 textstream.setrequestinfo (RInfo);
680
681 if (!recpt.produce_content (args, cout, cerr)) {
682 page_errorcgipage(gsdl_gsdlhome);
683 return;
684 }
685 recpt.log_cgi_args (args, cerr, empty);
686
687 cout << flush;
688 cerr << flush;
689
690 libaccessnum++;
691}
692
693static void handle_server_request(char *initialTailStr,
694 RequestInfoT *RequestInfo,
695 RequestFieldsT *RequestFields) {
696 char tmpstr[1024];
697 char tailstr[MAX_URL_SIZE];
698
699 // do any url adjustments necessary
700 if (strcmp(initialTailStr, "/") == 0) {
701 strcpy (tailstr, "/cgi-bin/gw");
702 } else strcpy (tailstr, initialTailStr);
703
704 // test to see if this is a library request or a local
705 // file request
706 if ((strncmp(tailstr, "/cgi-bin/gw", 11) == 0) &&
707 ((tailstr[11] == '\0') || (tailstr[11] == '?'))) {
708 // library request
709
710 // log the difference in access times
711 DWORD thislibaccesstime = GetTickCount();
712 if (gsdl_keep_log||gsdl_show_console) {
713 sprintf(tmpstr, "DELTA LIB ACCESS TIME: %i\n", (int)(thislibaccesstime - lastlibaccesstime));
714 log_message (tmpstr);
715 }
716 lastlibaccesstime = thislibaccesstime;
717
718 // log this request
719 if (gsdl_keep_log||gsdl_show_console) {
720 sprintf (tmpstr, "LOCAL LIB: %s\n", tailstr);
721 log_message (tmpstr);
722 }
723
724 handle_library_request (&tailstr[11], RequestInfo, RequestFields);
725
726 // remember the preferences
727 rememberpref (tailstr);
728
729 // log memory information
730 if (gsdl_keep_log||gsdl_show_console) {
731 MEMORYSTATUS memstatus;
732 memstatus.dwLength = sizeof(MEMORYSTATUS);
733 GlobalMemoryStatus(&memstatus);
734 sprintf (tmpstr, "BDELTA AVAIL VIRTUAL: %i K\n",
735 (int)((baseavailvirtual - memstatus.dwAvailVirtual)/1024));
736 log_message (tmpstr);
737 }
738
739 } else {
740 // local file
741 if (gsdl_keep_log||gsdl_show_console) {
742 sprintf (tmpstr, "LOCAL FILE: %s\n", tailstr);
743 log_message (tmpstr);
744 }
745 send_file_from_disk (tailstr, RequestInfo, RequestFields);
746 }
747}
748
749static void fix_prefix(char *dest, char *pref, char *suff)
750{
751 strcpy(dest,pref);
752 if (*suff != '/') strcat(dest,"/");
753 if (strlen(dest) + strlen(suff) + 1 > MAX_URL_SIZE)
754 strcpy(dest,"http://gsdl/name-too-long");
755 else
756 strcat(dest,suff);
757}
758
759int ExamineURIStr(char *URIStr,RequestInfoT *RequestInfo,
760 RequestFieldsT *RequestFields)
761{
762 char *protocol, *machine, *rest; int port;
763 char URICopyA[MAX_URL_SIZE], URICopyB[MAX_URL_SIZE];
764 strcpy(URICopyA,URIStr);
765
766 if (parse_url(URICopyA,&protocol,&machine,&port,&rest)!=http_ok) {
767 /* Alter local file request to address 'gsdl' */
768 fix_prefix(URICopyB, "http://gsdl", URIStr);
769 URIStr = URICopyB;
770 strcpy(URICopyA, URICopyB);
771 parse_url(URICopyA,&protocol,&machine,&port,&rest);
772 }
773
774 if (strncmp(machine, "gsdl", 5) == 0) {
775 // a local file request
776 handle_server_request(rest, RequestInfo, RequestFields);
777
778 } else {
779 send_retrieve_error(404, "File not found",
780 "Could not find the local file requested", RequestInfo);
781 }
782
783 return 1;
784}
Note: See TracBrowser for help on using the repository browser.