source: branches/New_Config_Format-branch/gsdl/src/w32server/cgiwrapper.cpp@ 1279

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

merged changes to trunk into New_Config_Format branch

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