Annotation of libwww/Library/src/HTAccess.c, revision 1.1.1.1

1.1       timbl       1: /*             Access Manager                                  HTAccess.c
                      2: **             ==============
                      3: **
                      4: ** Authors
                      5: **     TBL     Tim Berners-Lee timbl@info.cern.ch
                      6: **     JFG     Jean-Francois Groff jgh@next.com
                      7: **     DD      Denis DeLaRoca (310) 825-4580  <CSP1DWD@mvs.oac.ucla.edu>
                      8: ** History
                      9: **       8 Jun 92 Telnet hopping prohibited as telnet is not secure TBL
                     10: **     26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. JFG
                     11: **      6 Oct 92 Moved HTClientHost and logfile into here. TBL
                     12: **     17 Dec 92 Tn3270 added, bug fix. DD
                     13: */
                     14: 
                     15: /* Implements:
                     16: */
                     17: #include "HTAccess.h"
                     18: 
                     19: /* Uses:
                     20: */
                     21: 
                     22: #include "HTParse.h"
                     23: #include "HTUtils.h"
                     24: #include "WWW.h"
                     25: #include "HTAnchor.h"
                     26: #include "HTTP.h"
                     27: #include "HTFile.h"
                     28: #include <errno.h>
                     29: #include <stdio.h>
                     30: 
                     31: #include "tcp.h"
                     32: #include "HTList.h"
                     33: #include "HText.h"
                     34: #ifndef DECNET
                     35: #include "HTFTP.h"
                     36: #include "HTGopher.h"
                     37: #include "HTNews.h"
                     38: #endif
                     39: 
                     40: 
                     41: /*     These flags may be set to modify the operation of this module
                     42: */
                     43: PUBLIC int HTDiag = 0;         /* Diagnostics: load source as text */
                     44: PUBLIC char * HTClientHost = 0;        /* Name of remote login host if any */
                     45: PUBLIC FILE * logfile = 0;     /* File to which to output one-liners */
                     46: 
                     47: 
                     48: PRIVATE HTList * protocols = NULL;   /* List of registered protocol descriptors */
                     49: 
                     50: 
                     51: /*     Register a Protocol                             HTRegisterProtocol
                     52: **     -------------------
                     53: */
                     54: 
                     55: PUBLIC BOOL HTRegisterProtocol(protocol)
                     56:        HTProtocol * protocol;
                     57: {
                     58:     if (!protocols) protocols = HTList_new();
                     59:     HTList_addObject(protocols, protocol);
                     60:     return YES;
                     61: }
                     62: 
                     63: 
                     64: /*     Register all known protocols
                     65: **     ----------------------------
                     66: **
                     67: **     Add to or subtract from this list if you add or remove protocol modules.
                     68: **     This routine is called the first time the protocol list is needed,
                     69: **     unless any protocols are already registered, in which case it is not called.
                     70: **     Therefore the application can override this list.
                     71: **
                     72: **     Compiling with NO_INIT prevents all known protocols from being forced
                     73: **     in at link time.
                     74: */
                     75: #ifndef NO_INIT
                     76: PRIVATE void HTAccessInit NOARGS                       /* Call me once */
                     77: {
                     78: extern HTProtocol HTTP, HTFile, HTTelnet, HTTn3270, HTRlogin
                     79: #ifndef DECNET
                     80: extern HTProtocol HTFTP, HTNews, HTGopher
                     81:     HTRegisterProtocol(HTFTP);
                     82:     HTRegisterProtocol(HTNews);
                     83:     HTRegisterProtocol(HTGopher);
                     84: #endif
                     85: 
                     86:     HTRegisterProtocol(HTTP);
                     87:     HTRegisterProtocol(HTFile);
                     88:     HTRegisterProtocol(HTTelnet);
                     89:     HTRegisterProtocol(HTTn3270);
                     90:     HTRegisterProtocol(HTRlogin);
                     91: }
                     92: #endif
                     93: 
                     94: 
                     95: /*             Load a document
                     96: **             ---------------
                     97: **
                     98: **     This is an internal routine, which has an address and a matching
                     99: **     anchor.  The public routines are called with one or the other.
                    100: **
                    101: ** On entry,
                    102: **     addr            must point to the fully qualified hypertext reference.
                    103: **     anchor          a pareent anchor with whose address is addr
                    104: **
                    105: ** On exit,
                    106: **     returns         <0              Error has occured.
                    107: **                     >=0             Success
                    108: **                     HT_NO_DATA      Success, but no document loaded.
                    109: **
                    110: */
                    111: PRIVATE int HTLoad ARGS2(
                    112:        CONST char *,addr1,
                    113:        HTParentAnchor *,anchor)
                    114: {
                    115:     char * access=0;   /* Name of access method */
                    116:     int status;
                    117:     char * gateway;
                    118:     char * gateway_parameter;
                    119:     char * addr = (char *)malloc(strlen(addr1)+1);
                    120:     
                    121:     if (addr == NULL) outofmem(__FILE__, "HTLoad");
                    122:     strcpy(addr, addr1);                       /* Copy to play with */
                    123:     
                    124:     access =  HTParse(addr, "file:", PARSE_ACCESS);
                    125: 
                    126: /*     Check whether gateway access has been set up for this
                    127: */
                    128: #ifdef USE_GATEWAYS
                    129:     gateway_parameter = (char *)malloc(strlen(access)+20);
                    130:     if (gateway_parameter == NULL) outofmem(__FILE__, "HTLoad");
                    131:     strcpy(gateway_parameter, "WWW_");
                    132:     strcat(gateway_parameter, access);
                    133:     strcat(gateway_parameter, "_GATEWAY");
                    134:     gateway = (char *)getenv(gateway_parameter); /* coerce for decstation */
                    135:     free(gateway_parameter);
                    136:     if (gateway) {
                    137:        status = HTLoadHTTP(addr, gateway, anchor, HTDiag);
                    138:         goto done;
                    139:     } 
                    140: #endif
                    141: 
                    142: 
                    143: /*     Use rule file to vary actual access protocol
                    144: */
                    145: #ifdef RULES
                    146:        /* @@@ TBD */
                    147: #endif
                    148: 
                    149: 
                    150: /*     Search registered protocols to find suitable one
                    151: */
                    152:     {
                    153:        int i, n;
                    154: #ifndef NO_INIT
                    155:         if (!protocols) HTAccessInitialize();
                    156: #endif
                    157:        n = HTList_count(protocols);
                    158:        for (i=0; i<n; i++) {
                    159:            HTProtocol *p = HTList_objectAt(i);
                    160:            if (strcmp(p->name, access)==0) [
                    161:                status = (*(p->load))(addr, anchor, HTDiag);
                    162:                break;
                    163:            }
                    164:        }
                    165:     }
                    166: 
                    167: #ifdef OLD_CODE
                    168: 
                    169:     if (0==strcmp(access, "http")) {
                    170:         status = HTLoadHTTP(addr, 0, anchor, HTDiag);
                    171: #ifndef CURSES
                    172:        if (status<0) fprintf(stderr,   /* For simple users */
                    173:                "Cannot connect to information server.\n");
                    174: #endif
                    175:     } else if ((0==strcmp(access, "file"))
                    176:            ||  (0==strcmp(access, "ftp"))) {   /* TBL 921021 */
                    177:         status = HTLoadFile(addr, anchor, HTDiag);
                    178: #ifndef DECNET
                    179:     } else if (0==strcmp(access, "news")) {
                    180:         status = HTLoadNews(addr, anchor, HTDiag);
                    181:        if (status>0) status = HT_LOADED;
                    182: 
                    183:     } else if (0==strcmp(access, "gopher")) {
                    184:         status = HTLoadGopher(addr, anchor, HTDiag);
                    185:        if (status>0) status = HT_LOADED;
                    186: #endif
                    187:     } else if (!strcmp(access, "telnet") ||            /* TELNET */
                    188:        !strcmp(access, "rlogin")||                     /* etc */
                    189:        !strcmp(access, "tn3270")) {
                    190:         char * host = HTParse(addr, "", PARSE_HOST);
                    191:        status = remote_session(access, host);
                    192:        free(host);
                    193:        
                    194:     } else if (0==strcmp(access, "wais")) {
                    195:         user_message(
                    196: "HTAccess: For WAIS access set WWW_wais_GATEWAY to gateway address.\n");
                    197:     } else {
                    198: 
                    199:         user_message(
                    200:        "HTAccess: name scheme `%s' unknown by this browser version.\n",
                    201:                 access);
                    202:         status = -1;
                    203:     }
                    204: #endif /* old code */
                    205: 
                    206: done:
                    207: #ifndef CURSES
                    208:        if (status<0) fprintf(stderr,   /* For simple users */
                    209:            "Cannot retrieve required information.\n",);
                    210: #endif
                    211:     free(access);
                    212:     free(addr);
                    213:     return status;
                    214: }
                    215: 
                    216: 
                    217: 
                    218: /*             Load a document
                    219: **             ---------------
                    220: **
                    221: **    On Entry,
                    222: **       anchor            is the node_anchor for the document
                    223: **        full_address      The address of the document to be accessed.
                    224: **        filter            if YES, treat document as HTML
                    225: **
                    226: **    On Exit,
                    227: **        returns    YES     Success in opening document
                    228: **                   NO      Failure 
                    229: **
                    230: */
                    231: 
                    232: PUBLIC BOOL HTLoadDocument ARGS3(HTParentAnchor *,anchor,
                    233:        CONST char *,full_address,
                    234:        BOOL,   filter)
                    235: 
                    236: {
                    237:     int                status;
                    238:     HText *    text;
                    239: 
                    240:     if (TRACE) fprintf (stderr,
                    241:       "HTAccess: loading document %s\n", full_address);
                    242: 
                    243:     if (text=(HText *)HTAnchor_document(anchor)) {     /* Already loaded */
                    244:         if (TRACE) fprintf(stderr, "HTAccess: Document already in memory.\n");
                    245:         HText_select(text);
                    246:        return YES;
                    247:     }
                    248:     
                    249: #ifdef CURSES
                    250:       prompt_set("Retrieving document...");
                    251: #endif
                    252:     if (filter) {
                    253:         status = 0;
                    254:     } else {
                    255:        status = HTLoad(full_address, anchor);
                    256:     }
                    257: /*     Log the access if necessary
                    258: */
                    259:     if (logfile) {
                    260:        time_t theTime;
                    261:        time(&theTime);
                    262:        fprintf(logfile, "%24.24s %s %s %s\n",
                    263:            ctime(&theTime),
                    264:            HTClientHost ? HTClientHost : "local",
                    265:            status<0 ? "FAIL" : "GET",
                    266:            full_address);
                    267:        fflush(logfile);        /* Actually update it on disk */
                    268:        if (TRACE) fprintf(stderr, "Log: %24.24s %s %s %s\n",
                    269:            ctime(&theTime),
                    270:            HTClientHost ? HTClientHost : "local",
                    271:            status<0 ? "FAIL" : "GET",
                    272:            full_address);
                    273:     }
                    274:     
                    275: 
                    276:     if (status == HT_LOADED) {
                    277:        if (TRACE) {
                    278:            fprintf(stderr, "HTAccess: `%s' has been accessed.\n",
                    279:            full_address);
                    280:        }
                    281:        return YES;
                    282:     }
                    283:     
                    284:     if (status == HT_NO_DATA) {
                    285:        if (TRACE) {
                    286:            fprintf(stderr, 
                    287:            "HTAccess: `%s' has been accessed, No data left.\n",
                    288:            full_address);
                    289:        }
                    290:        return NO;
                    291:     }
                    292:     
                    293:     if (status<0) {                  /* Failure in accessing a file */
                    294: 
                    295: #ifdef CURSES
                    296:         user_message("Can't access `%s'", full_address);
                    297: #else
                    298:        if (TRACE)
                    299:            fprintf(stderr, "HTAccess: Can't access `%s'\n", full_address);
                    300: #endif
                    301: 
                    302:        return NO;
                    303:     }
                    304:     
                    305:     fprintf(stderr,
                    306:     "**** HTAcess: socket or file number returned by obsolete load routine!\n");
                    307:     exit(-6996);
                    308: 
                    309: 
                    310: } /* HTLoadDocument */
                    311: 
                    312: 
                    313: /*             Load a document from absolute name
                    314: **             ---------------
                    315: **
                    316: **    On Entry,
                    317: **        addr     The absolute address of the document to be accessed.
                    318: **        filter   if YES, treat document as HTML
                    319: **
                    320: **    On Exit,
                    321: **        returns    YES     Success in opening document
                    322: **                   NO      Failure 
                    323: **
                    324: **
                    325: */
                    326: 
                    327: PUBLIC BOOL HTLoadAbsolute ARGS2(CONST char *,addr, BOOL, filter)
                    328: {
                    329:    return HTLoadDocument(
                    330:                        HTAnchor_parent(HTAnchor_findAddress(addr)),
                    331:                        addr, filter);
                    332: }
                    333: 
                    334: 
                    335: /*             Load a document from relative name
                    336: **             ---------------
                    337: **
                    338: **    On Entry,
                    339: **        relative_name     The relative address of the document to be accessed.
                    340: **
                    341: **    On Exit,
                    342: **        returns    YES     Success in opening document
                    343: **                   NO      Failure 
                    344: **
                    345: **
                    346: */
                    347: 
                    348: PUBLIC BOOL HTLoadRelative ARGS1(CONST char *,relative_name)
                    349: {
                    350:     char *             full_address = 0;
                    351:     BOOL                       result;
                    352:     char *             mycopy = 0;
                    353:     char *             stripped = 0;
                    354:     char *             current_address =
                    355:                                HTAnchor_address((HTAnchor*)HTMainAnchor);
                    356: 
                    357:     StrAllocCopy(mycopy, relative_name);
                    358: 
                    359:     stripped = HTStrip(mycopy);
                    360:     full_address = HTParse(stripped,
                    361:                   current_address,
                    362:                   PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
                    363:     result = HTLoadAbsolute(full_address, NO);
                    364:     free(full_address);
                    365:     free(current_address);
                    366:     free(mycopy);  /* Memory leak fixed 10/7/92 -- JFG */
                    367:     return result;
                    368: }
                    369: 
                    370: 
                    371: /*             Load if necessary, and select an anchor
                    372: **             --------------------------------------
                    373: **
                    374: **    On Entry,
                    375: **        destination              The child or parenet anchor to be loaded.
                    376: **
                    377: **    On Exit,
                    378: **        returns    YES     Success
                    379: **                   NO      Failure 
                    380: **
                    381: */
                    382: 
                    383: PUBLIC BOOL HTLoadAnchor ARGS1(HTAnchor *,destination)
                    384: {
                    385:     HTParentAnchor * parent;
                    386:     BOOL loaded = NO;
                    387:     if (!destination) return NO;       /* No link */
                    388:     
                    389:     parent  = HTAnchor_parent(destination);
                    390:     
                    391:     if (HTAnchor_document(parent) == NULL) {   /* If not alread loaded */
                    392:                                                /* TBL 921202 */
                    393: /*  if ( parent != HTMainAnchor) {    before If not already loaded */
                    394:         BOOL result;
                    395:         char * address = HTAnchor_address((HTAnchor*) parent);
                    396:        result = HTLoadDocument(parent, address, NO);
                    397:        free(address);
                    398:        if (!result) return NO;
                    399:        loaded = YES;
                    400:     }
                    401:     
                    402:     {
                    403:        HText *text = (HText*)HTAnchor_document(parent);
                    404:        if (destination != (HTAnchor *)parent) {  /* If child anchor */
                    405:            HText_selectAnchor(text, 
                    406:                    (HTChildAnchor*)destination); /* Double display? @@ */
                    407:        } else {
                    408:            if (!loaded) HText_select(text);
                    409:        }
                    410:     }
                    411:     return YES;
                    412:        
                    413: } /* HTLoadAnchor */
                    414: 
                    415: 
                    416: /*             Search
                    417: **             ------
                    418: **  Performs a keyword search on word given by the user. Adds the keyword to 
                    419: **  the end of the current address and attempts to open the new address.
                    420: **
                    421: **  On Entry,
                    422: **       *keywords     space-separated keyword list or similar search list
                    423: **     HTMainAnchor    global must be valid.
                    424: */
                    425: 
                    426: PUBLIC BOOL HTSearch ARGS1(char *, keywords)
                    427: 
                    428: {
                    429:     char * p;            /* pointer to first non-blank */
                    430:     char * q, *s;
                    431:     char * address = HTAnchor_address((HTAnchor*)HTMainAnchor);
                    432:     BOOL result;
                    433:     
                    434:     p = HTStrip(keywords);
                    435:     for (q=p; *q; q++)
                    436:         if (WHITE(*q)) {
                    437:            *q = '+';
                    438:        }
                    439: 
                    440:     s=strchr(address, '?');            /* Find old search string */
                    441:     if (s) *s = 0;                             /* Chop old search off */
                    442: 
                    443:     StrAllocCat(address, "?");
                    444:     StrAllocCat(address, p);
                    445: 
                    446:     result = HTLoadRelative(address);
                    447:     free(address);
                    448:     return result;
                    449:     
                    450: }
                    451: 
                    452: 

Webmaster