Annotation of libwww/Library/src/HTHome.c, revision 2.20
2.1 frystyk 1: /* HTHome.c
2.2 frystyk 2: ** ANCHOR TRANSLATIONS
2.1 frystyk 3: **
4: ** (c) COPYRIGHT MIT 1995.
5: ** Please first read the full copyright statement in the file COPYRIGH.
2.20 ! frystyk 6: ** @(#) $Id: HTHome.c,v 2.19 1996/07/02 22:54:29 frystyk Exp $
2.1 frystyk 7: **
8: ** Authors
9: ** TBL Tim Berners-Lee timbl@w3.org
10: ** JFG Jean-Francois Groff jfg@dxcern.cern.ch
11: ** DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu>
2.2 frystyk 12: ** HFN Henrik Frystyk
2.1 frystyk 13: ** History
14: ** 8 Jun 92 Telnet hopping prohibited as telnet is not secure TBL
15: ** 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. JFG
16: ** 6 Oct 92 Moved HTClientHost and HTlogfile into here. TBL
17: ** 17 Dec 92 Tn3270 added, bug fix. DD
18: ** 4 Feb 93 Access registration, Search escapes bad chars TBL
19: ** PARAMETERS TO HTSEARCH AND HTLOADRELATIVE CHANGED
20: ** 28 May 93 WAIS gateway explicit if no WAIS library linked in.
21: ** Dec 93 Bug change around, more reentrant, etc
22: ** 09 May 94 logfile renamed to HTlogfile to avoid clash with WAIS
2.13 frystyk 23: ** 8 Jul 94 Insulate free from _free structure element.
2.1 frystyk 24: ** Sep 95 Rewritten, HFN
25: ** Nov 95 Spawned from HTAccess.c
26: */
27:
28: /* Library include files */
29: #include "WWWLib.h"
2.2 frystyk 30: #include "WWWApp.h"
2.9 frystyk 31: #include "WWWCache.h"
32: #include "WWWRules.h"
2.1 frystyk 33: #include "HTHome.h" /* Implemented here */
34:
35: /* ------------------------------------------------------------------------- */
36:
37: /* Find Related Name
38: ** -----------------
39: ** Creates a string that can be used as a related name when
40: ** calling HTParse initially.
41: **
42: ** The code for this routine originates from the Linemode
43: ** browser and was moved here by howcome@w3.org
44: ** in order for all clients to take advantage.
2.18 frystyk 45: ** The string returned must be freed by the caller
2.1 frystyk 46: */
2.18 frystyk 47: PUBLIC char * HTGetCurrentDirectoryURL (void)
2.1 frystyk 48: {
49: char* default_default = NULL; /* Parse home relative to this */
2.16 frystyk 50: char * host = HTGetHostName();
2.1 frystyk 51: StrAllocCopy(default_default, "file://");
2.16 frystyk 52: if (host) {
2.1 frystyk 53: StrAllocCat(default_default, host);
2.16 frystyk 54: HT_FREE(host);
55: } else
2.1 frystyk 56: StrAllocCat(default_default, "localhost");
57: {
58: char wd[HT_MAX_PATH+1];
59:
2.14 frystyk 60: #ifdef HAVE_GETCWD /* System V variant SIGN CHANGED TBL 921006 !! */
61: char *result = (char *) getcwd(wd, sizeof(wd));
62: #else
2.12 frystyk 63: #ifdef HAVE_GETWD
64: char *result = (char *) getwd(wd);
65: #else
66: #error "This platform does not support neither getwd nor getcwd\n"
2.1 frystyk 67: char *result = NULL;
2.14 frystyk 68: #endif /* HAVE_GETWD */
2.12 frystyk 69: #endif /* HAVE_GETCWD */
2.1 frystyk 70: *(wd+HT_MAX_PATH) = '\0';
71: if (result) {
72: #ifdef VMS
73: /* convert directory name to Unix-style syntax */
74: char * disk = strchr (wd, ':');
75: char * dir = strchr (wd, '[');
76: if (disk) {
77: *disk = '\0';
78: StrAllocCat (default_default, "/"); /* needs delimiter */
79: StrAllocCat (default_default, wd);
80: }
81: if (dir) {
82: char *p;
83: *dir = '/'; /* Convert leading '[' */
84: for (p = dir ; *p != ']'; ++p)
85: if (*p == '.') *p = '/';
86: *p = '\0'; /* Cut on final ']' */
87: StrAllocCat (default_default, dir);
88: }
89: #else /* not VMS */
90: #ifdef WIN32
91: char * p = wd ; /* a colon */
92: StrAllocCat(default_default, "/");
93: while( *p != 0 ) {
94: if (*p == '\\') /* change to one true slash */
95: *p = '/' ;
96: p++;
97: }
98: StrAllocCat( default_default, wd);
99: #else /* not WIN32 */
100: StrAllocCat (default_default, wd);
101: #endif /* not WIN32 */
102: #endif /* not VMS */
103: }
104: }
105: StrAllocCat(default_default, "/default.html");
106: return default_default;
107: }
108:
109:
110: /* Generate the anchor for the home page
111: ** -------------------------------------
112: **
113: ** As it involves file access, this should only be done once
114: ** when the program first runs.
115: ** This is a default algorithm -- browser don't HAVE to use this.
116: ** But consistency betwen browsers is STRONGLY recommended!
117: **
118: ** Priority order is:
119: **
120: ** 1 WWW_HOME environment variable (logical name, etc)
121: ** 2 ~/WWW/default.html
122: ** 3 /usr/local/bin/default.html
123: ** 4 http://www.w3.org/default.html
124: **
125: */
126: PUBLIC HTParentAnchor * HTHomeAnchor (void)
127: {
128: char * my_home_document = NULL;
129: char * home = (char *) getenv(LOGICAL_DEFAULT);
130: char * ref;
131: HTParentAnchor * anchor;
132:
133: /* Someone telnets in, they get a special home */
134: if (home) {
135: StrAllocCopy(my_home_document, home);
136: } else if (HTLib_secure()) { /* Telnet server */
137: FILE * fp = fopen(REMOTE_POINTER, "r");
138: char * status;
139: if (fp) {
2.10 frystyk 140: if ((my_home_document = (char *) HT_MALLOC(HT_MAX_PATH)) == NULL)
141: HT_OUTOFMEM("my_home_document ");
2.1 frystyk 142: status = fgets(my_home_document, HT_MAX_PATH, fp);
143: if (!status) {
2.10 frystyk 144: HT_FREE(my_home_document);
2.1 frystyk 145: my_home_document = NULL;
146: }
147: fclose(fp);
148: }
149: if (!my_home_document) StrAllocCopy(my_home_document, REMOTE_ADDRESS);
150: }
151:
152: if (!my_home_document) {
153: FILE * fp = NULL;
154: char * home = (char *) getenv("HOME");
155: if (home) {
2.10 frystyk 156: if ((my_home_document = (char *) HT_MALLOC(strlen(home)+1+ strlen(PERSONAL_DEFAULT)+1)) == NULL)
157: HT_OUTOFMEM("HTLocalName");
2.1 frystyk 158: sprintf(my_home_document, "%s/%s", home, PERSONAL_DEFAULT);
159: fp = fopen(my_home_document, "r");
160: }
161:
162: if (!fp) {
163: StrAllocCopy(my_home_document, LOCAL_DEFAULT_FILE);
164: fp = fopen(my_home_document, "r");
165: }
166: if (fp) {
167: fclose(fp);
168: } else {
169: if (WWWTRACE)
2.12 frystyk 170: HTTrace("Home Anchor. No local home document in ~/%s or %s\n",
2.1 frystyk 171: PERSONAL_DEFAULT, LOCAL_DEFAULT_FILE);
2.10 frystyk 172: HT_FREE(my_home_document);
2.1 frystyk 173: my_home_document = NULL;
174: }
175: }
2.12 frystyk 176:
2.1 frystyk 177: ref = HTParse(my_home_document ? my_home_document :
178: HTLib_secure() ? REMOTE_ADDRESS : LAST_RESORT, "file:",
179: PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
180: if (my_home_document) {
181: if (WWWTRACE)
2.12 frystyk 182: HTTrace("Home Anchor. `%s\' used for custom home page as\n`%s\'\n",
2.1 frystyk 183: my_home_document, ref);
2.10 frystyk 184: HT_FREE(my_home_document);
2.1 frystyk 185: }
186: anchor = (HTParentAnchor*) HTAnchor_findAddress(ref);
2.10 frystyk 187: HT_FREE(ref);
2.1 frystyk 188: return anchor;
2.19 frystyk 189: }
190:
191: /*
192: ** Standard interface to libwww TRACE messages. Pass this function a
193: ** string of characters and it will set up the appropriate TRACE flags.
194: ** The shortnames for the trace messages are not as intuitive as they
195: ** could be :-(. The string must be null terminated
196: */
197: PUBLIC int HTSetTraceMessageMask (const char * shortnames)
198: {
199: #ifdef WWWTRACE
200: WWWTRACE = 0;
201: if (shortnames) {
202: char * ptr;
203: for(ptr=shortnames; *ptr; ptr++) {
204: switch (*ptr) {
205: case 'a': WWWTRACE |= SHOW_ANCHOR_TRACE; break;
206: case 'b': WWWTRACE |= SHOW_BIND_TRACE; break;
207: case 'c': WWWTRACE |= SHOW_CACHE_TRACE; break;
208: case 'g': WWWTRACE |= SHOW_SGML_TRACE; break;
209: case 'h': WWWTRACE |= SHOW_AUTH_TRACE; break;
210: case 'i': WWWTRACE |= SHOW_PICS_TRACE; break;
211: case 'l': WWWTRACE |= SHOW_APP_TRACE; break;
212: case 'o': WWWTRACE |= SHOW_CORE_TRACE; break;
213: case 'p': WWWTRACE |= SHOW_PROTOCOL_TRACE; break;
214: case 's': WWWTRACE |= SHOW_STREAM_TRACE; break;
215: case 't': WWWTRACE |= SHOW_THREAD_TRACE; break;
216: case 'u': WWWTRACE |= SHOW_URI_TRACE; break;
217: default:
218: if (WWWTRACE) HTTrace("Trace....... Bad argument\n");
219: }
220: }
2.20 ! frystyk 221: if (!WWWTRACE) WWWTRACE = SHOW_ALL_TRACE;
2.19 frystyk 222: }
223: return WWWTRACE;
224: #else
225: return 0;
226: #endif
2.2 frystyk 227: }
228:
229: /* Application "BEFORE" Callback
230: ** -----------------------------
231: ** This function uses all the functionaly that the app part of the Library
232: ** gives for URL translations BEFORE a request is isseud.
233: ** It checks for Cache, proxy, and gateway (in that order)
2.3 frystyk 234: ** returns HT_LOADED We already have this
235: ** HT_ERROR We can't load this
2.2 frystyk 236: ** HT_OK Success
237: */
2.15 frystyk 238: PUBLIC int HTLoadStart (HTRequest * request, void * param, int status)
2.2 frystyk 239: {
2.16 frystyk 240: HTParentAnchor * anchor = HTRequest_anchor(request);
2.2 frystyk 241: char * addr = HTAnchor_address((HTAnchor *) anchor);
242: HTReload mode = HTRequest_reloadMode(request);
243:
244: /*
245: ** Check if document is already loaded.
246: */
247: if (mode != HT_FORCE_RELOAD) {
248: if (HTMemoryCache_check(request) == HT_LOADED) {
2.10 frystyk 249: HT_FREE(addr);
2.2 frystyk 250: return HT_LOADED;
251: }
252: } else {
2.7 frystyk 253: HTRequest_addGnHd(request, HT_G_NO_CACHE); /* No-cache pragma */
2.16 frystyk 254: HTAnchor_clearHeader(anchor);
2.2 frystyk 255: }
256:
257: /*
258: ** Check if we have any rule translations to do
259: */
260: {
261: HTList *list = HTRule_global();
262: char * physical = HTRule_translate(list, addr, NO);
263: if (!physical) {
2.16 frystyk 264: char *url = HTAnchor_address((HTAnchor *) anchor);
2.2 frystyk 265: if (url) {
266: HTUnEscape(url);
267: HTRequest_addError(request, ERR_FATAL, NO, HTERR_FORBIDDEN,
268: (void *) url, (int) strlen(url), "HTLoad");
269: } else {
270: HTRequest_addError(request, ERR_FATAL, NO, HTERR_FORBIDDEN,
271: NULL, 0, "HTLoad");
272: }
2.10 frystyk 273: HT_FREE(addr);
274: HT_FREE(url);
2.3 frystyk 275: return HT_ERROR;
2.2 frystyk 276: }
277: HTAnchor_setPhysical(anchor, physical);
2.10 frystyk 278: HT_FREE(physical);
2.2 frystyk 279: }
280:
281: /*
282: ** Check local Disk Cache (if we are not forced to reload), then
283: ** for proxy, and finally gateways
284: */
285: {
286: char *newaddr=NULL;
287: if (mode != HT_FORCE_RELOAD && (newaddr = HTCache_getReference(addr))){
288: if (mode != HT_CACHE_REFRESH) {
289: HTAnchor_setPhysical(anchor, newaddr);
290: HTAnchor_setCacheHit(anchor, YES);
291: } else { /* If refresh version in file cache */
2.6 frystyk 292: HTRequest_addGnHd(request, HT_G_NO_CACHE);
293: HTRequest_addRqHd(request, HT_C_IMS);
2.2 frystyk 294: }
295: } else if ((newaddr = HTProxy_find(addr))) {
296: StrAllocCat(newaddr, addr);
2.17 frystyk 297: HTRequest_setFullURI(request, YES);
2.2 frystyk 298: HTAnchor_setPhysical(anchor, newaddr);
299: } else if ((newaddr = HTGateway_find(addr))) {
300: char * path = HTParse(addr, "",
301: PARSE_HOST + PARSE_PATH + PARSE_PUNCTUATION);
302: /* Chop leading / off to make host into part of path */
303: char * gatewayed = HTParse(path+1, newaddr, PARSE_ALL);
304: HTAnchor_setPhysical(anchor, gatewayed);
2.10 frystyk 305: HT_FREE(path);
306: HT_FREE(gatewayed);
2.2 frystyk 307: } else {
2.17 frystyk 308: HTRequest_setFullURI(request, NO);
2.2 frystyk 309: }
2.10 frystyk 310: HT_FREE(newaddr);
2.2 frystyk 311: }
2.10 frystyk 312: HT_FREE(addr);
2.4 frystyk 313: return HT_OK;
2.2 frystyk 314: }
315:
316: /* Application "AFTER" Callback
317: ** -----------------------------
318: ** This function uses all the functionaly that the app part of the Library
319: ** gives for handling AFTER a request.
320: */
2.15 frystyk 321: PUBLIC int HTLoadTerminate (HTRequest * request, void * param, int status)
2.5 frystyk 322: {
2.16 frystyk 323: HTParentAnchor * anchor = HTRequest_anchor(request);
324: char * uri = HTAnchor_address((HTAnchor*) anchor);
2.5 frystyk 325: switch (status) {
326: case HT_RETRY:
327: if (PROT_TRACE)
2.11 eric 328: HTTrace("Load End.... NOT AVAILABLE, RETRY AT %ld\n",
2.5 frystyk 329: HTRequest_retryTime(request));
330: break;
331:
332: case HT_ERROR:
333: {
334: HTAlertCallback *cbf = HTAlert_find(HT_A_MESSAGE);
335: if (cbf) (*cbf)(request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
2.16 frystyk 336: HTRequest_error(request), NULL);
2.5 frystyk 337: }
338: if (PROT_TRACE)
2.11 eric 339: HTTrace("Load End.... ERROR: Can't access `%s\'\n",
2.8 frystyk 340: uri ? uri : "<UNKNOWN>");
2.5 frystyk 341: break;
342:
343: default:
344: if (PROT_TRACE)
2.13 frystyk 345: HTTrace("Load End.... Request ended with code %d\n", status);
2.5 frystyk 346: break;
347: }
2.2 frystyk 348:
349: /* Should we do logging? */
350: if (HTLog_isOpen()) HTLog_add(request, status);
2.10 frystyk 351: HT_FREE(uri);
2.2 frystyk 352: return HT_OK;
2.1 frystyk 353: }
Webmaster