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