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

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

Webmaster