Annotation of libwww/Library/src/HTAccess.c, revision 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