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

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

Another small change so that the local library compiles without the
GSDL_USE_IOS_H flag. It appears that rdbuf was a little different in
the old iostream libraries than in the new.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 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 recpt.add_action (apageaction);
429
430 pingaction *apingaction = new pingaction();
431 recpt.add_action (apingaction);
432
433 tipaction *atipaction = new tipaction();
434 recpt.add_action (atipaction);
435
436 queryaction *aqueryaction = new queryaction();
437 recpt.add_action (aqueryaction);
438
439 documentaction *adocumentaction = new documentaction();
440 recpt.add_action (adocumentaction);
441
442 usersaction *ausersaction = new usersaction();
443 recpt.add_action (ausersaction);
444
445 extlinkaction *anextlinkaction = new extlinkaction();
446 recpt.add_action (anextlinkaction);
447
448 buildaction *abuildaction = new buildaction();
449 abuildaction->set_receptionist (&recpt);
450 recpt.add_action (abuildaction);
451
452 authenaction *aauthenaction = new authenaction();
453 aauthenaction->set_receptionist(&recpt);
454 recpt.add_action (aauthenaction);
455
456 delhistoryaction *adelhistoryaction = new delhistoryaction();
457 recpt.add_action (adelhistoryaction);
458
459
460 // list of browsers
461 vlistbrowserclass *avlistbrowserclass = new vlistbrowserclass();
462 recpt.add_browser (avlistbrowserclass);
463 recpt.setdefaultbrowser ("VList");
464
465 hlistbrowserclass *ahlistbrowserclass = new hlistbrowserclass();
466 recpt.add_browser (ahlistbrowserclass);
467
468 datelistbrowserclass *adatelistbrowserclass = new datelistbrowserclass();
469 recpt.add_browser (adatelistbrowserclass);
470
471 invbrowserclass *ainvbrowserclass = new invbrowserclass();
472 recpt.add_browser (ainvbrowserclass);
473
474 pagedbrowserclass *apagedbrowserclass = new pagedbrowserclass();
475 recpt.add_browser (apagedbrowserclass);
476
477 htmlbrowserclass *ahtmlbrowserclass = new htmlbrowserclass();
478 recpt.add_browser (ahtmlbrowserclass);
479
480 // set defaults
481 recpt.configure ("gsdlhome", gsdl_gsdlhome);
482 recpt.configure ("collection", collection);
483
484 int maxrequests = 1;
485 text_tset seenhomes;
486 this_info = gsdl_collectinfo.begin();
487
488 // configure any collections with gsdlhome (or gdbmhome)
489 // different from the default
490 while (this_info != end_info) {
491 if (((*this_info).second.gsdl_gsdlhome != gsdl_gsdlhome) ||
492 ((*this_info).second.gsdl_gdbmhome != gsdl_gdbmhome) &&
493 (seenhomes.find ((*this_info).second.gsdl_gsdlhome +
494 (*this_info).second.gsdl_gdbmhome) == seenhomes.end())) {
495 text_tarray tmpconf;
496 tmpconf.push_back ((*this_info).first);
497 tmpconf.push_back ((*this_info).second.gsdl_gsdlhome);
498 tmpconf.push_back ((*this_info).second.gsdl_gdbmhome);
499 recpt.configure ("collectinfo", tmpconf);
500 seenhomes.insert ((*this_info).second.gsdl_gsdlhome +
501 (*this_info).second.gsdl_gdbmhome);
502 }
503 this_info ++;
504 }
505
506 // read in config files of each gsdlhome (in no particular order)
507 // those read in last will override those read earlier
508 // collections being used together in this way should be
509 // careful not to have main.cfg files that might
510 // screw with each other.
511 text_tset::const_iterator thome = gsdlhomes.begin();
512 text_tset::const_iterator ehome = gsdlhomes.end();
513 while (thome != ehome) {
514 if (!main_cfg_read (recpt, *thome, collection)) {
515 // couldn't find the main configuration file
516 page_errormaincfg (*thome, collection);
517 return 0;
518 }
519 thome ++;
520 }
521
522 // w32server relies on gwcgi being set to "gw"
523 recpt.configure ("gwcgi", "gw");
524
525 // initialise the library software
526 if (!recpt.init(cerr)) {
527 // an error occurred during the initialisation
528 page_errorinit(gsdl_gsdlhome);
529 return 0;
530 }
531
532 // get memory information
533 MEMORYSTATUS memstatus;
534 memstatus.dwLength = sizeof(MEMORYSTATUS);
535 GlobalMemoryStatus(&memstatus);
536 baseavailvirtual = memstatus.dwAvailVirtual; // save for later comparison
537
538 return 1;
539}
540
541
542static void rememberpref (char *tailstr) {
543
544 // gsdl_enterlib = tailstr;
545}
546
547
548static void send_file_from_disk(char *filename,
549 RequestInfoT *RInfo,
550 RequestFieldsT *RFields)
551{
552 int len, nr; char *tail, *kind;
553 FILE *thefile;
554
555 // select appropriate mime type from file name
556 len = strlen(filename);
557 while (len > 0 && filename[len-1] != '.') len--;
558 kind = "unknown";
559 if (len > 0) {
560 tail = &filename[len];
561 if (stricmp("gif",tail) == 0) kind = "image/gif";
562 else if (stricmp("jpg",tail) == 0 ||
563 stricmp("jpeg",tail) == 0) kind = "image/jpeg";
564 else if (stricmp("htm",tail) == 0 ||
565 stricmp("html",tail) == 0) kind = "text/html";
566 }
567
568 // set up file name
569 text_t filenamet = text_t(gsdl_gsdlhome) + filename;
570 text_t::iterator here = filenamet.begin();
571 text_t::iterator end = filenamet.end();
572 while (here != end) {
573 if (*here == '/') *here = '\\';
574 here ++;
575 }
576
577 filename = filenamet.getcstr();
578
579 // try to open it
580 thefile = fopen(filename, "rb");
581 if (thefile == NULL) {
582 log_message("file not found\n");
583 send_retrieve_error(404, "File not found",
584 "Could not find the local file requested", RInfo);
585 return;
586 }
587
588 char buffer[2048];
589 // send back required information
590 if (send_header(kind, RInfo) >= 0) {
591 if (strcmpi(RFields->MethodStr, "HEAD") != 0) {
592 for (;;) {
593 nr = fread(buffer, 1, 2048, thefile);
594 if (nr <= 0) break;
595 if (SendData(RInfo->ClientSocket,
596 (BYTE *)buffer, nr,
597 RInfo->ThreadNum) < 0) break;
598 }
599 }
600 }
601 fclose(thefile);
602}
603
604static void handle_library_request(char *TailStr, RequestInfoT *RInfo,
605 RequestFieldsT *RequestFields) {
606 // check for a "?" at the start of the tail string
607 if (*TailStr == '?') TailStr++;
608
609 outconvertclass text_t2ascii;
610
611 // parse the cgi arguments and produce the resulting page if there
612 // has been no errors so far
613 cgiargsclass args;
614 text_tmap empty; // don't use this (it's for fastcgi on unix)
615 if (!recpt.parse_cgi_args (TailStr, args, cerr, empty)) {
616 page_errorparseargs(gsdl_gsdlhome);
617 return;
618 }
619
620 // produce cgi header
621 response_t response;
622 text_t response_data;
623
624 recpt.get_cgihead_info (args, response, response_data, cerr, empty);
625
626 if (response == location) {
627 // location response
628 response_data = "@" + recpt.expandmacros (response_data, args, cerr);
629 char *response_data_c = response_data.getcstr();
630 send_header(response_data_c, RInfo);
631 delete response_data_c;
632 return;
633 } else if (response == content) {
634 // content response
635 char *response_data_c = response_data.getcstr();
636 if (send_header(response_data_c, RInfo) < 0) {
637 delete response_data_c;
638 return;
639 }
640 delete response_data_c;
641 } else {
642 // unknown response
643 cerr << "Error: get_cgihead_info returned an unknown response type.\n";
644 return;
645 }
646
647 textstream.tsbreset();
648 textstream.setrequestinfo (RInfo);
649
650 if (!recpt.produce_content (args, cout, cerr)) {
651 page_errorcgipage(gsdl_gsdlhome);
652 return;
653 }
654 recpt.log_cgi_args (args, cerr, empty);
655
656 cout << flush;
657 cerr << flush;
658
659 libaccessnum++;
660}
661
662static void handle_server_request(char *initialTailStr,
663 RequestInfoT *RequestInfo,
664 RequestFieldsT *RequestFields) {
665 char tmpstr[1024];
666 char tailstr[MAX_URL_SIZE];
667
668 // do any url adjustments necessary
669 if (strcmp(initialTailStr, "/") == 0) {
670 strcpy (tailstr, "/cgi-bin/gw");
671 } else strcpy (tailstr, initialTailStr);
672
673 // test to see if this is a library request or a local
674 // file request
675 if ((strncmp(tailstr, "/cgi-bin/gw", 11) == 0) &&
676 ((tailstr[11] == '\0') || (tailstr[11] == '?'))) {
677 // library request
678
679 // log the difference in access times
680 DWORD thislibaccesstime = GetTickCount();
681 if (gsdl_keep_log||gsdl_show_console) {
682 sprintf(tmpstr, "DELTA LIB ACCESS TIME: %i\n", (int)(thislibaccesstime - lastlibaccesstime));
683 log_message (tmpstr);
684 }
685 lastlibaccesstime = thislibaccesstime;
686
687 // log this request
688 if (gsdl_keep_log||gsdl_show_console) {
689 sprintf (tmpstr, "LOCAL LIB: %s\n", tailstr);
690 log_message (tmpstr);
691 }
692
693 handle_library_request (&tailstr[11], RequestInfo, RequestFields);
694
695 // remember the preferences
696 rememberpref (tailstr);
697
698 // log memory information
699 if (gsdl_keep_log||gsdl_show_console) {
700 MEMORYSTATUS memstatus;
701 memstatus.dwLength = sizeof(MEMORYSTATUS);
702 GlobalMemoryStatus(&memstatus);
703 sprintf (tmpstr, "BDELTA AVAIL VIRTUAL: %i K\n",
704 (int)((baseavailvirtual - memstatus.dwAvailVirtual)/1024));
705 log_message (tmpstr);
706 }
707
708 } else {
709 // local file
710 if (gsdl_keep_log||gsdl_show_console) {
711 sprintf (tmpstr, "LOCAL FILE: %s\n", tailstr);
712 log_message (tmpstr);
713 }
714 send_file_from_disk (tailstr, RequestInfo, RequestFields);
715 }
716}
717
718static void fix_prefix(char *dest, char *pref, char *suff)
719{
720 strcpy(dest,pref);
721 if (*suff != '/') strcat(dest,"/");
722 if (strlen(dest) + strlen(suff) + 1 > MAX_URL_SIZE)
723 strcpy(dest,"http://gsdl/name-too-long");
724 else
725 strcat(dest,suff);
726}
727
728int ExamineURIStr(char *URIStr,RequestInfoT *RequestInfo,
729 RequestFieldsT *RequestFields)
730{
731 char *protocol, *machine, *rest; int port;
732 char URICopyA[MAX_URL_SIZE], URICopyB[MAX_URL_SIZE];
733 strcpy(URICopyA,URIStr);
734
735 if (parse_url(URICopyA,&protocol,&machine,&port,&rest)!=http_ok) {
736 /* Alter local file request to address 'gsdl' */
737 fix_prefix(URICopyB, "http://gsdl", URIStr);
738 URIStr = URICopyB;
739 strcpy(URICopyA, URICopyB);
740 parse_url(URICopyA,&protocol,&machine,&port,&rest);
741 }
742
743 if (strncmp(machine, "gsdl", 5) == 0) {
744 // a local file request
745 handle_server_request(rest, RequestInfo, RequestFields);
746
747 } else {
748 send_retrieve_error(404, "File not found",
749 "Could not find the local file requested", RequestInfo);
750 }
751
752 return 1;
753}
Note: See TracBrowser for help on using the repository browser.