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