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

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

lots of stuff

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