Annotation of libwww/Library/src/HTAccess.html, revision 2.19

2.9       timbl       1: <HTML>
                      2: <HEAD>
2.6       timbl       3: <TITLE>HTAccess:  Access manager  for libwww</TITLE>
2.19    ! timbl       4: <NEXTID N="z11">
2.9       timbl       5: </HEAD>
2.5       timbl       6: <BODY>
                      7: <H1>Access Manager</H1>This module keeps a list of valid
                      8: protocol (naming scheme) specifiers
                      9: with associated access code.  It
                     10: allows documents to be loaded given
                     11: various combinations of parameters.
                     12: New access protocols may be registered
                     13: at any time.<P>
2.9       timbl      14: Note: HTRequest defined and request
                     15: parametsr added to almost all calls
                     16: 18 Nov 1993.<P>
2.5       timbl      17: Part of the <A
2.19    ! timbl      18: NAME="z0" HREF="Overview.html">libwww library</A> .  Implemented
        !            19: by <A
        !            20: NAME="z8" HREF="HTAccess.c">HTAcces.c</A>
2.5       timbl      21: <PRE>#ifndef HTACCESS_H
1.1       timbl      22: #define HTACCESS_H
                     23: 
                     24: /*     Definition uses:
                     25: */
                     26: #include "HTUtils.h"
2.16      luotonen   27: #include "HTList.h"
1.1       timbl      28: #include "tcp.h"
2.14      luotonen   29: 
1.1       timbl      30: 
                     31: #ifdef SHORT_NAMES
2.8       timbl      32: #define HTClientHost           HTClHost
                     33: #define HTSearchAbsolute       HTSeAbso
                     34: #define HTOutputStream         HTOuStre
                     35: #define HTOutputFormat         HTOuForm
1.1       timbl      36: #endif
                     37: 
2.16      luotonen   38: typedef enum {
                     39:        METHOD_INVALID  = 0,
                     40:        METHOD_GET      = 1,
                     41:        METHOD_HEAD,
                     42:        METHOD_POST,
                     43:        METHOD_PUT,
                     44:        METHOD_DELETE,
                     45:        METHOD_CHECKOUT,
                     46:        METHOD_CHECKIN,
                     47:        METHOD_SHOWMETHOD,
                     48:        METHOD_LINK,
                     49:        METHOD_UNLINK,
                     50:        MAX_METHODS
                     51: } HTMethod;
                     52: 
                     53: 
                     54: </PRE>
                     55: <H2>Methods</H2>
                     56: <PRE>
                     57: 
                     58: /*     Get method enum value
                     59: **     ---------------------
                     60: */
                     61: PUBLIC HTMethod HTMethod_enum PARAMS((char * name));
                     62: 
                     63: 
                     64: /*     Get method name
                     65: **     ---------------
                     66: */
                     67: PUBLIC char * HTMethod_name PARAMS((HTMethod method));
                     68: 
                     69: 
                     70: /* PUBLIC                                              HTMethod_inList()
                     71: **             IS A METHOD IN A LIST OF METHOD NAMES
                     72: ** ON ENTRY:
                     73: **     method          is the method to look for.
                     74: **     list            is a list of method names.
                     75: **
                     76: ** ON EXIT:
                     77: **     returns         YES, if method was found.
                     78: **                     NO, if not found.
                     79: */
                     80: PUBLIC BOOL HTMethod_inList PARAMS((HTMethod   method,
                     81:                                    HTList *    list));
                     82: </PRE>
                     83: <H2>Match Template Against Filename</H2>
                     84: <PRE>
                     85: /* PUBLIC                                              HTAA_templateMatch()
                     86: **             STRING COMPARISON FUNCTION FOR FILE NAMES
                     87: **                WITH ONE WILDCARD * IN THE TEMPLATE
                     88: ** NOTE:
                     89: **     This is essentially the same code as in HTRules.c, but it
                     90: **     cannot be used because it is embedded in between other code.
                     91: **     (In fact, HTRules.c should use this routine, but then this
                     92: **      routine would have to be more sophisticated... why is life
                     93: **      sometimes so hard...)
                     94: **
                     95: ** ON ENTRY:
                     96: **     template        is a template string to match the file name
                     97: **                     agaist, may contain a single wildcard
                     98: **                     character * which matches zero or more
                     99: **                     arbitrary characters.
                    100: **     filename        is the filename (or pathname) to be matched
                    101: **                     agaist the template.
                    102: **
                    103: ** ON EXIT:
                    104: **     returns         YES, if filename matches the template.
                    105: **                     NO, otherwise.
                    106: */
                    107: PUBLIC BOOL HTAA_templateMatch PARAMS((CONST char * template, 
                    108:                                       CONST char * filename));
                    109: 
                    110: 
