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

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

Made a few minor changes to get the local library compiling under VC++ 6.0
using the built-in STL (i.e. without the GSDL_USE_IOS_H pre-processor
definition set).

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