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

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

Added collector to local library (even though it won't work properly yet)

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 22.1 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
359 // collection specific mode
360 text_t collection = "";
361 text_tset gsdlhomes;
362 text_tarray collections;
363 colinfo_tmap::const_iterator this_info = gsdl_collectinfo.begin();
364 colinfo_tmap::const_iterator end_info = gsdl_collectinfo.end();
365
366 // note the current time
367 lastlibaccesstime = GetTickCount();
368
369 // before we do the init we should make sure
370 // that we can find the relevant directories
371 if (!checkdir (gsdl_gsdlhome + "\\")) return 0;
372 if (!checkdir (gsdl_gsdlhome + "\\macros\\")) return 0;
373
374 if (collection.empty()) {
375
376 // get all collections from each gsdlhome (this relies
377 // on there not being more than one collection with the same
378 // name)
379 read_dir (filename_cat (gsdl_gsdlhome, "collect"), collections);
380 gsdlhomes.insert (gsdl_gsdlhome);
381 while (this_info != end_info) {
382 if (gsdlhomes.find ((*this_info).second.gsdl_gsdlhome) == gsdlhomes.end()) {
383 read_dir (filename_cat ((*this_info).second.gsdl_gsdlhome, "collect"), collections);
384 gsdlhomes.insert ((*this_info).second.gsdl_gsdlhome);
385 }
386 this_info ++;
387 }
388 } else {
389 collections.push_back (collection);
390 }
391
392 text_tarray::const_iterator thiscol = collections.begin();
393 text_tarray::const_iterator endcol = collections.end();
394
395 while (thiscol != endcol) {
396
397 // this memory is created but never destroyed
398 // we're also not doing any error checking to make sure we didn't
399 // run out of memory
400 collectserver *cserver = new collectserver();
401 gdbmclass *gdbmhandler = new gdbmclass();
402 mgsearchclass *mgsearch = new mgsearchclass();
403
404 // add a null filter
405 filterclass *filter = new filterclass();
406 cserver->add_filter (filter);
407
408 // add a browse filter
409 browsefilterclass *browsefilter = new browsefilterclass();
410 browsefilter->set_gdbmptr (gdbmhandler);
411 cserver->add_filter (browsefilter);
412
413 // add a query filter
414 mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
415 queryfilter->set_gdbmptr (gdbmhandler);
416 queryfilter->set_mgsearchptr (mgsearch);
417 cserver->add_filter (queryfilter);
418
419 // add an mg and gdbm source
420 mggdbmsourceclass *mggdbmsource = new mggdbmsourceclass();
421 mggdbmsource->set_gdbmptr (gdbmhandler);
422 mggdbmsource->set_mgsearchptr (mgsearch);
423 cserver->add_source (mggdbmsource);
424
425 // inform collection server and everything it contains about
426 // its collection name
427 cserver->configure ("collection", *thiscol);
428
429 nproto.add_collectserver (cserver);
430
431 thiscol ++;
432 }
433
434 // add the protocol to the receptionist
435 recpt.add_protocol (&nproto);
436
437 // add other converters
438 utf8inconvertclass *utf8inconvert = new utf8inconvertclass();
439 utf8outconvertclass *utf8outconvert = new utf8outconvertclass();
440 recpt.add_converter ("u", utf8inconvert, utf8outconvert);
441
442 mapinconvertclass *gbinconvert = new mapinconvertclass();
443 gbinconvert->setmapfile (gsdl_gsdlhome, "gbku", 0x25a1);
444 mapoutconvertclass *gboutconvert = new mapoutconvertclass();
445 gboutconvert->setmapfile (gsdl_gsdlhome, "ugbk", 0xa1f5);
446 recpt.add_converter ("g", gbinconvert, gboutconvert);
447
448 // the list of actions.
449 statusaction *astatusaction = new statusaction();
450 astatusaction->set_receptionist (&recpt);
451 recpt.add_action (astatusaction);
452
453 pageaction *apageaction = new pageaction();
454 apageaction->set_receptionist (&recpt);
455 recpt.add_action (apageaction);
456
457 pingaction *apingaction = new pingaction();
458 recpt.add_action (apingaction);
459
460 tipaction *atipaction = new tipaction();
461 recpt.add_action (atipaction);
462
463 queryaction *aqueryaction = new queryaction();
464 aqueryaction->set_receptionist (&recpt);
465 recpt.add_action (aqueryaction);
466
467 documentaction *adocumentaction = new documentaction();
468 adocumentaction->set_receptionist (&recpt);
469 recpt.add_action (adocumentaction);
470
471 usersaction *ausersaction = new usersaction();
472 recpt.add_action (ausersaction);
473
474 extlinkaction *anextlinkaction = new extlinkaction();
475 recpt.add_action (anextlinkaction);
476
477 collectoraction *acollectoraction = new collectoraction();
478 acollectoraction->set_receptionist (&recpt);
479 recpt.add_action (acollectoraction);
480
481 authenaction *aauthenaction = new authenaction();
482 aauthenaction->set_receptionist(&recpt);
483 recpt.add_action (aauthenaction);
484
485 delhistoryaction *adelhistoryaction = new delhistoryaction();
486 recpt.add_action (adelhistoryaction);
487
488
489 // list of browsers
490 vlistbrowserclass *avlistbrowserclass = new vlistbrowserclass();
491 recpt.add_browser (avlistbrowserclass);
492 recpt.setdefaultbrowser ("VList");
493
494 hlistbrowserclass *ahlistbrowserclass = new hlistbrowserclass();
495 recpt.add_browser (ahlistbrowserclass);
496
497 datelistbrowserclass *adatelistbrowserclass = new datelistbrowserclass();
498 recpt.add_browser (adatelistbrowserclass);
499
500 invbrowserclass *ainvbrowserclass = new invbrowserclass();
501 recpt.add_browser (ainvbrowserclass);
502
503 pagedbrowserclass *apagedbrowserclass = new pagedbrowserclass();
504 recpt.add_browser (apagedbrowserclass);
505
506 htmlbrowserclass *ahtmlbrowserclass = new htmlbrowserclass();
507 recpt.add_browser (ahtmlbrowserclass);
508
509 // set defaults
510 recpt.configure ("gsdlhome", gsdl_gsdlhome);
511 recpt.configure ("collection", collection);
512
513 int maxrequests = 1;
514 text_tset seenhomes;
515 this_info = gsdl_collectinfo.begin();
516
517 // configure any collections with gsdlhome (or gdbmhome)
518 // different from the default
519 while (this_info != end_info) {
520 if (((*this_info).second.gsdl_gsdlhome != gsdl_gsdlhome) ||
521 ((*this_info).second.gsdl_gdbmhome != gsdl_gdbmhome) &&
522 (seenhomes.find ((*this_info).second.gsdl_gsdlhome +
523 (*this_info).second.gsdl_gdbmhome) == seenhomes.end())) {
524 text_tarray tmpconf;
525 tmpconf.push_back ((*this_info).first);
526 tmpconf.push_back ((*this_info).second.gsdl_gsdlhome);
527 tmpconf.push_back ((*this_info).second.gsdl_gdbmhome);
528 recpt.configure ("collectinfo", tmpconf);
529 seenhomes.insert ((*this_info).second.gsdl_gsdlhome +
530 (*this_info).second.gsdl_gdbmhome);
531 }
532 this_info ++;
533 }
534
535 // read in config files of each gsdlhome (in no particular order)
536 // those read in last will override those read earlier
537 // collections being used together in this way should be
538 // careful not to have main.cfg files that might
539 // screw with each other.
540 text_tset::const_iterator thome = gsdlhomes.begin();
541 text_tset::const_iterator ehome = gsdlhomes.end();
542 while (thome != ehome) {
543 if (!main_cfg_read (recpt, *thome, collection)) {
544 // couldn't find the main configuration file
545 page_errormaincfg (*thome, collection);
546 return 0;
547 }
548 thome ++;
549 }
550
551 // w32server relies on gwcgi being set to "gw"
552 recpt.configure ("gwcgi", "gw");
553
554 // initialise the library software
555 if (!recpt.init(cerr)) {
556 // an error occurred during the initialisation
557 page_errorinit(gsdl_gsdlhome);
558 return 0;
559 }
560
561 // get memory information
562 MEMORYSTATUS memstatus;
563 memstatus.dwLength = sizeof(MEMORYSTATUS);
564 GlobalMemoryStatus(&memstatus);
565 baseavailvirtual = memstatus.dwAvailVirtual; // save for later comparison
566
567 return 1;
568}
569
570
571static void rememberpref (char *tailstr) {
572
573 // gsdl_enterlib = tailstr;
574}
575
576
577static void send_file_from_disk(char *filename,
578 RequestInfoT *RInfo,
579 RequestFieldsT *RFields)
580{
581 int len, nr; char *tail, *kind;
582 FILE *thefile;
583
584 // select appropriate mime type from file name
585 len = strlen(filename);
586 while (len > 0 && filename[len-1] != '.') len--;
587 kind = "unknown";
588 if (len > 0) {
589 tail = &filename[len];
590 if (stricmp("gif",tail) == 0) kind = "image/gif";
591 else if (stricmp("jpg",tail) == 0 ||
592 stricmp("jpeg",tail) == 0) kind = "image/jpeg";
593 else if (stricmp("htm",tail) == 0 ||
594 stricmp("html",tail) == 0) kind = "text/html";
595 }
596
597 // set up file name
598 text_t filenamet = text_t(gsdl_gsdlhome) + filename;
599 text_t::iterator here = filenamet.begin();
600 text_t::iterator end = filenamet.end();
601 while (here != end) {
602 if (*here == '/') *here = '\\';
603 here ++;
604 }
605
606 filename = filenamet.getcstr();
607
608 // try to open it
609 thefile = fopen(filename, "rb");
610 if (thefile == NULL) {
611 log_message("file not found\n");
612 send_retrieve_error(404, "File not found",
613 "Could not find the local file requested", RInfo);
614 return;
615 }
616
617 char buffer[2048];
618 // send back required information
619 if (send_header(kind, RInfo) >= 0) {
620 if (strcmpi(RFields->MethodStr, "HEAD") != 0) {
621 for (;;) {
622 nr = fread(buffer, 1, 2048, thefile);
623 if (nr <= 0) break;
624 if (SendData(RInfo->ClientSocket,
625 (BYTE *)buffer, nr,
626 RInfo->ThreadNum) < 0) break;
627 }
628 }
629 }
630 fclose(thefile);
631}
632
633static void handle_library_request(char *TailStr, RequestInfoT *RInfo,
634 RequestFieldsT *RequestFields) {
635 // check for a "?" at the start of the tail string
636 if (*TailStr == '?') TailStr++;
637
638 outconvertclass text_t2ascii;
639
640 // parse the cgi arguments and produce the resulting page if there
641 // has been no errors so far
642 cgiargsclass args;
643 text_tmap empty; // don't use this (it's for fastcgi on unix)
644 if (!recpt.parse_cgi_args (TailStr, args, cerr, empty)) {
645 page_errorparseargs(gsdl_gsdlhome);
646 return;
647 }
648
649 // produce cgi header
650 response_t response;
651 text_t response_data;
652
653 recpt.get_cgihead_info (args, response, response_data, cerr, empty);
654
655 if (response == location) {
656 // location response
657 response_data = "@" + recpt.expandmacros (response_data, args, cerr);
658 char *response_data_c = response_data.getcstr();
659 send_header(response_data_c, RInfo);
660 delete response_data_c;
661 return;
662 } else if (response == content) {
663 // content response
664 char *response_data_c = response_data.getcstr();
665 if (send_header(response_data_c, RInfo) < 0) {
666 delete response_data_c;
667 return;
668 }
669 delete response_data_c;
670 } else {
671 // unknown response
672 cerr << "Error: get_cgihead_info returned an unknown response type.\n";
673 return;
674 }
675
676 textstream.tsbreset();
677 textstream.setrequestinfo (RInfo);
678
679 if (!recpt.produce_content (args, cout, cerr)) {
680 page_errorcgipage(gsdl_gsdlhome);
681 return;
682 }
683 recpt.log_cgi_args (args, cerr, empty);
684
685 cout << flush;
686 cerr << flush;
687
688 libaccessnum++;
689}
690
691static void handle_server_request(char *initialTailStr,
692 RequestInfoT *RequestInfo,
693 RequestFieldsT *RequestFields) {
694 char tmpstr[1024];
695 char tailstr[MAX_URL_SIZE];
696
697 // do any url adjustments necessary
698 if (strcmp(initialTailStr, "/") == 0) {
699 strcpy (tailstr, "/cgi-bin/gw");
700 } else strcpy (tailstr, initialTailStr);
701
702 // test to see if this is a library request or a local
703 // file request
704 if ((strncmp(tailstr, "/cgi-bin/gw", 11) == 0) &&
705 ((tailstr[11] == '\0') || (tailstr[11] == '?'))) {
706 // library request
707
708 // log the difference in access times
709 DWORD thislibaccesstime = GetTickCount();
710 if (gsdl_keep_log||gsdl_show_console) {
711 sprintf(tmpstr, "DELTA LIB ACCESS TIME: %i\n", (int)(thislibaccesstime - lastlibaccesstime));
712 log_message (tmpstr);
713 }
714 lastlibaccesstime = thislibaccesstime;
715
716 // log this request
717 if (gsdl_keep_log||gsdl_show_console) {
718 sprintf (tmpstr, "LOCAL LIB: %s\n", tailstr);
719 log_message (tmpstr);
720 }
721
722 handle_library_request (&tailstr[11], RequestInfo, RequestFields);
723
724 // remember the preferences
725 rememberpref (tailstr);
726
727 // log memory information
728 if (gsdl_keep_log||gsdl_show_console) {
729 MEMORYSTATUS memstatus;
730 memstatus.dwLength = sizeof(MEMORYSTATUS);
731 GlobalMemoryStatus(&memstatus);
732 sprintf (tmpstr, "BDELTA AVAIL VIRTUAL: %i K\n",
733 (int)((baseavailvirtual - memstatus.dwAvailVirtual)/1024));
734 log_message (tmpstr);
735 }
736
737 } else {
738 // local file
739 if (gsdl_keep_log||gsdl_show_console) {
740 sprintf (tmpstr, "LOCAL FILE: %s\n", tailstr);
741 log_message (tmpstr);
742 }
743 send_file_from_disk (tailstr, RequestInfo, RequestFields);
744 }
745}
746
747static void fix_prefix(char *dest, char *pref, char *suff)
748{
749 strcpy(dest,pref);
750 if (*suff != '/') strcat(dest,"/");
751 if (strlen(dest) + strlen(suff) + 1 > MAX_URL_SIZE)
752 strcpy(dest,"http://gsdl/name-too-long");
753 else
754 strcat(dest,suff);
755}
756
757int ExamineURIStr(char *URIStr,RequestInfoT *RequestInfo,
758 RequestFieldsT *RequestFields)
759{
760 char *protocol, *machine, *rest; int port;
761 char URICopyA[MAX_URL_SIZE], URICopyB[MAX_URL_SIZE];
762 strcpy(URICopyA,URIStr);
763
764 if (parse_url(URICopyA,&protocol,&machine,&port,&rest)!=http_ok) {
765 /* Alter local file request to address 'gsdl' */
766 fix_prefix(URICopyB, "http://gsdl", URIStr);
767 URIStr = URICopyB;
768 strcpy(URICopyA, URICopyB);
769 parse_url(URICopyA,&protocol,&machine,&port,&rest);
770 }
771
772 if (strncmp(machine, "gsdl", 5) == 0) {
773 // a local file request
774 handle_server_request(rest, RequestInfo, RequestFields);
775
776 } else {
777 send_retrieve_error(404, "File not found",
778 "Could not find the local file requested", RequestInfo);
779 }
780
781 return 1;
782}
Note: See TracBrowser for help on using the repository browser.