2.19    ! timbl     111: </PRE>The following have to be defined
2.10      timbl     112: in advance of the other include files
                    113: because of circular references.
                    114: <PRE>typedef struct _HTRequest HTRequest;
                    115: 
2.14      luotonen  116: /*
                    117: ** Callback to call when username and password
                    118: ** have been prompted.
                    119: */
                    120: typedef int (*HTRetryCallbackType) PARAMS((HTRequest * req));
                    121: 
                    122: 
2.10      timbl     123: #include "HTAnchor.h"
                    124: #include <A
                    125: NAME="z3" HREF="HTFormat.html">"HTFormat.h"</A>
2.15      luotonen  126: #include "HTAAUtil.h"          /* HTAAScheme, HTAAFailReason */
2.14      luotonen  127: #include "HTAABrow.h"          /* HTAASetup */
2.10      timbl     128: 
                    129: 
1.1       timbl     130: /*     Return codes from load routines:
                    131: **
                    132: **     These codes may be returned by the protocol modules,
                    133: **     and by the HTLoad routines.
                    134: **     In general, positive codes are OK and negative ones are bad.
                    135: */
                    136: 
                    137: #define HT_NO_DATA -9999       /* return code: OK but no data was loaded */
                    138:                                /* Typically, other app started or forked */
                    139: 
2.5       timbl     140: </PRE>
2.6       timbl     141: <H2>Default Addresses</H2>These control the home page selection.
2.8       timbl     142: To mess with these for normal browses
2.6       timbl     143: is asking for user confusion.
                    144: <PRE>#define LOGICAL_DEFAULT "WWW_HOME"  /* Defined to be the home page */
1.1       timbl     145: 
2.6       timbl     146: #ifndef PERSONAL_DEFAULT
                    147: #define PERSONAL_DEFAULT "WWW/default.html"    /* in home directory */
                    148: #endif
                    149: #ifndef LOCAL_DEFAULT_FILE
1.1       timbl     150: #define LOCAL_DEFAULT_FILE "/usr/local/lib/WWW/default.html"
2.6       timbl     151: #endif
2.7       timbl     152: /*  If one telnets to a www access point,
                    153:     it will look in this file for home page */
                    154: #ifndef REMOTE_POINTER
                    155: #define REMOTE_POINTER  "/etc/www-remote.url"  /* can't be file */
                    156: #endif
                    157: /* and if that fails it will use this. */
2.6       timbl     158: #ifndef REMOTE_ADDRESS
1.1       timbl     159: #define REMOTE_ADDRESS  "http://info.cern.ch/remote.html"  /* can't be file */
                    160: #endif
                    161: 
                    162: /* If run from telnet daemon and no -l specified, use this file:
                    163: */
                    164: #ifndef DEFAULT_LOGFILE
                    165: #define DEFAULT_LOGFILE        "/usr/adm/www-log/www-log"
                    166: #endif
                    167: 
                    168: /*     If the home page isn't found, use this file:
                    169: */
                    170: #ifndef LAST_RESORT
2.6       timbl     171: #define LAST_RESORT    "http://info.cern.ch/default.html"
1.1       timbl     172: #endif
                    173: 
2.10      timbl     174: 
2.9       timbl     175: </PRE>
                    176: <H2><A
                    177: NAME="z1">The Request structure</A></H2>When a request is handled, all kinds
                    178: of things about it need to be passed
                    179: along.  These are all put into a
2.11      timbl     180: HTRequest structure.  Note there
                    181: is also a <A
2.12      timbl     182: NAME="z4" HREF="HTFormat.html#z17">global list of converters</A>
                    183: .
2.10      timbl     184: <PRE>struct _HTRequest {
2.19    ! timbl     185: 
        !           186: 
        !           187: </PRE>The elements of the request structure
        !           188: are as follows.
        !           189: <H3>Set by the caller of HTaccess:</H3>
        !           190: <H4>Conditions of the request itself:</H4>
        !           191: <PRE>  HTMethod        method;
        !           192: 
        !           193: </PRE>An atom for the name of the operation
        !           194: using HTTP <A
        !           195: NAME="z7" HREF="../../Protocols/HTTP/Methods.html">method names</A> .
        !           196: <PRE>  HTList *        conversions ;
        !           197: </PRE>
        !           198: <DL>
        !           199: <DT>
        !           200: </DL>
        !           201: NULL, or a list of conversions which
        !           202: the format manager can do in order
        !           203: to fulfill the request.  This is
        !           204: set by the caller of HTAccess. Typically
        !           205: points to a list set up an initialisation
        !           206: time for example by HTInit.
        !           207: <PRE>  HTList *        encodings;      /* allowed content-encodings      */
        !           208: 
        !           209: </PRE>The list of encodings acceptablein
        !           210: the output stream.
        !           211: <PRE>  HTList *        languages;      /* accepted content-languages     */
        !           212: 
        !           213: </PRE>The list of (human) language values
        !           214: acceptable in the response
        !           215: <PRE>  BOOL (*<A
        !           216: NAME="z9">callback</A>) PARAMS((
2.9       timbl     217:                                struct _HTRequest* request,
                    218:                                void *param));
2.19    ! timbl     219: 
        !           220: </PRE>A function to be called back in the
        !           221: event that a file has been saved
        !           222: to disk by HTSaveAndCallBack for
        !           223: example.
        !           224: <PRE>  void *          context;        /* caller data -- HTAccess unaware */
        !           225: 
        !           226: </PRE>An arbitrary pointer passed to HTAccess
        !           227: and passed back as a parameter to
        !           228: the <A
        !           229: NAME="z10" HREF="#z9">callback</A>.
        !           230: <PRE>  HTStream*       output_stream; 
        !           231: 
        !           232: </PRE>NULL in the case of display to the
        !           233: user, or if a specific output stream
        !           234: is required, the stream.
        !           235: <PRE>  HTAtom *        output_format;
        !           236: 
        !           237: </PRE>The output format required, or a
        !           238: generic format such as www/present
        !           239: (present to user). 
        !           240: <H4>Information about the requester</H4>
        !           241: <PRE>  char *          from;
        !           242: 
        !           243: </PRE>Email format address of person responible
        !           244: for request
        !           245: <PRE>  char *          user_agent;
        !           246: 
        !           247: </PRE>The name of the client software package
        !           248: in use.
        !           249: <H3>Set by HTAccess</H3>None of the bits below may be looked
        !           250: at by a client application except
        !           251: in the callback routine, when the
        !           252: anchor may be picked out.
        !           253: <PRE>  HTParentAnchor* anchor;
        !           254: 
        !           255: </PRE>The anchor for the object in question.
        !           256:  Set immediately by HTAcesss.  Used
        !           257: by the protocol and parsing modules.
        !           258: Valid thoughout the access.
        !           259: <PRE>  HTChildAnchor * childAnchor;    /* For element within the object  */
        !           260: 
        !           261: </PRE><A
        !           262: NAME="z6">T</A>he anchor for the sub object if
        !           263: any.  The object builder should ensure
        !           264: that htis is selected, highlighted,
        !           265: etc when the object is loaded. NOTE:
        !           266: Set by HTAccess.
        !           267: <PRE>  void *          using_cache;
        !           268: 
        !           269: </PRE>pointer to cache element if cache
        !           270: hit
        !           271: <PRE>  int             status_code;
        !           272: 
        !           273: </PRE>HTTP-style status code in case of
        !           274: error.  Initialised by AA code to
        !           275: 200, overwritten with something else
        !           276: if error.
        !           277: <PRE>  char *          reason_line;
        !           278: 
        !           279: </PRE>Reason for failing if any. Human
        !           280: readable.
        !           281: <H3>Server side</H3>
        !           282: <PRE>  int             soc;            /* Socket from which request came */
2.15      luotonen  283:        HTInputSocket * isoc;           /* InputSocket object for reading */
2.14      luotonen  284:        char *          request;        /* First request line as received */
                    285:        char *          argument;       /* Arg to HTTP method as given    */
                    286:        char *          arg_path;       /* Pathinfo part of argument      */
2.16      luotonen  287:        char *          arg_keywords;   /* Keyword part of URL            */
2.19    ! timbl     288:        char *          translated;
        !           289: 
        !           290: </PRE>Translated filename (set by function
        !           291: HTTranslateReq(). NULL, if this is
        !           292: a script execution request
        !           293: <PRE>  char *          script;
        !           294: 
        !           295: </PRE>Executable script name (set by HTTranslateReq().
        !           296: NULL if not a script request.
        !           297: <PRE>  char *          script_pathinfo;/* Path info after script name    */
2.15      luotonen  298:        char *          script_pathtrans;/* Path info translated          */
2.18      luotonen  299:        HTAtom *        content_language;/* Language                      */
                    300:        HTAtom *        content_encoding;/* Encoding                      */
2.14      luotonen  301:        char *          location;       /* Location for redirection       */
2.16      luotonen  302:        HTAtom *        content_type;   /* Content-Type:                  */
                    303:        int             content_length; /* Content-Length:                */
                    304:        char *          last_modified;  /* Last-Modified:                 */
                    305:        char *          expires;        /* Expires:                       */
                    306:        char *          uri;            /* Uri:                           */
                    307:        char *          message_id;     /* Message-Id:                    */
                    308:        HTList *        allowed;        /* Allowed: (list of HTAtoms)     */
                    309:        HTList *        public;         /* Public: (list of HTAtoms)      */
2.17      luotonen  310:        char *          meta_file;      /* File for meta information      */
2.14      luotonen  311:        char *          authorization;  /* Authorization: field           */
                    312:        HTAAScheme      scheme;         /* Authentication scheme used     */
                    313:        char *          auth_string;    /* Authentication string          */
2.15      luotonen  314:        char *          www_authenticate;/*WWW-Authenticate: (should be a */
                    315:                                        /* a HTList *)                    */
2.14      luotonen  316:        HTAAFailReason  reason;         /* Reason for failing             */
2.16      luotonen  317: 
2.19    ! timbl     318: 
        !           319: </PRE>
        !           320: <H3>Client side AA</H3>
        !           321: <PRE>
2.14      luotonen  322:        HTList *        valid_schemes;  /* Valid auth.schemes             */
                    323:        HTAssocList **  scheme_specifics;/* Scheme-specific parameters    */
                    324:        char *          prot_template;  /* WWW-Protection-Template: field */
                    325:        HTAASetup *     setup;          /* Doc protection info            */
                    326:        HTAARealm *     realm;          /* Password realm                 */
                    327:        char *          dialog_msg;     /* Authentication prompt (client) */
                    328:        HTRetryCallbackType
                    329:                        retry_callback; /* Called when password entered   */
2.10      timbl     330: };
2.9       timbl     331: 
2.19    ! timbl     332: </PRE>Just to make things easier especially
2.9       timbl     333: for clients, here is a function to
                    334: return a new blank request:
                    335: <H2>Create blank request</H2>This request has defaults in -- in
                    336: most cases it will need some information
                    337: added before being passed to HTAccess,
                    338: but it will work as is for a simple
                    339: request.
2.14      luotonen  340: <PRE>
                    341: PUBLIC HTRequest * HTRequest_new NOPARAMS;
                    342: 
                    343: 
                    344: </PRE>
2.19    ! timbl     345: <H2>Delete request structure</H2>Frees also conversion list hanging
        !           346: from req->conversions.
2.14      luotonen  347: <PRE>
                    348: PUBLIC void HTRequest_delete PARAMS((HTRequest * req));
1.1       timbl     349: 
2.9       timbl     350: 
2.5       timbl     351: </PRE>
                    352: <H2>Flags which may be set to control
                    353: this module</H2>
                    354: <PRE>extern int HTDiag;                        /* Flag: load source as plain text */
1.1       timbl     355: extern char * HTClientHost;            /* Name or number of telnetting host */
                    356: extern FILE * logfile;                 /* File to output one-liners to */
2.7       timbl     357: extern BOOL HTSecure;                  /* Disable security holes? */
1.1       timbl     358: 
                    359: 
                    360: 
2.5       timbl     361: </PRE>
                    362: <H2>Load a document from relative name</H2>
                    363: <H3>On Entry,</H3>
                    364: <DL>
                    365: <DT>relative_name
2.6       timbl     366: <DD> The relative address
2.5       timbl     367: of the file to be accessed.
                    368: <DT>here
2.6       timbl     369: <DD> The anchor of the object being
2.5       timbl     370: searched
2.9       timbl     371: <DT>request->anchor
                    372: <DD> not filled in yet
2.5       timbl     373: </DL>
                    374: 
                    375: <H3>On Exit,</H3>
                    376: <DL>
                    377: <DT>returns    YES
2.6       timbl     378: <DD> Success in opening
2.5       timbl     379: file
                    380: <DT>NO
2.6       timbl     381: <DD> Failure 
2.5       timbl     382: </DL>
1.1       timbl     383: 
2.5       timbl     384: <PRE>extern  BOOL HTLoadRelative PARAMS((
1.1       timbl     385:                CONST char *            relative_name,
2.9       timbl     386:                HTParentAnchor *        here,
                    387:                HTRequest *             request));
1.1       timbl     388: 
                    389: 
2.5       timbl     390: </PRE>
                    391: <H2>Load a document from absolute name</H2>
                    392: <H3>On Entry,</H3>
                    393: <DL>
                    394: <DT>addr
2.6       timbl     395: <DD> The absolute address of the
                    396: document to be accessed.
2.5       timbl     397: <DT>filter
2.6       timbl     398: <DD> if YES, treat document as
                    399: HTML
2.9       timbl     400: <DT>request->anchor
                    401: <DD> not filled in yet
2.5       timbl     402: </DL>
1.1       timbl     403: 
2.5       timbl     404: <PRE>
                    405: </PRE>
                    406: <H3>On Exit,</H3>
                    407: <PRE>
                    408: </PRE>
                    409: <DL>
                    410: <DT>returns YES
2.6       timbl     411: <DD> Success in opening document
2.5       timbl     412: <DT>NO
2.6       timbl     413: <DD> Failure 
2.5       timbl     414: </DL>
1.1       timbl     415: 
2.9       timbl     416: <PRE>extern BOOL HTLoadAbsolute PARAMS((CONST char * addr,
                    417:                HTRequest *             request));
1.1       timbl     418: 
                    419: 
2.5       timbl     420: </PRE>
                    421: <H2>Load a document from absolute name
                    422: to a stream</H2>
                    423: <H3>On Entry,</H3>
                    424: <DL>
                    425: <DT>addr
2.6       timbl     426: <DD> The absolute address of the
                    427: document to be accessed.
2.5       timbl     428: <DT>filter
2.6       timbl     429: <DD> if YES, treat document as
                    430: HTML
2.9       timbl     431: <DT>request->anchor
                    432: <DD> not filled in yet
2.5       timbl     433: </DL>
                    434: 
                    435: <H3>On Exit,</H3>
                    436: <DL>
                    437: <DT>returns YES
2.6       timbl     438: <DD> Success in opening document
2.5       timbl     439: <DT>NO
2.6       timbl     440: <DD> Failure 
2.5       timbl     441: </DL>
                    442: Note: This is equivalent to HTLoadDocument
2.9       timbl     443: <PRE>extern BOOL HTLoadToStream PARAMS((
                    444:                CONST char *            addr,
                    445:                BOOL                    filter,
                    446:                HTRequest *             request));
1.1       timbl     447: 
                    448: 
2.5       timbl     449: </PRE>
                    450: <H2>Load if necessary, and select an
2.9       timbl     451: anchor</H2>The anchor parameter may be a child
                    452: anchor. The anchor in the request
                    453: is set to the parent anchor.
2.5       timbl     454: <H3>On Entry,</H3>
                    455: <DL>
2.9       timbl     456: <DT>anchor
                    457: <DD> may be a child or parenet
                    458: anchor or 0 in which case there is
                    459: no effect.
                    460: <DT>request->anchor      
                    461: <DD>    Not set
                    462: yet.
2.5       timbl     463: </DL>
                    464: 
                    465: <H3>On Exit,</H3>
                    466: <PRE>
                    467: </PRE>
                    468: <DL>
                    469: <DT>returns YES
2.6       timbl     470: <DD> Success
2.5       timbl     471: <DT>returns NO
2.6       timbl     472: <DD> Failure 
2.9       timbl     473: <DT>request->anchor
                    474: <DD> The parenet anchor.
2.5       timbl     475: </DL>
                    476: 
2.9       timbl     477: <PRE>extern BOOL HTLoadAnchor PARAMS((HTAnchor * a,
                    478:                        HTRequest *             request));
1.1       timbl     479: 
                    480: 
2.5       timbl     481: </PRE>
                    482: <H2>Make a stream for Saving object back</H2>
                    483: <H3>On Entry,</H3>
                    484: <DL>
2.9       timbl     485: <DT>request->anchor
                    486: <DD> is valid anchor which
                    487: has previously beeing loaded
2.5       timbl     488: </DL>
                    489: 
                    490: <H3>On exit,</H3>
                    491: <DL>
                    492: <DT>returns
2.6       timbl     493: <DD> 0 if error else a stream
                    494: to save the object to.
2.5       timbl     495: </DL>
                    496: 
                    497: <PRE>
                    498: 
2.13      timbl     499: extern HTStream * HTSaveStream PARAMS((HTRequest * request));
1.1       timbl     500: 
                    501: 
2.5       timbl     502: </PRE>
                    503: <H2>Search</H2>Performs a search on word given by
                    504: the user. Adds the search words to
                    505: the end of the current address and
                    506: attempts to open the new address.
                    507: <H3>On Entry,</H3>
                    508: <DL>
                    509: <DT>*keywords
2.6       timbl     510: <DD> space-separated keyword
2.5       timbl     511: list or similar search list
                    512: <DT>here
2.6       timbl     513: <DD> The anchor of the object being
2.5       timbl     514: searched
                    515: </DL>
1.1       timbl     516: 
2.9       timbl     517: <PRE>extern BOOL HTSearch PARAMS((
                    518:                CONST char *            keywords,
                    519:                HTParentAnchor*         here,
                    520:                HTRequest *             request));
1.1       timbl     521: 
                    522: 
2.5       timbl     523: </PRE>
                    524: <H2>Search Given Indexname</H2>Performs a keyword search on word
                    525: given by the user. Adds the keyword
                    526: to  the end of the current address
                    527: and attempts to open the new address.
                    528: <H3>On Entry,</H3>
                    529: <DL>
                    530: <DT>*keywords
2.6       timbl     531: <DD> space-separated keyword
2.5       timbl     532: list or similar search list
                    533: <DT>*indexname
2.6       timbl     534: <DD> is name of object search
2.5       timbl     535: is to be done on.
                    536: </DL>
1.1       timbl     537: 
2.5       timbl     538: <PRE>extern BOOL HTSearchAbsolute PARAMS((
2.9       timbl     539:        CONST char *            keywords,
                    540:        CONST char *            indexname,
                    541:        HTRequest *             request));
1.1       timbl     542: 
                    543: 
2.5       timbl     544: </PRE>
2.9       timbl     545: <H2>Register an access method</H2>An access method is defined by an
                    546: HTProtocol structure which point
                    547: to the routines for performing the
                    548: various logical operations on an
                    549: object: in HTTP terms,  GET, PUT,
                    550: and POST.<P>
                    551: Each of these routine takes as a
                    552: parameter a <A
                    553: NAME="z2" HREF="#z1">request structure</A> containing
                    554: details ofthe request.  When the
                    555: protocol class routine is called,
                    556: the anchor elemnt in the request
                    557: is already valid (made valid by HTAccess).
                    558: <PRE>typedef struct _HTProtocol {
1.1       timbl     559:        char * name;
                    560:        
2.11      timbl     561:        int (*load)PARAMS((HTRequest *  request));
1.1       timbl     562:                
2.11      timbl     563:        HTStream* (*saveStream)PARAMS((HTRequest *      request));
                    564: 
2.9       timbl     565:        HTStream* (*postStream)PARAMS((
                    566:                                HTRequest *     request,
                    567:                                HTParentAnchor* postTo));
1.1       timbl     568: 
                    569: } HTProtocol;
                    570: 
                    571: extern BOOL HTRegisterProtocol PARAMS((HTProtocol * protocol));
                    572: 
                    573: 
2.5       timbl     574: </PRE>
                    575: <H2>Generate the anchor for the home
                    576: page</H2>
                    577: <PRE>
                    578: </PRE>As it involves file access, this
                    579: should only be done once when the
                    580: program first runs. This is a default
                    581: algorithm -- browser don't HAVE to
                    582: use this.
                    583: <PRE>extern HTParentAnchor * HTHomeAnchor NOPARAMS;
1.1       timbl     584: 
                    585: #endif /* HTACCESS_H */
2.11      timbl     586: 
2.19    ! timbl     587: </PRE>end of HTAccess</A></BODY>
2.9       timbl     588: </HTML>

Webmaster