diff options
author | Anil Madhavapeddy <avsm@cvs.openbsd.org> | 2003-05-01 18:59:41 +0000 |
---|---|---|
committer | Anil Madhavapeddy <avsm@cvs.openbsd.org> | 2003-05-01 18:59:41 +0000 |
commit | 83a9886c0ab87ef4a00fe5eaa007ca5619e8a528 (patch) | |
tree | 245e9a9e918b534bf00cbf3b6919a26e5594f053 /gnu/usr.bin/lynx/WWW | |
parent | 44b1bba2a33b56bcaa32d20a6c76f14845797fb0 (diff) |
Update to lynx-2.8.4-rel1, patchset d, now with IPv6 as well
Local patches we maintain to the distribution are:
- replace unbounded fscanf with fgets (avsm)
- spelling fixes (deraadt)
- hppa -O0 workaround (mickey)
- default to ftp passive (deraadt)
- work with non-exec scripts (deraadt,hin,maja)
- be more careful with rlogin username (art)
- default to our webpage (deraadt)
- install helpfiles locally (maja)
- mkdtemp temp space directory (art)
- install more recent config.guess (avsm)
Tested by beck,millert,grange,fries,miod and others, deraadt@ ok
Diffstat (limited to 'gnu/usr.bin/lynx/WWW')
75 files changed, 8952 insertions, 4905 deletions
diff --git a/gnu/usr.bin/lynx/WWW/FreeofCharge.html b/gnu/usr.bin/lynx/WWW/FreeofCharge.html new file mode 100644 index 00000000000..67cb3f20481 --- /dev/null +++ b/gnu/usr.bin/lynx/WWW/FreeofCharge.html @@ -0,0 +1,26 @@ +<!-- X-URL: http://www.w3.org/History/1993/WWW/Conditions/old/FreeofCharge.html --> +<BASE HREF="http://www.w3.org/History/1993/WWW/Conditions/old/FreeofCharge.html"> + +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + +<HTML><HEAD><TITLE> +CERN WWW software freely available</TITLE><NEXTID N="z9"></HEAD><BODY><H1> +Software freely available</H1>The following CERN software is hereby put into +the public domain. +<UL> +<LI>WWW basic ("line-mode") client <LI>WWW basic server <LI>WWW Library of +common code.</UL>CERN relinquishes all intellectual property rights to this +code, both source and binary form and permission is granted for anyone to use, +duplicate, +modify and redistribute it.<P>CERN provides absolutely NO WARRANTY OF ANY KIND +with respect to this software. +The entire risk as to the quality and performance of this software is with the +user. +IN NO EVENT WILL CERN BE LIABLE TO ANYONE FOR ANY DAMAGES ARISING OUT THE USE +OF THIS SOFTWARE, INCLUDING, WITHOUT LIMITATION, +DAMAGES RESULTING FROM LOST DATA OR LOST PROFITS, OR FOR ANY SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES.<P>This is part of the <A +HREF="Introduction.html" NAME="z8"> +CERN WWW</A> distribution condidtions.<P>Declaration to this effect signed by +the CERN directors of Administration (H. Weber) and Research (W. +Hoogland), May 1993.</BODY></HTML> diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAABrow.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAABrow.c index 0f72cc71bed..519030faa2d 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAABrow.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAABrow.c @@ -75,11 +75,11 @@ typedef struct { int portnumber; /* Port number */ BOOL IsProxy; /* Is it a proxy? */ HTList * setups; /* List of protection setups */ - /* on this server; i.e., valid */ - /* authentication schemes and */ - /* templates when to use them. */ - /* This is actually a list of */ - /* HTAASetup objects. */ + /* on this server; i.e., valid */ + /* authentication schemes and */ + /* templates when to use them. */ + /* This is actually a list of */ + /* HTAASetup objects. */ HTList * realms; /* Information about passwords */ } HTAAServer; @@ -90,7 +90,7 @@ typedef struct { typedef struct { HTAAServer *server; /* Which server serves this tree */ char * template; /* Template for this tree */ - HTList * valid_schemes; /* Valid authentic.schemes */ + HTList * valid_schemes; /* Valid authentic.schemes */ HTAssocList**scheme_specifics;/* Scheme specific params */ BOOL retry; /* Failed last time -- reprompt (or whatever)*/ } HTAASetup; @@ -119,14 +119,14 @@ PRIVATE char *compose_auth_stringResult = NULL; /* Uuencoded presentation */ PRIVATE HTList *server_table = NULL; /* Browser's info about servers */ PRIVATE char *secret_key = NULL; /* Browser's latest secret key */ PRIVATE HTAASetup *current_setup= NULL; /* The server setup we are currently */ - /* talking to */ + /* talking to */ PRIVATE char *current_hostname = NULL; /* The server's name and portnumber */ PRIVATE int current_portnumber = 80; /* where we are currently trying to */ - /* connect. */ -PRIVATE char *current_docname = NULL; /* The document's name we are */ - /* trying to access. */ + /* connect. */ +PRIVATE char *current_docname = NULL; /* The document's name we are */ + /* trying to access. */ PRIVATE char *HTAAForwardAuth = NULL; /* Authorization: line to forward */ - /* (used by gateway httpds) */ + /* (used by gateway httpds) */ PRIVATE HTAASetup *proxy_setup = NULL; /* Same as above, but for Proxy -AJL */ PRIVATE char *proxy_hostname = NULL; PRIVATE char *proxy_docname = NULL; @@ -140,10 +140,10 @@ PUBLIC void HTAAForwardAuth_set ARGS2( CONST char *, scheme_specifics) { int len = 20 + (scheme_name ? strlen(scheme_name) : 0) - + (scheme_specifics ? strlen(scheme_specifics) : 0); + + (scheme_specifics ? strlen(scheme_specifics) : 0); FREE(HTAAForwardAuth); - if (!(HTAAForwardAuth = (char*)calloc(1, sizeof(char) * len))) + if ((HTAAForwardAuth = typecallocn(char, len)) == 0) outofmem(__FILE__, "HTAAForwardAuth_set"); strcpy(HTAAForwardAuth, "Authorization: "); @@ -189,7 +189,7 @@ PRIVATE HTAAServer *HTAAServer_new ARGS3( { HTAAServer *server; - if (!(server = (HTAAServer *)calloc(1, sizeof(HTAAServer)))) + if ((server = typecalloc(HTAAServer)) == 0) outofmem(__FILE__, "HTAAServer_new"); server->hostname = NULL; @@ -199,10 +199,10 @@ PRIVATE HTAAServer *HTAAServer_new ARGS3( server->realms = HTList_new(); if (hostname) - StrAllocCopy(server->hostname, hostname); + StrAllocCopy(server->hostname, hostname); if (!server_table) - server_table = HTList_new(); + server_table = HTList_new(); HTList_addObject(server_table, (void*)server); @@ -233,8 +233,8 @@ PRIVATE void HTAAServer_delete ARGS1( if (killme->setups != NULL) { n = HTList_count(killme->setups); for (i = (n - 1); i >= 0; i--) { - if ((setup = (HTAASetup*)HTList_objectAt(killme->setups, - i)) != NULL) { + if ((setup = (HTAASetup*)HTList_objectAt(killme->setups, + i)) != NULL) { HTAASetup_delete(setup); setup = NULL; } @@ -310,7 +310,7 @@ PRIVATE HTAAServer *HTAAServer_lookup ARGS3( ** are trying to access. ** IsProxy should be TRUE if this is a proxy. ** -** This function goes through the information known about +** This function goes through the information known about ** all the setups of the server, and finds out if the given ** filename resides in one of the protected directories. ** @@ -331,7 +331,7 @@ PRIVATE HTAASetup *HTAASetup_lookup ARGS4( HTAASetup *setup; if (portnumber <= 0) - portnumber = 80; + portnumber = 80; if (hostname && docname && *hostname && *docname && NULL != (server = HTAAServer_lookup(hostname, @@ -340,29 +340,29 @@ PRIVATE HTAASetup *HTAASetup_lookup ARGS4( HTList *cur = server->setups; - CTRACE(tfp, "%s %s (%s:%d:%s)\n", + CTRACE((tfp, "%s %s (%s:%d:%s)\n", "HTAASetup_lookup: resolving setup for", (IsProxy ? "proxy" : "server"), - hostname, portnumber, docname); + hostname, portnumber, docname)); while (NULL != (setup = (HTAASetup*)HTList_nextObject(cur))) { if (HTAA_templateMatch(setup->template, docname)) { - CTRACE(tfp, "%s `%s' %s `%s'\n", + CTRACE((tfp, "%s `%s' %s `%s'\n", "HTAASetup_lookup:", docname, - "matched template", setup->template); + "matched template", setup->template)); return setup; } else { - CTRACE(tfp, "%s `%s' %s `%s'\n", + CTRACE((tfp, "%s `%s' %s `%s'\n", "HTAASetup_lookup:", docname, - "did NOT match template", setup->template); + "did NOT match template", setup->template)); } } /* while setups remain */ } /* if valid parameters and server found */ - CTRACE(tfp, "%s `%s' %s\n", + CTRACE((tfp, "%s `%s' %s\n", "HTAASetup_lookup: No template matched", - (docname ? docname : "(null)"), - "(so probably not protected)"); + NONNULL(docname), + "(so probably not protected)")); return NULL; /* NULL in parameters, or not found */ } @@ -395,16 +395,16 @@ PRIVATE HTAASetup *HTAASetup_new ARGS4( HTAASetup *setup; if (!server || !template || !*template) - return NULL; + return NULL; - if (!(setup = (HTAASetup*)calloc(1, sizeof(HTAASetup)))) + if ((setup = typecalloc(HTAASetup)) == 0) outofmem(__FILE__, "HTAASetup_new"); setup->retry = NO; setup->server = server; setup->template = NULL; if (template) - StrAllocCopy(setup->template, template); + StrAllocCopy(setup->template, template); setup->valid_schemes = valid_schemes; setup->scheme_specifics = scheme_specifics; @@ -428,9 +428,10 @@ PRIVATE void HTAASetup_delete ARGS1( if (killme) { FREE(killme->template); - if (killme->valid_schemes) + if (killme->valid_schemes) { HTList_delete(killme->valid_schemes); killme->valid_schemes = NULL; + } for (scheme = 0; scheme < HTAA_MAX_SCHEMES; scheme++) if (killme->scheme_specifics[scheme]) HTAssocList_delete(killme->scheme_specifics[scheme]); @@ -473,7 +474,7 @@ PRIVATE void HTAASetup_updateSpecifics ARGS2( /*************************** HTAARealm **********************************/ -/* PRIVATE HTAARealm_lookup() +/* PRIVATE HTAARealm_lookup() ** LOOKUP HTAARealm STRUCTURE BY REALM NAME ** ON ENTRY: ** realm_table a list of realm objects. @@ -524,7 +525,7 @@ PRIVATE HTAARealm *HTAARealm_new ARGS4( realm = HTAARealm_lookup(realm_table, realmname); if (!realm) { - if (!(realm = (HTAARealm*)calloc(1, sizeof(HTAARealm)))) + if ((realm = typecalloc(HTAARealm)) == 0) outofmem(__FILE__, "HTAARealm_new"); realm->realmname = NULL; realm->username = NULL; @@ -534,9 +535,9 @@ PRIVATE HTAARealm *HTAARealm_new ARGS4( HTList_addObject(realm_table, (void*)realm); } if (username) - StrAllocCopy(realm->username, username); + StrAllocCopy(realm->username, username); if (password) - StrAllocCopy(realm->password, password); + StrAllocCopy(realm->password, password); return realm; } @@ -594,16 +595,16 @@ PRIVATE char *compose_auth_string ARGS3( realmname = HTAssocList_lookup(setup->scheme_specifics[scheme], "realm"); if (!realmname) - return NULL; + return NULL; realm = HTAARealm_lookup(setup->server->realms, realmname); if (!(realm && - realm->username && *realm->username && + realm->username && *realm->username && realm->password) || setup->retry) { if (!realm) { - CTRACE(tfp, "%s `%s' %s\n", + CTRACE((tfp, "%s `%s' %s\n", "compose_auth_string: realm:", realmname, - "not found -- creating"); + "not found -- creating")); realm = HTAARealm_new(setup->server->realms, realmname, NULL, NULL); } @@ -620,7 +621,7 @@ PRIVATE char *compose_auth_string ARGS3( if ((!IsProxy) && using_proxy && setup->template) { proxiedHost = HTParse(setup->template, "", PARSE_HOST); if (proxiedHost && *proxiedHost != '\0') { - theHost = proxiedHost; + theHost = proxiedHost; } } /* @@ -630,10 +631,10 @@ PRIVATE char *compose_auth_string ARGS3( */ if (!theHost) theHost = setup->server->hostname; - if (setup->server->portnumber > 0 && - setup->server->portnumber != 80) { - HTSprintf0(&thePort, ":%d", setup->server->portnumber); - } + if (setup->server->portnumber > 0 && + setup->server->portnumber != 80) { + HTSprintf0(&thePort, ":%d", setup->server->portnumber); + } /* * Set up the message for the username prompt, * and then issue the prompt. The default @@ -643,7 +644,7 @@ PRIVATE char *compose_auth_string ARGS3( */ len = strlen(realm->realmname) + strlen(theHost ? - theHost : "??") + 50; + theHost : "??") + 50; HTSprintf0(&msg, gettext("Username for '%s' at %s '%s%s':"), realm->realmname, (IsProxy ? "proxy" : "server"), @@ -689,18 +690,18 @@ PRIVATE char *compose_auth_string ARGS3( FREE(secret_key); } - if (!(cleartext = (char*)calloc(1, sizeof(char) * len))) + if ((cleartext = typecallocn(char, len)) == 0) outofmem(__FILE__, "compose_auth_string"); if (realm->username) - strcpy(cleartext, realm->username); + strcpy(cleartext, realm->username); else - *cleartext = '\0'; + *cleartext = '\0'; strcat(cleartext, ":"); if (realm->password) - strcat(cleartext, realm->password); + strcat(cleartext, realm->password); if (scheme == HTAA_PUBKEY) { strcat(cleartext, ":"); @@ -711,9 +712,8 @@ PRIVATE char *compose_auth_string ARGS3( if (secret_key) strcat(cleartext, secret_key); - if (!((ciphertext = (char *)calloc(1, (sizeof(char) * 2) * len)) && - (compose_auth_stringResult = - (char *)calloc(1, (sizeof(char) * 3) * len)))) + if (!((ciphertext = typecallocn(char, 2 * len)) && + (compose_auth_stringResult = typecallocn(char, 3 * len)))) outofmem(__FILE__, "compose_auth_string"); #ifdef PUBKEY HTPK_encrypt(cleartext, ciphertext, server->public_key); @@ -725,7 +725,7 @@ PRIVATE char *compose_auth_string ARGS3( } else { /* scheme == HTAA_BASIC */ if (!(compose_auth_stringResult = - (char*)calloc(1, (4 * ((len+2)/3)) + 1))) + typecallocn(char, (4 * ((len+2)/3)) + 1))) outofmem(__FILE__, "compose_auth_string"); HTUU_encode((unsigned char *)cleartext, strlen(cleartext), compose_auth_stringResult); @@ -780,11 +780,11 @@ PRIVATE void free_HTAAGlobals NOARGS int n, i; if (server_table != NULL) { - n = HTList_count(server_table); + n = HTList_count(server_table); for (i = (n - 1); i >= 0; i--) { if ((server = (HTAAServer*)HTList_objectAt(server_table, - i)) != NULL) { - HTAAServer_delete(server); + i)) != NULL) { + HTAAServer_delete(server); server = NULL; } } @@ -838,7 +838,7 @@ PUBLIC char *HTAA_composeAuth ARGS4( */ if (!free_HTAAGlobalsSet) { #ifdef LY_FIND_LEAKS - atexit(free_HTAAGlobals); + atexit(free_HTAAGlobals); #endif free_HTAAGlobalsSet = TRUE; } @@ -853,8 +853,8 @@ PUBLIC char *HTAA_composeAuth ARGS4( ** on server-side. Life is hard.) */ if (HTAAForwardAuth) { - CTRACE(tfp, "HTAA_composeAuth: %s\n", - "Forwarding received authorization"); + CTRACE((tfp, "HTAA_composeAuth: %s\n", + "Forwarding received authorization")); StrAllocCopy(HTAA_composeAuthResult, HTAAForwardAuth); HTAAForwardAuth_reset(); /* Just a precaution */ return HTAA_composeAuthResult; @@ -863,15 +863,15 @@ PUBLIC char *HTAA_composeAuth ARGS4( FREE(HTAA_composeAuthResult); /* From previous call */ if (IsProxy) { - /* + /* ** Proxy Authorization required. - AJL */ - CTRACE(tfp, "Composing Proxy Authorization for %s:%d/%s\n", - hostname, portnumber, docname); + CTRACE((tfp, "Composing Proxy Authorization for %s:%d/%s\n", + hostname, portnumber, docname)); - if (proxy_portnumber != portnumber || - !proxy_hostname || !proxy_docname || + if (proxy_portnumber != portnumber || + !proxy_hostname || !proxy_docname || !hostname || !docname || 0 != strcmp(proxy_hostname, hostname) || 0 != strcmp(proxy_docname, docname)) { @@ -900,7 +900,7 @@ PUBLIC char *HTAA_composeAuth ARGS4( if (!proxy_setup) return NULL; - switch (scheme = HTAA_selectScheme(proxy_setup)) { + switch (scheme = HTAA_selectScheme(proxy_setup)) { case HTAA_BASIC: case HTAA_PUBKEY: auth_string = compose_auth_string(scheme, proxy_setup, IsProxy); @@ -934,7 +934,7 @@ PUBLIC char *HTAA_composeAuth ARGS4( return(HTAA_composeAuthResult); } len = strlen(auth_string) + strlen((char *)HTAAScheme_name(scheme)) + 26; - if (!(HTAA_composeAuthResult = (char*)calloc(1, sizeof(char) * len))) + if ((HTAA_composeAuthResult = typecallocn(char, len)) == 0) outofmem(__FILE__, "HTAA_composeAuth"); strcpy(HTAA_composeAuthResult, "Proxy-Authorization: "); @@ -942,8 +942,8 @@ PUBLIC char *HTAA_composeAuth ARGS4( /* ** Normal WWW authorization. */ - CTRACE(tfp, "Composing Authorization for %s:%d/%s\n", - hostname, portnumber, docname); + CTRACE((tfp, "Composing Authorization for %s:%d/%s\n", + hostname, portnumber, docname)); if (current_portnumber != portnumber || !current_hostname || !current_docname || @@ -1010,7 +1010,7 @@ PUBLIC char *HTAA_composeAuth ARGS4( } len = strlen(auth_string) + strlen((char *)HTAAScheme_name(scheme)) + 20; - if (!(HTAA_composeAuthResult = (char*)calloc(1, sizeof(char) * len))) + if ((HTAA_composeAuthResult = typecallocn(char, len)) == 0) outofmem(__FILE__, "HTAA_composeAuth"); strcpy(HTAA_composeAuthResult, "Authorization: "); } @@ -1068,7 +1068,7 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( */ if (!free_HTAAGlobalsSet) { #ifdef LY_FIND_LEAKS - atexit(free_HTAAGlobals); + atexit(free_HTAAGlobals); #endif free_HTAAGlobalsSet = TRUE; } @@ -1076,11 +1076,11 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( /* ** Read server reply header lines */ - CTRACE(tfp, "Server reply header lines:\n"); + CTRACE((tfp, "Server reply header lines:\n")); HTAA_setupReader(start_of_headers, length, soc); while (NULL != (line = HTAA_getUnfoldedLine()) && *line != '\0') { - CTRACE(tfp, "%s\n", line); + CTRACE((tfp, "%s\n", line)); if (strchr(line, ':')) { /* Valid header line */ @@ -1091,9 +1091,9 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( if ((IsProxy && 0==strcasecomp(fieldname, "Proxy-Authenticate:")) || - (!IsProxy && + (!IsProxy && 0==strcasecomp(fieldname, "WWW-Authenticate:"))) { - if (!(arg1 && *arg1 && args && *args)) { + if (!(arg1 && *arg1 && args && *args)) { HTSprintf0(&temp, gettext("Invalid header '%s%s%s%s%s'"), line, ((arg1 && *arg1) ? " " : ""), ((arg1 && *arg1) ? arg1 : ""), @@ -1106,8 +1106,8 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( HTList_addObject(valid_schemes, (void*)scheme); if (!scheme_specifics) { int i; - scheme_specifics = (HTAssocList**) - calloc(1, HTAA_MAX_SCHEMES * sizeof(HTAssocList*)); + scheme_specifics = + typecallocn(HTAssocList *, HTAA_MAX_SCHEMES); if (!scheme_specifics) outofmem(__FILE__, "HTAA_shouldRetryWithAuth"); for (i=0; i < HTAA_MAX_SCHEMES; i++) @@ -1116,23 +1116,23 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( scheme_specifics[scheme] = HTAA_parseArgList(args); num_schemes++; } else { - CTRACE(tfp, "Unknown scheme `%s' %s\n", - (arg1 ? arg1 : "(null)"), + CTRACE((tfp, "Unknown scheme `%s' %s\n", + NONNULL(arg1), (IsProxy ? "in Proxy-Authenticate: field" : - "in WWW-Authenticate: field")); + "in WWW-Authenticate: field"))); } } else if (!IsProxy && 0==strcasecomp(fieldname, "WWW-Protection-Template:")) { - CTRACE(tfp, "Protection template set to `%s'\n", arg1); + CTRACE((tfp, "Protection template set to `%s'\n", arg1)); StrAllocCopy(template, arg1); } } /* if a valid header line */ else { - CTRACE(tfp, "Invalid header line `%s' ignored\n", line); + CTRACE((tfp, "Invalid header line `%s' ignored\n", line)); } /* else invalid header line */ FREE(line); @@ -1151,7 +1151,7 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( proxy_setup = NULL; return NO; } - /* + /* ** Doing it for proxy. -AJL */ if (proxy_setup && proxy_setup->server) { @@ -1169,7 +1169,7 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( proxy_setup = NULL; return NO; } else { - /* + /* ** Re-ask username+password (if misspelled). */ proxy_setup->retry = YES; @@ -1235,7 +1235,7 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( return YES; } } else { - /* + /* ** current_setup == NULL, i.e., we have a ** first connection to a protected server or ** the server serves a wider set of documents @@ -1257,7 +1257,7 @@ PUBLIC BOOL HTAA_shouldRetryWithAuth ARGS4( scheme_specifics); FREE(template); - HTAlert(gettext("Access without authorization denied -- retrying")); + HTAlert(gettext("Access without authorization denied -- retrying")); return YES; } /* Never reached */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAProt.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAProt.c index cddfa1c48d6..6821068f383 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAProt.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAProt.c @@ -30,6 +30,7 @@ #include <HTLex.h> /* Lexical analysor */ #include <HTAAProt.h> /* Implemented here */ +#include <LYUtils.h> #include <LYLeaks.h> #define NOBODY 65534 /* -2 in 16-bit environment */ @@ -46,11 +47,11 @@ typedef struct { PRIVATE HTList * prot_cache = NULL; /* Protection setup cache. */ PRIVATE HTAAProt *default_prot = NULL; /* Default protection. */ PRIVATE HTAAProt *current_prot = NULL; /* Current protection mode */ - /* which is set up by callbacks */ - /* from the rule system when */ - /* a "protect" rule is matched. */ - + /* which is set up by callbacks */ + /* from the rule system when */ + /* a "protect" rule is matched. */ +#ifndef NOUSERS /* PRIVATE isNumber() ** DOES A CHARACTER STRING REPRESENT A NUMBER */ @@ -70,6 +71,7 @@ PRIVATE BOOL isNumber ARGS1(CONST char *, s) } return YES; } +#endif /* !NOUSERS */ #if defined (NOUSERS) @@ -85,7 +87,7 @@ PRIVATE BOOL isNumber ARGS1(CONST char *, s) PUBLIC char * HTAA_getUidName NOARGS { if (current_prot && current_prot->uid_name - && (0 != strcmp(current_prot->uid_name,"nobody")) ) + && (0 != strcmp(current_prot->uid_name,"nobody")) ) return(current_prot->uid_name); else return(""); @@ -256,8 +258,8 @@ PRIVATE void HTAA_parseProtFile ARGS2(HTAAProt *, prot, if (LEX_FIELD_SEP != (lex_item = lex(fp))) unlex(lex_item); /* If someone wants to use colon */ - /* after field name it's ok, but */ - /* not required. Here we read it.*/ + /* after field name it's ok, but */ + /* not required. Here we read it.*/ if (0==strncasecomp(fieldname, "Auth", 4)) { lex_item = lex(fp); @@ -267,15 +269,15 @@ PRIVATE void HTAA_parseProtFile ARGS2(HTAAProt *, prot, if (!prot->valid_schemes) prot->valid_schemes = HTList_new(); HTList_addObject(prot->valid_schemes,(void*)scheme); - CTRACE(tfp, "%s %s `%s'\n", - "HTAA_parseProtFile: valid", - "authentication scheme:", - HTAAScheme_name(scheme)); + CTRACE((tfp, "%s %s `%s'\n", + "HTAA_parseProtFile: valid", + "authentication scheme:", + HTAAScheme_name(scheme))); } else { - CTRACE(tfp, "%s %s `%s'\n", + CTRACE((tfp, "%s %s `%s'\n", "HTAA_parseProtFile: unknown", "authentication scheme:", - HTlex_buffer); + HTlex_buffer)); } if (LEX_ITEM_SEP != (lex_item = lex(fp))) @@ -310,19 +312,19 @@ PRIVATE void HTAA_parseProtFile ARGS2(HTAAProt *, prot, prot->values = HTAssocList_new(); HTAssocList_add(prot->values, fieldname, HTlex_buffer); lex_item = lex(fp); /* Read record separator */ - CTRACE(tfp, "%s `%s' bound to value `%s'\n", + CTRACE((tfp, "%s `%s' bound to value `%s'\n", "HTAA_parseProtFile: Name", - fieldname, HTlex_buffer); + fieldname, HTlex_buffer)); } } /* else name-value pair */ } /* if valid field */ if (lex_item != LEX_EOF && lex_item != LEX_REC_SEP) { - CTRACE(tfp, "%s %s %d (that line ignored)\n", + CTRACE((tfp, "%s %s %d (that line ignored)\n", "HTAA_parseProtFile: Syntax error", "in protection setup file at line", - HTlex_line); + HTlex_line)); do { lex_item = lex(fp); } while (lex_item != LEX_EOF && lex_item != LEX_REC_SEP); @@ -377,13 +379,13 @@ PRIVATE HTAAProt *HTAAProt_new ARGS3(CONST char *, cur_docname, } if (cache_item) { prot = cache_item->prot; - CTRACE(tfp, "%s `%s' already in cache\n", - "HTAAProt_new: Protection file", prot_filename); + CTRACE((tfp, "%s `%s' already in cache\n", + "HTAAProt_new: Protection file", prot_filename)); } else { - CTRACE(tfp, "HTAAProt_new: Loading protection file `%s'\n", - prot_filename); + CTRACE((tfp, "HTAAProt_new: Loading protection file `%s'\n", + prot_filename)); - if (!(prot = (HTAAProt*)calloc(1, sizeof(HTAAProt)))) + if ((prot = typecalloc(HTAAProt)) == 0) outofmem(__FILE__, "HTAAProt_new"); prot->template = NULL; @@ -394,20 +396,19 @@ PRIVATE HTAAProt *HTAAProt_new ARGS3(CONST char *, cur_docname, prot->mask_group= NULL; /* Masking disabled by defaults */ prot->values = HTAssocList_new(); - if (prot_filename && NULL != (fp = fopen(prot_filename, "r"))) { + if (prot_filename && NULL != (fp = fopen(prot_filename, TXT_R))) { HTAA_parseProtFile(prot, fp); fclose(fp); - if (!(cache_item = - (HTAAProtCache*)calloc(1, sizeof(HTAAProtCache)))) + if ((cache_item = typecalloc(HTAAProtCache)) == 0) outofmem(__FILE__, "HTAAProt_new"); cache_item->prot = prot; cache_item->prot_filename = NULL; StrAllocCopy(cache_item->prot_filename, prot_filename); HTList_addObject(prot_cache, (void*)cache_item); } else { - CTRACE(tfp, "HTAAProt_new: %s `%s'\n", + CTRACE((tfp, "HTAAProt_new: %s `%s'\n", "Unable to open protection setup file", - (prot_filename ? prot_filename : "(null)")); + NONNULL(prot_filename))); } } @@ -447,9 +448,9 @@ PUBLIC void HTAA_setDefaultProtection ARGS3(CONST char *, cur_docname, if (prot_filename) { default_prot = HTAAProt_new(cur_docname, prot_filename, ids); } else { - CTRACE(tfp, "%s %s\n", + CTRACE((tfp, "%s %s\n", "HTAA_setDefaultProtection: ERROR: Protection file", - "not specified (obligatory for DefProt rule)!!\n"); + "not specified (obligatory for DefProt rule)!!\n")); } } @@ -485,15 +486,15 @@ PUBLIC void HTAA_setCurrentProtection ARGS3(CONST char *, cur_docname, if (default_prot) { current_prot = default_prot; HTAA_setIds(current_prot, ids); - CTRACE(tfp, "%s %s %s\n", - "HTAA_setCurrentProtection: Protection file", - "not specified for Protect rule", - "-- using default protection"); + CTRACE((tfp, "%s %s %s\n", + "HTAA_setCurrentProtection: Protection file", + "not specified for Protect rule", + "-- using default protection")); } else { - CTRACE(tfp, "%s %s %s\n", - "HTAA_setCurrentProtection: ERROR: Protection", - "file not specified for Protect rule, and", - "default protection is not set!!"); + CTRACE((tfp, "%s %s %s\n", + "HTAA_setCurrentProtection: ERROR: Protection", + "file not specified for Protect rule, and", + "default protection is not set!!")); } } } @@ -570,17 +571,20 @@ PUBLIC void HTAA_clearProtections NOARGS } typedef struct { - char *name; + char *name; int user; - } USER_DATA; + } USER_DATA; +#ifndef NOUSERS PRIVATE HTList *known_grp = NULL; PRIVATE HTList *known_pwd = NULL; PRIVATE BOOL uidgid_cache_inited = NO; +#endif #ifdef LY_FIND_LEAKS PRIVATE void clear_uidgid_cache NOARGS { +#ifndef NOUSERS USER_DATA *data; if (known_grp) { while ((data = HTList_removeLastObject(known_grp)) != NULL) { @@ -596,12 +600,14 @@ PRIVATE void clear_uidgid_cache NOARGS } FREE(known_pwd); } +#endif } #endif /* LY_FIND_LEAKS */ +#ifndef NOUSERS PRIVATE void save_gid_info ARGS2(char *, name, int, user) { - USER_DATA *data = (USER_DATA *)calloc(1, sizeof(USER_DATA)); + USER_DATA *data = typecalloc(USER_DATA); if (!data) return; if (!known_grp) { @@ -617,10 +623,12 @@ PRIVATE void save_gid_info ARGS2(char *, name, int, user) data->user = user; HTList_addObject (known_grp, data); } +#endif /* NOUSERS */ +#ifndef NOUSERS PRIVATE void save_uid_info ARGS2(char *, name, int, user) { - USER_DATA *data = (USER_DATA *)calloc(1, sizeof(USER_DATA)); + USER_DATA *data = typecalloc(USER_DATA); if (!data) return; if (!known_pwd) { @@ -636,9 +644,10 @@ PRIVATE void save_uid_info ARGS2(char *, name, int, user) data->user = user; HTList_addObject (known_pwd, data); } +#endif /* !NOUSERS */ -/* PUBLIC HTAA_UidToName -** GET THE USER NAME +/* PUBLIC HTAA_UidToName +** GET THE USER NAME ** ON ENTRY: ** The user-id ** @@ -659,10 +668,10 @@ PUBLIC char * HTAA_UidToName ARGS1(int, uid) if ((pw = getpwuid(uid)) != 0 && pw->pw_name != 0) { - CTRACE(tfp, "%s(%d) returned (%s:%d:...)\n", + CTRACE((tfp, "%s(%d) returned (%s:%d:...)\n", "HTAA_UidToName: getpwuid", uid, - pw->pw_name, (int) pw->pw_uid); + pw->pw_name, (int) pw->pw_uid)); save_uid_info(pw->pw_name, (int) pw->pw_uid); return pw->pw_name; } @@ -670,8 +679,8 @@ PUBLIC char * HTAA_UidToName ARGS1(int, uid) return ""; } -/* PUBLIC HTAA_NameToUid -** GET THE USER ID +/* PUBLIC HTAA_NameToUid +** GET THE USER ID ** ON ENTRY: ** The user-name ** @@ -691,10 +700,10 @@ PUBLIC int HTAA_NameToUid ARGS1(char *, name) } if ((pw = getpwnam(name)) != 0) { - CTRACE(tfp, "%s(%s) returned (%s:%d:...)\n", + CTRACE((tfp, "%s(%s) returned (%s:%d:...)\n", "HTAA_NameToUid: getpwnam", name, - pw->pw_name, (int) pw->pw_uid); + pw->pw_name, (int) pw->pw_uid)); save_uid_info(pw->pw_name, (int) pw->pw_uid); return (int) pw->pw_uid; } @@ -702,8 +711,8 @@ PUBLIC int HTAA_NameToUid ARGS1(char *, name) return NONESUCH; } -/* PUBLIC HTAA_GidToName -** GET THE GROUP NAME +/* PUBLIC HTAA_GidToName +** GET THE GROUP NAME ** ON ENTRY: ** The group-id ** @@ -724,10 +733,10 @@ PUBLIC char * HTAA_GidToName ARGS1(int, gid) if ((gr = getgrgid(gid)) != 0 && gr->gr_name != 0) { - CTRACE(tfp, "%s(%d) returned (%s:%d:...)\n", + CTRACE((tfp, "%s(%d) returned (%s:%d:...)\n", "HTAA_GidToName: getgrgid", gid, - gr->gr_name, (int) gr->gr_gid); + gr->gr_name, (int) gr->gr_gid)); save_gid_info(gr->gr_name, (int) gr->gr_gid); return gr->gr_name; } @@ -735,8 +744,8 @@ PUBLIC char * HTAA_GidToName ARGS1(int, gid) return ""; } -/* PUBLIC HTAA_NameToGid -** GET THE GROUP ID +/* PUBLIC HTAA_NameToGid +** GET THE GROUP ID ** ON ENTRY: ** The group-name ** @@ -756,10 +765,10 @@ PUBLIC int HTAA_NameToGid ARGS1(char *, name) } if ((gr = getgrnam(name)) != 0) { - CTRACE(tfp, "%s(%s) returned (%s:%d:...)\n", + CTRACE((tfp, "%s(%s) returned (%s:%d:...)\n", "HTAA_NameToGid: getgrnam", name, - gr->gr_name, (int) gr->gr_gid); + gr->gr_name, (int) gr->gr_gid)); save_gid_info(gr->gr_name, (int) gr->gr_gid); return (int) gr->gr_gid; } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAUtil.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAUtil.c index 20463162247..25d24aa67b0 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAUtil.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAAUtil.c @@ -48,11 +48,9 @@ #include <HTAAUtil.h> /* Implemented here */ #include <HTAssoc.h> /* Assoc list */ #include <HTTCP.h> +#include <HTTP.h> #ifdef USE_SSL -#define free_func free__func -#include <openssl/ssl.h> -#undef free_func PRIVATE SSL * Handle = NULL; /* The SSL Handle */ #endif /* USE_SSL */ @@ -197,7 +195,7 @@ PUBLIC BOOL HTAAMethod_inList ARGS2(HTAAMethod, method, char *item; while (NULL != (item = (char*)HTList_nextObject(cur))) { - CTRACE(tfp, " %s", item); + CTRACE((tfp, " %s", item)); if (method == HTAAMethod_enum(item)) return YES; } @@ -346,8 +344,8 @@ PUBLIC char *HTAA_makeProtectionTemplate ARGS1(CONST char *, docname) else StrAllocCopy(template, "*"); - CTRACE(tfp, "make_template: made template `%s' for file `%s'\n", - template, docname); + CTRACE((tfp, "make_template: made template `%s' for file `%s'\n", + template, docname)); return template; } @@ -550,9 +548,9 @@ PUBLIC char *HTAA_getUnfoldedLine NOARGS BOOL peek_for_folding = NO; if (in_soc < 0) { - CTRACE(tfp, "%s %s\n", + CTRACE((tfp, "%s %s\n", "HTAA_getUnfoldedLine: buffer not initialized", - "with function HTAA_setupReader()"); + "with function HTAA_setupReader()")); return NULL; } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.c index d0a25dbcc06..61097ce34ab 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.c @@ -64,14 +64,13 @@ #include <LYUtils.h> #include <LYLeaks.h> -extern HTCJKlang HTCJK; - /* ** These flags may be set to modify the operation of this module */ PUBLIC char * HTClientHost = NULL; /* Name of remote login host if any */ PUBLIC FILE * HTlogfile = NULL; /* File to which to output one-liners */ PUBLIC BOOL HTSecure = NO; /* Disable access for telnet users? */ +PUBLIC BOOL HTPermitRedir = NO; /* Always allow redirection in getfile()? */ PUBLIC BOOL using_proxy = NO; /* are we using a proxy gateway? */ @@ -268,15 +267,16 @@ PUBLIC BOOL override_proxy ARGS1( } Host = (((at = strchr(host, '@')) != NULL) ? (at+1) : host); - if ((acc_method = HTParse(addr, "", PARSE_ACCESS))) { - if (!strcmp("file", acc_method) && - (!strcmp(Host, "localhost") || #ifdef VMS - !strcasecomp(Host, HTHostName()) +#define CompareHostname(a,b) strcasecomp(a, b) #else - !strcmp(Host, HTHostName()) +#define CompareHostname(a,b) strcmp(a, b) #endif /* VMS */ - )) { + + if ((acc_method = HTParse(addr, "", PARSE_ACCESS))) { + if (!strcmp("file", acc_method) && + (!strcmp(Host, "localhost") || + !CompareHostname(Host, HTHostName()))) { FREE(host); FREE(acc_method); return YES; @@ -315,6 +315,9 @@ PUBLIC BOOL override_proxy ARGS1( #ifndef DISABLE_FINGER else if (!strcmp(acc_method, "finger")) port = 79; #endif + else if (!strcmp(acc_method, "telnet")) port = 23; + else if (!strcmp(acc_method, "tn3270")) port = 23; + else if (!strcmp(acc_method, "rlogin")) port = 513; FREE(acc_method); } } @@ -351,6 +354,15 @@ PUBLIC BOOL override_proxy ARGS1( FREE(host); return YES; } +#ifdef CJK_EX /* ASATAKU PROXY HACK */ + if ((!templ_port || templ_port == port) && + (t_len > 0 && t_len <= h_len && + isdigit(UCH(*no_proxy)) && !strncmp(host, no_proxy, t_len))) { + FREE(host); + return YES; + } +#endif /* ASATAKU PROXY HACK */ + if (*end) no_proxy = (end + 1); else @@ -379,23 +391,40 @@ PRIVATE int get_physical ARGS2( char * acc_method = NULL; /* Name of access method */ char * physical = NULL; char * Server_addr = NULL; + BOOL override_flag = NO; + + /* + ** Make sure the using_proxy variable is FALSE. + */ + using_proxy = NO; #ifndef NO_RULES physical = HTTranslate(addr); if (!physical) { + if (redirecting_url) { + return HT_REDIRECTING; + } return HT_FORBIDDEN; } if (anchor->isISMAPScript == TRUE) { StrAllocCat(physical, "?0,0"); - CTRACE(tfp, "HTAccess: Appending '?0,0' coordinate pair.\n"); + CTRACE((tfp, "HTAccess: Appending '?0,0' coordinate pair.\n")); + } + if (!strncmp(physical, "Proxied=", 8)) { + HTAnchor_setPhysical(anchor, physical + 8); + using_proxy = YES; + } else if (!strncmp(physical, "NoProxy=", 8)) { + HTAnchor_setPhysical(anchor, physical + 8); + override_flag = YES; + } else { + HTAnchor_setPhysical(anchor, physical); } - HTAnchor_setPhysical(anchor, physical); FREE(physical); /* free our copy */ #else if (anchor->isISMAPScript == TRUE) { StrAllocCopy(physical, addr); StrAllocCat(physical, "?0,0"); - CTRACE(tfp, "HTAccess: Appending '?0,0' coordinate pair.\n"); + CTRACE((tfp, "HTAccess: Appending '?0,0' coordinate pair.\n")); HTAnchor_setPhysical(anchor, physical); FREE(physical); /* free our copy */ } else { @@ -410,65 +439,63 @@ PRIVATE int get_physical ARGS2( ** Check whether gateway access has been set up for this. ** ** This function can be replaced by the rule system above. + ** + ** If the rule system has already determined that we should + ** use a proxy, or that we shouldn't, ignore proxy-related + ** settings, don't use no_proxy either. */ #define USE_GATEWAYS #ifdef USE_GATEWAYS - /* - ** Make sure the using_proxy variable is FALSE. - */ - using_proxy = NO; - if (!strcasecomp(acc_method, "news")) { - /* - ** News is different, so we need to check the name of the server, - ** as well as the default port for selective exclusions. - */ - char *host = NULL; - if ((host = HTParse(addr, "", PARSE_HOST))) { - if (strchr(host, ':') == NULL) { + if (!override_flag && !using_proxy) { /* else ignore no_proxy env var */ + if (!strcasecomp(acc_method, "news")) { + /* + ** News is different, so we need to check the name of the server, + ** as well as the default port for selective exclusions. + */ + char *host = NULL; + if ((host = HTParse(addr, "", PARSE_HOST))) { + if (strchr(host, ':') == NULL) { + StrAllocCopy(Server_addr, "news://"); + StrAllocCat(Server_addr, host); + StrAllocCat(Server_addr, ":119/"); + } + FREE(host); + } else if (getenv("NNTPSERVER") != NULL) { StrAllocCopy(Server_addr, "news://"); - StrAllocCat(Server_addr, host); + StrAllocCat(Server_addr, (char *)getenv("NNTPSERVER")); StrAllocCat(Server_addr, ":119/"); } - FREE(host); - } else if (getenv("NNTPSERVER") != NULL) { - StrAllocCopy(Server_addr, "news://"); - StrAllocCat(Server_addr, (char *)getenv("NNTPSERVER")); - StrAllocCat(Server_addr, ":119/"); - } - } else if (!strcasecomp(acc_method, "wais")) { - /* + } else if (!strcasecomp(acc_method, "wais")) { + /* ** Wais also needs checking of the default port ** for selective exclusions. */ - char *host = NULL; - if ((host = HTParse(addr, "", PARSE_HOST))) { - if (!(strchr(host, ':'))) { - StrAllocCopy(Server_addr, "wais://"); - StrAllocCat(Server_addr, host); - StrAllocCat(Server_addr, ":210/"); + char *host = NULL; + if ((host = HTParse(addr, "", PARSE_HOST))) { + if (!(strchr(host, ':'))) { + StrAllocCopy(Server_addr, "wais://"); + StrAllocCat(Server_addr, host); + StrAllocCat(Server_addr, ":210/"); + } + FREE(host); } - FREE(host); - } - else + else + StrAllocCopy(Server_addr, addr); + } else { StrAllocCopy(Server_addr, addr); - } else { - StrAllocCopy(Server_addr, addr); + } + override_flag = override_proxy(Server_addr); } - if (!override_proxy(Server_addr)) { - char * gateway_parameter, *gateway, *proxy; + if (!override_flag && !using_proxy) { + char * gateway_parameter = NULL, *gateway, *proxy; /* ** Search for gateways. */ - gateway_parameter = (char *)calloc(1, (strlen(acc_method) + 20)); - if (gateway_parameter == NULL) - outofmem(__FILE__, "HTLoad"); - strcpy(gateway_parameter, "WWW_"); - strcat(gateway_parameter, acc_method); - strcat(gateway_parameter, "_GATEWAY"); - gateway = (char *)getenv(gateway_parameter); /* coerce for decstation */ + HTSprintf0(&gateway_parameter, "WWW_%s_GATEWAY", acc_method); + gateway = getenv(gateway_parameter); /* coerce for decstation */ /* ** Search for proxy servers. @@ -477,17 +504,16 @@ PRIVATE int get_physical ARGS2( /* ** If we got to here, a file URL is for ftp on a remote host. - FM */ - strcpy(gateway_parameter, "ftp"); + strcpy(gateway_parameter, "ftp_proxy"); else - strcpy(gateway_parameter, acc_method); - strcat(gateway_parameter, "_proxy"); - proxy = (char *)getenv(gateway_parameter); + sprintf(gateway_parameter, "%s_proxy", acc_method); + proxy = getenv(gateway_parameter); FREE(gateway_parameter); if (gateway) - CTRACE(tfp, "Gateway found: %s\n", gateway); + CTRACE((tfp, "Gateway found: %s\n", gateway)); if (proxy) - CTRACE(tfp, "proxy server found: %s\n", proxy); + CTRACE((tfp, "proxy server found: %s\n", proxy)); /* ** Proxy servers have precedence over gateway servers. @@ -495,6 +521,14 @@ PRIVATE int get_physical ARGS2( if (proxy) { char * gatewayed = NULL; StrAllocCopy(gatewayed,proxy); + if (!strncmp(gatewayed, "http", 4)) { + char *cp = strrchr(gatewayed, '/'); + /* Append a slash to the proxy specification if it doesn't + * end in one but otherwise looks normal (starts with "http", + * has no '/' other than ones before the hostname). - kw */ + if (cp && (cp - gatewayed) <= 7) + LYAddHtmlSep(&gatewayed); + } /* ** Ensure that the proxy server uses ftp for file URLs. - FM */ @@ -578,13 +612,16 @@ PUBLIC void LYUCPushAssumed ARGS1( if (anchor_UCI && anchor_UCI->MIMEname) { pushed_assume_MIMEname = UCAssume_MIMEcharset; UCAssume_MIMEcharset = NULL; + if (HTCJK == JAPANESE) + StrAllocCopy(UCAssume_MIMEcharset, pushed_assume_MIMEname); + else StrAllocCopy(UCAssume_MIMEcharset, anchor_UCI->MIMEname); pushed_assume_LYhndl = anchor_LYhndl; /* some diagnostics */ if (UCLYhndl_for_unspec != anchor_LYhndl) - CTRACE(tfp, "LYUCPushAssumed: UCLYhndl_for_unspec changed %d -> %d\n", + CTRACE((tfp, "LYUCPushAssumed: UCLYhndl_for_unspec changed %d -> %d\n", UCLYhndl_for_unspec, - anchor_LYhndl); + anchor_LYhndl)); UCLYhndl_for_unspec = anchor_LYhndl; return; } @@ -603,9 +640,9 @@ PUBLIC int LYUCPopAssumed NOARGS if (pushed_assume_LYhndl >= 0) { /* some diagnostics */ if (UCLYhndl_for_unspec != pushed_assume_LYhndl) - CTRACE(tfp, "LYUCPopAssumed: UCLYhndl_for_unspec changed %d -> %d\n", + CTRACE((tfp, "LYUCPopAssumed: UCLYhndl_for_unspec changed %d -> %d\n", UCLYhndl_for_unspec, - pushed_assume_LYhndl); + pushed_assume_LYhndl)); UCLYhndl_for_unspec = pushed_assume_LYhndl; pushed_assume_LYhndl = -1; FREE(UCAssume_MIMEcharset); @@ -641,11 +678,17 @@ PRIVATE int HTLoad ARGS4( HTProtocol *p; int status = get_physical(addr, anchor); if (status == HT_FORBIDDEN) { + /* prevent crash if telnet or similar was forbidden by rule. - kw */ + LYFixCursesOn("show alert:"); return HTLoadError(sink, 500, gettext("Access forbidden by rule")); + } else if (status == HT_REDIRECTING) { + return status; /* fake redirection by rule, to redirecting_url */ } if (status < 0) return status; /* Can't resolve or forbidden */ + /* prevent crash if telnet or similar mapped or proxied by rule. - kw */ + LYFixCursesOnForAccess(addr, HTAnchor_physical(anchor)); p = (HTProtocol *)HTAnchor_protocol(anchor); anchor->underway = TRUE; /* Hack to deal with caching */ status= (*(p->load))(HTAnchor_physical(anchor), @@ -668,6 +711,8 @@ PUBLIC HTStream *HTSaveStream ARGS1( return (*p->saveStream)(anchor); } +PUBLIC int redirection_attempts = 0; /* counter in HTLoadDocument */ + /* Load a document - with logging etc HTLoadDocument() ** ---------------------------------- ** @@ -697,9 +742,8 @@ PRIVATE BOOL HTLoadDocument ARGS4( CONST char * address_to_load = full_address; char *cp; BOOL ForcingNoCache = LYforce_no_cache; - static int redirection_attempts = 0; - CTRACE (tfp, "HTAccess: loading document %s\n", address_to_load); + CTRACE((tfp, "HTAccess: loading document %s\n", address_to_load)); /* ** Free use_this_url_instead and reset permanent_redirection @@ -755,9 +799,9 @@ PRIVATE BOOL HTLoadDocument ARGS4( !strncmp(cp, "Location=", 9)) { DocAddress NewDoc; - CTRACE (tfp, "HTAccess: '%s' is a redirection URL.\n", - anchor->address); - CTRACE (tfp, "HTAccess: Redirecting to '%s'\n", cp+9); + CTRACE((tfp, "HTAccess: '%s' is a redirection URL.\n", + anchor->address)); + CTRACE((tfp, "HTAccess: Redirecting to '%s'\n", cp+9)); /* ** Don't exceed the redirection_attempts limit. - FM @@ -779,7 +823,7 @@ PRIVATE BOOL HTLoadDocument ARGS4( NewDoc.bookmark = anchor->bookmark; NewDoc.isHEAD = anchor->isHEAD; NewDoc.safe = anchor->safe; - anchor = (HTParentAnchor *)HTAnchor_findAddress(&NewDoc); + anchor = HTAnchor_parent(HTAnchor_findAddress(&NewDoc)); } } /* @@ -855,7 +899,7 @@ PRIVATE BOOL HTLoadDocument ARGS4( strncmp(full_address, "LYNXIMGMAP:", 11))) #endif /* TRACK_INTERNAL_LINKS */ { - CTRACE(tfp, "HTAccess: Document already in memory.\n"); + CTRACE((tfp, "HTAccess: Document already in memory.\n")); HText_select(text); #ifdef DIRED_SUPPORT @@ -866,7 +910,7 @@ PRIVATE BOOL HTLoadDocument ARGS4( return YES; } else { ForcingNoCache = YES; - CTRACE(tfp, "HTAccess: Auto-reloading document.\n"); + CTRACE((tfp, "HTAccess: Auto-reloading document.\n")); } } @@ -881,7 +925,7 @@ PRIVATE BOOL HTLoadDocument ARGS4( FREE(anchor->title); } status = HTLoad(address_to_load, anchor, format_out, sink); - CTRACE(tfp, "HTAccess: status=%d\n", status); + CTRACE((tfp, "HTAccess: status=%d\n", status)); /* ** Log the access if necessary. @@ -895,11 +939,11 @@ PRIVATE BOOL HTLoadDocument ARGS4( status < 0 ? "FAIL" : "GET", full_address); fflush(HTlogfile); /* Actually update it on disk */ - CTRACE(tfp, "Log: %24.24s %s %s %s\n", + CTRACE((tfp, "Log: %24.24s %s %s %s\n", ctime(&theTime), HTClientHost ? HTClientHost : "local", status < 0 ? "FAIL" : "GET", - full_address); + full_address)); } /* @@ -923,11 +967,18 @@ PRIVATE BOOL HTLoadDocument ARGS4( ** So, instead, we'll go all the way back to the top of getfile ** in LYGetFile.c when the status is HT_REDIRECTING. This may ** seem bizarre, but it works like a charm! - FM + ** + ** Actually, the location header for redirections is now again + ** picked up in HTMIME.c. But that's an internal matter between + ** HTTP.c and HTMIME.c, is still under control of HTLoadHTTP for + ** http URLs, is done in a way that doesn't load the redirection + ** response's body (except when wanted as an error fallback), and + ** thus need not concern us here. - kw 1999-12-02 */ - CTRACE(tfp, "HTAccess: '%s' is a redirection URL.\n", - address_to_load); - CTRACE(tfp, "HTAccess: Redirecting to '%s'\n", - redirecting_url); + CTRACE((tfp, "HTAccess: '%s' is a redirection URL.\n", + address_to_load)); + CTRACE((tfp, "HTAccess: Redirecting to '%s'\n", + redirecting_url)); /* ** Prevent circular references. */ @@ -967,32 +1018,32 @@ PRIVATE BOOL HTLoadDocument ARGS4( permanent_redirection = FALSE; if (status == HT_LOADED) { - CTRACE(tfp, "HTAccess: `%s' has been accessed.\n", - full_address); + CTRACE((tfp, "HTAccess: `%s' has been accessed.\n", + full_address)); return YES; } if (status == HT_PARTIAL_CONTENT) { HTAlert(gettext("Loading incomplete.")); - CTRACE(tfp, "HTAccess: `%s' has been accessed, partial content.\n", - full_address); + CTRACE((tfp, "HTAccess: `%s' has been accessed, partial content.\n", + full_address)); return YES; } if (status == HT_NO_DATA) { - CTRACE(tfp, "HTAccess: `%s' has been accessed, No data left.\n", - full_address); + CTRACE((tfp, "HTAccess: `%s' has been accessed, No data left.\n", + full_address)); return NO; } if (status == HT_NOT_LOADED) { - CTRACE(tfp, "HTAccess: `%s' has been accessed, No data loaded.\n", - full_address); + CTRACE((tfp, "HTAccess: `%s' has been accessed, No data loaded.\n", + full_address)); return NO; } if (status == HT_INTERRUPTED) { - CTRACE(tfp, "HTAccess: `%s' has been accessed, transfer interrupted.\n", - full_address); + CTRACE((tfp, "HTAccess: `%s' has been accessed, transfer interrupted.\n", + full_address)); return NO; } @@ -1004,9 +1055,9 @@ PRIVATE BOOL HTLoadDocument ARGS4( fprintf(stderr, gettext("**** HTAccess: socket or file number returned by obsolete load routine!\n")); fprintf(stderr, - gettext("**** HTAccess: Internal software error. Please mail lynx_dev@sig.net!\n")); + gettext("**** HTAccess: Internal software error. Please mail lynx-dev@sig.net!\n")); fprintf(stderr, gettext("**** HTAccess: Status returned was: %d\n"),status); - exit(-1); + exit(EXIT_FAILURE); } /* Failure in accessing a document */ @@ -1018,7 +1069,7 @@ PRIVATE BOOL HTLoadDocument ARGS4( _HTProgress(cp); FREE(cp); - CTRACE(tfp, "HTAccess: Can't access `%s'\n", full_address); + CTRACE((tfp, "HTAccess: Can't access `%s'\n", full_address)); HTLoadError(sink, 500, gettext("Unable to access document.")); return NO; } /* HTLoadDocument */ @@ -1193,7 +1244,7 @@ PUBLIC BOOL HTSearch ARGS2( CONST char * p, *s, *e; /* Pointers into keywords */ char * address = NULL; BOOL result; - char * escaped = (char *)calloc(1, ((strlen(keywords)*3) + 1)); + char * escaped = typecallocn(char, (strlen(keywords)*3) + 1); static CONST BOOL isAcceptable[96] = /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ @@ -1217,12 +1268,12 @@ PUBLIC BOOL HTSearch ARGS2( for (e = s + strlen(s); e > s && WHITE(*(e-1)); e--) /* Scan */ ; /* Skip trailers */ for (q = escaped, p = s; p < e; p++) { /* Scan stripped field */ - unsigned char c = (unsigned char)TOASCII(*p); + unsigned char c = UCH(TOASCII(*p)); if (WHITE(*p)) { *q++ = '+'; } else if (HTCJK != NOCJK) { *q++ = *p; - } else if (c>=32 && c<=(unsigned char)127 && isAcceptable[c-32]) { + } else if (c>=32 && c<=UCH(127) && isAcceptable[c-32]) { *q++ = *p; /* 930706 TBL for MVS bug */ } else { *q++ = '%'; @@ -1312,7 +1363,7 @@ PUBLIC HTParentAnchor * HTHomeAnchor NOARGS FILE * fp = fopen(REMOTE_POINTER, "r"); char * status; if (fp) { - my_home_document = (char*)calloc(1, MAX_FILE_NAME); + my_home_document = typecallocn(char, MAX_FILE_NAME); if (my_home_document == NULL) outofmem(__FILE__, "HTHomeAnchor"); status = fgets(my_home_document, MAX_FILE_NAME, fp); @@ -1325,7 +1376,7 @@ PUBLIC HTParentAnchor * HTHomeAnchor NOARGS StrAllocCopy(my_home_document, REMOTE_ADDRESS); } -#ifdef unix +#ifdef UNIX if (my_home_document == NULL) { FILE * fp = NULL; CONST char * home = (CONST char*)getenv("HOME"); @@ -1341,20 +1392,20 @@ PUBLIC HTParentAnchor * HTHomeAnchor NOARGS if (fp) { fclose(fp); } else { - CTRACE(tfp, "HTBrowse: No local home document ~/%s or %s\n", - PERSONAL_DEFAULT, LOCAL_DEFAULT_FILE); + CTRACE((tfp, "HTBrowse: No local home document ~/%s or %s\n", + PERSONAL_DEFAULT, LOCAL_DEFAULT_FILE)); FREE(my_home_document); } } -#endif /* unix */ +#endif /* UNIX */ ref = HTParse((my_home_document ? my_home_document : (HTClientHost ? REMOTE_ADDRESS : LAST_RESORT)), "file:", PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION); if (my_home_document) { - CTRACE(tfp, "HTAccess: Using custom home page %s i.e., address %s\n", - my_home_document, ref); + CTRACE((tfp, "HTAccess: Using custom home page %s i.e., address %s\n", + my_home_document, ref)); FREE(my_home_document); } anchor = (HTParentAnchor*)HTAnchor_findAddress(ref); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.h index 2cfd49d518d..0c763051716 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAccess.h @@ -13,6 +13,8 @@ extern char * use_this_url_instead; +extern int redirection_attempts; + /* Definition uses: */ #include <HTAnchor.h> @@ -76,6 +78,7 @@ extern int HTDiag; /* Flag: load source as plain text */ extern char * HTClientHost; /* Name or number of telnetting host */ extern FILE * HTlogfile; /* File to output one-liners to */ extern BOOL HTSecure; /* Disable security holes? */ +extern BOOL HTPermitRedir; /* Special flag for getfile() */ extern HTStream* HTOutputStream; /* For non-interactive, set this */ extern HTFormat HTOutputFormat; /* To convert on load, set this */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.c index 22af2bfb379..d336cb7b796 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.c @@ -21,6 +21,7 @@ #include <UCAux.h> #include <UCMap.h> +#include <LYUtils.h> #include <LYCharSets.h> #include <LYLeaks.h> @@ -66,18 +67,22 @@ PRIVATE HTList **adult_table = 0; /* Point to table of lists of all parents */ */ PRIVATE HTParentAnchor * HTParentAnchor_new NOARGS { - HTParentAnchor *newAnchor = - (HTParentAnchor *)calloc(1, sizeof(HTParentAnchor)); /* zero-filled */ + HTParentAnchor *newAnchor = typecalloc(HTParentAnchor); if (newAnchor == NULL) outofmem(__FILE__, "HTParentAnchor_new"); newAnchor->parent = newAnchor; - newAnchor->bookmark = NULL; /* Bookmark filename. - FM */ + newAnchor->bookmark = NULL; /* Bookmark filename. - FM */ newAnchor->isISMAPScript = FALSE; /* Lynx appends ?0,0 if TRUE. - FM */ newAnchor->isHEAD = FALSE; /* HEAD request if TRUE. - FM */ newAnchor->safe = FALSE; /* Safe. - FM */ +#ifdef SOURCE_CACHE + newAnchor->source_cache_file = NULL; + newAnchor->source_cache_chunk = NULL; +#endif newAnchor->FileCache = NULL; /* Path to a disk-cached copy. - FM */ - newAnchor->SugFname = NULL; /* Suggested filename. - FM */ - newAnchor->RevTitle = NULL; /* TITLE for a LINK with REV. - FM */ + newAnchor->SugFname = NULL; /* Suggested filename. - FM */ + newAnchor->RevTitle = NULL; /* TITLE for a LINK with REV. - FM */ + newAnchor->citehost = NULL; /* LINK REL=citehost - RDC */ newAnchor->cache_control = NULL; /* Cache-Control. - FM */ newAnchor->no_cache = FALSE; /* no-cache? - FM */ newAnchor->content_type = NULL; /* Content-Type. - FM */ @@ -98,7 +103,12 @@ PRIVATE HTParentAnchor * HTParentAnchor_new NOARGS PRIVATE HTChildAnchor * HTChildAnchor_new NOARGS { - return (HTChildAnchor *)calloc(1, sizeof(HTChildAnchor)); /* zero-filled */ + HTChildAnchor *p; + + p = typecalloc(HTChildAnchor); + if (p == NULL) + outofmem(__FILE__, "HTChildAnchor_new"); + return p; } @@ -124,7 +134,7 @@ PRIVATE BOOL HTEquivalent ARGS2( } return( TOUPPER(*s) == TOUPPER(*t)); } else { - return(s == t); /* Two NULLs are equivalent, aren't they ? */ + return(s == t); /* Two NULLs are equivalent, aren't they ? */ } } @@ -144,14 +154,20 @@ PRIVATE BOOL HTIdentical ARGS2( CONST char *, t) { if (s && t) { /* Make sure they point to something */ +#ifdef SH_EX /* 1998/04/28 (Tue) 22:02:58 */ + if (*s == 'P' || *t == 'P') { + if (strcmp(s + 1, "Name") == 0 || strcmp(t + 1, "Name") == 0) + return NO; + } +#endif for (; *s && *t; s++, t++) { if (*s != *t) { return(NO); } } - return(*s == *t); + return (BOOL) (*s == *t); } else { - return(s == t); /* Two NULLs are identical, aren't they ? */ + return (BOOL) (s == t); /* Two NULLs are identical, aren't they ? */ } } #endif /* CASE_INSENSITIVE_ANCHORS */ @@ -171,7 +187,7 @@ PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2( HTList *kids; if (!parent) { - CTRACE(tfp, "HTAnchor_findChild called with NULL parent.\n"); + CTRACE((tfp, "HTAnchor_findChild called with NULL parent.\n")); return(NULL); } if ((kids = parent->children) != 0) { @@ -186,8 +202,8 @@ PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2( if (HTIdentical(child->tag, tag)) /* Case sensitive - FM */ #endif /* CASE_INSENSITIVE_ANCHORS */ { - CTRACE(tfp, "Child anchor %p of parent %p with name `%s' already exists.\n", - (void *)child, (void *)parent, tag); + CTRACE((tfp, "Child anchor %p of parent %p with name `%s' already exists.\n", + (void *)child, (void *)parent, tag)); return(child); } } @@ -197,12 +213,10 @@ PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2( } child = HTChildAnchor_new(); - if (child == NULL) - outofmem(__FILE__, "HTChildAnchor_new"); - CTRACE(tfp, "new Anchor %p named `%s' is child of %p\n", + CTRACE((tfp, "HTAnchor: New Anchor %p named `%s' is child of %p\n", (void *)child, tag ? tag : (CONST char *)"", - (void *)parent); /* int for apollo */ + (void *)parent)); /* int for apollo */ HTList_addObject (parent->children, child); child->parent = parent; StrAllocCopy(child->tag, tag); @@ -225,7 +239,7 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4( { HTChildAnchor * child = HTAnchor_findChild(parent, tag); - CTRACE(tfp,"Entered HTAnchor_findChildAndLink\n"); + CTRACE((tfp,"Entered HTAnchor_findChildAndLink\n")); if (href && *href) { char *relative_to = HTAnchor_address((HTAnchor *)parent); @@ -259,15 +273,15 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4( testdest1 = child->mainLink.dest; if (testdest1) { nlinks = 1 + HTList_count(child->links); - CTRACE(tfp, + CTRACE((tfp, "*** Duplicate ChildAnchor %p named `%s' with %d links", - child, tag, nlinks); + child, tag, nlinks)); if (dest == testdest1 && ltype == child->mainLink.type) { - CTRACE(tfp,", same dest %p and type, keeping it\n", - testdest1); + CTRACE((tfp,", same dest %p and type, keeping it\n", + testdest1)); } else { - CTRACE(tfp,", different dest %p, creating unnamed child\n", - testdest1); + CTRACE((tfp,", different dest %p, creating unnamed child\n", + testdest1)); child = HTAnchor_findChild(parent, 0); } } @@ -304,11 +318,11 @@ PRIVATE void free_adult_table NOARGS adult_table[i_counter] = HTAp_freeme->next; if (HTAp_freeme->object) { parent = (HTParentAnchor *)HTAp_freeme->object; - CTRACE(tfp, "delete anchor:%d/%d,%d,%d %s\n", + CTRACE((tfp, "delete anchor:%d/%d,%d,%d %s\n", i_counter, HTList_count(HTAp_freeme) + 1, (parent->physical ? 1 : 0), (int)parent->underway, - (parent->address ? parent->address : "(no address)")); + (parent->address ? parent->address : "(no address)"))); parent->underway = FALSE; HTAnchor_delete(parent); } @@ -333,7 +347,7 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( /* Anchor tag specified ? */ char *tag = HTParse(newdoc->address, "", PARSE_ANCHOR); - CTRACE(tfp,"Entered HTAnchor_findAddress\n"); + CTRACE((tfp,"Entered HTAnchor_findAddress\n")); /* ** If the address represents a sub-anchor, we recursively load its @@ -374,7 +388,7 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( */ hash = HASH_FUNCTION(newdoc->address); if (!adult_table) { - adult_table = (HTList **)calloc(HASH_SIZE, sizeof(HTList *)); + adult_table = typecallocn(HTList *, HASH_SIZE); if (!adult_table) outofmem(__FILE__, "HTAnchor_findAddress"); #ifdef LY_FIND_LEAKS @@ -401,8 +415,8 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( foundAnchor->isHEAD == newdoc->isHEAD) #endif /* CASE_INSENSITIVE_ANCHORS */ { - CTRACE(tfp, "Anchor %p with address `%s' already exists.\n", - (void *)foundAnchor, newdoc->address); + CTRACE((tfp, "Anchor %p with address `%s' already exists.\n", + (void *)foundAnchor, newdoc->address)); return (HTAnchor *)foundAnchor; } } @@ -411,8 +425,8 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( ** Node not found: create new anchor. */ foundAnchor = HTParentAnchor_new(); - CTRACE(tfp, "New anchor %p has hash %d and address `%s'\n", - (void *)foundAnchor, hash, newdoc->address); + CTRACE((tfp, "New anchor %p has hash %d and address `%s'\n", + (void *)foundAnchor, hash, newdoc->address)); StrAllocCopy(foundAnchor->address, newdoc->address); if (newdoc->post_data) StrAllocCopy(foundAnchor->post_data, newdoc->post_data); @@ -427,7 +441,25 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( return (HTAnchor *)foundAnchor; } } - +/* Create new or find old named anchor - simple form +** ------------------------------------------------- +** +** Like the previous one, but simpler to use for simple cases. +** No post data etc. can be supplied. - kw +*/ +PUBLIC HTAnchor * HTAnchor_findSimpleAddress ARGS1( + CONST char *, url) +{ + DocAddress urldoc; + + urldoc.address = (char *)url; /* ignore warning, it IS treated like const - kw */ + urldoc.post_data = NULL; + urldoc.post_content_type = NULL; + urldoc.bookmark = NULL; + urldoc.isHEAD = FALSE; + urldoc.safe = FALSE; + return HTAnchor_findAddress(&urldoc); +} /* Delete an anchor and possibly related things (auto garbage collection) ** -------------------------------------------- @@ -566,6 +598,28 @@ PRIVATE void deleteLinks ARGS1( } } +#ifdef SOURCE_CACHE +PUBLIC void HTAnchor_clearSourceCache ARGS1( + HTParentAnchor *, me) +{ + /* + * Clean up the source cache, if any. + */ + if (me->source_cache_file) { + CTRACE((tfp, "SourceCache: Removing file %s\n", + me->source_cache_file)); + LYRemoveTemp(me->source_cache_file); + FREE(me->source_cache_file); + } + if (me->source_cache_chunk) { + CTRACE((tfp, "SourceCache: Removing memory chunk %p\n", + (void *)me->source_cache_chunk)); + HTChunkFree(me->source_cache_chunk); + me->source_cache_chunk = NULL; + } +} +#endif /* SOURCE_CACHE */ + PUBLIC BOOL HTAnchor_delete ARGS1( HTParentAnchor *, me) { @@ -689,6 +743,10 @@ PUBLIC BOOL HTAnchor_delete ARGS1( FREE(me->bookmark); FREE(me->owner); FREE(me->RevTitle); + FREE(me->citehost); +#ifdef SOURCE_CACHE + HTAnchor_clearSourceCache(me); +#endif if (me->FileCache) { FILE *fd; if ((fd = fopen(me->FileCache, "r")) != NULL) { @@ -713,7 +771,7 @@ PUBLIC BOOL HTAnchor_delete ARGS1( FREE(me->last_modified); FREE(me->ETag); FREE(me->server); -#ifdef USE_HASH +#ifdef USE_COLOR_STYLE FREE(me->style); #endif @@ -721,7 +779,7 @@ PUBLIC BOOL HTAnchor_delete ARGS1( * Remove ourselves from the hash table's list. */ if (adult_table) { - unsigned short int usi_hash = HASH_FUNCTION(me->address); + unsigned short usi_hash = (unsigned short) HASH_FUNCTION(me->address); if (adult_table[usi_hash]) { HTList_removeObject(adult_table[usi_hash], (void *)me); @@ -803,13 +861,8 @@ PUBLIC char * HTAnchor_address ARGS1( !((HTChildAnchor *)me)->tag) { /* it's an adult or no tag */ StrAllocCopy(addr, me->parent->address); } else { /* it's a named child */ - addr = malloc(2 + - strlen(me->parent->address) + - strlen(((HTChildAnchor *)me)->tag)); - if (addr == NULL) - outofmem(__FILE__, "HTAnchor_address"); - sprintf(addr, "%s#%s", - me->parent->address, ((HTChildAnchor *)me)->tag); + HTSprintf0(&addr, "%s#%s", + me->parent->address, ((HTChildAnchor *)me)->tag); } } return(addr); @@ -831,7 +884,7 @@ PUBLIC HTFormat HTAnchor_format ARGS1( PUBLIC void HTAnchor_setIndex ARGS2( HTParentAnchor *, me, - char *, address) + char *, address) { if (me) { me->isIndex = YES; @@ -841,7 +894,7 @@ PUBLIC void HTAnchor_setIndex ARGS2( PUBLIC void HTAnchor_setPrompt ARGS2( HTParentAnchor *, me, - char *, prompt) + char *, prompt) { if (me) { StrAllocCopy(me->isIndexPrompt, prompt); @@ -866,10 +919,10 @@ PUBLIC BOOL HTAnchor_isISMAPScript ARGS1( PUBLIC BOOL HTAnchor_hasChildren ARGS1( HTParentAnchor *, me) { - return( me ? ! HTList_isEmpty(me->children) : NO); + return (BOOL) ( me ? ! HTList_isEmpty(me->children) : NO); } -#if defined(USE_HASH) +#if defined(USE_COLOR_STYLE) /* Style handling. */ PUBLIC CONST char * HTAnchor_style ARGS1( @@ -907,18 +960,18 @@ PUBLIC void HTAnchor_setTitle ARGS2( if (title) { StrAllocCopy(me->title, title); for (i = 0; me->title[i]; i++) { - if ((unsigned char)me->title[i] == 1 || - (unsigned char)me->title[i] == 2) { + if (UCH(me->title[i]) == 1 || + UCH(me->title[i]) == 2) { me->title[i] = ' '; } } } else { - CTRACE(tfp,"HTAnchor_setTitle: New title is NULL! "); + CTRACE((tfp,"HTAnchor_setTitle: New title is NULL! ")); if (me->title) { - CTRACE(tfp,"Old title was \"%s\".\n", me->title); + CTRACE((tfp,"Old title was \"%s\".\n", me->title)); FREE(me->title); } else { - CTRACE(tfp,"Old title was NULL.\n"); + CTRACE((tfp,"Old title was NULL.\n")); } } } @@ -933,8 +986,8 @@ PUBLIC void HTAnchor_appendTitle ARGS2( if (me) { StrAllocCat(me->title, title); for (i = 0; me->title[i]; i++) { - if ((unsigned char)me->title[i] == 1 || - (unsigned char)me->title[i] == 2) { + if (UCH(me->title[i]) == 1 || + UCH(me->title[i]) == 2) { me->title[i] = ' '; } } @@ -991,14 +1044,33 @@ PUBLIC void HTAnchor_setRevTitle ARGS2( if (me) { StrAllocCopy(me->RevTitle, title); for (i = 0; me->RevTitle[i]; i++) { - if ((unsigned char)me->RevTitle[i] == 1 || - (unsigned char)me->RevTitle[i] == 2) { + if (UCH(me->RevTitle[i]) == 1 || + UCH(me->RevTitle[i]) == 2) { me->RevTitle[i] = ' '; } } } } +#ifndef DISABLE_BIBP +/* Citehost for bibp links from LINKs with REL="citehost". - RDC +*/ +PUBLIC CONST char * HTAnchor_citehost ARGS1( + HTParentAnchor *, me) +{ + return( me ? me->citehost : NULL); +} + +PUBLIC void HTAnchor_setCitehost ARGS2( + HTParentAnchor *, me, + CONST char *, citehost) +{ + if (me) { + StrAllocCopy(me->citehost, citehost); + } +} +#endif /* !DISABLE_BIBP */ + /* Suggested filename handling. - FM ** (will be loaded if we had a Content-Disposition ** header or META element with filename=name.suffix) @@ -1056,7 +1128,7 @@ PUBLIC CONST char * HTAnchor_server ARGS1( PUBLIC BOOL HTAnchor_safe ARGS1( HTParentAnchor *, me) { - return( me ? me->safe : FALSE); + return (BOOL) ( me ? me->safe : FALSE); } /* Content-Base header handling. - FM @@ -1123,12 +1195,12 @@ PUBLIC BOOL HTAnchor_link ARGS3( { if (!(source && destination)) return(NO); /* Can't link to/from non-existing anchor */ - CTRACE(tfp, "Linking anchor %p to anchor %p\n", source, destination); + CTRACE((tfp, "Linking anchor %p to anchor %p\n", source, destination)); if (!source->mainLink.dest) { source->mainLink.dest = destination; source->mainLink.type = type; } else { - HTLink * newLink = (HTLink *)calloc (1, sizeof (HTLink)); + HTLink * newLink = typecalloc(HTLink); if (newLink == NULL) outofmem(__FILE__, "HTAnchor_link"); newLink->dest = destination; @@ -1183,7 +1255,7 @@ PUBLIC BOOL HTAnchor_makeMainLink ARGS2( return(NO); /* link not found or NULL anchor */ } else { /* First push current main link onto top of links list */ - HTLink *newLink = (HTLink *)calloc (1, sizeof (HTLink)); + HTLink *newLink = typecalloc(HTLink); if (newLink == NULL) outofmem(__FILE__, "HTAnchor_makeMainLink"); memcpy((void *)newLink, @@ -1238,7 +1310,7 @@ PUBLIC char * HTAnchor_physical ARGS1( PUBLIC void HTAnchor_setPhysical ARGS2( HTParentAnchor *, me, - char *, physical) + char *, physical) { if (me) { StrAllocCopy(me->physical, physical); @@ -1276,8 +1348,7 @@ PUBLIC LYUCcharset * HTAnchor_getUCInfoStage ARGS2( if (me && !me->UCStages) { int i; int chndl = UCLYhndl_for_unspec; /* always >= 0 */ - UCAnchorInfo * stages = (UCAnchorInfo*)calloc(1, - sizeof(UCAnchorInfo)); + UCAnchorInfo * stages = typecalloc(UCAnchorInfo); if (stages == NULL) outofmem(__FILE__, "HTAnchor_getUCInfoStage"); for (i = 0; i < UCT_STAGEMAX; i++) { @@ -1325,6 +1396,20 @@ PUBLIC int HTAnchor_getUCLYhndl ARGS2( return( -1); } +#ifdef CAN_SWITCH_DISPLAY_CHARSET +PRIVATE void setup_switch_display_charset ARGS2(HTParentAnchor *, me, int, h) +{ + if (!Switch_Display_Charset(h,SWITCH_DISPLAY_CHARSET_MAYBE)) + return; + HTAnchor_setUCInfoStage(me, current_char_set, + UCT_STAGE_HTEXT, UCT_SETBY_MIME); /* highest priorty! */ + HTAnchor_setUCInfoStage(me, current_char_set, + UCT_STAGE_STRUCTURED, UCT_SETBY_MIME); /* highest priorty! */ + CTRACE((tfp, "changing UCInfoStage: HTEXT/STRUCTURED stages charset='%s'.\n", + LYCharSet_UC[current_char_set].MIMEname)); +} +#endif + PUBLIC LYUCcharset * HTAnchor_setUCInfoStage ARGS4( HTParentAnchor *, me, int, LYhndl, @@ -1340,10 +1425,18 @@ PUBLIC LYUCcharset * HTAnchor_setUCInfoStage ARGS4( * Can we override? */ if (set_by >= me->UCStages->s[which_stage].lock) { +#ifdef CAN_SWITCH_DISPLAY_CHARSET + int ohandle = me->UCStages->s[which_stage].LYhndl; +#endif me->UCStages->s[which_stage].lock = set_by; me->UCStages->s[which_stage].LYhndl = LYhndl; if (LYhndl >= 0) { memcpy(p, &LYCharSet_UC[LYhndl], sizeof(LYUCcharset)); +#ifdef CAN_SWITCH_DISPLAY_CHARSET + /* Allow a switch to a more suitable display charset */ + if ( LYhndl != ohandle && which_stage == UCT_STAGE_PARSER ) + setup_switch_display_charset(me, LYhndl); +#endif } else { p->UChndl = -1; @@ -1360,10 +1453,18 @@ PUBLIC LYUCcharset * HTAnchor_resetUCInfoStage ARGS4( int, which_stage, int, set_by) { + int ohandle; + if (!me || !me->UCStages) return(NULL); me->UCStages->s[which_stage].lock = set_by; + ohandle = me->UCStages->s[which_stage].LYhndl; me->UCStages->s[which_stage].LYhndl = LYhndl; +#ifdef CAN_SWITCH_DISPLAY_CHARSET + /* Allow a switch to a more suitable display charset */ + if (LYhndl >= 0 && LYhndl != ohandle && which_stage == UCT_STAGE_PARSER) + setup_switch_display_charset(me, LYhndl); +#endif return( &me->UCStages->s[which_stage].C); } @@ -1390,9 +1491,20 @@ PUBLIC LYUCcharset * HTAnchor_copyUCInfoStage ARGS4( if (set_by == UCT_SETBY_NONE) set_by = UCT_SETBY_DEFAULT; if (set_by >= me->UCStages->s[to_stage].lock) { +#ifdef CAN_SWITCH_DISPLAY_CHARSET + int ohandle = me->UCStages->s[to_stage].LYhndl; +#endif me->UCStages->s[to_stage].lock = set_by; me->UCStages->s[to_stage].LYhndl = me->UCStages->s[from_stage].LYhndl; +#ifdef CAN_SWITCH_DISPLAY_CHARSET + /* Allow a switch to a more suitable display charset */ + if ( me->UCStages->s[to_stage].LYhndl >= 0 + && me->UCStages->s[to_stage].LYhndl != ohandle + && to_stage == UCT_STAGE_PARSER ) + setup_switch_display_charset(me, + me->UCStages->s[to_stage].LYhndl); +#endif if (p_to != p_from) memcpy(p_to, p_from, sizeof(LYUCcharset)); return(p_to); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.h index cb47e52e32e..89a7f88ff5e 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAnchor.h @@ -15,6 +15,7 @@ /* Version 1 of 24-Oct-1991 (JFG), written in C, browser-independent */ #include <HTList.h> +#include <HTChunk.h> #include <HTAtom.h> #include <UCDefs.h> @@ -66,7 +67,8 @@ struct _HTParentAnchor { char * title; /* Title of document */ char * owner; /* Owner of document */ char * RevTitle; /* TITLE in REV="made" or REV="owner" LINK */ -#ifdef USE_HASH + char * citehost; /* Citehost from REL="citehost" LINK */ +#ifdef USE_COLOR_STYLE char * style; #endif @@ -77,7 +79,11 @@ struct _HTParentAnchor { BOOL isISMAPScript; /* Script for clickable image map */ BOOL isHEAD; /* Document is headers from a HEAD request */ BOOL safe; /* Safe */ - char * FileCache; /* Path to a disk-cached copy */ +#ifdef SOURCE_CACHE + char * source_cache_file; + HTChunk * source_cache_chunk; +#endif + char * FileCache; /* Path to a disk-cached copy (see src/HTFWriter.c) */ char * SugFname; /* Suggested filename */ char * cache_control; /* Cache-Control */ BOOL no_cache; /* Cache-Control, Pragma or META "no-cache"? */ @@ -163,6 +169,15 @@ extern HTChildAnchor * HTAnchor_findChildAndLink PARAMS(( extern HTAnchor * HTAnchor_findAddress PARAMS(( CONST DocAddress * address)); +/* Create new or find old named anchor - simple form +** ------------------------------------------------- +** +** Like the previous one, but simpler to use for simple cases. +** No post data etc. can be supplied. - kw +*/ +extern HTAnchor * HTAnchor_findSimpleAddress PARAMS(( + CONST char * url)); + /* Delete an anchor and possibly related things (auto garbage collection) ** -------------------------------------------- ** @@ -175,6 +190,11 @@ extern HTAnchor * HTAnchor_findAddress PARAMS(( extern BOOL HTAnchor_delete PARAMS(( HTParentAnchor * me)); +#ifdef SOURCE_CACHE +extern void HTAnchor_clearSourceCache PARAMS(( + HTParentAnchor * me)); +#endif + /* Move an anchor to the head of the list of its siblings ** ------------------------------------------------------ ** @@ -227,7 +247,7 @@ extern BOOL HTAnchor_isISMAPScript PARAMS(( extern BOOL HTAnchor_hasChildren PARAMS(( HTParentAnchor * me)); -#if defined(USE_HASH) +#if defined(USE_COLOR_STYLE) extern CONST char * HTAnchor_style PARAMS(( HTParentAnchor * me)); @@ -276,6 +296,15 @@ extern void HTAnchor_setRevTitle PARAMS(( HTParentAnchor * me, CONST char * title)); +/* Citehost for bibp links from LINKs with REL="citehost". - RDC +*/ +extern CONST char * HTAnchor_citehost PARAMS(( + HTParentAnchor * me)); + +extern void HTAnchor_setCitehost PARAMS(( + HTParentAnchor * me, + CONST char * citehost)); + /* Suggested filename handling. - FM ** (will be loaded if we had a Content-Disposition ** header or META element with filename=name.suffix) diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAssoc.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAssoc.c index 05b631cd7d9..8e16e76125f 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAssoc.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAssoc.c @@ -62,7 +62,7 @@ PUBLIC void HTAssocList_add ARGS3(HTAssocList *, alist, StrAllocCopy(assoc->value, value); HTList_addObject(alist, (void*)assoc); } else { - CTRACE(tfp, "HTAssoc_add: ERROR: assoc list NULL!!\n"); + CTRACE((tfp, "HTAssoc_add: ERROR: assoc list NULL!!\n")); } } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAtom.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAtom.c index 44ac6c7a2b0..cb5fc7c4471 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAtom.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTAtom.c @@ -36,7 +36,7 @@ PRIVATE void free_atoms NOPARAMS; /* * Alternate hashing function. */ -#define HASH_FUNCTION(cp_hash) ((strlen(cp_hash) * (unsigned char)*cp_hash) % HASH_SIZE) +#define HASH_FUNCTION(cp_hash) ((strlen(cp_hash) * UCH(*cp_hash)) % HASH_SIZE) PUBLIC HTAtom * HTAtom_for ARGS1(CONST char *, string) { @@ -67,7 +67,7 @@ PUBLIC HTAtom * HTAtom_for ARGS1(CONST char *, string) */ for (a = hash_table[hash]; a; a = a->next) { if (0 == strcasecomp(a->name, string)) { - /* CTRACE(tfp, "HTAtom: Old atom %p for `%s'\n", a, string); */ + /* CTRACE((tfp, "HTAtom: Old atom %p for `%s'\n", a, string)); */ return a; /* Found: return it */ } } @@ -84,7 +84,7 @@ PUBLIC HTAtom * HTAtom_for ARGS1(CONST char *, string) a->next = hash_table[hash]; /* Put onto the head of list */ hash_table[hash] = a; #ifdef NOT_DEFINED - CTRACE(tfp, "HTAtom: New atom %p for `%s'\n", a, string); + CTRACE((tfp, "HTAtom: New atom %p for `%s'\n", a, string)); #endif /* NOT_DEFINED */ return a; } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c index c545eb0e70f..db3b50db510 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c @@ -9,9 +9,6 @@ #include <HTUtils.h> #include <HTBTree.h> -#ifndef __STRICT_BSD__ -#include <stdlib.h> -#endif #define MAXIMUM(a,b) ((a)>(b)?(a):(b)) diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTCJK.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTCJK.h index 8765461d4d9..f234adfe085 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTCJK.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTCJK.h @@ -37,19 +37,25 @@ #define IS_SJIS_HI1(hi) ((0x81<=hi)&&(hi<=0x9F)) /* 1st lev. */ #define IS_SJIS_HI2(hi) ((0xE0<=hi)&&(hi<=0xEF)) /* 2nd lev. */ #define IS_SJIS(hi,lo,in_sjis) (!IS_SJIS_LO(lo)?0:IS_SJIS_HI1(hi)?(in_sjis=1):in_sjis&&IS_SJIS_HI2(hi)) +#define IS_SJIS_2BYTE(hi,lo) (IS_SJIS_LO(lo)&&(IS_SJIS_HI1(hi)||IS_SJIS_HI2(hi))) +#define IS_SJIS_X0201KANA(lo) ((0xA1<=lo)&&(lo<=0xDF)) -#define IS_EUC_LOS(lo) ((0x21<=lo)&&(lo<=0x7E)) /* standard */ #define IS_EUC_LOX(lo) ((0xA1<=lo)&&(lo<=0xFE)) /* extended */ #define IS_EUC_HI(hi) ((0xA1<=hi)&&(hi<=0xFE)) -#define IS_EUC(hi,lo) IS_EUC_HI(hi) && (IS_EUC_LOS(lo) || IS_EUC_LOX(lo)) +#define IS_EUC_X0201KANA(hi,lo) ((hi==0x8E)&&(0xA1<=lo)&&(lo<=0xDF)) +#define IS_EUC(hi,lo) ((IS_EUC_HI(hi) && IS_EUC_LOX(lo))||IS_EUC_X0201KANA(hi,lo)) + +#define IS_JAPANESE_2BYTE(hi,lo) (IS_SJIS_2BYTE(hi,lo) || IS_EUC(hi,lo)) #define IS_BIG5_LOS(lo) ((0x40<=lo)&&(lo<=0x7E)) /* standard */ #define IS_BIG5_LOX(lo) ((0xA1<=lo)&&(lo<=0xFE)) /* extended */ #define IS_BIG5_HI(hi) ((0xA1<=hi)&&(hi<=0xFE)) -#define IS_BIG5(hi,lo) IS_BIG5_HI(hi) && (IS_BIG5_LOS(lo) || IS_BIG5_LOX(lo)) +#define IS_BIG5(hi,lo) (IS_BIG5_HI(hi) && (IS_BIG5_LOS(lo) || IS_BIG5_LOX(lo))) + +typedef enum {NOKANJI, EUC, SJIS, JIS} HTkcode; +typedef enum {NOCJK, JAPANESE, CHINESE, KOREAN, TAIPEI} HTCJKlang; -typedef enum _HTkcode {NOKANJI, EUC, SJIS, JIS} HTkcode; -typedef enum _HTCJKlang {NOCJK, JAPANESE, CHINESE, KOREAN, TAIPEI} HTCJKlang; +extern HTCJKlang HTCJK; /* ** Function prototypes. @@ -111,4 +117,6 @@ extern void TO_JIS PARAMS(( CONST unsigned char * any, unsigned char * jis)); +extern char *str_kcode PARAMS((HTkcode code)); + #endif /* HTCJK_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c index 0149dfffd69..05a5da61999 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c @@ -8,19 +8,42 @@ #include <LYLeaks.h> +/* +** Initialize a chunk with a certain allocation unit +*/ +PUBLIC void HTChunkInit ARGS2 (HTChunk *,ch, int,grow) +{ + ch->data = 0; + ch->growby = grow; + ch->size = 0; + ch->allocated = 0; +} + /* Create a chunk with a certain allocation unit ** -------------- */ PUBLIC HTChunk * HTChunkCreate ARGS1 (int,grow) { - HTChunk * ch = (HTChunk *) calloc(1, sizeof(HTChunk)); + HTChunk * ch = typecalloc(HTChunk); if (ch == NULL) - outofmem(__FILE__, "creation of chunk"); + outofmem(__FILE__, "creation of chunk"); - ch->data = 0; - ch->growby = grow; - ch->size = 0; - ch->allocated = 0; + HTChunkInit (ch, grow); + return ch; +} + +PUBLIC HTChunk * HTChunkCreateMayFail ARGS2 (int,grow, int,failok) +{ + HTChunk * ch = typecalloc(HTChunk); + if (ch == NULL) { + if (!failok) { + outofmem(__FILE__, "creation of chunk"); + } else { + return ch; + } + } + HTChunkInit (ch, grow); + ch->failok = failok; return ch; } @@ -29,19 +52,20 @@ PUBLIC HTChunk * HTChunkCreate ARGS1 (int,grow) */ PUBLIC HTChunk * HTChunkCreate2 ARGS2 (int,grow, size_t, needed) { - HTChunk * ch = (HTChunk *) calloc(1, sizeof(HTChunk)); + HTChunk * ch = typecalloc(HTChunk); if (ch == NULL) - outofmem(__FILE__, "HTChunkCreate2"); + outofmem(__FILE__, "HTChunkCreate2"); - ch->growby = grow; + HTChunkInit (ch, grow); if (needed > 0) { ch->allocated = needed-1 - ((needed-1) % ch->growby) + ch->growby; /* Round up */ - ch->data = (char *)calloc(1, ch->allocated); + CTRACE((tfp, "HTChunkCreate2: requested %d, allocate %d\n", + needed, ch->allocated)); + ch->data = typecallocn(char, ch->allocated); if (!ch->data) outofmem(__FILE__, "HTChunkCreate2 data"); } - ch->size = 0; return ch; } @@ -75,11 +99,18 @@ PUBLIC void HTChunkFree ARGS1 (HTChunk *,ch) PUBLIC void HTChunkPutc ARGS2 (HTChunk *,ch, char,c) { if (ch->size >= ch->allocated) { + char *data; ch->allocated = ch->allocated + ch->growby; - ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated) - : (char *)calloc(1, ch->allocated); - if (!ch->data) - outofmem(__FILE__, "HTChunkPutc"); + data = ch->data ? (char *)realloc(ch->data, ch->allocated) + : typecallocn(char, ch->allocated); + if (data) { + ch->data = data; + } else if (ch->failok) { + HTChunkClear(ch); /* allocation failed, clear all data - kw */ + return; /* caller should check ch->allocated - kw */ + } else { + outofmem(__FILE__, "HTChunkPutc"); + } } ch->data[ch->size++] = c; } @@ -92,11 +123,11 @@ PUBLIC void HTChunkEnsure ARGS2 (HTChunk *,ch, int,needed) { if (needed <= ch->allocated) return; ch->allocated = needed-1 - ((needed-1) % ch->growby) - + ch->growby; /* Round up */ + + ch->growby; /* Round up */ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated) - : (char *)calloc(1, ch->allocated); + : typecallocn(char, ch->allocated); if (ch->data == NULL) - outofmem(__FILE__, "HTChunkEnsure"); + outofmem(__FILE__, "HTChunkEnsure"); } PUBLIC void HTChunkPutb ARGS3 (HTChunk *,ch, CONST char *,b, int,l) @@ -104,12 +135,19 @@ PUBLIC void HTChunkPutb ARGS3 (HTChunk *,ch, CONST char *,b, int,l) int needed = ch->size + l; if (l <= 0) return; if (needed > ch->allocated) { + char *data; ch->allocated = needed-1 - ((needed-1) % ch->growby) + ch->growby; /* Round up */ - ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated) - : (char *)calloc(1, ch->allocated); - if (ch->data == NULL) + data = ch->data ? (char *)realloc(ch->data, ch->allocated) + : typecallocn(char, ch->allocated); + if (data) { + ch->data = data; + } else if (ch->failok) { + HTChunkClear(ch); /* allocation failed, clear all data - kw */ + return; /* caller should check ch->allocated - kw */ + } else { outofmem(__FILE__, "HTChunkPutb"); + } } memcpy(ch->data + ch->size, b, l); ch->size += l; @@ -124,7 +162,7 @@ PUBLIC void HTChunkPutUtf8Char ARGS2( { int utflen; - if (code < 128) + if (TOASCII(code) < 128) utflen = 1; else if (code < 0x800L) { utflen = 2; @@ -140,12 +178,19 @@ PUBLIC void HTChunkPutUtf8Char ARGS2( utflen = 0; if (ch->size + utflen > ch->allocated) { + char *data; int growby = (ch->growby >= utflen) ? ch->growby : utflen; ch->allocated = ch->allocated + growby; - ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated) - : (char *)calloc(1, ch->allocated); - if (!ch->data) - outofmem(__FILE__, "HTChunkPutUtf8Char"); + data = ch->data ? (char *)realloc(ch->data, ch->allocated) + : typecallocn(char, ch->allocated); + if (data) { + ch->data = data; + } else if (ch->failok) { + HTChunkClear(ch); /* allocation failed, clear all data - kw */ + return; /* caller should check ch->allocated - kw */ + } else { + outofmem(__FILE__, "HTChunkPutUtf8Char"); + } } switch (utflen) { @@ -168,18 +213,24 @@ PUBLIC void HTChunkPutUtf8Char ARGS2( break; case 6: PUTC(0xfc | (code>>30)); + break; } switch (utflen) { case 6: PUTC2(code>>24); + /* FALLTHRU */ case 5: PUTC2(code>>18); + /* FALLTHRU */ case 4: PUTC2(code>>12); + /* FALLTHRU */ case 3: PUTC2(code>>6); + /* FALLTHRU */ case 2: PUTC2(code); + break; } } @@ -198,6 +249,9 @@ PUBLIC void HTChunkTerminate ARGS1 (HTChunk *,ch) PUBLIC void HTChunkPuts ARGS2 (HTChunk *,ch, CONST char *,s) { CONST char * p; - for (p=s; *p; p++) - HTChunkPutc(ch, *p); + for (p=s; *p; p++) { + HTChunkPutc(ch, *p); + if (ch->allocated == 0) + return; /* must have been allocation failure - kw */ + } } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.h index e6cf19c8578..a243b2b4edc 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.h @@ -21,10 +21,16 @@ typedef struct { int growby; /* Allocation unit in bytes */ int allocated; /* Current size of *data */ char * data; /* Pointer to malloced area or 0 */ + int failok; /* allowed to fail without exiting program? */ } HTChunk; /* + * Initialize a chunk's allocation data and allocation-increment. + */ +extern void HTChunkInit PARAMS((HTChunk * ch, int grow)); + +/* * * Create new chunk * @@ -43,6 +49,15 @@ typedef struct { extern HTChunk * HTChunkCreate PARAMS((int growby)); /* + * Create a chunk for which an allocation error is not a fatal application + * error if failok != 0, but merely resets the chunk. When using a chunk + * created this way, the caller should always check whether the contents + * are ok each time after data have been appended. + * The create call may also fail and will reurn NULL in that case. - kw + */ +extern HTChunk * HTChunkCreateMayFail PARAMS((int growby, int failok)); + +/* * Like HTChunkCreate but with initial allocation - kw * */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.c index 8b8231f0f65..5313f1e5630 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.c @@ -5,11 +5,15 @@ #include <HTUtils.h> #include <HTDOS.h> +#ifdef WIN_EX +#include <LYGlobalDefs.h> +#endif + /* * Make a copy of the source argument in the result, allowing some extra * space so we can append directly onto the result without reallocating. */ -PRIVATE char * copy_plus ARGS2(char **, result, char *, source) +PRIVATE char * copy_plus ARGS2(char **, result, CONST char *, source) { int length = strlen(source); HTSprintf0(result, "%-*s", length+10, source); @@ -26,16 +30,44 @@ PRIVATE char * copy_plus ARGS2(char **, result, char *, source) ** returns WWW file specification ** */ -char * HTDOS_wwwName ARGS1(char *, dosname) +char * HTDOS_wwwName ARGS1(CONST char *, dosname) { - static char *wwwname; + static char *wwwname = NULL; char *cp_url = copy_plus(&wwwname, dosname); + int wwwname_len; + +#ifdef SH_EX + char ch; + while ((ch = *dosname) != '\0') { + switch (ch) { + case '\\': + /* convert dos backslash to unix-style */ + *cp_url++ = '/'; + break; + case ' ': + *cp_url++ = '%'; + *cp_url++ = '2'; + *cp_url++ = '0'; + break; + default: + *cp_url++ = ch; + break; + } + dosname++; + } + *cp_url = '\0'; +#else for ( ; *cp_url != '\0' ; cp_url++) if(*cp_url == '\\') *cp_url = '/'; /* convert dos backslash to unix-style */ +#endif + + wwwname_len = strlen(wwwname); + if (wwwname_len > 1) + cp_url--; /* point last char */ - if(strlen(wwwname) > 3 && *cp_url == '/') + if (wwwname_len > 3 && *cp_url == '/') *cp_url = '\0'; #ifdef NOTUSED @@ -59,26 +91,91 @@ char * HTDOS_wwwName ARGS1(char *, dosname) */ char * HTDOS_name ARGS1(char *, wwwname) { - static char *cp_url; - char *result; +#ifdef _WINDOWS /* 1998/04/02 (Thu) 08:47:20 */ + extern char windows_drive[]; + char temp_buff[LY_MAXPATH]; +#endif + static char *result = NULL; int joe; - copy_plus(&cp_url, wwwname); + copy_plus(&result, wwwname); - for (joe = 0; cp_url[joe] != '\0'; joe++) { - if (cp_url[joe] == '/') { - cp_url[joe] = '\\'; /* convert slashes to dos-style */ + for (joe = 0; result[joe] != '\0'; joe++) { + if (result[joe] == '/') { + result[joe] = '\\'; /* convert slashes to dos-style */ } } /* pesky leading slash, rudiment from file://localhost/ */ /* the rest of path may be with or without drive letter */ - if((cp_url[1] == '\\') || (cp_url[0] != '\\')) { - result = cp_url; + if((result[1] != '\\') && (result[0] == '\\')) { + for (joe = 0; (result[joe] = result[joe+1]) != 0; joe++) + ; + } + +#ifdef _WINDOWS /* 1998/04/02 (Thu) 08:59:48 */ + if (strchr(result, '\\') != NULL + && strchr(result, ':') == NULL) { + sprintf(temp_buff, "%.3s\\%.*s", windows_drive, + (int)(sizeof(temp_buff) - 5), result); + StrAllocCopy(result, temp_buff); } else { - result = cp_url+1; + char *p = strchr(result, ':'); + if (p && (strcmp(p, ":\\") == 0)) { + p[2] = '.'; + p[3] = '\0'; + } } +#endif + /* + * If we have only a device, add a trailing slash. Otherwise it just + * refers to the current directory on the given device. + */ + if (strchr(result, '\\') == 0 + && result[1] == ':') + StrAllocCat(result, "\\"); - CTRACE(tfp, "HTDOS_name changed `%s' to `%s'\n", wwwname, result); + CTRACE((tfp, "HTDOS_name changed `%s' to `%s'\n", wwwname, result)); return (result); } + +#if defined(DJGPP) && defined(DJGPP_KEYHANDLER) +/* PUBLIC getxkey() +** Replaces libc's getxkey() with polling of tcp/ip +** library (WatTcp or Watt-32). This is required to +** be able to finish off dead sockets, answer pings etc. +** +** ON EXIT: +** returns extended keypress. +*/ + +/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ +#include <pc.h> +#include <dpmi.h> +#include <libc/farptrgs.h> +#include <go32.h> + +int getxkey (void) +{ + __dpmi_regs r; + + /* poll tcp/ip lib and yield to DPMI-host while nothing in + * keyboard buffer (head = tail) (simpler than kbhit). + */ + while (_farpeekw(_dos_ds, 0x41a) == _farpeekw(_dos_ds, 0x41c)) + { + tcp_tick (NULL); + __dpmi_yield(); + } + + r.h.ah = 0x10; + __dpmi_int(0x16, &r); + + if (r.h.al == 0x00) + return 0x0100 | r.h.ah; + if (r.h.al == 0xe0) + return 0x0200 | r.h.ah; + return r.h.al; +} +#endif /* DJGPP && DJGPP_KEYHANDLER */ + diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.h index 37a613868e4..319a63588c7 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTDOS.h @@ -16,7 +16,7 @@ ** returns WWW file specification ** */ -char * HTDOS_wwwName PARAMS((char * dosname)); +char * HTDOS_wwwName PARAMS((CONST char * dosname)); /* PUBLIC HTDOS_name() @@ -31,5 +31,10 @@ char * HTDOS_wwwName PARAMS((char * dosname)); */ char * HTDOS_name PARAMS((char * wwwname)); +#ifdef WIN_EX +char * HTDOS_short_name (char * fn); +#else +#define HTDOS_short_name(fn) fn +#endif #endif /* HTDOS_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c index 87729de3d7c..8cd3099cbff 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c @@ -57,7 +57,7 @@ BUGS: @@@ Limit connection cache size! ** same time. */ -#ifdef DJGPP +#if defined(DJGPP) && !defined(WATT32) #define u_long unsigned long #endif @@ -66,9 +66,8 @@ BUGS: @@@ Limit connection cache size! #include <HTAlert.h> #include <HTFTP.h> /* Implemented here */ - -/* this define should be in HTFont.h :( */ -#define HT_NON_BREAK_SPACE ((char)1) /* For now */ +#include <HTTCP.h> +#include <HTFont.h> #define REPEAT_PORT /* Give the port number for each file */ #define REPEAT_LISTEN /* Close each listen socket and open a new one */ @@ -80,12 +79,8 @@ BUGS: @@@ Limit connection cache size! #define LAST_TCP_PORT 5999 #define LINE_LENGTH 256 -#define COMMAND_LENGTH 256 - -#define INFINITY 512 #include <HTParse.h> -#include <HTTCP.h> #include <HTAnchor.h> #include <HTFile.h> /* For HTFileFormat() */ #include <HTBTree.h> @@ -106,10 +101,6 @@ typedef struct _connection { BOOL binary; /* Binary mode? */ } connection; -#ifndef NIL -#define NIL 0 -#endif /* !NIL */ - /* Hypertext object building machinery */ #include <HTML.h> @@ -150,36 +141,40 @@ PRIVATE int data_soc = -1; /* Socket for data transfer =invalid */ PRIVATE char *user_entered_password = NULL; PRIVATE char *last_username_and_host = NULL; -#define GENERIC_SERVER 0 -#define MACHTEN_SERVER 1 -#define UNIX_SERVER 2 -#define VMS_SERVER 3 -#define CMS_SERVER 4 -#define DCTS_SERVER 5 -#define TCPC_SERVER 6 -#define PETER_LEWIS_SERVER 7 -#define NCSA_SERVER 8 -#define WINDOWS_NT_SERVER 9 -#define MS_WINDOWS_SERVER 10 -#define MSDOS_SERVER 11 -#define APPLESHARE_SERVER 12 -#define NETPRESENZ_SERVER 13 - -PRIVATE int server_type = GENERIC_SERVER; /* the type of ftp host */ +typedef enum { + GENERIC_SERVER + , MACHTEN_SERVER + , UNIX_SERVER + , VMS_SERVER + , CMS_SERVER + , DCTS_SERVER + , TCPC_SERVER + , PETER_LEWIS_SERVER + , NCSA_SERVER + , WINDOWS_NT_SERVER + , WINDOWS_2K_SERVER + , MS_WINDOWS_SERVER + , MSDOS_SERVER + , APPLESHARE_SERVER + , NETPRESENZ_SERVER + , DLS_SERVER +} eServerType; + +PRIVATE eServerType server_type = GENERIC_SERVER; /* the type of ftp host */ PRIVATE int unsure_type = FALSE; /* sure about the type? */ PRIVATE BOOLEAN use_list = FALSE; /* use the LIST command? */ PRIVATE int interrupted_in_next_data_char = FALSE; #ifdef POLL_PORTS -PRIVATE unsigned short port_number = FIRST_TCP_PORT; +PRIVATE PortNumber port_number = FIRST_TCP_PORT; #endif /* POLL_PORTS */ PRIVATE int master_socket = -1; /* Listening socket = invalid */ PRIVATE char port_command[255]; /* Command for setting the port */ PRIVATE fd_set open_sockets; /* Mask of active channels */ PRIVATE int num_sockets; /* Number of sockets to scan */ -PRIVATE unsigned short passive_port; /* Port server specified for data */ +PRIVATE PortNumber passive_port; /* Port server specified for data */ #define NEXT_CHAR HTGetCharacter() /* Use function in HTFormat.c */ @@ -209,7 +204,7 @@ PRIVATE void free_FTPGlobals NOARGS } #endif /* LY_FIND_LEAKS */ -/* PUBLIC HTMake_VMS_name() +/* PUBLIC HTVMS_name() ** CONVERTS WWW name into a VMS name ** ON ENTRY: ** nn Node Name (optional) @@ -220,7 +215,7 @@ PRIVATE void free_FTPGlobals NOARGS ** ** Bug: Returns pointer to static -- non-reentrant */ -PUBLIC char * HTMake_VMS_name ARGS2( +PUBLIC char * HTVMS_name ARGS2( CONST char *, nn, CONST char *, fn) { @@ -232,7 +227,7 @@ PUBLIC char * HTMake_VMS_name ARGS2( ** The node is assumed to be local if the hostname WITHOUT DOMAIN ** matches the local one. @@@ */ - static char vmsname[INFINITY]; /* returned */ + static char *vmsname; char * filename = (char*)malloc(strlen(fn)+1); char * nodename = (char*)malloc(strlen(nn)+2+1); /* Copies to hack */ char *second; /* 2nd slash */ @@ -265,16 +260,16 @@ PUBLIC char * HTMake_VMS_name ARGS2( last = strrchr(filename, '/'); /* last slash */ if (!second) { /* Only one slash */ - sprintf(vmsname, "%s%s", nodename, filename + 1); + HTSprintf0(&vmsname, "%s%s", nodename, filename + 1); } else if (second == last) { /* Exactly two slashes */ *second = '\0'; /* Split filename from disk */ - sprintf(vmsname, "%s%s:%s", nodename, filename+1, second+1); + HTSprintf0(&vmsname, "%s%s:%s", nodename, filename+1, second+1); *second = '/'; /* restore */ } else { /* More than two slashes */ char * p; *second = '\0'; /* Split disk from directories */ *last = '\0'; /* Split dir from filename */ - sprintf(vmsname, "%s%s:[%s]%s", + HTSprintf0(&vmsname, "%s%s:[%s]%s", nodename, filename+1, second+1, last+1); *second = *last = '/'; /* restore filename */ for (p = strchr(vmsname, '['); *p!=']'; p++) @@ -307,7 +302,7 @@ PRIVATE int next_data_char NOARGS return FROMASCII(c); } #else - return (unsigned char)(*data_read_pointer++); + return UCH(*data_read_pointer++); #endif /* NOT_ASCII */ } @@ -319,12 +314,15 @@ PRIVATE int close_connection ARGS1( connection *, con) { connection * scan; - int status = NETCLOSE(con->socket); - if (TRACE) { - CTRACE(tfp, "HTFTP: Closing control socket %d\n", con->socket); + int status; + CTRACE((tfp, "HTFTP: Closing control socket %d\n", con->socket)); + status = NETCLOSE(con->socket); + if (TRACE && status != 0) { #ifdef UNIX - if (status != 0) - perror("HTFTP:close_connection"); + CTRACE((tfp, "HTFTP:close_connection: %s", LYStrerror(errno))); +#else + if (con->socket != INVSOC) + HTInetStatus("HTFTP:close_connection"); #endif } con->socket = -1; @@ -358,7 +356,7 @@ PRIVATE void help_message_cache_add ARGS1( else StrAllocCopy(help_message_buffer, string); - CTRACE(tfp,"Adding message to help cache: %s\n",string); + CTRACE((tfp,"Adding message to help cache: %s\n",string)); } PRIVATE char *help_message_cache_non_empty NOARGS @@ -370,41 +368,35 @@ PRIVATE char *help_message_cache_contents NOARGS return(help_message_buffer); } -/* Execute Command and get Response -** -------------------------------- -** -** See the state machine illustrated in RFC959, p57. This implements -** one command/reply sequence. It also interprets lines which are to -** be continued, which are marked with a "-" immediately after the -** status code. +/* Send One Command +** ---------------- ** -** Continuation then goes on until a line with a matching reply code -** an a space after it. +** This function checks whether we have a control connection, and sends +** one command if given. ** ** On entry, -** con points to the connection which is established. -** cmd points to a command, or is NIL to just get the response. +** control points to the connection which is established. +** cmd points to a command, or is zero to just get the response. ** -** The command is terminated with the CRLF pair. +** The command should already be terminated with the CRLF pair. ** ** On exit, -** returns: The first digit of the reply type, -** or negative for communication failure. +** returns: 1 for success, +** or negative for communication failure (in which case +** the control connection will be closed). */ -PRIVATE int response ARGS1( +PRIVATE int write_cmd ARGS1( char *, cmd) { - int result; /* Three-digit decimal code */ - int continuation_response = -1; int status; if (!control) { - CTRACE(tfp, "HTFTP: No control connection set up!!\n"); + CTRACE((tfp, "HTFTP: No control connection set up!!\n")); return -99; } if (cmd) { - CTRACE(tfp, " Tx: %s", cmd); + CTRACE((tfp, " Tx: %s", cmd)); #ifdef NOT_ASCII { char * p; @@ -415,31 +407,64 @@ PRIVATE int response ARGS1( #endif /* NOT_ASCII */ status = NETWRITE(control->socket, cmd, (int)strlen(cmd)); if (status < 0) { - CTRACE(tfp, "HTFTP: Error %d sending command: closing socket %d\n", - status, control->socket); + CTRACE((tfp, "HTFTP: Error %d sending command: closing socket %d\n", + status, control->socket)); close_connection(control); return status; } } + return 1; +} + +/* Execute Command and get Response +** -------------------------------- +** +** See the state machine illustrated in RFC959, p57. This implements +** one command/reply sequence. It also interprets lines which are to +** be continued, which are marked with a "-" immediately after the +** status code. +** +** Continuation then goes on until a line with a matching reply code +** an a space after it. +** +** On entry, +** control points to the connection which is established. +** cmd points to a command, or is zero to just get the response. +** +** The command must already be terminated with the CRLF pair. +** +** On exit, +** returns: The first digit of the reply type, +** or negative for communication failure. +*/ +PRIVATE int response ARGS1( + char *, cmd) +{ + int result; /* Three-digit decimal code */ + int continuation_response = -1; + int status; + + if ((status = write_cmd(cmd)) < 0) + return status; do { char *p = response_text; for (;;) { int ich = NEXT_CHAR; - if (((*p++ = ich) == LF) + if (((*p++ = (char) ich) == LF) || (p == &response_text[LINE_LENGTH])) { char continuation; if (interrupted_in_htgetcharacter) { - CTRACE (tfp, "HTFTP: Interrupted in HTGetCharacter, apparently.\n"); + CTRACE((tfp, "HTFTP: Interrupted in HTGetCharacter, apparently.\n")); NETCLOSE (control->socket); control->socket = -1; return HT_INTERRUPTED; } *p = '\0'; /* Terminate the string */ - CTRACE(tfp, " Rx: %s", response_text); + CTRACE((tfp, " Rx: %s", response_text)); /* Check for login or help messages */ if (!strncmp(response_text,"230-",4) || @@ -460,15 +485,15 @@ PRIVATE int response ARGS1( } /* if end of line */ if (interrupted_in_htgetcharacter) { - CTRACE (tfp, "HTFTP: Interrupted in HTGetCharacter, apparently.\n"); + CTRACE((tfp, "HTFTP: Interrupted in HTGetCharacter, apparently.\n")); NETCLOSE (control->socket); control->socket = -1; return HT_INTERRUPTED; } if (ich == EOF) { - CTRACE(tfp, "Error on rx: closing socket %d\n", - control->socket); + CTRACE((tfp, "Error on rx: closing socket %d\n", + control->socket)); strcpy(response_text, "000 *** TCP read error on response\n"); close_connection(control); return -1; /* End of file on response */ @@ -478,8 +503,8 @@ PRIVATE int response ARGS1( } while (continuation_response != -1); if (result == 421) { - CTRACE(tfp, "HTFTP: They close so we close socket %d\n", - control->socket); + CTRACE((tfp, "HTFTP: They close so we close socket %d\n", + control->socket)); close_connection(control); return -1; } @@ -521,7 +546,7 @@ PRIVATE int send_cmd_2 ARGS2(char *, verb, char *, param) * Some servers need an additional letter after the MACB command. */ PRIVATE int set_mac_binary ARGS1( - int, ServerType) + eServerType, ServerType) { /* try to set mac binary mode */ if (ServerType == APPLESHARE_SERVER || @@ -540,7 +565,7 @@ PRIVATE int set_mac_binary ARGS1( */ PRIVATE void get_ftp_pwd ARGS2( - int *, ServerType, + eServerType *, ServerType, BOOLEAN *, UseList) { @@ -556,30 +581,30 @@ PRIVATE void get_ftp_pwd ARGS2( if (*ServerType == TCPC_SERVER) { *ServerType = ((response_text[5] == '/') ? NCSA_SERVER : TCPC_SERVER); - CTRACE(tfp, "HTFTP: Treating as %s server.\n", + CTRACE((tfp, "HTFTP: Treating as %s server.\n", ((*ServerType == NCSA_SERVER) ? - "NCSA" : "TCPC")); + "NCSA" : "TCPC"))); } else if (response_text[5] == '/') { /* path names beginning with / imply Unix, * right? */ if (set_mac_binary(*ServerType)) { *ServerType = NCSA_SERVER; - CTRACE(tfp, "HTFTP: Treating as NCSA server.\n"); + CTRACE((tfp, "HTFTP: Treating as NCSA server.\n")); } else { *ServerType = UNIX_SERVER; *UseList = TRUE; - CTRACE(tfp, "HTFTP: Treating as Unix server.\n"); + CTRACE((tfp, "HTFTP: Treating as Unix server.\n")); } return; } else if (response_text[strlen(response_text)-1] == ']') { /* path names ending with ] imply VMS, right? */ *ServerType = VMS_SERVER; *UseList = TRUE; - CTRACE(tfp, "HTFTP: Treating as VMS server.\n"); + CTRACE((tfp, "HTFTP: Treating as VMS server.\n")); } else { *ServerType = GENERIC_SERVER; - CTRACE(tfp, "HTFTP: Treating as Generic server.\n"); + CTRACE((tfp, "HTFTP: Treating as Generic server.\n")); } if ((*ServerType == NCSA_SERVER) || @@ -590,6 +615,45 @@ PRIVATE void get_ftp_pwd ARGS2( } } +/* This function turns MSDOS-like directory output off for + * Windows NT servers. + */ + +PRIVATE void set_unix_dirstyle ARGS2( + eServerType *, ServerType, + BOOLEAN *, UseList) +{ + + char *cp; + /* This is a toggle. It seems we have to toggle in order to see + * the current state (after toggling), so we may end up toggling + * twice. - kw + */ + int status = response("SITE DIRSTYLE\r\n"); + if (status != 2) { + *ServerType = GENERIC_SERVER; + CTRACE((tfp, "HTFTP: DIRSTYLE failed, treating as Generic server.\n")); + return; + } else { + *UseList = TRUE; + /* Expecting one of: + * 200 MSDOS-like directory output is off + * 200 MSDOS-like directory output is on + * The following code doesn't look for the full exact string - + * who knows how the wording may change in some future version. + * If the first response isn't recognized, we toggle again + * anyway, under the assumption that it's more likely that + * the MSDOS setting was "off" originally. - kw + */ + cp = strstr(response_text+4, "MSDOS"); + if (cp && strstr(cp, " off")) { + return; /* already off now. */ + } else { + response("SITE DIRSTYLE\r\n"); + } + } +} + /* Get a valid connection to the host ** ---------------------------------- ** @@ -640,7 +704,7 @@ PRIVATE int get_connection ARGS2( /* ** Allocate and init control struct. */ - con = (connection *)calloc(1, sizeof(connection)); + con = typecalloc(connection); if (con == NULL) outofmem(__FILE__, "get_connection"); } @@ -651,6 +715,7 @@ PRIVATE int get_connection ARGS2( /* Get node name: */ + CTRACE((tfp, "get_connection(%s)\n", arg)); { char *p1 = HTParse(arg, "", PARSE_HOST); char *p2 = strrchr(p1, '@'); /* user? */ @@ -707,10 +772,10 @@ PRIVATE int get_connection ARGS2( if (status < 0) { if (status == HT_INTERRUPTED) { - CTRACE (tfp, "HTFTP: Interrupted on connect\n"); + CTRACE((tfp, "HTFTP: Interrupted on connect\n")); } else { - CTRACE(tfp, "HTFTP: Unable to connect to remote host for `%s'.\n", - arg); + CTRACE((tfp, "HTFTP: Unable to connect to remote host for `%s'.\n", + arg)); } if (status == HT_INTERRUPTED) { _HTProgress (CONNECTION_INTERRUPTED); @@ -730,8 +795,8 @@ PRIVATE int get_connection ARGS2( return status; /* Bad return */ } - CTRACE(tfp, "FTP connected, socket %d control %ld\n", - con->socket, (long)con); + CTRACE((tfp, "FTP connected, socket %d control %ld\n", + con->socket, (long)con)); control = con; /* Current control connection */ /* Initialise buffering for control connection */ @@ -744,7 +809,7 @@ PRIVATE int get_connection ARGS2( status = response((char *)0); /* Get greeting */ if (status == HT_INTERRUPTED) { - CTRACE (tfp, "HTFTP: Interrupted at beginning of login.\n"); + CTRACE((tfp, "HTFTP: Interrupted at beginning of login.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; @@ -773,7 +838,7 @@ PRIVATE int get_connection ARGS2( : "anonymous"); if (status == HT_INTERRUPTED) { - CTRACE (tfp, "HTFTP: Interrupted while sending username.\n"); + CTRACE((tfp, "HTFTP: Interrupted while sending username.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; @@ -830,8 +895,7 @@ PRIVATE int get_connection ARGS2( status = response(command); FREE(command); if (status == HT_INTERRUPTED) { - CTRACE (tfp, - "HTFTP: Interrupted while sending password.\n"); + CTRACE((tfp, "HTFTP: Interrupted while sending password.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; @@ -843,7 +907,7 @@ PRIVATE int get_connection ARGS2( if (status == 3) { status = send_cmd_1("ACCT noaccount"); if (status == HT_INTERRUPTED) { - CTRACE (tfp, "HTFTP: Interrupted while sending password.\n"); + CTRACE((tfp, "HTFTP: Interrupted while sending password.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; @@ -852,11 +916,11 @@ PRIVATE int get_connection ARGS2( } if (status != 2) { - CTRACE(tfp, "HTFTP: Login fail: %s", response_text); + CTRACE((tfp, "HTFTP: Login fail: %s", response_text)); /* if (control->socket > 0) close_connection(control->socket); */ return -1; /* Bad return */ } - CTRACE(tfp, "HTFTP: Logged in.\n"); + CTRACE((tfp, "HTFTP: Logged in.\n")); /** Check for host type **/ if (server_type != NETPRESENZ_SERVER) @@ -868,71 +932,85 @@ PRIVATE int get_connection ARGS2( "UNIX Type: L8 MAC-OS MachTen", 28) == 0) { server_type = MACHTEN_SERVER; use_list = TRUE; - CTRACE(tfp, "HTFTP: Treating as MachTen server.\n"); + CTRACE((tfp, "HTFTP: Treating as MachTen server.\n")); } else if (strstr(response_text+4, "UNIX") != NULL || strstr(response_text+4, "Unix") != NULL) { server_type = UNIX_SERVER; + unsure_type = FALSE; /* to the best of out knowledge... */ use_list = TRUE; - CTRACE(tfp, "HTFTP: Treating as Unix server.\n"); + CTRACE((tfp, "HTFTP: Treating as Unix server.\n")); } else if (strstr(response_text+4, "MSDOS") != NULL) { server_type = MSDOS_SERVER; use_list = TRUE; - CTRACE(tfp, "HTFTP: Treating as MSDOS (Unix emulation) server.\n"); + CTRACE((tfp, "HTFTP: Treating as MSDOS (Unix emulation) server.\n")); } else if (strncmp(response_text+4, "VMS", 3) == 0) { - server_type = VMS_SERVER; + char *tilde = strstr(arg, "/~"); use_list = TRUE; - CTRACE(tfp, "HTFTP: Treating as VMS server.\n"); + if (tilde != 0 + && tilde[2] != 0 + && strstr(response_text+4, "MadGoat") != 0) { + server_type = UNIX_SERVER; + CTRACE((tfp, "HTFTP: Treating VMS as UNIX server.\n")); + } else { + server_type = VMS_SERVER; + CTRACE((tfp, "HTFTP: Treating as VMS server.\n")); + } } else if ((strncmp(response_text+4, "VM/CMS", 6) == 0) || (strncmp(response_text+4, "VM ", 3) == 0)) { server_type = CMS_SERVER; use_list = TRUE; - CTRACE(tfp, "HTFTP: Treating as CMS server.\n"); + CTRACE((tfp, "HTFTP: Treating as CMS server.\n")); } else if (strncmp(response_text+4, "DCTS", 4) == 0) { server_type = DCTS_SERVER; - CTRACE(tfp, "HTFTP: Treating as DCTS server.\n"); + CTRACE((tfp, "HTFTP: Treating as DCTS server.\n")); } else if (strstr(response_text+4, "MAC-OS TCP/Connect II") != NULL) { server_type = TCPC_SERVER; - CTRACE(tfp, "HTFTP: Looks like a TCPC server.\n"); + CTRACE((tfp, "HTFTP: Looks like a TCPC server.\n")); get_ftp_pwd(&server_type, &use_list); unsure_type = TRUE; } else if (server_type == NETPRESENZ_SERVER) { /* already set above */ use_list = TRUE; set_mac_binary(server_type); - CTRACE(tfp, "HTFTP: Treating as NetPresenz (MACOS) server.\n"); + CTRACE((tfp, "HTFTP: Treating as NetPresenz (MACOS) server.\n")); } else if (strncmp(response_text+4, "MACOS Peter's Server", 20) == 0) { server_type = PETER_LEWIS_SERVER; use_list = TRUE; set_mac_binary(server_type); - CTRACE(tfp, "HTFTP: Treating as Peter Lewis (MACOS) server.\n"); + CTRACE((tfp, "HTFTP: Treating as Peter Lewis (MACOS) server.\n")); } else if (strncmp(response_text+4, "Windows_NT", 10) == 0) { server_type = WINDOWS_NT_SERVER; - use_list = TRUE; - CTRACE(tfp, "HTFTP: Treating as Window_NT server.\n"); + CTRACE((tfp, "HTFTP: Treating as Window_NT server.\n")); + set_unix_dirstyle(&server_type, &use_list); + + } else if (strncmp(response_text+4, "Windows2000", 11) == 0) { + server_type = WINDOWS_2K_SERVER; + CTRACE((tfp, "HTFTP: Treating as Window_2K server.\n")); + set_unix_dirstyle(&server_type, &use_list); } else if (strncmp(response_text+4, "MS Windows", 10) == 0) { server_type = MS_WINDOWS_SERVER; use_list = TRUE; - CTRACE(tfp, "HTFTP: Treating as MS Windows server.\n"); + CTRACE((tfp, "HTFTP: Treating as MS Windows server.\n")); } else if (strncmp(response_text+4, "MACOS AppleShare IP FTP Server", 30) == 0) { server_type = APPLESHARE_SERVER; use_list = TRUE; set_mac_binary(server_type); - CTRACE(tfp, "HTFTP: Treating as AppleShare server.\n"); + CTRACE((tfp, "HTFTP: Treating as AppleShare server.\n")); } else { server_type = GENERIC_SERVER; - CTRACE(tfp, "HTFTP: Ugh! A Generic server.\n"); + CTRACE((tfp, "HTFTP: Ugh! A Generic server.\n")); get_ftp_pwd(&server_type, &use_list); unsure_type = TRUE; } @@ -951,7 +1029,7 @@ PRIVATE int get_connection ARGS2( close_connection(control->socket); return -status; /* Bad return */ } - CTRACE(tfp, "HTFTP: Port defined.\n"); + CTRACE((tfp, "HTFTP: Port defined.\n")); } #endif /* NOTREPEAT_PORT */ return con->socket; /* Good return */ @@ -970,7 +1048,7 @@ PRIVATE int close_master_socket NOARGS if (master_socket != -1) FD_CLR(master_socket, &open_sockets); status = NETCLOSE(master_socket); - CTRACE(tfp, "HTFTP: Closed master socket %d\n", master_socket); + CTRACE((tfp, "HTFTP: Closed master socket %d\n", master_socket)); master_socket = -1; if (status < 0) return HTInetStatus(gettext("close master socket")); @@ -995,8 +1073,15 @@ PRIVATE int close_master_socket NOARGS */ PRIVATE int get_listen_socket NOARGS { +#ifdef INET6 + struct sockaddr_storage soc_address; /* Binary network address */ + struct sockaddr_in* soc_in = (struct sockaddr_in *)&soc_address; + int af; + int slen; +#else struct sockaddr_in soc_address; /* Binary network address */ struct sockaddr_in* soc_in = &soc_address; +#endif /* INET6 */ int new_socket; /* Will be master_socket */ @@ -1008,22 +1093,56 @@ PRIVATE int get_listen_socket NOARGS return master_socket; /* Done already */ #endif /* !REPEAT_LISTEN */ +#ifdef INET6 + /* query address family of control connection */ + slen = sizeof(soc_address); + if (getsockname(control->socket, (struct sockaddr *)&soc_address, + &slen) < 0) { + return HTInetStatus("getsockname failed"); + } + af = ((struct sockaddr *)&soc_address)->sa_family; + memset(&soc_address, 0, sizeof(soc_address)); +#endif /* INET6 */ + /* Create internet socket */ +#ifdef INET6 + new_socket = socket(af, SOCK_STREAM, IPPROTO_TCP); +#else new_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +#endif /* INET6 */ if (new_socket < 0) return HTInetStatus(gettext("socket for master socket")); - CTRACE(tfp, "HTFTP: Opened master socket number %d\n", new_socket); + CTRACE((tfp, "HTFTP: Opened master socket number %d\n", new_socket)); /* Search for a free port. */ +#ifdef INET6 + memset(&soc_address, 0, sizeof(soc_address)); + ((struct sockaddr *)&soc_address)->sa_family = af; + switch (af) { + case AF_INET: +#ifdef SIN6_LEN + ((struct sockaddr *)&soc_address)->sa_len = sizeof(struct sockaddr_in); +#endif /* SIN6_LEN */ + break; + case AF_INET6: +#ifdef SIN6_LEN + ((struct sockaddr *)&soc_address)->sa_len = sizeof(struct sockaddr_in6); +#endif /* SIN6_LEN */ + break; + default: + HTInetStatus("AF"); + } +#else soc_in->sin_family = AF_INET; /* Family = internet, host order */ soc_in->sin_addr.s_addr = INADDR_ANY; /* Any peer address */ +#endif /* INET6 */ #ifdef POLL_PORTS { - unsigned short old_port_number = port_number; + PortNumber old_port_number = port_number; for (port_number = (old_port_number+1); ; port_number++) { int status; if (port_number > LAST_TCP_PORT) @@ -1031,27 +1150,33 @@ PRIVATE int get_listen_socket NOARGS if (port_number == old_port_number) { return HTInetStatus("bind"); } +#ifdef INET6 + soc_in->sin_port = htons(port_number); +#else soc_address.sin_port = htons(port_number); +#endif /* INET6 */ #ifdef SOCKS if (socks_flag) if ((status=Rbind(new_socket, (struct sockaddr*)&soc_address, /* Cast to generic sockaddr */ - sizeof(soc_address) + SOCKADDR_LEN(soc_address) #ifndef SHORTENED_RBIND ,socks_bind_remoteAddr #endif /* !SHORTENED_RBIND */ - )) == 0) + )) == 0) { break; - else + } else #endif /* SOCKS */ if ((status=bind(new_socket, (struct sockaddr*)&soc_address, /* Cast to generic sockaddr */ - sizeof(soc_address))) == 0) + SOCKADDR_LEN(soc_address) + )) == 0) { break; - CTRACE(tfp, "TCP bind attempt to port %d yields %d, errno=%d\n", - port_number, status, SOCKET_ERRNO); + } + CTRACE((tfp, "TCP bind attempt to port %d yields %d, errno=%d\n", + port_number, status, SOCKET_ERRNO)); } /* for */ } #else @@ -1069,10 +1194,17 @@ PRIVATE int get_listen_socket NOARGS (struct sockaddr *)&soc_address, (void *)&address_length); if (status<0) return HTInetStatus("getsockname"); - CTRACE(tfp, "HTFTP: This host is %s\n", - HTInetString(soc_in)); +#ifdef INET6 + CTRACE((tfp, "HTFTP: This host is %s\n", + HTInetString((SockA *)soc_in))); + + soc_in->sin_port = 0; /* Unspecified: please allocate */ +#else + CTRACE((tfp, "HTFTP: This host is %s\n", + HTInetString(soc_in))); soc_address.sin_port = 0; /* Unspecified: please allocate */ +#endif /* INET6 */ #ifdef SOCKS if (socks_flag) status=Rbind(new_socket, @@ -1080,7 +1212,11 @@ PRIVATE int get_listen_socket NOARGS /* Cast to generic sockaddr */ sizeof(soc_address) #ifndef SHORTENED_RBIND +#ifdef INET6 + socks_bind_remoteAddr +#else ,socks_bind_remoteAddr +#endif /* INET6 */ #endif /* !SHORTENED_RBIND */ ); else @@ -1088,7 +1224,8 @@ PRIVATE int get_listen_socket NOARGS status=bind(new_socket, (struct sockaddr*)&soc_address, /* Cast to generic sockaddr */ - sizeof(soc_address)); + SOCKADDR_LEN(soc_address) + ); if (status<0) return HTInetStatus("bind"); address_length = sizeof(soc_address); @@ -1106,21 +1243,31 @@ PRIVATE int get_listen_socket NOARGS } #endif /* POLL_PORTS */ - CTRACE(tfp, "HTFTP: bound to port %d on %s\n", +#ifdef INET6 + CTRACE((tfp, "HTFTP: bound to port %d on %s\n", + (int)ntohs(soc_in->sin_port), + HTInetString((SockA *)soc_in))); +#else + CTRACE((tfp, "HTFTP: bound to port %d on %s\n", (int)ntohs(soc_in->sin_port), - HTInetString(soc_in)); + HTInetString(soc_in))); +#endif /* INET6 */ #ifdef REPEAT_LISTEN if (master_socket >= 0) (void) close_master_socket(); -#endif /* REPEAD_LISTEN */ +#endif /* REPEAT_LISTEN */ master_socket = new_socket; /* Now we must find out who we are to tell the other guy */ (void)HTHostName(); /* Make address valid - doesn't work*/ - sprintf(port_command, "PORT %d,%d,%d,%d,%d,%d%c%c", +#ifdef INET6 + switch (((struct sockaddr *)&soc_address)->sa_family) { + case AF_INET: +#endif /* INET6 */ + sprintf(port_command, "PORT %d,%d,%d,%d,%d,%d%c%c", (int)*((unsigned char *)(&soc_in->sin_addr)+0), (int)*((unsigned char *)(&soc_in->sin_addr)+1), (int)*((unsigned char *)(&soc_in->sin_addr)+2), @@ -1129,23 +1276,43 @@ PRIVATE int get_listen_socket NOARGS (int)*((unsigned char *)(&soc_in->sin_port)+1), CR, LF); - -/* Inform TCP that we will accept connections -*/ - { - int status; +#ifdef INET6 + break; + + case AF_INET6: + { + char hostbuf[MAXHOSTNAMELEN]; + char portbuf[MAXHOSTNAMELEN]; + getnameinfo((struct sockaddr *)&soc_address, + SOCKADDR_LEN(soc_address), + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV); + sprintf(port_command, "EPRT |%d|%s|%s|%c%c", 2, hostbuf, portbuf, + CR, LF); + break; + } + default: + sprintf(port_command, "JUNK%c%c", CR, LF); + break; + } +#endif /* INET6 */ + + /* Inform TCP that we will accept connections + */ + { + int status; #ifdef SOCKS - if (socks_flag) - status = Rlisten(master_socket, 1); - else + if (socks_flag) + status = Rlisten(master_socket, 1); + else #endif /* SOCKS */ - status = listen(master_socket, 1); - if (status < 0) { - master_socket = -1; - return HTInetStatus("listen"); + status = listen(master_socket, 1); + if (status < 0) { + master_socket = -1; + return HTInetStatus("listen"); + } } - } - CTRACE(tfp, "TCP: Master socket(), bind() and listen() all OK\n"); + CTRACE((tfp, "TCP: Master socket(), bind() and listen() all OK\n")); FD_SET(master_socket, &open_sockets); if ((master_socket+1) > num_sockets) num_sockets = master_socket+1; @@ -1181,7 +1348,6 @@ PRIVATE void set_years_and_date NOARGS day[0] = '0'; } strncpy(month, (char *)ctime(&NowTime)+4, 3); - strncpy(month, (char *)ctime(&NowTime)+4, 3); month[3] = '\0'; for (i = 0; i < 12; i++) { if (!strcasecomp(month, months[i])) { @@ -1189,8 +1355,7 @@ PRIVATE void set_years_and_date NOARGS } } i++; - sprintf(month, "%s%d", (i < 10 ? "0" : ""), i); - sprintf(date, "9999%.2s%.2s", month, day); + sprintf(date, "9999%02d%.2s", i, day); TheDate = atoi(date); strcpy(ThisYear, (char *)ctime(&NowTime)+20); ThisYear[4] = '\0'; @@ -1229,7 +1394,7 @@ PRIVATE BOOLEAN is_ls_date ARGS1( char *, s) { /* must start with three alpha characters */ - if (!isalpha(*s++) || !isalpha(*s++) || !isalpha(*s++)) + if (!isalpha(UCH(*s++)) || !isalpha(UCH(*s++)) || !isalpha(UCH(*s++))) return FALSE; /* space or HT_NON_BREAK_SPACE */ @@ -1240,14 +1405,14 @@ PRIVATE BOOLEAN is_ls_date ARGS1( s++; /* space or digit */ - if (!(*s == ' ' || isdigit(*s))) { + if (!(*s == ' ' || isdigit(UCH(*s)))) { s++; return FALSE; } s++; /* digit */ - if (!isdigit(*s++)) + if (!isdigit(UCH(*s++))) return FALSE; /* space */ @@ -1255,29 +1420,29 @@ PRIVATE BOOLEAN is_ls_date ARGS1( return FALSE; /* space or digit */ - if (!(*s == ' ' || isdigit(*s))) { + if (!(*s == ' ' || isdigit(UCH(*s)))) { s++; return FALSE; } s++; /* digit */ - if (!isdigit(*s++)) + if (!isdigit(UCH(*s++))) return FALSE; /* colon or digit */ - if (!(*s == ':' || isdigit(*s))) { + if (!(*s == ':' || isdigit(UCH(*s)))) { s++; return FALSE; } s++; /* digit */ - if (!isdigit(*s++)) + if (!isdigit(UCH(*s++))) return FALSE; /* space or digit */ - if (!(*s == ' ' || isdigit(*s))) { + if (!(*s == ' ' || isdigit(UCH(*s)))) { s++; return FALSE; } @@ -1336,6 +1501,7 @@ PRIVATE void parse_eplf_line ARGS2( break; case '/': StrAllocCopy(info->type, ENTRY_IS_DIRECTORY); + /* FALLTHRU */ default: while (*cp) { if (*cp++ == ',') @@ -1354,12 +1520,12 @@ PRIVATE void parse_ls_line ARGS2( char *, line, EntryInfo *, entry_info) { - short i, j; + int i, j; int base=1; int size_num=0; for (i = strlen(line) - 1; - (i > 13) && (!isspace(line[i]) || !is_ls_date(&line[i-12])); i--) + (i > 13) && (!isspace(UCH(line[i])) || !is_ls_date(&line[i-12])); i--) ; /* null body */ line[i] = '\0'; if (i > 13) { @@ -1375,7 +1541,7 @@ PRIVATE void parse_ls_line ARGS2( } } j = i - 14; - while (isdigit(line[j])) { + while (isdigit(UCH(line[j]))) { size_num += (line[j] - '0') * base; base *= 10; j--; @@ -1385,6 +1551,111 @@ PRIVATE void parse_ls_line ARGS2( } /* parse_ls_line() */ /* + * parse_dls_line() -- + * Extract the name and size info and whether it refers to a + * directory from a LIST line in "dls" format. + */ +PRIVATE void parse_dls_line ARGS3( + char *, line, + EntryInfo *, entry_info, + char **, pspilledname) +{ + short j; + int base=1; + int size_num=0; + int len; + char *cps = NULL; + + /* README 763 Information about this server\0 + bin/ - \0 + etc/ = \0 + ls-lR 0 \0 + ls-lR.Z 3 \0 + pub/ = Public area\0 + usr/ - \0 + morgan 14 -> ../real/morgan\0 + TIMIT.mostlikely.Z\0 + 79215 \0 + */ + + len = strlen(line); + if (len == 0) { + FREE(*pspilledname); + entry_info->display = FALSE; + return; + } + cps = LYSkipNonBlanks(line); + if (*cps == '\0') { /* only a filename, save it and return. */ + StrAllocCopy(*pspilledname, line); + entry_info->display = FALSE; + return; + } + if (len < 24 || line[23] != ' ' || + (isspace(UCH(line[0])) && !*pspilledname)) { + /* this isn't the expected "dls" format! */ + if (!isspace(UCH(line[0]))) + *cps = '\0'; + if (*pspilledname && !*line) { + entry_info->filename = *pspilledname; + *pspilledname = NULL; + if (entry_info->filename[strlen(entry_info->filename)-1] == '/') + StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); + else + StrAllocCopy(entry_info->type, ""); + } else { + StrAllocCopy(entry_info->filename, line); + if (cps && cps != line && *(cps-1) == '/') + StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); + else + StrAllocCopy(entry_info->type, ""); + FREE(*pspilledname); + } + return; + } + + j = 22; + if (line[j] == '=' || line[j] == '-') { + StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); + } else { + while (isdigit(UCH(line[j]))) { + size_num += (line[j] - '0') * base; + base *= 10; + j--; + } + } + entry_info->size = size_num; + + cps = LYSkipBlanks(&line[23]); + if (!strncmp(cps, "-> ", 3) && cps[3] != '\0' && cps[3] != ' ') { + StrAllocCopy(entry_info->type, gettext("Symbolic Link")); + entry_info->size = 0; /* don't display size */ + } + + if (j > 0) + line[j] = '\0'; + + LYTrimTrailing(line); + + len = strlen(line); + if (len == 0 && *pspilledname && **pspilledname) { + line = *pspilledname; + len = strlen(*pspilledname); + } + if (len > 0 && line[len-1] == '/') { + /* + ** It's a dir, remove / and mark it as such. + */ + if (len > 1) + line[len-1] = '\0'; + if (!entry_info->type) + StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); + } + + StrAllocCopy(entry_info->filename, line); + FREE(*pspilledname); +} /* parse_dls_line() */ + +/* * parse_vms_dir_entry() * Format the name, date, and size from a VMS LIST line * into the EntryInfo structure - FM @@ -1457,34 +1728,26 @@ PRIVATE void parse_vms_dir_entry ARGS2( /** Track down the date. **/ if ((cpd=strchr(cp, '-')) != NULL && - strlen(cpd) > 9 && isdigit(*(cpd-1)) && - isalpha(*(cpd+1)) && *(cpd+4) == '-') { + strlen(cpd) > 9 && isdigit(UCH(*(cpd-1))) && + isalpha(UCH(*(cpd+1))) && *(cpd+4) == '-') { /** Month **/ - *(cpd+4) = '\0'; - *(cpd+2) = TOLOWER(*(cpd+2)); - *(cpd+3) = TOLOWER(*(cpd+3)); - sprintf(date, "%s ", cpd+1); - *(cpd+4) = '-'; + *(cpd+2) = (char) TOLOWER(*(cpd+2)); + *(cpd+3) = (char) TOLOWER(*(cpd+3)); + sprintf(date, "%.3s ", cpd+1); /** Day **/ - *cpd = '\0'; - if (isdigit(*(cpd-2))) - sprintf(date+4, "%s ", cpd-2); + if (isdigit(UCH(*(cpd-2)))) + sprintf(date+4, "%.2s ", cpd-2); else - sprintf(date+4, "%c%s ", HT_NON_BREAK_SPACE, cpd-1); - *cpd = '-'; + sprintf(date+4, "%c%.1s ", HT_NON_BREAK_SPACE, cpd-1); /** Time or Year **/ if (!strncmp(ThisYear, cpd+5, 4) && strlen(cpd) > 15 && *(cpd+12) == ':') { - *(cpd+15) = '\0'; - sprintf(date+7, "%s", cpd+10); - *(cpd+15) = ' '; + sprintf(date+7, "%.5s", cpd+10); } else { - *(cpd+9) = '\0'; - sprintf(date+7, " %s", cpd+5); - *(cpd+9) = ' '; + sprintf(date+7, " %.4s", cpd+5); } StrAllocCopy(entry_info->date, date); @@ -1494,13 +1757,13 @@ PRIVATE void parse_vms_dir_entry ARGS2( if ((cpd=strchr(cp, '/')) != NULL) { /* Appears be in used/allocated format */ cps = cpd; - while (isdigit(*(cps-1))) + while (isdigit(UCH(*(cps-1)))) cps--; if (cps < cpd) *cpd = '\0'; entry_info->size = atoi(cps); cps = cpd+1; - while (isdigit(*cps)) + while (isdigit(UCH(*cps))) cps++; *cps = '\0'; ialloc = atoi(cpd+1); @@ -1513,7 +1776,7 @@ PRIVATE void parse_vms_dir_entry ARGS2( /* Now let's hunt for a lone, size number */ while ((cps=strtok(NULL, sp)) != NULL) { cpd = cps; - while (isdigit(*cpd)) + while (isdigit(UCH(*cpd))) cpd++; if (*cpd == '\0') { /* Assume it's blocks */ @@ -1524,10 +1787,10 @@ PRIVATE void parse_vms_dir_entry ARGS2( } /** Wrap it up **/ - CTRACE(tfp, "HTFTP: VMS filename: %s date: %s size: %d\n", + CTRACE((tfp, "HTFTP: VMS filename: %s date: %s size: %d\n", entry_info->filename, entry_info->date ? entry_info->date : "", - entry_info->size); + entry_info->size)); return; } /* parse_vms_dir_entry() */ @@ -1562,7 +1825,7 @@ PRIVATE void parse_ms_windows_dir_entry ARGS2( cps = LYSkipBlanks(cps); cpd = LYSkipNonBlanks(cps); *cpd++ = '\0'; - if (isdigit(*cps)) { + if (isdigit(UCH(*cps))) { entry_info->size = atoi(cps); } else { StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); @@ -1585,10 +1848,10 @@ PRIVATE void parse_ms_windows_dir_entry ARGS2( *(cpd+17) = '\0'; /* Time */ if (strcmp(ThisYear, cpd+7)) /* Not this year, so show the year */ - sprintf(date, "%s %s", cpd, (cpd+7)); + sprintf(date, "%.6s %.4s", cpd, (cpd+7)); else /* Is this year, so show the time */ - sprintf(date, "%s %s", cpd, (cpd+12)); + sprintf(date, "%.6s %.5s", cpd, (cpd+12)); StrAllocCopy(entry_info->date, date); if (entry_info->date[4] == ' '|| entry_info->date[4] == '0') { entry_info->date[4] = HT_NON_BREAK_SPACE; @@ -1597,10 +1860,10 @@ PRIVATE void parse_ms_windows_dir_entry ARGS2( } /** Wrap it up **/ - CTRACE(tfp, "HTFTP: MS Windows filename: %s date: %s size: %d\n", + CTRACE((tfp, "HTFTP: MS Windows filename: %s date: %s size: %d\n", entry_info->filename, entry_info->date ? entry_info->date : "", - entry_info->size); + entry_info->size)); return; } /* parse_ms_windows_dir_entry */ @@ -1666,16 +1929,16 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2( *(cp+2) = '\0'; /* Month */ i = atoi(cp) - 1; *(cp+5) = '\0'; /* Day */ - sprintf(date, "%s %s", months[i], (cp+3)); + sprintf(date, "%.3s %.2s", months[i], (cp+3)); if (date[4] == '0') date[4] = ' '; cp += 6; /* Year */ if (strcmp((ThisYear+2), cp)) { /* Not this year, so show the year */ if (atoi(cp) < 70) { - sprintf(&date[6], " 20%s", cp); + sprintf(&date[6], " 20%.2s", cp); } else { - sprintf(&date[6], " 19%s", cp); + sprintf(&date[6], " 19%.2s", cp); } } else { /* Is this year, so show the time */ @@ -1683,9 +1946,7 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2( i = atoi(cpd); if (*(cpd+5) == 'P' || *(cpd+5) == 'p') i += 12; - *(cpd+5) = '\0'; - sprintf(&date[6], " %s%d:%s", - (i < 10 ? "0" : ""), i, (cpd+3)); + sprintf(&date[6], " %02d:%.2s", i, (cpd+3)); } StrAllocCopy(entry_info->date, date); if (entry_info->date[4] == ' '|| entry_info->date[4] == '0') { @@ -1708,10 +1969,10 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2( } /** Wrap it up **/ - CTRACE(tfp, "HTFTP: Windows NT filename: %s date: %s size: %d\n", + CTRACE((tfp, "HTFTP: Windows NT filename: %s date: %s size: %d\n", entry_info->filename, entry_info->date ? entry_info->date : "", - entry_info->size); + entry_info->size)); return; } /* parse_windows_nt_dir_entry */ #endif /* NOTDEFINED */ @@ -1782,7 +2043,7 @@ PRIVATE void parse_cms_dir_entry ARGS2( cp = LYSkipBlanks(cp); cps = LYSkipNonBlanks(cp); *cps++ = '\0'; - if (isdigit(*cp)) { + if (isdigit(UCH(*cp))) { RecordLength = atoi(cp); } } @@ -1793,7 +2054,7 @@ PRIVATE void parse_cms_dir_entry ARGS2( cp = LYSkipBlanks(cp); cps = LYSkipNonBlanks(cp); *cps++ = '\0'; - if (isdigit(*cp)) { + if (isdigit(UCH(*cp))) { Records = atoi(cp); } if (Records > 0 && RecordLength > 0) { @@ -1812,7 +2073,7 @@ PRIVATE void parse_cms_dir_entry ARGS2( if (((cps < end) && (cps = strchr(cpd, ':')) != NULL) && (cps < (end - 3) && - isdigit(*(cps+1)) && isdigit(*(cps+2)) && *(cps+3) == ':')) { + isdigit(UCH(*(cps+1))) && isdigit(UCH(*(cps+2))) && *(cps+3) == ':')) { cps += 3; *cps = '\0'; if ((cps - cpd) >= 14) { @@ -1824,23 +2085,22 @@ PRIVATE void parse_cms_dir_entry ARGS2( if (*cpd == ' ') *cpd = '0'; i = atoi(cpd) - 1; - sprintf(date, "%s %s", months[i], (cpd+3)); + sprintf(date, "%.3s %.2s", months[i], (cpd+3)); if (date[4] == '0') date[4] = ' '; cpd += 6; /* Year */ if (strcmp((ThisYear+2), cpd)) { /* Not this year, so show the year. */ if (atoi(cpd) < 70) { - sprintf(&date[6], " 20%s", cpd); + sprintf(&date[6], " 20%.2s", cpd); } else { - sprintf(&date[6], " 19%s", cpd); + sprintf(&date[6], " 19%.2s", cpd); } } else { /* Is this year, so show the time. */ *(cps+2) = '\0'; /* Hour */ i = atoi(cps); - sprintf(&date[6], " %s%d:%s", - (i < 10 ? "0" : ""), i, (cps+3)); + sprintf(&date[6], " %02d:%.2s", i, (cps+3)); } StrAllocCopy(entry_info->date, date); if (entry_info->date[4] == ' '|| entry_info->date[4] == '0') { @@ -1850,10 +2110,10 @@ PRIVATE void parse_cms_dir_entry ARGS2( } /** Wrap it up. **/ - CTRACE(tfp, "HTFTP: VM/CMS filename: %s date: %s size: %d\n", + CTRACE((tfp, "HTFTP: VM/CMS filename: %s date: %s size: %d\n", entry_info->filename, entry_info->date ? entry_info->date : "", - entry_info->size); + entry_info->size)); return; } /* parse_cms_dir_entry */ @@ -1865,9 +2125,10 @@ PRIVATE void parse_cms_dir_entry ARGS2( * If first is true, this is the first name in a directory. */ -PRIVATE EntryInfo * parse_dir_entry ARGS2( +PRIVATE EntryInfo * parse_dir_entry ARGS3( char *, entry, - BOOLEAN *, first) + BOOLEAN *, first, + char **, pspilledname) { EntryInfo *entry_info; int i; @@ -1885,11 +2146,57 @@ PRIVATE EntryInfo * parse_dir_entry ARGS2( entry_info->display = TRUE; switch (server_type) { + case DLS_SERVER: + + /* + ** Interpret and edit LIST output from a Unix server + ** in "dls" format. + ** This one must have claimed to be Unix in order to + ** get here; if the first line looks fishy, we revert + ** to Unix and hope that fits better (this recovery is + ** untested). - kw + */ + + if (*first) { + len = strlen(entry); + if (!len || entry[0] == ' ' || + (len >= 24 && entry[23] != ' ') || + (len < 24 && strchr(entry, ' '))) { + server_type = UNIX_SERVER; + CTRACE((tfp, + "HTFTP: Falling back to treating as Unix server.\n")); + } else { + *first = FALSE; + } + } + + if (server_type == DLS_SERVER) { + /* if still unchanged... */ + parse_dls_line(entry, entry_info, pspilledname); + + if (!entry_info->filename || *entry_info->filename == '\0') { + entry_info->display = FALSE; + return(entry_info); + } + if (!strcmp(entry_info->filename,"..") || + !strcmp(entry_info->filename,".")) + entry_info->display = FALSE; + if (entry_info->type && *entry_info->type == '\0') { + FREE(entry_info->type); + return(entry_info); + } + /* + ** Goto the bottom and get real type. + */ + break; + } /* fall through if server_type changed for *first == TRUE ! */ + case UNIX_SERVER: case PETER_LEWIS_SERVER: case MACHTEN_SERVER: case MSDOS_SERVER: case WINDOWS_NT_SERVER: + case WINDOWS_2K_SERVER: case APPLESHARE_SERVER: case NETPRESENZ_SERVER: /* @@ -1948,7 +2255,7 @@ PRIVATE EntryInfo * parse_dir_entry ARGS2( ** Strip off " -> pathname". */ for (i = len - 1; (i > 3) && - (!isspace(entry[i]) || + (!isspace(UCH(entry[i])) || (entry[i-1] != '>') || (entry[i-2] != '-') || (entry[i-3] != ' ')); i--) @@ -2203,29 +2510,33 @@ PRIVATE int compare_EntryInfo_structs ARGS2( } } i++; - sprintf(month, "%s%d", (i < 10 ? "0" : ""), i); + sprintf(month, "%02d", i); strcat(date1, month); strncat(date1, &entry1->date[4], 2); date1[8] = '\0'; if (date1[6] == ' ' || date1[6] == HT_NON_BREAK_SPACE) { date1[6] = '0'; } - if (date1[0] == '9' && atoi(date1) > TheDate) { + /* If no year given, assume last year if it would otherwise + * be in the future by more than one day. The one day + * tolerance is to account for a possible timezone + * difference. - kw */ + if (date1[0] == '9' && atoi(date1) > TheDate + 1) { for (i = 0; i < 4; i++) { date1[i] = LastYear[i]; } } strcat(date1, time1); - if (entry2->date[9] == ':') { - strcpy(date2, "9999"); - strcpy(time2, &entry2->date[7]); - if (time2[0] == ' ') { - time2[0] = '0'; - } - } else { - strcpy(date2, &entry2->date[8]); - strcpy(time2, "00:00"); + if (entry2->date[9] == ':') { + strcpy(date2, "9999"); + strcpy(time2, &entry2->date[7]); + if (time2[0] == ' ') { + time2[0] = '0'; } + } else { + strcpy(date2, &entry2->date[8]); + strcpy(time2, "00:00"); + } strncpy(month, entry2->date, 3); month[3] = '\0'; for (i = 0; i < 12; i++) { @@ -2234,14 +2545,18 @@ PRIVATE int compare_EntryInfo_structs ARGS2( } } i++; - sprintf(month, "%s%d", (i < 10 ? "0" : ""), i); + sprintf(month, "%02d", i); strcat(date2, month); strncat(date2, &entry2->date[4], 2); date2[8] = '\0'; if (date2[6] == ' ' || date2[6] == HT_NON_BREAK_SPACE) { date2[6] = '0'; } - if (date2[0] == '9' && atoi(date2) > TheDate) { + /* If no year given, assume last year if it would otherwise + * be in the future by more than one day. The one day + * tolerance is to account for a possible timezone + * difference. - kw */ + if (date2[0] == '9' && atoi(date2) > TheDate + 1) { for (i = 0; i < 4; i++) { date2[i] = LastYear[i]; } @@ -2297,6 +2612,13 @@ PRIVATE int read_directory ARGS4( _HTProgress (gettext("Receiving FTP directory.")); /* + * Force the current Date and Year (TheDate, ThisYear, and LastYear) + * to be recalculated for each directory request. Otherwise we have + * a problem with long-running sessions assuming the wrong date for + * today. - kw + */ + HaveYears = FALSE; + /* ** Check whether we always want the home ** directory treated as Welcome. - FM */ @@ -2346,33 +2668,43 @@ PRIVATE int read_directory ARGS4( int BytesReceived = 0; int BytesReported = 0; char NumBytes[64]; + char *spilledname = NULL; PUTC('\n'); /* prettier LJM */ for (ic = 0; ic != EOF;) { /* For each entry in the directory */ HTChunkClear(chunk); if (HTCheckForInterrupt()) { + CTRACE((tfp, + "read_directory: interrupted after %d bytes\n", + BytesReceived)); WasInterrupted = TRUE; if (BytesReceived) { goto unload_btree; /* unload btree */ } else { ABORT_TARGET; HTBTreeAndObject_free(bt); + FREE(spilledname); return HT_INTERRUPTED; } } /* read directory entry */ + interrupted_in_next_data_char = FALSE; for (;;) { /* Read in one line as filename */ ic = NEXT_DATA_CHAR; AgainForMultiNet: if (interrupted_in_next_data_char) { + CTRACE((tfp, + "read_directory: interrupted_in_next_data_char after %d bytes\n", + BytesReceived)); WasInterrupted = TRUE; if (BytesReceived) { goto unload_btree; /* unload btree */ } else { ABORT_TARGET; HTBTreeAndObject_free(bt); + FREE(spilledname); return HT_INTERRUPTED; } } else if ((char)ic == CR || (char)ic == LF) { /* Terminator? */ @@ -2417,7 +2749,14 @@ AgainForMultiNet: BytesReceived += chunk->size; if (BytesReceived > BytesReported + 1024) { +#ifdef _WINDOWS + extern int ws_read_per_sec; + + sprintf(NumBytes,gettext("Transferred %d bytes (%5d)"), + BytesReceived, ws_read_per_sec); +#else sprintf(NumBytes, TRANSFERRED_X_BYTES, BytesReceived); +#endif HTProgress(NumBytes); BytesReported = BytesReceived; } @@ -2425,13 +2764,14 @@ AgainForMultiNet: if (ic == EOF && chunk->size == 1) /* 1 means empty: includes terminating 0 */ break; - CTRACE(tfp, "HTFTP: Line in %s is %s\n", - lastpath, chunk->data); + CTRACE((tfp, "HTFTP: Line in %s is %s\n", + lastpath, chunk->data)); - entry_info = parse_dir_entry(chunk->data, &first); + entry_info = parse_dir_entry(chunk->data, &first, &spilledname); if (entry_info->display) { - CTRACE(tfp, "Adding file to BTree: %s\n", - entry_info->filename); + FREE(spilledname); + CTRACE((tfp, "Adding file to BTree: %s\n", + entry_info->filename)); HTBTree_add(bt, (EntryInfo *)entry_info); } else { free_entryinfo_struct_contents(entry_info); @@ -2443,6 +2783,7 @@ AgainForMultiNet: unload_btree: HTChunkFree(chunk); + FREE(spilledname); /* print out the handy help message if it exits :) */ if (help_message_cache_non_empty()) { @@ -2466,6 +2807,14 @@ unload_btree: /* Run through tree printing out in order */ { +#ifdef SH_EX /* 1997/10/18 (Sat) 14:14:28 */ + char *p, name_buff[256]; + int name_len, dot_len; + +#define FNAME_WIDTH 30 +#define FILE_GAP 2 + +#endif HTBTElement * ele; int i; for (ele = HTBTree_next(bt, NULL); @@ -2481,7 +2830,7 @@ unload_btree: } if (entry_info->type) { - for (i = 0; entry_info->type[i] != '\0' && i < 15; i++) + for (i = 0; entry_info->type[i] != '\0' && i < 16; i++) PUTC(entry_info->type[i]); for (; i < 17; i++) PUTC(' '); @@ -2489,16 +2838,44 @@ unload_btree: /* start the anchor */ HTDirEntry(target, lastpath, entry_info->filename); +#ifdef SH_EX /* 1997/10/18 (Sat) 16:00 */ + name_len = strlen(entry_info->filename); + + sprintf(name_buff, "%-30s", entry_info->filename); + + if (name_len < FNAME_WIDTH) { + dot_len = FNAME_WIDTH - FILE_GAP - name_len; + if (dot_len > 0) { + p = name_buff + name_len + 1; + while (dot_len--) + *p++ = '.'; + } + } else { + name_buff[FNAME_WIDTH] = '\0'; + } + + PUTS(name_buff); +#else PUTS(entry_info->filename); +#endif END(HTML_A); if (entry_info->size) { +#ifdef SH_EX /* 1998/02/02 (Mon) 16:34:52 */ + if (entry_info->size < 1024) + sprintf(string_buffer, "%6d bytes", + entry_info->size); + else + sprintf(string_buffer, "%6d Kb", + entry_info->size/1024); +#else if (entry_info->size < 1024) sprintf(string_buffer, " %d bytes", entry_info->size); else sprintf(string_buffer, " %dKb", entry_info->size/1024); +#endif PUTS(string_buffer); } @@ -2514,27 +2891,25 @@ unload_btree: FREE(lastpath); - if (server_type == APPLESHARE_SERVER || - server_type == NETPRESENZ_SERVER) { + if (WasInterrupted || data_soc != -1) { /* should always be true */ /* * Without closing the data socket first, - * the response(NIL) below hangs. - KW + * the response(0) later may hang. + * Some servers expect the client to fin/ack the close + * of the data connection before proceeding with the + * conversation on the control connection. - kw */ - NETCLOSE(data_soc); + CTRACE((tfp, "HTFTP: Closing data socket %d\n", data_soc)); + status = NETCLOSE(data_soc); + if (status == -1) + HTInetStatus("close"); /* Comment only */ + data_soc = -1; } if (WasInterrupted || HTCheckForInterrupt()) { - if (server_type != CMS_SERVER) - response(NIL); _HTProgress(TRANSFER_INTERRUPTED); - return HT_LOADED; } - if (server_type != CMS_SERVER) - response(NIL); return HT_LOADED; -#ifdef NOTDEFINED - return response(NIL) == 2 ? HT_LOADED : -1; -#endif /* NOTDEFINED */ } /* Retrieve File from Server @@ -2554,39 +2929,47 @@ PUBLIC int HTFTPLoad ARGS4( { BOOL isDirectory = NO; HTAtom * encoding = NULL; - int status; + int status, final_status; int retry; /* How many times tried? */ + int outstanding = 1; /* outstanding control connection responses + that we are willing to wait for, if we + get to the point of reading data - kw */ HTFormat format; - /* set use_list to NOT since we don't know what kind of server * this is yet. And set the type to GENERIC */ use_list = FALSE; server_type = GENERIC_SERVER; + HTReadProgress(0,0); for (retry = 0; retry < 2; retry++) { /* For timed out/broken connections */ status = get_connection(name, anchor); if (status < 0) return status; - if (!ftp_local_passive) { + if (!ftp_passive) { status = get_listen_socket(); if (status < 0) { NETCLOSE (control->socket); control->socket = -1; +#ifdef INET6 + if (master_socket >= 0) + (void)close_master_socket (); +#else close_master_socket (); +#endif /* INET6 */ /* HT_INTERRUPTED would fall through, if we could interrupt somehow in the middle of it, which we currently can't. */ return status; } #ifdef REPEAT_PORT - /* Inform the server of the port number we will listen on + /* Inform the server of the port number we will listen on */ status = response(port_command); if (status == HT_INTERRUPTED) { - CTRACE (tfp, "HTFTP: Interrupted in response (port_command)\n"); + CTRACE((tfp, "HTFTP: Interrupted in response (port_command)\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE (control->socket); control->socket = -1; @@ -2598,15 +2981,77 @@ PUBLIC int HTFTPLoad ARGS4( continue; /* try again - net error*/ return -status; /* bad reply */ } - CTRACE(tfp, "HTFTP: Port defined.\n"); + CTRACE((tfp, "HTFTP: Port defined.\n")); #endif /* REPEAT_PORT */ } else { /* Tell the server to be passive */ - char command[LINE_LENGTH+1]; + char *command = NULL; char *p; - int reply, h0, h1, h2, h3, p0, p1; /* Parts of reply */ + int h0, h1, h2, h3, p0, p1; /* Parts of reply */ +#ifdef INET6 + char dst[LINE_LENGTH+1]; +#endif data_soc = status; +#ifdef INET6 + status = send_cmd_1(p = "EPSV"); + if (status < 0) /* retry or Bad return */ + continue; + else if (status != 2) { + status = send_cmd_1(p = "PASV"); + if (status < 0) /* retry or Bad return */ + continue; + else if (status != 2) { + return -status; /* bad reply */ + } + } + + if (strcmp(p, "PASV") == 0) { + for (p = response_text; *p && *p != ','; p++) + ; /* null body */ + + while (--p > response_text && '0' <= *p && *p <= '9') + ; /* null body */ + status = sscanf(p+1, "%d,%d,%d,%d,%d,%d", + &h0, &h1, &h2, &h3, &p0, &p1); + if (status < 4) { + fprintf(tfp, "HTFTP: PASV reply has no inet address!\n"); + return -99; + } + passive_port = (p0<<8) + p1; + snprintf(dst, sizeof(dst), "%d.%d.%d.%d", h0, h1, h2, h3); + } else if (strcmp(p, "EPSV") == 0) { + unsigned char c0, c1, c2, c3; + struct sockaddr_storage ss; + int sslen; + + /* + * EPSV bla (|||port|) + */ + for (p = response_text; *p && !isspace(*p); p++) + ; /* null body */ + for (/*nothing*/; *p && *p && *p != '('; p++) /*)*/ + ; /* null body */ + status = sscanf(p, "(%c%c%c%d%c)", &c0, &c1, &c2, &p0, &c3); + if (status != 5) { + fprintf(tfp, "HTFTP: EPSV reply has invalid format!\n"); + return -99; + } + passive_port = p0; + + sslen = sizeof(ss); + if (getpeername(control->socket, (struct sockaddr *)&ss, + &sslen) < 0) { + fprintf(tfp, "HTFTP: getpeername(control) failed\n"); + return -99; + } + if (getnameinfo((struct sockaddr *)&ss, sslen, dst, + sizeof(dst), NULL, 0, NI_NUMERICHOST)) { + fprintf(tfp, "HTFTP: getnameinfo failed\n"); + return -99; + } + } +#else status = send_cmd_1("PASV"); if (status != 2) { if (status < 0) @@ -2619,22 +3064,27 @@ PUBLIC int HTFTPLoad ARGS4( while (--p > response_text && '0' <= *p && *p <= '9') ; /* null body */ - status = sscanf(p+1, "%d,%d,%d,%d,%d,%d", - &h0, &h1, &h2, &h3, &p0, &p1); - if (status < 4) { - fprintf(tfp, "HTFTP: PASV reply has no inet address!\n"); - return -99; - } - passive_port = (p0<<8) + p1; - CTRACE(tfp, "HTFTP: Server is listening on port %d\n", - passive_port); + status = sscanf(p+1, "%d,%d,%d,%d,%d,%d", + &h0, &h1, &h2, &h3, &p0, &p1); + if (status < 4) { + fprintf(tfp, "HTFTP: PASV reply has no inet address!\n"); + return -99; + } + passive_port = (PortNumber)((p0<<8) + p1); +#endif /* INET6 */ + CTRACE((tfp, "HTFTP: Server is listening on port %d\n", + passive_port)); + /* Open connection for data: */ -/* Open connection for data: -*/ - sprintf(command, - "ftp://%d.%d.%d.%d:%d/",h0,h1,h2,h3,passive_port); - status = HTDoConnect(name, "FTP", passive_port, &data_soc); +#ifdef INET6 + HTSprintf0(&command, "ftp://%s:%d/", dst, passive_port); +#else + HTSprintf0(&command, "ftp://%d.%d.%d.%d:%d/", + h0, h1, h2, h3, passive_port); +#endif + status = HTDoConnect(command, "FTP data", passive_port, &data_soc); + FREE(command); if (status < 0) { (void) HTInetStatus(gettext("connect for data")); @@ -2642,7 +3092,7 @@ PUBLIC int HTFTPLoad ARGS4( return status; /* Bad return */ } - CTRACE(tfp, "FTP data connected, socket %d\n", data_soc); + CTRACE((tfp, "FTP data connected, socket %d\n", data_soc)); } status = 0; break; /* No more retries */ @@ -2656,6 +3106,7 @@ PUBLIC int HTFTPLoad ARGS4( { char *filename = HTParse(name, "", PARSE_PATH + PARSE_PUNCTUATION); char *fname = filename; /** Save for subsequent free() **/ + char *vmsname = NULL; BOOL binary; char *type = NULL; char *cp; @@ -2668,7 +3119,7 @@ PUBLIC int HTFTPLoad ARGS4( init_help_message_cache(); /* to free memory */ NETCLOSE(control->socket); control->socket = -1; - CTRACE(tfp, "HTFTP: Rejecting path due to illegal escaped slash.\n"); + CTRACE((tfp, "HTFTP: Rejecting path due to illegal escaped slash.\n")); return -1; } } @@ -2704,11 +3155,11 @@ PUBLIC int HTFTPLoad ARGS4( } } if (*type != '\0') { - CTRACE(tfp, "HTFTP: type=%s\n", type); + CTRACE((tfp, "HTFTP: type=%s\n", type)); } } HTUnEscape(filename); - CTRACE(tfp, "HTFTP: UnEscaped %s\n", filename); + CTRACE((tfp, "HTFTP: UnEscaped %s\n", filename)); if (filename[1] == '~') { /* ** Check if translation of HOME as tilde is supported, @@ -2768,7 +3219,7 @@ PUBLIC int HTFTPLoad ARGS4( format = HTFileFormat(filename, &encoding, NULL); } format = HTCharsetFormat(format, anchor, -1); - binary = (encoding != HTAtom_for("8bit") && + binary = (BOOL) (encoding != HTAtom_for("8bit") && encoding != HTAtom_for("7bit")); if (!binary && /* @@ -2816,6 +3267,7 @@ PUBLIC int HTFTPLoad ARGS4( { char *cp1, *cp2; BOOL included_device = FALSE; + BOOL found_tilde = FALSE; /** Accept only Unix-style filename **/ if (strchr(filename, ':') != NULL || strchr(filename, '[') != NULL) { @@ -2823,7 +3275,7 @@ PUBLIC int HTFTPLoad ARGS4( init_help_message_cache(); /* to free memory */ NETCLOSE(control->socket); control->socket = -1; - CTRACE(tfp, "HTFTP: Rejecting path due to non-Unix-style syntax.\n"); + CTRACE((tfp, "HTFTP: Rejecting path due to non-Unix-style syntax.\n")); return -1; } /** Handle any unescaped "/%2F" path **/ @@ -2833,15 +3285,12 @@ PUBLIC int HTFTPLoad ARGS4( for (i = 0; filename[(i+1)]; i++) filename[i] = filename[(i+1)]; filename[i] = '\0'; - CTRACE(tfp, "HTFTP: Trimmed '%s'\n", filename); - cp = HTMake_VMS_name("", filename); - CTRACE(tfp, "HTFTP: VMSized '%s'\n", cp); + CTRACE((tfp, "HTFTP: Trimmed '%s'\n", filename)); + cp = HTVMS_name("", filename); + CTRACE((tfp, "HTFTP: VMSized '%s'\n", cp)); if ((cp1=strrchr(cp, ']')) != NULL) { - cp1++; - for (i = 0; cp1[i]; i++) - filename[i] = cp1[i]; - filename[i] = '\0'; - CTRACE(tfp, "HTFTP: Filename '%s'\n", filename); + strcpy(filename, ++cp1); + CTRACE((tfp, "HTFTP: Filename '%s'\n", filename)); *cp1 = '\0'; status = send_cwd(cp); if (status != 2) { @@ -2879,22 +3328,16 @@ PUBLIC int HTFTPLoad ARGS4( strchr(cp, ']') == NULL) { cp1++; if (*cp1 != '\0') { - for (i = 0; cp1[i]; i++) - filename[i] = cp1[i]; - filename[i] = '\0'; - CTRACE(tfp, "HTFTP: Filename '%s'\n", filename); - *cp1 = '\0'; - strcat(cp, "["); - strcat(cp, filename); - strcat(cp, "]"); - status = send_cwd(cp); + strcpy(filename, cp1); + CTRACE((tfp, "HTFTP: Filename '%s'\n", filename)); + HTSprintf0(&vmsname, "%.*s[%s]", cp1-cp, cp, filename); + status = send_cwd(vmsname); if (status != 2) { - *cp1 = '\0'; - strcat(cp, "[000000]"); - status = send_cwd(cp); + HTSprintf(&vmsname, "%.*s[000000]", cp1-cp, cp); + status = send_cwd(vmsname); if (status != 2) { - *cp1 = '\0'; - status = send_cwd(cp); + HTSprintf(&vmsname, "%.*s", cp1-cp, cp); + status = send_cwd(vmsname); if (status != 2) { FREE(fname); init_help_message_cache(); @@ -2904,15 +3347,15 @@ PUBLIC int HTFTPLoad ARGS4( } } } else { - strcpy(cp, "000000"); - filename = cp; + HTSprintf0(&vmsname, "000000"); + filename = vmsname; } } } else if (0==strcmp(cp, (filename+1))) { status = send_cwd(cp); if (status != 2) { - strcat(cp, ":"); - status = send_cwd(cp); + HTSprintf0(&vmsname, "%s:", cp); + status = send_cwd(vmsname); if (status != 2) { FREE(fname); init_help_message_cache(); /* to free memory */ @@ -2921,8 +3364,8 @@ PUBLIC int HTFTPLoad ARGS4( return ((status < 0) ? status : -status); } } - strcpy(cp, "000000"); - filename = cp; + HTSprintf0(&vmsname, "000000"); + filename = vmsname; } } /** Trim trailing slash if filename is not the top directory **/ @@ -2987,9 +3430,11 @@ PUBLIC int HTFTPLoad ARGS4( goto listen; } /** Otherwise, go to appropriate directory and doctor filename **/ - if (!strncmp(filename, "/~", 2)) + if (!strncmp(filename, "/~", 2)) { filename += 2; - CTRACE(tfp, "check '%s' to translate x/y/ to [.x.y]\n", filename); + found_tilde = TRUE; + } + CTRACE((tfp, "check '%s' to translate x/y/ to [.x.y]\n", filename)); if (!included_device && (cp = strchr(filename, '/')) != NULL && (cp1 = strrchr(cp, '/')) != NULL && @@ -2998,10 +3443,10 @@ PUBLIC int HTFTPLoad ARGS4( HTSprintf0(&tmp, "[.%.*s]", cp1-cp-1, cp+1); - CTRACE(tfp, "change path '%s'\n", tmp); + CTRACE((tfp, "change path '%s'\n", tmp)); while ((cp2 = strrchr(tmp, '/')) != NULL) *cp2 = '.'; - CTRACE(tfp, "...to path '%s'\n", tmp); + CTRACE((tfp, "...to path '%s'\n", tmp)); status = send_cwd(tmp); FREE(tmp); @@ -3015,7 +3460,7 @@ PUBLIC int HTFTPLoad ARGS4( } filename = cp1+1; } else { - if (!included_device) { + if (!included_device && !found_tilde) { filename += 1; } } @@ -3121,6 +3566,7 @@ PUBLIC int HTFTPLoad ARGS4( } } FREE(fname); + FREE(vmsname); if (status != 1) { init_help_message_cache(); /* to free memory */ NETCLOSE(control->socket); @@ -3133,9 +3579,13 @@ PUBLIC int HTFTPLoad ARGS4( } listen: - if (!ftp_local_passive) { + if(!ftp_passive) { /* Wait for the connection */ +#ifdef INET6 + struct sockaddr_storage soc_address; +#else struct sockaddr_in soc_address; +#endif /* INET6 */ int soc_addrlen=sizeof(soc_address); #ifdef SOCKS if (socks_flag) @@ -3151,21 +3601,47 @@ listen: init_help_message_cache(); /* to free memory */ return HTInetStatus("accept"); } - CTRACE(tfp, "TCP: Accepted new socket %d\n", status); + CTRACE((tfp, "TCP: Accepted new socket %d\n", status)); data_soc = status; - } /* !ftp_local_passive */ + } /* !ftp_passive */ + +#if 0 /* no - this makes the data connection go away too soon (2.8.3dev.22) */ + if ((status = send_cmd_nowait("QUIT")) == 1) + outstanding++; +#endif if (isDirectory) { - status = read_directory (anchor, name, format_out, sink); - NETCLOSE(data_soc); - NETCLOSE(control->socket); - control->socket = -1; - init_help_message_cache(); /* to free memory */ - return status; - /* returns HT_LOADED or error */ + if (server_type == UNIX_SERVER && !unsure_type && + !strcmp(response_text, + "150 Opening ASCII mode data connection for /bin/dl.\n")) { + CTRACE((tfp, "HTFTP: Treating as \"dls\" server.\n")); + server_type = DLS_SERVER; + } + final_status = read_directory (anchor, name, format_out, sink); + if (final_status > 0) { + if (server_type != CMS_SERVER) + if (outstanding-- > 0) { + status = response(0); + if (status < 0 || + (status == 2 && !strncmp(response_text, "221", 3))) + outstanding = 0; + } + } else { /* HT_INTERRUPTED */ + /* User may have pressed 'z' to give up because no + packets got through, so let's not make them wait + any longer - kw */ + outstanding = 0; + } + + if (data_soc != -1) { /* normally done in read_directory */ + CTRACE((tfp, "HTFTP: Closing data socket %d\n", data_soc)); + status = NETCLOSE(data_soc); + if (status == -1) + HTInetStatus("close"); /* Comment only */ + } + status = final_status; } else { int rv; - int len; char *FileName = HTParse(name, "", PARSE_PATH + PARSE_PUNCTUATION); /** Clear any login messages **/ @@ -3183,29 +3659,29 @@ listen: StrAllocCopy(anchor->content_encoding, HTAtom_name(encoding)); format = HTAtom_for("www/compressed"); - } else if ((len = strlen(FileName)) > 2) { - if ((FileName[len - 1] == 'Z') && - (FileName[len - 2] == '.' || - FileName[len - 2] == '-' || - FileName[len - 2] == '_')) { + } else { + char *dot; + CompressFileType cft = HTCompressFileType(FileName, "._-", &dot); - FileName[len - 2] = '\0'; + if (cft != cftNone) { + *dot = '\0'; format = HTFileFormat(FileName, &encoding, NULL); format = HTCharsetFormat(format, anchor, -1); StrAllocCopy(anchor->content_type, format->name); - StrAllocCopy(anchor->content_encoding, "x-compress"); format = HTAtom_for("www/compressed"); - } else if ((len > 3) && - !strcasecomp((char *)&FileName[len - 2], "gz")) { - if (FileName[len - 3] == '.' || - FileName[len - 3] == '-' || - FileName[len - 3] == '_') { - FileName[len - 3] = '\0'; - format = HTFileFormat(FileName, &encoding, NULL); - format = HTCharsetFormat(format, anchor, -1); - StrAllocCopy(anchor->content_type, format->name); + + switch (cft) { + case cftCompress: + StrAllocCopy(anchor->content_encoding, "x-compress"); + break; + case cftGzip: StrAllocCopy(anchor->content_encoding, "x-gzip"); - format = HTAtom_for("www/compressed"); + break; + case cftBzip2: + StrAllocCopy(anchor->content_encoding, "x-bzip2"); + break; + default: + break; } } } @@ -3214,31 +3690,66 @@ listen: _HTProgress (gettext("Receiving FTP file.")); rv = HTParseSocket(format, format_out, anchor, data_soc, sink); - if (rv == HT_INTERRUPTED) - _HTProgress(TRANSFER_INTERRUPTED); - HTInitInput(control->socket); /* Reset buffering to control connection DD 921208 */ - status = NETCLOSE(data_soc); - CTRACE(tfp, "HTFTP: Closing data socket %d\n", data_soc); + if (rv < 0) { +#if 0 /* any known servers where ABOR would work this way? */ + if (rv == HT_INTERRUPTED || rv == -501) + if (send_cmd_nowait("ABOR") == 1) { + outstanding++; + CTRACE((tfp, "HTFTP: outstanding responses: %d\n", outstanding)); + } +#endif + if (rv == -2) /* weird error, don't expect much response */ + outstanding--; + else if (rv == HT_INTERRUPTED || rv == -1) + /* User may have pressed 'z' to give up because no + packets got through, so let's not make them wait + longer - kw */ + outstanding = 0; + CTRACE((tfp, "HTFTP: Closing data socket %d\n", data_soc)); + status = NETCLOSE(data_soc); + } else + status = 2; /* data_soc already closed in HTCopy - kw */ + if (status < 0 && rv != HT_INTERRUPTED && rv != -1) { (void) HTInetStatus("close"); /* Comment only */ - data_soc = -1; /* invalidate it */ } else { - data_soc = -1; /* invalidate it */ - status = response(NIL); /* Pick up final reply */ - if (status != 2 && rv != HT_INTERRUPTED && rv != -1) { - init_help_message_cache(); /* to free memory */ - return HTLoadError(sink, 500, response_text); + if (rv != HT_LOADED && outstanding--) { + status = response(0); /* Pick up final reply */ + if (status != 2 && rv != HT_INTERRUPTED && rv != -1) { + data_soc = -1; /* invalidate it */ + init_help_message_cache(); /* to free memory */ + return HTLoadError(sink, 500, response_text); + } else if (status <= 0) { + outstanding = 0; + } else if (status == 2 && !strncmp(response_text, "221", 3)) + outstanding = 0; } } - - NETCLOSE(control->socket); - control->socket = -1; - init_help_message_cache(); /* to free memory */ - return HT_LOADED; + final_status = HT_LOADED; } + while (outstanding-- > 0 && + (status > 0)) { + status = response(0); + if (status == 2 && !strncmp(response_text, "221", 3)) + break; + } + data_soc = -1; /* invalidate it */ + CTRACE((tfp, "HTFTPLoad: normal end; ")); + if (control->socket < 0) { + CTRACE((tfp, "control socket is %d\n", control->socket)); + } else { + CTRACE((tfp, "closing control socket %d\n", control->socket)); + status = NETCLOSE(control->socket); + if (status == -1) + HTInetStatus("control connection close"); /* Comment only */ + } + control->socket = -1; + init_help_message_cache(); /* to free memory */ + /* returns HT_LOADED (always for file if we get here) or error */ + return final_status; } /* open_file_read */ /* diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.h index 4ef22f2dc33..60168b610db 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.h @@ -21,7 +21,7 @@ extern int HTfileSortMethod; /* specifies the method of sorting */ -/* PUBLIC HTMake_VMS_name() +/* PUBLIC HTVMS_name() ** CONVERTS WWW name into a VMS name ** ON ENTRY: ** nn Node Name (optional) @@ -32,7 +32,7 @@ extern int HTfileSortMethod; /* specifies the method of sorting */ ** ** Bug: Returns pointer to static -- non-reentrant */ -PUBLIC char * HTMake_VMS_name PARAMS(( +PUBLIC char * HTVMS_name PARAMS(( CONST char * nn, CONST char * fn)); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFWriter.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFWriter.c index 943e1a22b3e..b8b0c5d9bc8 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFWriter.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFWriter.c @@ -152,7 +152,7 @@ PRIVATE void HTFWriter_abort ARGS2(HTStream *, me, HTError, e) { fclose(me->fp); if (me->end_command) { /* Temp file */ - CTRACE(tfp, "HTFWriter: Aborting: file not executed.\n"); + CTRACE((tfp, "HTFWriter: Aborting: file not executed.\n")); FREE(me->end_command); if (me->remove_command) { system(me->remove_command); @@ -223,7 +223,7 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3( HTParentAnchor *, anchor, /* Not used */ HTStream *, sink) /* Not used */ -#ifdef unix +#ifdef UNIX #define REMOVE_COMMAND "/bin/rm -f %s\n" #endif #ifdef VMS @@ -254,9 +254,9 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3( if (fnam == NULL) outofmem(__FILE__, "HTSaveAndExecute"); tmpnam (fnam); - if (suffix) strcat(fnam, suffix); + strcat(fnam, suffix); - me->fp = fopen (fnam, "w"); + me->fp = fopen (fnam, BIN_W); if (!me->fp) { HTAlert(CANNOT_OPEN_TEMP); FREE(fnam); @@ -326,14 +326,14 @@ PUBLIC HTStream* HTSaveLocally ARGS3( if (fnam == NULL) outofmem(__FILE__, "HTSaveLocally"); tmpnam (fnam); - if (suffix) strcat(fnam, suffix); + strcat(fnam, suffix); /* Save Panel */ answer = HTPrompt(GIVE_FILENAME, fnam); FREE(fnam); - me->fp = fopen (answer, "w"); + me->fp = fopen (answer, BIN_W); if (!me->fp) { HTAlert(CANNOT_OPEN_OUTPUT); FREE(answer); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c index 35d77ea679a..829214e8f75 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c @@ -24,9 +24,9 @@ #ifndef VMS #ifdef DOSPATH +#undef LONG_LIST #define LONG_LIST /* Define this for long style unix listings (ls -l), the actual style is configurable from lynx.cfg */ -#define lstat stat #endif /* #define NO_PARENT_DIR_REFERENCE */ /* Define this for no parent links */ #endif /* !VMS */ @@ -46,7 +46,6 @@ #include <GridText.h> #endif -#define INFINITY 512 /* file name length @@ FIXME */ #define MULTI_SUFFIX ".multi" /* Extension for scanning formats */ #include <HTParse.h> @@ -121,7 +120,6 @@ PUBLIC int HTDirReadme = HT_DIR_README_TOP; #endif /* DIRED_SUPPORT */ extern BOOL HTPassEightBitRaw; -extern HTCJKlang HTCJK; PRIVATE char *HTMountRoot = "/Net/"; /* Where to find mounts */ #ifdef VMS @@ -140,14 +138,6 @@ PRIVATE HTSuffix no_suffix = { "*", NULL, NULL, NULL, 1.0 }; PRIVATE HTSuffix unknown_suffix = { "*.*", NULL, NULL, NULL, 1.0}; -#ifdef _WINDOWS -int exists(char *filename) -{ - return (access(filename,0)==0); -} -#endif - - /* To free up the suffixes at program exit. ** ---------------------------------------- */ @@ -165,8 +155,10 @@ PRIVATE char *FormatStr ARGS3( if (*start) { sprintf(fmt, "%%%.*ss", (int) sizeof(fmt) - 3, start); HTSprintf0(bufp, fmt, entry); - } else { - HTSprintf0(bufp, "%s", entry); + } else if (*bufp && !(entry && *entry)) { + **bufp = '\0'; + } else if (entry) { + StrAllocCopy(*bufp, entry); } return *bufp; } @@ -182,7 +174,7 @@ PRIVATE char *FormatNum ARGS3( HTSprintf0(bufp, fmt, entry); } else { sprintf(fmt, "%d", entry); - StrAllocCat(*bufp, fmt); + StrAllocCopy(*bufp, fmt); } return *bufp; } @@ -203,17 +195,31 @@ PRIVATE void LYListFmtParse ARGS5( char *buf = NULL; char tmp[LY_MAXPATH]; char type; +#ifndef _WINDOWS char *name; +#endif time_t now; char *datestr; +#ifdef S_IFLNK int len; +#endif #define SEC_PER_YEAR (60 * 60 * 24 * 365) + +#ifdef _WINDOWS /* 1998/01/06 (Tue) 21:20:53 */ + static char *pbits[] = { + "---", "--x", "-w-", "-wx", + "r--", "r-x", "rw-", "rwx", + 0 }; +#define PBIT(a, n, s) pbits[((a) >> (n)) & 0x7] + +#else static char *pbits[] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx", 0 }; static char *psbits[] = { "--S", "--s", "-wS", "-ws", "r-S", "r-s", "rwS", "rws", 0 }; #define PBIT(a, n, s) (s) ? psbits[((a) >> (n)) & 0x7] : \ pbits[((a) >> (n)) & 0x7] +#endif #ifdef S_ISVTX static char *ptbits[] = { "--T", "--t", "-wT", "-wt", "r-T", "r-t", "rwT", "rwt", 0 }; @@ -248,7 +254,7 @@ PRIVATE void LYListFmtParse ARGS5( if (s == end) break; start = ++s; - while (isdigit(*s) || *s == '.' || *s == '-' || *s == ' ' || + while (isdigit(UCH(*s)) || *s == '.' || *s == '-' || *s == ' ' || *s == '#' || *s == '+' || *s == '\'') s++; c = *s; /* the format char. or \0 */ @@ -341,7 +347,11 @@ PRIVATE void LYListFmtParse ARGS5( case 'p': /* unix-style permission bits */ switch(st.st_mode & S_IFMT) { +#if defined(_MSC_VER) && defined(_S_IFIFO) + case _S_IFIFO: type = 'p'; break; +#else case S_IFIFO: type = 'p'; break; +#endif case S_IFCHR: type = 'c'; break; case S_IFDIR: type = 'd'; break; case S_IFREG: type = '-'; break; @@ -362,13 +372,23 @@ PRIVATE void LYListFmtParse ARGS5( #endif /* S_IFSOCK */ default: type = '?'; break; } +#ifdef _WINDOWS + sprintf(tmp, "%c%s", type, + PBIT(st.st_mode, 6, st.st_mode & S_IRWXU)); +#else sprintf(tmp, "%c%s%s%s", type, PBIT(st.st_mode, 6, st.st_mode & S_ISUID), PBIT(st.st_mode, 3, st.st_mode & S_ISGID), PTBIT(st.st_mode, st.st_mode & S_ISVTX)); +#endif FormatStr(&buf, start, tmp); break; +#ifdef _WINDOWS + case 'o': /* owner */ + case 'g': /* group */ + break; +#else case 'o': /* owner */ name = HTAA_UidToName (st.st_uid); if (*name) { @@ -386,6 +406,7 @@ PRIVATE void LYListFmtParse ARGS5( FormatNum(&buf, start, (int) st.st_gid); } break; +#endif case 'l': /* link count */ FormatNum(&buf, start, (int) st.st_nlink); @@ -431,10 +452,10 @@ PUBLIC void HTSetSuffix5 ARGS5( CONST char *, representation, CONST char *, encoding, CONST char *, desc, - float, value) + double, value) { HTSuffix * suff; - BOOL trivial_enc = IsUnityEncStr(encoding); + BOOL trivial_enc = (BOOL) IsUnityEncStr(encoding); if (strcmp(suffix, "*") == 0) suff = &no_suffix; @@ -451,7 +472,7 @@ PUBLIC void HTSetSuffix5 ARGS5( break; } if (!suff) { /* Not found -- create a new node */ - suff = (HTSuffix *) calloc(1, sizeof(HTSuffix)); + suff = typecalloc(HTSuffix); if (suff == NULL) outofmem(__FILE__, "HTSetSuffix"); @@ -484,7 +505,7 @@ PUBLIC void HTSetSuffix5 ARGS5( StrAllocCopy(suff->desc, desc); - suff->quality = value; + suff->quality = (float) value; } #ifdef LY_FIND_LEAKS @@ -558,6 +579,50 @@ PRIVATE int HTCreatePath ARGS1(CONST char *,path) } #endif /* NOT_IMPLEMENTED */ +/* Convert filename from URL-path syntax to local path format +** ---------------------------------------------------------- +** Input name is assumed to be the URL-path of a local file +** URL, i.e. what comes after the "file://localhost". +** '#'-fragments to be treated as such must already be stripped. +** If expand_all is FALSE, unescape only escaped '/'. - kw +** +** On exit: +** Returns a malloc'ed string which must be freed by the caller. +*/ +PUBLIC char * HTURLPath_toFile ARGS2( + CONST char *, name, + BOOL, expand_all) +{ + char * path = NULL; + char * result = NULL; + + StrAllocCopy(path, name); + if (expand_all) + HTUnEscape(path); /* Interpret all % signs */ + else + HTUnEscapeSome(path, "/"); /* Interpret % signs for path delims */ + + CTRACE((tfp, "URLPath `%s' means path `%s'\n", name, path)); +#ifdef DOSPATH + StrAllocCopy(result, HTDOS_name(path)); +#else +#ifdef __EMX__ + if (path[0] == '/' + && isalpha(path[1]) + && path[2] == ':') /* pesky leading slash */ + StrAllocCopy(result, path+1); + else + StrAllocCopy(result, path); + CTRACE((tfp, "EMX hack changed `%s' to `%s'\n", path, result)); +#else + StrAllocCopy(result, path); +#endif /* __EMX__ */ +#endif /* DOSPATH */ + + FREE(path); + + return result; +} /* Convert filenames between local and WWW formats. ** ------------------------------------------------ ** Make up a suitable name for saving the node in @@ -568,6 +633,11 @@ PRIVATE int HTCreatePath ARGS1(CONST char *,path) ** On exit: ** Returns a malloc'ed string which must be freed by the caller. */ +/* NOTE: Don't use this function if you know that the input is a URL path + rather than a full URL, use HTURLPath_toFile instead. Otherwise + this function will return the wrong thing for some unusual + paths (like ones containing "//", possibly escaped). - kw +*/ PUBLIC char * HTnameOfFile_WWW ARGS3( CONST char *, name, BOOL, WWW_prefix, @@ -579,16 +649,16 @@ PUBLIC char * HTnameOfFile_WWW ARGS3( char * home; char * result = NULL; - if (expand_all) + if (expand_all) { HTUnEscape(path); /* Interpret all % signs */ - else + } else HTUnEscapeSome(path, "/"); /* Interpret % signs for path delims */ if (0 == strcmp(acc_method, "file") /* local file */ || !*acc_method) { /* implicitly local? */ if ((0 == strcasecomp(host, HTHostName())) || (0 == strcasecomp(host, "localhost")) || !*host) { - CTRACE(tfp, "Node `%s' means path `%s'\n", name, path); + CTRACE((tfp, "Node `%s' means path `%s'\n", name, path)); #ifdef DOSPATH StrAllocCopy(result, HTDOS_name(path)); #else @@ -599,14 +669,14 @@ PUBLIC char * HTnameOfFile_WWW ARGS3( StrAllocCopy(result, path+1); else StrAllocCopy(result, path); - CTRACE(tfp, "EMX hack changed `%s' to `%s'\n", path, result); + CTRACE((tfp, "EMX hack changed `%s' to `%s'\n", path, result)); #else StrAllocCopy(result, path); #endif /* __EMX__ */ #endif /* DOSPATH */ } else if (WWW_prefix) { HTSprintf0(&result, "%s%s%s", "/Net/", host, path); - CTRACE(tfp, "Node `%s' means file `%s'\n", name, result); + CTRACE((tfp, "Node `%s' means file `%s'\n", name, result)); } else { StrAllocCopy(result, path); } @@ -617,7 +687,12 @@ PUBLIC char * HTnameOfFile_WWW ARGS3( else home = HTVMS_wwwName(home); #else - if ((home = getenv("HOME")) == 0) +#if defined(_WINDOWS) /* 1997/10/16 (Thu) 20:42:51 */ + home = (char *)Home_Dir(); +#else + home = getenv("HOME"); +#endif + if (home == 0) home = "/tmp"; #endif /* VMS */ HTSprintf0(&result, "%s/WWW/%s/%s%s", home, acc_method, host, path); @@ -629,6 +704,9 @@ PUBLIC char * HTnameOfFile_WWW ARGS3( FREE(path); FREE(acc_method); + CTRACE((tfp, "HTnameOfFile_WWW(%s,%d,%d) = %s\n", + name, WWW_prefix, expand_all, result)); + return result; } @@ -654,7 +732,7 @@ PUBLIC char * WWW_nameOfFile ARGS1( } else { HTSprintf0(&result, "file://%s%s", HTHostName(), name); } - CTRACE(tfp, "File `%s'\n\tmeans node `%s'\n", name, result); + CTRACE((tfp, "File `%s'\n\tmeans node `%s'\n", name, result)); return result; } @@ -687,7 +765,7 @@ PUBLIC CONST char * HTFileSuffix ARGS2( HTFileInit(); #endif /* !NO_INIT */ - trivial_enc = IsUnityEncStr(enc); + trivial_enc = (BOOL) IsUnityEncStr(enc); n = HTList_count(HTSuffixes); for (i = 0; i < n; i++) { suff = (HTSuffix *)HTList_objectAt(HTSuffixes, i); @@ -802,6 +880,10 @@ PUBLIC HTFormat HTFileFormat ARGS3( if (suff->rep) { if (pdesc && !(*pdesc)) *pdesc = suff->desc; + if (pencoding && IsUnityEnc(*pencoding) && + *pencoding != WWW_ENC_7BIT && + !IsUnityEnc(suff->encoding)) + *pencoding = suff->encoding; #ifdef VMS if (semicolon != NULL) *semicolon = ';'; @@ -855,8 +937,8 @@ PUBLIC HTFormat HTCharsetFormat ARGS3( LYLowerCase(cp); if (((cp1 = strchr(cp, ';')) != NULL) && (cp2 = strstr(cp1, "charset")) != NULL) { - CTRACE(tfp, "HTCharsetFormat: Extended MIME Content-Type is %s\n", - format->name); + CTRACE((tfp, "HTCharsetFormat: Extended MIME Content-Type is %s\n", + format->name)); cp2 += 7; while (*cp2 == ' ' || *cp2 == '=') cp2++; @@ -944,15 +1026,15 @@ PUBLIC HTFormat HTCharsetFormat ARGS3( ** of match. */ BOOL given_is_8859 - = (!strncmp(cp4, "iso-8859-", 9) && - isdigit((unsigned char)cp4[9])); + = (BOOL) (!strncmp(cp4, "iso-8859-", 9) && + isdigit(UCH(cp4[9]))); BOOL given_is_8859like - = (given_is_8859 || + = (BOOL) (given_is_8859 || !strncmp(cp4, "windows-", 8) || !strncmp(cp4, "cp12", 4) || !strncmp(cp4, "cp-12", 5)); BOOL given_and_display_8859like - = (given_is_8859like && + = (BOOL) (given_is_8859like && (strstr(LYchar_set_names[current_char_set], "ISO-8859") || strstr(LYchar_set_names[current_char_set], @@ -965,7 +1047,7 @@ PUBLIC HTFormat HTCharsetFormat ARGS3( if (given_is_8859) { cp1 = &cp4[10]; while (*cp1 && - isdigit((unsigned char)(*cp1))) + isdigit(UCH(*cp1))) cp1++; *cp1 = '\0'; } @@ -1003,6 +1085,85 @@ PUBLIC HTFormat HTCharsetFormat ARGS3( return format; } + + +/* Get various pieces of meta info from file name. +** ----------------------------------------------- +** +** LYGetFileInfo fills in information that can be determined without +** an actual (new) access to the filesystem, based on current suffix +** and character set configuration. If the file has been loaded and +** parsed before (with the same URL generated here!) and the anchor +** is still around, some results may be influenced by that (in +** particular, charset info from a META tag - this is not actually +** tested!). +** The caller should not keep pointers to the returned objects around +** for too long, the valid lifetimes vary. In particular, the returned +** charset string should be copied if necessary. If return of the +** file_anchor is requested, that one can be used to retrieve +** additional bits of info that are stored in the anchor object and +** are not covered here; as usual, don't keep pointers to the +** file_anchor longer than necessary since the object may disappear +** through HTuncache_current_document or at the next document load. +** - kw +*/ +PUBLIC void LYGetFileInfo ARGS7( + CONST char *, filename, + HTParentAnchor **, pfile_anchor, + HTFormat *, pformat, + HTAtom **, pencoding, + CONST char**, pdesc, + CONST char**, pcharset, + int *, pfile_cs) +{ + char *Afn; + char *Aname = NULL; + HTFormat format; + HTAtom * myEnc = NULL; + HTParentAnchor *file_anchor; + CONST char *file_csname; + int file_cs; + + /* + * Convert filename to URL. Note that it is always supposed to + * be a filename, not maybe-filename-maybe-URL, so we don't + * use LYFillLocalFileURL and LYEnsureAbsoluteURL. - kw + */ + Afn = HTEscape(filename, URL_PATH); + LYLocalFileToURL(&Aname, Afn); + file_anchor = HTAnchor_parent(HTAnchor_findSimpleAddress(Aname)); + + file_csname = file_anchor->charset; + format = HTFileFormat(filename, &myEnc, pdesc); + format = HTCharsetFormat(format, file_anchor, UCLYhndl_HTFile_for_unspec); + file_cs = HTAnchor_getUCLYhndl(file_anchor, UCT_STAGE_MIME); + if (!file_csname) { + if (file_cs >= 0) + file_csname = LYCharSet_UC[file_cs].MIMEname; + else file_csname = "display character set"; + } + CTRACE((tfp, "GetFileInfo: '%s' is a%s %s %s file, charset=%s (%d).\n", + filename, + ((myEnc && *HTAtom_name(myEnc) == '8') ? "n" : myEnc ? "" : + *HTAtom_name(format) == 'a' ? "n" : ""), + myEnc ? HTAtom_name(myEnc) : "", + HTAtom_name(format), + file_csname, + file_cs)); + FREE(Afn); + FREE(Aname); + if (pfile_anchor) + *pfile_anchor = file_anchor; + if (pformat) + *pformat = format; + if (pencoding) + *pencoding = myEnc; + if (pcharset) + *pcharset = file_csname; + if (pfile_cs) + *pfile_cs = file_cs; + } + /* Determine value from file name. ** ------------------------------- ** @@ -1025,12 +1186,48 @@ PUBLIC float HTFileValue ARGS1( suff = (HTSuffix *)HTList_objectAt(HTSuffixes, i); ls = strlen(suff->suffix); if ((ls <= lf) && 0==strcmp(suff->suffix, filename + lf - ls)) { - CTRACE(tfp, "File: Value of %s is %.3f\n", - filename, suff->quality); + CTRACE((tfp, "File: Value of %s is %.3f\n", + filename, suff->quality)); return suff->quality; /* OK -- found */ } } - return 0.3; /* Dunno! */ + return (float)0.3; /* Dunno! */ +} + +/* +** Determine compression type from file name, by looking at its suffix. +** Sets as side-effect a pointer to the "dot" that begins the suffix. +*/ +PUBLIC CompressFileType HTCompressFileType ARGS3( + char *, filename, + char *, dots, + char **, suffix) +{ + CompressFileType result = cftNone; + size_t len = strlen(filename); + char *ftype = filename + len; + + if ((len > 4) + && !strcasecomp((ftype - 3), "bz2") + && strchr(dots, ftype[-4]) != 0) { + result = cftBzip2; + ftype -= 4; + } else if ((len > 3) + && !strcasecomp((ftype - 2), "gz") + && strchr(dots, ftype[-3]) != 0) { + result = cftGzip; + ftype -= 3; + } else if ((len > 2) + && !strcmp((ftype - 1), "Z") + && strchr(dots, ftype[-2]) != 0) { + result = cftCompress; + ftype -= 2; + } + + *suffix = ftype; + CTRACE((tfp, "HTCompressFileType(%s) returns %d:%s\n", + filename, result, *suffix)); + return result; } /* Determine write access to a file. @@ -1043,36 +1240,10 @@ PUBLIC float HTFileValue ARGS1( ** 1. No code for non-unix systems. ** 2. Isn't there a quicker way? */ - -#if defined(HAVE_CONFIG_H) - -#ifndef HAVE_GETGROUPS -#define NO_GROUPS -#endif - -#else - -#ifdef VMS -#define NO_GROUPS -#endif /* VMS */ -#ifdef NO_UNIX_IO -#define NO_GROUPS -#endif /* NO_UNIX_IO */ -#ifdef PCNFS -#define NO_GROUPS -#endif /* PCNFS */ -#ifdef NOUSERS -#define NO_GROUPS -#endif /* PCNFS */ - -#endif /* HAVE_CONFIG_H */ - PUBLIC BOOL HTEditable ARGS1( CONST char *, filename) { -#ifdef NO_GROUPS - return NO; /* Safe answer till we find the correct algorithm */ -#else +#ifndef NO_GROUPS GETGROUPS_T groups[NGROUPS]; uid_t myUid; int ngroups; /* The number of groups */ @@ -1113,9 +1284,9 @@ PUBLIC BOOL HTEditable ARGS1( return YES; } } - CTRACE(tfp, "\tFile is not editable.\n"); - return NO; /* If no excuse, can't do */ + CTRACE((tfp, "\tFile is not editable.\n")); #endif /* NO_GROUPS */ + return NO; /* If no excuse, can't do */ } /* Make a save stream. @@ -1130,7 +1301,7 @@ PUBLIC HTStream * HTFileSaveStream ARGS1( CONST char * addr = HTAnchor_address((HTAnchor*)anchor); char * localname = HTLocalName(addr); - FILE* fp = fopen(localname, "w"); + FILE* fp = fopen(localname, BIN_W); if (!fp) return NULL; @@ -1193,9 +1364,9 @@ PUBLIC void HTDirEntry ARGS3( ** On exit: ** Returns TRUE if an "Up to <parent>" link was not created ** for a readable local directory because LONG_LIST is defined -** and NO_PARENT_DIR_REFERENCE is not defined, such that the -** calling function use LYListFmtParse() to create a link to -** the parent directory. Otherwise, it returns FALSE. - FM +** and NO_PARENT_DIR_REFERENCE is not defined, so that the +** calling function should use LYListFmtParse() to create a link +** to the parent directory. Otherwise, it returns FALSE. - FM */ PUBLIC BOOL HTDirTitles ARGS3( HTStructured *, target, @@ -1211,7 +1382,7 @@ PUBLIC BOOL HTDirTitles ARGS3( #ifdef DOSPATH BOOL local_link = FALSE; - if (logical[18] == ':') local_link = TRUE; + if (strlen(logical) > 18 && logical[18] == ':') local_link = TRUE; #endif /* ** Check tildeIsTop for treating home directory as Welcome @@ -1246,10 +1417,11 @@ PUBLIC BOOL HTDirTitles ARGS3( char * printable = NULL; #ifdef DIRED_SUPPORT - printable = HTfullURL_toFile( + printable = HTURLPath_toFile( (0 == strncasecomp(path, "/%2F", 4)) /* "//" ? */ ? (path+1) - : path); + : path, + TRUE); if (0 == strncasecomp(printable, "/vmsysu:", 8) || 0 == strncasecomp(printable, "/anonymou.", 10)) { StrAllocCopy(cp, (printable+1)); @@ -1300,6 +1472,9 @@ PUBLIC BOOL HTDirTitles ARGS3( /* ** Make link back to parent directory. */ +#ifdef DOSPATH + if (current != path) /* leave "/c:" alone */ +#endif if (current && current[1]) { /* was a slash AND something else too */ char * parent = NULL; char * relative = NULL; @@ -1320,15 +1495,15 @@ PUBLIC BOOL HTDirTitles ARGS3( HTSprintf0(&relative, "%s/..", current); #ifdef DOSPATH - if (local_link) - if (strlen(parent) == 3 ) + if (local_link) { + if (parent != 0 && strlen(parent) == 3 ) { StrAllocCat(relative, "/."); + } + } + else #endif #if !defined (VMS) -#ifdef DOSPATH - if(!local_link) -#endif { /* ** On Unix, if it's not ftp and the directory cannot @@ -1425,15 +1600,11 @@ PUBLIC BOOL HTDirTitles ARGS3( PRIVATE void do_readme ARGS2(HTStructured *, target, CONST char *, localname) { FILE * fp; - char * readme_file_name = - malloc(strlen(localname)+ 1 + strlen(HT_DIR_README_FILE) + 1); - if (readme_file_name == NULL) - outofmem(__FILE__, "do_readme"); - strcpy(readme_file_name, localname); - strcat(readme_file_name, "/"); - strcat(readme_file_name, HT_DIR_README_FILE); + char * readme_file_name = NULL; - fp = fopen(readme_file_name, "r"); + HTSprintf0(&readme_file_name, "%s/%s", localname, HT_DIR_README_FILE); + + fp = fopen(readme_file_name, "r"); if (fp) { HTStructuredClass targetClass; @@ -1441,8 +1612,8 @@ PRIVATE void do_readme ARGS2(HTStructured *, target, CONST char *, localname) targetClass = *target->isa; /* (Can't init agregate in K&R) */ START(HTML_PRE); for (;;){ - char c = fgetc(fp); - if (c == (char)EOF) break; + int c = fgetc(fp); + if (c == EOF) break; #ifdef NOTDEFINED switch (c) { case '&': @@ -1458,10 +1629,10 @@ PRIVATE void do_readme ARGS2(HTStructured *, target, CONST char *, localname) PUTC('\r'); Bug removed thanks to joe@athena.mit.edu */ default: - PUTC(c); + PUTC((char)c); } #else - PUTC(c); + PUTC((char)c); #endif /* NOTDEFINED */ } END(HTML_PRE); @@ -1489,8 +1660,9 @@ PRIVATE int print_local_dir ARGS5( BOOL need_parent_link = FALSE; struct stat file_info; int status; + int i; - CTRACE(tfp, "print_local_dir() started\n"); + CTRACE((tfp, "print_local_dir() started\n")); logical = HTAnchor_address((HTAnchor*)anchor); pathname = HTParse(logical, "", @@ -1529,10 +1701,8 @@ PRIVATE int print_local_dir ARGS5( target = HTML_new(anchor, format_out, sink); targetClass = *target->isa; /* Copy routine entry points */ - { int i; - for (i = 0; i < HTML_A_ATTRIBUTES; i++) - present[i] = (i == HTML_A_HREF); - } + for (i = 0; i < HTML_A_ATTRIBUTES; i++) + present[i] = (BOOL) (i == HTML_A_HREF); /* ** The need_parent_link flag will be set if an @@ -1559,7 +1729,7 @@ PRIVATE int print_local_dir ARGS5( HTBTree * bt = HTBTree_new((HTComparer)AS_cmp); int num_of_entries = 0; /* lines counter */ - _HTProgress (gettext("Reading directory...")); + _HTProgress (READING_DIRECTORY); status = HT_LOADED; /* assume we don't get interrupted */ while ((dirbuf = readdir(dp)) != NULL) { /* @@ -1597,13 +1767,14 @@ PRIVATE int print_local_dir ARGS5( StrAllocCat(tmpfilename, dirbuf->d_name); stat(tmpfilename, &file_info); - if (S_ISDIR(file_info.st_mode)) #ifndef DIRED_SUPPORT + if (S_ISDIR(file_info.st_mode)) HTSprintf0(&dirname, "D%s",dirbuf->d_name); else HTSprintf0(&dirname, "F%s",dirbuf->d_name); /* D & F to have first directories, then files */ #else + if (S_ISDIR(file_info.st_mode)) { if (dir_list_style == MIXED_STYLE) HTSprintf0(&dirname, " %s/", dirbuf->d_name); @@ -1641,9 +1812,9 @@ PRIVATE int print_local_dir ARGS5( } /* end while directory entries left to read */ if (status != HT_PARTIAL_CONTENT) - _HTProgress (gettext("OK")); + _HTProgress (OPERATION_OK); else - CTRACE(tfp, "Reading the directory interrupred by user\n"); + CTRACE((tfp, "Reading the directory interrupted by user\n")); /* @@ -1652,7 +1823,7 @@ PRIVATE int print_local_dir ARGS5( { HTBTElement * next_element = HTBTree_next(bt,NULL); /* pick up the first element of the list */ - int num_of_entries_partial = 0; /* lines counter */ + int num_of_entries_output = 0; /* lines counter */ char state; /* I for initial (.. file), @@ -1667,19 +1838,28 @@ PRIVATE int print_local_dir ARGS5( while (next_element != NULL) { char *entry, *file_extra; +#ifndef DISP_PARTIAL + if (num_of_entries_output % HTMAX(display_lines,10) == 0) { + if (HTCheckForInterrupt()) { + _HTProgress (TRANSFER_INTERRUPTED); + status = HT_PARTIAL_CONTENT; + break; + } + } +#endif StrAllocCopy(tmpfilename,localname); if (strcmp(localname, "/")) /* ** If filename is not root directory. */ - StrAllocCat(tmpfilename, "/"); + LYAddHtmlSep(&tmpfilename); - StrAllocCat(tmpfilename, - (char *)HTBTree_object(next_element)+1); + entry = (char*)HTBTree_object(next_element)+1; /* ** Append the current entry's filename ** to the path. */ + StrAllocCat(tmpfilename, entry); HTSimplify(tmpfilename); /* ** Output the directory entry. @@ -1706,7 +1886,7 @@ PRIVATE int print_local_dir ARGS5( } #endif /* !LONG_LIST */ state = - (*(char *)(HTBTree_object(next_element)) + (char) (*(char *)(HTBTree_object(next_element)) == 'D' ? 'D' : 'F'); START(HTML_H2); if (dir_list_style != MIXED_STYLE) { @@ -1733,7 +1913,7 @@ PRIVATE int print_local_dir ARGS5( } #endif /* !LONG_LIST */ state = - (*(char *)(HTBTree_object(next_element)) + (char) (*(char *)(HTBTree_object(next_element)) == 'D' ? 'D' : 'F'); START(HTML_H2); START(HTML_EM); @@ -1753,7 +1933,6 @@ PRIVATE int print_local_dir ARGS5( START(HTML_LI); #endif /* !LONG_LIST */ } - entry = (char*)HTBTree_object(next_element)+1; file_extra = NULL; #ifdef LONG_LIST @@ -1777,10 +1956,10 @@ PRIVATE int print_local_dir ARGS5( /* optimize for expensive operation: */ #ifdef DISP_PARTIAL - if (num_of_entries_partial % + if (num_of_entries_output % (partial_threshold > 0 ? partial_threshold : display_lines) == 0) { - /* num_of_entries, num_of_entries_partial... */ + /* num_of_entries, num_of_entries_output... */ /* HTReadProgress...(bytes, 0); */ HTDisplayPartial(); @@ -1790,7 +1969,7 @@ PRIVATE int print_local_dir ARGS5( break; } } - num_of_entries_partial++; + num_of_entries_output++; #endif /* DISP_PARTIAL */ } /* end while next_element */ @@ -1807,7 +1986,6 @@ PRIVATE int print_local_dir ARGS5( } } /* end printing out the tree in order */ - closedir(dp); FREE(logical); FREE(tmpfilename); FREE(tail); @@ -1827,6 +2005,40 @@ PRIVATE int print_local_dir ARGS5( #endif /* HAVE_READDIR */ +#ifndef VMS +PUBLIC int HTStat ARGS2( + CONST char *, filename, + struct stat *, data) +{ + int result = -1; + char *temp_name = NULL; + size_t len = strlen(filename); + + if (len != 0 && LYIsPathSep(filename[len-1])) { + HTSprintf0(&temp_name, "%s.", filename); + } else { + temp_name = (char *)filename; + } +#ifdef _WINDOWS + /* + * Someone claims that stat() doesn't give the proper result for a + * directory on Windows. + */ + if (access(temp_name, 0) == 0) { + if (stat(temp_name, data) == -1) + data->st_mode = S_IFDIR; + result = 0; + } +#else + result = stat(temp_name, data); +#endif + + if (temp_name != filename) { + FREE(temp_name); + } + return result; +} +#endif /* Load a document. ** ---------------- @@ -1848,13 +2060,13 @@ PUBLIC int HTLoadFile ARGS4( { char * filename = NULL; char * acc_method = NULL; - char * ftp_newhost; HTFormat format; char * nodename = NULL; char * newname = NULL; /* Simplified name of file */ HTAtom * encoding; /* @@ not used yet */ HTAtom * myEncoding = NULL; /* enc of this file, may be gzip etc. */ int status; + char *dot; #ifdef VMS struct stat stat_info; #endif /* VMS */ @@ -1882,34 +2094,20 @@ PUBLIC int HTLoadFile ARGS4( strcmp(nodename, HTHostName()) != 0 #endif /* VMS */ )) { + status = -1; FREE(newname); FREE(filename); FREE(nodename); FREE(acc_method); #ifndef DISABLE_FTP - ftp_newhost = HTParse(addr, "", PARSE_HOST); /* HTParse mallocs */ - if (strcmp(ftp_lasthost, ftp_newhost)) - ftp_local_passive = ftp_passive; /* set to default */ - status = HTFTPLoad(addr, anchor, format_out, sink); - - if ( ftp_passive == ftp_local_passive ) { - if (( status <= -4 ) || ( status == -1 )) { - ftp_local_passive = !ftp_passive; - status = HTFTPLoad(addr, anchor, format_out, sink); - } - } - free(ftp_lasthost); - ftp_lasthost = ftp_newhost; - return status; -#else - return -1; #endif /* DISABLE_FTP */ + return status; } else { FREE(newname); FREE(acc_method); } -#ifdef VMS +#if defined(VMS) || defined(DOSPATH) HTUnEscape(filename); #endif /* VMS */ @@ -1951,7 +2149,7 @@ PUBLIC int HTLoadFile ARGS4( ** to the directories or files listed. */ if (HTStat(filename, &stat_info) == -1) { - CTRACE(tfp, "HTLoadFile: Can't stat %s\n", filename); + CTRACE((tfp, "HTLoadFile: Can't stat %s\n", filename)); } else { if (S_ISDIR(stat_info.st_mode)) { if (HTDirAccess == HT_DIR_FORBID) { @@ -1961,14 +2159,9 @@ PUBLIC int HTLoadFile ARGS4( } if (HTDirAccess == HT_DIR_SELECTIVE) { - char * enable_file_name = - malloc(strlen(filename)+ 1 + - strlen(HT_DIR_ENABLE_FILE) + 1); - if (enable_file_name == NULL) - outofmem(__FILE__, "HTLoadFile"); - strcpy(enable_file_name, filename); - strcat(enable_file_name, "/"); - strcat(enable_file_name, HT_DIR_ENABLE_FILE); + char * enable_file_name = NULL; + + HTSprintf0(&enable_file_name, "%s/%s", filename, HT_DIR_ENABLE_FILE); if (HTStat(enable_file_name, &stat_info) == -1) { FREE(filename); FREE(nodename); @@ -1998,18 +2191,16 @@ PUBLIC int HTLoadFile ARGS4( */ if (!fp) { char * ultrixname = 0; - CTRACE(tfp, "HTLoadFile: Can't open as %s\n", vmsname); + CTRACE((tfp, "HTLoadFile: Can't open as %s\n", vmsname)); HTSprintf0(&ultrixname, "%s::\"%s\"", nodename, filename); fp = fopen(ultrixname, "r", "shr=put", "shr=upd"); if (!fp) { - CTRACE(tfp, "HTLoadFile: Can't open as %s\n", - ultrixname); + CTRACE((tfp, "HTLoadFile: Can't open as %s\n", + ultrixname)); } FREE(ultrixname); } if (fp) { - int len; - char *cp = NULL; char *semicolon = NULL; if (HTEditable(vmsname)) { @@ -2042,10 +2233,10 @@ PUBLIC int HTLoadFile ARGS4( fclose(fp); if (semicolon != NULL) *semicolon = ';'; - gzfp = gzopen(vmsname, "rb"); + gzfp = gzopen(vmsname, BIN_R); - CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", - vmsname, (void*)gzfp); + CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n", + vmsname, (void*)gzfp)); use_gzread = YES; } else #endif /* USE_ZLIB */ @@ -2054,50 +2245,50 @@ PUBLIC int HTLoadFile ARGS4( StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding)); format = HTAtom_for("www/compressed"); } - } else if ((len = strlen(vmsname)) > 2) { - if ((vmsname[len - 1] == 'Z') && - (vmsname[len - 2] == '.' || - vmsname[len - 2] == '-' || - vmsname[len - 2] == '_') && - vmsname[len - 3] != ']' && - vmsname[len - 3] != ':') { + } else { + /* FIXME: should we check if suffix is after ']' or ':' ? */ + CompressFileType cft = HTCompressFileType(vmsname, "._-", &dot); + + if (cft != cftNone) { + char *cp = NULL; + StrAllocCopy(cp, vmsname); - cp[len - 2] = '\0'; + cp[dot - vmsname] = '\0'; format = HTFileFormat(cp, &encoding, NULL); FREE(cp); format = HTCharsetFormat(format, anchor, UCLYhndl_HTFile_for_unspec); StrAllocCopy(anchor->content_type, format->name); + } + + switch (cft) { + case cftCompress: StrAllocCopy(anchor->content_encoding, "x-compress"); format = HTAtom_for("www/compressed"); - } else if ((len > 3) && - !strcasecomp((char *)&vmsname[len - 2], "gz")) { - if (vmsname[len - 3] == '.' || - vmsname[len - 3] == '-' || - vmsname[len - 3] == '_') { - StrAllocCopy(cp, vmsname); - cp[len - 3] = '\0'; - format = HTFileFormat(cp, &encoding, NULL); - FREE(cp); - format = HTCharsetFormat(format, anchor, - UCLYhndl_HTFile_for_unspec); - StrAllocCopy(anchor->content_type, format->name); - StrAllocCopy(anchor->content_encoding, "x-gzip"); + break; + case cftGzip: + StrAllocCopy(anchor->content_encoding, "x-gzip"); #ifdef USE_ZLIB - if (strcmp(format_out->name, "www/download") != 0) { - fclose(fp); - if (semicolon != NULL) - *semicolon = ';'; - gzfp = gzopen(vmsname, "rb"); + if (strcmp(format_out->name, "www/download") != 0) { + fclose(fp); + if (semicolon != NULL) + *semicolon = ';'; + gzfp = gzopen(vmsname, BIN_R); - CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", - vmsname, (void*)gzfp); - use_gzread = YES; - } + CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n", + vmsname, (void*)gzfp)); + use_gzread = YES; + } #else /* USE_ZLIB */ - format = HTAtom_for("www/compressed"); + format = HTAtom_for("www/compressed"); #endif /* USE_ZLIB */ - } + break; + case cftBzip2: + StrAllocCopy(anchor->content_encoding, "x-bzip2"); + format = HTAtom_for("www/compressed"); + break; + case cftNone: + break; } } if (semicolon != NULL) @@ -2146,7 +2337,7 @@ PUBLIC int HTLoadFile ARGS4( FREE(filename); } -#else /* Unix: */ +#else /* not VMS: */ FREE(filename); @@ -2177,7 +2368,7 @@ PUBLIC int HTLoadFile ARGS4( BOOL forget_multi = NO; STRUCT_DIRENT * dirbuf; - float best = NO_VALUE_FOUND; /* So far best is bad */ + float best = (float) NO_VALUE_FOUND; /* So far best is bad */ HTFormat best_rep = NULL; /* Set when rep found */ HTAtom * best_enc = NULL; char * best_name = NULL; /* Best dir entry so far */ @@ -2217,40 +2408,38 @@ PUBLIC int HTLoadFile ARGS4( filevalue, 0L /* @@@@@@ */); if (value <= 0.0) { + char *atomname = NULL; + CompressFileType cft = HTCompressFileType(dirbuf->d_name, ".", &dot); char * cp = NULL; - int len = strlen(dirbuf->d_name); + enc = NULL; - if (len > 2 && - dirbuf->d_name[len - 1] == 'Z' && - dirbuf->d_name[len - 2] == '.') { + if (cft != cftNone) { StrAllocCopy(cp, dirbuf->d_name); - cp[len - 2] = '\0'; + cp[dot - dirbuf->d_name] = '\0'; format = HTFileFormat(cp, NULL, NULL); FREE(cp); value = HTStackValue(format, format_out, filevalue, 0); - if (value <= 0.0) { - format = HTAtom_for("application/x-compressed"); - value = HTStackValue(format, format_out, - filevalue, 0); - } - if (value <= 0.0) { - format = HTAtom_for("www/compressed"); - value = HTStackValue(format, format_out, - filevalue, 0); + switch (cft) { + case cftCompress: + atomname = "application/x-compressed"; + break; + case cftGzip: + atomname = "application/x-gzip"; + break; + case cftBzip2: + atomname = "application/x-bzip2"; + break; + case cftNone: + break; } - } else if ((len > 3) && - !strcasecomp((char *)&dirbuf->d_name[len - 2], - "gz") && - dirbuf->d_name[len - 3] == '.') { - StrAllocCopy(cp, dirbuf->d_name); - cp[len - 3] = '\0'; - format = HTFileFormat(cp, NULL, NULL); - FREE(cp); + } + + if (atomname != NULL) { value = HTStackValue(format, format_out, filevalue, 0); if (value <= 0.0) { - format = HTAtom_for("application/x-gzip"); + format = HTAtom_for(atomname); value = HTStackValue(format, format_out, filevalue, 0); } @@ -2262,8 +2451,8 @@ PUBLIC int HTLoadFile ARGS4( } } if (value != NO_VALUE_FOUND) { - CTRACE(tfp, "HTLoadFile: value of presenting %s is %f\n", - HTAtom_name(rep), value); + CTRACE((tfp, "HTLoadFile: value of presenting %s is %f\n", + HTAtom_name(rep), value)); if (value > best) { best_rep = rep; best_enc = enc; @@ -2300,21 +2489,13 @@ PUBLIC int HTLoadFile ARGS4( ** will hold the directory entry, and a type 'DIR' which is used ** to point to the current directory being read. */ -#ifdef _WINDOWS - if (!exists(localname)) -#else - if (stat(localname,&dir_info) == -1) /* get file information */ -#endif + if (HTStat(localname,&dir_info) == -1) /* get file information */ { /* if can't read file information */ - CTRACE(tfp, "HTLoadFile: can't stat %s\n", localname); + CTRACE((tfp, "HTLoadFile: can't stat %s\n", localname)); } else { /* Stat was OK */ -#ifdef _WINDOWS - if (stat(localname,&dir_info) == -1) dir_info.st_mode = S_IFDIR; -#endif - if (S_ISDIR(dir_info.st_mode)) { /* ** If localname is a directory. @@ -2322,7 +2503,7 @@ PUBLIC int HTLoadFile ARGS4( DIR *dp; struct stat file_info; - CTRACE(tfp, "%s is a directory\n", localname); + CTRACE((tfp, "%s is a directory\n", localname)); /* ** Check directory access. @@ -2335,16 +2516,10 @@ PUBLIC int HTLoadFile ARGS4( return HTLoadError(sink, 403, DISALLOWED_DIR_SCAN); } - if (HTDirAccess == HT_DIR_SELECTIVE) { - char * enable_file_name = - malloc(strlen(localname)+ 1 + - strlen(HT_DIR_ENABLE_FILE) + 1); - if (enable_file_name == NULL) - outofmem(__FILE__, "HTLoadFile"); - strcpy(enable_file_name, localname); - strcat(enable_file_name, "/"); - strcat(enable_file_name, HT_DIR_ENABLE_FILE); + char * enable_file_name = NULL; + + HTSprintf0(&enable_file_name, "%s/%s", localname, HT_DIR_ENABLE_FILE); if (stat(enable_file_name, &file_info) != 0) { FREE(localname); FREE(nodename); @@ -2353,6 +2528,7 @@ PUBLIC int HTLoadFile ARGS4( } } + CTRACE((tfp, "Opening directory %s\n", localname)); dp = opendir(localname); if (!dp) { FREE(localname); @@ -2366,11 +2542,19 @@ PUBLIC int HTLoadFile ARGS4( status = print_local_dir(dp, localname, anchor, format_out, sink); + closedir(dp); FREE(localname); FREE(nodename); return status; /* document loaded, maybe partial */ - } /* end if localname is a directory */ + } /* end if localname is a directory */ + + if (S_ISREG(dir_info.st_mode)) { +#ifdef INT_MAX + if (dir_info.st_size <= INT_MAX) +#endif + anchor->content_length = dir_info.st_size; + } } /* end if file stat worked */ @@ -2378,20 +2562,12 @@ PUBLIC int HTLoadFile ARGS4( */ #endif /* HAVE_READDIR */ { -# ifdef __EMX__ - int len = strlen(localname); - int bin = ((len > 3) && !strcasecomp(localname + len - 3, ".gz")); - FILE * fp = fopen(localname, (bin ? "rb" : "r")); -# else /* !( defined __EMX__ ) */ - FILE * fp = fopen(localname, "r"); -# endif + int bin = HTCompressFileType(localname, ".", &dot) != cftNone; + FILE * fp = fopen(localname, (bin ? BIN_R : "r")); - CTRACE (tfp, "HTLoadFile: Opening `%s' gives %p\n", - localname, (void*)fp); + CTRACE((tfp, "HTLoadFile: Opening `%s' gives %p\n", + localname, (void*)fp)); if (fp) { /* Good! */ - int len; - char *cp = NULL; - if (HTEditable(localname)) { HTAtom * put = HTAtom_for("PUT"); HTList * methods = HTAnchor_methods(anchor); @@ -2413,10 +2589,10 @@ PUBLIC int HTLoadFile ARGS4( (!strcmp(HTAtom_name(myEncoding), "gzip") || !strcmp(HTAtom_name(myEncoding), "x-gzip"))) { fclose(fp); - gzfp = gzopen(localname, "rb"); + gzfp = gzopen(localname, BIN_R); - CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", - localname, (void*)gzfp); + CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n", + localname, (void*)gzfp)); use_gzread = YES; } else #endif /* USE_ZLIB */ @@ -2425,42 +2601,47 @@ PUBLIC int HTLoadFile ARGS4( StrAllocCopy(anchor->content_encoding, HTAtom_name(myEncoding)); format = HTAtom_for("www/compressed"); } - } else if ((len = strlen(localname)) > 2) { - if (localname[len - 1] == 'Z' && - localname[len - 2] == '.') { + } else { + CompressFileType cft = HTCompressFileType(localname, ".", &dot); + + if (cft != cftNone) { + char *cp = NULL; + StrAllocCopy(cp, localname); - cp[len - 2] = '\0'; + cp[dot - localname] = '\0'; format = HTFileFormat(cp, &encoding, NULL); FREE(cp); format = HTCharsetFormat(format, anchor, UCLYhndl_HTFile_for_unspec); StrAllocCopy(anchor->content_type, format->name); + } + + switch (cft) { + case cftCompress: StrAllocCopy(anchor->content_encoding, "x-compress"); format = HTAtom_for("www/compressed"); - } else if ((len > 3) && - !strcasecomp((char *)&localname[len - 2], - "gz") && - localname[len - 3] == '.') { - StrAllocCopy(cp, localname); - cp[len - 3] = '\0'; - format = HTFileFormat(cp, &encoding, NULL); - FREE(cp); - format = HTCharsetFormat(format, anchor, - UCLYhndl_HTFile_for_unspec); - StrAllocCopy(anchor->content_type, format->name); + break; + case cftGzip: StrAllocCopy(anchor->content_encoding, "x-gzip"); #ifdef USE_ZLIB if (strcmp(format_out->name, "www/download") != 0) { fclose(fp); - gzfp = gzopen(localname, "rb"); + gzfp = gzopen(localname, BIN_R); - CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", - localname, (void*)gzfp); + CTRACE((tfp, "HTLoadFile: gzopen of `%s' gives %p\n", + localname, (void*)gzfp)); use_gzread = YES; } #else /* USE_ZLIB */ format = HTAtom_for("www/compressed"); #endif /* USE_ZLIB */ + break; + case cftBzip2: + StrAllocCopy(anchor->content_encoding, "x-bzip2"); + format = HTAtom_for("www/compressed"); + break; + case cftNone: + break; } } FREE(localname); @@ -2524,18 +2705,17 @@ PUBLIC int HTLoadFile ARGS4( if (strcmp(nodename, HTHostName()) != 0) #endif /* VMS */ { + status = -1; FREE(nodename); - if (!strncmp(addr, "file://localhost", 16)) { - return -1; /* never go to ftp site when URL - * is file://localhost - */ - } else { + if (strncmp(addr, "file://localhost", 16)) { + /* never go to ftp site when URL + * is file://localhost + */ #ifndef DISABLE_FTP - return HTFTPLoad(addr, anchor, format_out, sink); -#else - return -1; + status = HTFTPLoad(addr, anchor, format_out, sink); #endif /* DISABLE_FTP */ } + return status; } FREE(nodename); } @@ -2545,7 +2725,7 @@ PUBLIC int HTLoadFile ARGS4( ** All attempts have failed. */ { - CTRACE(tfp, "Can't open `%s', errno=%d\n", addr, SOCKET_ERRNO); + CTRACE((tfp, "Can't open `%s', errno=%d\n", addr, SOCKET_ERRNO)); return HTLoadError(sink, 403, FAILED_FILE_UNREADABLE); } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.h index a88b12854a5..edee6ded9de 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.h @@ -42,6 +42,7 @@ extern int HTDirReadme; /* Include readme files in listing? */ /* ** Convert filenames between local and WWW formats */ +extern char * HTURLPath_toFile PARAMS((CONST char * name, BOOL expand_all)); extern char * HTnameOfFile_WWW PARAMS((CONST char * name, BOOL WWW_prefix, BOOL expand_all)); #define HTLocalName(name) HTnameOfFile_WWW(name,TRUE,TRUE) #define HTfullURL_toFile(name) HTnameOfFile_WWW(name,FALSE,TRUE) @@ -71,6 +72,13 @@ extern BOOL HTDirTitles PARAMS(( HTAnchor * anchor, BOOL tildeIsTop)); +/* +** Check existence. +*/ +extern int HTStat PARAMS(( + CONST char * filename, + struct stat * data)); + /* Load a document. ** ---------------- */ @@ -126,7 +134,7 @@ extern void HTSetSuffix5 PARAMS(( CONST char * representation, CONST char * encoding, CONST char * desc, - float quality)); + double quality)); #define HTSetSuffix(suff,rep,enc,q) HTSetSuffix5(suff, rep, enc, NULL, q) @@ -157,6 +165,35 @@ extern HTFormat HTCharsetFormat PARAMS(( HTParentAnchor * anchor, int default_LYhndl)); +/* Get various pieces of meta info from file name. +** ----------------------------------------------- +** +** LYGetFileInfo fills in information that can be determined without +** an actual (new) access to the filesystem, based on current suffix +** and character set configuration. If the file has been loaded and +** parsed before (with the same URL generated here!) and the anchor +** is still around, some results may be influenced by that (in +** particular, charset info from a META tag - this is not actually +** tested!). +** The caller should not keep pointers to the returned objects around +** for too long, the valid lifetimes vary. In particular, the returned +** charset string should be copied if necessary. If return of the +** file_anchor is requested, that one can be used to retrieve +** additional bits of info that are stored in the anchor object and +** are not covered here; as usual, don't keep pointers to the +** file_anchor longer than necessary since the object may disappear +** through HTuncache_current_document or at the next document load. +** - kw +*/ +extern void LYGetFileInfo PARAMS(( + CONST char * filename, + HTParentAnchor ** pfile_anchor, + HTFormat * pformat, + HTAtom ** pencoding, + CONST char** pdesc, + CONST char** pcharset, + int * pfile_cs)); + /* ** Determine file value from file name. */ @@ -164,6 +201,21 @@ extern float HTFileValue PARAMS(( CONST char * filename)); /* +** Determine compression type from file name, by looking at its suffix. +*/ +typedef enum { + cftNone + , cftCompress + , cftGzip + , cftBzip2 +} CompressFileType; + +extern CompressFileType HTCompressFileType PARAMS(( + char * filename, + char * dots, + char ** suffix)); + +/* ** Determine write access to a file. ** ** ON EXIT, @@ -174,6 +226,30 @@ extern float HTFileValue PARAMS(( ** ** Isn't there a quicker way? */ + +#if defined(HAVE_CONFIG_H) + +#ifndef HAVE_GETGROUPS +#define NO_GROUPS +#endif + +#else + +#ifdef VMS +#define NO_GROUPS +#endif /* VMS */ +#ifdef NO_UNIX_IO +#define NO_GROUPS +#endif /* NO_UNIX_IO */ +#ifdef PCNFS +#define NO_GROUPS +#endif /* PCNFS */ +#ifdef NOUSERS +#define NO_GROUPS +#endif /* PCNFS */ + +#endif /* HAVE_CONFIG_H */ + extern BOOL HTEditable PARAMS((CONST char * filename)); /* Make a save stream. diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFinger.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFinger.c index 08f9763e506..9f205e0c0d7 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFinger.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFinger.c @@ -86,7 +86,7 @@ PRIVATE void start_anchor ARGS1(CONST char *, href) { int i; for(i=0; i<HTML_A_ATTRIBUTES; i++) - present[i] = (i==HTML_A_HREF); + present[i] = (BOOL) (i==HTML_A_HREF); } ((CONST char **)value)[HTML_A_HREF] = href; (*targetClass.start_element)(target, HTML_A, present, @@ -107,7 +107,7 @@ PRIVATE void start_anchor ARGS1(CONST char *, href) PRIVATE int response ARGS5( - CONST char *, command, + char *, command, char *, sitename, HTParentAnchor *, anAnchor, HTFormat, format_out, @@ -128,10 +128,10 @@ PRIVATE int response ARGS5( /* Send the command. */ - CTRACE(tfp, "HTFinger command to be sent: %s", command); + CTRACE((tfp, "HTFinger command to be sent: %s", command)); status = NETWRITE(s, (char *)command, length); if (status < 0) { - CTRACE(tfp, "HTFinger: Unable to send command. Disconnecting.\n"); + CTRACE((tfp, "HTFinger: Unable to send command. Disconnecting.\n")); NETCLOSE(s); s = -1; return status; @@ -144,7 +144,7 @@ PRIVATE int response ARGS5( /* Create the results report. */ - CTRACE(tfp,"HTFinger: Reading finger information\n"); + CTRACE((tfp,"HTFinger: Reading finger information\n")); START(HTML_HTML); PUTC('\n'); START(HTML_HEAD); @@ -185,13 +185,13 @@ PRIVATE int response ARGS5( while ((ch=NEXT_CHAR) != EOF) { if (interrupted_in_htgetcharacter) { - CTRACE(tfp, "HTFinger: Interrupted in HTGetCharacter, apparently.\n"); + CTRACE((tfp, "HTFinger: Interrupted in HTGetCharacter, apparently.\n")); _HTProgress (CONNECTION_INTERRUPTED); goto end_html; } if (ch != LF) { - *p = ch; /* Put character in line */ + *p = (char) ch; /* Put character in line */ if (p < &line[BIG-1]) { p++; } @@ -262,7 +262,7 @@ PUBLIC int HTLoadFinger ARGS4( int port; /* Port number from URL */ int status; /* tcp return */ - CTRACE(tfp, "HTFinger: Looking for %s\n", (arg ? arg : "NULL")); + CTRACE((tfp, "HTFinger: Looking for %s\n", (arg ? arg : "NULL"))); if (!(arg && *arg)) { HTAlert(COULD_NOT_LOAD_DATA); @@ -377,13 +377,13 @@ PUBLIC int HTLoadFinger ARGS4( /* Now, let's get a stream setup up from the FingerHost: ** CONNECTING to finger host */ - CTRACE(tfp, "HTFinger: doing HTDoConnect on '%s'\n", str); + CTRACE((tfp, "HTFinger: doing HTDoConnect on '%s'\n", str)); status = HTDoConnect(str, "finger", FINGER_PORT, &s); - CTRACE(tfp, "HTFinger: Done DoConnect; status %d\n", status); + CTRACE((tfp, "HTFinger: Done DoConnect; status %d\n", status)); if (status == HT_INTERRUPTED) { /* Interrupt cleanly */ - CTRACE(tfp, "HTFinger: Interrupted on connect; recovering cleanly.\n"); + CTRACE((tfp, "HTFinger: Interrupted on connect; recovering cleanly.\n")); HTProgress (CONNECTION_INTERRUPTED); FREE(str); FREE(command); @@ -392,13 +392,13 @@ PUBLIC int HTLoadFinger ARGS4( if (status < 0) { NETCLOSE(s); s = -1; - CTRACE(tfp, "HTFinger: Unable to connect to finger host.\n"); + CTRACE((tfp, "HTFinger: Unable to connect to finger host.\n")); HTAlert(gettext("Could not access finger host.")); FREE(str); FREE(command); return HT_NOT_LOADED; /* FAIL */ } - CTRACE(tfp, "HTFinger: Connected to finger host '%s'.\n", str); + CTRACE((tfp, "HTFinger: Connected to finger host '%s'.\n", str)); FREE(str); /* Send the command, and process response if successful. diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c index ed309bf3796..70184064e67 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c @@ -16,24 +16,18 @@ */ #include <HTFormat.h> -#ifdef USE_SSL -#define free_func free__func -#include <openssl/ssl.h> -#undef free_func -#endif /* USE_SSL */ - PUBLIC float HTMaxSecs = 1e10; /* No effective limit */ PUBLIC float HTMaxLength = 1e10; /* No effective limit */ PUBLIC long int HTMaxBytes = 0; /* No effective limit */ -#ifdef unix +#ifdef UNIX #ifdef NeXT #define PRESENT_POSTSCRIPT "open %s; /bin/rm -f %s\n" #else #define PRESENT_POSTSCRIPT "(ghostview %s ; /bin/rm -f %s)&\n" /* Full pathname would be better! */ #endif /* NeXT */ -#endif /* unix */ +#endif /* UNIX */ #include <HTML.h> #include <HTMLDTD.h> @@ -42,6 +36,7 @@ PUBLIC long int HTMaxBytes = 0; /* No effective limit */ #include <HTList.h> #include <HTInit.h> #include <HTTCP.h> +#include <HTTP.h> /* Streams and structured streams which we use: */ #include <HTFWriter.h> @@ -55,6 +50,10 @@ PUBLIC long int HTMaxBytes = 0; /* No effective limit */ #include <LYGlobalDefs.h> #include <LYLeaks.h> +#ifdef DISP_PARTIAL +#include <LYMainLoop.h> +#endif + PUBLIC BOOL HTOutputSource = NO; /* Flag: shortcut parser to stdout */ /* extern BOOL interactive; LJM */ @@ -91,21 +90,21 @@ PRIVATE void HTFreePresentations NOPARAMS; PUBLIC void HTSetPresentation ARGS6( CONST char *, representation, CONST char *, command, - float, quality, - float, secs, - float, secs_per_byte, + double, quality, + double, secs, + double, secs_per_byte, long int, maxbytes) { - HTPresentation * pres = (HTPresentation *)malloc(sizeof(HTPresentation)); + HTPresentation * pres = typecalloc(HTPresentation); if (pres == NULL) outofmem(__FILE__, "HTSetPresentation"); pres->rep = HTAtom_for(representation); pres->rep_out = WWW_PRESENT; /* Fixed for now ... :-) */ pres->converter = HTSaveAndExecute; /* Fixed for now ... */ - pres->quality = quality; - pres->secs = secs; - pres->secs_per_byte = secs_per_byte; + pres->quality = (float) quality; + pres->secs = (float) secs; + pres->secs_per_byte = (float) secs_per_byte; pres->maxbytes = maxbytes; pres->command = NULL; StrAllocCopy(pres->command, command); @@ -141,7 +140,7 @@ PUBLIC void HTSetConversion ARGS7( float, secs_per_byte, long int, maxbytes) { - HTPresentation * pres = (HTPresentation *)malloc(sizeof(HTPresentation)); + HTPresentation * pres = typecalloc(HTPresentation); if (pres == NULL) outofmem(__FILE__, "HTSetConversion"); @@ -243,11 +242,11 @@ PUBLIC int HTGetCharacter NOARGS if (status == 0) return EOF; if (status == HT_INTERRUPTED) { - CTRACE(tfp, "HTFormat: Interrupted in HTGetCharacter\n"); + CTRACE((tfp, "HTFormat: Interrupted in HTGetCharacter\n")); interrupted_in_htgetcharacter = 1; return EOF; } - CTRACE(tfp, "HTFormat: File read error %d\n", status); + CTRACE((tfp, "HTFormat: File read error %d\n", status)); return EOF; /* -1 is returned by UCX at end of HTTP link */ } @@ -257,7 +256,7 @@ PUBLIC int HTGetCharacter NOARGS ch = *input_pointer++; } while (ch == (char) 13); /* Ignore ASCII carriage return */ - return FROMASCII((unsigned char)ch); + return FROMASCII(UCH(ch)); } #ifdef USE_SSL @@ -275,11 +274,11 @@ PUBLIC char HTGetSSLCharacter ARGS1(void *, handle) if (status == 0) return (char)EOF; if (status == HT_INTERRUPTED) { - CTRACE(tfp, "HTFormat: Interrupted in HTGetSSLCharacter\n"); + CTRACE((tfp, "HTFormat: Interrupted in HTGetSSLCharacter\n")); interrupted_in_htgetcharacter = 1; return (char)EOF; } - CTRACE(tfp, "HTFormat: SSL_read error %d\n", status); + CTRACE((tfp, "HTFormat: SSL_read error %d\n", status)); return (char)EOF; /* -1 is returned by UCX at end of HTTP link */ } @@ -298,14 +297,14 @@ PUBLIC char HTGetSSLCharacter ARGS1(void *, handle) */ PRIVATE int half_match ARGS2(char *,trial_type, char *,target) { - char *cp=strchr(trial_type,'/'); + char *cp = strchr(trial_type, '/'); /* if no '/' or no '*' */ if (!cp || *(cp+1) != '*') return 0; - CTRACE(tfp, "HTFormat: comparing %s and %s for half match\n", - trial_type, target); + CTRACE((tfp, "HTFormat: comparing %s and %s for half match\n", + trial_type, target)); /* main type matches */ if (!strncmp(trial_type, target, (cp-trial_type)-1)) @@ -314,6 +313,8 @@ PRIVATE int half_match ARGS2(char *,trial_type, char *,target) return 0; } +#define WWW_WILDCARD_REP_OUT HTAtom_for("*") + /* Look up a presentation ** ---------------------- ** @@ -330,10 +331,10 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( HTFormat, rep_out, HTPresentation*, fill_in) { - HTAtom * wildcard = HTAtom_for("*"); + HTAtom * wildcard = NULL; /* = HTAtom_for("*"); lookup when needed - kw */ - CTRACE(tfp, "HTFormat: Looking up presentation for %s to %s\n", - HTAtom_name(rep_in), HTAtom_name(rep_out)); + CTRACE((tfp, "HTFormat: Looking up presentation for %s to %s\n", + HTAtom_name(rep_in), HTAtom_name(rep_out))); /* don't do anymore do it in the Lynx code at startup LJM */ /* if (!HTPresentations) HTFormatInit(); */ /* set up the list */ @@ -351,18 +352,21 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( pres = (HTPresentation *)HTList_objectAt(HTPresentations, i); if (pres->rep == rep_in) { if (pres->rep_out == rep_out) { - CTRACE(tfp, "FindPresentation: found exact match: %s\n", - HTAtom_name(pres->rep)); + CTRACE((tfp, "FindPresentation: found exact match: %s\n", + HTAtom_name(pres->rep))); return pres; } else if (!fill_in) { continue; - } else if (pres->rep_out == wildcard) { - if (!strong_wildcard_match) - strong_wildcard_match = pres; - /* otherwise use the first one */ - CTRACE(tfp, "StreamStack: found strong wildcard match: %s\n", - HTAtom_name(pres->rep)); + } else { + if (!wildcard) wildcard = WWW_WILDCARD_REP_OUT; + if (pres->rep_out == wildcard) { + if (!strong_wildcard_match) + strong_wildcard_match = pres; + /* otherwise use the first one */ + CTRACE((tfp, "StreamStack: found strong wildcard match: %s\n", + HTAtom_name(pres->rep))); + } } } else if (!fill_in) { @@ -374,8 +378,8 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( if (!strong_subtype_wildcard_match) strong_subtype_wildcard_match = pres; /* otherwise use the first one */ - CTRACE(tfp, "StreamStack: found strong subtype wildcard match: %s\n", - HTAtom_name(pres->rep)); + CTRACE((tfp, "StreamStack: found strong subtype wildcard match: %s\n", + HTAtom_name(pres->rep))); } } @@ -384,11 +388,12 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( if (!weak_wildcard_match) weak_wildcard_match = pres; /* otherwise use the first one */ - CTRACE(tfp, "StreamStack: found weak wildcard match: %s\n", - HTAtom_name(pres->rep_out)); - } - if (pres->rep_out == wildcard) { - if (!last_default_match) + CTRACE((tfp, "StreamStack: found weak wildcard match: %s\n", + HTAtom_name(pres->rep_out))); + + } else if (!last_default_match) { + if (!wildcard) wildcard = WWW_WILDCARD_REP_OUT; + if (pres->rep_out == wildcard) last_default_match = pres; /* otherwise use the first one */ } @@ -429,30 +434,44 @@ PUBLIC HTStream * HTStreamStack ARGS4( { HTPresentation temp; HTPresentation *match; + HTStream *result; - CTRACE(tfp, "HTFormat: Constructing stream stack for %s to %s\n", - HTAtom_name(rep_in), HTAtom_name(rep_out)); + CTRACE((tfp, "HTFormat: Constructing stream stack for %s to %s\n", + HTAtom_name(rep_in), HTAtom_name(rep_out))); /* don't return on WWW_SOURCE some people might like * to make use of the source!!!! LJM - *//* + */ +#if 0 if (rep_out == WWW_SOURCE || rep_out == rep_in) - return sink; LJM */ + return sink; /* LJM */ +#endif - if (rep_out == rep_in) - return sink; + if (rep_out == rep_in) { + result = sink; - if ((match = HTFindPresentation(rep_in, rep_out, &temp))) { + } else if ((match = HTFindPresentation(rep_in, rep_out, &temp))) { if (match == &temp) { - CTRACE(tfp, "StreamStack: Using %s\n", HTAtom_name(temp.rep_out)); + CTRACE((tfp, "StreamStack: Using %s\n", HTAtom_name(temp.rep_out))); } else { - CTRACE(tfp, "StreamStack: found exact match: %s\n", - HTAtom_name(match->rep)); + CTRACE((tfp, "StreamStack: found exact match: %s\n", + HTAtom_name(match->rep))); } - return (*match->converter)(match, anchor, sink); + result = (*match->converter)(match, anchor, sink); } else { - return NULL; + result = NULL; + } + if (TRACE) { + if (result && result->isa && result->isa->name) { + CTRACE((tfp, "StreamStack: Returning \"%s\"\n", result->isa->name)); + } else if (result) { + CTRACE((tfp, "StreamStack: Returning *unknown* stream!\n")); + } else { + CTRACE((tfp, "StreamStack: Returning NULL!\n")); + CTRACE_FLUSH(tfp); /* a crash may be imminent... - kw */ + } } + return result; } /* Put a presentation near start of list @@ -471,6 +490,56 @@ PUBLIC void HTReorderPresentation ARGS2( HTList_addObject(HTPresentations, match); } } + +/* + * Setup 'get_accept' flag to denote presentations that are not redundant, + * and will be listed in "Accept:" header. + */ +PUBLIC void HTFilterPresentations NOARGS +{ + int i, j; + int n = HTList_count(HTPresentations); + HTPresentation *p, *q; + BOOL matched; + char *s, *t, *x, *y; + + for (i = 0; i < n; i++) { + p = (HTPresentation *)HTList_objectAt(HTPresentations, i); + s = HTAtom_name(p->rep); + + if (p->rep_out == WWW_PRESENT) { + if (p->rep != WWW_SOURCE + && strcasecomp(s, "www/mime") + && strcasecomp(s, "www/compressed") + && p->quality <= 1.0 && p->quality >= 0.0) { + for (j = 0, matched = FALSE; j < i; j++) { + q = (HTPresentation *)HTList_objectAt(HTPresentations, j); + t = HTAtom_name(q->rep); + + if (!strcasecomp(s, t)) { + matched = TRUE; + break; + } + if ((x = strchr(s, '/')) != 0 + && (y = strchr(t, '/')) != 0) { + int len1 = x++ - s; + int len2 = y++ - t; + int lens = (len1 > len2) ? len1 : len2; + + if ((*t == '*' || !strncasecomp(s, t, lens)) + && (*y == '*' || !strcasecomp(x, y))) { + matched = TRUE; + break; + } + } + } + if (!matched) + p->get_accept = TRUE; + } + } + } +} + /* Find the cost of a filter stack ** ------------------------------- ** @@ -485,10 +554,10 @@ PUBLIC float HTStackValue ARGS4( float, initial_value, long int, length) { - HTAtom * wildcard = HTAtom_for("*"); + HTAtom * wildcard = WWW_WILDCARD_REP_OUT; - CTRACE(tfp, "HTFormat: Evaluating stream stack for %s worth %.3f to %s\n", - HTAtom_name(rep_in), initial_value, HTAtom_name(rep_out)); + CTRACE((tfp, "HTFormat: Evaluating stream stack for %s worth %.3f to %s\n", + HTAtom_name(rep_in), initial_value, HTAtom_name(rep_out))); if (rep_out == WWW_SOURCE || rep_out == rep_in) return 0.0; @@ -513,7 +582,7 @@ PUBLIC float HTStackValue ARGS4( } } - return -1e30; /* Really bad */ + return (float) -1e30; /* Really bad */ } @@ -529,14 +598,13 @@ PUBLIC void HTDisplayPartial NOARGS #ifdef DISP_PARTIAL if (display_partial) { /* - ** HText_getNumOfLines() = "current" number of lines received + ** HText_getNumOfLines() = "current" number of complete lines received ** NumOfLines_partial = number of lines at the moment of last repaint. + ** (we update NumOfLines_partial only when we repaint the display.) ** - ** We update NumOfLines_partial only when we repaint the display. - ** -1 is the special value: - ** This is a synchronization flag switched to 0 when HText_new() - ** starts a new HTMainText object - all HText_ functions use it, - ** lines counter in particular [we call it from HText_getNumOfLines()]. + ** display_partial could only be enabled in HText_new() + ** so a new HTMainText object available - all HText_ functions use it, + ** lines counter HText_getNumOfLines() in particular. ** ** Otherwise HTMainText holds info from the previous document ** and we may repaint it instead of the new one: @@ -545,13 +613,13 @@ PUBLIC void HTDisplayPartial NOARGS ** ** So repaint the page only when necessary: */ - if ((NumOfLines_partial != -1) - /* new HText object available */ - && ((Newline_partial + display_lines) > NumOfLines_partial) + int Newline_partial = LYGetNewline(); + + if (((Newline_partial + display_lines) - 1 > NumOfLines_partial) /* current page not complete... */ && (partial_threshold > 0 ? - ((Newline_partial + partial_threshold) < HText_getNumOfLines()) : - ((Newline_partial + display_lines) < HText_getNumOfLines())) + ((Newline_partial + partial_threshold) -1 <= HText_getNumOfLines()) : + ((Newline_partial + display_lines) - 1 <= HText_getNumOfLines())) /* * Originally we rendered by increments of 2 lines, * but that got annoying on slow network connections. @@ -560,7 +628,7 @@ PUBLIC void HTDisplayPartial NOARGS */ ) { NumOfLines_partial = HText_getNumOfLines(); - HText_pageDisplay(Newline_partial, ""); + LYMainLoop_pageDisplay(Newline_partial); } } #else /* nothing */ @@ -571,24 +639,10 @@ PUBLIC void HTDisplayPartial NOARGS PUBLIC void HTFinishDisplayPartial NOARGS { #ifdef DISP_PARTIAL - if (display_partial) { - /* - * Override Newline with a new value if user - * scrolled the document while downloading. - */ - if (Newline_partial != Newline - && NumOfLines_partial > 0) - Newline = Newline_partial; - } - /* * End of incremental rendering stage here. */ display_partial = FALSE; - NumOfLines_partial = -1; /* initialize to -1 */ - /* -1 restrict HTDisplayPartial() */ - /* until HText_new() start next HTMainText */ - /* and set the flag to 0 */ #endif /* DISP_PARTIAL */ } @@ -631,8 +685,15 @@ PUBLIC int HTCopy ARGS4( HTStream*, sink) { HTStreamClass targetClass; + BOOL suppress_readprogress = NO; int bytes; int rv = 0; +#ifdef _WINDOWS /* 1997/11/11 (Tue) 15:18:16 */ + long file_length; + extern int bytes_already_read; + + file_length = anchor->content_length; +#endif /* Push the data down the stream */ @@ -684,6 +745,9 @@ PUBLIC int HTCopy ARGS4( rv = -1; goto finished; } else if (SOCKET_ERRNO == ENOTCONN || +#ifdef _WINDOWS /* 1997/11/10 (Mon) 16:57:18 */ + SOCKET_ERRNO == ETIMEDOUT || +#endif SOCKET_ERRNO == ECONNRESET || SOCKET_ERRNO == EPIPE) { /* @@ -705,10 +769,10 @@ PUBLIC int HTCopy ARGS4( * TCP stacks for VMS etc., so this is currently * only for UNIX. - kw */ - HTInetStatus("NETREAD"); - HTAlert("Unexpected server disconnect."); - CTRACE(tfp, - "HTCopy: Unexpected server disconnect. Treating as completed.\n"); + HTInetStatus("NETREAD"); + HTAlert("Unexpected server disconnect."); + CTRACE((tfp, + "HTCopy: Unexpected server disconnect. Treating as completed.\n")); status = 0; break; #else /* !UNIX */ @@ -716,8 +780,8 @@ PUBLIC int HTCopy ARGS4( * Treat what we've gotten already * as the complete transmission. - FM */ - CTRACE(tfp, - "HTCopy: Unexpected server disconnect. Treating as completed.\n"); + CTRACE((tfp, + "HTCopy: Unexpected server disconnect. Treating as completed.\n")); status = 0; break; #endif /* UNIX */ @@ -746,6 +810,16 @@ PUBLIC int HTCopy ARGS4( break; } + /* + * Suppress ReadProgress messages when collecting a redirection + * message, at least initially (unless/until anchor->content_type + * gets changed, probably by the MIME message parser). That way + * messages put up by the HTTP module or elsewhere can linger in + * the statusline for a while. - kw + */ + suppress_readprogress = (anchor && anchor->content_type && + !strcmp(anchor->content_type, + "message/x-http-redirection")); #ifdef NOT_ASCII { char * p; @@ -757,7 +831,8 @@ PUBLIC int HTCopy ARGS4( (*targetClass.put_block)(sink, input_buffer, status); bytes += status; - HTReadProgress(bytes, anchor ? anchor->content_length : 0); + if (!suppress_readprogress) + HTReadProgress(bytes, anchor ? anchor->content_length : 0); HTDisplayPartial(); } /* next bufferload */ @@ -813,8 +888,8 @@ PUBLIC int HTFileCopy ARGS2( rv = HT_LOADED; break; } - CTRACE(tfp, "HTFormat: Read error, read returns %d\n", - ferror(fp)); + CTRACE((tfp, "HTFormat: Read error, read returns %d\n", + ferror(fp))); if (bytes) { rv = HT_PARTIAL_CONTENT; } else { @@ -826,7 +901,13 @@ PUBLIC int HTFileCopy ARGS2( (*targetClass.put_block)(sink, input_buffer, status); bytes += status; HTReadProgress(bytes, 0); - HTDisplayPartial(); + /* Suppress last screen update in partial mode - a regular update + * under control of mainloop() should follow anyway. - kw + */ +#ifdef DISP_PARTIAL + if (display_partial && bytes != HTMainAnchor->content_length) + HTDisplayPartial(); +#endif if (HTCheckForInterrupt()) { _HTProgress (TRANSFER_INTERRUPTED); @@ -864,11 +945,12 @@ PUBLIC int HTMemCopy ARGS2( HTChunk *, chunk, HTStream *, sink) { - HTStreamClass targetClass = *(sink->isa); + HTStreamClass targetClass; int bytes = 0; CONST char *data = chunk->data; int rv = HT_OK; + targetClass = *(sink->isa); HTReadProgress(0, 0); for (;;) { /* Push the data down the stream a piece at a time, in case we're @@ -945,10 +1027,10 @@ PRIVATE int HTGzFileCopy ARGS2( rv = HT_LOADED; break; } - CTRACE(tfp, "HTGzFileCopy: Read error, gzread returns %d\n", - status); - CTRACE(tfp, "gzerror : %s\n", - gzerror(gzfp, &gzerrnum)); + CTRACE((tfp, "HTGzFileCopy: Read error, gzread returns %d\n", + status)); + CTRACE((tfp, "gzerror : %s\n", + gzerror(gzfp, &gzerrnum))); if (TRACE) { if (gzerrnum == Z_ERRNO) perror("gzerror "); @@ -999,7 +1081,7 @@ PUBLIC void HTCopyNoCR ARGS3( HTStream*, sink) { HTStreamClass targetClass; - char character; + int character; /* Push the data, ignoring CRLF, down the stream */ @@ -1013,9 +1095,9 @@ PUBLIC void HTCopyNoCR ARGS3( HTInitInput(file_number); for (;;) { character = HTGetCharacter(); - if (character == (char)EOF) + if (character == EOF) break; - (*targetClass.put_character)(sink, character); + (*targetClass.put_character)(sink, UCH(character)); } } @@ -1074,7 +1156,7 @@ PUBLIC int HTParseSocket ARGS5( } HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(rep_in), HTAtom_name(format_out)); - CTRACE(tfp, "HTFormat: %s\n", buffer); + CTRACE((tfp, "HTFormat: %s\n", buffer)); rv = HTLoadError(sink, 501, buffer); /* returns -501 */ FREE(buffer); } else { @@ -1124,9 +1206,12 @@ PUBLIC int HTParseFile ARGS5( HTStreamClass targetClass; int rv; - stream = HTStreamStack(rep_in, - format_out, - sink , anchor); +#ifdef SH_EX /* 1998/01/04 (Sun) 16:04:09 */ + if (fp == NULL) + return HT_LOADED; +#endif + + stream = HTStreamStack(rep_in, format_out, sink, anchor); if (!stream) { char *buffer = 0; @@ -1136,7 +1221,7 @@ PUBLIC int HTParseFile ARGS5( } HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(rep_in), HTAtom_name(format_out)); - CTRACE(tfp, "HTFormat(in HTParseFile): %s\n", buffer); + CTRACE((tfp, "HTFormat(in HTParseFile): %s\n", buffer)); rv = HTLoadError(sink, 501, buffer); FREE(buffer); return rv; @@ -1178,7 +1263,7 @@ PUBLIC int HTParseFile ARGS5( ** -501 Stream stack failed (cannot present or convert). ** HT_LOADED All data sent. ** -** Stat of memory and target stream on return: +** State of memory and target stream on return: ** always chunk unchanged; target freed, aborted, or NULL. */ PUBLIC int HTParseMem ARGS5( @@ -1197,7 +1282,7 @@ PUBLIC int HTParseMem ARGS5( char *buffer = 0; HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(rep_in), HTAtom_name(format_out)); - CTRACE(tfp, "HTFormat(in HTParseMem): %s\n", buffer); + CTRACE((tfp, "HTFormat(in HTParseMem): %s\n", buffer)); rv = HTLoadError(sink, 501, buffer); FREE(buffer); return rv; @@ -1224,7 +1309,7 @@ PRIVATE int HTCloseGzFile ARGS1( if (gzres == Z_ERRNO) { perror("gzclose "); } else if (gzres != Z_OK) { - CTRACE(tfp, "gzclose : error number %d\n", gzres); + CTRACE((tfp, "gzclose : error number %d\n", gzres)); } } return(gzres); @@ -1257,9 +1342,7 @@ PUBLIC int HTParseGzFile ARGS5( HTStreamClass targetClass; int rv; - stream = HTStreamStack(rep_in, - format_out, - sink , anchor); + stream = HTStreamStack(rep_in, format_out, sink, anchor); if (!stream) { char *buffer = 0; @@ -1270,7 +1353,7 @@ PUBLIC int HTParseGzFile ARGS5( } HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(rep_in), HTAtom_name(format_out)); - CTRACE(tfp, "HTFormat(in HTParseGzFile): %s\n", buffer); + CTRACE((tfp, "HTFormat(in HTParseGzFile): %s\n", buffer)); rv = HTLoadError(sink, 501, buffer); FREE(buffer); return rv; @@ -1322,7 +1405,7 @@ PRIVATE void NetToText_put_character ARGS2(HTStream *, me, char, net_char) me->sink->isa->put_character(me->sink, CR); /* leftover */ } } - me->had_cr = (c == CR); + me->had_cr = (BOOL) (c == CR); if (!me->had_cr) me->sink->isa->put_character(me->sink, c); /* normal */ } @@ -1370,7 +1453,7 @@ PRIVATE HTStreamClass NetToTextClass = { */ PUBLIC HTStream * HTNetToText ARGS1(HTStream *, sink) { - HTStream* me = (HTStream*)malloc(sizeof(*me)); + HTStream* me = typecalloc(HTStream); if (me == NULL) outofmem(__FILE__, "NetToText"); @@ -1381,3 +1464,53 @@ PUBLIC HTStream * HTNetToText ARGS1(HTStream *, sink) return me; } +PRIVATE HTStream HTBaseStreamInstance; /* Made static */ +/* +** ERROR STREAM +** ------------ +** There is only one error stream shared by anyone who wants a +** generic error returned from all stream methods. +*/ +PRIVATE void HTErrorStream_put_character ARGS2(HTStream *, me GCC_UNUSED, char, c GCC_UNUSED) +{ + LYCancelDownload = TRUE; +} + +PRIVATE void HTErrorStream_put_string ARGS2(HTStream *, me GCC_UNUSED, CONST char *, s) +{ + if (s && *s) + LYCancelDownload = TRUE; +} + +PRIVATE void HTErrorStream_write ARGS3(HTStream *, me GCC_UNUSED, CONST char *, s, int, l) +{ + if (l && s) + LYCancelDownload = TRUE; +} + +PRIVATE void HTErrorStream_free ARGS1(HTStream *, me GCC_UNUSED) +{ + return; +} + +PRIVATE void HTErrorStream_abort ARGS2(HTStream *, me GCC_UNUSED, HTError, e GCC_UNUSED) +{ + return; +} + +PRIVATE CONST HTStreamClass HTErrorStreamClass = +{ + "ErrorStream", + HTErrorStream_free, + HTErrorStream_abort, + HTErrorStream_put_character, + HTErrorStream_put_string, + HTErrorStream_write +}; + +PUBLIC HTStream * HTErrorStream NOARGS +{ + CTRACE((tfp, "ErrorStream. Created\n")); + HTBaseStreamInstance.isa = &HTErrorStreamClass; /* The rest is random */ + return &HTBaseStreamInstance; +} diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.h index 42aeea5021f..63c96f5b70f 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.h @@ -48,6 +48,14 @@ typedef HTAtom * HTFormat; */ #define WWW_PRESENT HTAtom_for("www/present") /* The user's perception */ +#define WWW_DEBUG HTAtom_for("www/debug") +/* + + WWW_DEBUG represents the user's perception of debug information, for example sent as a + HTML document in a HTTP redirection message. + + */ + /* The message/rfc822 format means a MIME message or a plain text message with no MIME @@ -57,6 +65,11 @@ typedef HTAtom * HTFormat; #define WWW_MIME HTAtom_for("www/mime") /* A MIME message */ /* + For parsing only the header. - kw + */ +#define WWW_MIME_HEAD HTAtom_for("message/x-rfc822-head") + +/* www/print is like www/present except it represents a printed copy. @@ -137,7 +150,7 @@ typedef HTAtom* HTEncoding; The HTPresentation and HTConverter types This HTPresentation structure represents a possible conversion algorithm from one - format to annother. It includes a pointer to a conversion routine. The conversion + format to another. It includes a pointer to a conversion routine. The conversion routine returns a stream to which data should be fed. See also HTStreamStack which scans the list of registered converters and calls one. See the initialisation module for a list of conversion routines. @@ -151,14 +164,15 @@ typedef HTStream * HTConverter PARAMS(( HTStream * sink)); struct _HTPresentation { - HTAtom * rep; /* representation name atmoized */ + HTAtom * rep; /* representation name atomized */ HTAtom * rep_out; /* resulting representation */ - HTConverter * converter; /* The routine to gen the stream stack */ + HTConverter * converter; /* routine to gen the stream stack */ char * command; /* MIME-format string */ float quality; /* Between 0 (bad) and 1 (good) */ float secs; float secs_per_byte; long int maxbytes; + BOOL get_accept; /* list in "Accept:" for GET */ }; /* @@ -171,7 +185,7 @@ extern HTList * HTPresentations; /* - The default presentation is used when no other is appriporate + The default presentation is used when no other is appropriate */ extern HTPresentation* default_presentation; @@ -197,9 +211,9 @@ HTSetPresentation: Register a system command to present a format extern void HTSetPresentation PARAMS(( CONST char * representation, CONST char * command, - float quality, - float secs, - float secs_per_byte, + double quality, + double secs, + double secs_per_byte, long int maxbytes )); @@ -259,6 +273,12 @@ extern void HTReorderPresentation PARAMS(( HTFormat format_out)); /* + * Setup 'get_accept' flag to denote presentations that are not redundant, + * and will be listed in "Accept:" header. + */ +extern void HTFilterPresentations NOPARAMS; + +/* HTStackValue: Find the cost of a filter stack @@ -282,7 +302,7 @@ extern float HTStackValue PARAMS(( float initial_value, long int length)); -#define NO_VALUE_FOUND -1e20 /* returned if none found */ +#define NO_VALUE_FOUND -1e20 /* returned if none found */ /* Display the page while transfer in progress ** ------------------------------------------- diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGopher.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGopher.c index 02a830577c8..96681e6649d 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGopher.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGopher.c @@ -158,10 +158,10 @@ PRIVATE CONST char hex[17] = "0123456789abcdef"; PRIVATE char from_hex ARGS1(char, c) { - return (c>='0')&&(c<='9') ? c-'0' + return (char) ( (c>='0')&&(c<='9') ? c-'0' : (c>='A')&&(c<='F') ? c-'A'+10 : (c>='a')&&(c<='f') ? c-'a'+10 - : 0; + : 0); } /* Paste in an Anchor @@ -191,7 +191,7 @@ PRIVATE void write_anchor ARGS2(CONST char *,text, CONST char *,addr) present[HTML_A_TITLE] = YES; ((CONST char **)value)[HTML_A_TITLE] = text; - CTRACE(tfp,"HTGopher: adding URL: %s\n",addr); + CTRACE((tfp,"HTGopher: adding URL: %s\n",addr)); HT_Is_Gopher_URL = TRUE; /* tell HTML.c that this is a Gopher URL */ (*targetClass.start_element)(target, HTML_A, present, @@ -251,12 +251,12 @@ PRIVATE void parse_menu ARGS2( while ((ich=NEXT_CHAR) != EOF) { if (interrupted_in_htgetcharacter) { - CTRACE(tfp, "HTGopher: Interrupted in HTGetCharacter, apparently.\n"); + CTRACE((tfp, "HTGopher: Interrupted in HTGetCharacter, apparently.\n")); goto end_html; } if ((char)ich != LF) { - *p = ich; /* Put character in line */ + *p = (char) ich; /* Put character in line */ if (p< &line[BIG-1]) p++; } else { @@ -264,7 +264,7 @@ PRIVATE void parse_menu ARGS2( bytes += p-line; /* add size */ p = line; /* Scan it to parse it */ port = 0; /* Flag "not parsed" */ - CTRACE(tfp, "HTGopher: Menu item: %s\n", line); + CTRACE((tfp, "HTGopher: Menu item: %s\n", line)); gtype = *p++; if (bytes > BytesReported + 1024) { @@ -403,7 +403,7 @@ PRIVATE void parse_menu ARGS2( HTSprintf0(&address, "//%s/%c", host, gtype); for(r = selector; *r; r++) { /* Encode selector string */ - if (acceptable[(unsigned char)*r]) { + if (acceptable[UCH(*r)]) { HTSprintf(&address, "%c", *r); } else { HTSprintf(&address, "%c%c%c", @@ -421,7 +421,7 @@ PRIVATE void parse_menu ARGS2( PUTS(name); FREE(address); } else { /* parse error */ - CTRACE(tfp, "HTGopher: Bad menu item.\n"); + CTRACE((tfp, "HTGopher: Bad menu item.\n")); PUTS(line); } /* parse error */ @@ -497,7 +497,7 @@ PRIVATE void parse_cso ARGS2( { if ((char)ich != LF) { - *p = ich; /* Put character in line */ + *p = (char) ich; /* Put character in line */ if (p< &line[BIG-1]) p++; } else @@ -708,7 +708,7 @@ PRIVATE void de_escape ARGS2(char *, command, CONST char *, selector) b = from_hex(c); c = *p++; if (!c) break; /* Odd number of chars! */ - *q++ = FROMASCII((b<<4) + from_hex(c)); + *q++ = (char) FROMASCII((b<<4) + from_hex(c)); } else { *q++ = *p++; /* Record */ } @@ -760,9 +760,7 @@ PRIVATE void interpret_cso_key ARGS5( if (0 == strncmp(key, "$(FID)", 6)) { sprintf(buf, "%d", fld->id); } else if (0 == strncmp(key, "$(FDESC)", 8)) { - sprintf(buf, "%s%s%s", fld->description, - ctx->public_override ? /***" "***/"" : "", - ctx->public_override ? /***fld->attributes***/"" : ""); + sprintf(buf, "%.2046s", fld->description); } else if (0 == strncmp(key, "$(FDEF)", 7)) { strcpy(buf, fld->defreturn ? " checked" : ""); } else if (0 == strncmp(key, "$(FNDX)", 7)) { @@ -940,14 +938,14 @@ PRIVATE int parse_cso_fields ARGS2( */ while ((ich = NEXT_CHAR) != EOF) { if (interrupted_in_htgetcharacter) { - CTRACE(tfp, "HTLoadCSO: Interrupted in HTGetCharacter, apparently.\n"); + CTRACE((tfp, "HTLoadCSO: Interrupted in HTGetCharacter, apparently.\n")); free_CSOfields(); buf[0] = '\0'; return HT_INTERRUPTED; } if ((char)ich != LF) { - *p = ich; /* Put character in buffer */ + *p = (char) ich; /* Put character in buffer */ if (p < &buf[size-1]) { p++; } @@ -981,28 +979,30 @@ PRIVATE int parse_cso_fields ARGS2( ** multiple digits (infinite?). */ - /* - ** Check status, ignore any non-success. - */ - if (p[1] != '2' ) - continue; + /* + ** Check status, ignore any non-success. + */ + if (p[1] != '2' ) + continue; - /* - ** Parse fields within returned line into status, ndx, name, data. - */ - indx = NULL; - name = NULL; - for (i = 0; p[i]; i++) - if (p[i] == ':' ) { - p[i] = '\0'; - if (!indx) { - indx = (char *)&p[i+1]; - code = atoi (indx); - } else if (!name) { - name = (char *)&p[i+1]; - } else { - i++; - break; + /* + ** Parse fields within returned line into status, ndx, name, + ** data. + */ + indx = NULL; + name = NULL; + for (i = 0; p[i]; i++) { + if (p[i] == ':' ) { + p[i] = '\0'; + if (!indx) { + indx = (char *)&p[i+1]; + code = atoi (indx); + } else if (!name) { + name = (char *)&p[i+1]; + } else { + i++; + break; + } } } /* @@ -1028,7 +1028,7 @@ PRIVATE int parse_cso_fields ARGS2( ** Initialize new block, append to end of list ** to preserve order. */ - new = (CSOfield_info *)calloc(1, sizeof(CSOfield_info)); + new = typecalloc(CSOfield_info); if (!new) { outofmem(__FILE__, "HTLoadCSO"); } @@ -1097,7 +1097,7 @@ PRIVATE int generate_cso_form ARGS4( char *key, *line; CSOformgen_context ctx; static char *template[] = { - "<HEAD>\n<TITLE>CSO/PH Query Form for $(HOST)</TITLE>\n</HEAD>\n<BODY>", + "<HTML>\n<HEAD>\n<TITLE>CSO/PH Query Form for $(HOST)</TITLE>\n</HEAD>\n<BODY>", "<H2><I>CSO/PH Query Form</I> for <EM>$(HOST)</EM></H2>", "To search the database for a name, fill in one or more of the fields", "in the form below and activate the 'Submit query' button. At least", @@ -1237,13 +1237,13 @@ PRIVATE int generate_cso_report ARGS1( */ while (!stop && (ich = NEXT_CHAR) != EOF) { if (interrupted_in_htgetcharacter) { - CTRACE(tfp, "HTLoadCSO: Interrupted in HTGetCharacter, apparently.\n"); + CTRACE((tfp, "HTLoadCSO: Interrupted in HTGetCharacter, apparently.\n")); _HTProgress (CONNECTION_INTERRUPTED); goto end_CSOreport; } if ((char)ich != LF) { - *p = ich; /* Put character in line */ + *p = (char) ich; /* Put character in line */ if (p < &line[BIG-1]) { p++; } @@ -1459,7 +1459,7 @@ PRIVATE int HTLoadCSO ARGS4( return -3; /* Bad if no name sepcified */ if (!*arg) return -2; /* Bad if name had zero length */ - CTRACE(tfp, "HTLoadCSO: Looking for %s\n", arg); + CTRACE((tfp, "HTLoadCSO: Looking for %s\n", arg)); /* ** Set up a socket to the server for the data. @@ -1469,26 +1469,26 @@ PRIVATE int HTLoadCSO ARGS4( /* ** Interrupt cleanly. */ - CTRACE(tfp, "HTLoadCSO: Interrupted on connect; recovering cleanly.\n"); + CTRACE((tfp, "HTLoadCSO: Interrupted on connect; recovering cleanly.\n")); _HTProgress (CONNECTION_INTERRUPTED); return HT_NOT_LOADED; } if (status < 0) { - CTRACE(tfp, "HTLoadCSO: Unable to connect to remote host for `%s'.\n", - arg); + CTRACE((tfp, "HTLoadCSO: Unable to connect to remote host for `%s'.\n", + arg)); return HTInetStatus("connect"); } HTInitInput(s); /* Set up input buffering */ HTSprintf0(&command, "fields%c%c", CR, LF); - CTRACE(tfp, "HTLoadCSO: Connected, writing command `%s' to socket %d\n", - command, s); + CTRACE((tfp, "HTLoadCSO: Connected, writing command `%s' to socket %d\n", + command, s)); _HTProgress (GOPHER_SENDING_CSO_REQUEST); status = NETWRITE(s, command, (int)strlen(command)); FREE(command); if (status < 0) { - CTRACE(tfp, "HTLoadCSO: Unable to send command.\n"); + CTRACE((tfp, "HTLoadCSO: Unable to send command.\n")); return HTInetStatus("send"); } _HTProgress (GOPHER_SENT_CSO_REQUEST); @@ -1655,12 +1655,12 @@ PRIVATE int HTLoadCSO ARGS4( (*Target->isa->put_block)(Target, command, strlen(command)); strcpy(buf, "</H2>\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); - CTRACE(tfp, "HTLoadCSO: Writing command `%s' to socket %d\n", - command, s); + CTRACE((tfp, "HTLoadCSO: Writing command `%s' to socket %d\n", + command, s)); status = NETWRITE(s, command, strlen(command)); FREE(command); if (status < 0) { - CTRACE(tfp, "HTLoadCSO: Unable to send command.\n"); + CTRACE((tfp, "HTLoadCSO: Unable to send command.\n")); free_CSOfields(); return HTInetStatus("send"); } @@ -1697,7 +1697,7 @@ PRIVATE int HTLoadGopher ARGS4( return -3; /* Bad if no name sepcified */ if (!*arg) return -2; /* Bad if name had zero length */ - CTRACE(tfp, "HTGopher: Looking for %s\n", arg); + CTRACE((tfp, "HTGopher: Looking for %s\n", arg)); /* ** If it's a port 105 GOPHER_CSO gtype with no ISINDEX token ('?'), @@ -1710,7 +1710,7 @@ PRIVATE int HTLoadGopher ARGS4( if ((len = strlen(arg)) > 5) { if (0 == strcmp((CONST char *)&arg[len-6], ":105/2")) { /* Use CSO gateway. */ - CTRACE(tfp, "HTGopher: Passing to CSO/PH gateway.\n"); + CTRACE((tfp, "HTGopher: Passing to CSO/PH gateway.\n")); return HTLoadCSO(arg, anAnchor, format_out, sink); } } @@ -1721,10 +1721,10 @@ PRIVATE int HTLoadGopher ARGS4( */ if (strstr(arg, ":79/0") != NULL) { #ifndef DISABLE_FINGER - CTRACE(tfp, "HTGopher: Passing to finger gateway.\n"); + CTRACE((tfp, "HTGopher: Passing to finger gateway.\n")); return HTLoadFinger(arg, anAnchor, format_out, sink); #else /* finger is disabled */ - HTAlert(gettext("Unable to access document!")); + HTAlert(COULD_NOT_ACCESS_DOCUMENT); return HT_NOT_LOADED; #endif /* DISABLE_FINGER */ } @@ -1824,22 +1824,22 @@ PRIVATE int HTLoadGopher ARGS4( /* ** Interrupt cleanly. */ - CTRACE(tfp, "HTGopher: Interrupted on connect; recovering cleanly.\n"); + CTRACE((tfp, "HTGopher: Interrupted on connect; recovering cleanly.\n")); _HTProgress (CONNECTION_INTERRUPTED); FREE(command); return HT_NOT_LOADED; } if (status < 0) { - CTRACE(tfp, "HTGopher: Unable to connect to remote host for `%s'.\n", - arg); + CTRACE((tfp, "HTGopher: Unable to connect to remote host for `%s'.\n", + arg)); FREE(command); return HTInetStatus("connect"); } HTInitInput(s); /* Set up input buffering */ - CTRACE(tfp, "HTGopher: Connected, writing command `%s' to socket %d\n", - command, s); + CTRACE((tfp, "HTGopher: Connected, writing command `%s' to socket %d\n", + command, s)); #ifdef NOT_ASCII { @@ -1855,7 +1855,7 @@ PRIVATE int HTLoadGopher ARGS4( status = NETWRITE(s, command, (int)strlen(command)); FREE(command); if (status < 0) { - CTRACE(tfp, "HTGopher: Unable to send command.\n"); + CTRACE((tfp, "HTGopher: Unable to send command.\n")); return HTInetStatus("send"); } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGroup.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGroup.c index 490699d3429..2b16599fb6a 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGroup.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTGroup.c @@ -48,6 +48,7 @@ #include <HTLex.h> /* Lexical analysor */ #include <HTGroup.h> /* Implemented here */ +#include <LYUtils.h> #include <LYLeaks.h> /* @@ -78,12 +79,12 @@ PRIVATE void syntax_error ARGS3(FILE *, fp, int ch; while ((ch = getc(fp)) != EOF && ch != '\n') - if (cnt < 40) buffer[cnt++] = ch; + if (cnt < 40) buffer[cnt++] = (char) ch; buffer[cnt] = (char)0; - CTRACE(tfp, "%s %d before: '%s'\nHTGroup.c: %s (got %s)\n", + CTRACE((tfp, "%s %d before: '%s'\nHTGroup.c: %s (got %s)\n", "HTGroup.c: Syntax error in rule file at line", - HTlex_line, buffer, msg, lex_verbose(lex_item)); + HTlex_line, buffer, msg, lex_verbose(lex_item))); HTlex_line++; } @@ -107,7 +108,7 @@ PRIVATE AddressDefList *parse_address_part ARGS1(FILE *, fp) address_def_list = HTList_new(); for(;;) { - Ref *ref = (Ref*)calloc(1, sizeof(Ref)); + Ref *ref = typecalloc(Ref); if (ref == NULL) outofmem(__FILE__, "parse_address_part"); ref->name = NULL; @@ -163,7 +164,7 @@ PRIVATE UserDefList *parse_user_part ARGS1(FILE *, fp) user_def_list = HTList_new(); for (;;) { - Ref *ref = (Ref*)calloc(1, sizeof(Ref)); + Ref *ref = typecalloc(Ref); if (ref == NULL) outofmem(__FILE__, "parse_user_part"); ref->name = NULL; @@ -238,7 +239,7 @@ PRIVATE Item *parse_item ARGS1(FILE *, fp) syntax_error(fp, "Empty item not allowed", lex_item); return NULL; } - item = (Item*)calloc(1, sizeof(Item)); + item = typecalloc(Item); if (item == NULL) outofmem(__FILE__, "parse_item"); item->user_def_list = user_def_list; @@ -287,7 +288,7 @@ PUBLIC GroupDef *HTAA_parseGroupDef ARGS1(FILE *, fp) if (!(item_list = parse_item_list(fp))) { return NULL; } - group_def = (GroupDef*)calloc(1, sizeof(GroupDef)); + group_def = typecalloc(GroupDef); if (group_def == NULL) outofmem(__FILE__, "HTAA_parseGroupDef"); group_def->group_name = NULL; @@ -506,8 +507,8 @@ PRIVATE BOOL part_match ARGS2(CONST char *, tcur, actual[cnt] = (char)0; status = HTAA_templateMatch(required, actual); - CTRACE(tfp, "part_match: req: '%s' act: '%s' match: %s\n", - required, actual, (status ? "yes" : "no")); + CTRACE((tfp, "part_match: req: '%s' act: '%s' match: %s\n", + required, actual, (status ? "yes" : "no"))); return status; } @@ -660,25 +661,25 @@ PUBLIC GroupDefList *HTAA_readGroupFile ARGS1(CONST char *, filename) while (NULL != (group_cache = (GroupCache*)HTList_nextObject(cur))) { if (!strcmp(filename, group_cache->group_filename)) { - CTRACE(tfp, "%s '%s' %s\n", + CTRACE((tfp, "%s '%s' %s\n", "HTAA_readGroupFile: group file", - filename, "already found in cache"); + filename, "already found in cache")); return group_cache->group_list; } /* if cache match */ } /* while cached files remain */ } /* cache exists */ - CTRACE(tfp, "HTAA_readGroupFile: reading group file `%s'\n", - filename); + CTRACE((tfp, "HTAA_readGroupFile: reading group file `%s'\n", + filename)); - if (!(fp = fopen(filename, "r"))) { - CTRACE(tfp, "%s '%s'\n", + if (!(fp = fopen(filename, TXT_R))) { + CTRACE((tfp, "%s '%s'\n", "HTAA_readGroupFile: unable to open group file", - filename); + filename)); return NULL; } - if (!(group_cache = (GroupCache*)calloc(1, sizeof(GroupCache)))) + if ((group_cache = typecalloc(GroupCache)) == 0) outofmem(__FILE__, "HTAA_readGroupFile"); group_cache->group_filename = NULL; @@ -687,7 +688,7 @@ PUBLIC GroupDefList *HTAA_readGroupFile ARGS1(CONST char *, filename) HTList_addObject(group_cache_list, (void*)group_cache); fclose(fp); - CTRACE(tfp, "Read group file '%s', results follow:\n", filename); + CTRACE((tfp, "Read group file '%s', results follow:\n", filename)); if (TRACE) print_group_def_list(group_cache->group_list); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTLex.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTLex.c index 59901fb3ba6..9d9412af21b 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTLex.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTLex.c @@ -43,7 +43,7 @@ PUBLIC void unlex ARGS1(LexItem, lex_item) PUBLIC LexItem lex ARGS1(FILE *, fp) { - int ch; + int ch = 0; if (fp != cache) { /* This cache doesn't work ok because the system */ cache = fp; /* often assign same FILE structure the next open */ @@ -89,7 +89,7 @@ PUBLIC LexItem lex ARGS1(FILE *, fp) } break; default: - HTlex_buffer[lex_cnt++] = ch; + HTlex_buffer[lex_cnt++] = (char) ch; HTlex_buffer[lex_cnt] = '\0'; if ('*' == ch) lex_template = YES; } /* switch ch */ @@ -119,10 +119,10 @@ PUBLIC char *lex_verbose ARGS1(LexItem, lex_item) case LEX_AT_SIGN: /* Address qualifier */ return "address qualifier '@'"; case LEX_ALPH_STR: /* Alphanumeric string */ - sprintf(msg, "alphanumeric string '%s'", HTlex_buffer); + sprintf(msg, "alphanumeric string '%.70s'", HTlex_buffer); return msg; case LEX_TMPL_STR: /* Template string */ - sprintf(msg, "template string '%s'", HTlex_buffer); + sprintf(msg, "template string '%.70s'", HTlex_buffer); return msg; default: return "UNKNOWN-LEX-ITEM"; diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTList.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTList.c index 3ea533697b9..90871f901ad 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTList.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTList.c @@ -17,8 +17,8 @@ PUBLIC HTList * HTList_new NOARGS { HTList *newList; - if ((newList = (HTList *)calloc(1, sizeof(HTList))) == NULL) - outofmem(__FILE__, "HTList_new"); + if ((newList = typecalloc(HTList)) == NULL) + outofmem(__FILE__, "HTList_new"); newList->object = NULL; newList->next = NULL; @@ -71,9 +71,9 @@ PUBLIC HTList * HTList_appendList ARGS2( HTList * temp = start; if (!start) { - CTRACE(tfp, "HTList: Trying to append list %p to a nonexisting list\n", - tail); - return NULL; + CTRACE((tfp, "HTList: Trying to append list %p to a nonexisting list\n", + tail)); + return NULL; } if (!(tail && tail->next)) return start; @@ -96,15 +96,15 @@ PUBLIC void HTList_addObject ARGS2( HTList *newNode; if (me) { - if ((newNode = (HTList *)calloc(1, sizeof(HTList))) == NULL) + if ((newNode = typecalloc(HTList)) == NULL) outofmem(__FILE__, "HTList_addObject"); newNode->object = newObject; newNode->next = me->next; me->next = newNode; } else { - CTRACE(tfp, "HTList: Trying to add object %p to a nonexisting list\n", - newObject); + CTRACE((tfp, "HTList: Trying to add object %p to a nonexisting list\n", + newObject)); } return; @@ -144,32 +144,32 @@ PUBLIC void HTList_insertObjectAt ARGS3( int Pos = pos; if (!temp) { - CTRACE(tfp, "HTList: Trying to add object %p to a nonexisting list\n", - newObject); + CTRACE((tfp, "HTList: Trying to add object %p to a nonexisting list\n", + newObject)); return; } if (Pos < 0) { Pos = 0; - CTRACE(tfp, "HTList: Treating negative object position %d as %d.\n", - pos, Pos); + CTRACE((tfp, "HTList: Treating negative object position %d as %d.\n", + pos, Pos)); } prevNode = temp; while ((temp = temp->next)) { if (Pos == 0) { - if ((newNode = (HTList *)calloc(1, sizeof(HTList))) == NULL) - outofmem(__FILE__, "HTList_addObjectAt"); + if ((newNode = typecalloc(HTList)) == NULL) + outofmem(__FILE__, "HTList_addObjectAt"); newNode->object = newObject; newNode->next = temp; if (prevNode) - prevNode->next = newNode; + prevNode->next = newNode; return; } prevNode = temp; Pos--; } if (Pos >= 0) - HTList_addObject(prevNode, newObject); + HTList_addObject(prevNode, newObject); return; } @@ -189,7 +189,7 @@ PUBLIC BOOL HTList_removeObject ARGS2( prevNode = temp; temp = temp->next; if (temp->object == oldObject) { - prevNode->next = temp->next; + prevNode->next = temp->next; FREE (temp); return YES; /* Success */ } @@ -241,14 +241,14 @@ PUBLIC void * HTList_removeLastObject ARGS1( void * lastObject; if (me && me->next) { - lastNode = me->next; + lastNode = me->next; lastObject = lastNode->object; me->next = lastNode->next; FREE (lastNode); return lastObject; } else { /* Empty list */ - return NULL; + return NULL; } } @@ -264,7 +264,7 @@ PUBLIC void * HTList_removeFirstObject ARGS1( void *firstObject; if (!temp) - return NULL; + return NULL; prevNode = temp; if (temp->next) { @@ -278,7 +278,7 @@ PUBLIC void * HTList_removeFirstObject ARGS1( return firstObject; } else { /* Empty list */ - return NULL; + return NULL; } } @@ -293,7 +293,7 @@ PUBLIC int HTList_count ARGS1( int count = 0; if (temp) - while ((temp = temp->next)) + while ((temp = temp->next)) count++; return count; @@ -313,7 +313,7 @@ PUBLIC int HTList_indexOf ARGS2( if (temp) { while ((temp = temp->next)) { if (temp->object == object) - return position; + return position; position++; } } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.c index 46b0e6283f4..6d4ec71e0a9 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.c @@ -13,6 +13,7 @@ */ #include <HTUtils.h> #include <HTMIME.h> /* Implemented here */ +#include <HTTP.h> /* for redirecting_url */ #include <HTAlert.h> #include <HTCJK.h> #include <UCMap.h> @@ -26,13 +27,12 @@ #include <LYLeaks.h> extern BOOL HTPassEightBitRaw; -extern HTCJKlang HTCJK; /* MIME Object ** ----------- */ -typedef enum _MIME_state { +typedef enum { MIME_TRANSPARENT, /* put straight through to target ASAP! */ miBEGINNING_OF_LINE, /* first character and not a continuation */ miA, @@ -100,12 +100,12 @@ typedef enum _MIME_state { miJUNK_LINE, /* Ignore the rest of this folded line */ miNEWLINE, /* Just found a LF .. maybe continuation */ miCHECK, /* check against check_pointer */ - MIME_NET_ASCII, /* Translate from net ascii */ + MIME_NET_ASCII, /* Translate from net ascii */ MIME_IGNORE /* Ignore entire file */ /* TRANSPARENT and IGNORE are defined as stg else in _WINDOWS */ } MIME_state; -#define VALUE_SIZE 5120 /* @@@@@@@ Arbitrary? */ +#define VALUE_SIZE 5120 /* @@@@@@@ Arbitrary? */ struct _HTStream { CONST HTStreamClass * isa; @@ -114,22 +114,26 @@ struct _HTStream { MIME_state if_ok; /* got this state if match */ MIME_state field; /* remember which field */ MIME_state fold_state; /* state on a fold */ + BOOL head_only; /* only parsing header */ + BOOL pickup_redirection; /* parsing for location */ + BOOL no_streamstack; /* use sink directly */ CONST char * check_pointer; /* checking input */ char * value_pointer; /* storing values */ char value[VALUE_SIZE]; - HTParentAnchor * anchor; /* Given on creation */ + HTParentAnchor * anchor; /* Given on creation */ HTStream * sink; /* Given on creation */ char * boundary; /* For multipart */ char * set_cookie; /* Set-Cookie */ char * set_cookie2; /* Set-Cookie2 */ + char * location; /* Location */ HTFormat encoding; /* Content-Transfer-Encoding */ char * compression_encoding; - HTFormat format; /* Content-Type */ - HTStream * target; /* While writing out */ + HTFormat format; /* Content-Type */ + HTStream * target; /* While writing out */ HTStreamClass targetClass; HTAtom * targetRep; /* Converting into? */ @@ -143,7 +147,7 @@ struct _HTStream { ** first and last characters are double-quotes. - FM */ PUBLIC void HTMIME_TrimDoubleQuotes ARGS1( - char *, value) + char *, value) { int i; char *cp = value; @@ -161,6 +165,747 @@ PUBLIC void HTMIME_TrimDoubleQuotes ARGS1( value[i] = cp[(i +1)]; } +PRIVATE int pumpData ARGS1(HTStream *, me) +{ + if (strchr(HTAtom_name(me->format), ';') != NULL) { + char *cp = NULL, *cp1, *cp2, *cp3 = NULL, *cp4; + + CTRACE((tfp, "HTMIME: Extended MIME Content-Type is %s\n", + HTAtom_name(me->format))); + StrAllocCopy(cp, HTAtom_name(me->format)); + /* + ** Note that the Content-Type value was converted + ** to lower case when we loaded into me->format, + ** but there may have been a mixed or upper-case + ** atom, so we'll force lower-casing again. We + ** also stripped spaces and double-quotes, but + ** we'll make sure they're still gone from any + ** charset parameter we check. - FM + */ + LYLowerCase(cp); + if ((cp1 = strchr(cp, ';')) != NULL) { + BOOL chartrans_ok = NO; + if ((cp2 = strstr(cp1, "charset")) != NULL) { + int chndl; + + cp2 += 7; + while (*cp2 == ' ' || *cp2 == '=' || *cp2 == '\"') + cp2++; + StrAllocCopy(cp3, cp2); /* copy to mutilate more */ + for (cp4 = cp3; (*cp4 != '\0' && *cp4 != '\"' && + *cp4 != ';' && *cp4 != ':' && + !WHITE(*cp4)); cp4++) + ; /* do nothing */ + *cp4 = '\0'; + cp4 = cp3; + chndl = UCGetLYhndl_byMIME(cp3); + if (UCCanTranslateFromTo(chndl, + current_char_set)) { + chartrans_ok = YES; + *cp1 = '\0'; + me->format = HTAtom_for(cp); + StrAllocCopy(me->anchor->charset, cp4); + HTAnchor_setUCInfoStage(me->anchor, chndl, + UCT_STAGE_MIME, + UCT_SETBY_MIME); + } + else if (chndl < 0) {/* got something but we don't + recognize it */ + chndl = UCLYhndl_for_unrec; + if (chndl < 0) + /* + ** UCLYhndl_for_unrec not defined :-( + ** fallback to UCLYhndl_for_unspec + ** which always valid. + */ + chndl = UCLYhndl_for_unspec; /* always >= 0 */ + if (UCCanTranslateFromTo(chndl, + current_char_set)) { + chartrans_ok = YES; + *cp1 = '\0'; + me->format = HTAtom_for(cp); + HTAnchor_setUCInfoStage(me->anchor, chndl, + UCT_STAGE_MIME, + UCT_SETBY_DEFAULT); + } + } + if (chartrans_ok) { + LYUCcharset * p_in = + HTAnchor_getUCInfoStage(me->anchor, + UCT_STAGE_MIME); + LYUCcharset * p_out = + HTAnchor_setUCInfoStage(me->anchor, + current_char_set, + UCT_STAGE_HTEXT, + UCT_SETBY_DEFAULT); + if (!p_out) + /* + ** Try again. + */ + p_out = + HTAnchor_getUCInfoStage(me->anchor, + UCT_STAGE_HTEXT); + + if (!strcmp(p_in->MIMEname, + "x-transparent")) { + HTPassEightBitRaw = TRUE; + HTAnchor_setUCInfoStage(me->anchor, + HTAnchor_getUCLYhndl(me->anchor, + UCT_STAGE_HTEXT), + UCT_STAGE_MIME, + UCT_SETBY_DEFAULT); + } + if (!strcmp(p_out->MIMEname, + "x-transparent")) { + HTPassEightBitRaw = TRUE; + HTAnchor_setUCInfoStage(me->anchor, + HTAnchor_getUCLYhndl(me->anchor, + UCT_STAGE_MIME), + UCT_STAGE_HTEXT, + UCT_SETBY_DEFAULT); + } + if (p_in->enc != UCT_ENC_CJK) { + HTCJK = NOCJK; + if (!(p_in->codepoints & + UCT_CP_SUBSETOF_LAT1) && + chndl == current_char_set) { + HTPassEightBitRaw = TRUE; + } + } else if (p_out->enc == UCT_ENC_CJK) { + Set_HTCJK(p_in->MIMEname, p_out->MIMEname); + } + } else { + /* + ** Cannot translate. + ** If according to some heuristic the given + ** charset and the current display character + ** both are likely to be like ISO-8859 in + ** structure, pretend we have some kind + ** of match. + */ + BOOL given_is_8859 + = (BOOL) (!strncmp(cp4, "iso-8859-", 9) && + isdigit(UCH(cp4[9]))); + BOOL given_is_8859like + = (BOOL) (given_is_8859 || + !strncmp(cp4, "windows-", 8) || + !strncmp(cp4, "cp12", 4) || + !strncmp(cp4, "cp-12", 5)); + BOOL given_and_display_8859like + = (BOOL) (given_is_8859like && + (strstr(LYchar_set_names[current_char_set], + "ISO-8859") || + strstr(LYchar_set_names[current_char_set], + "windows-"))); + + if (given_and_display_8859like) { + *cp1 = '\0'; + me->format = HTAtom_for(cp); + } + if (given_is_8859) { + cp1 = &cp4[10]; + while (*cp1 && + isdigit(UCH(*cp1))) + cp1++; + *cp1 = '\0'; + } + if (given_and_display_8859like) { + StrAllocCopy(me->anchor->charset, cp4); + HTPassEightBitRaw = TRUE; + } + HTAlert(*cp4 ? cp4 : me->anchor->charset); + } + FREE(cp3); + } else { + /* + ** No charset parameter is present. + ** Ignore all other parameters, as + ** we do when charset is present. - FM + */ + *cp1 = '\0'; + me->format = HTAtom_for(cp); + } + } + FREE(cp); + } + /* + ** If we have an Expires header and haven't + ** already set the no_cache element for the + ** anchor, check if we should set it based + ** on that header. - FM + */ + if (me->anchor->no_cache == FALSE && + me->anchor->expires != NULL) { + if (!strcmp(me->anchor->expires, "0")) { + /* + * The value is zero, which we treat as + * an absolute no-cache directive. - FM + */ + me->anchor->no_cache = TRUE; + } else if (me->anchor->date != NULL) { + /* + ** We have a Date header, so check if + ** the value is less than or equal to + ** that. - FM + */ + if (LYmktime(me->anchor->expires, TRUE) <= + LYmktime(me->anchor->date, TRUE)) { + me->anchor->no_cache = TRUE; + } + } else if (LYmktime(me->anchor->expires, FALSE) <= 0) { + /* + ** We don't have a Date header, and + ** the value is in past for us. - FM + */ + me->anchor->no_cache = TRUE; + } + } + StrAllocCopy(me->anchor->content_type, + HTAtom_name(me->format)); + + if (me->set_cookie != NULL || me->set_cookie2 != NULL) { + LYSetCookie(me->set_cookie, + me->set_cookie2, + me->anchor->address); + FREE(me->set_cookie); + FREE(me->set_cookie2); + } + if (me->pickup_redirection) { + if (me->location && *me->location) { + redirecting_url = me->location; + me->location = NULL; + if (me->targetRep != WWW_DEBUG || me->sink) + me->head_only = YES; + + } else { + permanent_redirection = FALSE; + if (me->location) { + CTRACE((tfp, "HTTP: 'Location:' is zero-length!\n")); + HTAlert(REDIRECTION_WITH_BAD_LOCATION); + } + CTRACE((tfp, "HTTP: Failed to pick up location.\n")); + if (me->location) { + FREE(me->location); + } else { + HTAlert(REDIRECTION_WITH_NO_LOCATION); + } + } + } + if (me->head_only) { + /* We are done! - kw */ + me->state = MIME_IGNORE; + return HT_OK; + } + + if (me->no_streamstack) { + me->target = me->sink; + } else { + if (!me->compression_encoding) { + CTRACE((tfp, "HTMIME: MIME Content-Type is '%s', converting to '%s'\n", + HTAtom_name(me->format), HTAtom_name(me->targetRep))); + } else { + /* + ** Change the format to that for "www/compressed" + ** and set up a stream to deal with it. - FM + */ + CTRACE((tfp, "HTMIME: MIME Content-Type is '%s',\n", HTAtom_name(me->format))); + me->format = HTAtom_for("www/compressed"); + CTRACE((tfp, " Treating as '%s'. Converting to '%s'\n", + HTAtom_name(me->format), HTAtom_name(me->targetRep))); + FREE(me->compression_encoding); + } + me->target = HTStreamStack(me->format, me->targetRep, + me->sink , me->anchor); + if (!me->target) { + CTRACE((tfp, "HTMIME: Can't translate! ** \n")); + me->target = me->sink; /* Cheat */ + } + } + if (me->target) { + me->targetClass = *me->target->isa; + /* + ** Check for encoding and select state from there, + ** someday, but until we have the relevant code, + ** from now push straight through. - FM + */ + me->state = MIME_TRANSPARENT; /* Pump rest of data right through */ + } else { + me->state = MIME_IGNORE; /* What else to do? */ + } + return HT_OK; +} + +PRIVATE int dispatchField ARGS1(HTStream *, me) +{ + int i, j; + char *cp; + + *me->value_pointer = '\0'; + cp = me->value_pointer; + while ((cp > me->value) && *(--cp) == ' ') /* S/390 -- gil -- 0146 */ + /* + ** Trim trailing spaces. + */ + *cp = '\0'; + + switch (me->field) { + case miACCEPT_RANGES: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Accept-Ranges: '%s'\n", + me->value)); + break; + case miAGE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Age: '%s'\n", + me->value)); + break; + case miALLOW: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Allow: '%s'\n", + me->value)); + break; + case miALTERNATES: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Alternates: '%s'\n", + me->value)); + break; + case miCACHE_CONTROL: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Cache-Control: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Convert to lowercase and indicate in anchor. - FM + */ + LYLowerCase(me->value); + StrAllocCopy(me->anchor->cache_control, me->value); + /* + ** Check whether to set no_cache for the anchor. - FM + */ + { + char *cp1, *cp0 = me->value; + + while ((cp1 = strstr(cp0, "no-cache")) != NULL) { + cp1 += 8; + while (*cp1 != '\0' && WHITE(*cp1)) + cp1++; + if (*cp1 == '\0' || *cp1 == ';') { + me->anchor->no_cache = TRUE; + break; + } + cp0 = cp1; + } + if (me->anchor->no_cache == TRUE) + break; + cp0 = me->value; + while ((cp1 = strstr(cp0, "max-age")) != NULL) { + cp1 += 7; + while (*cp1 != '\0' && WHITE(*cp1)) + cp1++; + if (*cp1 == '=') { + cp1++; + while (*cp1 != '\0' && WHITE(*cp1)) + cp1++; + if (isdigit(UCH(*cp1))) { + cp0 = cp1; + while (isdigit(UCH(*cp1))) + cp1++; + if (*cp0 == '0' && cp1 == (cp0 + 1)) { + me->anchor->no_cache = TRUE; + break; + } + } + } + cp0 = cp1; + } + } + break; + case miCOOKIE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Cookie: '%s'\n", + me->value)); + break; + case miCONNECTION: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Connection: '%s'\n", + me->value)); + break; + case miCONTENT_BASE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Base: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->content_base, me->value); + break; + case miCONTENT_DISPOSITION: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Disposition: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->content_disposition, me->value); + /* + ** It's not clear yet from existing RFCs and IDs + ** whether we should be looking for file;, attachment;, + ** and/or inline; before the filename=value, so we'll + ** just search for "filename" followed by '=' and just + ** hope we get the intended value. It is purely a + ** suggested name, anyway. - FM + */ + cp = me->anchor->content_disposition; + while (*cp != '\0' && strncasecomp(cp, "filename", 8)) + cp++; + if (*cp == '\0') + break; + cp += 8; + while ((*cp != '\0') && (WHITE(*cp) || *cp == '=')) + cp++; + if (*cp == '\0') + break; + while (*cp != '\0' && WHITE(*cp)) + cp++; + if (*cp == '\0') + break; + StrAllocCopy(me->anchor->SugFname, cp); + if (*me->anchor->SugFname == '\"') { + if ((cp = strchr((me->anchor->SugFname + 1), + '\"')) != NULL) { + *(cp + 1) = '\0'; + HTMIME_TrimDoubleQuotes(me->anchor->SugFname); + } else { + FREE(me->anchor->SugFname); + break; + } + } + cp = me->anchor->SugFname; + while (*cp != '\0' && !WHITE(*cp)) + cp++; + *cp = '\0'; + if (*me->anchor->SugFname == '\0') + FREE(me->anchor->SugFname); + break; + case miCONTENT_ENCODING: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Encoding: '%s'\n", + me->value)); + if (!(me->value && *me->value) || + !strcasecomp(me->value, "identity")) + break; + /* + ** Convert to lowercase and indicate in anchor. - FM + */ + LYLowerCase(me->value); + StrAllocCopy(me->anchor->content_encoding, me->value); + FREE(me->compression_encoding); + if (!strcmp(me->value, "8bit") || + !strcmp(me->value, "7bit") || + !strcmp(me->value, "binary")) { + /* + ** Some server indicated "8bit", "7bit" or "binary" + ** inappropriately. We'll ignore it. - FM + */ + CTRACE((tfp, " Ignoring it!\n")); + } else { + /* + ** Save it to use as a flag for setting + ** up a "www/compressed" target. - FM + */ + StrAllocCopy(me->compression_encoding, me->value); + } + break; + case miCONTENT_FEATURES: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Features: '%s'\n", + me->value)); + break; + case miCONTENT_LANGUAGE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Language: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Convert to lowercase and indicate in anchor. - FM + */ + LYLowerCase(me->value); + StrAllocCopy(me->anchor->content_language, me->value); + break; + case miCONTENT_LENGTH: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Length: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Convert to integer and indicate in anchor. - FM + */ + me->anchor->content_length = atoi(me->value); + if (me->anchor->content_length < 0) + me->anchor->content_length = 0; + CTRACE((tfp, " Converted to integer: '%d'\n", + me->anchor->content_length)); + break; + case miCONTENT_LOCATION: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Location: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->content_location, me->value); + break; + case miCONTENT_MD5: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-MD5: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->content_md5, me->value); + break; + case miCONTENT_RANGE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Range: '%s'\n", + me->value)); + break; + case miCONTENT_TRANSFER_ENCODING: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Transfer-Encoding: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Force the Content-Transfer-Encoding value + ** to all lower case. - FM + */ + LYLowerCase(me->value); + me->encoding = HTAtom_for(me->value); + break; + case miCONTENT_TYPE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Content-Type: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Force the Content-Type value to all lower case + ** and strip spaces and double-quotes. - FM + */ + for (i = 0, j = 0; me->value[i]; i++) { + if (me->value[i] != ' ' && me->value[i] != '\"') { + me->value[j++] = (char) TOLOWER(me->value[i]); + } + } + me->value[j] = '\0'; + me->format = HTAtom_for(me->value); + break; + case miDATE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Date: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->date, me->value); + break; + case miETAG: + /* Do not trim double quotes: + * an entity tag consists of an opaque quoted string, + * possibly prefixed by a weakness indicator. + */ + CTRACE((tfp, "HTMIME: PICKED UP ETag: %s\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->ETag, me->value); + break; + case miEXPIRES: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Expires: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->expires, me->value); + break; + case miKEEP_ALIVE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Keep-Alive: '%s'\n", + me->value)); + break; + case miLAST_MODIFIED: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Last-Modified: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->last_modified, me->value); + break; + case miLINK: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Link: '%s'\n", + me->value)); + break; + case miLOCATION: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Location: '%s'\n", + me->value)); + if (me->pickup_redirection && !me->location) { + StrAllocCopy(me->location, me->value); + } else { + CTRACE((tfp, "HTMIME: *** Ignoring Location!\n")); + } + break; + case miPRAGMA: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Pragma: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Check whether to set no_cache for the anchor. - FM + */ + if (!strcmp(me->value, "no-cache")) + me->anchor->no_cache = TRUE; + break; + case miPROXY_AUTHENTICATE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Proxy-Authenticate: '%s'\n", + me->value)); + break; + case miPUBLIC: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Public: '%s'\n", + me->value)); + break; + case miRETRY_AFTER: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Retry-After: '%s'\n", + me->value)); + break; + case miSAFE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Safe: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor if "YES" or "TRUE". - FM + */ + if (!strcasecomp(me->value, "YES") || + !strcasecomp(me->value, "TRUE")) { + me->anchor->safe = TRUE; + } else if (!strcasecomp(me->value, "NO") || + !strcasecomp(me->value, "FALSE")) { + /* + ** If server explicitly tells us that it has changed + ** its mind, reset flag in anchor. - kw + */ + me->anchor->safe = FALSE; + } + break; + case miSERVER: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Server: '%s'\n", + me->value)); + if (!(me->value && *me->value)) + break; + /* + ** Indicate in anchor. - FM + */ + StrAllocCopy(me->anchor->server, me->value); + break; + case miSET_COOKIE1: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Set-Cookie: '%s'\n", + me->value)); + if (me->set_cookie == NULL) { + StrAllocCopy(me->set_cookie, me->value); + } else { + StrAllocCat(me->set_cookie, ", "); + StrAllocCat(me->set_cookie, me->value); + } + break; + case miSET_COOKIE2: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Set-Cookie2: '%s'\n", + me->value)); + if (me->set_cookie2 == NULL) { + StrAllocCopy(me->set_cookie2, me->value); + } else { + StrAllocCat(me->set_cookie2, ", "); + StrAllocCat(me->set_cookie2, me->value); + } + break; + case miTITLE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Title: '%s'\n", + me->value)); + break; + case miTRANSFER_ENCODING: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Transfer-Encoding: '%s'\n", + me->value)); + break; + case miUPGRADE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Upgrade: '%s'\n", + me->value)); + break; + case miURI: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP URI: '%s'\n", + me->value)); + break; + case miVARY: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Vary: '%s'\n", + me->value)); + break; + case miVIA: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Via: '%s'\n", + me->value)); + break; + case miWARNING: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP Warning: '%s'\n", + me->value)); + break; + case miWWW_AUTHENTICATE: + HTMIME_TrimDoubleQuotes(me->value); + CTRACE((tfp, "HTMIME: PICKED UP WWW-Authenticate: '%s'\n", + me->value)); + break; + default: /* Should never get here */ + return HT_ERROR; + } + return HT_OK; +} + + /*_________________________________________________________________________ ** ** A C T I O N R O U T I N E S @@ -169,16 +914,15 @@ PUBLIC void HTMIME_TrimDoubleQuotes ARGS1( /* Character handling ** ------------------ ** -** This is a FSM parser which is tolerant as it can be of all -** syntax errors. It ignores field names it does not understand, -** and resynchronises on line beginnings. +** This is a FSM parser. It ignores field names it does not understand. +** Folded header fields are recognized. Lines without a fieldname at +** the beginning (that are not folded continuation lines) are ignored +** as unknown field names. Fields with empty values are not picked up. */ PRIVATE void HTMIME_put_character ARGS2( HTStream *, me, char, c) { - int i, j; - if (me->state == MIME_TRANSPARENT) { (*me->targetClass.put_character)(me->target, c);/* MUST BE FAST */ return; @@ -223,10 +967,19 @@ PRIVATE void HTMIME_put_character ARGS2( case miNEWLINE: if (c != '\n' && WHITE(c)) { /* Folded line */ me->state = me->fold_state; /* pop state before newline */ + if (me->state == miGET_VALUE && + me->value_pointer && me->value_pointer != me->value && + !WHITE(*(me->value_pointer-1))) { + c = ' '; + goto GET_VALUE; /* will add space to value if it fits - kw */ + } break; + } else if (me->fold_state == miGET_VALUE) { + /* Got a field, and now we know it's complete - so + * act on it. - kw */ + dispatchField(me); } - - /* else Falls through */ + /* FALLTHRU */ case miBEGINNING_OF_LINE: me->net_ascii = YES; @@ -234,13 +987,13 @@ PRIVATE void HTMIME_put_character ARGS2( case 'a': case 'A': me->state = miA; - CTRACE(tfp, "HTMIME: Got 'A' at beginning of line, state now A\n"); + CTRACE((tfp, "HTMIME: Got 'A' at beginning of line, state now A\n")); break; case 'c': case 'C': me->state = miC; - CTRACE (tfp, "HTMIME: Got 'C' at beginning of line, state now C\n"); + CTRACE((tfp, "HTMIME: Got 'C' at beginning of line, state now C\n")); break; case 'd': @@ -248,13 +1001,13 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ate:"; me->if_ok = miDATE; me->state = miCHECK; - CTRACE (tfp, "HTMIME: Got 'D' at beginning of line, checking for 'ate:'\n"); + CTRACE((tfp, "HTMIME: Got 'D' at beginning of line, checking for 'ate:'\n")); break; case 'e': case 'E': me->state = miE; - CTRACE (tfp, "HTMIME: Got 'E' at beginning of line, state now E\n"); + CTRACE((tfp, "HTMIME: Got 'E' at beginning of line, state now E\n")); break; case 'k': @@ -262,19 +1015,19 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "eep-alive:"; me->if_ok = miKEEP_ALIVE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Got 'K' at beginning of line, checking for 'eep-alive:'\n"); + CTRACE((tfp, "HTMIME: Got 'K' at beginning of line, checking for 'eep-alive:'\n")); break; case 'l': case 'L': me->state = miL; - CTRACE (tfp, "HTMIME: Got 'L' at beginning of line, state now L\n"); + CTRACE((tfp, "HTMIME: Got 'L' at beginning of line, state now L\n")); break; case 'p': case 'P': me->state = miP; - CTRACE (tfp, "HTMIME: Got 'P' at beginning of line, state now P\n"); + CTRACE((tfp, "HTMIME: Got 'P' at beginning of line, state now P\n")); break; case 'r': @@ -282,275 +1035,43 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "etry-after:"; me->if_ok = miRETRY_AFTER; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Got 'R' at beginning of line, checking for 'etry-after'\n"); + CTRACE((tfp, "HTMIME: Got 'R' at beginning of line, checking for 'etry-after'\n")); break; case 's': case 'S': me->state = miS; - CTRACE (tfp, "HTMIME: Got 'S' at beginning of line, state now S\n"); + CTRACE((tfp, "HTMIME: Got 'S' at beginning of line, state now S\n")); break; case 't': case 'T': me->state = miT; - CTRACE (tfp, "HTMIME: Got 'T' at beginning of line, state now T\n"); + CTRACE((tfp, "HTMIME: Got 'T' at beginning of line, state now T\n")); break; case 'u': case 'U': me->state = miU; - CTRACE (tfp, "HTMIME: Got 'U' at beginning of line, state now U\n"); + CTRACE((tfp, "HTMIME: Got 'U' at beginning of line, state now U\n")); break; case 'v': case 'V': me->state = miV; - CTRACE (tfp, "HTMIME: Got 'V' at beginning of line, state now V\n"); + CTRACE((tfp, "HTMIME: Got 'V' at beginning of line, state now V\n")); break; case 'w': case 'W': me->state = miW; - CTRACE (tfp, "HTMIME: Got 'W' at beginning of line, state now W\n"); + CTRACE((tfp, "HTMIME: Got 'W' at beginning of line, state now W\n")); break; case '\n': /* Blank line: End of Header! */ { me->net_ascii = NO; - if (strchr(HTAtom_name(me->format), ';') != NULL) { - char *cp = NULL, *cp1, *cp2, *cp3 = NULL, *cp4; - - CTRACE(tfp, "HTMIME: Extended MIME Content-Type is %s\n", - HTAtom_name(me->format)); - StrAllocCopy(cp, HTAtom_name(me->format)); - /* - ** Note that the Content-Type value was converted - ** to lower case when we loaded into me->format, - ** but there may have been a mixed or upper-case - ** atom, so we'll force lower-casing again. We - ** also stripped spaces and double-quotes, but - ** we'll make sure they're still gone from any - ** charset parameter we check. - FM - */ - LYLowerCase(cp); - if ((cp1 = strchr(cp, ';')) != NULL) { - BOOL chartrans_ok = NO; - if ((cp2 = strstr(cp1, "charset")) != NULL) { - int chndl; - - cp2 += 7; - while (*cp2 == ' ' || *cp2 == '=' || *cp2 == '\"') - cp2++; - StrAllocCopy(cp3, cp2); /* copy to mutilate more */ - for (cp4 = cp3; (*cp4 != '\0' && *cp4 != '\"' && - *cp4 != ';' && *cp4 != ':' && - !WHITE(*cp4)); cp4++) - ; /* do nothing */ - *cp4 = '\0'; - cp4 = cp3; - chndl = UCGetLYhndl_byMIME(cp3); - if (UCCanTranslateFromTo(chndl, - current_char_set)) { - chartrans_ok = YES; - *cp1 = '\0'; - me->format = HTAtom_for(cp); - StrAllocCopy(me->anchor->charset, cp4); - HTAnchor_setUCInfoStage(me->anchor, chndl, - UCT_STAGE_MIME, - UCT_SETBY_MIME); - } - else if (chndl < 0) {/* got something but we don't - recognize it */ - chndl = UCLYhndl_for_unrec; - if (chndl < 0) - /* - ** UCLYhndl_for_unrec not defined :-( - ** fallback to UCLYhndl_for_unspec - ** which always valid. - */ - chndl = UCLYhndl_for_unspec; /* always >= 0 */ - if (UCCanTranslateFromTo(chndl, - current_char_set)) { - chartrans_ok = YES; - *cp1 = '\0'; - me->format = HTAtom_for(cp); - HTAnchor_setUCInfoStage(me->anchor, chndl, - UCT_STAGE_MIME, - UCT_SETBY_DEFAULT); - } - } - if (chartrans_ok) { - LYUCcharset * p_in = - HTAnchor_getUCInfoStage(me->anchor, - UCT_STAGE_MIME); - LYUCcharset * p_out = - HTAnchor_setUCInfoStage(me->anchor, - current_char_set, - UCT_STAGE_HTEXT, - UCT_SETBY_DEFAULT); - if (!p_out) - /* - ** Try again. - */ - p_out = - HTAnchor_getUCInfoStage(me->anchor, - UCT_STAGE_HTEXT); - - if (!strcmp(p_in->MIMEname, - "x-transparent")) { - HTPassEightBitRaw = TRUE; - HTAnchor_setUCInfoStage(me->anchor, - HTAnchor_getUCLYhndl(me->anchor, - UCT_STAGE_HTEXT), - UCT_STAGE_MIME, - UCT_SETBY_DEFAULT); - } - if (!strcmp(p_out->MIMEname, - "x-transparent")) { - HTPassEightBitRaw = TRUE; - HTAnchor_setUCInfoStage(me->anchor, - HTAnchor_getUCLYhndl(me->anchor, - UCT_STAGE_MIME), - UCT_STAGE_HTEXT, - UCT_SETBY_DEFAULT); - } - if (p_in->enc != UCT_ENC_CJK) { - HTCJK = NOCJK; - if (!(p_in->codepoints & - UCT_CP_SUBSETOF_LAT1) && - chndl == current_char_set) { - HTPassEightBitRaw = TRUE; - } - } else if (p_out->enc == UCT_ENC_CJK) { - Set_HTCJK(p_in->MIMEname, p_out->MIMEname); - } - } else { - /* - ** Cannot translate. - ** If according to some heuristic the given - ** charset and the current display character - ** both are likely to be like ISO-8859 in - ** structure, pretend we have some kind - ** of match. - */ - BOOL given_is_8859 - = (!strncmp(cp4, "iso-8859-", 9) && - isdigit((unsigned char)cp4[9])); - BOOL given_is_8859like - = (given_is_8859 || - !strncmp(cp4, "windows-", 8) || - !strncmp(cp4, "cp12", 4) || - !strncmp(cp4, "cp-12", 5)); - BOOL given_and_display_8859like - = (given_is_8859like && - (strstr(LYchar_set_names[current_char_set], - "ISO-8859") || - strstr(LYchar_set_names[current_char_set], - "windows-"))); - - if (given_and_display_8859like) { - *cp1 = '\0'; - me->format = HTAtom_for(cp); - } - if (given_is_8859) { - cp1 = &cp4[10]; - while (*cp1 && - isdigit((unsigned char)(*cp1))) - cp1++; - *cp1 = '\0'; - } - if (given_and_display_8859like) { - StrAllocCopy(me->anchor->charset, cp4); - HTPassEightBitRaw = TRUE; - } - HTAlert(*cp4 ? cp4 : me->anchor->charset); - } - FREE(cp3); - } else { - /* - ** No charset parameter is present. - ** Ignore all other parameters, as - ** we do when charset is present. - FM - */ - *cp1 = '\0'; - me->format = HTAtom_for(cp); - } - } - FREE(cp); - } - /* - ** If we have an Expires header and haven't - ** already set the no_cache element for the - ** anchor, check if we should set it based - ** on that header. - FM - */ - if (me->anchor->no_cache == FALSE && - me->anchor->expires != NULL) { - if (!strcmp(me->anchor->expires, "0")) { - /* - * The value is zero, which we treat as - * an absolute no-cache directive. - FM - */ - me->anchor->no_cache = TRUE; - } else if (me->anchor->date != NULL) { - /* - ** We have a Date header, so check if - ** the value is less than or equal to - ** that. - FM - */ - if (LYmktime(me->anchor->expires, TRUE) <= - LYmktime(me->anchor->date, TRUE)) { - me->anchor->no_cache = TRUE; - } - } else if (LYmktime(me->anchor->expires, FALSE) <= 0) { - /* - ** We don't have a Date header, and - ** the value is in past for us. - FM - */ - me->anchor->no_cache = TRUE; - } - } - StrAllocCopy(me->anchor->content_type, - HTAtom_name(me->format)); - if (!me->compression_encoding) { - CTRACE(tfp, "HTMIME: MIME Content-Type is '%s', converting to '%s'\n", - HTAtom_name(me->format), HTAtom_name(me->targetRep)); - } else { - /* - ** Change the format to that for "www/compressed" - ** and set up a stream to deal with it. - FM - */ - CTRACE(tfp, "HTMIME: MIME Content-Type is '%s',\n", HTAtom_name(me->format)); - me->format = HTAtom_for("www/compressed"); - CTRACE(tfp, " Treating as '%s'. Converting to '%s'\n", - HTAtom_name(me->format), HTAtom_name(me->targetRep)); - } - if (me->set_cookie != NULL || me->set_cookie2 != NULL) { - LYSetCookie(me->set_cookie, - me->set_cookie2, - me->anchor->address); - FREE(me->set_cookie); - FREE(me->set_cookie2); - } - me->target = HTStreamStack(me->format, me->targetRep, - me->sink , me->anchor); - if (!me->target) { - CTRACE(tfp, "HTMIME: Can't translate! ** \n"); - me->target = me->sink; /* Cheat */ - } - if (me->target) { - me->targetClass = *me->target->isa; - /* - ** Check for encoding and select state from there, - ** someday, but until we have the relevant code, - ** from now push straight through. - FM - */ - me->state = MIME_TRANSPARENT; - } else { - me->state = MIME_IGNORE; /* What else to do? */ - } - FREE(me->compression_encoding); + pumpData(me); } break; @@ -567,7 +1088,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "cept-ranges:"; me->if_ok = miACCEPT_RANGES; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was A, found C, checking for 'cept-ranges:'\n"); + CTRACE((tfp, "HTMIME: Was A, found C, checking for 'cept-ranges:'\n")); break; case 'g': @@ -575,18 +1096,18 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "e:"; me->if_ok = miAGE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was A, found G, checking for 'e:'\n"); + CTRACE((tfp, "HTMIME: Was A, found G, checking for 'e:'\n")); break; case 'l': case 'L': me->state = miAL; - CTRACE(tfp, "HTMIME: Was A, found L, state now AL'\n"); + CTRACE((tfp, "HTMIME: Was A, found L, state now AL'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'g' or 'l'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'g' or 'l'")); goto bad_field_name; } /* switch on character */ @@ -599,7 +1120,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ow:"; me->if_ok = miALLOW; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was AL, found L, checking for 'ow:'\n"); + CTRACE((tfp, "HTMIME: Was AL, found L, checking for 'ow:'\n")); break; case 't': @@ -607,12 +1128,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ernates:"; me->if_ok = miALTERNATES; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was AL, found T, checking for 'ernates:'\n"); + CTRACE((tfp, "HTMIME: Was AL, found T, checking for 'ernates:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'l' or 't'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'l' or 't'")); goto bad_field_name; } /* switch on character */ @@ -625,18 +1146,18 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "che-control:"; me->if_ok = miCACHE_CONTROL; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was C, found A, checking for 'che-control:'\n"); + CTRACE((tfp, "HTMIME: Was C, found A, checking for 'che-control:'\n")); break; case 'o': case 'O': me->state = miCO; - CTRACE(tfp, "HTMIME: Was C, found O, state now CO'\n"); + CTRACE((tfp, "HTMIME: Was C, found O, state now CO'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'a' or 'o'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'a' or 'o'")); goto bad_field_name; } /* switch on character */ @@ -647,7 +1168,7 @@ PRIVATE void HTMIME_put_character ARGS2( case 'n': case 'N': me->state = miCON; - CTRACE(tfp, "HTMIME: Was CO, found N, state now CON\n"); + CTRACE((tfp, "HTMIME: Was CO, found N, state now CON\n")); break; case 'o': @@ -655,25 +1176,25 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "kie:"; me->if_ok = miCOOKIE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CO, found O, checking for 'kie:'\n"); + CTRACE((tfp, "HTMIME: Was CO, found O, checking for 'kie:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'n' or 'o'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'n' or 'o'")); goto bad_field_name; } /* switch on character */ break; - case miCON: /* Check for 'n' or 't' */ + case miCON: /* Check for 'n' or 't' */ switch (c) { case 'n': case 'N': me->check_pointer = "ection:"; me->if_ok = miCONNECTION; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CON, found N, checking for 'ection:'\n"); + CTRACE((tfp, "HTMIME: Was CON, found N, checking for 'ection:'\n")); break; case 't': @@ -681,12 +1202,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ent-"; me->if_ok = miCONTENT_; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CON, found T, checking for 'ent-'\n"); + CTRACE((tfp, "HTMIME: Was CON, found T, checking for 'ent-'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'n' or 't'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'n' or 't'")); goto bad_field_name; } /* switch on character */ @@ -699,7 +1220,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ag:"; me->if_ok = miETAG; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was E, found T, checking for 'ag:'\n"); + CTRACE((tfp, "HTMIME: Was E, found T, checking for 'ag:'\n")); break; case 'x': @@ -707,12 +1228,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "pires:"; me->if_ok = miEXPIRES; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was E, found X, checking for 'pires:'\n"); + CTRACE((tfp, "HTMIME: Was E, found X, checking for 'pires:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'t' or 'x'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'t' or 'x'")); goto bad_field_name; } /* switch on character */ @@ -725,7 +1246,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "st-modified:"; me->if_ok = miLAST_MODIFIED; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was L, found A, checking for 'st-modified:'\n"); + CTRACE((tfp, "HTMIME: Was L, found A, checking for 'st-modified:'\n")); break; case 'i': @@ -733,7 +1254,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "nk:"; me->if_ok = miLINK; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was L, found I, checking for 'nk:'\n"); + CTRACE((tfp, "HTMIME: Was L, found I, checking for 'nk:'\n")); break; case 'o': @@ -741,12 +1262,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "cation:"; me->if_ok = miLOCATION; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was L, found O, checking for 'cation:'\n"); + CTRACE((tfp, "HTMIME: Was L, found O, checking for 'cation:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'a', 'i' or 'o'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'a', 'i' or 'o'")); goto bad_field_name; } /* switch on character */ @@ -757,7 +1278,7 @@ PRIVATE void HTMIME_put_character ARGS2( case 'r': case 'R': me->state = miPR; - CTRACE(tfp, "HTMIME: Was P, found R, state now PR'\n"); + CTRACE((tfp, "HTMIME: Was P, found R, state now PR'\n")); break; case 'u': @@ -765,12 +1286,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "blic:"; me->if_ok = miPUBLIC; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was P, found U, checking for 'blic:'\n"); + CTRACE((tfp, "HTMIME: Was P, found U, checking for 'blic:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'r' or 'u'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'r' or 'u'")); goto bad_field_name; } /* switch on character */ @@ -783,7 +1304,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "gma:"; me->if_ok = miPRAGMA; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was PR, found A, checking for 'gma'\n"); + CTRACE((tfp, "HTMIME: Was PR, found A, checking for 'gma'\n")); break; case 'o': @@ -791,12 +1312,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "xy-authenticate:"; me->if_ok = miPROXY_AUTHENTICATE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was PR, found O, checking for 'xy-authenticate'\n"); + CTRACE((tfp, "HTMIME: Was PR, found O, checking for 'xy-authenticate'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'a' or 'o'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'a' or 'o'")); goto bad_field_name; } /* switch on character */ @@ -809,18 +1330,18 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "fe:"; me->if_ok = miSAFE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was S, found A, checking for 'fe:'\n"); + CTRACE((tfp, "HTMIME: Was S, found A, checking for 'fe:'\n")); break; case 'e': case 'E': me->state = miSE; - CTRACE(tfp, "HTMIME: Was S, found E, state now SE'\n"); + CTRACE((tfp, "HTMIME: Was S, found E, state now SE'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'a' or 'e'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'a' or 'e'")); goto bad_field_name; } /* switch on character */ @@ -833,7 +1354,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ver:"; me->if_ok = miSERVER; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was SE, found R, checking for 'ver'\n"); + CTRACE((tfp, "HTMIME: Was SE, found R, checking for 'ver'\n")); break; case 't': @@ -841,12 +1362,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "-cookie"; me->if_ok = miSET_COOKIE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was SE, found T, checking for '-cookie'\n"); + CTRACE((tfp, "HTMIME: Was SE, found T, checking for '-cookie'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'r' or 't'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'r' or 't'")); goto bad_field_name; } /* switch on character */ @@ -857,19 +1378,19 @@ PRIVATE void HTMIME_put_character ARGS2( case ':': me->field = miSET_COOKIE1; /* remember it */ me->state = miSKIP_GET_VALUE; - CTRACE(tfp, "HTMIME: Was SET_COOKIE, found :, processing\n"); + CTRACE((tfp, "HTMIME: Was SET_COOKIE, found :, processing\n")); break; case '2': me->check_pointer = ":"; me->if_ok = miSET_COOKIE2; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was SET_COOKIE, found 2, checking for ':'\n"); + CTRACE((tfp, "HTMIME: Was SET_COOKIE, found 2, checking for ':'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "':' or '2'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "':' or '2'")); goto bad_field_name; } /* switch on character */ @@ -882,7 +1403,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "tle:"; me->if_ok = miTITLE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was T, found I, checking for 'tle:'\n"); + CTRACE((tfp, "HTMIME: Was T, found I, checking for 'tle:'\n")); break; case 'r': @@ -890,12 +1411,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ansfer-encoding:"; me->if_ok = miTRANSFER_ENCODING; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was T, found R, checking for 'ansfer-encoding'\n"); + CTRACE((tfp, "HTMIME: Was T, found R, checking for 'ansfer-encoding'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'i' or 'r'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'i' or 'r'")); goto bad_field_name; } /* switch on character */ @@ -908,7 +1429,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "grade:"; me->if_ok = miUPGRADE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was U, found P, checking for 'grade:'\n"); + CTRACE((tfp, "HTMIME: Was U, found P, checking for 'grade:'\n")); break; case 'r': @@ -916,12 +1437,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "i:"; me->if_ok = miURI; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was U, found R, checking for 'i:'\n"); + CTRACE((tfp, "HTMIME: Was U, found R, checking for 'i:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'p' or 'r'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'p' or 'r'")); goto bad_field_name; } /* switch on character */ @@ -934,7 +1455,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ry:"; me->if_ok = miVARY; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was V, found A, checking for 'ry:'\n"); + CTRACE((tfp, "HTMIME: Was V, found A, checking for 'ry:'\n")); break; case 'i': @@ -942,12 +1463,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "a:"; me->if_ok = miVIA; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was V, found I, checking for 'a:'\n"); + CTRACE((tfp, "HTMIME: Was V, found I, checking for 'a:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'a' or 'i'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'a' or 'i'")); goto bad_field_name; } /* switch on character */ @@ -960,7 +1481,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "rning:"; me->if_ok = miWARNING; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was W, found A, checking for 'rning:'\n"); + CTRACE((tfp, "HTMIME: Was W, found A, checking for 'rning:'\n")); break; case 'w': @@ -968,12 +1489,12 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "w-authenticate:"; me->if_ok = miWWW_AUTHENTICATE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was W, found W, checking for 'w-authenticate:'\n"); + CTRACE((tfp, "HTMIME: Was W, found W, checking for 'w-authenticate:'\n")); break; default: - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, "'a' or 'w'"); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'a' or 'w'")); goto bad_field_name; } /* switch on character */ @@ -984,14 +1505,14 @@ PRIVATE void HTMIME_put_character ARGS2( if (!*me->check_pointer) me->state = me->if_ok; } else { /* Error */ - CTRACE(tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", - c, me->check_pointer - 1); + CTRACE((tfp, "HTMIME: Bad character `%c' found where `%s' expected\n", + c, me->check_pointer - 1)); goto bad_field_name; } break; case miCONTENT_: - CTRACE (tfp, "HTMIME: in case CONTENT_\n"); + CTRACE((tfp, "HTMIME: in case CONTENT_\n")); switch(c) { case 'b': @@ -999,7 +1520,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ase:"; me->if_ok = miCONTENT_BASE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_, found B, checking for 'ase:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found B, checking for 'ase:'\n")); break; case 'd': @@ -1007,7 +1528,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "isposition:"; me->if_ok = miCONTENT_DISPOSITION; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_, found D, checking for 'isposition:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found D, checking for 'isposition:'\n")); break; case 'e': @@ -1015,7 +1536,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ncoding:"; me->if_ok = miCONTENT_ENCODING; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_, found E, checking for 'ncoding:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found E, checking for 'ncoding:'\n")); break; case 'f': @@ -1023,13 +1544,13 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "eatures:"; me->if_ok = miCONTENT_FEATURES; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_, found F, checking for 'eatures:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found F, checking for 'eatures:'\n")); break; case 'l': case 'L': me->state = miCONTENT_L; - CTRACE (tfp, "HTMIME: Was CONTENT_, found L, state now CONTENT_L\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found L, state now CONTENT_L\n")); break; case 'm': @@ -1037,7 +1558,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "d5:"; me->if_ok = miCONTENT_MD5; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_, found M, checking for 'd5:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found M, checking for 'd5:'\n")); break; case 'r': @@ -1045,24 +1566,24 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ange:"; me->if_ok = miCONTENT_RANGE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_, found R, checking for 'ange:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found R, checking for 'ange:'\n")); break; case 't': case 'T': me->state = miCONTENT_T; - CTRACE(tfp, "HTMIME: Was CONTENT_, found T, state now CONTENT_T\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found T, state now CONTENT_T\n")); break; default: - CTRACE(tfp, "HTMIME: Was CONTENT_, found nothing; bleah\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_, found nothing; bleah\n")); goto bad_field_name; } /* switch on character */ break; case miCONTENT_L: - CTRACE (tfp, "HTMIME: in case CONTENT_L\n"); + CTRACE((tfp, "HTMIME: in case CONTENT_L\n")); switch(c) { case 'a': @@ -1070,7 +1591,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "nguage:"; me->if_ok = miCONTENT_LANGUAGE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_L, found A, checking for 'nguage:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_L, found A, checking for 'nguage:'\n")); break; case 'e': @@ -1078,7 +1599,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ngth:"; me->if_ok = miCONTENT_LENGTH; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_L, found E, checking for 'ngth:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_L, found E, checking for 'ngth:'\n")); break; case 'o': @@ -1086,18 +1607,18 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "cation:"; me->if_ok = miCONTENT_LOCATION; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_L, found O, checking for 'cation:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_L, found O, checking for 'cation:'\n")); break; default: - CTRACE (tfp, "HTMIME: Was CONTENT_L, found nothing; bleah\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_L, found nothing; bleah\n")); goto bad_field_name; } /* switch on character */ break; case miCONTENT_T: - CTRACE (tfp, "HTMIME: in case CONTENT_T\n"); + CTRACE((tfp, "HTMIME: in case CONTENT_T\n")); switch(c) { case 'r': @@ -1105,7 +1626,7 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "ansfer-encoding:"; me->if_ok = miCONTENT_TRANSFER_ENCODING; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_T, found R, checking for 'ansfer-encoding:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_T, found R, checking for 'ansfer-encoding:'\n")); break; case 'y': @@ -1113,11 +1634,11 @@ PRIVATE void HTMIME_put_character ARGS2( me->check_pointer = "pe:"; me->if_ok = miCONTENT_TYPE; me->state = miCHECK; - CTRACE(tfp, "HTMIME: Was CONTENT_T, found Y, checking for 'pe:'\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_T, found Y, checking for 'pe:'\n")); break; default: - CTRACE (tfp, "HTMIME: Was CONTENT_T, found nothing; bleah\n"); + CTRACE((tfp, "HTMIME: Was CONTENT_T, found nothing; bleah\n")); goto bad_field_name; } /* switch on character */ @@ -1170,9 +1691,9 @@ PRIVATE void HTMIME_put_character ARGS2( case miSKIP_GET_VALUE: if (c == '\n') { - me->fold_state = me->state; - me->state = miNEWLINE; - break; + me->fold_state = me->state; + me->state = miNEWLINE; + break; } if (WHITE(c)) /* @@ -1185,458 +1706,8 @@ PRIVATE void HTMIME_put_character ARGS2( /* Fall through to store first character */ case miGET_VALUE: - if (WHITE(c) && c != ' ') { /* End of field */ - char *cp; - *me->value_pointer = '\0'; - cp = (me->value_pointer - 1); - while ((cp >= me->value) && *cp == ' ') /* S/390 -- gil -- 0146 */ - /* - ** Trim trailing spaces. - */ - *cp = '\0'; - switch (me->field) { - case miACCEPT_RANGES: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Accept-Ranges: '%s'\n", - me->value); - break; - case miAGE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Age: '%s'\n", - me->value); - break; - case miALLOW: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Allow: '%s'\n", - me->value); - break; - case miALTERNATES: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Alternates: '%s'\n", - me->value); - break; - case miCACHE_CONTROL: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Cache-Control: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Convert to lowercase and indicate in anchor. - FM - */ - LYLowerCase(me->value); - StrAllocCopy(me->anchor->cache_control, me->value); - /* - ** Check whether to set no_cache for the anchor. - FM - */ - { - char *cp1, *cp0 = me->value; - - while ((cp1 = strstr(cp0, "no-cache")) != NULL) { - cp1 += 8; - while (*cp1 != '\0' && WHITE(*cp1)) - cp1++; - if (*cp1 == '\0' || *cp1 == ';') { - me->anchor->no_cache = TRUE; - break; - } - cp0 = cp1; - } - if (me->anchor->no_cache == TRUE) - break; - cp0 = me->value; - while ((cp1 = strstr(cp0, "max-age")) != NULL) { - cp1 += 7; - while (*cp1 != '\0' && WHITE(*cp1)) - cp1++; - if (*cp1 == '=') { - cp1++; - while (*cp1 != '\0' && WHITE(*cp1)) - cp1++; - if (isdigit((unsigned char)*cp1)) { - cp0 = cp1; - while (isdigit((unsigned char)*cp1)) - cp1++; - if (*cp0 == '0' && cp1 == (cp0 + 1)) { - me->anchor->no_cache = TRUE; - break; - } - } - } - cp0 = cp1; - } - } - break; - case miCOOKIE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Cookie: '%s'\n", - me->value); - break; - case miCONNECTION: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Connection: '%s'\n", - me->value); - break; - case miCONTENT_BASE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Base: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->content_base, me->value); - break; - case miCONTENT_DISPOSITION: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Disposition: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->content_disposition, me->value); - /* - ** It's not clear yet from existing RFCs and IDs - ** whether we should be looking for file;, attachment;, - ** and/or inline; before the filename=value, so we'll - ** just search for "filename" followed by '=' and just - ** hope we get the intended value. It is purely a - ** suggested name, anyway. - FM - */ - cp = me->anchor->content_disposition; - while (*cp != '\0' && strncasecomp(cp, "filename", 8)) - cp++; - if (*cp == '\0') - break; - cp += 8; - while ((*cp != '\0') && (WHITE(*cp) || *cp == '=')) - cp++; - if (*cp == '\0') - break; - while (*cp != '\0' && WHITE(*cp)) - cp++; - if (*cp == '\0') - break; - StrAllocCopy(me->anchor->SugFname, cp); - if (*me->anchor->SugFname == '\"') { - if ((cp = strchr((me->anchor->SugFname + 1), - '\"')) != NULL) { - *(cp + 1) = '\0'; - HTMIME_TrimDoubleQuotes(me->anchor->SugFname); - } else { - FREE(me->anchor->SugFname); - break; - } - } - cp = me->anchor->SugFname; - while (*cp != '\0' && !WHITE(*cp)) - cp++; - *cp = '\0'; - if (*me->anchor->SugFname == '\0') - FREE(me->anchor->SugFname); - break; - case miCONTENT_ENCODING: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Encoding: '%s'\n", - me->value); - if (!(me->value && *me->value) || - !strcasecomp(me->value, "identity")) - break; - /* - ** Convert to lowercase and indicate in anchor. - FM - */ - LYLowerCase(me->value); - StrAllocCopy(me->anchor->content_encoding, me->value); - FREE(me->compression_encoding); - if (!strcmp(me->value, "8bit") || - !strcmp(me->value, "7bit") || - !strcmp(me->value, "binary")) { - /* - ** Some server indicated "8bit", "7bit" or "binary" - ** inappropriately. We'll ignore it. - FM - */ - CTRACE(tfp, " Ignoring it!\n"); - } else { - /* - ** Save it to use as a flag for setting - ** up a "www/compressed" target. - FM - */ - StrAllocCopy(me->compression_encoding, me->value); - } - break; - case miCONTENT_FEATURES: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Features: '%s'\n", - me->value); - break; - case miCONTENT_LANGUAGE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Language: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Convert to lowercase and indicate in anchor. - FM - */ - LYLowerCase(me->value); - StrAllocCopy(me->anchor->content_language, me->value); - break; - case miCONTENT_LENGTH: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Length: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Convert to integer and indicate in anchor. - FM - */ - me->anchor->content_length = atoi(me->value); - if (me->anchor->content_length < 0) - me->anchor->content_length = 0; - CTRACE(tfp, " Converted to integer: '%d'\n", - me->anchor->content_length); - break; - case miCONTENT_LOCATION: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Location: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->content_location, me->value); - break; - case miCONTENT_MD5: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-MD5: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->content_md5, me->value); - break; - case miCONTENT_RANGE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Range: '%s'\n", - me->value); - break; - case miCONTENT_TRANSFER_ENCODING: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Transfer-Encoding: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Force the Content-Transfer-Encoding value - ** to all lower case. - FM - */ - LYLowerCase(me->value); - me->encoding = HTAtom_for(me->value); - break; - case miCONTENT_TYPE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Content-Type: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Force the Content-Type value to all lower case - ** and strip spaces and double-quotes. - FM - */ - for (i = 0, j = 0; me->value[i]; i++) { - if (me->value[i] != ' ' && me->value[i] != '\"') { - me->value[j++] = TOLOWER(me->value[i]); - } - } - me->value[j] = '\0'; - me->format = HTAtom_for(me->value); - break; - case miDATE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Date: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->date, me->value); - break; - case miETAG: - /* Do not trim double quotes: - * an entity tag consists of an opaque quoted string, - * possibly prefixed by a weakness indicator. - */ - CTRACE(tfp, "HTMIME: PICKED UP ETag: %s\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->ETag, me->value); - break; - case miEXPIRES: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Expires: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->expires, me->value); - break; - case miKEEP_ALIVE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Keep-Alive: '%s'\n", - me->value); - break; - case miLAST_MODIFIED: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Last-Modified: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->last_modified, me->value); - break; - case miLINK: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Link: '%s'\n", - me->value); - break; - case miLOCATION: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Location: '%s'\n", - me->value); - break; - case miPRAGMA: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Pragma: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Check whether to set no_cache for the anchor. - FM - */ - if (!strcmp(me->value, "no-cache")) - me->anchor->no_cache = TRUE; - break; - case miPROXY_AUTHENTICATE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Proxy-Authenticate: '%s'\n", - me->value); - break; - case miPUBLIC: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Public: '%s'\n", - me->value); - break; - case miRETRY_AFTER: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Retry-After: '%s'\n", - me->value); - break; - case miSAFE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Safe: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor if "YES" or "TRUE". - FM - */ - if (!strcasecomp(me->value, "YES") || - !strcasecomp(me->value, "TRUE")) { - me->anchor->safe = TRUE; - } - break; - case miSERVER: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Server: '%s'\n", - me->value); - if (!(me->value && *me->value)) - break; - /* - ** Indicate in anchor. - FM - */ - StrAllocCopy(me->anchor->server, me->value); - break; - case miSET_COOKIE1: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Set-Cookie: '%s'\n", - me->value); - if (me->set_cookie == NULL) { - StrAllocCopy(me->set_cookie, me->value); - } else { - StrAllocCat(me->set_cookie, ", "); - StrAllocCat(me->set_cookie, me->value); - } - break; - case miSET_COOKIE2: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Set-Cookie2: '%s'\n", - me->value); - if (me->set_cookie2 == NULL) { - StrAllocCopy(me->set_cookie2, me->value); - } else { - StrAllocCat(me->set_cookie2, ", "); - StrAllocCat(me->set_cookie2, me->value); - } - break; - case miTITLE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Title: '%s'\n", - me->value); - break; - case miTRANSFER_ENCODING: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Transfer-Encoding: '%s'\n", - me->value); - break; - case miUPGRADE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Upgrade: '%s'\n", - me->value); - break; - case miURI: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP URI: '%s'\n", - me->value); - break; - case miVARY: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Vary: '%s'\n", - me->value); - break; - case miVIA: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Via: '%s'\n", - me->value); - break; - case miWARNING: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP Warning: '%s'\n", - me->value); - break; - case miWWW_AUTHENTICATE: - HTMIME_TrimDoubleQuotes(me->value); - CTRACE(tfp, "HTMIME: PICKED UP WWW-Authenticate: '%s'\n", - me->value); - break; - default: /* Should never get here */ - break; - } - } else { + GET_VALUE: + if (c != '\n') { /* Not end of line */ if (me->value_pointer < me->value + VALUE_SIZE - 1) { *me->value_pointer++ = c; break; @@ -1644,12 +1715,12 @@ PRIVATE void HTMIME_put_character ARGS2( goto value_too_long; } } - /* Fall through */ + /* Fall through (if end of line) */ case miJUNK_LINE: if (c == '\n') { - me->state = miNEWLINE; me->fold_state = me->state; + me->state = miNEWLINE; } break; @@ -1659,9 +1730,9 @@ PRIVATE void HTMIME_put_character ARGS2( return; value_too_long: - CTRACE(tfp, "HTMIME: *** Syntax error. (string too long)\n"); + CTRACE((tfp, "HTMIME: *** Syntax error. (string too long)\n")); -bad_field_name: /* Ignore it */ +bad_field_name: /* Ignore it */ me->state = miJUNK_LINE; return; @@ -1684,7 +1755,7 @@ PRIVATE void HTMIME_put_string ARGS2( (*me->targetClass.put_string)(me->target,s); } else if (me->state != MIME_IGNORE) { - CTRACE(tfp, "HTMIME: %s\n", s); + CTRACE((tfp, "HTMIME: %s\n", s)); for (p=s; *p; p++) HTMIME_put_character(me, *p); @@ -1706,7 +1777,7 @@ PRIVATE void HTMIME_write ARGS3( (*me->targetClass.put_block)(me->target, s, l); } else { - CTRACE(tfp, "HTMIME: %.*s\n", l, s); + CTRACE((tfp, "HTMIME: %.*s\n", l, s)); for (p = s; p < s+l; p++) HTMIME_put_character(me, *p); @@ -1721,9 +1792,13 @@ PRIVATE void HTMIME_write ARGS3( PRIVATE void HTMIME_free ARGS1( HTStream *, me) { - if (me->target) - (*me->targetClass._free)(me->target); - FREE(me); + if (me) { + FREE(me->location); + FREE(me->compression_encoding); + if (me->target) + (*me->targetClass._free)(me->target); + FREE(me); + } } /* End writing @@ -1732,9 +1807,13 @@ PRIVATE void HTMIME_abort ARGS2( HTStream *, me, HTError, e) { - if (me->target) - (*me->targetClass._abort)(me->target, e); - FREE(me); + if (me) { + FREE(me->location); + FREE(me->compression_encoding); + if (me->target) + (*me->targetClass._abort)(me->target, e); + FREE(me); + } } @@ -1762,7 +1841,7 @@ PUBLIC HTStream* HTMIMEConvert ARGS3( { HTStream* me; - me = (HTStream *)calloc(1, sizeof(*me)); + me = typecalloc(HTStream); if (me == NULL) outofmem(__FILE__, "HTMIMEConvert"); me->isa = &HTMIME; @@ -1837,6 +1916,21 @@ PUBLIC HTStream* HTNetMIME ARGS3( return me; } +PUBLIC HTStream* HTMIMERedirect ARGS3( + HTPresentation *, pres, + HTParentAnchor *, anchor, + HTStream *, sink) +{ + HTStream* me = HTMIMEConvert(pres,anchor, sink); + if (!me) + return NULL; + + me->pickup_redirection = YES; + if (me->targetRep == WWW_DEBUG && sink) + me->no_streamstack = YES; + return me; +} + /* Japanese header handling functions ** ================================== ** @@ -1873,8 +1967,10 @@ PUBLIC HTStream* HTNetMIME ARGS3( ** ** Written by S. Ichikawa, ** partially inspired by encdec.c of <jh@efd.lth.se>. +** Assume caller's buffer is LINE_LENGTH bytes, these decode to +** no longer than the input strings. */ -#define BUFLEN 1024 +#define LINE_LENGTH 512 /* Maximum length of line of ARTICLE etc */ #ifdef ESC #undef ESC #endif /* ESC */ @@ -1887,11 +1983,11 @@ PRIVATE char HTmmquote[] = "0123456789ABCDEF"; PRIVATE int HTmmcont = 0; PUBLIC void HTmmdec_base64 ARGS2( - char *, t, - char *, s) + char *, t, + char *, s) { int d, count, j, val; - char buf[BUFLEN], *bp, nw[4], *p; + char buf[LINE_LENGTH], *bp, nw[4], *p; for (bp = buf; *s; s += 4) { val = 0; @@ -1911,7 +2007,7 @@ PUBLIC void HTmmdec_base64 ARGS2( val += d; } for (j = 2; j >= 0; j--) { - nw[j] = val & 255; + nw[j] = (char) (val & 255); val >>= 8; } if (count--) @@ -1926,23 +2022,23 @@ PUBLIC void HTmmdec_base64 ARGS2( } PUBLIC void HTmmdec_quote ARGS2( - char *, t, - char *, s) + char *, t, + char *, s) { - char buf[BUFLEN], cval, *bp, *p; + char buf[LINE_LENGTH], cval, *bp, *p; for (bp = buf; *s; ) { if (*s == '=') { cval = 0; if (s[1] && (p = strchr(HTmmquote, s[1]))) { - cval += (p - HTmmquote); + cval += (char) (p - HTmmquote); } else { *bp++ = *s++; continue; } if (s[2] && (p = strchr(HTmmquote, s[2]))) { cval <<= 4; - cval += (p - HTmmquote); + cval += (char) (p - HTmmquote); *bp++ = cval; s += 3; } else { @@ -1959,110 +2055,14 @@ PUBLIC void HTmmdec_quote ARGS2( strcpy(t, buf); } -#ifdef NOTDEFINED -/* -** Generalized HTmmdecode for chartrans - K. Weide 1997-03-06 -*/ -PUBLIC void HTmmdecode ARGS2( - char *, trg, - char *, str) -{ - char buf[BUFLEN], mmbuf[BUFLEN]; - char *s, *t, *u, *qm2; - int base64, quote; - - buf[0] = '\0'; - - /* - ** Encoded-words look like - ** =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= - */ - for (s = str, u = buf; *s; ) { - base64 = quote = 0; - if (*s == '=' && s[1] == '?' && - (s == str || *(s-1) == '(' || WHITE(*(s-1)))) - { /* must be beginning of word */ - qm2 = strchr(s+2, '?'); /* 2nd question mark */ - if (qm2 && - (qm2[1] == 'B' || qm2[1] == 'b' || qm2[1] == 'Q' || - qm2[1] == 'q') && - qm2[2] == '?') { /* 3rd question mark */ - char * qm4 = strchr(qm2 + 3, '?'); /* 4th question mark */ - if (qm4 && qm4 - s < 74 && /* RFC 2047 length restriction */ - qm4[1] == '=') { - char *p; - BOOL invalid = NO; - for (p = s+2; p < qm4; p++) - if (WHITE(*p)) { - invalid = YES; - break; - } - if (!invalid) { - int LYhndl; - - *qm2 = '\0'; - invalid = ((LYhndl = UCGetLYhndl_byMIME(s+2)) < 0 || - UCCanTranslateFromTo(LYhndl, - current_char_set)); - *qm2 = '?'; - } - if (!invalid) { - if (qm2[1] == 'B' || qm2[1] == 'b') - base64 = 1; - else if (qm2[1] == 'Q' || qm2[1] == 'q') - quote = 1; - } - } - } - } - if (base64 || quote) { - if (HTmmcont) { - for (t = s - 1; - t >= str && (*t == ' ' || *t == '\t'); t--) { - u--; - } - } - for (s = qm2 + 3, t = mmbuf; *s; ) { - if (s[0] == '?' && s[1] == '=') { - break; - } else { - *t++ = *s++; - } - } - if (s[0] != '?' || s[1] != '=') { - goto end; - } else { - s += 2; - *t = '\0'; - } - if (base64) - HTmmdec_base64(mmbuf, mmbuf); - if (quote) - HTmmdec_quote(mmbuf, mmbuf); - for (t = mmbuf; *t; ) - *u++ = *t++; - HTmmcont = 1; - /* if (*s == ' ' || *s == '\t') *u++ = *s; */ - /* for ( ; *s == ' ' || *s == '\t'; s++) ; */ - } else { - if (*s != ' ' && *s != '\t') - HTmmcont = 0; - *u++ = *s++; - } - } - *u = '\0'; -end: - strcpy(trg, buf); -} -#else /* ** HTmmdecode for ISO-2022-JP - FM */ PUBLIC void HTmmdecode ARGS2( - char *, trg, - char *, str) + char *, trg, + char *, str) { - char buf[BUFLEN], mmbuf[BUFLEN]; + char buf[LINE_LENGTH], mmbuf[LINE_LENGTH]; char *s, *t, *u; int base64, quote; @@ -2118,17 +2118,16 @@ PUBLIC void HTmmdecode ARGS2( end: strcpy(trg, buf); } -#endif /* NOTDEFINED */ /* ** Insert ESC where it seems lost. ** (The author of this function "rjis" is S. Ichikawa.) */ PUBLIC int HTrjis ARGS2( - char *, t, - char *, s) + char *, t, + char *, s) { - char *p, buf[BUFLEN]; + char *p, buf[LINE_LENGTH]; int kanji = 0; if (strchr(s, ESC) || !strchr(s, '$')) { @@ -2173,7 +2172,7 @@ PUBLIC int HTrjis ARGS2( */ /* * RJIS ( Recover JIS code from broken file ) - * $Header: /cvs/OpenBSD/src/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.c,v 1.2 2000/03/25 18:16:47 maja Exp $ + * $Header: /cvs/OpenBSD/src/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.c,v 1.3 2003/05/01 18:59:36 avsm Exp $ * Copyright (C) 1992 1994 * Hironobu Takahashi (takahasi@tiny.or.jp) * diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.h index 25c28660ec6..818f38f2d29 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMIME.h @@ -52,6 +52,14 @@ extern HTStream * HTMIMEConvert PARAMS((HTPresentation * pres, extern HTStream * HTNetMIME PARAMS((HTPresentation * pres, HTParentAnchor * anchor, HTStream * sink)); +/* + + INPUT: Redirection message, parse headers only for Location if present + + */ +extern HTStream * HTMIMERedirect PARAMS((HTPresentation * pres, + HTParentAnchor * anchor, + HTStream * sink)); /* diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.c index b5b6706e99a..09d3902333d 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.c @@ -8,6 +8,7 @@ #include <HTUtils.h> #include <HTMLDTD.h> #include <LYLeaks.h> +#include <LYJustify.h> /* * Character entities like   now excluded from our DTD tables, @@ -86,7 +87,7 @@ static CONST char* entities[] = { "frac12", /* fraction 1/2 */ "frac14", /* fraction 1/4 */ "frac34", /* fraction 3/4 */ - "gt", /* greater than */ + "gt", /* greater than */ "hibar", /* spacing macron */ "iacute", /* small i, acute accent */ "icirc", /* small i, circumflex accent */ @@ -95,7 +96,7 @@ static CONST char* entities[] = { "iquest", /* inverted question mark */ "iuml", /* small i, dieresis or umlaut mark */ "laquo", /* angle quotation mark, left */ - "lt", /* less than */ + "lt", /* less than */ "macr", /* spacing macron */ "mdash", /* dash the width of emsp */ "micro", /* micro sign */ @@ -145,7 +146,7 @@ static CONST char* entities[] = { ** Lists must be in alphabetical order by attribute name ** The tag elements contain the number of attributes */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC # define N HTMLA_NORMAL # define i HTMLA_ANAME # define h HTMLA_HREF @@ -156,7 +157,7 @@ static CONST char* entities[] = { # define T(t) /*nothing*/ #endif -static attr a_attr[] = { /* Anchor attributes */ +static attr a_attr[] = { /* Anchor attributes */ { "ACCESSKEY" T(N) }, { "CHARSET" T(N) }, { "CLASS" T(c) }, @@ -185,7 +186,7 @@ static attr a_attr[] = { /* Anchor attributes */ { 0 T(N) } /* Terminate list */ }; -static attr address_attr[] = { /* ADDRESS attributes */ +static attr address_attr[] = { /* ADDRESS attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -197,7 +198,7 @@ static attr address_attr[] = { /* ADDRESS attributes */ { 0 T(N) } /* Terminate list */ }; -static attr applet_attr[] = { /* APPLET attributes */ +static attr applet_attr[] = { /* APPLET attributes */ { "ALIGN" T(N) }, { "ALT" T(N) }, { "CLASS" T(c) }, @@ -218,7 +219,7 @@ static attr applet_attr[] = { /* APPLET attributes */ { 0 T(N) } /* Terminate list */ }; -static attr area_attr[] = { /* AREA attributes */ +static attr area_attr[] = { /* AREA attributes */ { "ALT" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -240,14 +241,14 @@ static attr area_attr[] = { /* AREA attributes */ { 0 T(N) } /* Terminate list */ }; -static attr base_attr[] = { /* BASE attributes */ +static attr base_attr[] = { /* BASE attributes */ { "HREF" T(h) }, { "TARGET" T(N) }, { "TITLE" T(N) }, { 0 T(N) } /* Terminate list */ }; -static attr bgsound_attr[] = { /* BGSOUND attributes */ +static attr bgsound_attr[] = { /* BGSOUND attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -260,7 +261,7 @@ static attr bgsound_attr[] = { /* BGSOUND attributes */ { 0 T(N) } /* Terminate list */ }; -static attr body_attr[] = { /* BODY attributes */ +static attr body_attr[] = { /* BODY attributes */ { "ALINK" T(N) }, { "BACKGROUND" T(h) }, { "BGCOLOR" T(N) }, @@ -273,13 +274,13 @@ static attr body_attr[] = { /* BODY attributes */ { "ONLOAD" T(N) }, { "ONUNLOAD" T(N) }, { "STYLE" T(N) }, - { "TITLE" T(N) }, { "TEXT" T(N) }, + { "TITLE" T(N) }, { "VLINK" T(N) }, { 0 T(N) } /* Terminate list */ }; -static attr bodytext_attr[] = { /* BODYTEXT attributes */ +static attr bodytext_attr[] = { /* BODYTEXT attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DATA" T(N) }, @@ -297,7 +298,7 @@ static attr bodytext_attr[] = { /* BODYTEXT attributes */ { 0 T(N) } /* Terminate list */ }; -static attr bq_attr[] = { /* BQ (BLOCKQUOTE) attributes */ +static attr bq_attr[] = { /* BQ (BLOCKQUOTE) attributes */ { "CITE" T(h) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -310,7 +311,7 @@ static attr bq_attr[] = { /* BQ (BLOCKQUOTE) attributes */ { 0 T(N) } /* Terminate list */ }; -static attr button_attr[] = { /* BUTTON attributes */ +static attr button_attr[] = { /* BUTTON attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -318,8 +319,8 @@ static attr button_attr[] = { /* BUTTON attributes */ { "ID" T(i) }, { "LANG" T(N) }, { "NAME" T(N) }, - { "ONFOCUS" T(N) }, { "ONBLUR" T(N) }, + { "ONFOCUS" T(N) }, { "STYLE" T(N) }, { "TABINDEX" T(N) }, { "TITLE" T(N) }, @@ -328,7 +329,7 @@ static attr button_attr[] = { /* BUTTON attributes */ { 0 T(N) } /* Terminate list */ }; -static attr caption_attr[] = { /* CAPTION attributes */ +static attr caption_attr[] = { /* CAPTION attributes */ { "ACCESSKEY" T(N) }, { "ALIGN" T(N) }, { "CLASS" T(c) }, @@ -358,7 +359,7 @@ static attr col_attr[] = { /* COL and COLGROUP attributes */ { 0 T(N) } /* Terminate list */ }; -static attr credit_attr[] = { /* CREDIT attributes */ +static attr credit_attr[] = { /* CREDIT attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -369,7 +370,7 @@ static attr credit_attr[] = { /* CREDIT attributes */ { 0 T(N) } /* Terminate list */ }; -static attr div_attr[] = { /* DIV attributes */ +static attr div_attr[] = { /* DIV attributes */ { "ALIGN" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -381,7 +382,7 @@ static attr div_attr[] = { /* DIV attributes */ { 0 T(N) } /* Terminate list */ }; -static attr embed_attr[] = { /* EMBED attributes */ +static attr embed_attr[] = { /* EMBED attributes */ { "ALIGN" T(N) }, /* (including, for now, those from FIG and IMG) */ { "ALT" T(N) }, { "BORDER" T(N) }, @@ -406,7 +407,7 @@ static attr embed_attr[] = { /* EMBED attributes */ { 0 T(N) } /* Terminate list */ }; -static attr fig_attr[] = { /* FIG attributes */ +static attr fig_attr[] = { /* FIG attributes */ { "ALIGN" T(N) }, { "BORDER" T(N) }, { "CLASS" T(c) }, @@ -427,7 +428,7 @@ static attr fig_attr[] = { /* FIG attributes */ { 0 T(N) } /* Terminate list */ }; -static attr fieldset_attr[] = { /* FIELDSET attributes */ +static attr fieldset_attr[] = { /* FIELDSET attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -438,7 +439,7 @@ static attr fieldset_attr[] = { /* FIELDSET attributes */ { 0 T(N) } /* Terminate list */ }; -static attr fn_attr[] = { /* FN attributes */ +static attr fn_attr[] = { /* FN attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -449,7 +450,7 @@ static attr fn_attr[] = { /* FN attributes */ { 0 T(N) } /* Terminate list */ }; -static attr font_attr[] = { /* FONT attributes */ +static attr font_attr[] = { /* FONT attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "COLOR" T(N) }, @@ -463,7 +464,7 @@ static attr font_attr[] = { /* FONT attributes */ { 0 T(N) } /* Terminate list */ }; -static attr form_attr[] = { /* FORM attributes */ +static attr form_attr[] = { /* FORM attributes */ { "ACCEPT-CHARSET" T(N) }, /* HTML 4.0 draft - kw */ { "ACTION" T(h) }, { "CLASS" T(c) }, @@ -482,7 +483,7 @@ static attr form_attr[] = { /* FORM attributes */ { 0 T(N) } /* Terminate list */ }; -static attr frame_attr[] = { /* FRAME attributes */ +static attr frame_attr[] = { /* FRAME attributes */ { "ID" T(i) }, { "LONGDESC" T(h) }, { "MARGINHEIGHT" T(N) }, @@ -494,13 +495,13 @@ static attr frame_attr[] = { /* FRAME attributes */ { 0 T(N) } /* Terminate list */ }; -static attr frameset_attr[] = { /* FRAMESET attributes */ +static attr frameset_attr[] = { /* FRAMESET attributes */ { "COLS" T(N) }, { "ROWS" T(N) }, { 0 T(N) } /* Terminate list */ }; -static attr gen_attr[] = { /* Minimum HTML 3.0 */ +static attr gen_attr[] = { /* Minimum HTML 3.0 */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -511,7 +512,7 @@ static attr gen_attr[] = { /* Minimum HTML 3.0 */ { 0 T(N) } /* Terminate list */ }; -static attr glossary_attr[] = { /* DL (and DLC) attributes */ +static attr glossary_attr[] = { /* DL (and DLC) attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "COMPACT" T(N) }, @@ -523,7 +524,7 @@ static attr glossary_attr[] = { /* DL (and DLC) attributes */ { 0 T(N) } /* Terminate list */ }; -static attr h_attr[] = { /* H1 - H6 attributes */ +static attr h_attr[] = { /* H1 - H6 attributes */ { "ALIGN" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -541,7 +542,7 @@ static attr h_attr[] = { /* H1 - H6 attributes */ { 0 T(N) } /* Terminate list */ }; -static attr hr_attr[] = { /* HR attributes */ +static attr hr_attr[] = { /* HR attributes */ { "ALIGN" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -557,7 +558,7 @@ static attr hr_attr[] = { /* HR attributes */ { 0 T(N) } /* Terminate list */ }; -static attr iframe_attr[] = { /* IFRAME attributes */ +static attr iframe_attr[] = { /* IFRAME attributes */ { "ALIGN" T(N) }, { "FRAMEBORDER" T(N) }, { "HEIGHT" T(N) }, @@ -573,7 +574,7 @@ static attr iframe_attr[] = { /* IFRAME attributes */ { 0 T(N) } /* Terminate list */ }; -static attr img_attr[] = { /* IMG attributes */ +static attr img_attr[] = { /* IMG attributes */ { "ALIGN" T(N) }, { "ALT" T(N) }, { "BORDER" T(N) }, @@ -581,11 +582,11 @@ static attr img_attr[] = { /* IMG attributes */ { "CLEAR" T(N) }, { "DIR" T(N) }, { "HEIGHT" T(N) }, - { "LONGDESC" T(h) }, { "ID" T(i) }, { "ISMAP" T(N) }, { "ISOBJECT" T(N) }, { "LANG" T(N) }, + { "LONGDESC" T(h) }, { "MD" T(N) }, { "SRC" T(h) }, { "STYLE" T(N) }, @@ -596,7 +597,7 @@ static attr img_attr[] = { /* IMG attributes */ { 0 T(N) } /* Terminate list */ }; -static attr input_attr[] = { /* INPUT attributes */ +static attr input_attr[] = { /* INPUT attributes */ { "ACCEPT" T(N) }, { "ACCEPT-CHARSET" T(N) }, /* RFC 2070 HTML i18n - kw */ { "ALIGN" T(N) }, @@ -629,10 +630,10 @@ static attr input_attr[] = { /* INPUT attributes */ { "TYPE" T(N) }, { "VALUE" T(N) }, { "WIDTH" T(N) }, - { 0 T(N) } /* Terminate list */ + { 0 T(N) } /* Terminate list */ }; -static attr isindex_attr[] = { /* ISINDEX attributes */ +static attr isindex_attr[] = { /* ISINDEX attributes */ { "ACTION" T(h) }, /* Not in spec. Lynx treats it as HREF. - FM */ { "DIR" T(N) }, { "HREF" T(h) }, /* HTML 3.0 attribute for search action. - FM */ @@ -643,7 +644,7 @@ static attr isindex_attr[] = { /* ISINDEX attributes */ { 0 T(N) } /* Terminate list */ }; -static attr keygen_attr[] = { /* KEYGEN attributes */ +static attr keygen_attr[] = { /* KEYGEN attributes */ { "CHALLENGE" T(N) }, { "CLASS" T(c) }, { "DIR" T(N) }, @@ -655,7 +656,7 @@ static attr keygen_attr[] = { /* KEYGEN attributes */ { 0 T(N) } /* Terminate list */ }; -static attr label_attr[] = { /* LABEL attributes */ +static attr label_attr[] = { /* LABEL attributes */ { "ACCESSKEY" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -669,7 +670,7 @@ static attr label_attr[] = { /* LABEL attributes */ { 0 T(N) } /* Terminate list */ }; -static attr legend_attr[] = { /* LEGEND attributes */ +static attr legend_attr[] = { /* LEGEND attributes */ { "ACCESSKEY" T(N) }, { "ALIGN" T(N) }, { "CLASS" T(c) }, @@ -682,8 +683,8 @@ static attr legend_attr[] = { /* LEGEND attributes */ { 0 T(N) } /* Terminate list */ }; -static attr link_attr[] = { /* LINK attributes */ - { "CHARSET" T(N) }, /* RFC 2070 HTML i18n -- hint for UA -- - kw */ +static attr link_attr[] = { /* LINK attributes */ + { "CHARSET" T(N) }, /* RFC 2070 HTML i18n -- hint for UA -- - kw */ { "CLASS" T(c) }, { "HREF" T(h) }, { "ID" T(i) }, @@ -697,7 +698,7 @@ static attr link_attr[] = { /* LINK attributes */ { 0 T(N) } /* Terminate list */ }; -static attr list_attr[] = { /* LI attributes */ +static attr list_attr[] = { /* LI attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DINGBAT" T(N) }, @@ -714,19 +715,19 @@ static attr list_attr[] = { /* LI attributes */ { 0 T(N) } /* Terminate list */ }; -static attr map_attr[] = { /* MAP attributes */ +static attr map_attr[] = { /* MAP attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, { "ID" T(i) }, { "LANG" T(N) }, - { "NAME" T(N) }, + { "NAME" T(i) }, { "STYLE" T(N) }, { "TITLE" T(N) }, { 0 T(N) } /* Terminate list */ }; -static attr math_attr[] = { /* MATH attributes */ +static attr math_attr[] = { /* MATH attributes */ { "BOX" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -738,19 +739,19 @@ static attr math_attr[] = { /* MATH attributes */ { 0 T(N) } /* Terminate list */ }; -static attr meta_attr[] = { /* META attributes */ +static attr meta_attr[] = { /* META attributes */ { "CONTENT" T(N) }, { "HTTP-EQUIV" T(N) }, { "NAME" T(N) }, { 0 T(N) } /* Terminate list */ }; -static attr nextid_attr[] = { /* NEXTID attributes */ +static attr nextid_attr[] = { /* NEXTID attributes */ { "N" T(N) }, { 0 T(N) } /* Terminate list */ }; -static attr note_attr[] = { /* NOTE attributes */ +static attr note_attr[] = { /* NOTE attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -764,7 +765,7 @@ static attr note_attr[] = { /* NOTE attributes */ { 0 T(N) } /* Terminate list */ }; -static attr object_attr[] = { /* OBJECT attributes */ +static attr object_attr[] = { /* OBJECT attributes */ { "ALIGN" T(N) }, { "BORDER" T(N) }, { "CLASS" T(c) }, @@ -790,10 +791,10 @@ static attr object_attr[] = { /* OBJECT attributes */ { "USEMAP" T(h) }, { "VSPACE" T(N) }, { "WIDTH" T(N) }, - { 0 T(N) } /* Terminate list */ + { 0 T(N) } /* Terminate list */ }; -static attr olist_attr[] = { /* OL attributes */ +static attr olist_attr[] = { /* OL attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "COMPACT" T(N) }, @@ -809,7 +810,7 @@ static attr olist_attr[] = { /* OL attributes */ { 0 T(N) } /* Terminate list */ }; -static attr option_attr[] = { /* OPTION attributes */ +static attr option_attr[] = { /* OPTION attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -825,7 +826,7 @@ static attr option_attr[] = { /* OPTION attributes */ { 0 T(N) } /* Terminate list */ }; -static attr overlay_attr[] = { /* OVERLAY attributes */ +static attr overlay_attr[] = { /* OVERLAY attributes */ { "CLASS" T(c) }, { "HEIGHT" T(N) }, { "ID" T(i) }, @@ -841,7 +842,7 @@ static attr overlay_attr[] = { /* OVERLAY attributes */ { 0 T(N) } /* Terminate list */ }; -static attr p_attr[] = { /* P attributes */ +static attr p_attr[] = { /* P attributes */ { "ALIGN" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -854,7 +855,7 @@ static attr p_attr[] = { /* P attributes */ { 0 T(N) } /* Terminate list */ }; -static attr param_attr[] = { /* PARAM attributes */ +static attr param_attr[] = { /* PARAM attributes */ { "ACCEPT" T(N) }, { "ACCEPT-CHARSET" T(N) }, { "ACCEPT-ENCODING" T(N) }, @@ -876,7 +877,7 @@ static attr param_attr[] = { /* PARAM attributes */ { 0 T(N) } /* Terminate list */ }; -static attr script_attr[] = { /* SCRIPT attributes */ +static attr script_attr[] = { /* SCRIPT attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "DIR" T(N) }, @@ -894,7 +895,7 @@ static attr script_attr[] = { /* SCRIPT attributes */ { 0 T(N) } /* Terminate list */ }; -static attr select_attr[] = { /* SELECT attributes */ +static attr select_attr[] = { /* SELECT attributes */ { "ALIGN" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -920,7 +921,7 @@ static attr select_attr[] = { /* SELECT attributes */ { 0 T(N) } /* Terminate list */ }; -static attr style_attr[] = { /* STYLE attributes */ +static attr style_attr[] = { /* STYLE attributes */ { "DIR" T(N) }, { "LANG" T(N) }, { "NOTATION" T(N) }, @@ -928,7 +929,7 @@ static attr style_attr[] = { /* STYLE attributes */ { 0 T(N) } /* Terminate list */ }; -static attr tab_attr[] = { /* TAB attributes */ +static attr tab_attr[] = { /* TAB attributes */ { "ALIGN" T(N) }, { "CLASS" T(c) }, { "CLEAR" T(N) }, @@ -943,7 +944,7 @@ static attr tab_attr[] = { /* TAB attributes */ { 0 T(N) } /* Terminate list */ }; -static attr table_attr[] = { /* TABLE attributes */ +static attr table_attr[] = { /* TABLE attributes */ { "ALIGN" T(N) }, { "BACKGROUND" T(h) }, { "BORDER" T(N) }, @@ -969,7 +970,7 @@ static attr table_attr[] = { /* TABLE attributes */ { 0 T(N) } /* Terminate list */ }; -static attr td_attr[] = { /* TD and TH attributes */ +static attr td_attr[] = { /* TD and TH attributes */ { "ALIGN" T(N) }, { "AXES" T(N) }, { "AXIS" T(N) }, @@ -993,7 +994,7 @@ static attr td_attr[] = { /* TD and TH attributes */ { 0 T(N) } /* Terminate list */ }; -static attr textarea_attr[] = { /* TEXTAREA attributes */ +static attr textarea_attr[] = { /* TEXTAREA attributes */ { "ACCEPT-CHARSET" T(N) }, /* RFC 2070 HTML i18n - kw */ { "ALIGN" T(N) }, { "CLASS" T(c) }, @@ -1034,7 +1035,7 @@ static attr tr_attr[] = { /* TR, THEAD, TFOOT, and TBODY attributes */ { 0 T(N) } /* Terminate list */ }; -static attr ulist_attr[] = { /* UL attributes */ +static attr ulist_attr[] = { /* UL attributes */ { "CLASS" T(c) }, { "CLEAR" T(N) }, { "COMPACT" T(N) }, @@ -1076,7 +1077,7 @@ static attr ulist_attr[] = { /* UL attributes */ BASEFONT, APPLET, OBJECT, EMBED, SCRIPT, MAP, MARQUEE, HR, ISINDEX, BGSOUND, TAB,?IMG, 1 e? 2 2 l 1 e 2 l 8 4 4 E 1? E 1 E ! E ?1 E IMAGE, BR, plus NOEMBED, SERVER, SPACER, AUDIOSCOPE, and SIDEBAR; ?area - 1 n 1 E n n n n n 8 E + 1 n 1 E n n n n n 8 E %text; @@ -1116,7 +1117,7 @@ static attr ulist_attr[] = { /* UL attributes */ /* 1 2 3 4 5 6 7 8 */ /*345678901234567890123456789012345678901234567890123456789012345678901234567890 */ -/* self contain icont'n contn'd icont'd canclos omit */ +/* self contain icont'n contn'd icont'd canclos flags*/ /* { "A" , a_attr, HTML_A_ATTRIBUTES, SGML_MIXED }, */ #define T_A 0x0008, 0x0B007,0x0FF17,0x37787,0x77BA7,0x8604F,0x00014 /* { "ABBREV" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ @@ -1148,7 +1149,7 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "BIG" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ #define T_BIG 0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00014 /* { "BLINK" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ -#define T_BLINK 0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00001,0x00014 +#define T_BLINK 0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00001,0x00014 /* { "BLOCKQUOTE", bq_attr, HTML_BQ_ATTRIBUTES, SGML_MIXED }, */ #define T_BLOCKQUOTE 0x0200, 0xAFBCF,0xAFFFF,0xB6680,0xB6FAF,0x8031F,0x00000 /* { "BODY" , body_attr, HTML_BODY_ATTRIBUTES, SGML_MIXED }, */ @@ -1159,7 +1160,7 @@ static attr ulist_attr[] = { /* UL attributes */ #define T_BQ 0x0200, 0xAFBCF,0xAFFFF,0xB6680,0xB6FAF,0x8031F,0x00000 /* { "BR" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY }, */ #define T_BR 0x1000, 0x00000,0x00000,0x377BF,0x77FBF,0x8101F,0x00001 -#define T_BUTTON 0x0200, 0x0BB0B,0x0FF3B,0x0378F,0x37FAF,0x8035F,0x00000 +#define T_BUTTON 0x2000, 0x0BB07,0x0FF37,0x0378F,0x37FBF,0x8135F,0x00000 /* { "CAPTION" , caption_attr, HTML_CAPTION_ATTRIBUTES, SGML_MIXED }, */ #define T_CAPTION 0x0100, 0x0B04F,0x8FFFF,0x06A00,0xB6FA7,0x8035F,0x00000 /* { "CENTER" , div_attr, HTML_DIV_ATTRIBUTES, SGML_MIXED }, */ @@ -1179,7 +1180,7 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "DD" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY }, */ #define T_DD 0x0400, 0x0FBCF,0x8FFFF,0x00800,0xB6FFF,0x8071F,0x00001 /* { "DEL" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ -#define T_DEL 0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000 +#define T_DEL 0x0002, 0x8BBCF,0x8FFFF,0xA7F8F,0xF7FBF,0x00003,0x00000 /* { "DFN" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ #define T_DFN 0x0002, 0x8B0CF,0x8FFFF,0x8778F,0xF7FBF,0x00003,0x00000 /* { "DIR" , ulist_attr, HTML_UL_ATTRIBUTES, SGML_MIXED }, */ @@ -1195,9 +1196,9 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "EM" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ #define T_EM 0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00003,0x00010 /* { "EMBED" , embed_attr, HTML_EMBED_ATTRIBUTES, SGML_EMPTY }, */ -#define T_EMBED 0x2000, 0x8F107,0x8FFF7,0xB6FBF,0xB7FBF,0x1FF7F,0x00001 +#define T_EMBED 0x2000, 0x8F107,0x8FFF7,0xB6FBF,0xB7FBF,0x1FF7F,0x00001 /* { "FIELDSET", fieldset_attr,HTML_FIELDSET_ATTRIBUTES, SGML_MIXED }, */ -#define T_FIELDSET 0x0200, 0x0FB42,0x0FF5F,0x07787,0x37FF7,0x8805F,0x00000 +#define T_FIELDSET 0x0200, 0x8FB4F,0x8FF7F,0x86787,0xB7FF7,0x8805F,0x00000 /* { "FIG" , fig_attr, HTML_FIG_ATTRIBUTES, SGML_MIXED }, */ #define T_FIG 0x0200, 0x0FB00,0x8FFFF,0x36680,0xB6FBF,0x8834F,0x00000 /* { "FN" , fn_attr, HTML_FN_ATTRIBUTES, SGML_MIXED }, */ @@ -1205,25 +1206,25 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "FONT" , font_attr, HTML_FONT_ATTRIBUTES, SGML_EMPTY }, */ #define T_FONT 0x0001, 0x8B04F,0x8FFFF,0xB778F,0xF7FBF,0x00001,0x00014 /* { "FORM" , form_attr, HTML_FORM_ATTRIBUTES, SGML_EMPTY }, */ -#define T_FORM 0x0080, 0x0FF6F,0x0FF7F,0x36E07,0x33F07,0x88DFF,0x00000 +#define T_FORM 0x0080, 0x0FF6F,0x0FF7F,0x36E07,0x32F07,0x88DFF,0x00000 /* { "FRAME" , frame_attr, HTML_FRAME_ATTRIBUTES, SGML_EMPTY }, */ -#define T_FRAME 0x10000,0x00000,0x00000,0x10000,0x10000,0x9FFFF,0x00001 +#define T_FRAME 0x10000,0x00000,0x00000,0x10000,0x10000,0x9FFFF,0x00001 /* { "FRAMESET", frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_MIXED }, */ #define T_FRAMESET 0x10000,0x90000,0x90000,0x90000,0x93000,0x9FFFF,0x00000 /* { "H1" , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED }, */ -#define T_H1 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000 +#define T_H1 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80117,0x00000 /* { "H2" , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED }, */ -#define T_H2 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000 +#define T_H2 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80117,0x00000 /* { "H3" , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED }, */ -#define T_H3 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000 +#define T_H3 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80117,0x00000 /* { "H4" , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED }, */ -#define T_H4 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000 +#define T_H4 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80117,0x00000 /* { "H5" , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED }, */ -#define T_H5 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000 +#define T_H5 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80117,0x00000 /* { "H6" , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED }, */ -#define T_H6 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80317,0x00000 +#define T_H6 0x0100, 0x0B04F,0x0B05F,0x36680,0x37FAF,0x80117,0x00000 /* { "HEAD" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ -#define T_HEAD 0x40000,0x4F000,0x47000,0x10000,0x10000,0x9FF7F,0x00006 +#define T_HEAD 0x40000,0x4F000,0x47000,0x10000,0x10000,0x9FF7F,0x00007 /* { "HR" , hr_attr, HTML_HR_ATTRIBUTES, SGML_EMPTY }, */ #define T_HR 0x4000, 0x00000,0x00000,0x3FE80,0x3FFBF,0x87F37,0x00001 /* { "HTML" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ @@ -1235,9 +1236,9 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "IMG" , img_attr, HTML_IMG_ATTRIBUTES, SGML_EMPTY }, */ #define T_IMG 0x1000, 0x00000,0x00000,0x3779F,0x37FBF,0x80000,0x00001 /* { "INPUT" , input_attr, HTML_INPUT_ATTRIBUTES, SGML_EMPTY }, */ -#define T_INPUT 0x0040, 0x00000,0x00000,0x03F87,0x37F87,0x8904F,0x00001 +#define T_INPUT 0x0040, 0x00000,0x00000,0x03F87,0x37F87,0x8904F,0x00001 /* { "INS" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ -#define T_INS 0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00003,0x00000 +#define T_INS 0x0002, 0x8BBCF,0x8FFFF,0xA7F8F,0xF7FBF,0x00003,0x00000 /* { "ISINDEX" , isindex_attr, HTML_ISINDEX_ATTRIBUTES,SGML_EMPTY }, */ #define T_ISINDEX 0x8000, 0x00000,0x00000,0x7778F,0x7FFAF,0x80007,0x00001 /* { "KBD" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ @@ -1245,8 +1246,8 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "KEYGEN" , keygen_attr, HTML_KEYGEN_ATTRIBUTES, SGML_EMPTY }, */ #define T_KEYGEN 0x0040, 0x00000,0x00000,0x07FB7,0x37FB7,0x80070,0x00001 /* { "LABEL" , label_attr, HTML_LABEL_ATTRIBUTES, SGML_MIXED }, */ -#define T_LABEL 0x0020, 0x9FFFF,0x9FFFF,0x9FFFF,0x9FFFF,0x00007,0x00000 -#define T_LEGEND 0x0002, 0x0B04F,0x0FF7F,0x00200,0x37FA7,0x00003,0x00000 +#define T_LABEL 0x0002, 0x0304F,0x0FFFF,0x0679F,0x36FBF,0x00007,0x00000 +#define T_LEGEND 0x0002, 0x0B04F,0x8FF7F,0x00200,0xB7FA7,0x00003,0x00000 /* { "LH" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY }, */ #define T_LH 0x0400, 0x0BB7F,0x8FFFF,0x00800,0x97FFF,0x8071F,0x00001 /* { "LI" , list_attr, HTML_LI_ATTRIBUTES, SGML_EMPTY }, */ @@ -1272,7 +1273,8 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "NOTE" , note_attr, HTML_NOTE_ATTRIBUTES, SGML_MIXED }, */ #define T_NOTE 0x0200, 0x0BBAF,0x8FFFF,0x376B0,0xB7FFF,0x8031F,0x00000 /* { "OBJECT" , object_attr, HTML_OBJECT_ATTRIBUTES, SGML_LITTERAL }, */ -#define T_OBJECT 0x2000, 0x8FBCF,0x8FFFF,0xB679F,0xB6FBF,0x83F5F,0x00000 +#define T_OBJECT 0x2000, 0x8FBCF,0x8FFFF,0xB679F,0xB6FBF,0x83F5F,0x00020 +#define T_OBJECT_PCDATA 0x2000, 0x8FBCF,0x8FFFF,0xB679F,0xB6FBF,0x83F5F,0x00008 /* { "OL" , olist_attr, HTML_OL_ATTRIBUTES, SGML_MIXED }, */ #define T_OL 0x0800, 0x0C400,0x8FFFF,0x37680,0xB7FB7,0x88F7F,0x00000 /* { "OPTION" , option_attr, HTML_OPTION_ATTRIBUTES, SGML_EMPTY }, */ @@ -1282,7 +1284,7 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "P" , p_attr, HTML_P_ATTRIBUTES, SGML_EMPTY }, */ #define T_P 0x0100, 0x0B04F,0x8FFFF,0x36680,0xB6FA7,0x80117,0x00001 /* { "PARAM" , param_attr, HTML_PARAM_ATTRIBUTES, SGML_EMPTY }, */ -#define T_PARAM 0x1000, 0x00000,0x00000,0x33500,0x37FFF,0x81560,0x00001 +#define T_PARAM 0x1000, 0x00000,0x00000,0x33500,0x37FFF,0x81560,0x00001 /* { "PLAINTEXT", gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL }, */ #define T_PLAINTEXT 0x10000,0xFFFFF,0xFFFFF,0x90000,0x90000,0x3FFFF,0x00001 /* { "PRE" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ @@ -1296,10 +1298,10 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "SCRIPT" , script_attr, HTML_SCRIPT_ATTRIBUTES, SGML_LITTERAL }, */ #define T_SCRIPT 0x2000, 0x00000,0x00000,0x77F9F,0x77FFF,0x87F5F,0x00000 /* { "SELECT" , select_attr, HTML_SELECT_ATTRIBUTES, SGML_MIXED }, */ -#define T_SELECT 0x0040, 0x08000,0x08000,0x03FAF,0x13FBF,0x80F5F,0x00008 +#define T_SELECT 0x0040, 0x08000,0x08000,0x03FAF,0x33FBF,0x80F5F,0x00008 #define T_SHY 0x1000, 0x00000,0x00000,0x3779F,0x77FBF,0x8101F,0x00001 /* { "SMALL" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ -#define T_SMALL 0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00014 +#define T_SMALL 0x0001, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x00001,0x00014 /* { "SPAN" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ #define T_SPAN 0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FBF,0x80003,0x00000 /* { "SPOT" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY }, */ @@ -1309,7 +1311,7 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "STRONG" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ #define T_STRONG 0x0002, 0x8B04F,0x8FFFF,0xA778F,0xF7FAF,0x00003,0x00010 /* { "STYLE" , style_attr, HTML_STYLE_ATTRIBUTES, SGML_LITTERAL }, */ -#define T_STYLE 0x40000,0x00000,0x00000,0x7638F,0x76FAF,0x8001F,0x00000 +#define T_STYLE 0x40000,0x00000,0x00000,0x7638F,0x76FAF,0x8001F,0x00000 /* { "SUB" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ #define T_SUB 0x0004, 0x8B05F,0x8FFFF,0x8779F,0xF7FBF,0x00007,0x00000 /* { "SUP" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ @@ -1317,23 +1319,23 @@ static attr ulist_attr[] = { /* UL attributes */ /* { "TAB" , tab_attr, HTML_TAB_ATTRIBUTES, SGML_EMPTY }, */ #define T_TAB 0x1000, 0x00000,0x00000,0x3778F,0x57FAF,0x00001,0x00001 /* { "TABLE" , table_attr, HTML_TABLE_ATTRIBUTES, SGML_MIXED }, */ -#define T_TABLE 0x0800, 0x0F1E0,0x8FFFF,0x36680,0xB6FA7,0x8C57F,0x00000 +#define T_TABLE 0x0800, 0x0F1E0,0x8FFFF,0x36680,0xB6FA7,0x8C57F,0x00000 /* { "TBODY" , tr_attr, HTML_TR_ATTRIBUTES, SGML_EMPTY }, */ -#define T_TBODY 0x0020, 0x00020,0x8FFFF,0x00880,0xB7FB7,0x8C75F,0x00003 +#define T_TBODY 0x0020, 0x00020,0x8FFFF,0x00880,0xB7FB7,0x8C75F,0x00003 /* { "TD" , td_attr, HTML_TD_ATTRIBUTES, SGML_EMPTY }, */ #define T_TD 0x0400, 0x0FBCF,0x8FFFF,0x00020,0xB7FB7,0x8C75F,0x00001 /* { "TEXTAREA", textarea_attr,HTML_TEXTAREA_ATTRIBUTES, SGML_LITTERAL }, */ -#define T_TEXTAREA 0x0040, 0x00000,0x00000,0x07F8F,0x33FBF,0x80F5F,0x00000 +#define T_TEXTAREA 0x0040, 0x00000,0x00000,0x07F8F,0x33FBF,0x80F5F,0x00040 /* { "TEXTFLOW", bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED }, */ #define T_TEXTFLOW 0x20000,0x8FBFF,0x9FFFF,0x977B0,0xB7FB7,0x9B00F,0x00003 /* { "TFOOT" , tr_attr, HTML_TR_ATTRIBUTES, SGML_EMPTY }, */ -#define T_TFOOT 0x0020, 0x00020,0x8FFFF,0x00800,0xB7FB7,0x8CF5F,0x00001 +#define T_TFOOT 0x0020, 0x00020,0x8FFFF,0x00800,0xB7FB7,0x8CF5F,0x00001 /* { "TH" , td_attr, HTML_TD_ATTRIBUTES, SGML_EMPTY }, */ #define T_TH 0x0400, 0x0FBCF,0x0FFFF,0x00020,0xB7FB7,0x8CF5F,0x00001 /* { "THEAD" , tr_attr, HTML_TR_ATTRIBUTES, SGML_EMPTY }, */ -#define T_THEAD 0x0020, 0x00020,0x8FFFF,0x00800,0xB7FB7,0x8CF5F,0x00001 +#define T_THEAD 0x0020, 0x00020,0x8FFFF,0x00800,0xB7FB7,0x8CF5F,0x00001 /* { "TITLE", gen_attr, HTML_GEN_ATTRIBUTES, SGML_RCDATA }, */ -#define T_TITLE 0x40000,0x00000,0x00000,0x50000,0x50000,0x0031F,0x00004 +#define T_TITLE 0x40000,0x00000,0x00000,0x50000,0x50000,0x0031F,0x0000C /* { "TR" , tr_attr, HTML_TR_ATTRIBUTES, SGML_EMPTY }, */ #define T_TR 0x0020, 0x00400,0x8FFFF,0x00820,0xB7FB7,0x8C75F,0x00001 /* { "TT" , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED }, */ @@ -1356,22 +1358,35 @@ static attr ulist_attr[] = { /* UL attributes */ ** Must match definitions in HTMLDTD.html! ** Must be in alphabetical order. ** -** The T_* extra info is listed here, but it won't matter (is not used -** in SGML.c if Old_DTD is not set). This mainly simplifies comparison -** of the tags_old[] table (otherwise unchanged from original Lynx treatment) -** with the tags_new[] table below. - kw +** The T_* extra info is listed here, even though most fields are not used +** in SGML.c if Old_DTD is set (with the exception of some Tgf_* flags). +** This simplifies comparison of the tags_old[] table (otherwise unchanged +** from original Lynx treatment) with the tags_new[] table below. - kw ** -** Name, Attributes, No. of attributes, content, extra info... +** Name*, Attributes, No. of attributes, content, extra info... */ +#undef P +#undef P +#undef P_ #ifdef USE_COLOR_STYLE -#define P(x) x , (sizeof x) -1 -#define NULL_HTTag NULL, 0 +#define P_(x) x , (sizeof x) -1 +#define NULL_HTTag_ NULL, 0 +#else +#define P_(x) x +#define NULL_HTTag_ NULL +#endif + +#ifdef EXP_JUSTIFY_ELTS +#define P(x) P_(x), 1 +#define P0(x) P_(x), 0 +#define NULL_HTTag NULL_HTTag_,0 #else -#define P(x) x -#define NULL_HTTag NULL +#define P(x) P_(x) +#define P0(x) P_(x) +#define NULL_HTTag NULL_HTTag_ #endif -static CONST HTTag tags_old[HTML_ELEMENTS] = { +static CONST HTTag tags_old[HTML_ALL_ELEMENTS] = { { P("A") , a_attr, HTML_A_ATTRIBUTES, SGML_EMPTY,T_A}, { P("ABBREV") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_ABBREV}, { P("ACRONYM") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_ACRONYM}, @@ -1381,7 +1396,7 @@ static CONST HTTag tags_old[HTML_ELEMENTS] = { { P("AU") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_AU}, { P("AUTHOR") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_AUTHOR}, { P("B") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY,T_B}, - { P("BANNER") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_BANNER}, + { P0("BANNER") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_BANNER}, { P("BASE") , base_attr, HTML_BASE_ATTRIBUTES, SGML_EMPTY,T_BASE}, { P("BASEFONT"), font_attr, HTML_FONT_ATTRIBUTES, SGML_EMPTY,T_BASEFONT}, { P("BDO") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_BDO}, @@ -1419,12 +1434,12 @@ static CONST HTTag tags_old[HTML_ELEMENTS] = { { P("FORM") , form_attr, HTML_FORM_ATTRIBUTES, SGML_EMPTY,T_FORM}, { P("FRAME") , frame_attr, HTML_FRAME_ATTRIBUTES, SGML_EMPTY,T_FRAME}, { P("FRAMESET"), frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_MIXED,T_FRAMESET}, - { P("H1") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H1}, - { P("H2") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H2}, - { P("H3") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H3}, - { P("H4") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H4}, - { P("H5") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H5}, - { P("H6") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H6}, + { P0("H1") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H1}, + { P0("H2") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H2}, + { P0("H3") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H3}, + { P0("H4") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H4}, + { P0("H5") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H5}, + { P0("H6") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H6}, { P("HEAD") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_HEAD}, { P("HR") , hr_attr, HTML_HR_ATTRIBUTES, SGML_EMPTY,T_HR}, { P("HTML") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_HTML}, @@ -1458,7 +1473,7 @@ static CONST HTTag tags_old[HTML_ELEMENTS] = { { P("P") , p_attr, HTML_P_ATTRIBUTES, SGML_EMPTY,T_P}, { P("PARAM") , param_attr, HTML_PARAM_ATTRIBUTES, SGML_EMPTY,T_PARAM}, { P("PLAINTEXT"), gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL,T_PLAINTEXT}, - { P("PRE") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_PRE}, + { P0("PRE") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_PRE}, { P("Q") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_Q}, { P("S") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_S}, { P("SAMP") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_SAMP}, @@ -1482,17 +1497,21 @@ static CONST HTTag tags_old[HTML_ELEMENTS] = { { P("TFOOT") , tr_attr, HTML_TR_ATTRIBUTES, SGML_EMPTY,T_TFOOT}, { P("TH") , td_attr, HTML_TD_ATTRIBUTES, SGML_EMPTY,T_TH}, { P("THEAD") , tr_attr, HTML_TR_ATTRIBUTES, SGML_EMPTY,T_THEAD}, - { P("TITLE"), gen_attr, HTML_GEN_ATTRIBUTES, SGML_RCDATA,T_TITLE}, + { P("TITLE") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_RCDATA,T_TITLE}, { P("TR") , tr_attr, HTML_TR_ATTRIBUTES, SGML_EMPTY,T_TR}, { P("TT") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY,T_TT}, { P("U") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY,T_U}, { P("UL") , ulist_attr, HTML_UL_ATTRIBUTES, SGML_MIXED,T_UL}, { P("VAR") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_VAR}, { P("WBR") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY,T_WBR}, - { P("XMP") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL,T_XMP}, + { P0("XMP") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL,T_XMP}, + /* additional (alternative variants), not counted in HTML_ELEMENTS: */ +/* This one will be used as a temporary substitute within the parser when + it has been signalled to parse OBJECT content as MIXED. - kw */ + { P("OBJECT") , object_attr, HTML_OBJECT_ATTRIBUTES, SGML_MIXED,T_OBJECT_PCDATA}, }; -static CONST HTTag tags_new[HTML_ELEMENTS] = { +static CONST HTTag tags_new[HTML_ALL_ELEMENTS] = { { P("A") , a_attr, HTML_A_ATTRIBUTES, SGML_MIXED,T_A}, { P("ABBREV") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_ABBREV}, { P("ACRONYM") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_ACRONYM}, @@ -1502,7 +1521,7 @@ static CONST HTTag tags_new[HTML_ELEMENTS] = { { P("AU") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_AU}, { P("AUTHOR") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_AUTHOR}, { P("B") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_B}, - { P("BANNER") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_BANNER}, + { P0("BANNER") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_BANNER}, { P("BASE") , base_attr, HTML_BASE_ATTRIBUTES, SGML_EMPTY,T_BASE}, { P("BASEFONT"), font_attr, HTML_FONT_ATTRIBUTES, SGML_EMPTY,T_BASEFONT}, { P("BDO") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_BDO}, @@ -1540,12 +1559,12 @@ static CONST HTTag tags_new[HTML_ELEMENTS] = { { P("FORM") , form_attr, HTML_FORM_ATTRIBUTES, SGML_MIXED,T_FORM}, { P("FRAME") , frame_attr, HTML_FRAME_ATTRIBUTES, SGML_EMPTY,T_FRAME}, { P("FRAMESET"), frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_ELEMENT,T_FRAMESET}, - { P("H1") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H1}, - { P("H2") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H2}, - { P("H3") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H3}, - { P("H4") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H4}, - { P("H5") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H5}, - { P("H6") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H6}, + { P0("H1") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H1}, + { P0("H2") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H2}, + { P0("H3") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H3}, + { P0("H4") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H4}, + { P0("H5") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H5}, + { P0("H6") , h_attr, HTML_H_ATTRIBUTES, SGML_MIXED,T_H6}, { P("HEAD") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_ELEMENT,T_HEAD}, { P("HR") , hr_attr, HTML_HR_ATTRIBUTES, SGML_EMPTY,T_HR}, { P("HTML") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_HTML}, @@ -1566,7 +1585,7 @@ static CONST HTTag tags_new[HTML_ELEMENTS] = { { P("LISTING") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL,T_LISTING}, { P("MAP") , map_attr, HTML_MAP_ATTRIBUTES, SGML_ELEMENT,T_MAP}, { P("MARQUEE") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_MARQUEE}, - { P("MATH") , math_attr, HTML_MATH_ATTRIBUTES, SGML_LITTERAL,T_MATH}, + { P("MATH") , math_attr, HTML_MATH_ATTRIBUTES, SGML_PCDATA,T_MATH}, { P("MENU") , ulist_attr, HTML_UL_ATTRIBUTES, SGML_MIXED,T_MENU}, { P("META") , meta_attr, HTML_META_ATTRIBUTES, SGML_EMPTY,T_META}, { P("NEXTID") , nextid_attr, 1, SGML_EMPTY,T_NEXTID}, @@ -1579,11 +1598,11 @@ static CONST HTTag tags_new[HTML_ELEMENTS] = { { P("P") , p_attr, HTML_P_ATTRIBUTES, SGML_MIXED,T_P}, { P("PARAM") , param_attr, HTML_PARAM_ATTRIBUTES, SGML_EMPTY,T_PARAM}, { P("PLAINTEXT"), gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL,T_PLAINTEXT}, - { P("PRE") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_PRE}, + { P0("PRE") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_PRE}, { P("Q") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_Q}, { P("S") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_S}, { P("SAMP") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_SAMP}, - { P("SCRIPT") , script_attr, HTML_SCRIPT_ATTRIBUTES, SGML_LITTERAL,T_SCRIPT}, + { P("SCRIPT") , script_attr, HTML_SCRIPT_ATTRIBUTES, SGML_SCRIPT,T_SCRIPT}, { P("SELECT") , select_attr, HTML_SELECT_ATTRIBUTES, SGML_ELEMENT,T_SELECT}, { P("SHY") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY,T_SHY}, { P("SMALL") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_SMALL}, @@ -1591,14 +1610,14 @@ static CONST HTTag tags_new[HTML_ELEMENTS] = { { P("SPOT") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY,T_SPOT}, { P("STRIKE") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_STRIKE}, { P("STRONG") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_STRONG}, - { P("STYLE") , style_attr, HTML_STYLE_ATTRIBUTES, SGML_LITTERAL,T_STYLE}, + { P("STYLE") , style_attr, HTML_STYLE_ATTRIBUTES, SGML_CDATA,T_STYLE}, { P("SUB") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_SUB}, { P("SUP") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_SUP}, { P("TAB") , tab_attr, HTML_TAB_ATTRIBUTES, SGML_EMPTY,T_TAB}, { P("TABLE") , table_attr, HTML_TABLE_ATTRIBUTES, SGML_ELEMENT,T_TABLE}, { P("TBODY") , tr_attr, HTML_TR_ATTRIBUTES, SGML_ELEMENT,T_TBODY}, { P("TD") , td_attr, HTML_TD_ATTRIBUTES, SGML_MIXED,T_TD}, - { P("TEXTAREA"), textarea_attr,HTML_TEXTAREA_ATTRIBUTES, SGML_LITTERAL,T_TEXTAREA}, + { P("TEXTAREA"), textarea_attr,HTML_TEXTAREA_ATTRIBUTES, SGML_PCDATA,T_TEXTAREA}, { P("TEXTFLOW"), bodytext_attr,HTML_BODYTEXT_ATTRIBUTES, SGML_MIXED,T_TEXTFLOW}, { P("TFOOT") , tr_attr, HTML_TR_ATTRIBUTES, SGML_ELEMENT,T_TFOOT}, { P("TH") , td_attr, HTML_TD_ATTRIBUTES, SGML_MIXED,T_TH}, @@ -1610,20 +1629,27 @@ static CONST HTTag tags_new[HTML_ELEMENTS] = { { P("UL") , ulist_attr, HTML_UL_ATTRIBUTES, SGML_MIXED,T_UL}, { P("VAR") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_MIXED,T_VAR}, { P("WBR") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_EMPTY,T_WBR}, - { P("XMP") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL,T_XMP}, + { P0("XMP") , gen_attr, HTML_GEN_ATTRIBUTES, SGML_LITTERAL,T_XMP}, + /* additional (alternative variants), not counted in HTML_ELEMENTS: */ +/* This one will be used as a temporary substitute within the parser when + it has been signalled to parse OBJECT content as MIXED. - kw */ + { P("OBJECT") , object_attr, HTML_OBJECT_ATTRIBUTES, SGML_MIXED,T_OBJECT_PCDATA}, }; + #undef P +#undef P0 +#undef P_ /* Dummy space, will be filled with the contents of either tags_new or tags_old on calling HTSwitchDTD - kw */ -static HTTag tags[HTML_ELEMENTS]; +static HTTag tags[HTML_ALL_ELEMENTS]; PUBLIC CONST SGML_dtd HTML_dtd = { tags, HTML_ELEMENTS, entities, /* probably unused */ - sizeof(entities)/sizeof(entities[0]), + TABLESIZE(entities), }; /* This function fills the "tags" part of the HTML_dtd structure with @@ -1634,23 +1660,24 @@ PUBLIC CONST SGML_dtd HTML_dtd = { is limited and I didn't want to list the whole tags_new table twice... - kw */ PUBLIC void HTSwitchDTD ARGS1( - BOOL, new) + int, new_flag) { if (TRACE) - CTRACE(tfp,"HTMLDTD: Copying DTD element info of size %d, %d * %d\n", - (int) (new ? sizeof(tags_new) : sizeof(tags_old)), - HTML_ELEMENTS, - (int) sizeof(HTTag)); - if (new) - memcpy(tags, tags_new, HTML_ELEMENTS * sizeof(HTTag)); + CTRACE((tfp,"HTMLDTD: Copying DTD element info of size %d, %d * %d\n", + (int) (new_flag ? sizeof(tags_new) : sizeof(tags_old)), + HTML_ALL_ELEMENTS, + (int) sizeof(HTTag))); + if (new_flag) + memcpy(tags, tags_new, HTML_ALL_ELEMENTS * sizeof(HTTag)); else - memcpy(tags, tags_old, HTML_ELEMENTS * sizeof(HTTag)); + memcpy(tags, tags_old, HTML_ALL_ELEMENTS * sizeof(HTTag)); } PUBLIC HTTag HTTag_unrecognized = { NULL_HTTag, NULL, 0, SGML_EMPTY,T__UNREC_}; + /* ** Utility Routine: Useful for people building HTML objects. */ @@ -1668,7 +1695,7 @@ struct _HTStructured { }; PUBLIC void HTStartAnchor ARGS3( - HTStructured *, obj, + HTStructured *, obj, CONST char *, name, CONST char *, href) { @@ -1691,8 +1718,39 @@ PUBLIC void HTStartAnchor ARGS3( (*obj->isa->start_element)(obj, HTML_A, present, value, -1, 0); } + +PUBLIC void HTStartAnchor5 ARGS5( + HTStructured *, obj, + CONST char *, name, + CONST char *, href, + CONST char *, linktype, + int, tag_charset) +{ + BOOL present[HTML_A_ATTRIBUTES]; + CONST char * value[HTML_A_ATTRIBUTES]; + int i; + + for (i = 0; i < HTML_A_ATTRIBUTES; i++) + present[i] = NO; + + if (name && *name) { + present[HTML_A_NAME] = YES; + value[HTML_A_NAME] = name; + } + if (href) { + present[HTML_A_HREF] = YES; + value[HTML_A_HREF] = href; + } + if (linktype) { + present[HTML_A_TYPE] = YES; + value[HTML_A_TYPE] = linktype; + } + + (*obj->isa->start_element)(obj, HTML_A, present, value, tag_charset, 0); +} + PUBLIC void HTStartIsIndex ARGS3( - HTStructured *, obj, + HTStructured *, obj, CONST char *, prompt, CONST char *, href) { diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.h index 8b1cd4fb05d..79d1111fc2d 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLDTD.h @@ -13,19 +13,20 @@ #define HTMLDTD_H #include <SGML.h> +#include <HTFont.h> /* -** Lynx internal character representations. +** Valid name chars for tag parsing. */ -#ifndef HT_NON_BREAK_SPACE -#define HT_NON_BREAK_SPACE ((char)1) /* For now */ -#endif /* !HT_NON_BREAK_SPACE */ -#ifndef HT_EN_SPACE -#define HT_EN_SPACE ((char)2) /* For now */ -#endif /* !HT_EN_SPACE */ -#ifndef LY_SOFT_HYPHEN -#define LY_SOFT_HYPHEN ((char)7) -#endif /* !LY_SOFT_HYPHEN */ +#define IsNmStart(c) (isalpha(UCH(c))) +#define IsNmChar(c) (isalnum(UCH(c)) || \ + c == '_' || c=='-' || c == '.' || c==':') + + +#define ReallyEmptyTagNum(e) ((HTML_dtd.tags[e].contents == SGML_EMPTY) && \ + !(HTML_dtd.tags[e].flags & Tgf_nreie)) +#define ReallyEmptyTag(t) ((t->contents == SGML_EMPTY) && \ + !(t->flags & Tgf_nreie)) /* @@ -39,7 +40,7 @@ Element Numbers These include tables in HTMLDTD.c and code in HTML.c. */ -typedef enum _HTMLElement { +typedef enum { HTML_A, HTML_ABBREV, HTML_ACRONYM, @@ -157,10 +158,23 @@ typedef enum _HTMLElement { HTML_UL, HTML_VAR, HTML_WBR, - HTML_XMP } HTMLElement; + HTML_XMP, + HTML_ALT_OBJECT } HTMLElement; +/* Notes: HTML.c uses a different extension of the HTML_ELEMENTS space + privately, see HTNestedList.h. */ +/* Don't replace HTML_ELEMENTS with TABLESIZE(mumble_dtd.tags). */ +/* Keep the following defines in synch with the above enum! */ + +/* HTML_ELEMENTS: number of elements visible to Lynx code in general, + alphabetic (ASCII) order. */ #define HTML_ELEMENTS 118 +/* HTML_ALL_ELEMENTS: number of elements visible to SGML parser, + additional variant(s) at end. */ +#define HTML_ALL_ELEMENTS 119 + + /* Attribute numbers @@ -957,7 +971,7 @@ Attribute numbers #define HTML_UL_WRAP 13 #define HTML_UL_ATTRIBUTES 14 -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC /* values of HTML attributes' types */ #define HTMLA_NORMAL 0 /* nothing specific */ #define HTMLA_ANAME 1 /* anchor name - 'id' or a's 'name' */ @@ -968,10 +982,10 @@ Attribute numbers #endif extern CONST SGML_dtd HTML_dtd; -extern void HTSwitchDTD PARAMS(( - BOOL new)); +extern void HTSwitchDTD PARAMS((int new_flag)); extern HTTag HTTag_unrecognized; +extern HTTag HTTag_mixedObject; /* @@ -993,6 +1007,13 @@ extern void HTStartAnchor PARAMS(( CONST char * name, CONST char * href)); +extern void HTStartAnchor5 PARAMS(( + HTStructured * targetstream, + CONST char * name, + CONST char * href, + CONST char * linktype, + int tag_charset)); + /* Start IsIndex element - FM diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLGen.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLGen.c index a5269eba7be..6047d074fa0 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLGen.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTMLGen.c @@ -33,10 +33,9 @@ #include <LYStyle.h> #endif +#include <LYGlobalDefs.h> #include <LYLeaks.h> -extern BOOLEAN LYPreparsedSource; /* Show source as preparsed? */ - #define PUTC(c) (*me->targetClass.put_character)(me->target, c) /* #define PUTS(s) (*me->targetClass.put_string)(me->target, s) */ #define PUTB(s,l) (*me->targetClass.put_block)(me->target, s, l) @@ -83,7 +82,7 @@ struct _HTStructured { */ PRIVATE void flush_breaks ARGS1( - HTStructured *, me) + HTStructured *, me) { int i; for (i=0; i<= MAX_CLEANNESS; i++) { @@ -92,7 +91,7 @@ PRIVATE void flush_breaks ARGS1( } PRIVATE void HTMLGen_flush ARGS1( - HTStructured *, me) + HTStructured *, me) { (*me->targetClass.put_block)(me->target, me->buffer, @@ -132,7 +131,7 @@ PRIVATE void HTMLGen_flush ARGS1( * -preparsed flag. - kw */ PRIVATE void do_cstyle_flush ARGS1( - HTStructured *, me) + HTStructured *, me) { if (!me->text && LYPreparsedSource) { me->text = HTMainText; @@ -177,10 +176,10 @@ PRIVATE void allow_break ARGS3( ** by hand, too, though this is not a primary design consideration. TBL */ PRIVATE void HTMLGen_put_character ARGS2( - HTStructured *, me, + HTStructured *, me, char, c) { - if (me->escape_specials && (unsigned char)c < 32) { + if (me->escape_specials && UCH(c) < 32) { if (c == HT_NON_BREAK_SPACE || c == HT_EN_SPACE || c == LY_SOFT_HYPHEN) { /* recursion... */ HTMLGen_put_character(me, '&'); @@ -288,7 +287,7 @@ PRIVATE void HTMLGen_put_character ARGS2( ** --------------- */ PRIVATE void HTMLGen_put_string ARGS2( - HTStructured *, me, + HTStructured *, me, CONST char *, s) { CONST char * p; @@ -298,7 +297,7 @@ PRIVATE void HTMLGen_put_string ARGS2( } PRIVATE void HTMLGen_write ARGS3( - HTStructured *, me, + HTStructured *, me, CONST char *, s, int, l) { @@ -314,8 +313,8 @@ PRIVATE void HTMLGen_write ARGS3( ** Within the opening tag, there may be spaces ** and the line may be broken at these spaces. */ -PRIVATE void HTMLGen_start_element ARGS6( - HTStructured *, me, +PRIVATE int HTMLGen_start_element ARGS6( + HTStructured *, me, int, element_number, CONST BOOL*, present, CONST char **, value, @@ -338,26 +337,26 @@ PRIVATE void HTMLGen_start_element ARGS6( strcpy (myHash, HTML_dtd.tags[element_number].name); if (class_string[0]) { + int len = strlen(myHash); + sprintf (myHash + len, ".%.*s", (int) sizeof(myHash) - len - 2, class_string); HTSprintf (&Style_className, ".%s", class_string); - strcat (myHash, "."); - strcat (myHash, class_string); } class_string[0] = '\0'; strtolower(myHash); hcode = hash_code(myHash); strtolower(Style_className); - if (TRACE) + if (TRACE_STYLE) { fprintf(tfp, "CSSTRIM:%s -> %d", myHash, hcode); if (hashStyles[hcode].code!=hcode) { - char *rp=strrchr(myHash, '.'); + char *rp = strrchr(myHash, '.'); fprintf(tfp, " (undefined) %s\n", myHash); if (rp) { int hcd; - *rp='\0'; /* trim the class */ + *rp = '\0'; /* trim the class */ hcd = hash_code(myHash); fprintf(tfp, "CSS:%s -> %d", myHash, hcd); if (hashStyles[hcd].code!=hcd) @@ -372,8 +371,9 @@ PRIVATE void HTMLGen_start_element ARGS6( if (displayStyles[element_number + STARTAT].color > -2) /* actually set */ { - CTRACE(tfp, "CSSTRIM: start_element: top <%s>\n", - HTML_dtd.tags[element_number].name); + CTRACE2(TRACE_STYLE, + (tfp, "CSSTRIM: start_element: top <%s>\n", + HTML_dtd.tags[element_number].name)); do_cstyle_flush(me); HText_characterStyle(me->text, hcode, 1); } @@ -412,7 +412,8 @@ PRIVATE void HTMLGen_start_element ARGS6( if (title && *title) { HTSprintf0(&title_tmp, "link.%s.%s", value[HTML_LINK_CLASS], title); - CTRACE(tfp, "CSSTRIM:link=%s\n", title_tmp); + CTRACE2(TRACE_STYLE, + (tfp, "CSSTRIM:link=%s\n", title_tmp)); do_cstyle_flush(me); HText_characterStyle(me->text, hash_code(title_tmp), 1); @@ -486,23 +487,35 @@ PRIVATE void HTMLGen_start_element ARGS6( * Same logic as in HTML_start_element, copied from there. - kw */ -/* end really empty tags straight away */ -#define REALLY_EMPTY(e) ((HTML_dtd.tags[e].contents == SGML_EMPTY) && \ - !(HTML_dtd.tags[e].flags & Tgf_nreie)) - - if (LYPreparsedSource && REALLY_EMPTY(element_number)) + /* end really empty tags straight away */ + if (LYPreparsedSource && ReallyEmptyTagNum(element_number)) { - CTRACE(tfp, "STYLE:begin_element:ending EMPTY element style\n"); + CTRACE2(TRACE_STYLE, + (tfp, "STYLE:begin_element:ending EMPTY element style\n")); do_cstyle_flush(me); -#if !defined(USE_HASH) - HText_characterStyle(me->text, element_number+STARTAT, STACK_OFF); -#else HText_characterStyle(me->text, hcode, STACK_OFF); -#endif /* USE_HASH */ TrimColorClass(HTML_dtd.tags[element_number].name, Style_className, &hcode); } #endif /* USE_COLOR_STYLE */ + if (element_number == HTML_OBJECT && tag->contents == SGML_LITTERAL) { + /* + * These conditions only approximate the ones used in HTML.c. + * Let our SGML parser know that further content is to be parsed + * normally not literally. - kw + */ + if (!present) { + return HT_PARSER_OTHER_CONTENT; + } else if (!present[HTML_OBJECT_DECLARE] && + !(present[HTML_OBJECT_NAME] && + value[HTML_OBJECT_NAME] && *value[HTML_OBJECT_NAME])) { + if (present[HTML_OBJECT_SHAPES] || + !(present[HTML_OBJECT_USEMAP] && + value[HTML_OBJECT_USEMAP] && *value[HTML_OBJECT_USEMAP])) + return HT_PARSER_OTHER_CONTENT; + } + } + return HT_OK; } /* End Element @@ -516,8 +529,8 @@ PRIVATE void HTMLGen_start_element ARGS6( ** should be linked to the whole stack not just the top one.) ** TBL 921119 */ -PRIVATE void HTMLGen_end_element ARGS3( - HTStructured *, me, +PRIVATE int HTMLGen_end_element ARGS3( + HTStructured *, me, int, element_number, char **, insert GCC_UNUSED) { @@ -544,17 +557,14 @@ PRIVATE void HTMLGen_end_element ARGS3( TrimColorClass(HTML_dtd.tags[element_number].name, Style_className, &hcode); - if (LYPreparsedSource && !REALLY_EMPTY(element_number)) - { - CTRACE(tfp, "STYLE:end_element: ending non-EMPTY style\n"); + if (LYPreparsedSource && !ReallyEmptyTagNum(element_number)) { + CTRACE2(TRACE_STYLE, + (tfp, "STYLE:end_element: ending non-EMPTY style\n")); do_cstyle_flush(me); -#if !defined(USE_HASH) - HText_characterStyle(me->text, element_number+STARTAT, STACK_OFF); -#else HText_characterStyle(me->text, hcode, STACK_OFF); -#endif /* USE_HASH */ } #endif /* USE_COLOR_STYLE */ + return HT_OK; } /* Expanding entities @@ -562,7 +572,7 @@ PRIVATE void HTMLGen_end_element ARGS3( ** */ PRIVATE int HTMLGen_put_entity ARGS2( - HTStructured *, me, + HTStructured *, me, int, entity_number) { int nent = HTML_dtd.number_of_entities; @@ -580,7 +590,7 @@ PRIVATE int HTMLGen_put_entity ARGS2( ** */ PRIVATE void HTMLGen_free ARGS1( - HTStructured *, me) + HTStructured *, me) { (*me->targetClass.put_character)(me->target, '\n'); HTMLGen_flush(me); @@ -592,14 +602,14 @@ PRIVATE void HTMLGen_free ARGS1( } PRIVATE void PlainToHTML_free ARGS1( - HTStructured *, me) + HTStructured *, me) { HTMLGen_end_element(me, HTML_PRE, 0); HTMLGen_free(me); } PRIVATE void HTMLGen_abort ARGS2( - HTStructured *, me, + HTStructured *, me, HTError, e GCC_UNUSED) { HTMLGen_free(me); @@ -609,7 +619,7 @@ PRIVATE void HTMLGen_abort ARGS2( } PRIVATE void PlainToHTML_abort ARGS2( - HTStructured *, me, + HTStructured *, me, HTError, e GCC_UNUSED) { PlainToHTML_free(me); @@ -632,8 +642,6 @@ PRIVATE CONST HTStructuredClass HTMLGeneration = /* As opposed to print etc */ ** ------------------------- */ extern int LYcols; /* LYCurses.h, set in LYMain.c */ -extern BOOL dump_output_immediately; /* TRUE if no interactive user */ -extern int dump_output_width; /* -width instead of 80 */ PUBLIC HTStructured * HTMLGenerator ARGS1( HTStream *, output) diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.c index 99433f0740b..30068713170 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.c @@ -16,11 +16,10 @@ #include <HTCJK.h> #include <HTMIME.h> +#include <HTFont.h> #include <HTTCP.h> #include <LYUtils.h> - -/* this define should be in HTFont.h :( */ -#define HT_NON_BREAK_SPACE ((char)1) /* For now */ +#include <LYStrings.h> #define NEWS_PORT 119 /* See rfc977 */ #define SNEWS_PORT 563 /* See Lou Montulli */ @@ -36,18 +35,13 @@ PUBLIC int HTNewsMaxChunk = 40; /* Largest number of articles in one window */ #endif /* SERVER_FILE */ #ifdef USE_SSL -#define free_func free__func -#include <openssl/ssl.h> -#undef free_func extern SSL_CTX * ssl_ctx; -extern SSL * HTGetSSLHandle NOPARAMS; PRIVATE SSL * Handle = NULL; PRIVATE int channel_s = 1; #define NEWS_NETWRITE(sock, buff, size) \ (Handle ? SSL_write(Handle, buff, size) : NETWRITE(sock, buff, size)) #define NEWS_NETCLOSE(sock) \ { (void)NETCLOSE(sock); if (Handle) SSL_free(Handle); Handle = NULL; } -extern char HTGetSSLCharacter PARAMS((void *handle)); PRIVATE char HTNewsGetCharacter NOPARAMS; #define NEXT_CHAR HTNewsGetCharacter() #else @@ -65,6 +59,7 @@ PRIVATE char HTNewsGetCharacter NOPARAMS; #include <LYGlobalDefs.h> #include <LYLeaks.h> +#define SnipIn(d,fmt,len,s) sprintf(d, fmt, (int)sizeof(d)-len, s) struct _HTStructured { CONST HTStructuredClass * isa; @@ -75,12 +70,11 @@ struct _HTStream HTStreamClass * isa; }; -#define LINE_LENGTH 512 /* Maximum length of line of ARTICLE etc */ +#define LINE_LENGTH 512 /* Maximum length of line of ARTICLE etc */ #define GROUP_NAME_LENGTH 256 /* Maximum length of group name */ extern BOOLEAN scan_for_buried_news_references; extern BOOLEAN LYListNewsNumbers; extern BOOLEAN LYListNewsDates; -extern HTCJKlang HTCJK; extern int interrupted_in_htgetcharacter; extern BOOL keep_mime_headers; /* Include mime headers and force raw text */ extern BOOL using_proxy; /* Are we using an NNTP proxy? */ @@ -89,8 +83,8 @@ extern BOOL using_proxy; /* Are we using an NNTP proxy? */ ** Module-wide variables. */ PUBLIC char * HTNewsHost = NULL; /* Default host */ -PRIVATE char * NewsHost = NULL; /* Current host */ -PRIVATE char * NewsHREF = NULL; /* Current HREF prefix */ +PRIVATE char * NewsHost = NULL; /* Current host */ +PRIVATE char * NewsHREF = NULL; /* Current HREF prefix */ PRIVATE int s; /* Socket for NewsHost */ PRIVATE int HTCanPost = FALSE; /* Current POST permission */ PRIVATE char response_text[LINE_LENGTH+1]; /* Last response */ @@ -211,10 +205,10 @@ PRIVATE BOOL initialize NOARGS #else if (getenv("NNTPSERVER")) { StrAllocCopy(HTNewsHost, (char *)getenv("NNTPSERVER")); - CTRACE(tfp, "HTNews: NNTPSERVER defined as `%s'\n", - HTNewsHost); + CTRACE((tfp, "HTNews: NNTPSERVER defined as `%s'\n", + HTNewsHost)); } else { - FILE* fp = fopen(SERVER_FILE, "r"); + FILE* fp = fopen(SERVER_FILE, TXT_R); if (fp) { char server_name[MAXHOSTNAMELEN+1]; if (fgets(server_name, sizeof server_name, fp) != NULL) { @@ -222,8 +216,8 @@ PRIVATE BOOL initialize NOARGS if (p != NULL) *p = '\0'; StrAllocCopy(HTNewsHost, server_name); - CTRACE(tfp, "HTNews: File %s defines news host as `%s'\n", - SERVER_FILE, HTNewsHost); + CTRACE((tfp, "HTNews: File %s defines news host as `%s'\n", + SERVER_FILE, HTNewsHost)); } fclose(fp); } @@ -249,7 +243,7 @@ PRIVATE BOOL initialize NOARGS ** Negative status indicates transmission error, socket closed. ** Positive status is an NNTP status. */ -PRIVATE int response ARGS1(CONST char *,command) +PRIVATE int response ARGS1(char *,command) { int result; char * p = response_text; @@ -258,7 +252,7 @@ PRIVATE int response ARGS1(CONST char *,command) if (command) { int status; int length = strlen(command); - CTRACE(tfp, "NNTP command to be sent: %s", command); + CTRACE((tfp, "NNTP command to be sent: %s", command)); #ifdef NOT_ASCII { CONST char * p; @@ -273,7 +267,7 @@ PRIVATE int response ARGS1(CONST char *,command) status = NEWS_NETWRITE(s, (char *)command, length); #endif /* NOT_ASCII */ if (status < 0){ - CTRACE(tfp, "HTNews: Unable to send command. Disconnecting.\n"); + CTRACE((tfp, "HTNews: Unable to send command. Disconnecting.\n")); NEWS_NETCLOSE(s); s = -1; return status; @@ -282,10 +276,10 @@ PRIVATE int response ARGS1(CONST char *,command) for (;;) { ich = NEXT_CHAR; - if (((*p++ = ich) == LF) || + if (((*p++ = (char) ich) == LF) || (p == &response_text[LINE_LENGTH])) { *--p = '\0'; /* Terminate the string */ - CTRACE(tfp, "NNTP Response: %s\n", response_text); + CTRACE((tfp, "NNTP Response: %s\n", response_text)); sscanf(response_text, "%d", &result); return result; } /* if end of line */ @@ -293,11 +287,11 @@ PRIVATE int response ARGS1(CONST char *,command) if (ich == EOF) { *(p-1) = '\0'; if (interrupted_in_htgetcharacter) { - CTRACE(tfp, "HTNews: Interrupted on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n", + s)); } else { - CTRACE(tfp, "HTNews: EOF on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: EOF on read, closing socket %d\n", + s)); } NEWS_NETCLOSE(s); /* End of file, close socket */ s = -1; @@ -335,7 +329,7 @@ typedef enum { ** This function handles nntp authentication. - FM */ PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1( - char *, host) + char *, host) { HTList *cur = NULL; NNTPAuth *auth = NULL; @@ -373,15 +367,12 @@ PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1( /* ** Handle the username. - FM */ - buffer[511] = '\0'; + buffer[sizeof(buffer)-1] = '\0'; tries = 3; while (tries) { if (UserName == NULL) { - if ((msg = (char *)calloc(1, (strlen(host) + 30))) == NULL) { - outofmem(__FILE__, "HTHandleAuthInfo"); - } - sprintf(msg, gettext("Username for news host '%s':"), host); + HTSprintf0(&msg, gettext("Username for news host '%s':"), host); UserName = HTPrompt(msg, NULL); FREE(msg); if (!(UserName && *UserName)) { @@ -389,7 +380,8 @@ PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1( return NNTPAUTH_ERROR; } } - sprintf(buffer, "AUTHINFO USER %.*s%c%c", 495, UserName, CR, LF); + sprintf(buffer, "AUTHINFO USER %.*s%c%c", + (int) sizeof(buffer)-17, UserName, CR, LF); if ((status = response(buffer)) < 0) { if (status == HT_INTERRUPTED) _HTProgress(CONNECTION_INTERRUPTED); @@ -418,8 +410,7 @@ PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1( /* ** Store the accepted username and no password. - FM */ - if ((auth = - (NNTPAuth *)calloc(1, sizeof(NNTPAuth))) != NULL) { + if ((auth = typecalloc(NNTPAuth)) != NULL) { StrAllocCopy(auth->host, host); auth->user = UserName; HTList_appendObject(NNTP_AuthInfo, auth); @@ -462,10 +453,7 @@ PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1( tries = 3; while (tries) { if (PassWord == NULL) { - if ((msg = (char *)calloc(1, (strlen(host) + 30))) == NULL) { - outofmem(__FILE__, "HTHandleAuthInfo"); - } - sprintf(msg, gettext("Password for news host '%s':"), host); + HTSprintf0(&msg, gettext("Password for news host '%s':"), host); PassWord = HTPromptPassword(msg); FREE(msg); if (!(PassWord && *PassWord)) { @@ -473,7 +461,8 @@ PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1( return NNTPAUTH_ERROR; } } - sprintf(buffer, "AUTHINFO PASS %.*s%c%c", 495, PassWord, CR, LF); + sprintf(buffer, "AUTHINFO PASS %.*s%c%c", + (int) sizeof(buffer)-17, PassWord, CR, LF); if ((status = response(buffer)) < 0) { if (status == HT_INTERRUPTED) { _HTProgress(CONNECTION_INTERRUPTED); @@ -528,8 +517,7 @@ PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1( auth->pass = PassWord; } } else { - if ((auth = - (NNTPAuth *)calloc(1, sizeof(NNTPAuth))) != NULL) { + if ((auth = typecalloc(NNTPAuth)) != NULL) { StrAllocCopy(auth->host, host); auth->user = UserName; auth->pass = PassWord; @@ -582,18 +570,19 @@ PRIVATE char * author_name ARGS1 (char *,email) char *p, *e; StrAllocCopy(name, email); - CTRACE(tfp,"Trying to find name in: %s\n",name); + CTRACE((tfp,"Trying to find name in: %s\n",name)); - if ((p = strchr(name, '(')) && (e = strchr(name, ')'))) { + if ((p = strrchr(name, '(')) && (e = strrchr(name, ')'))) { if (e > p) { *e = '\0'; /* Chop off everything after the ')' */ return HTStrip(p+1); /* Remove leading and trailing spaces */ } } - if ((p = strchr(name, '<')) && (e = strchr(name, '>'))) { - if (e > p) { - strcpy(p, e+1); /* Remove <...> */ + if ((p = strrchr(name, '<')) && (e = strrchr(name, '>'))) { + if (e++ > p) { + while ((*p++ = *e++) != 0) /* Remove <...> */ + ; return HTStrip(name); /* Remove leading and trailing spaces */ } } @@ -618,10 +607,10 @@ PRIVATE char * author_address ARGS1(char *,email) char *p, *at, *e; StrAllocCopy(address, email); - CTRACE(tfp,"Trying to find address in: %s\n",address); + CTRACE((tfp,"Trying to find address in: %s\n",address)); - if ((p = strchr(address, '<'))) { - if ((e = strchr(p, '>')) && (at = strchr(p, '@'))) { + if ((p = strrchr(address, '<'))) { + if ((e = strrchr(p, '>')) && (at = strrchr(p, '@'))) { if (at < e) { *e = '\0'; /* Remove > */ return HTStrip(p+1); /* Remove leading and trailing spaces */ @@ -629,20 +618,20 @@ PRIVATE char * author_address ARGS1(char *,email) } } - if ((p = strchr(address, '(')) && - (e = strchr(address, ')')) && (at = strchr(address, '@'))) { + if ((p = strrchr(address, '(')) && + (e = strrchr(address, ')')) && (at = strchr(address, '@'))) { if (e > p && at < e) { *p = '\0'; /* Chop off everything after the ')' */ return HTStrip(address); /* Remove leading and trailing spaces */ } } - if ((at = strchr(address, '@')) && at > address) { + if ((at = strrchr(address, '@')) && at > address) { p = (at - 1); e = (at + 1); - while (p > address && !isspace((unsigned char)*p)) + while (p > address && !isspace(UCH(*p))) p--; - while (*e && !isspace((unsigned char)*e)) + while (*e && !isspace(UCH(*e))) e++; *e = 0; return HTStrip(p); @@ -652,10 +641,10 @@ PRIVATE char * author_address ARGS1(char *,email) ** Default to the first word. */ p = address; - while (isspace((unsigned char)*p)) + while (isspace(UCH(*p))) p++; /* find first non-space */ e = p; - while (!isspace((unsigned char)*e) && *e != '\0') + while (!isspace(UCH(*e)) && *e != '\0') e++; /* find next space or end */ *e = '\0'; /* terminate space */ @@ -668,16 +657,13 @@ PRIVATE char * author_address ARGS1(char *,email) PRIVATE void start_anchor ARGS1(CONST char *, href) { BOOL present[HTML_A_ATTRIBUTES]; - CONST char* value[HTML_A_ATTRIBUTES]; + CONST char* value[HTML_A_ATTRIBUTES]; + int i; - { - int i; - for(i=0; i < HTML_A_ATTRIBUTES; i++) - present[i] = (i == HTML_A_HREF); - } - ((CONST char **)value)[HTML_A_HREF] = href; - (*targetClass.start_element)(target, HTML_A , present, - (CONST char **)value, -1, 0); + for(i=0; i < HTML_A_ATTRIBUTES; i++) + present[i] = (BOOL) (i == HTML_A_HREF); + value[HTML_A_HREF] = href; + (*targetClass.start_element)(target, HTML_A, present, value, -1, 0); } /* Start link element @@ -686,17 +672,14 @@ PRIVATE void start_anchor ARGS1(CONST char *, href) PRIVATE void start_link ARGS2(CONST char *, href, CONST char *, rev) { BOOL present[HTML_LINK_ATTRIBUTES]; - CONST char* value[HTML_LINK_ATTRIBUTES]; + CONST char* value[HTML_LINK_ATTRIBUTES]; + int i; - { - int i; - for(i=0; i < HTML_LINK_ATTRIBUTES; i++) - present[i] = (i == HTML_LINK_HREF || i == HTML_LINK_REV); - } - ((CONST char **)value)[HTML_LINK_HREF] = href; - ((CONST char **)value)[HTML_LINK_REV] = rev; - (*targetClass.start_element)(target, HTML_LINK, present, - (CONST char **)value, -1, 0); + for(i=0; i < HTML_LINK_ATTRIBUTES; i++) + present[i] = (BOOL) (i == HTML_LINK_HREF || i == HTML_LINK_REV); + value[HTML_LINK_HREF] = href; + value[HTML_LINK_REV] = rev; + (*targetClass.start_element)(target, HTML_LINK, present, value, -1, 0); } /* Start list element @@ -705,17 +688,16 @@ PRIVATE void start_link ARGS2(CONST char *, href, CONST char *, rev) PRIVATE void start_list ARGS1(int, seqnum) { BOOL present[HTML_OL_ATTRIBUTES]; - CONST char* value[HTML_OL_ATTRIBUTES]; + CONST char* value[HTML_OL_ATTRIBUTES]; char SeqNum[20]; int i; for (i = 0; i < HTML_OL_ATTRIBUTES; i++) - present[i] = (i == HTML_OL_SEQNUM || i == HTML_OL_START); + present[i] = (BOOL) (i == HTML_OL_SEQNUM || i == HTML_OL_START); sprintf(SeqNum, "%d", seqnum); - ((CONST char **)value)[HTML_OL_SEQNUM] = SeqNum; - ((CONST char **)value)[HTML_OL_START] = SeqNum; - (*targetClass.start_element)(target, HTML_OL , present, - (CONST char **)value, -1, 0); + value[HTML_OL_SEQNUM] = SeqNum; + value[HTML_OL_START] = SeqNum; + (*targetClass.start_element)(target, HTML_OL, present, value, -1, 0); } /* Paste in an Anchor @@ -731,18 +713,26 @@ PRIVATE void start_list ARGS1(int, seqnum) PRIVATE void write_anchor ARGS2(CONST char *,text, CONST char *,addr) { char href[LINE_LENGTH+1]; + CONST char * p; + char *q; - { - CONST char * p; - strcpy(href, NewsHREF); - for (p = addr; *p && (*p != '>') && !WHITE(*p) && (*p!=','); p++) - ; - strncat(href, addr, p-addr); /* Make complete hypertext reference */ + for (p = addr; *p && (*p != '>') && !WHITE(*p) && (*p!=','); p++) + ; + if (strlen(NewsHREF) + (p - addr) + 1 < sizeof(href)) { + q = href; + strcpy(q, NewsHREF); + strncat(q, addr, p-addr); /* Make complete hypertext reference */ + } else { + q = NULL; + HTSprintf0(&q, "%s%.*s", NewsHREF, p-addr, addr); } - start_anchor(href); + start_anchor(q); PUTS(text); END(HTML_A); + + if (q != href) + FREE(q); } /* Write list of anchors @@ -789,19 +779,23 @@ PRIVATE void write_anchors ARGS1 (char *,text) */ PRIVATE void abort_socket NOARGS { - CTRACE(tfp, "HTNews: EOF on read, closing socket %d\n", s); + CTRACE((tfp, "HTNews: EOF on read, closing socket %d\n", s)); NEWS_NETCLOSE(s); /* End of file, close socket */ - PUTS("Network Error: connection lost"); - PUTC('\n'); + if (rawtext) { + RAW_PUTS("Network Error: connection lost\n"); + } else { + PUTS("Network Error: connection lost"); + PUTC('\n'); + } s = -1; /* End of file on response */ } /* -** Determine if a line is a valid header line. valid_header +** Determine if a line is a valid header line. valid_header ** ------------------------------------------- */ PRIVATE BOOLEAN valid_header ARGS1( - char *, line) + char *, line) { char *colon, *space; @@ -818,7 +812,7 @@ PRIVATE BOOLEAN valid_header ARGS1( */ colon = strchr(line, ':'); space = strchr(line, ' '); - if (isalpha(line[0]) && colon && space == colon + 1) + if (isalpha(UCH(line[0])) && colon && space == colon + 1) return(TRUE); /* @@ -838,7 +832,7 @@ PRIVATE BOOLEAN valid_header ARGS1( ** postfile file with header and article to post. */ PRIVATE void post_article ARGS1( - char *, postfile) + char *, postfile) { char line[512]; char buf[512]; @@ -854,7 +848,7 @@ PRIVATE void post_article ARGS1( ** Open the temporary file with the ** nntp headers and message body. - FM */ - if ((fd = fopen((postfile ? postfile : ""), "r")) == NULL) { + if ((fd = fopen((postfile ? postfile : ""), TXT_R)) == NULL) { HTAlert(FAILED_CANNOT_OPEN_POST); return; } @@ -865,7 +859,7 @@ PRIVATE void post_article ARGS1( */ buf[0] = '\0'; sprintf(crlf, "%c%c", CR, LF); - while (fgets(line, sizeof(line), fd) != NULL) { + while (fgets(line, sizeof(line)-2, fd) != NULL) { if ((cp = strchr(line, '\n')) != NULL) *cp = '\0'; if (line[0] == '.') { @@ -893,16 +887,13 @@ PRIVATE void post_article ARGS1( if (seen_header) { in_header = 0; if (!seen_fromline) { - if (blen < 475) { - strcat(buf, "From: anonymous@nowhere.you.know"); - strcat(buf, crlf); - blen += 34; - } else { + if (blen >= (int) sizeof(buf) - 35) { NEWS_NETWRITE(s, buf, blen); - sprintf(buf, - "From: anonymous@nowhere.you.know%s", crlf); - blen = 34; + buf[blen = 0] = 0; } + strcat(buf, "From: anonymous@nowhere.you.know"); + strcat(buf, crlf); + blen += 34; } } else { continue; @@ -916,14 +907,12 @@ PRIVATE void post_article ARGS1( } strcat(line, crlf); llen += 2; - if ((blen + llen) < 511) { - strcat(buf, line); - blen += llen; - } else { + if ((blen + llen) >= (int) sizeof(buf)-1) { NEWS_NETWRITE(s, buf, blen); - strcpy(buf, line); - blen = llen; + buf[blen = 0] = 0; } + strcat(buf, line); + blen += llen; } fclose(fd); HTSYS_remove(postfile); @@ -931,17 +920,15 @@ PRIVATE void post_article ARGS1( /* ** Send the nntp EOF and get the server's response. - FM */ - if (blen < 508) { - strcat(buf, "."); - strcat(buf, crlf); - blen += 3; - NEWS_NETWRITE(s, buf, blen); - } else { - NEWS_NETWRITE(s, buf, blen); - sprintf(buf, ".%s", crlf); - blen = 3; + if (blen >= (int) sizeof(buf)-4) { NEWS_NETWRITE(s, buf, blen); + buf[blen = 0] = 0; } + strcat(buf, "."); + strcat(buf, crlf); + blen += 3; + NEWS_NETWRITE(s, buf, blen); + status = response(NULL); if (status == 240) { /* @@ -956,6 +943,69 @@ PRIVATE void post_article ARGS1( } } +#ifdef SH_EX /* for MIME */ +#define NEWS_DEBUG 0 +#if NEWS_DEBUG +/* for DEBUG 1997/11/07 (Fri) 17:20:16 */ +void debug_print(unsigned char *p) +{ + while (*p) { + if (*p == '\0') + break; + if (*p == 0x1b) + printf("[ESC]"); + else if (*p == '\n') + printf("[NL]"); + else if (*p < ' ' || *p >= 0x80) + printf("(%02x)", *p); + else + putchar(*p); + p++; + } + printf("]\n"); +} +#endif + +static char *decode_mime(char *str) +{ + char temp[LINE_LENGTH]; /* FIXME: what determines the actual size? */ + char *p, *q; + + if (str == NULL) + return ""; + + if (HTCJK != JAPANESE) + return str; + + LYstrncpy(temp, str, sizeof(temp) - 1); + q = temp; + while ((p = strchr(q, '=')) != 0) { + if (p[1] == '?') { + HTmmdecode(p, p); + q = p + 2; + } else { + q = p + 1; + } + } +#if NEWS_DEBUG + printf("new=["); + debug_print(temp); +#endif + HTrjis(temp, temp); + strcpy(str, temp); + + return str; +} +#else /* !SH_EX */ +static char *decode_mime ARGS1(char *, str) +{ + HTmmdecode(str, str); + HTrjis(str, str); + return str; +} +#endif + + /* Read in an Article read_article ** ------------------ ** @@ -995,22 +1045,22 @@ PRIVATE int read_article ARGS1( if (!diagnostic && !rawtext) { while (!done) { int ich = NEXT_CHAR; - *p++ = ich; + *p++ = (char) ich; if (ich == EOF) { if (interrupted_in_htgetcharacter) { interrupted_in_htgetcharacter = 0; - CTRACE(tfp, "HTNews: Interrupted on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n", + s)); NEWS_NETCLOSE(s); s = -1; return(HT_INTERRUPTED); } - abort_socket(); /* End of file, close socket */ + abort_socket(); /* End of file, close socket */ return(HT_LOADED); /* End of file on response */ } if (((char)ich == LF) || (p == &line[LINE_LENGTH])) { *--p = '\0'; /* Terminate the string */ - CTRACE(tfp, "H %s\n", line); + CTRACE((tfp, "H %s\n", line)); if (line[0] == '\t' || line[0] == ' ') { int i = 0; @@ -1032,47 +1082,31 @@ PRIVATE int read_article ARGS1( /* ** End of article? */ - if ((unsigned char)full_line[1] < ' ') { + if (UCH(full_line[1]) < ' ') { done = YES; break; } - } else if ((unsigned char)full_line[0] < ' ') { + } else if (UCH(full_line[0]) < ' ') { break; /* End of Header? */ } else if (match(full_line, "SUBJECT:")) { StrAllocCopy(subject, HTStrip(strchr(full_line,':')+1)); - if (HTCJK == JAPANESE) { - HTmmdecode(subject, subject); - HTrjis(subject, subject); - } - if (*subject) { - HTAnchor_setSubject(thisanchor, subject); - } - + decode_mime(subject); } else if (match(full_line, "DATE:")) { StrAllocCopy(date, HTStrip(strchr(full_line,':')+1)); } else if (match(full_line, "ORGANIZATION:")) { StrAllocCopy(organization, HTStrip(strchr(full_line,':')+1)); - if (HTCJK == JAPANESE) { - HTmmdecode(organization, organization); - HTrjis(organization, organization); - } + decode_mime(organization); } else if (match(full_line, "FROM:")) { StrAllocCopy(from, HTStrip(strchr(full_line,':')+1)); - if (HTCJK == JAPANESE) { - HTmmdecode(from, from); - HTrjis(from, from); - } + decode_mime(from); } else if (match(full_line, "REPLY-TO:")) { StrAllocCopy(replyto, HTStrip(strchr(full_line,':')+1)); - if (HTCJK == JAPANESE) { - HTmmdecode(replyto, replyto); - HTrjis(replyto, replyto); - } + decode_mime(replyto); } else if (match(full_line, "NEWSGROUPS:")) { StrAllocCopy(newsgroups, HTStrip(strchr(full_line,':')+1)); @@ -1087,7 +1121,7 @@ PRIVATE int read_article ARGS1( char * msgid = HTStrip(full_line+11); if (msgid[0] == '<' && msgid[strlen(msgid)-1] == '>') { msgid[strlen(msgid)-1] = '\0'; /* Chop > */ - msgid++; /* Chop < */ + msgid++; /* Chop < */ HTAnchor_setMessageID(thisanchor, msgid); } @@ -1110,7 +1144,7 @@ PRIVATE int read_article ARGS1( ** Put in the owner as a link rel. */ if (from || replyto) { - char *temp=NULL; + char *temp = NULL; StrAllocCopy(temp, author_address(replyto ? replyto : from)); StrAllocCopy(href,"mailto:"); if (strchr(temp, '%') || strchr(temp, '?')) { @@ -1319,7 +1353,7 @@ PRIVATE int read_article ARGS1( if (rawtext) { /* - * No tags - kw + * No tags, and never do a PUTC. - kw */ ; } else if (diagnostic) { @@ -1328,24 +1362,25 @@ PRIVATE int read_article ARGS1( ** as XMP formatted text. - FM */ START(HTML_XMP); + PUTC('\n'); } else { /* ** Read in the BODY of the Article ** as PRE formatted text. - FM */ START(HTML_PRE); + PUTC('\n'); } - PUTC('\n'); p = line; while (!done) { int ich = NEXT_CHAR; - *p++ = ich; + *p++ = (char) ich; if (ich == EOF) { if (interrupted_in_htgetcharacter) { interrupted_in_htgetcharacter = 0; - CTRACE(tfp, "HTNews: Interrupted on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n", + s)); NEWS_NETCLOSE(s); s = -1; return(HT_INTERRUPTED); @@ -1355,19 +1390,23 @@ PRIVATE int read_article ARGS1( } if (((char)ich == LF) || (p == &line[LINE_LENGTH])) { *p++ = '\0'; /* Terminate the string */ - CTRACE(tfp, "B %s", line); + CTRACE((tfp, "B %s", line)); +#if NEWS_DEBUG /* 1997/11/09 (Sun) 15:56:11 */ + debug_print(line); /* @@@ */ +#endif if (line[0] == '.') { /* ** End of article? */ - if ((unsigned char)line[1] < ' ') { + if (UCH(line[1]) < ' ') { done = YES; break; } else { /* Line starts with dot */ - if (rawtext) + if (rawtext) { RAW_PUTS(&line[1]); - else + } else { PUTS(&line[1]); /* Ignore first dot */ + } } } else { if (rawtext) { @@ -1394,8 +1433,8 @@ PRIVATE int read_article ARGS1( char *p2; while ((p2 = strstr(l, "rticle <")) != NULL) { - char *q = strchr(p2,'>'); - char *at = strchr(p2, '@'); + char *q = strrchr(p2,'>'); + char *at = strrchr(p2, '@'); if (q && at && at<q) { char c = q[1]; q[1] = 0; /* chop up */ @@ -1417,9 +1456,9 @@ PRIVATE int read_article ARGS1( strncmp(l, "wais://", 7) && strncmp(l, "mailto:", 7) && strncmp(l, "cso://", 6) && - strncmp(l, "gopher://", 9)) + strncmp(l, "gopher://", 9)) { PUTC (*l++); - else { + } else { StrAllocCopy(href, l); start_anchor(strtok(href, " \r\n\t,>)\"")); while (*l && !strchr(" \r\n\t,>)\"", *l)) @@ -1435,7 +1474,7 @@ PRIVATE int read_article ARGS1( PUTS(p2); END(HTML_A); q[1] = c; /* again */ - l=q+1; + l = q + 1; } else { break; /* line has unmatched <> */ } @@ -1545,12 +1584,12 @@ PRIVATE int read_list ARGS1(char *, arg) PUTC('\n'); while (!done) { int ich = NEXT_CHAR; - char ch = ich; + char ch = (char) ich; if (ich == EOF) { if (interrupted_in_htgetcharacter) { interrupted_in_htgetcharacter = 0; - CTRACE(tfp, "HTNews: Interrupted on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n", + s)); NEWS_NETCLOSE(s); s = -1; return(HT_INTERRUPTED); @@ -1569,7 +1608,7 @@ PRIVATE int read_list ARGS1(char *, arg) continue; } } else if (p == &line[LINE_LENGTH]) { - CTRACE(tfp, "b %.*s%c[...]\n", (LINE_LENGTH), line, ch); + CTRACE((tfp, "b %.*s%c[...]\n", (LINE_LENGTH), line, ch)); *p = '\0'; if (ch == LF) { ; /* Will be dealt with below */ @@ -1579,7 +1618,7 @@ PRIVATE int read_list ARGS1(char *, arg) } else if (strchr(line, ' ') == NULL && strchr(line, '\t') == NULL) { /* No separator found */ - CTRACE(tfp, "HTNews..... group name too long, discarding.\n"); + CTRACE((tfp, "HTNews..... group name too long, discarding.\n")); skip_this_line = YES; /* ignore whole line */ continue; } else { @@ -1591,12 +1630,12 @@ PRIVATE int read_list ARGS1(char *, arg) if (ch == LF) { skip_rest_of_line = NO; /* done, reset flag */ *p = '\0'; /* Terminate the string */ - CTRACE(tfp, "B %s", line); + CTRACE((tfp, "B %s", line)); if (line[0] == '.') { /* ** End of article? */ - if ((unsigned char)line[1] < ' ') { + if (UCH(line[1]) < ' ') { done = YES; break; } else { /* Line starts with dot */ @@ -1650,10 +1689,12 @@ PRIVATE int read_list ARGS1(char *, arg) } /* if end of line */ } /* Loop over characters */ if (!listing) { + char *msg = NULL; START(HTML_DT); - sprintf(line, gettext("No matches for: %s"), arg); - PUTS(line); + HTSprintf0(&msg, gettext("No matches for: %s"), arg); + PUTS(msg); MAYBE_END(HTML_DT); + FREE(msg); } END(HTML_DLC); PUTC('\n'); @@ -1669,9 +1710,9 @@ PRIVATE int read_list ARGS1(char *, arg) ** */ PRIVATE int read_group ARGS3( - CONST char *,groupName, - int,first_required, - int,last_required) + CONST char *, groupName, + int, first_required, + int, last_required) { char line[LINE_LENGTH+1]; char author[LINE_LENGTH+1]; @@ -1681,7 +1722,8 @@ PRIVATE int read_group ARGS3( char *p; BOOL done; - char buffer[LINE_LENGTH]; + char buffer[LINE_LENGTH+1]; + char *temp = NULL; char *reference = NULL; /* Href for article */ int art; /* Article number WITHIN GROUP */ int status, count, first, last; /* Response fields */ @@ -1699,8 +1741,8 @@ PRIVATE int read_group ARGS3( PUTC('\n'); sscanf(response_text, " %d %d %d %d", &status, &count, &first, &last); - CTRACE(tfp, "Newsgroup status=%d, count=%d, (%d-%d) required:(%d-%d)\n", - status, count, first, last, first_required, last_required); + CTRACE((tfp, "Newsgroup status=%d, count=%d, (%d-%d) required:(%d-%d)\n", + status, count, first, last, first_required, last_required)); if (last == 0) { PUTS(gettext("\nNo articles in this group.\n")); goto add_post; @@ -1710,7 +1752,7 @@ PRIVATE int read_group ARGS3( #define CHOP_THRESHOLD 50 /* Above this, chop off the rest */ if (first_required < first) - first_required = first; /* clip */ + first_required = first; /* clip */ if ((last_required == 0) || (last_required > last)) last_required = last; @@ -1722,16 +1764,17 @@ PRIVATE int read_group ARGS3( if (last_required-first_required+1 > HTNewsMaxChunk) { /* Trim this block */ first_required = last_required-HTNewsChunkSize+1; } - CTRACE(tfp, " Chunk will be (%d-%d)\n", - first_required, last_required); + CTRACE((tfp, " Chunk will be (%d-%d)\n", + first_required, last_required)); /* ** Set window title. */ - sprintf(buffer, gettext("%s, Articles %d-%d"), + HTSprintf0(&temp, gettext("%s, Articles %d-%d"), groupName, first_required, last_required); START(HTML_H1); - PUTS(buffer); + PUTS(temp); + FREE(temp); END(HTML_H1); PUTC('\n'); @@ -1746,7 +1789,7 @@ PRIVATE int read_group ARGS3( before = first_required-HTNewsChunkSize; HTSprintf0(&dbuf, "%s%s/%d-%d", NewsHREF, groupName, before, first_required-1); - CTRACE(tfp, " Block before is %s\n", dbuf); + CTRACE((tfp, " Block before is %s\n", dbuf)); PUTC('('); start_anchor(dbuf); PUTS(gettext("Earlier articles")); @@ -1761,10 +1804,11 @@ PRIVATE int read_group ARGS3( /*#define USE_XHDR*/ #ifdef USE_XHDR if (count > FAST_THRESHOLD) { - sprintf(buffer, + HTSprintf0(&temp, gettext("\nThere are about %d articles currently available in %s, IDs as follows:\n\n"), count, groupName); - PUTS(buffer); + PUTS(temp); + FREE(temp); sprintf(buffer, "XHDR Message-ID %d-%d%c%c", first, last, CR, LF); status = response(buffer); if (status == 221) { @@ -1775,8 +1819,8 @@ PRIVATE int read_group ARGS3( if (ich == EOF) { if (interrupted_in_htgetcharacter) { interrupted_in_htgetcharacter = 0; - CTRACE(tfp, "HTNews: Interrupted on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n", + s)); NEWS_NETCLOSE(s); s = -1; return(HT_INTERRUPTED); @@ -1786,12 +1830,12 @@ PRIVATE int read_group ARGS3( } if (((char)ich == '\n') || (p == &line[LINE_LENGTH])) { *p = '\0'; /* Terminate the string */ - CTRACE(tfp, "X %s", line); + CTRACE((tfp, "X %s", line)); if (line[0] == '.') { /* ** End of article? */ - if ((unsigned char)line[1] < ' ') { + if (UCH(line[1]) < ' ') { done = YES; break; } else { /* Line starts with dot */ @@ -1875,17 +1919,17 @@ PRIVATE int read_group ARGS3( done = NO; while( !done ) { int ich = NEXT_CHAR; - *p++ = ich; + *p++ = (char) ich; if (ich == EOF) { if (interrupted_in_htgetcharacter) { interrupted_in_htgetcharacter = 0; - CTRACE(tfp, "HTNews: Interrupted on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n", + s)); NEWS_NETCLOSE(s); s = -1; return(HT_INTERRUPTED); } - abort_socket(); /* End of file, close socket */ + abort_socket(); /* End of file, close socket */ return(HT_LOADED); /* End of file on response */ } if (((char)ich == LF) || @@ -1893,24 +1937,21 @@ PRIVATE int read_group ARGS3( *--p = '\0'; /* Terminate & chop LF*/ p = line; /* Restart at beginning */ - CTRACE(tfp, "G %s\n", line); + CTRACE((tfp, "G %s\n", line)); switch(line[0]) { case '.': /* ** End of article? */ - done = ((unsigned char)line[1] < ' '); + done = (BOOL) (UCH(line[1]) < ' '); break; case 'S': case 's': if (match(line, "SUBJECT:")) { - strcpy(subject, line+9);/* Save subject */ - if (HTCJK == JAPANESE) { - HTmmdecode(subject, subject); - HTrjis(subject, subject); - } + LYstrncpy(subject, line+9, sizeof(subject)-1);/* Save subject */ + decode_mime(subject); } break; @@ -1927,12 +1968,10 @@ PRIVATE int read_group ARGS3( case 'F': if (match(line, "FROM:")) { char * p2; - strcpy(author, - author_name(strchr(line,':')+1)); - if (HTCJK == JAPANESE) { - HTmmdecode(author, author); - HTrjis(author, author); - } + LYstrncpy(author, + author_name(strchr(line,':')+1), + sizeof(author)-1); + decode_mime(author); p2 = author + strlen(author) - 1; if (*p2==LF) *p2 = '\0'; /* Chop off newline */ @@ -1953,18 +1992,28 @@ PRIVATE int read_group ARGS3( PUTC('\n'); START(HTML_LI); - sprintf(buffer, "\"%s\"", subject); +#ifdef SH_EX /* for MIME */ + HTSprintf0(&temp, "\"%s\"", decode_mime(subject)); +#else + HTSprintf0(&temp, "\"%s\"", subject); +#endif if (reference) { - write_anchor(buffer, reference); + write_anchor(temp, reference); FREE(reference); } else { - PUTS(buffer); + PUTS(temp); } + FREE(temp); + if (author[0] != '\0') { PUTS(" - "); if (LYListNewsDates) START(HTML_I); +#ifdef SH_EX /* for MIME */ + PUTS(decode_mime(author)); +#else PUTS(author); +#endif if (LYListNewsDates) END(HTML_I); author[0] = '\0'; @@ -1977,7 +2026,7 @@ PRIVATE int read_group ARGS3( } } } - sprintf(buffer, " [%s]", date); + sprintf(buffer, " [%.*s]", (int)(sizeof(buffer) - 4), date); PUTS(buffer); FREE(date); } @@ -1987,8 +2036,8 @@ PRIVATE int read_group ARGS3( */ } else if (status == HT_INTERRUPTED) { interrupted_in_htgetcharacter = 0; - CTRACE(tfp, "HTNews: Interrupted on read, closing socket %d\n", - s); + CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n", + s)); NEWS_NETCLOSE(s); s = -1; return(HT_INTERRUPTED); @@ -2000,7 +2049,7 @@ PRIVATE int read_group ARGS3( START(HTML_LI); START(HTML_I); if (LYListNewsNumbers) - strcpy(buffer, "Status:"); + LYstrncpy(buffer, "Status:", sizeof(buffer) - 1); else sprintf(buffer, "Status (ARTICLE %d):", art); PUTS(buffer); @@ -2029,7 +2078,7 @@ PRIVATE int read_group ARGS3( else HTSprintf0(&dbuf, "%s%s/%d-%d", NewsHREF, groupName, last_required+1, after); - CTRACE(tfp, " Block after is %s\n", dbuf); + CTRACE((tfp, " Block after is %s\n", dbuf)); PUTC('('); start_anchor(dbuf); PUTS(gettext("Later articles")); @@ -2076,17 +2125,18 @@ PRIVATE int HTLoadNews ARGS4( HTFormat, format_out, HTStream*, stream) { - char command[260]; /* The whole command */ - char proxycmd[260]; /* The proxy command */ + char command[262]; /* The whole command */ + char proxycmd[260]; /* The proxy command */ char groupName[GROUP_NAME_LENGTH]; /* Just the group name */ - int status; /* tcp return */ + int status; /* tcp return */ int retries; /* A count of how hard we have tried */ + BOOL normal_url; /* Flag: "news:" or "nntp:" (physical) URL */ BOOL group_wanted; /* Flag: group was asked for, not article */ BOOL list_wanted; /* Flag: list was asked for, not article */ BOOL post_wanted; /* Flag: new post to group was asked for */ BOOL reply_wanted; /* Flag: followup post was asked for */ BOOL spost_wanted; /* Flag: new SSL post to group was asked for */ - BOOL sreply_wanted; /* Flag: followup SSL post was asked for */ + BOOL sreply_wanted; /* Flag: followup SSL post was asked for */ BOOL head_wanted = NO; /* Flag: want HEAD of single article */ int first, last; /* First and last articles asked for */ char *cp = 0; @@ -2094,13 +2144,16 @@ PRIVATE int HTLoadNews ARGS4( char *ProxyHost = NULL; char *ProxyHREF = NULL; char *postfile = NULL; +#ifdef USE_SSL + char SSLprogress[256]; +#endif /* USE_SSL */ diagnostic = (format_out == WWW_SOURCE || /* set global flag */ format_out == HTAtom_for("www/download") || format_out == HTAtom_for("www/dump")); rawtext = NO; - CTRACE(tfp, "HTNews: Looking for %s\n", arg); + CTRACE((tfp, "HTNews: Looking for %s\n", arg)); if (!initialized) initialized = initialize(); @@ -2109,9 +2162,9 @@ PRIVATE int HTLoadNews ARGS4( FREE(NewsHREF); command[0] = '\0'; - command[259] = '\0'; + command[sizeof(command)-1] = '\0'; proxycmd[0] = '\0'; - proxycmd[259] = '\0'; + proxycmd[sizeof(proxycmd)-1] = '\0'; { CONST char * p1 = arg; @@ -2120,26 +2173,27 @@ PRIVATE int HTLoadNews ARGS4( ** We will ask for the document, omitting the host name & anchor. ** ** Syntax of address is - ** xxx@yyy Article + ** xxx@yyy Article ** <xxx@yyy> Same article ** xxxxx News group (no "@") ** group/n1-n2 Articles n1 to n2 in group */ - spost_wanted = (strstr(arg, "snewspost:") != NULL); - sreply_wanted = (!(spost_wanted) && + normal_url = (BOOL) (!strncmp(arg, "news:", 5) || !strncmp(arg, "nntp:", 5)); + spost_wanted = (BOOL) (!normal_url && strstr(arg, "snewspost:") != NULL); + sreply_wanted = (BOOL) (!(normal_url || spost_wanted) && strstr(arg, "snewsreply:") != NULL); - post_wanted = (!(spost_wanted || sreply_wanted) && + post_wanted = (BOOL) (!(normal_url || spost_wanted || sreply_wanted) && strstr(arg, "newspost:") != NULL); - reply_wanted = (!(spost_wanted || sreply_wanted || + reply_wanted = (BOOL) (!(normal_url || spost_wanted || sreply_wanted || post_wanted) && strstr(arg, "newsreply:") != NULL); - group_wanted = (!(spost_wanted || sreply_wanted || + group_wanted = (BOOL) ((!(spost_wanted || sreply_wanted || post_wanted || reply_wanted) && - strchr(arg, '@') == NULL) && (strchr(arg, '*') == NULL); - list_wanted = (!(spost_wanted || sreply_wanted || + strchr(arg, '@') == NULL) && (strchr(arg, '*') == NULL)); + list_wanted = (BOOL) ((!(spost_wanted || sreply_wanted || post_wanted || reply_wanted || group_wanted) && - strchr(arg, '@') == NULL) && (strchr(arg, '*') != NULL); + strchr(arg, '@') == NULL) && (strchr(arg, '*') != NULL)); #ifndef USE_SSL if (!strncasecomp(arg, "snewspost:", 10) || @@ -2175,14 +2229,14 @@ PRIVATE int HTLoadNews ARGS4( StrAllocCopy(NewsHost, cp); } FREE(cp); - sprintf(command, "%s://%.245s/", + HTSprintf0(&NewsHREF, "%s://%.*s/", (post_wanted ? "newspost" : (reply_wanted ? "newreply" : (spost_wanted ? - "snewspost" : "snewsreply"))), NewsHost); - StrAllocCopy(NewsHREF, command); + "snewspost" : "snewsreply"))), + (int) sizeof(command) - 15, NewsHost); /* ** If the SSL daemon is being used as a proxy, @@ -2231,7 +2285,7 @@ PRIVATE int HTLoadNews ARGS4( StrAllocCopy(NewsHost, cp); } FREE(cp); - sprintf(command, "nntp://%.251s/", NewsHost); + SnipIn(command, "nntp://%.*s/", 9, NewsHost); StrAllocCopy(NewsHREF, command); } else if (!strncasecomp(arg, "snews:", 6)) { @@ -2301,7 +2355,7 @@ PRIVATE int HTLoadNews ARGS4( StrAllocCopy(NewsHost, cp); } FREE(cp); - sprintf(command, "news://%.251s/", NewsHost); + SnipIn(command, "news://%.*s/", 9, NewsHost); StrAllocCopy(NewsHREF, command); } else { p1 = (arg + 5); /* Skip "news:" prefix */ @@ -2329,16 +2383,18 @@ PRIVATE int HTLoadNews ARGS4( !strncasecomp(p1, "snewsreply:", 11)) { StrAllocCopy(ProxyHost, NewsHost); if ((cp = HTParse(p1, "", PARSE_HOST)) != NULL && *cp != '\0') { - sprintf(command, "snews://%.250s", cp); + SnipIn(command, "snews://%.*s", 10, cp); StrAllocCopy(NewsHost, cp); } else { - sprintf(command, "snews://%.250s", NewsHost); + SnipIn(command, "snews://%.*s", 10, NewsHost); } - command[258] = '\0'; + command[sizeof(command)-2] = '\0'; FREE(cp); - sprintf(proxycmd, "GET %.251s%c%c%c%c", command, CR, LF, CR, LF); - CTRACE(tfp, "HTNews: Proxy command is '%.*s'\n", - (int)(strlen(proxycmd) - 4), proxycmd); + sprintf(proxycmd, "GET %.*s%c%c%c%c", + (int) sizeof(proxycmd)-9, command, + CR, LF, CR, LF); + CTRACE((tfp, "HTNews: Proxy command is '%.*s'\n", + (int)(strlen(proxycmd) - 4), proxycmd)); strcat(command, "/"); StrAllocCopy(ProxyHREF, NewsHREF); StrAllocCopy(NewsHREF, command); @@ -2353,7 +2409,7 @@ PRIVATE int HTLoadNews ARGS4( } } else { /* - ** Reset p1 so that it points to the newgroup + ** Reset p1 so that it points to the newsgroup ** (or a wildcard), or the article. */ if (!(cp = strrchr((p1 + 6), '/')) || *(cp + 1) == '\0') { @@ -2372,18 +2428,29 @@ PRIVATE int HTLoadNews ARGS4( if (post_wanted || reply_wanted || spost_wanted || sreply_wanted) { strcpy(command, "POST"); } else if (list_wanted) { - sprintf(command, "XGTITLE %.*s", 249, p1); + if (strlen(p1) > 249) { + FREE(ProxyHost); + FREE(ProxyHREF); + HTAlert(URL_TOO_LONG); + return -400; + } + SnipIn(command, "XGTITLE %.*s", 11, p1); } else if (group_wanted) { char * slash = strchr(p1, '/'); - strcpy(command, "GROUP "); first = 0; last = 0; if (slash) { *slash = '\0'; - strcpy(groupName, p1); + if (strlen(p1) >= sizeof(groupName)) { + FREE(ProxyHost); + FREE(ProxyHREF); + HTAlert(URL_TOO_LONG); + return -400; + } + LYstrncpy(groupName, p1, sizeof(groupName) - 1); *slash = '/'; (void)sscanf(slash+1, "%d-%d", &first, &last); - if ((first > 0) && (isdigit(*(slash+1))) && + if ((first > 0) && (isdigit(UCH(*(slash+1)))) && (strchr(slash+1, '-') == NULL || first == last)) { /* ** We got a number greater than 0, which will be @@ -2396,16 +2463,29 @@ PRIVATE int HTLoadNews ARGS4( last = -1; } } else { - strcpy(groupName, p1); + if (strlen(p1) >= sizeof(groupName)) { + FREE(ProxyHost); + FREE(ProxyHREF); + HTAlert(URL_TOO_LONG); + return -400; + } + LYstrncpy(groupName, p1, sizeof(groupName) - 1); } - strcat(command, groupName); + SnipIn(command, "GROUP %.*s", 9, groupName); } else { - strcpy(command, "ARTICLE "); - if (strchr(p1, '<') == 0) - strcat(command,"<"); - strcat(command, p1); - if (strchr(p1, '>') == 0) - strcat(command,">"); + int add_open=(strchr(p1, '<') == 0); + int add_close=(strchr(p1, '>') == 0); + if (strlen(p1) + add_open + add_close >= 252) { + FREE(ProxyHost); + FREE(ProxyHREF); + HTAlert(URL_TOO_LONG); + return -400; + } + sprintf(command, "ARTICLE %s%.*s%s", + add_open ? "<" : "", + (int) (sizeof(command) - (11 + add_open + add_close)), + p1, + add_close ? ">" : ""); } { @@ -2431,14 +2511,14 @@ PRIVATE int HTLoadNews ARGS4( if (!(post_wanted || reply_wanted || spost_wanted || sreply_wanted || (group_wanted && last != -1) || list_wanted)) { head_wanted = anAnchor->isHEAD; - if (head_wanted && !strncmp(command, "ARTICLE_", 8)) { + if (head_wanted && !strncmp(command, "ARTICLE ", 8)) { /* overwrite "ARTICLE" - hack... */ strcpy(command, "HEAD "); for (cp = command + 5; ; cp++) if ((*cp = *(cp + 3)) == '\0') break; } - rawtext = (head_wanted || keep_mime_headers); + rawtext = (BOOL) (head_wanted || keep_mime_headers); } if (rawtext) { node_anchor = anAnchor; @@ -2473,13 +2553,13 @@ PRIVATE int HTLoadNews ARGS4( /* CONNECTING to news host */ char url[260]; if (!strcmp(NewsHREF, "news:")) { - sprintf (url, "lose://%.251s/", NewsHost); + SnipIn (url, "lose://%.*s/", 9, NewsHost); } else if (ProxyHREF) { - sprintf (url, "%.259s", ProxyHREF); + SnipIn (url, "%.*s", 1, ProxyHREF); } else { - sprintf (url, "%.259s", NewsHREF); + SnipIn (url, "%.*s", 1, NewsHREF); } - CTRACE (tfp, "News: doing HTDoConnect on '%s'\n", url); + CTRACE((tfp, "News: doing HTDoConnect on '%s'\n", url)); _HTProgress(gettext("Connecting to NewsHost ...")); @@ -2499,7 +2579,7 @@ PRIVATE int HTLoadNews ARGS4( /* ** Interrupt cleanly. */ - CTRACE(tfp, "HTNews: Interrupted on connect; recovering cleanly.\n"); + CTRACE((tfp, "HTNews: Interrupted on connect; recovering cleanly.\n")); _HTProgress(CONNECTION_INTERRUPTED); if (!(post_wanted || reply_wanted || spost_wanted || sreply_wanted)) { @@ -2525,7 +2605,7 @@ PRIVATE int HTLoadNews ARGS4( if (status < 0) { NEWS_NETCLOSE(s); s = -1; - CTRACE(tfp, "HTNews: Unable to connect to news host.\n"); + CTRACE((tfp, "HTNews: Unable to connect to news host.\n")); if (retries < 1) continue; if (!(post_wanted || reply_wanted || @@ -2544,8 +2624,8 @@ PRIVATE int HTLoadNews ARGS4( } return HTLoadError(stream, 500, dbuf); } else { - CTRACE(tfp, "HTNews: Connected to news host %s.\n", - NewsHost); + CTRACE((tfp, "HTNews: Connected to news host %s.\n", + NewsHost)); #ifdef USE_SSL /* ** If this is an snews url, @@ -2557,12 +2637,16 @@ PRIVATE int HTLoadNews ARGS4( !strncmp(url, "snewsreply:", 11))) { Handle = HTGetSSLHandle(); SSL_set_fd(Handle, s); + HTSSLInitPRNG(); status = SSL_connect(Handle); if (status <= 0) { - CTRACE(tfp, -"HTNews: Unable to complete SSL handshake for remote host '%s' (SSLerror = %d)\n", - url, status); + unsigned long SSLerror; + CTRACE((tfp,"HTNews: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n",url, status)); + SSL_load_error_strings(); + while((SSLerror = ERR_get_error()) != 0) { + CTRACE((tfp,"HTNews: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } HTAlert( "Unable to make secure connection to remote host."); NEWS_NETCLOSE(s); @@ -2586,14 +2670,15 @@ PRIVATE int HTLoadNews ARGS4( } return HT_NOT_LOADED; } - _HTProgress(SSL_get_cipher(Handle)); + sprintf(SSLprogress,"Secure %d-bit %s (%s) NNTP connection",SSL_get_cipher_bits(Handle,NULL),SSL_get_cipher_version(Handle),SSL_get_cipher(Handle)); + _HTProgress(SSLprogress); } #endif /* USE_SSL */ - HTInitInput(s); /* set up buffering */ + HTInitInput(s); /* set up buffering */ if (proxycmd[0]) { status = NEWS_NETWRITE(s, proxycmd, strlen(proxycmd)); - CTRACE(tfp, "HTNews: Proxy command returned status '%d'.\n", - status); + CTRACE((tfp, "HTNews: Proxy command returned status '%d'.\n", + status)); } if (((status = response(NULL)) / 100) != 2) { NEWS_NETCLOSE(s); @@ -2617,13 +2702,23 @@ PRIVATE int HTLoadNews ARGS4( } if (retries < 1) continue; + FREE(ProxyHost); + FREE(ProxyHREF); + FREE(ListArg); + FREE(postfile); if (!(post_wanted || reply_wanted || spost_wanted || sreply_wanted)) { ABORT_TARGET; } - HTSprintf0(&dbuf, + if (response_text[0]) { + HTSprintf0(&dbuf, gettext("Can't read news info. News host %.20s responded: %.200s"), NewsHost, response_text); + } else { + HTSprintf0(&dbuf, + gettext("Can't read news info, empty response from host %s"), + NewsHost); + } return HTLoadError(stream, 500, dbuf); } if (status == 200) { @@ -2668,7 +2763,8 @@ PRIVATE int HTLoadNews ARGS4( return(HT_NOT_LOADED); } if (postfile == NULL) { - postfile = LYNewsPost(ListArg, (reply_wanted || sreply_wanted)); + postfile = LYNewsPost(ListArg, + (BOOLEAN)(reply_wanted || sreply_wanted)); } if (postfile == NULL) { HTProgress(CANCELLED); @@ -2715,6 +2811,12 @@ PRIVATE int HTLoadNews ARGS4( } Send_NNTP_command: +#ifdef NEWS_DEB + if (postfile) + printf("postfile = %s, command = %s", postfile, command); + else + printf("command = %s", command); +#endif if ((status = response(command)) == HT_INTERRUPTED) { _HTProgress(CONNECTION_INTERRUPTED); break; @@ -2731,7 +2833,7 @@ Send_NNTP_command: * to occur in normal use, break from the loop without retrying * and without closing the connection. It is unlikely that * these are leftovers from a timed-out connection (but we do - * some checks to see whether the response rorresponds to the + * some checks to see whether the response corresponds to the * last command), or that they will give anything else when * automatically retried. - kw */ @@ -2875,10 +2977,11 @@ Send_NNTP_command: return status; } /* Retry loop */ - /* HTAlert(gettext("Sorry, could not load requested news.")); */ - -/* NXRunAlertPanel(NULL, "Sorry, could not load `%s'.", - NULL,NULL,NULL, arg);No -- message earlier wil have covered it */ +#if 0 + HTAlert(gettext("Sorry, could not load requested news.")); + NXRunAlertPanel(NULL, "Sorry, could not load `%s'.", NULL,NULL,NULL, arg); + /* No -- message earlier wil have covered it */ +#endif if (!(post_wanted || reply_wanted || spost_wanted || sreply_wanted)) { @@ -2900,7 +3003,7 @@ Send_NNTP_command: /* ** This function clears all authorization information by -** invoking the free_HTAAGlobals() function, which normally +** invoking the free_NNTP_AuthInfo() function, which normally ** is invoked at exit. It allows a browser command to do ** this at any time, for example, if the user is leaving ** the terminal for a period of time, but does not want @@ -2925,35 +3028,46 @@ PUBLIC void HTClearNNTPAuthInfo NOARGS PRIVATE char HTNewsGetCharacter NOARGS { if (!Handle) - return HTGetCharacter(); + return HTGetCharacter(); else - return HTGetSSLCharacter((void *)Handle); + return HTGetSSLCharacter((void *)Handle); } -PUBLIC int HTNewsProxyConnect ARGS5 (int, sock, CONST char *, url, - HTParentAnchor *, anAnchor, - HTFormat, format_out, - HTStream *, sink) +PUBLIC int HTNewsProxyConnect ARGS5 ( + int, sock, + CONST char *, url, + HTParentAnchor *, anAnchor, + HTFormat, format_out, + HTStream *, sink) { int status; CONST char * arg = url; + char SSLprogress[256]; s = channel_s = sock; Handle = HTGetSSLHandle(); SSL_set_fd(Handle, s); + HTSSLInitPRNG(); status = SSL_connect(Handle); if (status <= 0) { - channel_s = -1; - CTRACE(tfp, -"HTTP: Unable to complete SSL handshake for remote host '%s' (SSLerror = %d)\n", - url, status); + unsigned long SSLerror; + channel_s = -1; + CTRACE((tfp,"HTNews: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n",url, status)); + SSL_load_error_strings(); + while((SSLerror = ERR_get_error()) != 0) { + CTRACE((tfp,"HTNews: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } HTAlert("Unable to make secure connection to remote host."); NEWS_NETCLOSE(s); s = -1; return HT_NOT_LOADED; } - _HTProgress(SSL_get_cipher(Handle)); + sprintf(SSLprogress,"Secure %d-bit %s (%s) NNTP connection", + SSL_get_cipher_bits(Handle,NULL), + SSL_get_cipher_version(Handle), + SSL_get_cipher(Handle)); + _HTProgress(SSLprogress); status = HTLoadNews(arg, anAnchor, format_out, sink); channel_s = -1; return status; diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.h index 2e017fce7af..92bf7f33b7b 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTNews.h @@ -13,6 +13,9 @@ #include <HTAccess.h> #include <HTAnchor.h> +extern int HTNewsChunkSize; +extern int HTNewsMaxChunk; + #ifdef GLOBALREF_IS_MACRO extern GLOBALREF(HTProtocol, HTNews); extern GLOBALREF(HTProtocol, HTNNTP); @@ -38,9 +41,13 @@ extern char * HTNewsHost; extern void HTClearNNTPAuthInfo NOPARAMS; -#endif /* HTNEWS_H */ - +#ifdef USE_SSL +extern int HTNewsProxyConnect PARAMS (( + int sock, + CONST char * url, + HTParentAnchor *anAnchor, + HTFormat format_out, + HTStream * sink)); +#endif -/* - - tbl */ +#endif /* HTNEWS_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.c index 097f091d40b..8f58089267d 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.c @@ -14,12 +14,12 @@ struct struct_parts { char * host; char * absolute; char * relative; -/* char * search; no - treated as part of path */ + char * search; /* treated normally as part of path */ char * anchor; }; -/* Strip white space off a string. HTStrip() +/* Strip white space off a string. HTStrip() ** ------------------------------- ** ** On exit, @@ -27,7 +27,7 @@ struct struct_parts { ** All trailing white space is OVERWRITTEN with zero. */ PUBLIC char * HTStrip ARGS1( - char *, s) + char *, s) { #define SPACE(c) ((c == ' ') || (c == '\t') || (c == '\n')) char * p = s; @@ -55,7 +55,7 @@ PUBLIC char * HTStrip ARGS1( ** Any which are nonzero point to zero terminated strings. */ PRIVATE void scan ARGS2( - char *, name, + char *, name, struct struct_parts *, parts) { char * after_access; @@ -68,6 +68,7 @@ PRIVATE void scan ARGS2( parts->host = NULL; parts->absolute = NULL; parts->relative = NULL; + parts->search = NULL; /* normally not used - kw */ parts->anchor = NULL; /* @@ -111,6 +112,12 @@ PRIVATE void scan ARGS2( if (p != NULL) { *p = '\0'; /* Terminate host */ parts->absolute = (p + 1); /* Root has been found */ + } else { + p = strchr(parts->host, '?'); + if (p != NULL) { + *p = '\0'; /* Terminate host */ + parts->search = (p + 1); + } } } else { parts->absolute = (p + 1); /* Root found but no host */ @@ -171,7 +178,7 @@ PRIVATE void scan ARGS2( ** wanted A mask for the bits which are wanted. ** ** On exit, -** returns A pointer to a calloc'd string which MUST BE FREED +** returns A pointer to a calloc'd string which MUST BE FREED */ PUBLIC char * HTParse ARGS3( CONST char *, aName, @@ -187,7 +194,8 @@ PUBLIC char * HTParse ARGS3( char * acc_method; struct struct_parts given, related; - CTRACE(tfp, "HTParse: aName:%s relatedName:%s\n", aName, relatedName); + CTRACE((tfp, "HTParse: aName:`%s'\n", aName)); + CTRACE((tfp, " relatedName:`%s'\n", relatedName)); if (wanted & (PARSE_STRICTPATH | PARSE_QUERY)) { /* if detail wanted... */ if ((wanted & (PARSE_STRICTPATH | PARSE_QUERY)) @@ -200,7 +208,7 @@ PUBLIC char * HTParse ARGS3( ** Allocate the output string. */ len = strlen(aName) + strlen(relatedName) + 10; - result = (char *)calloc(1, len); /* Lots of space: more than enough */ + result = typecallocn(char, len); /* Lots of space: more than enough */ if (result == NULL) { outofmem(__FILE__, "HTParse"); } @@ -260,6 +268,7 @@ PUBLIC char * HTParse ARGS3( related.host = NULL; related.absolute = NULL; related.relative = NULL; + related.search = NULL; related.anchor = NULL; } @@ -283,7 +292,7 @@ PUBLIC char * HTParse ARGS3( if ((p2 = strchr(result, '@')) != NULL) tail = (p2 + 1); p2 = strchr(tail, ':'); - if (p2 != NULL && !isdigit((unsigned char)p2[1])) + if (p2 != NULL && !isdigit(UCH(p2[1]))) /* ** Colon not followed by a port number. */ @@ -319,7 +328,7 @@ PUBLIC char * HTParse ARGS3( if (*h == '.') *h = '\0'; /* chop final . */ } - } else { + } else if (p2 != result) { h = p2; h--; /* End of hostname */ if (*h == '.') { @@ -336,6 +345,23 @@ PUBLIC char * HTParse ARGS3( } /* + ** If host in given or related was ended directly with a '?' (no + ** slash), fake the search part into absolute. This is the only + ** case search is returned from scan. A host must have been present. + ** this restores the '?' at which the host part had been truncated in + ** scan, we have to do this after host part handling is done. - kw + ** + */ + if (given.search && *(given.search - 1) == '\0') { + given.absolute = given.search - 1; + given.absolute[0] = '?'; + } else if (related.search && !related.absolute && + *(related.search - 1) == '\0') { + related.absolute = related.search - 1; + related.absolute[0] = '?'; + } + + /* ** If different hosts, inherit no path. */ if (given.host && related.host) @@ -371,7 +397,7 @@ PUBLIC char * HTParse ARGS3( if (wanted & PARSE_PUNCTUATION) strcat(result, "/"); strcat(result, given.absolute); - CTRACE(tfp, "1\n"); + CTRACE((tfp, "HTParse: (ABS)\n")); } else if (related.absolute) { /* Adopt path not name */ strcat(result, "/"); strcat(result, related.absolute); @@ -385,13 +411,13 @@ PUBLIC char * HTParse ARGS3( strcat(result, given.relative); /* Add given one */ HTSimplify (result); } - CTRACE(tfp, "2\n"); + CTRACE((tfp, "HTParse: (Related-ABS)\n")); } else if (given.relative) { strcat(result, given.relative); /* what we've got */ - CTRACE(tfp, "3\n"); + CTRACE((tfp, "HTParse: (REL)\n")); } else if (related.relative) { strcat(result, related.relative); - CTRACE(tfp, "4\n"); + CTRACE((tfp, "HTParse: (Related-REL)\n")); } else { /* No inheritance */ if (strncasecomp(aName, "lynxcgi:", 8) && strncasecomp(aName, "lynxexec:", 9) && @@ -400,7 +426,7 @@ PUBLIC char * HTParse ARGS3( } if (!strcmp(result, "news:/")) result[5] = '*'; - CTRACE(tfp, "5\n"); + CTRACE((tfp, "HTParse: (No inheritance)\n")); } if (want_detail) { p = strchr(tail, '?'); /* Search part? */ @@ -432,7 +458,7 @@ PUBLIC char * HTParse ARGS3( strcat(result, (given.anchor) ? given.anchor : related.anchor); } - CTRACE(tfp, "HTParse: result:%s\n", result); + CTRACE((tfp, "HTParse: result:%s\n", result)); FREE(rel); FREE(name); @@ -458,7 +484,7 @@ PUBLIC char * HTParse ARGS3( ** or ../../albert.html */ PUBLIC void HTSimplify ARGS1( - char *, filename) + char *, filename) { char *p; char *q, *q1; @@ -656,7 +682,7 @@ PUBLIC char * HTRelative ARGS2( for (; *q && (*q != '#'); q++) if (*q == '/') levels++; - result = (char *)calloc(1, (3*levels + strlen(last_slash) + 1)); + result = typecallocn(char, 3*levels + strlen(last_slash) + 1); if (result == NULL) outofmem(__FILE__, "HTRelative"); result[0] = '\0'; @@ -664,12 +690,13 @@ PUBLIC char * HTRelative ARGS2( strcat(result, "../"); strcat(result, last_slash+1); } - CTRACE(tfp, "HT: `%s' expressed relative to\n `%s' is\n `%s'.", - aName, relatedName, result); + CTRACE((tfp, + "HTparse: `%s' expressed relative to\n `%s' is\n `%s'.\n", + aName, relatedName, result)); return result; } -/* Escape undesirable characters using % HTEscape() +/* Escape undesirable characters using % HTEscape() ** ------------------------------------- ** ** This function takes a pointer to a string in which @@ -682,7 +709,7 @@ PUBLIC char * HTRelative ARGS2( PRIVATE CONST unsigned char isAcceptable[96] = /* Bit 0 xalpha -- see HTFile.h -** Bit 1 xpalpha -- as xalpha but with plus. +** Bit 1 xpalpha -- as xalpha but with plus. ** Bit 2 ... path -- as xpalphas but with / */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ @@ -705,9 +732,9 @@ PUBLIC char * HTEscape ARGS2( char * result; int unacceptable = 0; for (p = str; *p; p++) - if (!ACCEPTABLE((unsigned char)TOASCII(*p))) + if (!ACCEPTABLE(UCH(TOASCII(*p)))) unacceptable++; - result = (char *)calloc(1, (p-str + unacceptable + unacceptable + 1)); + result = typecallocn(char, p-str + unacceptable + unacceptable + 1); if (result == NULL) outofmem(__FILE__, "HTEscape"); for (q = result, p = str; *p; p++) { @@ -727,13 +754,13 @@ PUBLIC char * HTEscape ARGS2( ** -------------------------------- ** ** This function takes a pointer to a string in which -** some characters that may be unsafe are unescaped. +** some characters may be that may be unsafe are unescaped. ** It returns a string which has these characters -** represented by a '%' character followed by two new hex digits. +** represented by a '%' character followed by two hex digits. ** ** Unlike HTUnEscape(), this routine returns a malloc'd string. */ -#define UNSAFE(ch) (((ch) <= 32 ) || ((ch) >= 127)) +#define UNSAFE(ch) (((ch) <= 32) || ((ch) >= 127)) PUBLIC char *HTEscapeUnsafe ARGS1( CONST char *, str) @@ -743,19 +770,19 @@ PUBLIC char *HTEscapeUnsafe ARGS1( char * result; int unacceptable = 0; for (p = str; *p; p++) - if (UNSAFE((unsigned char)TOASCII(*p))) + if (UNSAFE(UCH(TOASCII(*p)))) unacceptable++; - result = (char *)calloc(1, (p-str + unacceptable + unacceptable + 1)); + result = typecallocn(char, p-str + unacceptable + unacceptable + 1); if (result == NULL) - outofmem(__FILE__, "HTEscapeUnsafe"); + outofmem(__FILE__, "HTEscapeUnsafe"); for (q = result, p = str; *p; p++) { - unsigned char a = TOASCII(*p); + unsigned char a = TOASCII(*p); if (UNSAFE(a)) { - *q++ = HEX_ESCAPE; /* Means hex coming */ - *q++ = hex[a >> 4]; - *q++ = hex[a & 15]; - } - else *q++ = *p; + *q++ = HEX_ESCAPE; /* Means hex coming */ + *q++ = hex[a >> 4]; + *q++ = hex[a & 15]; + } + else *q++ = *p; } *q++ = '\0'; /* Terminate */ return result; @@ -781,9 +808,9 @@ PUBLIC char * HTEscapeSP ARGS2( char * result; int unacceptable = 0; for (p = str; *p; p++) - if (!(*p == ' ' || ACCEPTABLE((unsigned char)TOASCII(*p)))) + if (!(*p == ' ' || ACCEPTABLE(UCH(TOASCII(*p))))) unacceptable++; - result = (char *)calloc(1, (p-str + unacceptable + unacceptable + 1)); + result = typecallocn(char, p-str + unacceptable + unacceptable + 1); if (result == NULL) outofmem(__FILE__, "HTEscape"); for (q = result, p = str; *p; p++) { @@ -798,7 +825,7 @@ PUBLIC char * HTEscapeSP ARGS2( *q++ = *p; } } - *q++ = '\0'; /* Terminate */ + *q++ = '\0'; /* Terminate */ return result; } @@ -813,13 +840,13 @@ PUBLIC char * HTEscapeSP ARGS2( PRIVATE char from_hex ARGS1( char, c) { - return c >= '0' && c <= '9' ? c - '0' + return (char) ( c >= '0' && c <= '9' ? c - '0' : c >= 'A' && c <= 'F'? c - 'A' + 10 - : c - 'a' + 10; /* accept small letters just in case */ + : c - 'a' + 10); /* accept small letters just in case */ } PUBLIC char * HTUnEscape ARGS1( - char *, str) + char *, str) { char * p = str; char * q = str; @@ -833,17 +860,18 @@ PUBLIC char * HTUnEscape ARGS1( * Tests shouldn't be needed, but better safe than sorry. */ p[1] && p[2] && - isxdigit((unsigned char)p[1]) && - isxdigit((unsigned char)p[2])) { + isxdigit(UCH(p[1])) && + isxdigit(UCH(p[2]))) { p++; if (*p) - *q = from_hex(*p++) * 16; - if (*p) + *q = (char) (from_hex(*p++) * 16); + if (*p) { /* - ** Careful! FROMASCII() may evaluate its arg more than once! + ** Careful! FROMASCII() may evaluate its arg more than once! */ /* S/390 -- gil -- 0221 */ - *q = *q + from_hex(*p++) ; - *q = FROMASCII(*q ); + *q = (char) (*q + from_hex(*p++)); + } + *q = FROMASCII(*q); q++; } else { *q++ = *p++; @@ -866,7 +894,7 @@ PUBLIC char * HTUnEscape ARGS1( ** The first string is converted in place, as it will never grow. */ PUBLIC char * HTUnEscapeSome ARGS2( - char *, str, + char *, str, CONST char *, do_trans) { char * p = str; @@ -879,9 +907,10 @@ PUBLIC char * HTUnEscapeSome ARGS2( while (*p != '\0') { if (*p == HEX_ESCAPE && p[1] && p[2] && /* tests shouldn't be needed, but.. */ - isxdigit((unsigned char)p[1]) && - isxdigit((unsigned char)p[2]) && - (testcode = FROMASCII(from_hex(p[1])*16 + from_hex(p[2]))) && /* %00 no good*/ + isxdigit(UCH(p[1])) && + isxdigit(UCH(p[2])) && + (testcode = (char) FROMASCII(from_hex(p[1])*16 + + from_hex(p[2]))) && /* %00 no good*/ strchr(do_trans, testcode)) { /* it's one of the ones we want */ *q++ = testcode; p += 3; @@ -898,7 +927,7 @@ PUBLIC char * HTUnEscapeSome ARGS2( PRIVATE CONST unsigned char crfc[96] = /* Bit 0 xalpha -- need "quoting" -** Bit 1 xpalpha -- need \escape if quoted +** Bit 1 xpalpha -- need \escape if quoted */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ { 1,0,3,0,0,0,0,0,1,1,0,0,1,0,1,0, /* 2x !"#$%&'()*+,-./ */ @@ -939,7 +968,7 @@ PUBLIC void HTMake822Word ARGS1( } if (!added) return; - result = (char *)calloc(1, (p-(*str) + added + 1)); + result = typecallocn(char, p-(*str) + added + 1); if (result == NULL) outofmem(__FILE__, "HTMake822Word"); result[0] = '"'; diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.h index 46525bb8d9c..39f276a4704 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTParse.h @@ -36,9 +36,9 @@ ** The following are valid mask values. The terms are the BNF names ** in the URL document. */ -#define URL_XALPHAS (unsigned char) 1 -#define URL_XPALPHAS (unsigned char) 2 -#define URL_PATH (unsigned char) 4 +#define URL_XALPHAS UCH(1) +#define URL_XPALPHAS UCH(2) +#define URL_PATH UCH(4) /* Strip white space off a string. HTStrip() @@ -123,7 +123,7 @@ extern char * HTEscape PARAMS(( CONST char * str, unsigned char mask)); -/* Escape unsafe characters using % HTEscapeUnsafe() +/* Escape unsafe characters using % HTEscapeUnsafe() ** -------------------------------- ** ** This function takes a pointer to a string in which @@ -134,7 +134,7 @@ extern char * HTEscape PARAMS(( ** Unlike HTUnEscape(), this routine returns a malloc'd string. */ extern char * HTEscapeUnsafe PARAMS(( - CONST char * str)); + CONST char * str)); /* Escape undesirable characters using % but space to +. HTEscapeSP() ** ----------------------------------------------------- diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTPlain.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTPlain.c index a1a8a13647a..1ef4ca57fbf 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTPlain.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTPlain.c @@ -32,9 +32,9 @@ extern BOOL HTPassEightBitRaw; extern BOOL HTPassHighCtrlRaw; -extern HTCJKlang HTCJK; PUBLIC int HTPlain_lastraw = -1; +PRIVATE int HTPlain_bs_pending = 0; /* 1:bs 2:underline 3:underline+bs - kw */ /* HTML Object ** ----------- @@ -45,8 +45,8 @@ struct _HTStream { /* ** The node_anchor UCInfo and handle for the input (PARSER) stage. - FM */ - LYUCcharset * inUCI; - int inUCLYhndl; + LYUCcharset * inUCI; + int inUCLYhndl; /* ** The node_anchor UCInfo and handle for the output (HTEXT) stage. - FM */ @@ -131,10 +131,14 @@ PRIVATE void HTPlain_put_character ARGS2( HTPlain_lastraw = -1; return; } - HTPlain_lastraw = c; + if (c == '\b' || c == '_' || HTPlain_bs_pending) { + HTPlain_write(me, &c, 1); + return; + } + HTPlain_lastraw = UCH(c); if (c == '\r') { HText_appendCharacter(me->text, '\n'); - } else if (TOASCII((unsigned char)c) >= 127) { /* S/390 -- gil -- 0305 */ + } else if (TOASCII(UCH(c)) >= 127) { /* S/390 -- gil -- 0305 */ /* ** For now, don't repeat everything here ** that has been done below - KW @@ -142,23 +146,23 @@ PRIVATE void HTPlain_put_character ARGS2( HTPlain_write(me, &c, 1); } else if (HTCJK != NOCJK) { HText_appendCharacter(me->text, c); - } else if (TOASCII((unsigned char)c) >= 127 && TOASCII((unsigned char)c) < 161 && + } else if (TOASCII(UCH(c)) >= 127 && TOASCII(UCH(c)) < 161 && HTPassHighCtrlRaw) { HText_appendCharacter(me->text, c); - } else if ((unsigned char)c == CH_NBSP) { /* S/390 -- gil -- 0341 */ + } else if (UCH(c) == CH_NBSP) { /* S/390 -- gil -- 0341 */ HText_appendCharacter(me->text, ' '); - } else if ((unsigned char)c == CH_SHY) { + } else if (UCH(c) == CH_SHY) { return; - } else if (((unsigned char)c >= ' ' && TOASCII((unsigned char)c) < 127) || + } else if ((UCH(c) >= ' ' && TOASCII(UCH(c)) < 127) || c == '\n' || c == '\t') { HText_appendCharacter(me->text, c); - } else if (TOASCII((unsigned char)c) > 160) { + } else if (TOASCII(UCH(c)) > 160) { if (!HTPassEightBitRaw && !((me->outUCLYhndl == LATIN1) || (me->outUCI->enc & (UCT_CP_SUPERSETOF_LAT1)))) { int len, high, low, i, diff = 1; CONST char * name; - UCode_t value = (UCode_t)FROMASCII((TOASCII((unsigned char)c) - 160)); + UCode_t value = (UCode_t)FROMASCII((TOASCII(UCH(c)) - 160)); name = HTMLGetEntityName(value); len = strlen(name); @@ -228,6 +232,34 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) HText_appendCharacter(me->text, *p); } #else + if (*p == '\b') { + if (HTPlain_lastraw >= UCH(' ') && + HTPlain_lastraw != '\r' && HTPlain_lastraw != '\n') { + if (!HTPlain_bs_pending) { + HTPlain_bs_pending = 1; + continue; + } else if (HTPlain_bs_pending == 2) { + HTPlain_bs_pending = 3; + continue; + } + } + if (HTPlain_bs_pending >= 2) + HText_appendCharacter(me->text, '_'); + HTPlain_bs_pending = 0; + } else if (*p == '_') { + if (!HTPlain_bs_pending) { + HTPlain_bs_pending = 2; + HTPlain_lastraw = UCH(*p); + continue; +#if 0 + } else if (HTPlain_bs_pending != 2) { + HTPlain_bs_pending--; /* 1 -> 0, 3 -> 2 */ + HTPlain_lastraw = UCH(*p); + continue; +#endif + } + } + /* ** Try to handle lone LFs, CRLFs and lone CRs ** as newline, and to deal with control, ASCII, @@ -238,7 +270,35 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) HTPlain_lastraw = -1; continue; } - HTPlain_lastraw = *p; + + if (HTPlain_bs_pending && + !(UCH(*p) >= ' ' && *p != '\r' && *p != '\n' && + (HTPlain_lastraw == UCH(*p) || + HTPlain_lastraw == UCH('_') || + *p == '_'))) { + if (HTPlain_bs_pending >= 2) + HText_appendCharacter(me->text, '_'); + HTPlain_bs_pending = 0; + } else if (HTPlain_bs_pending == 1) { + HTPlain_bs_pending = 0; + continue; /* ignore last two of "X\bX" or "X\b_" - kw */ + } else if (HTPlain_bs_pending == 3) { + if (*p == '_') { + HTPlain_bs_pending = 2; + continue; /* ignore last two of "_\b_" - kw */ + } else { + HTPlain_bs_pending = 0; + /* ignore first two of "_\bX" - kw */ + } + } else if (HTPlain_bs_pending == 2) { + HText_appendCharacter(me->text, '_'); + if (*p == '_') + continue; /* keep second of "__" pending - kw */ + HTPlain_bs_pending = 0; + } else { + HTPlain_bs_pending = 0; + } + HTPlain_lastraw = UCH(*p); if (*p == '\r') { HText_appendCharacter(me->text, '\n'); continue; @@ -248,7 +308,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) ** whenever that's appropriate. - FM */ c = *p; - c_unsign = (unsigned char)c; + c_unsign = UCH(c); code = (UCode_t)c_unsign; saved_char_in = '\0'; /* @@ -283,7 +343,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) code = me->utf_char; if (code > 0 && code < 256) { c = FROMASCII((char)code); - c_unsign = (unsigned char)c; + c_unsign = UCH(c); } } else { /* @@ -349,7 +409,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) ** to Unicode (if appropriate). - FM */ if (!(me->T.decode_utf8 && - (unsigned char)(*p) > 127)) { + UCH(*p) > 127)) { #ifdef NOTDEFINED if (me->T.strip_raw_char_in) saved_char_in = c; @@ -366,7 +426,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) saved_char_in = c; if (code < 256) { c = FROMASCII((char)code); - c_unsign = (unsigned char)c; + c_unsign = UCH(c); } } } else if (code < 32 && code != 0 && @@ -382,7 +442,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) saved_char_in = c; if (code < 256) { c = FROMASCII((char)code); - c_unsign = (unsigned char)c; + c_unsign = UCH(c); } } else { uck = -1; @@ -400,7 +460,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) continue; } else if (uck < 0) { me->utf_buf[0] = '\0'; - code = (unsigned char)c; + code = UCH(c); } else { c = replace_buf[0]; if (c && replace_buf[1]) { @@ -409,11 +469,11 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) } } me->utf_buf[0] = '\0'; - code = (unsigned char)c; + code = UCH(c); } /* Next line end of ugly stuff for C0. - KW */ } else { me->utf_buf[0] = '\0'; - code = (unsigned char)c; + code = UCH(c); } } /* @@ -454,8 +514,15 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) /* ** If neither HTPassHighCtrlRaw nor CJK is set, play it safe ** and ignore 173 (shy). - FM + ** Now only ignore it for color style, which doesn't handle it anyway. + ** Otherwise pass it on as LY_SOFT_HYPHEN and let HText deal with it. + ** It should be either ignored, or displayed as a hyphen if it was + ** indeed at the end of a line. Well it should. - kw */ } else if (code == CH_SHY) { +#ifndef USE_COLOR_STYLE + HText_appendCharacter(me->text, LY_SOFT_HYPHEN); +#endif continue; /* ** If we get to here, pass the displayable ASCII characters. - FM @@ -478,12 +545,12 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) /****************************************************************** * I. LATIN-1 OR UCS2 TO DISPLAY CHARSET ******************************************************************/ - } else if ((chk = (me->T.trans_from_uni && code >= 160)) && + } else if ((chk = (BOOL) (me->T.trans_from_uni && code >= 160)) && (uck = UCTransUniChar(code, me->outUCLYhndl)) >= ' ' && /* S/390 -- gil -- 0464 */ uck < 256) { - CTRACE(tfp, "UCTransUniChar returned 0x%.2lX:'%c'.\n", - uck, FROMASCII((char)uck)); + CTRACE((tfp, "UCTransUniChar returned 0x%.2lX:'%c'.\n", + uck, FROMASCII((char)uck))); HText_appendCharacter(me->text, ((char)(uck & 0xff))); } else if (chk && (uck == -4 || @@ -521,19 +588,19 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) } #ifdef NOTDEFINED } else if (me->T.strip_raw_char_in && - (unsigned char)*p >= 192 && - (unsigned char)*p < 255) { + UCH(*p) >= 192 && + UCH(*p) < 255) { /* ** KOI special: strip high bit, gives ** (somewhat) readable ASCII. */ HText_appendCharacter(me->text, (char)(*p & 0x7f)); #endif /* NOTDEFINED */ - /* - ** If we don't actually want the character, - ** make it safe and output that now. - FM - */ - } else if ((c_unsign > 0 && + /* + ** If we don't actually want the character, + ** make it safe and output that now. - FM + */ + } else if ((c_unsign > 0 && (int) c_unsign < LYlowest_eightbit[me->outUCLYhndl]) || (me->T.trans_from_uni && !HTPassEightBitRaw)) { /* @@ -542,7 +609,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) ** seek a translation for that. Otherwise, or if the ** translation fails, use UHHH notation. - FM */ - if ((chk = (me->outUCLYhndl != + if ((chk = (BOOL) (me->outUCLYhndl != UCGetLYhndl_byMIME("us-ascii"))) && (uck = UCTransUniChar(code, UCGetLYhndl_byMIME("us-ascii"))) @@ -550,9 +617,9 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) /* ** Got an ASCII character (yippey). - FM */ - c = FROMASCII((char)uck); - HText_appendCharacter(me->text, c); - } else if ((chk && uck == -4) && + c = FROMASCII((char)uck); + HText_appendCharacter(me->text, c); + } else if ((chk && uck == -4) && (uck = UCTransUniCharStr(replace_buf, 60, code, UCGetLYhndl_byMIME("us-ascii"), @@ -565,12 +632,12 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) /* ** Ignore 8204 (zwnj) or 8205 (zwj), if we get to here. - FM */ - CTRACE(tfp, "HTPlain_write: Ignoring '%ld'.\n", code); + CTRACE((tfp, "HTPlain_write: Ignoring '%ld'.\n", code)); } else if (code == 8206 || code == 8207) { /* ** Ignore 8206 (lrm) or 8207 (rlm), if we get to here. - FM */ - CTRACE(tfp, "HTPlain_write: Ignoring '%ld'.\n", code); + CTRACE((tfp, "HTPlain_write: Ignoring '%ld'.\n", code)); } else { /* ** Out of luck, so use the UHHH notation (ugh). - FM @@ -585,8 +652,8 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) ** pass it. - FM */ } else if (c_unsign != 0 && c_unsign < 256) { - HText_appendCharacter(me->text, c); - } + HText_appendCharacter(me->text, c); + } #endif /* REMOVE_CR_ONLY */ } } @@ -600,6 +667,8 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l) PRIVATE void HTPlain_free ARGS1( HTStream *, me) { + if (HTPlain_bs_pending >= 2) + HText_appendCharacter(me->text, '_'); FREE(me); } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.c index 97df34e6d33..f2b3432ee2f 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.c @@ -15,6 +15,7 @@ ** Bug Fix: in case of PASS, only one parameter to printf. ** 19 Sep 93 AL Added Access Authorization stuff. ** 1 Nov 93 AL Added htbin. +** 25 May 99 KW Added redirect for lynx. ** */ @@ -35,10 +36,17 @@ typedef struct _rule { HTRuleOp op; char * pattern; char * equiv; + char * condition_op; /* as strings - may be inefficient, */ + char * condition; /* but this is not for a server - kw */ } rule; #ifndef NO_RULES +#include <HTTP.h> /* for redirecting_url, indirectly HTPermitRedir - kw */ +#include <LYGlobalDefs.h> /* for LYUserSpecifiedURL - kw */ +#include <LYUtils.h> /* for LYFixCursesOn - kw */ +#include <HTAlert.h> + /* Global variables ** ---------------- */ @@ -61,44 +69,50 @@ PRIVATE rule * rule_tail = 0; /* Pointer to last on list */ ** -------------------- ** ** On entry, -** pattern points to 0-terminated string containing a single "*" +** pattern points to 0-terminated string containing a single "*" ** equiv points to the equivalent string with * for the ** place where the text matched by * goes. ** On exit, -** returns 0 if success, -1 if error. +** returns 0 if success, -1 if error. */ -PUBLIC int HTAddRule ARGS3( +PUBLIC int HTAddRule ARGS5( HTRuleOp, op, CONST char *, pattern, - CONST char *, equiv) + CONST char *, equiv, + CONST char *, cond_op, + CONST char *, cond) { /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */ rule * temp; - char * pPattern; + char * pPattern = NULL; - temp = (rule *)malloc(sizeof(*temp)); + temp = typecalloc(rule); if (temp==NULL) outofmem(__FILE__, "HTAddRule"); - pPattern = (char *)malloc(strlen(pattern)+1); - if (pPattern==NULL) - outofmem(__FILE__, "HTAddRule"); if (equiv) { /* Two operands */ - char * pEquiv = (char *)malloc(strlen(equiv)+1); - if (pEquiv==NULL) - outofmem(__FILE__, "HTAddRule"); + char * pEquiv = NULL; + StrAllocCopy(pEquiv, equiv); temp->equiv = pEquiv; - strcpy(pEquiv, equiv); } else { temp->equiv = 0; } + if (cond_op) { + StrAllocCopy(temp->condition_op, cond_op); + StrAllocCopy(temp->condition, cond); + } + StrAllocCopy(pPattern, pattern); temp->pattern = pPattern; temp->op = op; - strcpy(pPattern, pattern); if (equiv) { - CTRACE(tfp, "Rule: For `%s' op %d `%s'\n", pattern, op, equiv); + CTRACE((tfp, "Rule: For `%s' op %d `%s'", pattern, op, equiv)); + } else { + CTRACE((tfp, "Rule: For `%s' op %d", pattern, op)); + } + if (cond_op) { + CTRACE((tfp, "\t%s %s\n", cond_op, NONNULL(cond))); } else { - CTRACE(tfp, "Rule: For `%s' op %d\n", pattern, op); + CTRACE((tfp, "\n")); } if (!rules) { @@ -121,7 +135,7 @@ PUBLIC int HTAddRule ARGS3( } -/* Clear all rules HTClearRules() +/* Clear all rules HTClearRules() ** --------------- ** ** On exit, @@ -137,6 +151,8 @@ void HTClearRules NOARGS rules = temp->next; FREE(temp->pattern); FREE(temp->equiv); + FREE(temp->condition_op); + FREE(temp->condition); FREE(temp); } #ifndef PUT_ON_HEAD @@ -144,7 +160,32 @@ void HTClearRules NOARGS #endif } +PRIVATE BOOL rule_cond_ok ARGS1( + rule *, r) +{ + BOOL result; + if (!r->condition_op) + return YES; + if (strcmp(r->condition_op, "if") && strcmp(r->condition_op, "unless")) { + CTRACE((tfp, "....... rule ignored, unrecognized `%s'!\n", + r->condition_op)); + return NO; + } + if (!strcmp(r->condition, "redirected")) + result = (BOOL) (redirection_attempts > 0); + else if (!strcmp(r->condition, "userspec")) + result = LYUserSpecifiedURL; + else { + CTRACE((tfp, "....... rule ignored, unrecognized `%s %s'!\n", + r->condition_op, NONNULL(r->condition))); + return NO; + } + if (!strcmp(r->condition_op, "if")) + return result; + else + return (BOOL) (!result); +} /* Translate by rules HTTranslate() ** ------------------ ** @@ -153,7 +194,7 @@ void HTClearRules NOARGS ** On entry, ** required points to a string whose equivalent value is neeed ** On exit, -** returns the address of the equivalent string allocated from +** returns the address of the equivalent string allocated from ** the heap which the CALLER MUST FREE. If no translation ** occured, then it is a copy of te original. ** NEW FEATURES: @@ -169,6 +210,9 @@ char * HTTranslate ARGS1( { rule * r; char *current = NULL; + char *msgtmp = NULL, *pMsg; + int proxy_none_flag = 0; + int permitredir_flag = 0; StrAllocCopy(current, required); HTAA_clearProtections(); /* Reset from previous call -- AL */ @@ -188,6 +232,9 @@ char * HTTranslate ARGS1( } else /* Not wildcard */ if (*p != *q) continue; /* plain mismatch: go to next rule */ + if (!rule_cond_ok(r)) /* check condition, next rule if false - kw */ + continue; + switch (r->op) { /* Perform operation */ #ifdef ACCESS_AUTH @@ -199,12 +246,12 @@ char * HTTranslate ARGS1( char *eff_ids = NULL; char *prot_file = NULL; - CTRACE(tfp, "HTRule: `%s' matched %s %s: `%s'\n", + CTRACE((tfp, "HTRule: `%s' matched %s %s: `%s'\n", current, (r->op==HT_Protect ? "Protect" : "DefProt"), "rule, setup", (r->equiv ? r->equiv : - (r->op==HT_Protect ?"DEFAULT" :"NULL!!"))); + (r->op==HT_Protect ?"DEFAULT" :"NULL!!")))); if (r->equiv) { StrAllocCopy(local_copy, r->equiv); @@ -225,61 +272,145 @@ char * HTTranslate ARGS1( break; #endif /* ACCESS_AUTH */ + case HT_UserMsg: /* Produce message immediately */ + LYFixCursesOn("show rule message:"); + HTUserMsg2((r->equiv ? r->equiv : "Rule: %s"), current); + break; + case HT_InfoMsg: /* Produce messages immediately */ + case HT_Progress: + case HT_Alert: + LYFixCursesOn("show rule message:"); /* and fall through */ + case HT_AlwaysAlert: + pMsg = r->equiv ? r->equiv : + (r->op==HT_AlwaysAlert) ? "%s" : "Rule: %s"; + if (strchr(pMsg, '%')) { + HTSprintf0(&msgtmp, pMsg, current); + pMsg = msgtmp; + } + switch (r->op) { /* Actually produce message */ + case HT_InfoMsg: HTInfoMsg(pMsg); break; + case HT_Progress: HTProgress(pMsg); break; + case HT_Alert: HTAlert(pMsg); break; + case HT_AlwaysAlert: HTAlwaysAlert("Rule alert:", pMsg); break; + default: break; + } + FREE(msgtmp); + break; + + case HT_PermitRedir: /* Set special flag */ + permitredir_flag = 1; + CTRACE((tfp, "HTRule: Mark for redirection permitted\n")); + break; + case HT_Pass: /* Authorised */ - if (!r->equiv) { - CTRACE(tfp, "HTRule: Pass `%s'\n", current); - return current; + if (!r->equiv) { + if (proxy_none_flag) { + char * temp = NULL; + StrAllocCopy(temp, "NoProxy="); + StrAllocCat(temp, current); + FREE(current); + current = temp; } - /* Else fall through ...to map and pass */ + CTRACE((tfp, "HTRule: Pass `%s'\n", current)); + return current; + } + /* Else fall through ...to map and pass */ case HT_Map: + case HT_Redirect: + case HT_RedirectPerm: if (*p == *q) { /* End of both strings, no wildcard */ - CTRACE(tfp, "For `%s' using `%s'\n", current, r->equiv); + CTRACE((tfp, "For `%s' using `%s'\n", current, r->equiv)); StrAllocCopy(current, r->equiv); /* use entire translation */ } else { char * ins = strchr(r->equiv, '*'); /* Insertion point */ if (ins) { /* Consistent rule!!! */ - char * temp = (char *)malloc( - strlen(r->equiv)-1 + m + 1); - if (temp==NULL) - outofmem(__FILE__, "HTTranslate"); /* NT & AS */ - strncpy(temp, r->equiv, ins-r->equiv); - /* Note: temp may be unterminated now! */ - strncpy(temp+(ins-r->equiv), q, m); /* Matched bit */ - strcpy (temp+(ins-r->equiv)+m, ins+1); /* Last bit */ - CTRACE(tfp, "For `%s' using `%s'\n", - current, temp); + char * temp = NULL; + + HTSprintf0(&temp, "%.*s%.*s%s", + ins - r->equiv, + r->equiv, + m, + q, + ins + 1); + CTRACE((tfp, "For `%s' using `%s'\n", + current, temp)); FREE(current); - current = temp; /* Use this */ + current = temp; /* Use this */ } else { /* No insertion point */ - char * temp = (char *)malloc(strlen(r->equiv)+1); - if (temp==NULL) - outofmem(__FILE__, "HTTranslate"); /* NT & AS */ - strcpy(temp, r->equiv); - CTRACE(tfp, "For `%s' using `%s'\n", - current, temp); + char * temp = NULL; + + StrAllocCopy(temp, r->equiv); + CTRACE((tfp, "For `%s' using `%s'\n", + current, temp)); FREE(current); - current = temp; /* Use this */ + current = temp; /* Use this */ } /* If no insertion point exists */ } if (r->op == HT_Pass) { - CTRACE(tfp, "HTRule: ...and pass `%s'\n", - current); + if (proxy_none_flag) { + char * temp = NULL; + StrAllocCopy(temp, "NoProxy="); + StrAllocCat(temp, current); + FREE(current); + current = temp; + } + CTRACE((tfp, "HTRule: ...and pass `%s'\n", + current)); return current; + } else if (r->op == HT_Redirect) { + CTRACE((tfp, "HTRule: ...and redirect to `%s'\n", + current)); + redirecting_url = current; + HTPermitRedir = (BOOL) (permitredir_flag == 1); + return (char *)0; + } else if (r->op == HT_RedirectPerm) { + CTRACE((tfp, "HTRule: ...and redirect like 301 to `%s'\n", + current)); + redirecting_url = current; + permanent_redirection = TRUE; + HTPermitRedir = (BOOL) (permitredir_flag == 1); + return (char *)0; + } + break; + + case HT_UseProxy: + if (r->equiv && 0==strcasecomp(r->equiv, "none")) { + CTRACE((tfp, "For `%s' will not use proxy\n", current)); + proxy_none_flag = 1; + } else if (proxy_none_flag) { + CTRACE((tfp, "For `%s' proxy server ignored: %s\n", + current, + NONNULL(r->equiv))); + } else { + char * temp = NULL; + StrAllocCopy(temp, "Proxied="); + StrAllocCat(temp, r->equiv); + StrAllocCat(temp, current); + CTRACE((tfp, "HTRule: proxy server found: %s\n", + NONNULL(r->equiv))); + FREE(current); + return temp; } break; case HT_Invalid: case HT_Fail: /* Unauthorised */ - CTRACE(tfp, "HTRule: *** FAIL `%s'\n", - current); + CTRACE((tfp, "HTRule: *** FAIL `%s'\n", + current)); FREE(current); return (char *)0; } /* if tail matches ... switch operation */ } /* loop over rules */ + if (proxy_none_flag) { + char * temp = NULL; + StrAllocCopy(temp, "NoProxy="); + StrAllocCat(temp, current); + return temp; + } return current; } @@ -298,6 +429,7 @@ PUBLIC int HTSetConfiguration ARGS1( char * line = NULL; char * pointer = line; char *word1, *word2, *word3; + char *cond_op=NULL, *cond=NULL; float quality, secs, secs_per_byte; int maxbytes; int status; @@ -334,16 +466,16 @@ PUBLIC int HTSetConfiguration ARGS1( else status = 0; HTSetSuffix(word2, word3, encoding ? encoding : "binary", - status >= 1? quality : 1.0); + status >= 1? quality : (float) 1.0); } else if (0==strcasecomp(word1, "presentation")) { if (pointer) status = sscanf(pointer, "%f%f%f%d", &quality, &secs, &secs_per_byte, &maxbytes); else status = 0; HTSetPresentation(word2, word3, - status >= 1? quality : 1.0, + status >= 1 ? quality : 1.0, status >= 2 ? secs : 0.0, - status >= 3 ? secs_per_byte : 0.0, + status >= 3 ? secs_per_byte : 0.0, status >= 4 ? maxbytes : 0 ); } else if (0==strncasecomp(word1, "htbin", 5) || @@ -357,13 +489,121 @@ PUBLIC int HTSetConfiguration ARGS1( op = 0==strcasecomp(word1, "map") ? HT_Map : 0==strcasecomp(word1, "pass") ? HT_Pass : 0==strcasecomp(word1, "fail") ? HT_Fail + : 0==strcasecomp(word1, "redirect") ? HT_Redirect + : 0==strncasecomp(word1, "redirectperm", 12) ? HT_RedirectPerm + : 0==strcasecomp(word1, "redirecttemp") ? HT_Redirect + : 0==strcasecomp(word1, "permitredirection") ? HT_PermitRedir + : 0==strcasecomp(word1, "useproxy") ? HT_UseProxy + : 0==strcasecomp(word1, "alert") ? HT_Alert + : 0==strcasecomp(word1, "alwaysalert") ? HT_AlwaysAlert + : 0==strcasecomp(word1, "progress") ? HT_Progress + : 0==strcasecomp(word1, "usermsg") ? HT_UserMsg + : 0==strcasecomp(word1, "infomsg") ? HT_InfoMsg : 0==strcasecomp(word1, "defprot") ? HT_DefProt : 0==strcasecomp(word1, "protect") ? HT_Protect : HT_Invalid; if (op==HT_Invalid) { fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config); } else { - HTAddRule(op, word2, word3); + switch (op) { + case HT_Fail: /* never a or other 2nd parameter */ + case HT_PermitRedir: + cond_op = word3; + if (cond_op && *cond_op) { + word3 = NULL; + cond = HTNextField(&pointer); + } + break; + + case HT_Pass: /* possibly a URL2 */ + if (word3 && (!strcasecomp(word3, "if") || + !strcasecomp(word3, "unless"))) { + cond_op = word3; + word3 = NULL; + cond = HTNextField(&pointer); + break; + } /* else fall through */ + + case HT_Map: /* always a URL2 (or other 2nd parameter) */ + case HT_Redirect: + case HT_RedirectPerm: + case HT_UseProxy: + cond_op = HTNextField(&pointer); + /* check for extra status word in "Redirect" */ + if (op==HT_Redirect && 0==strcasecomp(word1, "redirect") && + cond_op && + strcasecomp(cond_op, "if") && + strcasecomp(cond_op, "unless")) { + if (0==strcmp(word2, "301") || + 0==strcasecomp(word2, "permanent")) { + op = HT_RedirectPerm; + } else if (!(0==strcmp(word2, "302") || + 0==strcmp(word2, "303") || + 0==strcasecomp(word2, "temp") || + 0==strcasecomp(word2, "seeother"))) { + CTRACE((tfp, "Rule: Ignoring `%s' in Redirect\n", word2)); + } + word2 = word3; + word3 = cond_op; /* cond_op isn't condition op after all */ + cond_op = HTNextField(&pointer); + } + if (cond_op && *cond_op) + cond = HTNextField(&pointer); + break; + + case HT_Progress: + case HT_InfoMsg: + case HT_UserMsg: + case HT_Alert: + case HT_AlwaysAlert: + cond_op = HTNextField(&pointer); + if (cond_op && *cond_op) + cond = HTNextField(&pointer); + if (word3) { /* Fix string with too may %s - kw */ + char *cp = word3, *cp1, *cp2; + while ((cp1=strchr(cp, '%'))) { + if (cp1[1] == '\0') { + *cp1 = '\0'; + break; + } else if (cp1[1] == '%') { + cp = cp1 + 2; + continue; + } else while ((cp2=strchr(cp1+2, '%'))) { + if (cp2[1] == '\0') { + *cp2 = '\0'; + break; + } else if (cp2[1] == '%') { + cp1 = cp2; + } else { + *cp2 = '?'; /* replace bad % */ + cp1 = cp2; + } + } + break; + } + } + break; + + default: + break; + } + if (cond_op && cond && *cond && !strcasecomp(cond_op, "unless")) { + cond_op = "unless"; + } else if (cond_op && cond && *cond && + !strcasecomp(cond_op, "if")) { + cond_op = "if"; + } else if (cond_op || cond) { + fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config); + FREE(line); /* syntax error, condition is a mess - kw */ + return -2; /* NB unrecognized cond passes here - kw */ + } + if (cond && !strncasecomp(cond, "redirected", strlen(cond))) { + cond = "redirected"; /* recognized, canonical case - kw */ + } else if (cond && strlen(cond) >= 8 && + !strncasecomp(cond, "userspecified", strlen(cond))) { + cond = "userspec"; /* also allow abbreviation - kw */ + } + HTAddRule(op, word2, word3, cond_op, cond); } } FREE(line); @@ -379,7 +619,7 @@ PUBLIC int HTSetConfiguration ARGS1( ** On exit, ** Any existing rules will have been kept. ** Any new rules will have been loaded. -** Returns 0 if no error, 0 if error! +** Returns 0 if no error, 0 if error! ** ** Bugs: ** The strings may not contain spaces. @@ -388,11 +628,11 @@ PUBLIC int HTSetConfiguration ARGS1( int HTLoadRules ARGS1( CONST char *, filename) { - FILE * fp = fopen(filename, "r"); + FILE * fp = fopen(filename, TXT_R); char line[LINE_LENGTH+1]; if (!fp) { - CTRACE(tfp, "HTRules: Can't open rules file %s\n", filename); + CTRACE((tfp, "HTRules: Can't open rules file %s\n", filename)); return -1; /* File open error */ } for(;;) { diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.h index fce782f8a4e..fb4a05d831e 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTRules.h @@ -22,13 +22,22 @@ #include <HTUtils.h> #endif -typedef enum _HTRuleOp { +typedef enum { HT_Invalid, HT_Map, HT_Pass, HT_Fail, HT_DefProt, - HT_Protect + HT_Protect, + HT_Progress, + HT_InfoMsg, + HT_UserMsg, + HT_Alert, + HT_AlwaysAlert, + HT_Redirect, + HT_RedirectPerm, + HT_PermitRedir, + HT_UseProxy } HTRuleOp; #ifndef NO_RULES @@ -57,7 +66,14 @@ HTAddRule: Add rule to the list pattern points to 0-terminated string containing a single "*" equiv points to the equivalent string with * for the place where the - text matched by * goes. + text matched by * goes; or to other 2nd parameter + meaning depends on op). + + cond_op, additional condition for applying rule; cond_op should + cond be either NULL (no additional condition), or one of + the strings "if" or "unless"; if cond_op is not NULL, + cond should point to a recognized condition keyword + (as a string) such as "userspec", "redirected". ON EXIT, @@ -68,7 +84,12 @@ HTAddRule: Add rule to the list large. */ -extern int HTAddRule PARAMS((HTRuleOp op, CONST char * pattern, CONST char * equiv)); +extern int HTAddRule PARAMS(( + HTRuleOp op, + CONST char * pattern, + CONST char * equiv, + CONST char * cond_op, + CONST char * cond)); /* diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStream.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStream.h index dd18e40b348..868e0f419c7 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStream.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStream.h @@ -54,6 +54,17 @@ typedef struct _HTStreamClass { }HTStreamClass; +/* + + Generic Error Stream + + The Error stream simply signals an error on all output methods. + This can be used to stop a stream as soon as data arrives, for + example from the network. + + */ +extern HTStream * HTErrorStream NOPARAMS; + #endif /* HTSTREAM_H */ /* diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c index 90b6665bb3e..210eedcf641 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c @@ -13,13 +13,20 @@ #include <LYLeaks.h> #include <LYStrings.h> -PUBLIC int WWW_TraceFlag = 0; /* Global trace flag for ALL W3 code */ +#ifndef NO_LYNX_TRACE +PUBLIC BOOLEAN WWW_TraceFlag = 0; /* Global trace flag for ALL W3 code */ +PUBLIC int WWW_TraceMask = 0; /* Global trace flag for ALL W3 code */ +#endif #ifndef VC #define VC "unknown" #endif /* !VC */ +#ifdef _WINDOWS +CONST char * HTLibraryVersion = "2.14FM"; /* String for help screen etc */ +#else PUBLIC CONST char * HTLibraryVersion = VC; /* String for help screen etc */ +#endif /* ** strcasecomp8 is a variant of strcasecomp (below) @@ -73,8 +80,82 @@ PUBLIC int strncasecomp8 ARGS3( } /*NOTREACHED*/ } + #ifndef VM /* VM has these already it seems */ +#ifdef SH_EX /* 1997/12/23 (Tue) 16:40:31 */ + +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static unsigned char charmap[] = { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', + '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', + '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', + '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', + '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', + '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', + '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', + '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', + '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', + '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', + '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', + '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', + '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', + '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', + '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', + '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', + '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\327', + '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\337', + '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', + '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', + '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', + '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', +}; + +PUBLIC int strcasecomp ARGS2( + CONST char*, s1, + CONST char*, s2) +{ + register unsigned char *cm = charmap; + register unsigned char *us1 = (unsigned char *)s1; + register unsigned char *us2 = (unsigned char *)s2; + + while (cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return (cm[*us1] - cm[*--us2]); +} + +PUBLIC int strncasecomp ARGS3( + CONST char*, a, + CONST char*, b, + int, n) +{ + register unsigned char *cm = charmap; + register unsigned char *us1 = (unsigned char *)a; + register unsigned char *us2 = (unsigned char *)b; + + while ((long)(--n) >= 0 && cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return ((long)n < 0 ? 0 : cm[*us1] - cm[*--us2]); +} + +#else /* SH_EX */ + /* Strings of any length ** --------------------- */ @@ -120,6 +201,8 @@ PUBLIC int strncasecomp ARGS3( } /*NOTREACHED*/ } + +#endif /* SH_EX */ #endif /* VM */ #ifdef NOT_ASCII @@ -135,7 +218,7 @@ PUBLIC int AS_casecomp ARGS2( for ( ; ; p++, q++) { if (!(*p && *q)) - return ((unsigned char) *p - (unsigned char) *q); + return (UCH(*p) - UCH(*q)); diff = TOASCII(TOLOWER(*p)) - TOASCII(TOLOWER(*q)); if (diff) @@ -159,7 +242,7 @@ PUBLIC int AS_ncmp ARGS3( for ( ; (p-a) < n; p++, q++) { if (!(*p && *q)) - return ((unsigned char) *p - (unsigned char) *q); + return (UCH(*p) - UCH(*q)); diff = TOASCII(*p) - TOASCII(*q); if (diff) @@ -275,7 +358,7 @@ PUBLIC char * HTNextField ARGS1( ** On entry, ** *pstr points to a string to be parsed. ** delims lists characters to be recognized as delimiters. -** If NULL default is white white space "," ";" or "=". +** If NULL, default is white space "," ";" or "=". ** The word can optionally be quoted or enclosed with ** chars from bracks. ** Comments surrrounded by '(' ')' are filtered out @@ -283,7 +366,7 @@ PUBLIC char * HTNextField ARGS1( ** ' ' or '(' in delims or bracks. ** bracks lists bracketing chars. Some are recognized as ** special, for those give the opening char. -** If NULL defaults to <"> and "<" ">". +** If NULL, defaults to <"> and "<" ">". ** found points to location to fill with the ending delimiter ** found, or is NULL. ** @@ -298,7 +381,7 @@ PUBLIC char * HTNextTok ARGS4( char **, pstr, CONST char *, delims, CONST char *, bracks, - char *, found) + char *, found) { char * p = *pstr; char * start = NULL; @@ -310,9 +393,9 @@ PUBLIC char * HTNextTok ARGS4( if (!delims) delims = " ;,=" ; if (!bracks) bracks = "<\"" ; - get_blanks = (!strchr(delims,' ') && !strchr(bracks,' ')); - get_comments = (strchr(bracks,'(') != NULL); - skip_comments = (!get_comments && !strchr(delims,'(') && !get_blanks); + get_blanks = (BOOL) (!strchr(delims,' ') && !strchr(bracks,' ')); + get_comments = (BOOL) (strchr(bracks,'(') != NULL); + skip_comments = (BOOL) (!get_comments && !strchr(delims,'(') && !get_blanks); #define skipWHITE(c) (!get_blanks && WHITE(c)) while (*p && skipWHITE(*p)) @@ -350,9 +433,9 @@ PUBLIC char * HTNextTok ARGS4( if (!*p || (!strchr(bracks,*p) && strchr(delims,*p))) { break; } else - get_closing_char_too = (strchr(bracks,*p) != NULL); + get_closing_char_too = (BOOL) (strchr(bracks,*p) != NULL); } - } else if (strchr(bracks,*p)) { /* quoted or bracketted field */ + } else if (strchr(bracks,*p)) { /* quoted or bracketed field */ switch (*p) { case '<': closer = '>'; break; case '[': closer = ']'; break; @@ -368,16 +451,9 @@ PUBLIC char * HTNextTok ARGS4( if (!*p || (!strchr(bracks,*p) && strchr(delims,*p))) { break; } else - get_closing_char_too = (strchr(bracks,*p) != NULL); + get_closing_char_too = (BOOL) (strchr(bracks,*p) != NULL); } else break; /* kr95-10-9: needs to stop here */ -#if 0 - } else if (*p == '<') { /* quoted field */ - if (!start) start = ++p; - for(;*p && *p!='>'; p++) - if (*p == '\\' && *(p+1)) p++; /* Skip escaped chars */ - break; /* kr95-10-9: needs to stop here */ -#endif } else { /* Spool field */ if (!start) start = p; while(*p && !skipWHITE(*p) && !strchr(bracks,*p) && @@ -416,6 +492,16 @@ PRIVATE char *HTAlloc ARGS2(char *, ptr, size_t, length) } /* + * If SAVE_TIME_NOT_SPACE is defined, StrAllocVsprintf will hang on to + * its temporary string buffers instead of allocating and freeing them + * in each invocation. They only grow and never shrink, and won't be + * cleaned up on exit. - kw + */ +#if defined(_REENTRANT) || defined(_THREAD_SAFE) || defined(LY_FIND_LEAKS) +#undef SAVE_TIME_NOT_SPACE +#endif + +/* * Replacement for sprintf, allocates buffer on the fly according to what's needed * for its arguments. Unlike sprintf, this always concatenates to the destination * buffer, so we do not have to provide both flavors. @@ -433,27 +519,54 @@ typedef enum { Flags, Width, Prec, Type, Format } PRINTF; #define GROW_EXPR(n) (((n) * 3) / 2) #define GROW_SIZE 256 -PRIVATE char * StrAllocVsprintf ARGS4( +PUBLIC_IF_FIND_LEAKS char * StrAllocVsprintf ARGS4( char **, pstr, size_t, dst_len, CONST char *, fmt, va_list *, ap) { +#ifdef SAVE_TIME_NOT_SPACE + static size_t tmp_len = 0; + static size_t fmt_len = 0; + static char *tmp_ptr = NULL; + static char *fmt_ptr = NULL; +#else size_t tmp_len = GROW_SIZE; - size_t have, need; char *tmp_ptr = 0; char *fmt_ptr; +#endif /* SAVE_TIME_NOT_SPACE */ + size_t have, need; char *dst_ptr = *pstr; CONST char *format = fmt; if (fmt == 0 || *fmt == '\0') return 0; +#ifdef USE_VASPRINTF + if (pstr && !dst_len) { + if (*pstr) + FREE(*pstr); + if (vasprintf(pstr, fmt, *ap) >= 0) { + mark_malloced(*pstr, strlen(*pstr)+1); + return(*pstr); + } + } +#endif /* USE_VASPRINTF */ + need = strlen(fmt) + 1; +#ifdef SAVE_TIME_NOT_SPACE + if (!fmt_ptr || fmt_len < need*NUM_WIDTH) { + fmt_ptr = HTAlloc(fmt_ptr, fmt_len = need*NUM_WIDTH); + } + if (!tmp_ptr || tmp_len < GROW_SIZE) { + tmp_ptr = HTAlloc(tmp_ptr, tmp_len = GROW_SIZE); + } +#else if ((fmt_ptr = malloc(need*NUM_WIDTH)) == 0 || (tmp_ptr = malloc(tmp_len)) == 0) { outofmem(__FILE__, "StrAllocVsprintf"); } +#endif /* SAVE_TIME_NOT_SPACE */ if (dst_ptr == 0) { dst_ptr = HTAlloc(dst_ptr, have = GROW_SIZE + need); @@ -482,7 +595,7 @@ PRIVATE char * StrAllocVsprintf ARGS4( while (*++fmt != '\0' && !done) { fmt_ptr[f++] = *fmt; - if (isdigit(*fmt)) { + if (isdigit(UCH(*fmt))) { int num = *fmt - '0'; if (state == Flags && num != 0) state = Width; @@ -506,7 +619,7 @@ PRIVATE char * StrAllocVsprintf ARGS4( } sprintf(&fmt_ptr[--f], "%d", ival); f = strlen(fmt_ptr); - } else if (isalpha(*fmt)) { + } else if (isalpha(UCH(*fmt))) { done = TRUE; switch (*fmt) { case 'Z': /* FALLTHRU */ @@ -535,11 +648,6 @@ PRIVATE char * StrAllocVsprintf ARGS4( case 'E': /* FALLTHRU */ case 'g': /* FALLTHRU */ case 'G': /* FALLTHRU */ -#if 0 /* we don't need this, it doesn't work on SunOS 4.x */ - if (type == 'L') - VA_FLOAT(long double); - else -#endif VA_FLOAT(double); used = 'f'; break; @@ -562,8 +670,8 @@ PRIVATE char * StrAllocVsprintf ARGS4( used = 0; break; default: - CTRACE(tfp, "unknown format character '%c' in %s\n", - *fmt, format); + CTRACE((tfp, "unknown format character '%c' in %s\n", + *fmt, format)); break; } } else if (*fmt == '.') { @@ -580,16 +688,21 @@ PRIVATE char * StrAllocVsprintf ARGS4( case 'f': if (width < prec + NUM_WIDTH) width = prec + NUM_WIDTH; + /* FALLTHRU */ case 'i': + /* FALLTHRU */ case 'p': if (width < prec + 2) width = prec + 2; /* leading sign/space/zero, "0x" */ + break; case 'c': + break; case '%': break; default: if (width < prec) width = prec; + break; } } if (width >= (int)tmp_len) { @@ -623,19 +736,27 @@ PRIVATE char * StrAllocVsprintf ARGS4( } } +#ifndef SAVE_TIME_NOT_SPACE FREE(tmp_ptr); FREE(fmt_ptr); +#endif dst_ptr[dst_len] = '\0'; if (pstr) - *pstr = dst_ptr; + *pstr = dst_ptr; return (dst_ptr); } +#undef SAVE_TIME_NOT_SPACE /* * Replacement for sprintf, allocates buffer on the fly according to what's needed * for its arguments. Unlike sprintf, this always concatenates to the destination * buffer. */ +/* Note: if making changes, also check the memory tracking version + * LYLeakHTSprintf in LYLeaks.c. - kw */ +#ifdef HTSprintf /* if hidden by LYLeaks stuff */ +#undef HTSprintf +#endif #if ANSI_VARARGS PUBLIC char * HTSprintf (char ** pstr, CONST char * fmt, ...) #else @@ -667,6 +788,11 @@ PUBLIC char * HTSprintf (va_alist) * needed for its arguments. Like sprintf, this always resets the destination * buffer. */ +/* Note: if making changes, also check the memory tracking version + * LYLeakHTSprintf0 in LYLeaks.c. - kw */ +#ifdef HTSprintf0 /* if hidden by LYLeaks stuff */ +#undef HTSprintf0 +#endif #if ANSI_VARARGS PUBLIC char * HTSprintf0 (char ** pstr, CONST char * fmt, ...) #else @@ -683,6 +809,15 @@ PUBLIC char * HTSprintf0 (va_alist) char ** pstr = va_arg(ap, char **); CONST char * fmt = va_arg(ap, CONST char *); #endif +#ifdef USE_VASPRINTF + if (pstr) { + if (*pstr) + FREE(*pstr); + if (vasprintf(pstr, fmt, ap) >= 0) /* else call outofmem?? */ + mark_malloced(*pstr, strlen(*pstr)+1); + result = *pstr; + } else +#endif /* USE_VASPRINTF */ result = StrAllocVsprintf(pstr, 0, fmt, &ap); } va_end(ap); @@ -708,7 +843,7 @@ PUBLIC char *HTQuoteParameter ARGS1( for (i=0; i < last; ++i) if (strchr("\\&#$^*?(){}<>\"';`|", parameter[i]) != 0 - || isspace(parameter[i])) + || isspace(UCH(parameter[i]))) ++quoted; result = (char *)malloc(last + 5*quoted + 3); @@ -725,10 +860,14 @@ PUBLIC char *HTQuoteParameter ARGS1( result[n++] = parameter[i]; result[n++] = D_QUOTE; result[n++] = S_QUOTE; - } else if (parameter[i] == '\\') { - result[n++] = parameter[i]; - result[n++] = parameter[i]; } else { + /* Note: No special handling of other characters, including + backslash, since we are constructing a single-quoted string! + Backslash has no special escape meaning within those for sh + and compatible shells, so trying to escape a backslash by + doubling it is unnecessary and would be interpreted by the + shell as an additional data character. - kw 2000-05-02 + */ result[n++] = parameter[i]; } } @@ -806,12 +945,12 @@ PUBLIC void HTAddXpand ARGS4( if (HTIsParam(next)) { if (next != last) { size_t len = (next - last) - + ((*result != 0) ? strlen(*result) : 0); + + ((*result != 0) ? strlen(*result) : 0); HTSACat(result, last); (*result)[len] = 0; } HTSACat(result, parameter); - CTRACE(tfp, "PARAM-EXP:%s\n", *result); + CTRACE((tfp, "PARAM-EXP:%s\n", *result)); return; } next++; @@ -840,7 +979,9 @@ PUBLIC void HTAddParam ARGS4( if (number > 0) { CONST char *last = HTAfterCommandArg(command, number - 1); CONST char *next = last; +#if USE_QUOTED_PARAMETER char *quoted; +#endif if (number <= 1) { FREE(*result); @@ -851,7 +992,7 @@ PUBLIC void HTAddParam ARGS4( if (HTIsParam(next)) { if (next != last) { size_t len = (next - last) - + ((*result != 0) ? strlen(*result) : 0); + + ((*result != 0) ? strlen(*result) : 0); HTSACat(result, last); (*result)[len] = 0; } @@ -862,7 +1003,7 @@ PUBLIC void HTAddParam ARGS4( #else HTSACat(result, parameter); #endif - CTRACE(tfp, "PARAM-ADD:%s\n", *result); + CTRACE((tfp, "PARAM-ADD:%s\n", *result)); return; } next++; @@ -888,5 +1029,67 @@ PUBLIC void HTEndParam ARGS3( if (last[0] != 0) { HTSACat(result, last); } - CTRACE(tfp, "PARAM-END:%s\n", *result); + CTRACE((tfp, "PARAM-END:%s\n", *result)); +} + + +#ifdef EXP_FILE_UPLOAD +/* bstring Allocate and Concatenate +*/ + +/* Allocate a new copy of a bstring, and returns it +*/ +PUBLIC void HTSABCopy ARGS3( + bstring**, dest, + CONST char *, src, + int, len) +{ + bstring *t; + CTRACE((tfp, "HTSABCopy(%p, %p, %d)\n", dest, src, len)); + /* if we already have a bstring ** ... */ + if (dest) { + /* ... with a valid bstring *, free it ... */ + if (*dest) { + FREE((*dest)->str); + FREE(*dest); + } + *dest = malloc(sizeof(bstring)); + if (src) { + CTRACE((tfp, "%% [%s]\n", src)); + t = (bstring*) malloc(sizeof(bstring)); + if (t == NULL) + outofmem(__FILE__, "HTSABCopy"); + t->str = (char *) malloc (len); + if (t->str == NULL) + outofmem(__FILE__, "HTSABCopy"); + memcpy (t->str, src, len); + t->len = len; + *dest = t; + } + } +} + +PUBLIC void HTSABCat ARGS3( + bstring **, dest, + CONST char *, src, + int, len) +{ + bstring *t = *dest; + if (src) { + if (t) { + int length = t->len; + t->str = (char *)realloc(t->str, length + len); + } else { + t = typecalloc(bstring); + if (t == NULL) + outofmem(__FILE__, "HTSACat"); + t->str = (char *)malloc(len); + } + if (t->str == NULL) + outofmem(__FILE__, "HTSACat"); + memcpy (t->str + t->len, src, len); + t->len += len; + *dest = t; + } } +#endif /* EXP_FILE_UPLOAD */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.h index 2891b29544c..53c52cd6792 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.h @@ -11,8 +11,6 @@ #include <HTUtils.h> #endif /* HTUTILS_H */ -extern int WWW_TraceFlag; /* Global flag for all W3 trace */ - extern CONST char * HTLibraryVersion; /* String for help screen etc */ /* @@ -81,7 +79,15 @@ extern char * HTSprintf () GCC_PRINTFLIKE(2,3); extern char * HTSprintf0 () GCC_PRINTFLIKE(2,3); #endif -#if defined(VMS) || defined(DOSPATH) || defined(__EMX__) +#if defined(LY_FIND_LEAKS) /* private otherwise */ +extern char * StrAllocVsprintf PARAMS(( + char ** pstr, + size_t len, + CONST char * fmt, + va_list * ap)); +#endif + +#if (defined(VMS) || defined(DOSPATH) || defined(__EMX__)) && !defined(__CYGWIN__) #define USE_QUOTED_PARAMETER 0 #else #define USE_QUOTED_PARAMETER 1 @@ -102,4 +108,16 @@ extern void HTEndParam PARAMS((char ** result, CONST char * command, int number) /* Force an option, with leading blanks, to be appended without quoting them */ #define HTOptParam(result, command, number, parameter) HTSACat(result, parameter) +/* Binary copy and concat */ +#ifdef EXP_FILE_UPLOAD + +typedef struct { + char *str; + int len; +} bstring; + +extern void HTSABCopy PARAMS((bstring** dest, CONST char * src, int len)); +extern void HTSABCat PARAMS((bstring ** dest, CONST char * src, int len)); +#endif + #endif /* HTSTRING_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.c index c5cabf78a11..2e8494d237b 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.c @@ -186,7 +186,7 @@ HTStyle * HTStyleNamed ARGS2 (HTStyleSheet *,self, CONST char *,name) HTStyle * scan; for (scan=self->styles; scan; scan=scan->next) if (0==strcmp(scan->name, name)) return scan; - CTRACE(tfp, "StyleSheet: No style named `%s'\n", name); + CTRACE((tfp, "StyleSheet: No style named `%s'\n", name)); return NULL; } @@ -237,8 +237,8 @@ HTStyle * HTStyleForRun (HTStyleSheet *self, NXRun *run) } } } - CTRACE(tfp, "HTStyleForRun: Best match for style is %d out of 18\n", - bestMatch); + CTRACE((tfp, "HTStyleForRun: Best match for style is %d out of 18\n", + bestMatch)); return best; } #endif /* NEXT_SUPRESS */ @@ -329,7 +329,7 @@ HTStyleSheet * HTStyleSheetRead(HTStyleSheet * self, NXStream * stream) HTStyle * style; char styleName[80]; NXScanf(stream, " %d ", &numStyles); - CTRACE(tfp, "Stylesheet: Reading %d styles\n", numStyles); + CTRACE((tfp, "Stylesheet: Reading %d styles\n", numStyles)); for (i=0; i<numStyles; i++) { NXScanf(stream, "%s", styleName); style = HTStyleNamed(self, styleName); @@ -357,7 +357,7 @@ HTStyleSheet * HTStyleSheetWrite(HTStyleSheet * self, NXStream * stream) for(style=self->styles; style; style=style->next) numStyles++; NXPrintf(stream, "%d\n", numStyles); - CTRACE(tfp, "StyleSheet: Writing %d styles\n", numStyles); + CTRACE((tfp, "StyleSheet: Writing %d styles\n", numStyles)); for (style=self->styles; style; style=style->next) { NXPrintf(stream, "%s ", style->name); (void) HTStyleWrite(style, stream); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.h index 0cc15895ed1..be958f079c4 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTStyle.h @@ -116,6 +116,7 @@ typedef struct _HTStyle { } HTStyle; +#define HT_ALIGN_NONE (-1) /* Style functions: */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.c index 1a6b2621502..fd916955c4a 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.c @@ -25,13 +25,17 @@ #ifdef NSL_FORK #include <signal.h> -#include <sys/wait.h> +#include <www_wait.h> #endif /* NSL_FORK */ #ifdef HAVE_RESOLV_H #include <resolv.h> #endif +#if defined(__DJGPP__) && defined (WATT32) +#include <netdb.h> +#endif /* __DJGPP__ */ + #define OK_HOST(p) ((p) != 0 && ((p)->h_length) != 0) #ifdef SVR4_BSDSELECT @@ -40,7 +44,7 @@ PUBLIC int BSDselect PARAMS(( fd_set * readfds, fd_set * writefds, fd_set * exceptfds, - struct timeval * timeout)); + struct timeval * select_timeout)); #ifdef select #undef select #endif /* select */ @@ -87,42 +91,33 @@ PUBLIC unsigned long socks_bind_remoteAddr; /* for long Rbind */ ** global errno gives the error number in the Unix way. ** ** On return, -** returns a negative status in the Unix way. +** returns a negative status in the Unix way. */ -#ifndef PCNFS - -#ifdef VMS -#include <perror.h> -#ifndef errno -extern int errno; -#endif /* !errno */ -#endif /* VMS */ - -#ifndef VM -#ifndef VMS -#ifndef THINK_C #ifdef DECL_SYS_ERRLIST extern char *sys_errlist[]; /* see man perror on cernvax */ extern int sys_nerr; #endif /* DECL_SYS_ERRLIST */ -#endif /* !THINK_C */ -#endif /* !VMS */ -#endif /* !VM */ - -#endif /* !PCNFS */ - #ifdef _WINDOWS_NSL - char host[512]; - struct hostent *phost; /* Pointer to host - See netdb.h */ - int donelookup; +char host[512]; +struct hostent *phost; /* Pointer to host - See netdb.h */ +int donelookup; -unsigned long _fork_func (void *arglist) +static unsigned long _fork_func (void *arglist) { - phost = gethostbyname(host); - donelookup = TRUE; - return (unsigned long)(phost); +#ifdef SH_EX + unsigned long addr; + addr = (unsigned long)inet_addr(host); + if ((int)addr != -1) + phost = gethostbyaddr((char *)&addr, sizeof (addr), AF_INET); + else + phost = gethostbyname(host); +#else + phost = gethostbyname(host); +#endif + donelookup = TRUE; + return (unsigned long)(phost); } #endif /* _WINDOWS_NSL */ @@ -131,9 +126,7 @@ unsigned long _fork_func (void *arglist) ** A routine to mimic the ioctl function for UCX. ** Bjorn S. Nilsson, 25-Nov-1993. Based on an example in the UCX manual. */ -#include <iodef.h> -#define IOC_OUT (int)0x40000000 -extern int vaxc$get_sdc(), sys$qiow(); +#include <HTioctl.h> PUBLIC int HTioctl ARGS3( int, d, @@ -154,7 +147,7 @@ PUBLIC int HTioctl ARGS3( } ioctl_desc; if ((sdc = vaxc$get_sdc (d)) == 0) { - errno = EBADF; + set_errno(EBADF); return -1; } ioctl_desc.opt = UCX$C_IOCTL; @@ -173,81 +166,90 @@ PUBLIC int HTioctl ARGS3( ioctl_comm.addr = (char *)argp; status = sys$qiow (0, sdc, fun, iosb, 0, 0, 0, 0, 0, 0, p5, p6); if (!(status & 01)) { - errno = status; + set_errno(status); return -1; } if (!(iosb[0] & 01)) { - errno = iosb[0]; + set_errno(iosb[0]); return -1; } return 0; } #endif /* VMS && UCX */ +#define MY_FORMAT "TCP: Error %d in `SOCKET_ERRNO' after call to %s() failed.\n\t%s\n" + /* third arg is transport/platform specific */ + /* Report Internet Error ** --------------------- */ PUBLIC int HTInetStatus ARGS1( - char *, where) + char *, where) { + int status; + int saved_errno = errno; #ifdef VMS #ifdef MULTINET SOCKET_ERRNO = vmserrno; #endif /* MULTINET */ #endif /* VMS */ - CTRACE(tfp, - "TCP: Error %d in `SOCKET_ERRNO' after call to %s() failed.\n\t%s\n", - SOCKET_ERRNO, where, - /* third arg is transport/platform specific */ #ifdef VM - "(Error number not translated)"); /* What Is the VM equiv? */ + CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where, + "(Error number not translated)")); /* What Is the VM equiv? */ #define ER_NO_TRANS_DONE #endif /* VM */ #ifdef VMS #ifdef MULTINET - vms_errno_string()); + CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where, + vms_errno_string())); #else + CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where, ((SOCKET_ERRNO > 0 && SOCKET_ERRNO <= 65) ? - strerror(SOCKET_ERRNO) : "(Error number not translated)")); + strerror(SOCKET_ERRNO) : "(Error number not translated)"))); #endif /* MULTINET */ #define ER_NO_TRANS_DONE #endif /* VMS */ #ifdef HAVE_STRERROR - strerror(SOCKET_ERRNO)); + CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where, + strerror(SOCKET_ERRNO))); #define ER_NO_TRANS_DONE #endif /* HAVE_STRERROR */ #ifndef ER_NO_TRANS_DONE + CTRACE((tfp, MY_FORMAT, SOCKET_ERRNO, where, (SOCKET_ERRNO < sys_nerr ? - sys_errlist[SOCKET_ERRNO] : "Unknown error" )); + sys_errlist[SOCKET_ERRNO] : "Unknown error" ))); #endif /* !ER_NO_TRANS_DONE */ #ifdef VMS #ifndef MULTINET - CTRACE(tfp, + CTRACE((tfp, " Unix error number (SOCKET_ERRNO) = %ld dec\n", - SOCKET_ERRNO); - CTRACE(tfp, + SOCKET_ERRNO)); + CTRACE((tfp, " VMS error (vaxc$errno) = %lx hex\n", - vaxc$errno); + vaxc$errno)); #endif /* MULTINET */ #endif /* VMS */ + set_errno(saved_errno); + #ifdef VMS /* ** uerrno and errno happen to be zero if vmserrno <> 0 */ #ifdef MULTINET - return -vmserrno; + status = -vmserrno; #else - return -vaxc$errno; + status = -vaxc$errno; #endif /* MULTINET */ #else - return -SOCKET_ERRNO; + status = -SOCKET_ERRNO; #endif /* VMS */ + return status; } /* Parse a cardinal value parse_cardinal() @@ -295,15 +297,23 @@ PUBLIC unsigned int HTCardinal ARGS3( ** it is to be kept. */ PUBLIC CONST char * HTInetString ARGS1( - SockA*, soc_in) + SockA*, soc_in) { - static char string[16]; +#ifdef INET6 + static char hostbuf[MAXHOSTNAMELEN]; + getnameinfo((struct sockaddr *)soc_in, + SOCKADDR_LEN(soc_in), + hostbuf, sizeof(hostbuf), NULL, 0, NI_NUMERICHOST); + return hostbuf; +#else + static char string[20]; sprintf(string, "%d.%d.%d.%d", (int)*((unsigned char *)(&soc_in->sin_addr)+0), (int)*((unsigned char *)(&soc_in->sin_addr)+1), (int)*((unsigned char *)(&soc_in->sin_addr)+2), (int)*((unsigned char *)(&soc_in->sin_addr)+3)); return string; +#endif /* INET6 */ } #endif /* !DECNET */ @@ -314,6 +324,7 @@ PUBLIC CONST char * HTInetString ARGS1( ** - contains only valid chars for domain names (actually, the ** restrictions are somewhat relaxed), ** - no leading dots or empty segments, +** - no segment starts with '-' or '+' [this protects telnet command], ** - max. length of dot-separated segment <= 63 (RFC 1034,1035), ** - total length <= 254 (if it ends with dot) or 253 (otherwise) ** [an interpretation of RFC 1034,1035, although RFC 1123 @@ -327,10 +338,10 @@ PUBLIC CONST char * HTInetString ARGS1( ** returns 1 if valid, otherwise 0. */ PUBLIC BOOL valid_hostname ARGS1( - CONST char *, name) + char *, name) { int i=1, iseg = 0; - CONST char *cp = name; + char *cp = name; if (!(name && *name)) return NO; for (; (*cp && i <= 253); cp++, i++) { @@ -341,16 +352,18 @@ PUBLIC BOOL valid_hostname ARGS1( iseg = 0; continue; } + } else if (iseg == 0 && (*cp == '-' || *cp == '+')) { + return NO; } else if (++iseg > 63) { - return NO; + return NO; } - if (!isalnum((unsigned char)*cp) && + if (!isalnum(UCH(*cp)) && *cp != '-' && *cp != '_' && *cp != '$' && *cp != '+') { return NO; } } - return (*cp == '\0' || (*cp == '.' && iseg != 0 && cp[1] == '\0')); + return (BOOL) (*cp == '\0' || (*cp == '.' && iseg != 0 && cp[1] == '\0')); } #ifdef NSL_FORK @@ -368,7 +381,7 @@ PRIVATE void quench ARGS1( PUBLIC int lynx_nsl_status = HT_OK; -#ifndef DJGPP /* much excluded! */ +#if !( defined(__DJGPP__) && !defined(WATT32) ) /* much excluded! */ #define DEBUG_HOSTENT /* disable in case of problems */ #define DEBUG_HOSTENT_CHILD /* for NSL_FORK, may screw up trace file */ @@ -387,52 +400,52 @@ PRIVATE void dump_hostent ARGS2( if (TRACE) { int i; char **pcnt; - CTRACE(tfp,"%s: %p ", msgprefix, phost); + CTRACE((tfp,"%s: %p ", msgprefix, phost)); if (phost) { - CTRACE(tfp,"{ h_name = %p", phost->h_name); + CTRACE((tfp,"{ h_name = %p", phost->h_name)); if (phost->h_name) { - CTRACE(tfp, " \"%s\",", phost->h_name); + CTRACE((tfp, " \"%s\",", phost->h_name)); } else { - CTRACE(tfp, ","); + CTRACE((tfp, ",")); } - CTRACE(tfp,"\n\t h_aliases = %p", phost->h_aliases); + CTRACE((tfp,"\n\t h_aliases = %p", phost->h_aliases)); if (phost->h_aliases) { - CTRACE(tfp, " {"); + CTRACE((tfp, " {")); for (pcnt = phost->h_aliases; *pcnt; pcnt++) { - CTRACE(tfp,"%s %p \"%s\"", + CTRACE((tfp,"%s %p \"%s\"", (pcnt == phost->h_aliases ? " " : ", "), - *pcnt, *pcnt); + *pcnt, *pcnt)); } - CTRACE(tfp, "%s0x0 },\n\t", - (*phost->h_aliases ? ", " : " ")); + CTRACE((tfp, "%s0x0 },\n\t", + (*phost->h_aliases ? ", " : " "))); } else { - CTRACE(tfp, ",\n\t"); + CTRACE((tfp, ",\n\t")); } - CTRACE(tfp," h_addrtype = %d,", phost->h_addrtype); - CTRACE(tfp," h_length = %d,\n\t", phost->h_length); - CTRACE(tfp," h_addr_list = %p", phost->h_addr_list); + CTRACE((tfp," h_addrtype = %d,", phost->h_addrtype)); + CTRACE((tfp," h_length = %d,\n\t", phost->h_length)); + CTRACE((tfp," h_addr_list = %p", phost->h_addr_list)); if (phost->h_addr_list) { - CTRACE(tfp, " {"); + CTRACE((tfp, " {")); for (pcnt = phost->h_addr_list; *pcnt; pcnt++) { - CTRACE(tfp,"%s %p", + CTRACE((tfp,"%s %p", (pcnt == phost->h_addr_list ? "" : ","), - *pcnt); + *pcnt)); for (i = 0; i < phost->h_length; i++) { - CTRACE(tfp, "%s%d%s", (i==0 ? " \"" : "."), + CTRACE((tfp, "%s%d%s", (i==0 ? " \"" : "."), (int)*((unsigned char *)(*pcnt)+i), - (i+1 == phost->h_length ? "\"" : "")); + (i+1 == phost->h_length ? "\"" : ""))); } } if (*phost->h_addr_list) { - CTRACE(tfp, ", 0x0 } }"); + CTRACE((tfp, ", 0x0 } }")); } else { - CTRACE(tfp, " 0x0 } }"); + CTRACE((tfp, " 0x0 } }")); } } else { - CTRACE(tfp, "}"); + CTRACE((tfp, "}")); } } - CTRACE(tfp,"\n"); + CTRACE((tfp,"\n")); fflush(tfp); } } @@ -445,11 +458,21 @@ PRIVATE void dump_hostent ARGS2( ** cast to a struct hostent. - kw ** See also description of LYGetHostByName. */ +#ifdef NSL_FORK + +#define REHOSTENT_SIZE 128 /* not bigger than pipe buffer! */ + +typedef struct { + struct hostent h; + char rest[REHOSTENT_SIZE]; + } AlignedHOSTENT; + PRIVATE size_t fill_rehostent ARGS3( char *, rehostent, size_t, rehostentsize, CONST struct hostent *, phost) { + AlignedHOSTENT *data = (AlignedHOSTENT *)rehostent; int num_addrs = 0; int num_aliases = 0; char **pcnt; @@ -509,8 +532,8 @@ PRIVATE size_t fill_rehostent ARGS3( } } - ((struct hostent *)rehostent)->h_addrtype = phost->h_addrtype; - ((struct hostent *)rehostent)->h_length = phost->h_length; + data->h.h_addrtype = phost->h_addrtype; + data->h.h_length = phost->h_length; p_next_charptr = (char **)(rehostent + curlen); p_next_char = rehostent + curlen; if (phost->h_addr_list) @@ -519,7 +542,7 @@ PRIVATE size_t fill_rehostent ARGS3( p_next_char += (num_aliases+1) * sizeof(phost->h_aliases[0]); if (phost->h_addr_list) { - ((struct hostent *)rehostent)->h_addr_list = p_next_charptr; + data->h.h_addr_list = p_next_charptr; for (pcnt=phost->h_addr_list, i_addr = 0; i_addr < num_addrs; pcnt++, i_addr++) { @@ -529,11 +552,11 @@ PRIVATE size_t fill_rehostent ARGS3( } *p_next_charptr++ = NULL; } else { - ((struct hostent *)rehostent)->h_addr_list = NULL; + data->h.h_addr_list = NULL; } if (phost->h_name) { - ((struct hostent *)rehostent)->h_name = p_next_char; + data->h.h_name = p_next_char; if (name_len) { strcpy(p_next_char, phost->h_name); p_next_char += name_len + 1; @@ -541,11 +564,11 @@ PRIVATE size_t fill_rehostent ARGS3( *p_next_char++ = '\0'; } } else { - ((struct hostent *)rehostent)->h_name = NULL; + data->h.h_name = NULL; } if (phost->h_aliases) { - ((struct hostent *)rehostent)->h_aliases = p_next_charptr; + data->h.h_aliases = p_next_charptr; for (pcnt=phost->h_aliases, i_alias = 0; (*pcnt && i_alias < num_addrs); pcnt++, i_alias++) { @@ -563,21 +586,22 @@ PRIVATE size_t fill_rehostent ARGS3( } *p_next_charptr++ = NULL; } else { - ((struct hostent *)rehostent)->h_aliases = NULL; + data->h.h_aliases = NULL; } curlen = p_next_char - (char *)rehostent; return curlen; } - -#define REHOSTENT_SIZE 128 /* not bigger than pipe buffer! */ +#endif /* NSL_FORK */ #ifndef HAVE_H_ERRNO #undef h_errno #define h_errno my_errno static int my_errno; #else /* we do HAVE_H_ERRNO: */ +#ifndef h_errno /* there may be a macro as well as the extern data */ extern int h_errno; #endif +#endif /* Resolve an internet hostname, like gethostbyname ** ------------------------------------------------ @@ -614,17 +638,14 @@ extern int h_errno; ** HT_INTERNAL Internal error */ PUBLIC struct hostent * LYGetHostByName ARGS1( - CONST char *, str) + char *, str) { #ifndef _WINDOWS_NSL - CONST char *host = str; -#endif /* _WINDOWS_NSL */ + char *host = str; +#endif #ifdef NSL_FORK /* for transfer of result between from child to parent: */ - static struct { - struct hostent h; - char rest[REHOSTENT_SIZE]; - } aligned_full_rehostent; + static AlignedHOSTENT aligned_full_rehostent; /* * We could define rehosten directly as a * static char rehostent[REHOSTENT_SIZE], @@ -645,7 +666,7 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( struct _statuses { size_t rehostentlen; int h_length; - int child_errno; /* maybe not very useful */ + int child_errno; /* sometimes useful to pass this on */ int child_h_errno; BOOL h_errno_valid; } statuses; @@ -656,38 +677,40 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( struct hostent *result_phost = NULL; if (!str) { - CTRACE(tfp, "LYGetHostByName: Can't parse `NULL'.\n"); + CTRACE((tfp, "LYGetHostByName: Can't parse `NULL'.\n")); lynx_nsl_status = HT_INTERNAL; return NULL; } - CTRACE(tfp, "LYGetHostByName: parsing `%s'.\n", str); + CTRACE((tfp, "LYGetHostByName: parsing `%s'.\n", str)); /* Could disable this if all our callers already check - kw */ if (HTCheckForInterrupt()) { - CTRACE (tfp, "LYGetHostByName: INTERRUPTED for '%s'.\n", str); + CTRACE((tfp, "LYGetHostByName: INTERRUPTED for '%s'.\n", str)); lynx_nsl_status = HT_INTERRUPTED; return NULL; } +#ifdef _WINDOWS_NSL + strncpy(host, str, sizeof(host)); +#endif /* _WINDOWS_NSL */ + if (!valid_hostname(host)) { lynx_nsl_status = HT_NOT_ACCEPTABLE; #ifdef NO_RECOVERY +#ifdef _WINDOWS + WSASetLastError(NO_RECOVERY); +#else h_errno = NO_RECOVERY; #endif +#endif return NULL; } -#ifdef _WINDOWS_NSL - strncpy(host, str, (size_t)512); -#else - host = str; -#endif /* _WINDOWS_NSL */ - #ifdef MVS /* Outstanding problem with crash in MVS gethostbyname */ - CTRACE(tfp, "LYGetHostByName: Calling gethostbyname(%s)\n", host); + CTRACE((tfp, "LYGetHostByName: Calling gethostbyname(%s)\n", host)); #endif /* MVS */ - CTRACE_FLUSH(tfp); /* so child messages will not mess parent log */ + CTRACE_FLUSH(tfp); /* so child messages will not mess up parent log */ lynx_nsl_status = HT_INTERNAL; /* should be set to something else below */ @@ -699,16 +722,25 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( */ { int got_rehostent = 0; +#if HAVE_SIGACTION + sigset_t old_sigset; + sigset_t new_sigset; +#endif /* ** Pipe, child pid, status buffers, start time, select() ** control variables. */ pid_t fpid, waitret; - int pfd[2], selret, readret, waitstat = 0; - time_t start_time = time(NULL); + int pfd[2], selret, readret; +#ifdef HAVE_TYPE_UNIONWAIT + union wait waitstat; +#else + int waitstat = 0; +#endif + time_t start_time = time((time_t *)0); fd_set readfds; - struct timeval timeout; - int dns_patience = 30; /* how many seconds will we wait for DNS? */ + struct timeval one_second; + long dns_patience = 30; /* how many seconds will we wait for DNS? */ int child_exited = 0; /* @@ -727,6 +759,32 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( pipe(pfd); +#if HAVE_SIGACTION + /* + * Attempt to prevent a rare situation where the child + * could execute the Lynx signal handlers because it gets + * killed before it even has a chance to reset its handlers, + * resulting in bogus 'Exiting via interrupt' message and + * screen corruption or worse. + * Should that continue to be reported, for systems without + * sigprocmask(), we need to find a different solutions for + * those. - kw 19990430 + */ + sigemptyset(&new_sigset); + sigaddset(&new_sigset, SIGTERM); + sigaddset(&new_sigset, SIGINT); +#ifndef NOSIGHUP + sigaddset(&new_sigset, SIGHUP); +#endif /* NOSIGHUP */ +#ifdef SIGTSTP + sigaddset(&new_sigset, SIGTSTP); +#endif /* SIGTSTP */ +#ifdef SIGWINCH + sigaddset(&new_sigset, SIGWINCH); +#endif /* SIGWINCH */ + sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset); +#endif /* HAVE_SIGACTION */ + if ((fpid = fork()) == 0 ) { struct hostent *phost; /* Pointer to host - See netdb.h */ /* @@ -764,15 +822,28 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( signal(SIGSEGV, SIG_DFL); signal(SIGILL, SIG_DFL); +#if HAVE_SIGACTION + /* Restore signal mask to whatever it was before the fork. -kw */ + sigprocmask(SIG_SETMASK, &old_sigset, NULL); +#endif /* HAVE_SIGACTION */ + /* ** Child won't use read side. -BL */ close(pfd[0]); +#ifdef HAVE_H_ERRNO + /* to detect cases when it doesn't get set although it should */ + h_errno = -2; +#endif + set_errno(0); phost = gethostbyname(host); + statuses.child_errno = errno; statuses.child_h_errno = h_errno; +#ifdef HAVE_H_ERRNO statuses.h_errno_valid = YES; +#endif #ifdef MVS - CTRACE(tfp, "LYGetHostByName: gethostbyname() returned %d\n", phost); + CTRACE((tfp, "LYGetHostByName: gethostbyname() returned %d\n", phost)); #endif /* MVS */ #ifdef DEBUG_HOSTENT_CHILD @@ -790,12 +861,17 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( statuses.h_length = 0; } else { statuses.h_length = ((struct hostent *)rehostent)->h_length; +#ifdef HAVE_H_ERRNO + if (h_errno == -2) /* success, but h_errno unchanged? */ + statuses.h_errno_valid = NO; +#endif } /* ** Send variables indicating status of lookup to parent. ** That includes rehostentlen, which the parent will use ** as the size for the second read (if > 0). */ + if (!statuses.child_errno) statuses.child_errno = errno; statuses.rehostentlen = rehostentlen; write(pfd[1], &statuses, sizeof(statuses)); @@ -815,6 +891,14 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( } } +#if HAVE_SIGACTION + /* + ** (parent) Restore signal mask to whatever it was + ** before the fork. - kw + */ + sigprocmask(SIG_SETMASK, &old_sigset, NULL); +#endif /* HAVE_SIGACTION */ + /* ** (parent) Wait until lookup finishes, or interrupt, ** or cycled too many times (just in case) -BL @@ -827,7 +911,7 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( goto failed; } - while (child_exited || time(NULL) - start_time < dns_patience) { + while (child_exited || (long)(time((time_t *)0) - start_time) < dns_patience) { FD_ZERO(&readfds); /* @@ -847,8 +931,8 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( } } - timeout.tv_sec = 1; - timeout.tv_usec = 0; + one_second.tv_sec = 1; + one_second.tv_usec = 0; FD_SET(pfd[0], &readfds); /* @@ -858,10 +942,10 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( */ #ifdef SOCKS if (socks_flag) - selret = Rselect(pfd[0] + 1, (void *)&readfds, NULL, NULL, &timeout); + selret = Rselect(pfd[0] + 1, (void *)&readfds, NULL, NULL, &one_second); else #endif /* SOCKS */ - selret = select(pfd[0] + 1, (void *)&readfds, NULL, NULL, &timeout); + selret = select(pfd[0] + 1, (void *)&readfds, NULL, NULL, &one_second); if ((selret > 0) && FD_ISSET(pfd[0], &readfds)) { /* @@ -870,9 +954,45 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( readret = read(pfd[0], &statuses, sizeof(statuses)); if (readret == sizeof(statuses)) { h_errno = statuses.child_h_errno; - errno = statuses.child_errno; - if (statuses.h_errno_valid) + set_errno(statuses.child_errno); +#ifdef HAVE_H_ERRNO + if (statuses.h_errno_valid) { lynx_nsl_status = HT_H_ERRNO_VALID; + /* + * If something went wrong in the child process + * other than normal lookup errors, and it appears + * that we have enough info to know what went wrong, + * generate diagnostic output. + * ENOMEM observed on linux in processes constrained + * with ulimit. It would be too unkind to abort + * the session, access to local files or through a + * proxy may still work. - kw + */ + if ( +#ifdef NETDB_INTERNAL /* linux glibc: defined in netdb.h */ + (errno && h_errno == NETDB_INTERNAL) || +#endif + (errno == ENOMEM && + statuses.rehostentlen == 0 && + /* should probably be NETDB_INTERNAL if child + memory exhausted, but we may find that + h_errno remains unchanged. - kw */ + h_errno == -2)) { +#ifndef MULTINET + HTInetStatus("CHILD gethostbyname"); +#endif + HTAlert(LYStrerror(statuses.child_errno)); + if (errno == ENOMEM) { + /* + * Not much point in continuing, right? + * Fake a 'z', should shorten pointless + * guessing cycle. - kw + */ + LYFakeZap(YES); + } + } + } +#endif /* HAVE_H_ERRNO */ if (statuses.rehostentlen > sizeof(struct hostent)) { /* ** Then get the full reorganized hostent. -BL, kw @@ -888,7 +1008,7 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( } else if (!statuses.h_errno_valid) { lynx_nsl_status = HT_INTERNAL; } - } + } } else { lynx_nsl_status = HT_ERROR; } @@ -928,7 +1048,7 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( ** Abort if interrupt key pressed. */ if (HTCheckForInterrupt()) { - CTRACE(tfp, "LYGetHostByName: INTERRUPTED gethostbyname.\n"); + CTRACE((tfp, "LYGetHostByName: INTERRUPTED gethostbyname.\n")); kill(fpid, SIGTERM); waitpid(fpid, NULL, WNOHANG); close(pfd[0]); @@ -943,20 +1063,20 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( } if (waitret > 0) { if (WIFEXITED(waitstat)) { - CTRACE(tfp, "LYGetHostByName: NSL_FORK child %d exited, status 0x%x.\n", - (int)waitret, waitstat); + CTRACE((tfp, "LYGetHostByName: NSL_FORK child %d exited, status 0x%x.\n", + (int)waitret, WEXITSTATUS(waitstat))); } else if (WIFSIGNALED(waitstat)) { - CTRACE(tfp, "LYGetHostByName: NSL_FORK child %d got signal, status 0x%x!\n", - (int)waitret, waitstat); + CTRACE((tfp, "LYGetHostByName: NSL_FORK child %d got signal, status 0x%x!\n", + (int)waitret, WTERMSIG(waitstat))); #ifdef WCOREDUMP if (WCOREDUMP(waitstat)) { - CTRACE(tfp, "LYGetHostByName: NSL_FORK child %d dumped core!\n", - (int)waitret); + CTRACE((tfp, "LYGetHostByName: NSL_FORK child %d dumped core!\n", + (int)waitret)); } #endif /* WCOREDUMP */ } else if (WIFSTOPPED(waitstat)) { - CTRACE(tfp, "LYGetHostByName: NSL_FORK child %d is stopped, status 0x%x!\n", - (int)waitret, waitstat); + CTRACE((tfp, "LYGetHostByName: NSL_FORK child %d is stopped, status 0x%x!\n", + (int)waitret, WEXITSTATUS(waitstat))); } } if (!got_rehostent) { @@ -967,50 +1087,53 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( #ifdef _WINDOWS_NSL { -#ifdef __BORLANDC__ - HANDLE hThread, dwThreadID; -#else - unsigned long hThread, dwThreadID; -#endif /* __BORLANDC__ */ - phost = (struct hostent *) NULL; - hThread = CreateThread((void *)NULL, 4096UL, -#ifdef __BORLANDC__ - (LPTHREAD_START_ROUTINE)_fork_func, -#else - (unsigned long (*)())_fork_func, -#endif /* __BORLANDC__ */ - (void *)NULL, 0UL, (unsigned long *)&dwThreadID); - if (!hThread) - MessageBox((void *)NULL, "CreateThread", - "CreateThread Failed", 0L); - - donelookup = FALSE; - while (!donelookup) - if (HTCheckForInterrupt()) - { - /* Note that host is a character array and is not freed */ - /* to avoid possible subthread problems: */ - if (!CloseHandle(hThread)) - MessageBox((void *)NULL, "CloseHandle","CloseHandle Failed", - 0L); - lynx_nsl_status = HT_INTERRUPTED; - return NULL; - }; - if (phost) { - lynx_nsl_status = HT_OK; - result_phost = phost; - } else { - lynx_nsl_status = HT_ERROR; - goto failed; + HANDLE hThread, dwThreadID; + + if (!system_is_NT) { /* for Windows9x */ + unsigned long t; + t = (unsigned long)inet_addr(host); + if ((int)t != -1) + phost = gethostbyaddr((char *)&t, sizeof (t), AF_INET); + else + phost = gethostbyname(host); + } else { /* for Windows NT */ + phost = (struct hostent *) NULL; + donelookup = FALSE; + hThread = CreateThread((void *)NULL, 4096UL, + (LPTHREAD_START_ROUTINE)_fork_func, + (void *)NULL, 0UL, (unsigned long *)&dwThreadID); + if (!hThread) + MessageBox((void *)NULL, "CreateThread", + "CreateThread Failed", 0L); + + while (!donelookup) { + if (HTCheckForInterrupt()) { + /* Note that host is a character array and is not freed */ + /* to avoid possible subthread problems: */ + if (!CloseHandle(hThread)) { + MessageBox((void *)NULL, + "CloseHandle","CloseHandle Failed", 0L); + } + lynx_nsl_status = HT_INTERRUPTED; + return NULL; } - }; + } + } + if (phost) { + lynx_nsl_status = HT_OK; + result_phost = phost; + } else { + lynx_nsl_status = HT_ERROR; + goto failed; + } + } #else /* !NSL_FORK, !_WINDOWS_NSL: */ { struct hostent *phost; - phost = gethostbyname((char *)host); /* See netdb.h */ + phost = gethostbyname(host); /* See netdb.h */ #ifdef MVS - CTRACE(tfp, "LYGetHostByName: gethostbyname() returned %d\n", phost); + CTRACE((tfp, "LYGetHostByName: gethostbyname() returned %d\n", phost)); #endif /* MVS */ if (phost) { lynx_nsl_status = HT_OK; @@ -1025,18 +1148,18 @@ PUBLIC struct hostent * LYGetHostByName ARGS1( #ifdef DEBUG_HOSTENT dump_hostent("End of LYGetHostByName", result_phost); - CTRACE(tfp, "LYGetHostByName: Resolved name to a hostent.\n"); + CTRACE((tfp, "LYGetHostByName: Resolved name to a hostent.\n")); #endif return result_phost; /* OK */ failed: - CTRACE(tfp, "LYGetHostByName: Can't find internet node name `%s'.\n", - host); + CTRACE((tfp, "LYGetHostByName: Can't find internet node name `%s'.\n", + host)); return NULL; } -#endif /* from here on DJGPP joins us again. */ +#endif /* from here on DJGPP without WATT32 joins us again. */ /* Parse a network node address and port @@ -1051,27 +1174,29 @@ failed: ** *soc_in is filled in. If no port is specified in str, that ** field is left unchanged in *soc_in. */ -PUBLIC int HTParseInet ARGS2( +#ifndef INET6 +PRIVATE int HTParseInet ARGS2( SockA *, soc_in, CONST char *, str) { char *port; int dotcount_ip = 0; /* for dotted decimal IP addr */ + char *strptr; #ifndef _WINDOWS_NSL char *host = NULL; #endif /* _WINDOWS_NSL */ if (!str) { - CTRACE(tfp, "HTParseInet: Can't parse `NULL'.\n"); + CTRACE((tfp, "HTParseInet: Can't parse `NULL'.\n")); return -1; } - CTRACE(tfp, "HTParseInet: parsing `%s'.\n", str); + CTRACE((tfp, "HTParseInet: parsing `%s'.\n", str)); if (HTCheckForInterrupt()) { - CTRACE (tfp, "HTParseInet: INTERRUPTED for '%s'.\n", str); + CTRACE((tfp, "HTParseInet: INTERRUPTED for '%s'.\n", str)); return -1; } #ifdef _WINDOWS_NSL - strncpy(host, str, (size_t)512); + strncpy(host, str, sizeof(host)); #else StrAllocCopy(host, str); /* Make a copy we can mutilate */ #endif /* _WINDOWS_NSL */ @@ -1080,26 +1205,34 @@ PUBLIC int HTParseInet ARGS2( */ if ((port = strchr(host, ':')) != NULL) { *port++ = 0; /* Chop off port */ + strptr = port; if (port[0] >= '0' && port[0] <= '9') { -#ifdef unix - soc_in->sin_port = htons(atol(port)); +#ifdef UNIX + soc_in->sin_port = (PortNumber)htons(strtol(port, &strptr, 10)); #else /* VMS: */ #ifdef DECNET - soc_in->sdn_objnum = (unsigned char)(strtol(port, (char**)0, 10)); + soc_in->sdn_objnum = (unsigned char)(strtol(port, &strptr, 10)); #else - soc_in->sin_port = htons((unsigned short)strtol(port,(char**)0,10)); + soc_in->sin_port = htons((PortNumber)strtol(port, &strptr, 10)); #endif /* Decnet */ #endif /* Unix vs. VMS */ -#ifdef SUPPRESS /* 1. crashes!?!. 2. Not recommended */ +#ifdef SUPPRESS /* 1. crashes!?!. 2. URL syntax has number not name */ } else { struct servent * serv = getservbyname(port, (char*)0); if (serv) { soc_in->sin_port = serv->s_port; } else { - CTRACE(tfp, "TCP: Unknown service %s\n", port); + CTRACE((tfp, "TCP: Unknown service %s\n", port)); } #endif /* SUPPRESS */ } + if (strptr && *strptr != '\0') { +#ifndef _WINDOWS_NSL + FREE(host); +#endif /* _WINDOWS_NSL */ + HTAlwaysAlert(NULL, gettext("Address has invalid port")); + return -1; + } } #ifdef DECNET @@ -1109,16 +1242,16 @@ PUBLIC int HTParseInet ARGS2( */ soc_in->sdn_nam.n_len = min(DN_MAXNAML, strlen(host)); /* <=6 in phase 4 */ strncpy(soc_in->sdn_nam.n_name, host, soc_in->sdn_nam.n_len + 1); - CTRACE(tfp, "DECnet: Parsed address as object number %d on host %.6s...\n", - soc_in->sdn_objnum, host); + CTRACE((tfp, "DECnet: Parsed address as object number %d on host %.6s...\n", + soc_in->sdn_objnum, host)); #else /* parse Internet host: */ if (*host >= '0' && *host <= '9') { /* Test for numeric node address: */ - char *strptr = host; + strptr = host; while (*strptr) { if (*strptr == '.') { dotcount_ip++; - } else if (!isdigit(*strptr)) { + } else if (!isdigit(UCH(*strptr))) { break; } strptr++; @@ -1131,9 +1264,10 @@ PUBLIC int HTParseInet ARGS2( /* ** Parse host number if present. */ - if (dotcount_ip == 3) { /* Numeric node address: */ + if (dotcount_ip == 3) /* Numeric node address: */ + { -#ifdef DJGPP +#if defined(__DJGPP__) && !defined(WATT32) soc_in->sin_addr.s_addr = htonl(aton(host)); #else #ifdef DGUX_OLD @@ -1144,7 +1278,7 @@ PUBLIC int HTParseInet ARGS2( #else #ifdef HAVE_INET_ATON if (!inet_aton(host, &(soc_in->sin_addr))) { - CTRACE(tfp, "inet_aton(%s) returns error\n", host); + CTRACE((tfp, "inet_aton(%s) returns error\n", host)); #ifndef _WINDOWS_NSL FREE(host); #endif /* _WINDOWS_NSL */ @@ -1155,17 +1289,18 @@ PUBLIC int HTParseInet ARGS2( #endif /* HAVE_INET_ATON */ #endif /* GUSI */ #endif /* DGUX_OLD */ -#endif /* DJGPP */ +#endif /* __DJGPP__ && !WATT32 */ #ifndef _WINDOWS_NSL FREE(host); #endif /* _WINDOWS_NSL */ - } else { /* Alphanumeric node name: */ + } else + { /* Alphanumeric node name: */ #ifdef MVS /* Outstanding problem with crash in MVS gethostbyname */ - CTRACE(tfp, "HTParseInet: Calling LYGetHostByName(%s)\n", host); + CTRACE((tfp, "HTParseInet: Calling LYGetHostByName(%s)\n", host)); #endif /* MVS */ -#ifdef DJGPP +#if defined(__DJGPP__) && !defined(WATT32) if (!valid_hostname(host)) { FREE(host); return HT_NOT_ACCEPTABLE; /* only HTDoConnect checks this. */ @@ -1174,12 +1309,12 @@ PUBLIC int HTParseInet ARGS2( if (soc_in->sin_addr.s_addr == 0) { goto failed; } -#else /* !DJGPP: */ +#else /* !(__DJGPP__ && !WATT32) */ #ifdef _WINDOWS_NSL phost = LYGetHostByName(host); /* See above */ if (!phost) goto failed; memcpy((void *)&soc_in->sin_addr, phost->h_addr, phost->h_length); -#else /* !DJGPP, !_WINDOWS_NSL: */ +#else /* !(__DJGPP__ && !WATT32) && !_WINDOWS_NSL */ { struct hostent *phost; phost = LYGetHostByName(host); /* See above */ @@ -1203,38 +1338,83 @@ PUBLIC int HTParseInet ARGS2( memcpy((void *)&soc_in->sin_addr, phost->h_addr, phost->h_length); #endif /* VMS && CMU_TCP */ } -#endif /* !DJGPP, !_WINDOWS_NSL */ -#endif /* !DJGPP */ +#endif /* _WINDOWS_NSL */ +#endif /* __DJGPP__ && !WATT32 */ #ifndef _WINDOWS_NSL FREE(host); #endif /* _WINDOWS_NSL */ } /* Alphanumeric node name */ - CTRACE(tfp, "HTParseInet: Parsed address as port %d, IP address %d.%d.%d.%d\n", + CTRACE((tfp, "HTParseInet: Parsed address as port %d, IP address %d.%d.%d.%d\n", (int)ntohs(soc_in->sin_port), (int)*((unsigned char *)(&soc_in->sin_addr)+0), (int)*((unsigned char *)(&soc_in->sin_addr)+1), (int)*((unsigned char *)(&soc_in->sin_addr)+2), - (int)*((unsigned char *)(&soc_in->sin_addr)+3)); + (int)*((unsigned char *)(&soc_in->sin_addr)+3))); #endif /* Internet vs. Decnet */ return 0; /* OK */ failed: - CTRACE(tfp, "HTParseInet: Can't find internet node name `%s'.\n", - host); + CTRACE((tfp, "HTParseInet: Can't find internet node name `%s'.\n", + host)); #ifndef _WINDOWS_NSL FREE(host); #endif /* _WINDOWS_NSL */ switch (lynx_nsl_status) { - case HT_NOT_ACCEPTABLE: - case HT_INTERRUPTED: - return lynx_nsl_status; - default: - return -1; + case HT_NOT_ACCEPTABLE: + case HT_INTERRUPTED: + return lynx_nsl_status; + default: + return -1; + } } +#endif /* !INET6 */ + +#ifdef INET6 +PRIVATE struct addrinfo * +HTGetAddrInfo ARGS2( + CONST char *, str, + CONST int, defport) +{ + struct addrinfo hints, *res; + int error; + char *p; + char *s; + char *host, *port; + char pbuf[10]; + + s = strdup(str); + + if (s[0] == '[' && (p = strchr(s, ']')) != NULL) { + *p++ = '\0'; + host = s + 1; + } else { + p = s; + host = &s[0]; + } + port = strrchr(p, ':'); + if (port) { + *port++ = '\0'; + } else { + snprintf(pbuf, sizeof(pbuf), "%d", defport); + port = pbuf; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(host, port, &hints, &res); + if (error || !res) { + CTRACE((tfp, "HTGetAddrInfo: getaddrinfo(%s, %s): %s\n", host, port, + gai_strerror(error))); + res = NULL; + } + + return res; } +#endif /* INET6 */ #ifdef LY_FIND_LEAKS /* Free our name for the host on which we are - FM @@ -1262,12 +1442,17 @@ PRIVATE void get_host_details NOARGS char *domain_name; /* The name of this host domain */ #endif /* UCX */ #ifdef NEED_HOST_ADDRESS /* no -- needs name server! */ +#ifdef INET6 + struct addrinfo hints, *res; + int error; +#else struct hostent * phost; /* Pointer to host -- See netdb.h */ +#endif /* INET6 */ #endif /* NEED_HOST_ADDRESS */ int namelength = sizeof(name); if (hostname) - return; /* Already done */ + return; /* Already done */ gethostname(name, namelength); /* Without domain */ StrAllocCopy(hostname, name); #ifdef LY_FIND_LEAKS @@ -1278,28 +1463,47 @@ PRIVATE void get_host_details NOARGS ** UCX doesn't give the complete domain name. ** Get rest from UCX$BIND_DOM logical. */ - if (strchr(hostname,'.') == NULL) { /* Not full address */ + if (strchr(hostname,'.') == NULL) { /* Not full address */ domain_name = getenv("UCX$BIND_DOMAIN"); + if (domain_name == NULL) + domain_name = getenv("TCPIP$BIND_DOMAIN"); if (domain_name != NULL) { StrAllocCat(hostname, "."); StrAllocCat(hostname, domain_name); } } #endif /* UCX */ - CTRACE(tfp, "TCP: Local host name is %s\n", hostname); + CTRACE((tfp, "TCP: Local host name is %s\n", hostname)); #ifndef DECNET /* Decnet ain't got no damn name server 8#OO */ #ifdef NEED_HOST_ADDRESS /* no -- needs name server! */ +#ifdef INET6 + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + error = getaddrinfo(name, NULL, &hints, &res); + if (error || !res || !res->ai_canonname) { + CTRACE((tfp, "TCP: %s: `%s'\n", gai_strerror(error), name)); + if (res) + freeaddrinfo(res); + return; /* Fail! */ + } + StrAllocCopy(hostname, res->ai_canonname); + memcpy(&HTHostAddress, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); +#else phost = gethostbyname(name); /* See netdb.h */ if (!OK_HOST(phost)) { - CTRACE(tfp, "TCP: Can't find my own internet node address for `%s'!!\n", - name); + CTRACE((tfp, "TCP: Can't find my own internet node address for `%s'!!\n", + name)); return; /* Fail! */ } StrAllocCopy(hostname, phost->h_name); memcpy(&HTHostAddress, &phost->h_addr, phost->h_length); - CTRACE(tfp, " Name server says that I am `%s' = %s\n", - hostname, HTInetString(&HTHostAddress)); +#endif /* INET6 */ + CTRACE((tfp, " Name server says that I am `%s' = %s\n", + hostname, HTInetString(&HTHostAddress))); #endif /* NEED_HOST_ADDRESS */ #endif /* !DECNET */ @@ -1311,31 +1515,40 @@ PUBLIC CONST char * HTHostName NOARGS return hostname; } +#ifndef MULTINET /* SOCKET_ERRNO != errno ? */ +#if !defined(UCX) || !defined(VAXC) /* errno not modifiable ? */ +#define SOCKET_DEBUG_TRACE /* show errno status after some system calls */ +#endif /* UCX && VAXC */ +#endif /* MULTINET */ /* -** Interruptable connect as implemented for Mosaic by Marc Andreesen +** Interruptible connect as implemented for Mosaic by Marc Andreesen ** and hacked in for Lynx years ago by Lou Montulli, and further ** modified over the years by numerous Lynx lovers. - FM */ PUBLIC int HTDoConnect ARGS4( CONST char *, url, - char *, protocol, + char *, protocol, int, default_port, int *, s) { - struct sockaddr_in soc_address; - struct sockaddr_in *soc_in = &soc_address; - int status; + int status = 0; char *line = NULL; char *p1 = NULL; char *at_sign = NULL; char *host = NULL; +#ifdef INET6 + struct addrinfo *res, *res0; +#else + struct sockaddr_in soc_address; + struct sockaddr_in *soc_in = &soc_address; /* ** Set up defaults. */ memset(soc_in, 0, sizeof(*soc_in)); soc_in->sin_family = AF_INET; - soc_in->sin_port = htons(default_port); + soc_in->sin_port = htons((PortNumber) default_port); +#endif /* INET6 */ /* ** Get node name and optional port number. @@ -1351,8 +1564,20 @@ PUBLIC int HTDoConnect ARGS4( } FREE(p1); - HTSprintf0 (&line, gettext("Looking up %s."), host); + HTSprintf0 (&line, "%s%s", WWW_FIND_MESSAGE, host); _HTProgress (line); +#ifdef INET6 + /* HTParseInet() is useless! */ + _HTProgress(host); + res0 = HTGetAddrInfo(host, default_port); + if (res0 == NULL) { + HTSprintf0 (&line, gettext("Unable to locate remote host %s."), host); + _HTProgress(line); + FREE(host); + FREE(line); + return HT_NO_DATA; + } +#else status = HTParseInet(soc_in, host); if (status) { if (status != HT_INTERRUPTED) { @@ -1373,8 +1598,9 @@ PUBLIC int HTDoConnect ARGS4( FREE(line); return status; } +#endif /* INET6 */ - HTSprintf0 (&line, gettext("Making %s connection to %s."), protocol, host); + HTSprintf0 (&line, gettext("Making %s connection to %s"), protocol, host); _HTProgress (line); FREE(host); FREE(line); @@ -1382,11 +1608,27 @@ PUBLIC int HTDoConnect ARGS4( /* ** Now, let's get a socket set up from the server for the data. */ +#ifdef INET6 + for (res = res0; res; res = res->ai_next) { + *s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (*s == -1) { + char hostbuf[1024], portbuf[1024]; + getnameinfo(res->ai_addr, res->ai_addrlen, + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), + NI_NUMERICHOST|NI_NUMERICSERV); + HTSprintf0 (&line, gettext("socket failed: family %d addr %s port %s."), + res->ai_family, hostbuf, portbuf); + _HTProgress (line); + FREE(line); + continue; + } +#else *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (*s == -1) { HTAlert(gettext("socket failed.")); return HT_NO_DATA; } +#endif /* INET6 */ #ifndef DOSPATH #if !defined(NO_IOCTL) || defined(USE_FCNTL) @@ -1415,16 +1657,24 @@ PUBLIC int HTDoConnect ARGS4( */ #ifdef SOCKS if (socks_flag) { +#ifdef INET6 + status = Rconnect(*s, res->ai_addr, res->ai_addrlen); +#else status = Rconnect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address)); +#endif /* INET6 */ /* ** For long Rbind. */ socks_bind_remoteAddr = soc_address.sin_addr.s_addr; } else #endif /* SOCKS */ +#ifdef INET6 + status = connect(*s, res->ai_addr, res->ai_addrlen); +#else status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address)); -#ifndef DJGPP +#endif /* INET6 */ +#ifndef __DJGPP__ /* ** According to the Sun man page for connect: ** EINPROGRESS The socket is non-blocking and the con- @@ -1444,11 +1694,18 @@ PUBLIC int HTDoConnect ARGS4( ** the normal case. */ if ((status < 0) && - (SOCKET_ERRNO == EINPROGRESS || SOCKET_ERRNO == EAGAIN)) { - struct timeval timeout; + (SOCKET_ERRNO == EINPROGRESS +#ifdef EAGAIN + || SOCKET_ERRNO == EAGAIN +#endif + )) { + struct timeval select_timeout; int ret; int tries=0; +#ifdef SOCKET_DEBUG_TRACE + HTInetStatus("this socket's first connect"); +#endif /* SOCKET_DEBUG_TRACE */ ret = 0; while (ret <= 0) { fd_set writefds; @@ -1456,34 +1713,49 @@ PUBLIC int HTDoConnect ARGS4( /* ** Protect against an infinite loop. */ - if (tries++ >= 180000) { - HTAlert(gettext("Connection failed for 180,000 tries.")); + if ((tries++/10) >= connect_timeout) { + HTAlert(gettext("Connection failed (too many retries).")); +#ifdef INET6 + FREE(line); + freeaddrinfo(res0); +#endif /* INET6 */ return HT_NO_DATA; } #ifdef _WINDOWS_NSL - timeout.tv_sec = 100; + select_timeout.tv_sec = connect_timeout; + select_timeout.tv_usec = 0; #else - timeout.tv_sec = 0; + select_timeout.tv_sec = 0; + select_timeout.tv_usec = 100000; #endif /* _WINDOWS_NSL */ - timeout.tv_usec = 100000; FD_ZERO(&writefds); - FD_SET(*s, &writefds); + FD_SET((unsigned) *s, &writefds); #ifdef SOCKS if (socks_flag) ret = Rselect(FD_SETSIZE, NULL, - (void *)&writefds, NULL, &timeout); + (void *)&writefds, NULL, &select_timeout); else #endif /* SOCKS */ - ret = select(FD_SETSIZE, NULL, (void *)&writefds, NULL, &timeout); + ret = select(FD_SETSIZE, NULL, (void *)&writefds, NULL, &select_timeout); - /* - ** If we suspend, then it is possible that select will be - ** interrupted. Allow for this possibility. - JED - */ - if ((ret == -1) && (errno == EINTR)) - continue; +#ifdef SOCKET_DEBUG_TRACE + if (tries == 1) { + HTInetStatus("this socket's first select"); + } +#endif /* SOCKET_DEBUG_TRACE */ + /* + ** If we suspend, then it is possible that select will be + ** interrupted. Allow for this possibility. - JED + */ + if ((ret == -1) && (errno == EINTR)) + continue; +#ifdef SOCKET_DEBUG_TRACE + if (ret < 0) { + HTInetStatus("failed select"); + } +#endif /* SOCKET_DEBUG_TRACE */ /* ** Again according to the Sun and Motorola man pages for connect: ** EALREADY The socket is non-blocking and a previ- @@ -1508,8 +1780,12 @@ PUBLIC int HTDoConnect ARGS4( status = 0; } else { #endif /* SOCKS */ +#ifdef INET6 + status = connect(*s, res->ai_addr, res->ai_addrlen); +#else status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address)); +#endif /* INET6 */ #ifdef UCX /* ** A UCX feature: Instead of returning EISCONN @@ -1527,8 +1803,14 @@ PUBLIC int HTDoConnect ARGS4( if (status && (SOCKET_ERRNO == EALREADY)) /* new stuff LJM */ ret = 0; /* keep going */ - else + else { +#ifdef SOCKET_DEBUG_TRACE + if (status < 0) { + HTInetStatus("confirm-ready connect"); + } +#endif /* SOCKET_DEBUG_TRACE */ break; + } #ifdef SOCKS } #endif /* SOCKS */ @@ -1551,27 +1833,61 @@ PUBLIC int HTDoConnect ARGS4( ** For some reason, UCX pre 3 apparently returns ** errno = 18242 instead the EALREADY or EISCONN. */ +#ifdef INET6 + status = connect(*s, res->ai_addr, res->ai_addrlen); +#else status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address)); +#endif /* INET6 */ if ((status < 0) && - (SOCKET_ERRNO != EALREADY && SOCKET_ERRNO != EAGAIN) && + (SOCKET_ERRNO != EALREADY +#ifdef EAGAIN + && SOCKET_ERRNO != EAGAIN +#endif + ) && #ifdef UCX (SOCKET_ERRNO != 18242) && #endif /* UCX */ (SOCKET_ERRNO != EISCONN)) { +#ifdef SOCKET_DEBUG_TRACE + HTInetStatus("confirm-not-ready connect"); +#endif /* SOCKET_DEBUG_TRACE */ break; } } if (HTCheckForInterrupt()) { - CTRACE(tfp, "*** INTERRUPTED in middle of connect.\n"); + CTRACE((tfp, "*** INTERRUPTED in middle of connect.\n")); status = HT_INTERRUPTED; +#ifdef _WINDOWS + WSASetLastError(EINTR); +#else SOCKET_ERRNO = EINTR; +#endif break; } } } -#endif /* !DJGPP */ - if (status < 0) { +#ifdef SOCKET_DEBUG_TRACE + else if (status < 0) { + HTInetStatus("this socket's first and only connect"); + } +#endif /* SOCKET_DEBUG_TRACE */ +#ifdef INET6 + if (status < 0) { + NETCLOSE(*s); + *s = -1; + continue; + } + break; + } +#endif /* INET6 */ +#endif /* !__DJGPP__ */ +#ifdef INET6 + if (*s < 0) +#else + if (status < 0) +#endif /* INET6 */ + { /* ** The connect attempt failed or was interrupted, ** so close up the socket. @@ -1596,6 +1912,10 @@ PUBLIC int HTDoConnect ARGS4( #endif /* !NO_IOCTL || USE_FCNTL */ #endif /* !DOSPATH */ +#ifdef INET6 + FREE(line); + freeaddrinfo(res0); +#endif /* INET6 */ return status; } @@ -1604,13 +1924,17 @@ PUBLIC int HTDoConnect ARGS4( */ PUBLIC int HTDoRead ARGS3( int, fildes, - void *, buf, + void *, buf, unsigned, nbyte) { int ready, ret; fd_set readfds; - struct timeval timeout; + struct timeval select_timeout; int tries=0; +#ifdef EXP_READPROGRESS + int otries = 0; + time_t otime = time((time_t *)0); +#endif #if defined(UNIX) || defined(UCX) int nb; #endif /* UCX, BSN */ @@ -1622,7 +1946,7 @@ PUBLIC int HTDoRead ARGS3( * have gone wrong. - kw */ if (isatty(fildes)) { - CTRACE(tfp, "HTDoRead - refusing to read fd 0 which is a tty!\n"); + CTRACE((tfp, "HTDoRead - refusing to read fd 0 which is a tty!\n")); return -1; } } else @@ -1631,7 +1955,11 @@ PUBLIC int HTDoRead ARGS3( return -1; if (HTCheckForInterrupt()) { +#ifdef _WINDOWS + WSASetLastError(EINTR); +#else SOCKET_ERRNO = EINTR; +#endif return (HT_INTERRUPTED); } @@ -1646,27 +1974,43 @@ PUBLIC int HTDoRead ARGS3( */ if (tries++ >= 180000) { HTAlert(gettext("Socket read failed for 180,000 tries.")); +#ifdef _WINDOWS + WSASetLastError(EINTR); +#else SOCKET_ERRNO = EINTR; +#endif return HT_INTERRUPTED; } +#ifdef EXP_READPROGRESS + if (tries - otries > 10) { + time_t t = time((time_t *)0); + + otries = tries; + if (t - otime >= 5) { + otime = t; + HTReadProgress(-1, 0); /* Put "stalled" message */ + } + } +#endif + /* ** If we suspend, then it is possible that select will be ** interrupted. Allow for this possibility. - JED */ do { - timeout.tv_sec = 0; - timeout.tv_usec = 100000; + select_timeout.tv_sec = 0; + select_timeout.tv_usec = 100000; FD_ZERO(&readfds); - FD_SET(fildes, &readfds); + FD_SET((unsigned)fildes, &readfds); #ifdef SOCKS if (socks_flag) ret = Rselect(FD_SETSIZE, - (void *)&readfds, NULL, NULL, &timeout); + (void *)&readfds, NULL, NULL, &select_timeout); else #endif /* SOCKS */ ret = select(FD_SETSIZE, - (void *)&readfds, NULL, NULL, &timeout); + (void *)&readfds, NULL, NULL, &select_timeout); } while ((ret == -1) && (errno == EINTR)); if (ret < 0) { @@ -1674,7 +2018,11 @@ PUBLIC int HTDoRead ARGS3( } else if (ret > 0) { ready = 1; } else if (HTCheckForInterrupt()) { +#ifdef _WINDOWS + WSASetLastError(EINTR); +#else SOCKET_ERRNO = EINTR; +#endif return HT_INTERRUPTED; } } @@ -1682,7 +2030,6 @@ PUBLIC int HTDoRead ARGS3( #if !defined(UCX) || !defined(VAXC) #ifdef UNIX while ((nb = SOCKET_READ (fildes, buf, nbyte)) == -1) { - int saved_errno = errno; if (errno == EINTR) continue; #ifdef ERESTARTSYS @@ -1690,7 +2037,6 @@ PUBLIC int HTDoRead ARGS3( continue; #endif /* ERESTARTSYS */ HTInetStatus("read"); - errno = saved_errno; /* our caller may check it */ break; } return nb; @@ -1704,8 +2050,8 @@ PUBLIC int HTDoRead ARGS3( */ errno = vaxc$errno = 0; nb = SOCKET_READ (fildes, buf, nbyte); - CTRACE(tfp, - "Read - nb,errno,vaxc$errno: %d %d %d\n", nb,errno,vaxc$errno); + CTRACE((tfp, + "Read - nb,errno,vaxc$errno: %d %d %d\n", nb,errno,vaxc$errno)); if ((nb <= 0) && TRACE) perror ("HTTCP.C:HTDoRead:read"); /* RJF */ /* @@ -1713,7 +2059,7 @@ PUBLIC int HTDoRead ARGS3( */ if ((nb <= 0) && (errno == EPIPE)) { nb = 0; - errno = 0; + set_errno(0); } return nb; #endif /* UCX, BSN */ @@ -1754,22 +2100,21 @@ PUBLIC int BSDselect ARGS5( fd_set *, readfds, fd_set *, writefds, fd_set *, exceptfds, - struct timeval *, timeout) + struct timeval *, select_timeout) { int rval, i; #ifdef SOCKS if (socks_flag) - rval = Rselect(nfds, readfds, writefds, exceptfds, timeout); + rval = Rselect(nfds, readfds, writefds, exceptfds, select_timeout); else #endif /* SOCKS */ - rval = select(nfds, readfds, writefds, exceptfds, timeout); + rval = select(nfds, readfds, writefds, exceptfds, select_timeout); switch (rval) { case -1: return(rval); - break; case 0: if (readfds != NULL) @@ -1779,7 +2124,6 @@ PUBLIC int BSDselect ARGS5( if (exceptfds != NULL) FD_ZERO(exceptfds); return(rval); - break; default: for (i = 0, rval = 0; i < nfds; i++) { diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.h index 4e43ed27cd8..91f98c80df9 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTCP.h @@ -10,7 +10,7 @@ #ifndef HTUTILS_H #include <HTUtils.h> #endif - + /* Produce a string for an internet address ** --------------------------------------- ** @@ -18,10 +18,11 @@ ** returns a pointer to a static string which must be copied if ** it is to be kept. */ -#ifndef _WINDOWS +#ifdef INET6 +extern CONST char * HTInetString PARAMS((SockA* mysin)); +#else extern CONST char * HTInetString PARAMS((struct sockaddr_in* mysin)); -#endif - +#endif /* INET6 */ /* Encode INET status (as in sys/errno.h) inet_status() ** ------------------ @@ -33,7 +34,7 @@ extern CONST char * HTInetString PARAMS((struct sockaddr_in* mysin)); ** On return: ** returns a negative status in the unix way. */ -#ifdef __STDC__ +#if defined(__STDC__) || defined(__BORLANDC__) || defined(_MSC_VER) extern int HTInetStatus(char *where); #else extern int HTInetStatus(); @@ -68,7 +69,7 @@ extern unsigned int HTCardinal PARAMS((int *pstatus, ** ------------------------------------------------- */ -extern BOOL valid_hostname PARAMS((CONST char * name)); +extern BOOL valid_hostname PARAMS((char * name)); /* Resolve an internet hostname, like gethostbyname ** ------------------------------------------------ @@ -86,29 +87,10 @@ extern BOOL valid_hostname PARAMS((CONST char * name)); */ extern int lynx_nsl_status; -#ifndef DJGPP -extern struct hostent * LYGetHostByName PARAMS(( - CONST char * str)); -#endif /* DJGPP */ - - -/* Parse an internet node address and port -** --------------------------------------- -** -** On entry: -** str points to a string with a node name or number, -** with optional trailing colon and port number. -** sin points to the binary internet or decnet address field. -** -** On exit: -** *sin is filled in. If no port is specified in str, that -** field is left unchanged in *sin. -*/ -#ifdef __STDC__ - extern int HTParseInet(struct sockaddr_in * mysin, CONST char * str); - /*!! had to change this to get it to compile. CTB */ +#if defined(__DJGPP__) && !defined(WATT32) +#define LYGetHostByName(host) resolv(host) /* we'll use it the same way */ #else - extern int HTParseInet(); +extern struct hostent * LYGetHostByName PARAMS((char * str)); #endif /* Get Name of This Machine diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c index 7bad3c773f9..0e7af29de68 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTP.c @@ -1,4 +1,4 @@ -/* HyperText Tranfer Protocol - Client implementation HTTP.c +/* HyperText Tranfer Protocol - Client implementation HTTP.c ** ========================== ** Modified: ** 27 Jan 1994 PDM Added Ari Luotonen's Fix for Reload when using proxy @@ -7,15 +7,15 @@ */ #include <HTUtils.h> +#if defined(__DJGPP__) && defined (WATT32) +#include <tcp.h> +#endif /* __DJGPP__ */ #include <HTTP.h> #include <LYUtils.h> #ifdef USE_SSL -#define free_func free__func -#include <openssl/ssl.h> -#include <openssl/crypto.h> -#undef free_func -#endif /* USE_SSL */ +#include <HTNews.h> +#endif #define HTTP_VERSION "HTTP/1.0" @@ -77,17 +77,17 @@ PUBLIC SSL_CTX * ssl_ctx = NULL; /* SSL ctx */ PRIVATE void free_ssl_ctx NOARGS { if (ssl_ctx != NULL) - SSL_CTX_free(ssl_ctx); + SSL_CTX_free(ssl_ctx); } PUBLIC SSL * HTGetSSLHandle NOARGS { if (ssl_ctx == NULL) { - /* + /* * First time only. */ #if SSLEAY_VERSION_NUMBER < 0x0800 - ssl_ctx = SSL_CTX_new(); + ssl_ctx = SSL_CTX_new(); X509_set_default_verify_paths(ssl_ctx->cert); #else SSLeay_add_ssl_algorithms(); @@ -100,6 +100,44 @@ PUBLIC SSL * HTGetSSLHandle NOARGS return(SSL_new(ssl_ctx)); } +PUBLIC void HTSSLInitPRNG NOARGS +{ +#if SSLEAY_VERSION_NUMBER >= 0x00905100 + if (RAND_status() == 0) { + char rand_file[256]; + time_t t; + pid_t pid; + long l,seed; + + t = time(NULL); + pid = getpid(); + RAND_file_name(rand_file, 256); + CTRACE((tfp,"HTTP: Seeding PRNG\n")); + if(rand_file != NULL) { + /* Seed as much as 1024 bytes from RAND_file_name */ + RAND_load_file(rand_file, 1024); + } + /* Seed in time (mod_ssl does this) */ + RAND_seed((unsigned char *)&t, sizeof(time_t)); + /* Seed in pid (mod_ssl does this) */ + RAND_seed((unsigned char *)&pid, sizeof(pid_t)); + /* Initialize system's random number generator */ + RAND_bytes((unsigned char *)&seed, sizeof(long)); + lynx_srand(seed); + while (RAND_status() == 0) { + /* Repeatedly seed the PRNG using the system's random number generator until it has been seeded with enough data */ + l = lynx_rand(); + RAND_seed((unsigned char *)&l, sizeof(long)); + } + if (rand_file != NULL) { + /* Write a rand_file */ + RAND_write_file(rand_file); + } + } +#endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */ + return; +} + #define HTTP_NETREAD(sock, buff, size, handle) \ (handle ? SSL_read(handle, buff, size) : NETREAD(sock, buff, size)) #define HTTP_NETWRITE(sock, buff, size, handle) \ @@ -107,16 +145,185 @@ PUBLIC SSL * HTGetSSLHandle NOARGS #define HTTP_NETCLOSE(sock, handle) \ { (void)NETCLOSE(sock); if (handle) SSL_free(handle); handle = NULL; } -extern int HTNewsProxyConnect PARAMS (( int sock, CONST char *url, - HTParentAnchor *anAnchor, - HTFormat format_out, - HTStream *sink )); #else #define HTTP_NETREAD(a, b, c, d) NETREAD(a, b, c) #define HTTP_NETWRITE(a, b, c, d) NETWRITE(a, b, c) #define HTTP_NETCLOSE(a, b) (void)NETCLOSE(a) #endif /* USE_SSL */ +#ifdef _WINDOWS /* 1997/11/06 (Thu) 13:00:08 */ + +#define BOX_TITLE "Lynx " __FILE__ +#define BOX_FLAG (MB_ICONINFORMATION | MB_SETFOREGROUND) + +typedef struct { + int fd; + char *buf; + int len; +} recv_data_t; + +PUBLIC int ws_read_per_sec = 0; +PRIVATE int ws_errno = 0; + +PRIVATE DWORD g_total_times = 0; +PRIVATE DWORD g_total_bytes = 0; + + +PUBLIC char * str_speed(void) +{ + static char buff[32]; + + if (ws_read_per_sec > 1000) + sprintf(buff, "%d.%03dkB", ws_read_per_sec / 1000, + (ws_read_per_sec % 1000) ); + else + sprintf(buff, "%3d", ws_read_per_sec); + + return buff; +} + +/* The same like read, but takes care of EINTR and uses select to + timeout the stale connections. */ + +PRIVATE int ws_read(int fd, char *buf, int len) +{ + int res; + int retry = 3; + + do { + res = recv(fd, buf, len, 0); + if (WSAEWOULDBLOCK == WSAGetLastError()) { + Sleep(100); + if (retry-- > 0) + continue; + } + } while (res == SOCKET_ERROR && SOCKET_ERRNO == EINTR); + + return res; +} + +PRIVATE void _thread_func (void *p) +{ + int i, val, ret; + recv_data_t *q = (recv_data_t *)p; + + i = 0; + i++; + val = ws_read(q->fd, q->buf, q->len); + + if (val == SOCKET_ERROR) { + ws_errno = WSAGetLastError(); +#if 0 + char buff[256]; + sprintf(buff, "Thread read: %d, error (%ld), fd = %d, len = %d", + i, ws_errno, q->fd, q->len); + MessageBox(NULL, buff, BOX_TITLE, BOX_FLAG); +#endif + ret = -1; + } else { + ret = val; + } + + ExitThread((DWORD)ret); +} + +/* The same like read, but takes care of EINTR and uses select to + timeout the stale connections. */ + +PUBLIC int ws_netread(int fd, char *buf, int len) +{ + int i; + char buff[256]; + + /* 1998/03/30 (Mon) 09:01:21 */ + HANDLE hThread; + DWORD dwThreadID; + DWORD exitcode = 0; + DWORD ret_val = -1, val, process_time, now_TickCount, save_TickCount; + + static recv_data_t para; + + extern int win32_check_interrupt(void); /* LYUtil.c */ + extern int lynx_timeout; /* LYMain.c */ + extern int AlertSecs; /* LYMain.c */ + extern CRITICAL_SECTION critSec_READ; /* LYMain.c */ + +#define TICK 5 +#define STACK_SIZE 0x2000uL + + InitializeCriticalSection(&critSec_READ); + + para.fd = fd; + para.buf = buf; + para.len = len; + + ws_read_per_sec = 0; + save_TickCount = GetTickCount(); + + hThread = CreateThread((void *)NULL, STACK_SIZE, + (LPTHREAD_START_ROUTINE)_thread_func, + (void *)¶, 0UL, &dwThreadID); + + if (hThread == 0) { + HTInfoMsg("CreateThread Failed (read)"); + goto read_exit; + } + + i = 0; + while (1) { + val = WaitForSingleObject(hThread, 1000/TICK); + i++; + if (val == WAIT_FAILED) { + HTInfoMsg("Wait Failed"); + ret_val = -1; + break; + } else if (val == WAIT_TIMEOUT) { + i++; + if (i/TICK > (AlertSecs + 2)) { + sprintf(buff, "Read Waiting (%2d.%01d) for %d Bytes", + i/TICK, (i%TICK) * 10 / TICK, len); + SetConsoleTitle(buff); + } + if (win32_check_interrupt() || ((i/TICK) > lynx_timeout)) { + if (CloseHandle(hThread) == FALSE) { + HTInfoMsg("Thread terminate Failed"); + } + WSASetLastError(ETIMEDOUT); + ret_val = HT_INTERRUPTED; + break; + } + } else if (val == WAIT_OBJECT_0) { + if (GetExitCodeThread(hThread, &exitcode) == FALSE) { + exitcode = -1; + } + if (CloseHandle(hThread) == FALSE) { + HTInfoMsg("Thread terminate Failed"); + } + now_TickCount = GetTickCount(); + if (now_TickCount > save_TickCount) + process_time = now_TickCount - save_TickCount; + else + process_time = now_TickCount + (0xffffffff - save_TickCount); + + g_total_times += process_time; + g_total_bytes += exitcode; + + if (g_total_bytes > 2000000) { + ws_read_per_sec = g_total_bytes / (g_total_times/1000); + } else { + ws_read_per_sec = g_total_bytes * 1000 / g_total_times; + } + ret_val = exitcode; + break; + } + } /* end while(1) */ + + read_exit: + LeaveCriticalSection(&critSec_READ); + return ret_val; +} +#endif + /* Load Document from HTTP Server HTLoadHTTP() ** ============================== @@ -143,39 +350,42 @@ PRIVATE int HTLoadHTTP ARGS4 ( { int s; /* Socket number for returned data */ CONST char *url = arg; /* The URL which get_physical() returned */ - char *command = NULL; /* The whole command */ + char *command = NULL; /* The whole command */ char *eol; /* End of line if found */ char *start_of_data; /* Start of body of reply */ int status; /* tcp return */ int bytes_already_read; - char crlf[3]; /* A CR LF equivalent string */ + char crlf[3]; /* A CR LF equivalent string */ HTStream *target; /* Unconverted data */ HTFormat format_in; /* Format arriving in the message */ - BOOL do_head = FALSE; /* Whether or not we should do a head */ - BOOL do_post = FALSE; /* ARE WE posting ? */ + BOOL do_head = FALSE; /* Whether or not we should do a head */ + BOOL do_post = FALSE; /* ARE WE posting ? */ char *METHOD; BOOL had_header; /* Have we had at least one header? */ char *line_buffer; char *line_kept_clean; + int real_length_of_line; BOOL extensions; /* Assume good HTTP server */ - char line[INIT_LINE_SIZE]; + char *linebuf = NULL; char temp[80]; BOOL first_Accept = TRUE; BOOL show_401 = FALSE; BOOL show_407 = FALSE; - BOOL auth_proxy = NO; /* Generate a proxy authorization. - AJL */ + BOOL auth_proxy = NO; /* Generate a proxy authorization. - AJL */ - int length, rv; - BOOL doing_redirect, already_retrying = FALSE, bad_location = FALSE; + int length, rawlength, rv; + int server_status; + BOOL doing_redirect, already_retrying = FALSE; int len = 0; #ifdef USE_SSL - BOOL do_connect = FALSE; /* ARE WE going to use a proxy tunnel ? */ - BOOL did_connect = FALSE; /* ARE WE actually using a proxy tunnel ? */ + BOOL do_connect = FALSE; /* ARE WE going to use a proxy tunnel ? */ + BOOL did_connect = FALSE; /* ARE WE actually using a proxy tunnel ? */ CONST char *connect_url = NULL; /* The URL being proxied */ - char *connect_host = NULL; /* The host being proxied */ - SSL * handle = NULL; /* The SSL handle */ + char *connect_host = NULL; /* The host being proxied */ + SSL * handle = NULL; /* The SSL handle */ + char SSLprogress[256]; /* progress bar message */ #if SSLEAY_VERSION_NUMBER >= 0x0900 BOOL try_tls = TRUE; #endif /* SSLEAY_VERSION_NUMBER >= 0x0900 */ @@ -201,24 +411,24 @@ PRIVATE int HTLoadHTTP ARGS4 ( #ifdef USE_SSL if (using_proxy && !strncmp(url, "http://", 7)) { - if (connect_url = strstr((url+7), "https://")) { + if ((connect_url = strstr((url+7), "https://"))) { do_connect = TRUE; connect_host = HTParse(connect_url, "https", PARSE_HOST); if (!strchr(connect_host, ':')) { sprintf(temp, ":%d", HTTPS_PORT); StrAllocCat(connect_host, temp); } - CTRACE(tfp, "HTTP: connect_url = '%s'\n", connect_url); - CTRACE(tfp, "HTTP: connect_host = '%s'\n", connect_host); - } else if (connect_url = strstr((url+7), "snews://")) { + CTRACE((tfp, "HTTP: connect_url = '%s'\n", connect_url)); + CTRACE((tfp, "HTTP: connect_host = '%s'\n", connect_host)); + } else if ((connect_url = strstr((url+7), "snews://"))) { do_connect = TRUE; connect_host = HTParse(connect_url, "snews", PARSE_HOST); if (!strchr(connect_host, ':')) { sprintf(temp, ":%d", SNEWS_PORT); StrAllocCat(connect_host, temp); } - CTRACE(tfp, "HTTP: connect_url = '%s'\n", connect_url); - CTRACE(tfp, "HTTP: connect_host = '%s'\n", connect_host); + CTRACE((tfp, "HTTP: connect_url = '%s'\n", connect_url)); + CTRACE((tfp, "HTTP: connect_host = '%s'\n", connect_host)); } } #endif /* USE_SSL */ @@ -245,12 +455,13 @@ try_again: line_buffer = NULL; line_kept_clean = NULL; - if (!strncmp(url, "https", 5)) #ifdef USE_SSL + if (!strncmp(url, "https", 5)) status = HTDoConnect (url, "HTTPS", HTTPS_PORT, &s); else status = HTDoConnect (url, "HTTP", HTTP_PORT, &s); #else + if (!strncmp(url, "https", 5)) { HTAlert(gettext("This client does not contain support for HTTPS URLs.")); status = HT_NOT_LOADED; @@ -262,19 +473,31 @@ try_again: /* ** Interrupt cleanly. */ - CTRACE (tfp, "HTTP: Interrupted on connect; recovering cleanly.\n"); + CTRACE((tfp, "HTTP: Interrupted on connect; recovering cleanly.\n")); _HTProgress (CONNECTION_INTERRUPTED); status = HT_NOT_LOADED; goto done; } if (status < 0) { - CTRACE(tfp, "HTTP: Unable to connect to remote host for `%s' (errno = %d).\n", - url, SOCKET_ERRNO); +#ifdef _WINDOWS + CTRACE((tfp, "HTTP: Unable to connect to remote host for `%s'\n" + " (status = %d, sock_errno = %d).\n", + url, status, SOCKET_ERRNO)); +#else + CTRACE((tfp, + "HTTP: Unable to connect to remote host for `%s' (errno = %d).\n", + url, SOCKET_ERRNO)); +#endif HTAlert(gettext("Unable to connect to remote host.")); status = HT_NOT_LOADED; goto done; } +/* *sob* All this needs to be converted to handle binary strings + * if we're going to be able to handle binary form uploads... + * This is a nice long function as well. *sigh* -RJP + */ + #ifdef USE_SSL use_tunnel: /* @@ -286,51 +509,63 @@ use_tunnel: SSL_set_fd(handle, s); #if SSLEAY_VERSION_NUMBER >= 0x0900 if (!try_tls) - handle->options|=SSL_OP_NO_TLSv1; + handle->options|=SSL_OP_NO_TLSv1; #endif /* SSLEAY_VERSION_NUMBER >= 0x0900 */ + HTSSLInitPRNG(); status = SSL_connect(handle); if (status <= 0) { #if SSLEAY_VERSION_NUMBER >= 0x0900 if (try_tls) { - CTRACE(tfp, "HTTP: Retrying connection without TLS\n"); + CTRACE((tfp, "HTTP: Retrying connection without TLS\n")); _HTProgress("Retrying connection."); try_tls = FALSE; if (did_connect) - HTTP_NETCLOSE(s, handle); - goto try_again; + HTTP_NETCLOSE(s, handle); + goto try_again; } else { - CTRACE(tfp, -"HTTP: Unable to complete SSL handshake for remote host '%s' (SSLerror = %d)\n", - url, status); - HTAlert("Unable to make secure connection to remote host."); + unsigned long SSLerror; + CTRACE((tfp, +"HTTP: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n", + url, status)); + SSL_load_error_strings(); + while((SSLerror=ERR_get_error())!=0) { + CTRACE((tfp,"HTTP: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } + HTAlert("Unable to make secure connection to remote host."); if (did_connect) - HTTP_NETCLOSE(s, handle); - status = HT_NOT_LOADED; - goto done; + HTTP_NETCLOSE(s, handle); + status = HT_NOT_LOADED; + goto done; } #else - CTRACE(tfp, -"HTTP: Unable to complete SSL handshake for remote host '%s' (SSLerror = %d)\n", - url, status); - HTAlert("Unable to make secure connection to remote host."); + unsigned long SSLerror; + CTRACE((tfp, +"HTTP: Unable to complete SSL handshake for '%s', SSL_connect=%d, SSL error stack dump follows\n", + url, status)); + SSL_load_error_strings(); + while((SSLerror=ERR_get_error())!=0) { + CTRACE((tfp,"HTTP: SSL: %s\n",ERR_error_string(SSLerror,NULL))); + } + HTAlert("Unable to make secure connection to remote host."); if (did_connect) HTTP_NETCLOSE(s, handle); - status = HT_NOT_LOADED; - goto done; + status = HT_NOT_LOADED; + goto done; #endif /* SSLEAY_VERSION_NUMBER >= 0x0900 */ } - _HTProgress (SSL_get_cipher(handle)); + sprintf(SSLprogress,"Secure %d-bit %s (%s) HTTP connection",SSL_get_cipher_bits(handle,NULL),SSL_get_cipher_version(handle),SSL_get_cipher(handle)); + _HTProgress(SSLprogress); #ifdef NOTDEFINED if (strcmp(HTParse(url, "", PARSE_HOST), - strstr(X509_NAME_oneline( - X509_get_subject_name( + strstr(X509_NAME_oneline( + X509_get_subject_name( handle->session->peer)),"/CN=")+4)) { HTAlert("Certificate is for different host name"); HTAlert(strstr(X509_NAME_oneline( - X509_get_subject_name( - handle->session->peer)),"/CN=")+4); + X509_get_subject_name( + handle->session->peer)),"/CN=")+4); } #endif /* NOTDEFINED */ } @@ -368,8 +603,8 @@ use_tunnel: if (using_proxy && !did_connect) { if (do_connect) StrAllocCat(command, connect_host); - else - StrAllocCat(command, p1+1); + else + StrAllocCat(command, p1+1); } #else if (using_proxy) @@ -391,8 +626,7 @@ use_tunnel: char * host = NULL; if ((host = HTParse(anAnchor->address, "", PARSE_HOST)) != NULL) { - sprintf(line, "Host: %s%c%c", host, CR,LF); - StrAllocCat(command, line); + HTSprintf(&command, "Host: %s%c%c", host, CR,LF); FREE(host); } @@ -405,70 +639,61 @@ use_tunnel: for (i = 0; i < n; i++) { HTPresentation *pres = (HTPresentation *)HTList_objectAt(HTPresentations, i); - if (pres->rep_out == WWW_PRESENT) { - if (pres->rep != WWW_SOURCE && - strcasecomp(HTAtom_name(pres->rep), "www/mime") && - strcasecomp(HTAtom_name(pres->rep), "www/compressed") && - pres->quality <= 1.0 && pres->quality >= 0.0) { - if (pres->quality < 1.0) { - if (pres->maxbytes > 0) { - sprintf(temp, ";q=%4.3f;mxb=%ld", - pres->quality, pres->maxbytes); - } else { - sprintf(temp, ";q=%4.3f", pres->quality); - } - } else if (pres->maxbytes > 0) { - sprintf(temp, ";mxb=%ld", pres->maxbytes); + if (pres->get_accept) { + if (pres->quality < 1.0) { + if (pres->maxbytes > 0) { + sprintf(temp, ";q=%4.3f;mxb=%ld", + pres->quality, pres->maxbytes); } else { - temp[0] = '\0'; + sprintf(temp, ";q=%4.3f", pres->quality); } - sprintf(line, "%s%s%s", - (first_Accept ? - "Accept: " : ", "), + } else if (pres->maxbytes > 0) { + sprintf(temp, ";mxb=%ld", pres->maxbytes); + } else { + temp[0] = '\0'; + } + HTSprintf0(&linebuf, "%s%s%s", + (first_Accept ? + "Accept: " : ", "), + HTAtom_name(pres->rep), + temp); + len += strlen(linebuf); + if (len > 252 && !first_Accept) { + StrAllocCat(command, crlf); + HTSprintf0(&linebuf, "Accept: %s%s", HTAtom_name(pres->rep), temp); - len += strlen(line); - if (len > 252 && !first_Accept) { - StrAllocCat(command, crlf); - sprintf(line, "Accept: %s%s", - HTAtom_name(pres->rep), - temp); - len = strlen(line); - } - StrAllocCat(command, line); - first_Accept = FALSE; + len = strlen(linebuf); } + StrAllocCat(command, linebuf); + first_Accept = FALSE; } } - sprintf(line, "%s*/*;q=0.01%c%c", + HTSprintf(&command, "%s*/*;q=0.01%c%c", (first_Accept ? "Accept: " : ", "), CR, LF); - StrAllocCat(command, line); first_Accept = FALSE; len = 0; - sprintf(line, "Accept-Encoding: %s, %s%c%c", + HTSprintf(&command, "Accept-Encoding: %s, %s%c%c", "gzip", "compress", CR, LF); - StrAllocCat(command, line); if (language && *language) { - sprintf(line, "Accept-Language: %s%c%c", language, CR, LF); - StrAllocCat(command, line); + HTSprintf(&command, "Accept-Language: %s%c%c", language, CR, LF); } if (pref_charset && *pref_charset) { StrAllocCat(command, "Accept-Charset: "); - strcpy(line, pref_charset); - if (line[strlen(line)-1] == ',') - line[strlen(line)-1] = '\0'; - LYLowerCase(line); - if (strstr(line, "iso-8859-1") == NULL) - strcat(line, ", iso-8859-1;q=0.01"); - if (strstr(line, "us-ascii") == NULL) - strcat(line, ", us-ascii;q=0.01"); - StrAllocCat(command, line); - sprintf(line, "%c%c", CR, LF); - StrAllocCat(command, line); + StrAllocCopy(linebuf, pref_charset); + if (linebuf[strlen(linebuf)-1] == ',') + linebuf[strlen(linebuf)-1] = '\0'; + LYLowerCase(linebuf); + if (strstr(linebuf, "iso-8859-1") == NULL) + StrAllocCat(linebuf, ", iso-8859-1;q=0.01"); + if (strstr(linebuf, "us-ascii") == NULL) + StrAllocCat(linebuf, ", us-ascii;q=0.01"); + StrAllocCat(command, linebuf); + HTSprintf(&command, "%c%c", CR, LF); } #if 0 @@ -495,8 +720,7 @@ use_tunnel: ** new-httpd@apache.org from Koen Holtman, Jan 1999. */ if (!do_post) { - sprintf(line, "Negotiate: trans%c%c", CR, LF); - StrAllocCat(command, line); + HTSprintf(&command, "Negotiate: trans%c%c", CR, LF); } #endif /* 0 */ @@ -507,31 +731,32 @@ use_tunnel: ** Also send it as a Cache-Control header for HTTP/1.1. - FM */ if (reloading) { - sprintf(line, "Pragma: no-cache%c%c", CR, LF); - StrAllocCat(command, line); - sprintf(line, "Cache-Control: no-cache%c%c", CR, LF); - StrAllocCat(command, line); + HTSprintf(&command, "Pragma: no-cache%c%c", CR, LF); + HTSprintf(&command, "Cache-Control: no-cache%c%c", CR, LF); } if (LYUserAgent && *LYUserAgent) { - sprintf(line, "User-Agent: %s%c%c", LYUserAgent, CR, LF); + char *cp = LYSkipBlanks(LYUserAgent); + /* Won't send it at all if all blank - kw */ + if (*cp != '\0') + HTSprintf(&command, "User-Agent: %.*s%c%c", + INIT_LINE_SIZE-15, LYUserAgent, CR, LF); } else { - sprintf(line, "User-Agent: %s/%s libwww-FM/%s%c%c", + HTSprintf(&command, "User-Agent: %s/%s libwww-FM/%s%c%c", HTAppName ? HTAppName : "unknown", HTAppVersion ? HTAppVersion : "0.0", HTLibraryVersion, CR, LF); } - StrAllocCat(command, line); if (personal_mail_address && !LYNoFromHeader) { - sprintf(line, "From: %s%c%c", personal_mail_address, CR,LF); - StrAllocCat(command, line); + HTSprintf(&command, "From: %s%c%c", personal_mail_address, CR,LF); } if (!(LYUserSpecifiedURL || LYNoRefererHeader || LYNoRefererForThis) && strcmp(HTLoadedDocumentURL(), "")) { - char *cp = HTLoadedDocumentURL(); + char *cp = LYRequestReferer; + if (!cp) cp = HTLoadedDocumentURL(); /* @@@ Try both? - kw */ StrAllocCat(command, "Referer: "); if (!strncasecomp(cp, "LYNXIMGMAP:", 11)) { char *cp1 = strchr(cp, '#'); @@ -543,8 +768,7 @@ use_tunnel: } else { StrAllocCat(command, cp); } - sprintf(line, "%c%c", CR, LF); - StrAllocCat(command, line); + HTSprintf(&command, "%c%c", CR, LF); } { @@ -554,7 +778,7 @@ use_tunnel: char *colon; int portnumber; char *auth, *cookie = NULL; - BOOL secure = (strncmp(anAnchor->address, "https", 5) ? + BOOL secure = (BOOL) (strncmp(anAnchor->address, "https", 5) ? FALSE : TRUE); abspath = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION); @@ -606,9 +830,8 @@ use_tunnel: ** If auth is not NULL nor zero-length, it's ** an Authorization header to be included. - FM */ - sprintf(line, "%s%c%c", auth, CR, LF); - StrAllocCat(command, line); - CTRACE(tfp, "HTTP: Sending authorization: %s\n", auth); + HTSprintf(&command, "%s%c%c", auth, CR, LF); + CTRACE((tfp, "HTTP: Sending authorization: %s\n", auth)); } else if (auth && *auth == '\0') { /* ** If auth is a zero-length string, the user either @@ -622,7 +845,7 @@ use_tunnel: if (traversal || dump_output_immediately) HTAlert(FAILED_NEED_PASSWD); #ifdef USE_SSL - if(did_connect) + if (did_connect) HTTP_NETCLOSE(s, handle); #endif /* USE_SSL */ FREE(command); @@ -635,7 +858,7 @@ use_tunnel: goto done; } } else { - CTRACE(tfp, "HTTP: Not sending authorization (yet).\n"); + CTRACE((tfp, "HTTP: Not sending authorization (yet).\n")); } /* ** Add 'Cookie:' header, if it's HTTP or HTTPS @@ -668,7 +891,7 @@ use_tunnel: */ StrAllocCat(command, "Cookie2: $Version=\"1\""); StrAllocCat(command, crlf); - CTRACE(tfp, "HTTP: Sending Cookie2: $Version =\"1\"\n"); + CTRACE((tfp, "HTTP: Sending Cookie2: $Version =\"1\"\n")); } if (*cookie != '\0') { /* @@ -679,7 +902,7 @@ use_tunnel: StrAllocCat(command, "Cookie: "); StrAllocCat(command, cookie); StrAllocCat(command, crlf); - CTRACE(tfp, "HTTP: Sending Cookie: %s\n", cookie); + CTRACE((tfp, "HTTP: Sending Cookie: %s\n", cookie)); } FREE(cookie); } @@ -702,12 +925,11 @@ use_tunnel: ** an Authorization or Proxy-Authorization ** header to be included. - FM */ - sprintf(line, "%s%c%c", auth, CR, LF); - StrAllocCat(command, line); - CTRACE(tfp, (auth_proxy ? + HTSprintf(&command, "%s%c%c", auth, CR, LF); + CTRACE((tfp, (auth_proxy ? "HTTP: Sending proxy authorization: %s\n" : "HTTP: Sending authorization: %s\n"), - auth); + auth)); } else if (auth && *auth == '\0') { /* ** If auth is a zero-length string, the user either @@ -730,9 +952,9 @@ use_tunnel: goto done; } } else { - CTRACE(tfp, (auth_proxy ? + CTRACE((tfp, (auth_proxy ? "HTTP: Not sending proxy authorization (yet).\n" : - "HTTP: Not sending authorization (yet).\n")); + "HTTP: Not sending authorization (yet).\n"))); } FREE(hostname); FREE(docname); @@ -740,44 +962,44 @@ use_tunnel: auth_proxy = NO; } + if ( #ifdef USE_SSL - if (!do_connect && do_post) { -#else - if (do_post) { + !do_connect && #endif /* USE_SSL */ - CTRACE (tfp, "HTTP: Doing post, content-type '%s'\n", + do_post) { + CTRACE((tfp, "HTTP: Doing post, content-type '%s'\n", anAnchor->post_content_type ? anAnchor->post_content_type - : "lose"); - sprintf (line, "Content-type: %s%c%c", - anAnchor->post_content_type ? anAnchor->post_content_type - : "lose", CR, LF); - StrAllocCat(command, line); - { - int content_length; - if (!anAnchor->post_data) - content_length = 0; - else - content_length = strlen (anAnchor->post_data); - sprintf (line, "Content-length: %d%c%c", - content_length, CR, LF); - StrAllocCat(command, line); - } - - StrAllocCat(command, crlf); /* Blank line means "end" of headers */ - - StrAllocCat(command, anAnchor->post_data); + : "lose")); + HTSprintf(&command, "Content-type: %s%c%c", + anAnchor->post_content_type + ? anAnchor->post_content_type + : "lose", + CR, LF); +/* + * Ack! This assumes non-binary data! Icky! + * + */ + HTSprintf(&command, "Content-length: %d%c%c", + (anAnchor->post_data) + ? strlen (anAnchor->post_data) + : 0, + CR, LF); + + StrAllocCat(command, crlf); /* Blank line means "end" of headers */ + + StrAllocCat(command, anAnchor->post_data); } - else - StrAllocCat(command, crlf); /* Blank line means "end" of headers */ + else + StrAllocCat(command, crlf); /* Blank line means "end" of headers */ #ifdef USE_SSL - CTRACE (tfp, "Writing:\n%s%s----------------------------------\n", + CTRACE((tfp, "Writing:\n%s%s----------------------------------\n", command, - (anAnchor->post_data && !do_connect ? crlf : "")); + (anAnchor->post_data && !do_connect ? crlf : ""))); #else - CTRACE (tfp, "Writing:\n%s%s----------------------------------\n", + CTRACE((tfp, "Writing:\n%s%s----------------------------------\n", command, - (anAnchor->post_data ? crlf : "")); + (anAnchor->post_data ? crlf : ""))); #endif /* USE_SSL */ _HTProgress (gettext("Sending HTTP request.")); @@ -791,9 +1013,10 @@ use_tunnel: #endif /* NOT_ASCII */ status = HTTP_NETWRITE(s, command, (int)strlen(command), handle); FREE(command); + FREE(linebuf); if (status <= 0) { if (status == 0) { - CTRACE (tfp, "HTTP: Got status 0 in initial write\n"); + CTRACE((tfp, "HTTP: Got status 0 in initial write\n")); /* Do nothing. */ } else if ((SOCKET_ERRNO == ENOTCONN || SOCKET_ERRNO == ECONNRESET || @@ -803,14 +1026,14 @@ use_tunnel: /* ** Arrrrgh, HTTP 0/1 compability problem, maybe. */ - CTRACE (tfp, "HTTP: BONZO ON WRITE Trying again with HTTP0 request.\n"); + CTRACE((tfp, "HTTP: BONZO ON WRITE Trying again with HTTP0 request.\n")); _HTProgress (RETRYING_AS_HTTP0); HTTP_NETCLOSE(s, handle); extensions = NO; already_retrying = TRUE; goto try_again; } else { - CTRACE (tfp, "HTTP: Hit unexpected network WRITE error; aborting connection.\n"); + CTRACE((tfp, "HTTP: Hit unexpected network WRITE error; aborting connection.\n")); HTTP_NETCLOSE(s, handle); status = -1; HTAlert(gettext("Unexpected network write error; connection aborted.")); @@ -818,7 +1041,7 @@ use_tunnel: } } - CTRACE (tfp, "HTTP: WRITE delivered OK\n"); + CTRACE((tfp, "HTTP: WRITE delivered OK\n")); _HTProgress (gettext("HTTP request sent; waiting for response.")); /* Read the first line of the response @@ -829,7 +1052,7 @@ use_tunnel: BOOL end_of_file = NO; int buffer_length = INIT_LINE_SIZE; - line_buffer = (char *)calloc(1, (buffer_length * sizeof(char))); + line_buffer = typecallocn(char, buffer_length); if (line_buffer == NULL) outofmem(__FILE__, "HTLoadHTTP"); @@ -845,31 +1068,33 @@ use_tunnel: if (line_buffer == NULL) outofmem(__FILE__, "HTLoadHTTP"); } - CTRACE (tfp, "HTTP: Trying to read %d\n", - buffer_length - length - 1); + CTRACE((tfp, "HTTP: Trying to read %d\n", buffer_length - length - 1)); status = HTTP_NETREAD(s, line_buffer + length, buffer_length - length - 1, handle); - CTRACE (tfp, "HTTP: Read %d\n", status); + CTRACE((tfp, "HTTP: Read %d\n", status)); if (status <= 0) { /* * Retry if we get nothing back too. * Bomb out if we get nothing twice. */ if (status == HT_INTERRUPTED) { - CTRACE (tfp, "HTTP: Interrupted initial read.\n"); + CTRACE((tfp, "HTTP: Interrupted initial read.\n")); _HTProgress (CONNECTION_INTERRUPTED); HTTP_NETCLOSE(s, handle); status = HT_NO_DATA; goto clean_up; } else if (status < 0 && (SOCKET_ERRNO == ENOTCONN || +#ifdef _WINDOWS /* 1997/11/09 (Sun) 16:59:58 */ + SOCKET_ERRNO == ETIMEDOUT || +#endif SOCKET_ERRNO == ECONNRESET || SOCKET_ERRNO == EPIPE) && !already_retrying && !do_post) { /* ** Arrrrgh, HTTP 0/1 compability problem, maybe. */ - CTRACE (tfp, "HTTP: BONZO Trying again with HTTP0 request.\n"); + CTRACE((tfp, "HTTP: BONZO Trying again with HTTP0 request.\n")); HTTP_NETCLOSE(s, handle); FREE(line_buffer); FREE(line_kept_clean); @@ -879,8 +1104,8 @@ use_tunnel: _HTProgress (RETRYING_AS_HTTP0); goto try_again; } else { - CTRACE (tfp, "HTTP: Hit unexpected network read error; aborting connection; status %d.\n", - status); + CTRACE((tfp, "HTTP: Hit unexpected network read error; aborting connection; status %d.\n", + status)); HTAlert(gettext("Unexpected network read error; connection aborted.")); HTTP_NETCLOSE(s, handle); status = -1; @@ -916,6 +1141,7 @@ use_tunnel: if (line_kept_clean == NULL) outofmem(__FILE__, "HTLoadHTTP"); memcpy(line_kept_clean, line_buffer, buffer_length); + real_length_of_line = length + status; } eol = strchr(line_buffer + length, LF); @@ -939,11 +1165,13 @@ use_tunnel: while (!eol && !end_of_file && bytes_already_read < 100); } /* Scope of loop variables */ + /* save total length, in case we decide later to show it all - kw */ + rawlength = length; /* We now have a terminated unfolded line. Parse it. ** -------------------------------------------------- */ - CTRACE(tfp, "HTTP: Rx: %s\n", line_buffer); + CTRACE((tfp, "HTTP: Rx: %s\n", line_buffer)); /* ** Kludge to work with old buggy servers and the VMS Help gateway. @@ -959,7 +1187,7 @@ use_tunnel: FREE(line_kept_clean); extensions = NO; already_retrying = TRUE; - CTRACE(tfp, "HTTP: close socket %d to retry with HTTP0\n", s); + CTRACE((tfp, "HTTP: close socket %d to retry with HTTP0\n", s)); HTTP_NETCLOSE(s, handle); /* print a progress message */ _HTProgress (RETRYING_AS_HTTP0); @@ -970,7 +1198,6 @@ use_tunnel: { int fields; char server_version[VERSION_LENGTH+1]; - int server_status; server_version[0] = 0; @@ -978,18 +1205,18 @@ use_tunnel: server_version, &server_status); - CTRACE (tfp, "HTTP: Scanned %d fields from line_buffer\n", fields); + CTRACE((tfp, "HTTP: Scanned %d fields from line_buffer\n", fields)); if (http_error_file) { /* Make the status code externally available */ FILE *error_file; #ifdef SERVER_STATUS_ONLY - error_file = fopen(http_error_file, "w"); + error_file = fopen(http_error_file, TXT_W); if (error_file) { /* Managed to open the file */ fprintf(error_file, "error=%d\n", server_status); fclose(error_file); } #else - error_file = fopen(http_error_file, "a"); + error_file = fopen(http_error_file, TXT_A); if (error_file) { /* Managed to open the file */ fprintf(error_file, " URL=%s (%s)\n", url, METHOD); fprintf(error_file, "STATUS=%s\n", line_buffer); @@ -1010,7 +1237,7 @@ use_tunnel: */ HTAtom * encoding; - CTRACE (tfp, "--- Talking HTTP0.\n"); + CTRACE((tfp, "--- Talking HTTP0.\n")); format_in = HTFileFormat(url, &encoding, NULL); /* @@ -1019,19 +1246,19 @@ use_tunnel: ** without looking at content. */ if (!strncmp(HTAtom_name(format_in), "text/plain",10)) { - CTRACE(tfp, "HTTP: format_in being changed to text/HTML\n"); + CTRACE((tfp, "HTTP: format_in being changed to text/HTML\n")); format_in = WWW_HTML; } if (!IsUnityEnc(encoding)) { /* ** Change the format to that for "www/compressed". */ - CTRACE(tfp, "HTTP: format_in is '%s',\n", HTAtom_name(format_in)); + CTRACE((tfp, "HTTP: format_in is '%s',\n", HTAtom_name(format_in))); StrAllocCopy(anAnchor->content_type, HTAtom_name(format_in)); StrAllocCopy(anAnchor->content_encoding, HTAtom_name(encoding)); format_in = HTAtom_for("www/compressed"); - CTRACE(tfp, " Treating as '%s' with encoding '%s'\n", - "www/compressed", HTAtom_name(encoding)); + CTRACE((tfp, " Treating as '%s' with encoding '%s'\n", + "www/compressed", HTAtom_name(encoding))); } start_of_data = line_kept_clean; @@ -1040,7 +1267,7 @@ use_tunnel: ** Set up to decode full HTTP/1.n response. - FM */ format_in = HTAtom_for("www/mime"); - CTRACE (tfp, "--- Talking HTTP1.\n"); + CTRACE((tfp, "--- Talking HTTP1.\n")); /* ** We set start_of_data to "" when !eol here because there @@ -1098,6 +1325,7 @@ use_tunnel: */ HTAlert(line_buffer); HTTP_NETCLOSE(s, handle); + HTNoDataOK = 1; status = HT_NO_DATA; goto clean_up; @@ -1135,17 +1363,17 @@ use_tunnel: * > 206 is unknown. * All should return something to display. */ -#ifdef USE_SSL - if (do_connect) { - CTRACE(tfp, "HTTP: Proxy tunnel to '%s' established.\n", - connect_host); +#if defined(USE_SSL) && !defined(DISABLE_NEWS) + if (do_connect) { + CTRACE((tfp, "HTTP: Proxy tunnel to '%s' established.\n", + connect_host)); do_connect = FALSE; url = connect_url; FREE(line_buffer); FREE(line_kept_clean); if (!strncmp(connect_url, "snews", 5)) { - CTRACE(tfp, - " Will attempt handshake and snews connection.\n"); + CTRACE((tfp, + " Will attempt handshake and snews connection.\n")); status = HTNewsProxyConnect(s, url, anAnchor, format_out, sink); goto done; @@ -1157,10 +1385,10 @@ use_tunnel: had_header = NO; length = 0; doing_redirect = FALSE; - permanent_redirection = FALSE; + permanent_redirection = FALSE; target = NULL; - CTRACE(tfp, - " Will attempt handshake and resubmit headers.\n"); + CTRACE((tfp, + " Will attempt handshake and resubmit headers.\n")); goto use_tunnel; } #endif /* USE_SSL */ @@ -1283,8 +1511,6 @@ use_tunnel: * previous document. - FM */ { - char *cp; - if ((dump_output_immediately || traversal) && do_post && server_status != 303 && @@ -1303,383 +1529,22 @@ use_tunnel: goto clean_up; } - /* - * Get the rest of the headers and data, if - * any, and then close the connection. - FM - */ - while ((status = HTTP_NETREAD(s, line_buffer, - (INIT_LINE_SIZE - 1), - handle)) > 0) { -#ifdef NOT_ASCII /* S/390 -- gil -- 0581 */ - { char *p; - - for ( p = line_buffer; p < line_buffer + status; p++ ) - *p = FROMASCII(*p); - } -#endif /* NOT_ASCII */ - line_buffer[status] = '\0'; - StrAllocCat(line_kept_clean, line_buffer); - } - HTTP_NETCLOSE(s, handle); - if (status == HT_INTERRUPTED) { - /* - * Impatient user. - FM - */ - CTRACE (tfp, "HTTP: Interrupted followup read.\n"); - _HTProgress (CONNECTION_INTERRUPTED); - status = HT_INTERRUPTED; - goto clean_up; - } - doing_redirect = TRUE; + HTProgress(line_buffer); if (server_status == 301) { /* Moved Permanently */ - HTProgress(line_buffer); if (do_post) { /* * Don't make the redirection permanent * if we have POST content. - FM */ - CTRACE(tfp, "HTTP: Have POST content. Treating 301 (Permanent) as Temporary.\n"); + CTRACE((tfp, "HTTP: Have POST content. Treating 301 (Permanent) as Temporary.\n")); HTAlert( gettext("Have POST content. Treating Permanent Redirection as Temporary.\n")); } else { permanent_redirection = TRUE; } } + doing_redirect = TRUE; - /* - ** Look for "Set-Cookie:" and "Set-Cookie2:" headers. - FM - */ - if (LYSetCookies == TRUE) { - char *value = NULL; - char *SetCookie = NULL; - char *SetCookie2 = NULL; - cp = line_kept_clean; - while (*cp) { - /* - ** Assume a CRLF pair terminates - ** the header section. - FM - */ - if (*cp == CR) { - if (*(cp+1) == LF && - *(cp+2) == CR && *(cp+3) == LF) { - break; - } - } - if (TOUPPER(*cp) != 'S') { - cp++; - } else if (!strncasecomp(cp, "Set-Cookie:", 11)) { - char *cp1 = NULL, *cp2 = NULL; - cp += 11; -Cookie_continuation: - /* - * Trim leading spaces. - FM - */ - while (isspace((unsigned char)*cp)) - cp++; - /* - ** Accept CRLF, LF, or CR as end of line. - FM - */ - if (((cp1 = strchr(cp, LF)) != NULL) || - (cp2 = strchr(cp, CR)) != NULL) { - if (*cp1) { - *cp1 = '\0'; - if ((cp2 = strchr(cp, CR)) != NULL) - *cp2 = '\0'; - } else { - *cp2 = '\0'; - } - } - if (*cp == '\0') { - if (cp1) - *cp1 = LF; - if (cp2) - *cp2 = CR; - if (value != NULL) { - HTMIME_TrimDoubleQuotes(value); - if (SetCookie == NULL) { - StrAllocCopy(SetCookie, value); - } else { - StrAllocCat(SetCookie, ", "); - StrAllocCat(SetCookie, value); - } - FREE(value); - } - break; - } - StrAllocCat(value, cp); - cp += strlen(cp); - if (cp1) { - *cp1 = LF; - cp1 = NULL; - } - if (cp2) { - *cp2 = CR; - cp2 = NULL; - } - cp1 = cp; - if (*cp1 == CR) - cp1++; - if (*cp1 == LF) - cp1++; - if (*cp1 == ' ' || *cp1 == '\t') { - StrAllocCat(value, " "); - cp = cp1; - cp++; - cp1 = NULL; - goto Cookie_continuation; - } - HTMIME_TrimDoubleQuotes(value); - if (SetCookie == NULL) { - StrAllocCopy(SetCookie, value); - } else { - StrAllocCat(SetCookie, ", "); - StrAllocCat(SetCookie, value); - } - FREE(value); - } else if (!strncasecomp(cp, "Set-Cookie2:", 12)) { - char *cp1 = NULL, *cp2 = NULL; - cp += 12; -Cookie2_continuation: - /* - * Trim leading spaces. - FM - */ - while (isspace((unsigned char)*cp)) - cp++; - /* - ** Accept CRLF, LF, or CR as end of line. - FM - */ - if (((cp1 = strchr(cp, LF)) != NULL) || - (cp2 = strchr(cp, CR)) != NULL) { - if (*cp1) { - *cp1 = '\0'; - if ((cp2 = strchr(cp, CR)) != NULL) - *cp2 = '\0'; - } else { - *cp2 = '\0'; - } - } - if (*cp == '\0') { - if (cp1) - *cp1 = LF; - if (cp2) - *cp2 = CR; - if (value != NULL) { - HTMIME_TrimDoubleQuotes(value); - if (SetCookie2 == NULL) { - StrAllocCopy(SetCookie2, value); - } else { - StrAllocCat(SetCookie2, ", "); - StrAllocCat(SetCookie2, value); - } - FREE(value); - } - break; - } - StrAllocCat(value, cp); - cp += strlen(cp); - if (cp1) { - *cp1 = LF; - cp1 = NULL; - } - if (cp2) { - *cp2 = CR; - cp2 = NULL; - } - cp1 = cp; - if (*cp1 == CR) - cp1++; - if (*cp1 == LF) - cp1++; - if (*cp1 == ' ' || *cp1 == '\t') { - StrAllocCat(value, " "); - cp = cp1; - cp++; - cp1 = NULL; - goto Cookie2_continuation; - } - HTMIME_TrimDoubleQuotes(value); - if (SetCookie2 == NULL) { - StrAllocCopy(SetCookie2, value); - } else { - StrAllocCat(SetCookie2, ", "); - StrAllocCat(SetCookie2, value); - } - FREE(value); - } else { - cp++; - } - } - FREE(value); - if (SetCookie != NULL || SetCookie2 != NULL) { - LYSetCookie(SetCookie, SetCookie2, anAnchor->address); - FREE(SetCookie); - FREE(SetCookie2); - } - } - - /* - * Look for the "Location:" in the headers. - FM - */ - cp = line_kept_clean; - while (*cp) { - if (TOUPPER(*cp) != 'L') { - cp++; - } else if (!strncasecomp(cp, "Location:", 9)) { - char *cp1 = NULL, *cp2 = NULL; - cp += 9; - /* - * Trim leading spaces. - FM - */ - while (isspace((unsigned char)*cp)) - cp++; - /* - * Accept CRLF, LF, or CR as end of header. - FM - */ - if (((cp1 = strchr(cp, LF)) != NULL) || - (cp2 = strchr(cp, CR)) != NULL) { - if (*cp1) { - *cp1 = '\0'; - if ((cp2 = strchr(cp, CR)) != NULL) - *cp2 = '\0'; - } else { - *cp2 = '\0'; - } - /* - * Load the new URL into redirecting_url, - * and make sure it's not zero-length. - FM - */ - StrAllocCopy(redirecting_url, cp); - HTMIME_TrimDoubleQuotes(redirecting_url); - if (*redirecting_url == '\0') { - /* - * The "Location:" value is zero-length, and - * thus is probably something in the body, so - * we'll show the user what was returned. - FM - */ - CTRACE(tfp, "HTTP: 'Location:' is zero-length!\n"); - if (cp1) - *cp1 = LF; - if (cp2) - *cp2 = CR; - bad_location = TRUE; - FREE(redirecting_url); - HTAlert( - gettext("Got redirection with a bad Location header.")); - HTProgress(line_buffer); - break; - } - - /* - * Set up for checking redirecting_url in - * LYGetFile.c for restrictions before we - * seek the document at that Location. - FM - */ - HTProgress(line_buffer); - CTRACE(tfp, "HTTP: Picked up location '%s'\n", - redirecting_url); - if (cp1) - *cp1 = LF; - if (cp2) - *cp2 = CR; - if (server_status == 305) { /* Use Proxy */ - /* - * Make sure the proxy field ends with - * a slash. - FM - */ - if (redirecting_url[strlen(redirecting_url)-1] - != '/') - StrAllocCat(redirecting_url, "/"); - /* - * Append our URL. - FM - */ - StrAllocCat(redirecting_url, anAnchor->address); - CTRACE(tfp, "HTTP: Proxy URL is '%s'\n", - redirecting_url); - } - if (!do_post || - server_status == 303 || - server_status == 302) { - /* - * We don't have POST content (nor support PUT - * or DELETE), or the status is "See Other" or - * "General Redirection" and we can convert to - * GET, so go back and check out the new URL. - FM - */ - status = HT_REDIRECTING; - goto clean_up; - } - /* - * Make sure the user wants to redirect - * the POST content, or treat as GET - FM & DK - */ - switch (HTConfirmPostRedirect(redirecting_url, - server_status)) { - /* - * User failed to confirm. - * Abort the fetch. - */ - case 0: - doing_redirect = FALSE; - FREE(redirecting_url); - status = HT_NO_DATA; - goto clean_up; - - /* - * User wants to treat as GET with no content. - * Go back to check out the URL. - */ - case 303: - status = HT_REDIRECTING; - goto clean_up; - - /* - * Set the flag to retain the POST - * content and go back to check out - * the URL. - FM - */ - default: - status = HT_REDIRECTING; - redirect_post_content = TRUE; - goto clean_up; - } - } - break; - } else { - /* - * Keep looking for the Location header. - FM - */ - cp++; - } - } - - /* - * If we get to here, we didn't find the Location - * header, so we'll show the user what we got, if - * anything. - FM - */ - CTRACE (tfp, "HTTP: Failed to pick up location.\n"); - doing_redirect = FALSE; - permanent_redirection = FALSE; - start_of_data = line_kept_clean; - length = strlen(start_of_data); - if (!bad_location) { - HTAlert(gettext("Got redirection with no Location header.")); - HTProgress(line_buffer); - } - if (traversal) { - HTTP_NETCLOSE(s, handle); - status = -1; - goto clean_up; - } - if (!dump_output_immediately && - format_out == HTAtom_for("www/download")) { - /* - * Convert a download request to - * a presentation request for - * interactive users. - FM - */ - format_out = WWW_PRESENT; - } break; } @@ -1713,9 +1578,9 @@ Cookie2_continuation: goto clean_up; } - CTRACE(tfp, "%s %d %s\n", + CTRACE((tfp, "%s %d %s\n", "HTTP: close socket", s, - "to retry with Access Authorization"); + "to retry with Access Authorization")); _HTProgress ( gettext("Retrying with access authorization information.")); @@ -1766,9 +1631,9 @@ Cookie2_continuation: goto clean_up; } - CTRACE(tfp, "%s %d %s\n", + CTRACE((tfp, "%s %d %s\n", "HTTP: close socket", s, - "to retry with Proxy Authorization"); + "to retry with Proxy Authorization")); _HTProgress (HTTP_RETRY_WITH_PROXY); FREE(line_buffer); @@ -1913,6 +1778,13 @@ Cookie2_continuation: */ if (HTCheckForInterrupt()) { HTTP_NETCLOSE(s, handle); + if (doing_redirect) { + /* + * Impatient user. - FM + */ + CTRACE((tfp, "HTTP: Interrupted followup read.\n")); + _HTProgress (CONNECTION_INTERRUPTED); + } status = HT_INTERRUPTED; goto clean_up; } @@ -1924,8 +1796,31 @@ Cookie2_continuation: ** It was a HEAD request, or we want the headers and source. */ start_of_data = line_kept_clean; - length = strlen(start_of_data); +#ifdef SH_EX /* FIX BUG by kaz@maczuka.hitachi.ibaraki.jp */ +/* GIF file contains \0, so strlen does not return the data length */ + length = real_length_of_line; +#else + length = rawlength; +#endif format_in = HTAtom_for("text/plain"); + + } else if (doing_redirect) { + + format_in = HTAtom_for("message/x-http-redirection"); + StrAllocCopy(anAnchor->content_type, HTAtom_name(format_in)); + if (traversal) { + format_out = WWW_DEBUG; + if (!sink) + sink = HTErrorStream(); + } else if (!dump_output_immediately && + format_out == HTAtom_for("www/download")) { + /* + * Convert a download request to + * a presentation request for + * interactive users. - FM + */ + format_out = WWW_PRESENT; + } } target = HTStreamStack(format_in, @@ -1933,12 +1828,13 @@ Cookie2_continuation: sink, anAnchor); if (!target || target == NULL) { - char buffer[1024]; /* @@@@@@@@ */ + char *buffer = NULL; HTTP_NETCLOSE(s, handle); - sprintf(buffer, CANNOT_CONVERT_I_TO_O, + HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(format_in), HTAtom_name(format_out)); _HTProgress (buffer); + FREE(buffer); status = -1; goto clean_up; } @@ -1953,12 +1849,23 @@ Cookie2_continuation: */ rv = HTCopy(anAnchor, s, (void *)handle, target); + /* + ** If we get here with doing_redirect set, it means that we were + ** looking for a Location header. We either have got it now in + ** redirecting_url - in that case the stream should not have loaded + ** any data. Or we didn't get it, in that case the stream may have + ** presented the message body normally. - kw + */ + if (rv == -1) { /* ** Intentional interrupt before data were received, not an error */ /* (*target->isa->_abort)(target, NULL); */ /* already done in HTCopy */ - status = HT_INTERRUPTED; + if (doing_redirect && traversal) + status = -1; + else + status = HT_INTERRUPTED; HTTP_NETCLOSE(s, handle); goto clean_up; } @@ -1968,21 +1875,29 @@ Cookie2_continuation: ** Aw hell, a REAL error, maybe cuz it's a dumb HTTP0 server */ (*target->isa->_abort)(target, NULL); - HTTP_NETCLOSE(s, handle); - if (!already_retrying && !do_post) { - CTRACE (tfp, "HTTP: Trying again with HTTP0 request.\n"); + if (doing_redirect && redirecting_url) { /* - ** May as well consider it an interrupt -- right? + ** Got a location before the error occurred? Then consider it + ** an interrupt but proceed below as normal. - kw */ - FREE(line_buffer); - FREE(line_kept_clean); - extensions = NO; - already_retrying = TRUE; - _HTProgress (RETRYING_AS_HTTP0); - goto try_again; + /* do nothing here */ } else { - status = HT_NOT_LOADED; - goto clean_up; + HTTP_NETCLOSE(s, handle); + if (!doing_redirect && !already_retrying && !do_post) { + CTRACE((tfp, "HTTP: Trying again with HTTP0 request.\n")); + /* + ** May as well consider it an interrupt -- right? + */ + FREE(line_buffer); + FREE(line_kept_clean); + extensions = NO; + already_retrying = TRUE; + _HTProgress (RETRYING_AS_HTTP0); + goto try_again; + } else { + status = HT_NOT_LOADED; + goto clean_up; + } } } @@ -1990,23 +1905,107 @@ Cookie2_continuation: ** Free if complete transmission (socket was closed before return). ** Close socket if partial transmission (was freed on abort). */ - if (rv != HT_INTERRUPTED) { + if (rv != HT_INTERRUPTED && rv != -2) { (*target->isa->_free)(target); } else { HTTP_NETCLOSE(s, handle); } if (doing_redirect) { - /* - ** We already jumped over all this if the "case 3:" code worked - ** above, but we'll check here as a backup in case it fails. - FM - */ - /* Lou's old comment: - FM */ - /* OK, now we've got the redirection URL temporarily stored - in external variable redirecting_url, exported from HTMIME.c, - since there's no straightforward way to do this in the library - currently. Do the right thing. */ - status = HT_REDIRECTING; + if (redirecting_url) { + /* + * Set up for checking redirecting_url in + * LYGetFile.c for restrictions before we + * seek the document at that Location. - FM + */ + CTRACE((tfp, "HTTP: Picked up location '%s'\n", + redirecting_url)); + if (rv == HT_INTERRUPTED) { + /* + ** Intentional interrupt after data were received, not an + ** error (probably). We take it as a user request to + ** abandon the redirection chain. + ** This could reasonably be changed (by just removing this + ** block), it would make sense if there are redirecting + ** resources that "hang" after sending the headers. - kw + */ + FREE(redirecting_url); + CTRACE((tfp, "HTTP: Interrupted followup read.\n")); + status = HT_INTERRUPTED; + goto clean_up; + } + HTProgress(line_buffer); + if (server_status == 305) { /* Use Proxy */ + /* + * Make sure the proxy field ends with + * a slash. - FM + */ + if (redirecting_url[strlen(redirecting_url)-1] + != '/') + StrAllocCat(redirecting_url, "/"); + /* + * Append our URL. - FM + */ + StrAllocCat(redirecting_url, anAnchor->address); + CTRACE((tfp, "HTTP: Proxy URL is '%s'\n", + redirecting_url)); + } + if (!do_post || + server_status == 303 || + server_status == 302) { + /* + * We don't have POST content (nor support PUT + * or DELETE), or the status is "See Other" or + * "General Redirection" and we can convert to + * GET, so go back and check out the new URL. - FM + */ + status = HT_REDIRECTING; + goto clean_up; + } + /* + * Make sure the user wants to redirect + * the POST content, or treat as GET - FM & DK + */ + switch (HTConfirmPostRedirect(redirecting_url, + server_status)) { + /* + * User failed to confirm. + * Abort the fetch. + */ + case 0: + doing_redirect = FALSE; + FREE(redirecting_url); + status = HT_NO_DATA; + goto clean_up; + + /* + * User wants to treat as GET with no content. + * Go back to check out the URL. + */ + case 303: + break; + + /* + * Set the flag to retain the POST + * content and go back to check out + * the URL. - FM + */ + default: + redirect_post_content = TRUE; + } + + /* Lou's old comment: - FM */ + /* OK, now we've got the redirection URL temporarily stored + in external variable redirecting_url, exported from HTMIME.c, + since there's no straightforward way to do this in the library + currently. Do the right thing. */ + + status = HT_REDIRECTING; + + } else { + status = traversal ? -1 : HT_LOADED; + } + } else { /* ** If any data were received, treat as a complete transmission diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTelnet.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTelnet.c index df6084fac6f..33f87e4eb8d 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTelnet.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTTelnet.c @@ -36,8 +36,12 @@ PRIVATE void do_system ARGS1(char *, command) { - CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command); + CTRACE((tfp, "HTTelnet: Command is: %s\n\n", command)); +#ifdef UNIX /* want LYSystem's signal sanitizing - kw */ + LYSystem(command); +#else /* Non-UNIX should use LYSystem too? - left for now - kw */ system(command); +#endif FREE(command); } @@ -65,7 +69,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) * or tab to prevent security whole */ for(cp = host; *cp != '\0'; cp++) { - if(!isalnum(*cp) && *cp != '_' && *cp != '-' && + if(!isalnum(UCH(*cp)) && *cp != '_' && *cp != '-' && *cp != ':' && *cp != '.' && *cp != '@') { *cp = '\0'; break; @@ -86,12 +90,12 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) *port++ = '\0'; /* Split */ if (!hostname || *hostname == '\0') { - CTRACE(tfp, "HTTelnet: No host specified!\n"); + CTRACE((tfp, "HTTelnet: No host specified!\n")); return HT_NO_DATA; } else if (!valid_hostname(hostname)) { char *prefix = NULL; char *line = NULL; - CTRACE(tfp, "HTTelnet: Invalid hostname %s!\n", host); + CTRACE((tfp, "HTTelnet: Invalid hostname %s!\n", host)); HTSprintf0(&prefix, gettext("remote %s session:"), acc_method); HTSprintf0(&line, @@ -149,7 +153,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) * NeXTSTEP is the implied version of the NeXT operating system. * You may need to define this yourself. */ -#if defined(NeXT) && defined(NeXTSTEP) && NeXTSTEP<=20100 +#if !defined(TELNET_DONE) && (defined(NeXT) && defined(NeXTSTEP) && NeXTSTEP<=20100) #define FMT_TELNET "%s%s%s %s %s" HTAddParam(&command, FMT_TELNET, 1, TELNET_PATH); @@ -160,13 +164,11 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) HTEndParam(&command, FMT_TELNET, 5); do_system(command); - return HT_NO_DATA; /* Ok - it was done but no data */ #define TELNET_DONE #endif -/* Most unix machines suppport username only with rlogin */ -#if defined(unix) || defined(DOSPATH) -#ifndef TELNET_DONE +/* Most unix machines support username only with rlogin */ +#if !defined(TELNET_DONE) && (defined(UNIX) || defined(DOSPATH) || defined(__CYGWIN__)) #define FMT_RLOGIN "%s %s%s%s" #define FMT_TN3270 "%s %s %s" @@ -196,6 +198,9 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) } #ifdef __DJGPP__ +#ifdef WATT32 + _eth_release(); +#endif /* WATT32 */ __djgpp_set_ctrl_c(0); _go32_want_ctrl_break(1); #endif /* __DJGPP__ */ @@ -203,14 +208,16 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) #ifdef __DJGPP__ __djgpp_set_ctrl_c(1); _go32_want_ctrl_break(0); +#ifdef WATT32 + _eth_init(); +#endif /* WATT32 */ #endif /* __DJGPP__ */ - return HT_NO_DATA; /* Ok - it was done but no data */ + #define TELNET_DONE -#endif /* !TELNET_DONE */ #endif /* unix */ /* VMS varieties */ -#if defined(MULTINET) +#if !defined(TELNET_DONE) && (defined(MULTINET)) if (login_protocol == rlogin) { HTSprintf0(&command, "RLOGIN%s%s%s%s%s %s", /*lm 930713 */ user ? "/USERNAME=\"" : "", @@ -234,66 +241,60 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) } do_system(command); - return HT_NO_DATA; /* Ok - it was done but no data */ #define TELNET_DONE #endif /* MULTINET */ -#if defined(WIN_TCP) - { - char *cp; - - if ((cp=getenv("WINTCP_COMMAND_STYLE")) != NULL && - 0==strncasecomp(cp, "VMS", 3)) { /* VMS command syntax */ - if (login_protocol == rlogin) { - HTSprintf0(&command, "RLOGIN%s%s%s%s%s %s", /*lm 930713 */ - user ? "/USERNAME=\"" : "", - user ? user : "", - user ? "\"" : "", - port ? "/PORT=" : "", - port ? port : "", - hostname); - - } else if (login_protocol == tn3270) { - HTSprintf0(&command, "TELNET/TN3270 %s%s %s", - port ? "/PORT=" : "", - port ? port : "", - hostname); - - } else { /* TELNET */ - HTSprintf0(&command, "TELNET %s%s %s", - port ? "/PORT=" : "", - port ? port : "", - hostname); - } - - } else { /* UNIX command syntax */ - if (login_protocol == rlogin) { - HTSprintf0(&command, "RLOGIN %s%s%s%s%s", - hostname, - user ? " -l " : "", - user ? "\"" : "", - user ? user : "", - user ? "\"" : ""); - - } else if (login_protocol == tn3270) { - HTSprintf0(&command, "TN3270 %s %s", - hostname, - port ? port : ""); - - } else { /* TELNET */ - HTSprintf0(&command, "TELNET %s %s", - hostname, - port ? port : ""); - } +#if !defined(TELNET_DONE) && defined(WIN_TCP) + if ((cp=getenv("WINTCP_COMMAND_STYLE")) != NULL && + 0==strncasecomp(cp, "VMS", 3)) { /* VMS command syntax */ + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN%s%s%s%s%s %s", /*lm 930713 */ + user ? "/USERNAME=\"" : "", + user ? user : "", + user ? "\"" : "", + port ? "/PORT=" : "", + port ? port : "", + hostname); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TELNET/TN3270 %s%s %s", + port ? "/PORT=" : "", + port ? port : "", + hostname); + + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s%s %s", + port ? "/PORT=" : "", + port ? port : "", + hostname); } - do_system(command); - return HT_NO_DATA; /* Ok - it was done but no data */ + } else { /* UNIX command syntax */ + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN %s%s%s%s%s", + hostname, + user ? " -l " : "", + user ? "\"" : "", + user ? user : "", + user ? "\"" : ""); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TN3270 %s %s", + hostname, + port ? port : ""); + + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s %s", + hostname, + port ? port : ""); + } } + + do_system(command); #define TELNET_DONE #endif /* WIN_TCP */ -#ifdef UCX +#if !defined(TELNET_DONE) && defined(UCX) if (login_protocol == rlogin) { HTSprintf0(&command, "RLOGIN%s%s%s %s %s", user ? "/USERNAME=\"" : "", @@ -314,11 +315,10 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) } do_system(command); - return HT_NO_DATA; /* Ok - it was done but no data */ #define TELNET_DONE #endif /* UCX */ -#ifdef CMU_TCP +#if !defined(TELNET_DONE) && defined(CMU_TCP) if (login_protocol == telnet) { HTSprintf0(&command, "TELNET %s%s %s", port ? "/PORT=" : "", @@ -336,14 +336,10 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) LYgetch(); HadVMSInterrupt = FALSE; } - return HT_NO_DATA; /* Ok - it was done but no data */ #define TELNET_DONE #endif /* CMU_TCP */ -#ifdef SOCKETSHR_TCP - { - char *cp; - +#if !defined(TELNET_DONE) && defined(SOCKETSHR_TCP) if (getenv("MULTINET_SOCKET_LIBRARY") != NULL) { if (login_protocol == rlogin) { HTSprintf0(&command, "MULTINET RLOGIN%s%s%s%s %s", /*lm 930713 */ @@ -409,7 +405,8 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) do_system(command); return HT_NO_DATA; /* Ok - it was done but no data */ } - else if (getenv("UCX$DEVICE") != NULL) { + else if (getenv("UCX$DEVICE") != NULL + || getenv("TCPIP$DEVICE") != NULL) { if (login_protocol == rlogin) { HTSprintf0(&command, "RLOGIN%s%s %s %s", user ? "/USERNAME=" : "", @@ -449,7 +446,6 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) LYgetch(); HadVMSInterrupt = FALSE; } - return HT_NO_DATA; /* Ok - it was done but no data */ } else { if (login_protocol == telnet) { @@ -469,22 +465,18 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) LYgetch(); HadVMSInterrupt = FALSE; } - return HT_NO_DATA; /* Ok - it was done but no data */ } - } #define TELNET_DONE #endif /* SOCKETSHR_TCP */ -#ifdef VM -#define SIMPLE_TELNET -#endif -#ifdef SIMPLE_TELNET +#if !defined(TELNET_DONE) && (defined(SIMPLE_TELNET) || defined(VM)) if (login_protocol == telnet) { /* telnet only */ HTSprintf0(&command, "TELNET %s", /* @@ Bug: port ignored */ hostname); do_system(command); return HT_NO_DATA; /* Ok - it was done but no data */ } +#define TELNET_DONE #endif #ifndef TELNET_DONE @@ -509,8 +501,8 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host) } #endif /* VMS */ } - return HT_NO_DATA; #endif /* !TELNET_DONE */ + return HT_NO_DATA; } /* "Load a document" -- establishes a session @@ -541,7 +533,7 @@ ARGS4 int status; if (sink) { - CTRACE(tfp, "HTTelnet: Can't output a live session -- must be interactive!\n"); + CTRACE((tfp, "HTTelnet: Can't output a live session -- must be interactive!\n")); return HT_NO_DATA; } acc_method = HTParse(addr, "file:", PARSE_ACCESS); @@ -549,7 +541,7 @@ ARGS4 host = HTParse(addr, "", PARSE_HOST); if (!host || *host == '\0') { status = HT_NO_DATA; - CTRACE(tfp, "HTTelnet: No host specified!\n"); + CTRACE((tfp, "HTTelnet: No host specified!\n")); } else { status = remote_session(acc_method, host); } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUU.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUU.c index 5465f89f375..580be9dae96 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUU.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUU.c @@ -147,7 +147,7 @@ PUBLIC int HTUU_decode ARGS3(char *, bufcoded, first = 0; for(j=0; j<256; j++) pr2six[j] = MAXVAL+1; - for(j=0; j<64; j++) pr2six[(unsigned char)six2pr[j]] = (unsigned char)j; + for(j=0; j<64; j++) pr2six[UCH(six2pr[j])] = UCH(j); #if 0 pr2six['A']= 0; pr2six['B']= 1; pr2six['C']= 2; pr2six['D']= 3; pr2six['E']= 4; pr2six['F']= 5; pr2six['G']= 6; pr2six['H']= 7; @@ -177,7 +177,7 @@ PUBLIC int HTUU_decode ARGS3(char *, bufcoded, * the output buffer, adjust the number of input bytes downwards. */ bufin = bufcoded; - while(pr2six[(unsigned char)*(bufin++)] <= MAXVAL); + while(pr2six[UCH(*(bufin++))] <= MAXVAL); nprbytes = bufin - bufcoded - 1; nbytesdecoded = ((nprbytes+3)/4) * 3; if(nbytesdecoded > outbufsize) { @@ -187,18 +187,18 @@ PUBLIC int HTUU_decode ARGS3(char *, bufcoded, bufin = bufcoded; while (nprbytes > 0) { - *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4); - *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2); - *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3])); + *(bufout++) = UCH((DEC(bufin[0]) << 2) | (DEC(bufin[1]) >> 4)); + *(bufout++) = UCH((DEC(bufin[1]) << 4) | (DEC(bufin[2]) >> 2)); + *(bufout++) = UCH((DEC(bufin[2]) << 6) | (DEC(bufin[3]))); bufin += 4; nprbytes -= 4; } if(nprbytes & 03) { if(pr2six[(int)bufin[-2]] > MAXVAL) { - nbytesdecoded -= 2; + nbytesdecoded -= 2; } else { - nbytesdecoded -= 1; + nbytesdecoded -= 1; } } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUtils.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUtils.h index dd5be2dda44..8172a7501d4 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUtils.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTUtils.h @@ -1,7 +1,7 @@ /* Utility macros for the W3 code library MACROS FOR GENERAL USE - See also: the system dependent file "tcp.h", which is included here. + See also: the system dependent file "www_tcp.h", which is included here. */ @@ -17,10 +17,12 @@ #include <sys/types.h> #include <stdio.h> -#else +#else /* HAVE_CONFIG_H */ #ifdef DJGPP #include <sys/config.h> /* pseudo-autoconf values for DJGPP libc/headers */ +#define HAVE_TRUNCATE 1 +#include <limits.h> #endif /* DJGPP */ #include <stdio.h> @@ -40,15 +42,21 @@ #define DISP_PARTIAL /* experimental */ #endif -#if defined(__STDC__) || defined(VMS) +#if defined(__STDC__) || defined(VMS) || defined(_WINDOWS) #define ANSI_VARARGS 1 #undef HAVE_STDARG_H #define HAVE_STDARG_H 1 #endif -/* FIXME: these should be removed after completing auto-configure script */ +#if defined(VMS) || defined(_WINDOWS) +#define HAVE_STDLIB_H 1 +#endif + +/* Accommodate non-autoconf'd Makefile's (VMS, DJGPP, etc) */ -/* Accommodate pre-autoconf Makefile */ +#ifndef NO_ARPA_INET_H +#define HAVE_ARPA_INET_H 1 +#endif #ifndef NO_CBREAK #define HAVE_CBREAK 1 @@ -94,44 +102,77 @@ #endif /* HAVE_CONFIG_H */ +#ifndef lynx_srand +#define lynx_srand srand +#endif + +#ifndef lynx_rand +#define lynx_rand rand +#endif + +#if '0' != 48 +#define NOT_ASCII +#endif + +#if '0' == 240 +#define EBCDIC +#endif + #ifndef LY_MAXPATH #define LY_MAXPATH 256 #endif +#ifndef GCC_NORETURN +#define GCC_NORETURN /* nothing */ +#endif + #ifndef GCC_UNUSED #define GCC_UNUSED /* nothing */ #endif -#ifdef _WINDOWS /* SCW */ -#include <windef.h> +/* FIXME: need a configure-test */ +#if defined(__STDC__) || defined(__DECC) || defined(_WINDOWS) || _WIN_CC +#define ANSI_PREPRO 1 +#endif + +#if defined(__CYGWIN32__) && ! defined(__CYGWIN__) +#define __CYGWIN__ 1 +#endif + +#if defined(__CYGWIN__) /* 1998/12/31 (Thu) 16:13:46 */ +#include <windows.h> /* #include "windef.h" */ +#define BOOLEAN_DEFINED +#undef HAVE_POPEN /* FIXME: does this not work, or is it missing */ +#endif + +#if defined(_WINDOWS) && !defined(__CYGWIN__) /* SCW */ +#include <windows.h> /* #include "windef.h" */ #define BOOLEAN_DEFINED -#define va_arg +#if !_WIN_CC /* 1999/09/29 (Wed) 22:00:53 */ #include <dos.h> +#endif +#undef sleep /* 1998/06/23 (Tue) 16:54:53 */ +extern void sleep(unsigned __seconds); #define popen _popen #define pclose _pclose -#endif /* _WINDOWS */ - -#ifdef __EMX__ -#include <unistd.h> /* should be re-include protected under EMX */ -#include <stdlib.h> /* should be re-include protected under EMX */ -#define getcwd _getcwd2 -#define chdir _chdir2 +#if defined(_MSC_VER) +typedef unsigned short mode_t; #endif -/* +#endif /* _WINDOWS */ -Debug message control. +#ifndef USE_COLOR_STYLE + /* it's useless for such setup */ +# define NO_EMPTY_HREFLESS_A +#endif - */ +#if defined(__EMX__) || defined(WIN_EX) +# define CAN_CUT_AND_PASTE +#endif -#ifdef NO_LYNX_TRACE -#define TRACE 0 -#define PROGRESS(str) /* nothing for now */ -#else -#define TRACE (WWW_TraceFlag) -#define PROGRESS(str) printf(str) - extern int WWW_TraceFlag; +#if defined(USE_SLANG) || (defined(USE_COLOR_STYLE) && defined(__EMX__)) +# define USE_BLINK #endif /* @@ -150,9 +191,23 @@ typedef void * HTError; /* Unused at present -- best definition? Standard C library for malloc() etc */ -#ifdef DGUX +#ifdef HAVE_STDLIB_H #include <stdlib.h> -#endif /* DGUX */ +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +#ifdef __EMX__ +#include <unistd.h> /* should be re-include protected under EMX */ +#define getcwd _getcwd2 +#define chdir _chdir2 +#endif #ifdef vax #ifdef unix @@ -166,22 +221,15 @@ Standard C library for malloc() etc #ifdef NeXT #include <libc.h> /* NeXT */ #endif /* NeXT */ -#ifndef MACH /* Vincent.Cate@furmint.nectar.cs.cmu.edu */ -#ifndef __STRICT_BSD__ -#include <stdlib.h> -#endif /* !__STRICT_BSD__ */ -#endif /* !MACH */ #else /* ultrix: */ #include <malloc.h> #include <memory.h> -#include <stdlib.h> /* ANSI */ /* BSN */ #endif /* !ultrix */ #else /* VMS: */ -#include <stdlib.h> #include <unixlib.h> #if defined(VAXC) && !defined(__DECC) #define malloc VAXC$MALLOC_OPT @@ -201,7 +249,7 @@ Macros for declarations #define PUBLIC /* Accessible outside this module */ #define PRIVATE static /* Accessible only within this module */ -#ifdef __STDC__ +#if defined(__STDC__) || defined(__BORLANDC__) || defined(_MSC_VER) #define CONST const /* "const" only exists in STDC */ #define NOPARAMS (void) #define PARAMS(parameter_list) parameter_list @@ -263,6 +311,25 @@ Macros for declarations #define NULL ((void *)0) #endif +#define NONNULL(s) (((s) != 0) ? s : "(null)") + +/* array/table size */ +#define TABLESIZE(v) (sizeof(v)/sizeof(v[0])) + +#define typecalloc(cast) (cast *)calloc(1,sizeof(cast)) +#define typecallocn(cast,ntypes) (cast *)calloc(ntypes,sizeof(cast)) + +/* + +OFTEN USED INTEGER MACROS + + Min and Max functions + + */ +#ifndef HTMIN +#define HTMIN(a,b) ((a) <= (b) ? (a) : (b)) +#define HTMAX(a,b) ((a) >= (b) ? (a) : (b)) +#endif /* Booleans @@ -303,12 +370,12 @@ extern BOOL LYOutOfMemory; /* Declared in LYexit.c - FM */ /* Inline Function WHITE: Is character c white space? */ /* For speed, include all control characters */ -#define WHITE(c) (((unsigned char)(TOASCII(c))) <= 32) +#define WHITE(c) ((UCH(TOASCII(c))) <= 32) /* Inline Function LYIsASCII: Is character c a traditional ASCII ** character (i.e. <128) after converting from host character set. */ -#define LYIsASCII(c) (TOASCII((unsigned char)(c)) < 128) +#define LYIsASCII(c) (TOASCII(UCH(c)) < 128) /* @@ -336,6 +403,8 @@ are generally not the response status from any specific protocol. #define HT_FORBIDDEN -403 /* Access forbidden */ #define HT_NOT_ACCEPTABLE -406 /* Not Acceptable */ +#define HT_PARSER_REOPEN_ELT 700 /* tells SGML parser to keep tag open */ +#define HT_PARSER_OTHER_CONTENT 701 /* tells SGML to change content model */ #define HT_H_ERRNO_VALID -800 /* see h_errno for resolver error */ #define HT_INTERNAL -900 /* Weird -- should never happen. */ @@ -397,11 +466,11 @@ Upper- and Lowercase macros #ifndef TOLOWER /* Pyramid and Mips can't uppercase non-alpha */ -#define TOLOWER(c) (isupper((unsigned char)c) ? tolower((unsigned char)c) : ((unsigned char)c)) -#define TOUPPER(c) (islower((unsigned char)c) ? toupper((unsigned char)c) : ((unsigned char)c)) +#define TOLOWER(c) (isupper(UCH(c)) ? tolower(UCH(c)) : UCH(c)) +#define TOUPPER(c) (islower(UCH(c)) ? toupper(UCH(c)) : UCH(c)) #endif /* TOLOWER */ -#define FREE(x) if (x) {free(x); x = NULL;} +#define FREE(x) if (x != 0) {free((char *)x); x = NULL;} /* @@ -415,14 +484,39 @@ The local equivalents of CR and LF #define LF FROMASCII('\012') /* ASCII line feed LOCAL EQUIVALENT */ #define CR FROMASCII('\015') /* Will be converted to ^M for transmission */ -#define CTRACE if(TRACE)fprintf +/* + * Debug message control. + */ +#ifdef NO_LYNX_TRACE +#define WWW_TraceFlag 0 +#define WWW_TraceMask 0 +#define LYTraceLogFP 0 +#else +extern BOOLEAN WWW_TraceFlag; +extern int WWW_TraceMask; +#endif + +#define TRACE (WWW_TraceFlag) +#define TRACE_bit(n) (TRACE && (WWW_TraceMask & (1 << n)) != 0) +#define TRACE_SGML (TRACE_bit(0)) +#define TRACE_STYLE (TRACE_bit(1)) +#define TRACE_TRST (TRACE_bit(2)) + +#if defined(LY_TRACELINE) +#define LY_SHOWWHERE fprintf( tfp, "%s: %d: ", __FILE__, LY_TRACELINE ), +#else +#define LY_SHOWWHERE /* nothing */ +#endif + +#define CTRACE(p) ((void)((TRACE) && ( LY_SHOWWHERE fprintf p ))) +#define CTRACE2(m,p) ((void)((m) && ( LY_SHOWWHERE fprintf p ))) #define tfp TraceFP() #define CTRACE_SLEEP(secs) if (TRACE && LYTraceLogFP == 0) sleep(secs) -#define CTRACE_FLUSH(fp) if(TRACE) fflush(fp) +#define CTRACE_FLUSH(fp) if (TRACE) fflush(fp) extern FILE *TraceFP NOPARAMS; -#include <tcp.h> +#include <www_tcp.h> /* * We force this include-ordering since socks.h contains redefinitions of @@ -447,10 +541,52 @@ extern FILE *TraceFP NOPARAMS; #define Rgetpeername getpeername #endif +/* + * Workaround for order-of-evaluation problem with gcc and socks5 headers + * which breaks the Rxxxx names by attaching the prefix twice: + */ +#ifdef INCLUDE_PROTOTYPES +#undef Raccept +#undef Rbind +#undef Rconnect +#undef Rlisten +#undef Rselect +#undef Rgetpeername +#undef Rgetsockname +#define Raccept accept +#define Rbind bind +#define Rconnect connect +#define Rgetpeername getpeername +#define Rgetsockname getsockname +#define Rlisten listen +#define Rselect select +#endif + #endif /* USE_SOCKS5 */ #define SHORTENED_RBIND /* FIXME: do this in configure-script */ +#ifdef USE_SSL +#define free_func free__func +#ifdef USE_OPENSSL_INCL +#include <openssl/ssl.h> +#include <openssl/crypto.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#else +#include <ssl.h> +#include <crypto.h> +#include <rand.h> +#include <err.h> +#endif +#undef free_func + +extern SSL * HTGetSSLHandle NOPARAMS; +extern void HTSSLInitPRNG NOPARAMS; +extern char HTGetSSLCharacter PARAMS((void * handle)); + +#endif /* USE_SSL */ + #include <userdefs.h> #endif /* HTUTILS_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.c index 775d411f2fb..5d3720350d6 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.c @@ -19,6 +19,7 @@ #include <UCDefs.h> #include <UCMap.h> #include <UCAux.h> +#include <HTFTP.h> #include <HTVMSUtils.h> #include <ssdef.h> #include <jpidef.h> @@ -32,8 +33,7 @@ #include <LYUtils.h> #include <LYLeaks.h> - -#define INFINITY 512 /* File name length @@ FIXME */ +#include <LYStrings.h> PUBLIC BOOL HTVMSFileVersions=FALSE; /* Include version numbers in listing? */ @@ -104,7 +104,7 @@ unsigned long Prv[2], PreviousPrv[2]; if (Result == SS$_NORMAL) { if (!(PreviousPrv[0] & PRV$M_SYSPRV)) { - CTRACE(tfp, "HTVMS_enableSysPrv: Enabled SYSPRV\n"); + CTRACE((tfp, "HTVMS_enableSysPrv: Enabled SYSPRV\n")); } } } @@ -130,7 +130,7 @@ unsigned long Prv[2], PreviousPrv[2]; if (Result == SS$_NORMAL) { if (PreviousPrv[0] & PRV$M_SYSPRV) { - CTRACE(tfp, "HTVMS_disableSysPrv: Disabled SYSPRV\n"); + CTRACE((tfp, "HTVMS_disableSysPrv: Disabled SYSPRV\n")); } } } @@ -207,9 +207,9 @@ char *colon; Result = sys$check_access(&ObjType,&FileNameDesc,&UserNameDesc,ItemList); if (Result == SS$_NORMAL) - return(YES); + return(YES); else - return(NO); + return(NO); } return(NO); @@ -223,30 +223,31 @@ char *colon; ** vmsname VMS file specification (NO NODE) ** ** ON EXIT: -** returns www file specification +** returns www file specification ** ** EXAMPLES: ** vmsname wwwname -** DISK$USER disk$user -** DISK$USER: /disk$user/ -** DISK$USER:[DUNS] /disk$user/duns -** DISK$USER:[DUNS.ECHO] /disk$user/duns/echo -** [DUNS] duns -** [DUNS.ECHO] duns/echo -** [DUNS.ECHO.-.TRANS] duns/echo/../trans -** [DUNS.ECHO.--.TRANS] duns/echo/../../trans -** [.DUNS] duns -** [.DUNS.ECHO] duns/echo -** [.DUNS.ECHO]TEST.COM duns/echo/test.com -** TEST.COM test.com +** DISK$USER disk$user +** DISK$USER: /disk$user/ +** DISK$USER:[DUNS] /disk$user/duns +** DISK$USER:[DUNS.ECHO] /disk$user/duns/echo +** [DUNS] duns +** [DUNS.ECHO] duns/echo +** [DUNS.ECHO.-.TRANS] duns/echo/../trans +** [DUNS.ECHO.--.TRANS] duns/echo/../../trans +** [.DUNS] duns +** [.DUNS.ECHO] duns/echo +** [.DUNS.ECHO]TEST.COM duns/echo/test.com +** TEST.COM test.com ** ** */ PUBLIC char * HTVMS_wwwName ARGS1( - char *, vmsname) + CONST char *, vmsname) { -static char wwwname[256]; -char *src, *dst; +static char wwwname[LY_MAXPATH]; +CONST char *src; +char *dst; int dir; dst = wwwname; src = vmsname; @@ -256,40 +257,40 @@ int dir; { switch(*src) { - case ':': *(dst++) = '/'; break; - case '-': if (dir) - { - if ((*(src-1)=='[' || *(src-1)=='.' || *(src-1)=='-') && - (*(src+1)=='.' || *(src+1)=='-')) + case ':': *(dst++) = '/'; break; + case '-': if (dir) + { + if ((*(src-1)=='[' || *(src-1)=='.' || *(src-1)=='-') && + (*(src+1)=='.' || *(src+1)=='-')) { - *(dst++) = '/'; - *(dst++) = '.'; - *(dst++) = '.'; + *(dst++) = '/'; + *(dst++) = '.'; + *(dst++) = '.'; } else - *(dst++) = '-'; + *(dst++) = '-'; } else { if (*(src-1) == ']') *(dst++) = '/'; *(dst++) = '-'; } - break; - case '.': if (dir) - { - if (*(src-1) != '[') *(dst++) = '/'; - } - else + break; + case '.': if (dir) + { + if (*(src-1) != '[') *(dst++) = '/'; + } + else { if (*(src-1) == ']') *(dst++) = '/'; - *(dst++) = '.'; + *(dst++) = '.'; } - break; - case '[': dir = 1; break; - case ']': dir = 0; break; - default: if (*(src-1) == ']') *(dst++) = '/'; - *(dst++) = *src; - break; + break; + case '[': dir = 1; break; + case ']': dir = 0; break; + default: if (*(src-1) == ']') *(dst++) = '/'; + *(dst++) = *src; + break; } } *(dst++) = '\0'; @@ -297,78 +298,6 @@ int dir; } -/* PUBLIC HTVMS_name() -** CONVERTS WWW name into a VMS name -** ON ENTRY: -** nn Node Name (optional) -** fn WWW file name -** -** ON EXIT: -** returns vms file specification -** -** Bug: Returns pointer to static -- non-reentrant -*/ -PUBLIC char * HTVMS_name ARGS2( - CONST char *, nn, - CONST char *, fn) -{ - -/* We try converting the filename into Files-11 syntax. That is, we assume -** first that the file is, like us, on a VMS node. We try remote -** (or local) DECnet access. Files-11, VMS, VAX and DECnet -** are trademarks of Digital Equipment Corporation. -** The node is assumed to be local if the hostname WITHOUT DOMAIN -** matches the local one. @@@ -*/ - static char vmsname[INFINITY]; /* returned */ - char * filename = (char*)malloc(strlen(fn)+1); - char * nodename = (char*)malloc(strlen(nn)+2+1); /* Copies to hack */ - char *second; /* 2nd slash */ - char *last; /* last slash */ - - char * hostname = (char *)HTHostName(); - - if (!filename || !nodename) outofmem(__FILE__, "HTVMSname"); - strcpy(filename, fn); - strcpy(nodename, ""); /* On same node? Yes if node names match */ - if (strncmp(nn,"localhost",9)) { - char *p, *q; - for (p=hostname, q=(char *)nn; - *p && *p!='.' && *q && *q!='.'; p++, q++){ - if (TOUPPER(*p)!=TOUPPER(*q)) { - strcpy(nodename, nn); - q = strchr(nodename, '.'); /* Mismatch */ - if (q) *q=0; /* Chop domain */ - strcat(nodename, "::"); /* Try decnet anyway */ - break; - } - } - } - - second = strchr(filename+1, '/'); /* 2nd slash */ - last = strrchr(filename, '/'); /* last slash */ - - if (!second) { /* Only one slash */ - sprintf(vmsname, "%s%s", nodename, filename + 1); - } else if(second==last) { /* Exactly two slashes */ - *second = 0; /* Split filename from disk */ - sprintf(vmsname, "%s%s:%s", nodename, filename+1, second+1); - *second = '/'; /* restore */ - } else { /* More than two slashes */ - char * p; - *second = 0; /* Split disk from directories */ - *last = 0; /* Split dir from filename */ - sprintf(vmsname, "%s%s:[%s]%s", - nodename, filename+1, second+1, last+1); - *second = *last = '/'; /* restore filename */ - for (p=strchr(vmsname, '['); *p!=']'; p++) - if (*p=='/') *p='.'; /* Convert dir sep. to dots */ - } - FREE(nodename); - FREE(filename); - return vmsname; -} - /* ** The code below is for directory browsing by VMS Curses clients. ** It is based on the newer WWWLib's HTDirBrw.c. - Foteos Macrides @@ -380,7 +309,7 @@ PUBLIC int HTStat ARGS2( /* the following stuff does not work in VMS with a normal stat... --> /disk$user/duns/www if www is a directory - is statted like: /disk$user/duns/www.dir + is statted like: /disk$user/duns/www.dir after a normal stat has failed --> /disk$user/duns if duns is a toplevel directory is statted like: /disk$user/000000/duns.dir @@ -394,7 +323,7 @@ PUBLIC int HTStat ARGS2( int Result; int Len; char *Ptr, *Ptr2; -char Name[256]; +static char *Name; /* try normal stat... */ Result = stat((char *)filename,info); @@ -402,32 +331,7 @@ char Name[256]; return(Result); /* make local copy */ - strcpy(Name,filename); - -#ifdef NOT_USED - /* if filename contains a node specification (! or ::), we will try to access - the file via DECNET, but we do not stat it..., just return success - with some fake information... */ - if (HTVMS_checkDecnet(Name)) - { - /* set up fake info, only the one we use... */ - info->st_dev = NULL; - info->st_ino[0] = 0; - info->st_ino[1] = 0; - info->st_ino[2] = 0; - info->st_mode = S_IFREG | S_IREAD; /* assume it is a regular Readable file */ - info->st_nlink = NULL; - info->st_uid = 0; - info->st_gid = 0; - info->st_rdev = 0; - info->st_size = 0; - info->st_atime = time(NULL); - info->st_mtime = time(NULL); - info->st_ctime = time(NULL); - - return(0); - } -#endif /* NOT_USED */ + StrAllocCopy(Name,filename); /* failed,so do device search in case root is requested */ if (!strcmp(Name,"/")) @@ -444,7 +348,7 @@ char Name[256]; Ptr = strchr(Name+1,'/'); if ((Ptr == NULL) && (Name[0] == '/')) { /* device only... */ - strcat(Name,"/000000/000000"); + StrAllocCat(Name, "/000000/000000"); } if (Ptr != NULL) @@ -452,21 +356,21 @@ char Name[256]; Ptr2 = strchr(Ptr+1,'/'); if ((Ptr2 == NULL) && (Name[0] == '/')) { - char End[256]; - strcpy(End,Ptr); - *(Ptr+1) = '\0'; - strcat(Name,"000000"); - strcat(Name,End); + char End[256]; + LYstrncpy(End, Ptr, sizeof(End) - 1); + *(Ptr+1) = '\0'; + StrAllocCat(Name, "000000"); + StrAllocCat(Name, End); } } - /* try in case a file on toplevel directory or .DIR was alreadyt specified */ + /* try in case a file on toplevel directory or .DIR was already specified */ Result = stat(Name,info); if (Result == 0) return(Result); /* add .DIR and try again */ - strcat(Name,".dir"); + StrAllocCat(Name, ".dir"); Result = stat(Name,info); return(Result); } @@ -479,15 +383,7 @@ char Name[256]; #endif /* !_POSIX_SOURCE */ typedef struct __dirdesc { -#if 0 - int dd_fd; /* file descriptor */ - long dd_loc; /* buf offset of entry from last readddir() */ - long dd_size; /* amount of valid data in buffer */ - long dd_bsize; /* amount of entries read at a time */ - long dd_off; /* Current offset in dir (for telldir) */ - char *dd_buf; /* directory data buffer */ -#endif - long context; /* context descriptor for LIB$FIND_FILE calls */ + long context; /* context descriptor for LIB$FIND_FILE calls */ char dirname[255+1]; /* keeps the directory name, including *.* */ struct dsc$descriptor_s dirname_desc; /* descriptor of dirname */ } DIR; @@ -495,28 +391,11 @@ typedef struct __dirdesc { PRIVATE DIR *HTVMSopendir(char *dirname); PRIVATE struct dirent *HTVMSreaddir(DIR *dirp); PRIVATE int HTVMSclosedir(DIR *dirp); -#if 0 -#ifndef _POSIX_SOURCE -extern void seekdir(/* DIR *dirp, int loc */); -extern long telldir(/* DIR *dirp */); -#endif /* POSIX_SOURCE */ -extern void rewinddir(/* DIR *dirp */); - -#ifndef lint -#define rewinddir(dirp) seekdir((dirp), (long)0) -#endif -#endif /* not defined for VMS */ /*** #include <sys_dirent.h> ***/ /*** "sys_dirent.h" ***/ struct dirent { -#if 0 - off_t d_off; /* offset of next disk dir entry */ -#endif unsigned long d_fileno; /* file number of entry */ -#if 0 - unsigned short d_reclen; /* length of this record */ -#endif unsigned short d_namlen; /* length of string in d_name */ char d_name[255+1]; /* name (up to MAXNAMLEN + 1) */ }; @@ -547,7 +426,8 @@ char *closebracket; long status; struct dsc$descriptor_s entryname_desc; struct dsc$descriptor_s dirname_desc; -char DirEntry[256]; +static char *DirEntry; +char Actual[256]; char VMSentry[256]; char UnixEntry[256]; int index; @@ -558,11 +438,13 @@ char *dot; /* or like /disk$user/duns/www/test/multi/ */ /* DirEntry should look like disk$user:[duns.www.test]multi in both cases */ /* dir.dirname should look like disk$user:[duns.www.test.multi] */ - strcpy(UnixEntry,dirname); + sprintf(UnixEntry, "%.*s", sizeof(UnixEntry) - 2, dirname); if (UnixEntry[strlen(UnixEntry)-1] != '/') strcat(UnixEntry,"/"); - strcpy(DirEntry, HTVMS_name("",UnixEntry)); + StrAllocCopy(DirEntry, HTVMS_name("",UnixEntry)); + if (strlen(DirEntry) > sizeof(dir.dirname) - 1) + return (NULL); strcpy(dir.dirname, DirEntry); index = strlen(DirEntry) - 1; @@ -574,31 +456,34 @@ char *dot; char *openbr = strrchr(DirEntry,'['); if (!openbr) { /* convert disk$user: into disk$user:[000000]000000.dir */ - strcpy(dir.dirname, DirEntry); - strcat(dir.dirname, "[000000]"); - strcat(DirEntry,"[000000]000000.dir"); + if (strlen(dir.dirname) > sizeof(dir.dirname) - 10) + return (NULL); + sprintf(dir.dirname, "%.*s[000000]", sizeof(dir.dirname) - 9, DirEntry); + StrAllocCat(DirEntry,"[000000]000000.dir"); } else { - char End[256]; - strcpy(End,openbr+1); - *(openbr+1) = '\0'; - strcat(DirEntry,"000000]"); - strcat(DirEntry,End); - strcat(DirEntry,".dir"); + char End[256]; + strcpy(End,openbr+1); + *(openbr+1) = '\0'; + StrAllocCat(DirEntry,"000000]"); + StrAllocCat(DirEntry,End); + StrAllocCat(DirEntry,".dir"); } } else { *dot = ']'; - strcat(DirEntry,".dir"); + StrAllocCat(DirEntry,".dir"); } + /* lib$find_file needs a fixed-size buffer */ + LYstrncpy(Actual, DirEntry, sizeof(Actual)-1); dir.context = 0; - dirname_desc.dsc$w_length = strlen(DirEntry); + dirname_desc.dsc$w_length = strlen(Actual); dirname_desc.dsc$b_dtype = DSC$K_DTYPE_T; dirname_desc.dsc$b_class = DSC$K_CLASS_S; - dirname_desc.dsc$a_pointer = (char *)&(DirEntry); + dirname_desc.dsc$a_pointer = (char *)&(Actual); /* look for the directory */ entryname_desc.dsc$w_length = 255; @@ -607,24 +492,16 @@ char *dot; entryname_desc.dsc$a_pointer = VMSentry; status = lib$find_file(&(dirname_desc), - &entryname_desc, - &(dir.context), - 0,0,0,0); + &entryname_desc, + &(dir.context), + 0,0,0,0); if (!(status & 0x01)) { /* directory not found */ return(NULL); } -#if 0 - /* now correct dirname, which looks like disk$user:[duns.www.test]multi */ - /* and should look like disk$user:[duns.www.test.multi] */ - closebracket = strchr(dir.dirname,']'); - *closebracket = '.'; - closebracket = strstr(dir.dirname,".dir"); - *closebracket = '\0'; - strcat(dir.dirname,"]"); -#endif - + if (strlen(dir.dirname) > sizeof(dir.dirname) - 10) + return (NULL); if (HTVMSFileVersions) strcat(dir.dirname,"*.*;*"); else @@ -652,9 +529,9 @@ char *UnixEntry; entryname_desc.dsc$a_pointer = VMSentry; status = lib$find_file(&(dirp->dirname_desc), - &entryname_desc, - &(dirp->context), - 0,0,0,0); + &entryname_desc, + &(dirp->context), + 0,0,0,0); if (status == RMS$_NMF) { /* no more files */ return(NULL); @@ -663,11 +540,11 @@ char *UnixEntry; { /* ok */ if (!(status & 0x01)) return(0); if (HTVMSFileVersions) - space = strchr(VMSentry,' '); + space = strchr(VMSentry,' '); else - space = strchr(VMSentry,';'); + space = strchr(VMSentry,';'); if (space) - *space = '\0'; + *space = '\0'; /* convert to unix style... */ UnixEntry = HTVMS_wwwName(VMSentry); @@ -733,12 +610,6 @@ PRIVATE void free_VMSEntryInfo_contents ARGS1(VMSEntryInfo *,entry_info) /* dont free the struct */ } -#define FILE_BY_NAME 0 -#define FILE_BY_TYPE 1 -#define FILE_BY_SIZE 2 -#define FILE_BY_DATE 3 -extern BOOLEAN HTfileSortMethod; /* specifies the method of sorting */ - PUBLIC int compare_VMSEntryInfo_structs ARGS2(VMSEntryInfo *,entry1, VMSEntryInfo *,entry2) { @@ -747,9 +618,9 @@ PUBLIC int compare_VMSEntryInfo_structs ARGS2(VMSEntryInfo *,entry1, switch(HTfileSortMethod) { - case FILE_BY_SIZE: + case FILE_BY_SIZE: /* both equal or both 0 */ - if(entry1->size == entry2->size) + if(entry1->size == entry2->size) return(strcasecomp(entry1->filename, entry2->filename)); else @@ -757,24 +628,22 @@ PUBLIC int compare_VMSEntryInfo_structs ARGS2(VMSEntryInfo *,entry1, return(1); else return(-1); - break; - case FILE_BY_TYPE: - if(entry1->type && entry2->type) { - status = strcasecomp(entry1->type, entry2->type); + case FILE_BY_TYPE: + if(entry1->type && entry2->type) { + status = strcasecomp(entry1->type, entry2->type); if(status) return(status); /* else fall to filename comparison */ } - return (strcasecomp(entry1->filename, + return (strcasecomp(entry1->filename, entry2->filename)); - break; - case FILE_BY_DATE: - if(entry1->date && entry2->date) { + case FILE_BY_DATE: + if(entry1->date && entry2->date) { /* ** Make sure we have the correct length. - FM */ if (strlen(entry1->date) != 12 || - strlen(entry2->date) != 12) { + strlen(entry2->date) != 12) { return (strcasecomp(entry1->filename, entry2->filename)); } @@ -783,71 +652,70 @@ PUBLIC int compare_VMSEntryInfo_structs ARGS2(VMSEntryInfo *,entry1, ** chronological order. - FM */ if (entry1->date[7] != ' ') { - strcpy(date1, "9999"); + strcpy(date1, "9999"); strcpy(time1, (char *)&entry1->date[7]); } else { strcpy(date1, (char *)&entry1->date[8]); - strcpy(time1, "00:00"); + strcpy(time1, "00:00"); } strncpy(month, entry1->date, 3); month[3] = '\0'; for (i = 0; i < 12; i++) { - if (!strcasecomp(month, months[i])) { + if (!strcasecomp(month, months[i])) { break; } } i++; - sprintf(month, "%s%d", (i < 10 ? "0" : ""), i); + sprintf(month, "%02d", i); strcat(date1, month); strncat(date1, (char *)&entry1->date[4], 2); date1[8] = '\0'; if (date1[6] == ' ') { - date1[6] = '0'; + date1[6] = '0'; } strcat(date1, time1); if (entry2->date[7] != ' ') { - strcpy(date2, "9999"); + strcpy(date2, "9999"); strcpy(time2, (char *)&entry2->date[7]); } else { strcpy(date2, (char *)&entry2->date[8]); - strcpy(time2, "00:00"); + strcpy(time2, "00:00"); } strncpy(month, entry2->date, 3); month[3] = '\0'; for (i = 0; i < 12; i++) { - if (!strcasecomp(month, months[i])) { + if (!strcasecomp(month, months[i])) { break; } } i++; - sprintf(month, "%s%d", (i < 10 ? "0" : ""), i); + sprintf(month, "%02d", i); strcat(date2, month); strncat(date2, (char *)&entry2->date[4], 2); date2[8] = '\0'; if (date2[6] == ' ') { - date2[6] = '0'; + date2[6] = '0'; } strcat(date2, time2); /* ** Do the comparison. - FM */ - status = strcasecomp(date2, date1); + status = strcasecomp(date2, date1); if(status) return(status); /* else fall to filename comparison */ } - return (strcasecomp(entry1->filename, + return (strcasecomp(entry1->filename, entry2->filename)); - break; - case FILE_BY_NAME: - default: - return (strcmp(entry1->filename, + case FILE_BY_NAME: + default: + return (strcmp(entry1->filename, entry2->filename)); } } -/* HTVMSBrowseDir() +/* HTVMSBrowseDir() ** ** This function generates a directory listing as an HTML-object ** for local file URL's. It assumes the first two elements of @@ -889,7 +757,7 @@ PUBLIC int HTVMSBrowseDir ARGS4( extern BOOLEAN no_dotfiles, show_dotfiles; HTUnEscape(pathname); - CTRACE(tfp,"HTVMSBrowseDir: Browsing `%s\'\n", pathname); + CTRACE((tfp,"HTVMSBrowseDir: Browsing `%s\'\n", pathname)); /* * Require at least two elements (presumably a device and directory) @@ -898,12 +766,12 @@ PUBLIC int HTVMSBrowseDir ARGS4( * to /sys$sysroot/syshlp) before calling this routine. */ if (((*pathname != '/') || - (cp=strchr(pathname+1, '/')) == NULL || + (cp=strchr(pathname+1, '/')) == NULL || *(cp+1) == '\0' || 0==strncmp((cp+1), "000000", 6)) || - (dp=HTVMSopendir(pathname)) == NULL) { - FREE(pathname); - return HTLoadError(sink, 403, COULD_NOT_ACCESS_DIR); + (dp=HTVMSopendir(pathname)) == NULL) { + FREE(pathname); + return HTLoadError(sink, 403, COULD_NOT_ACCESS_DIR); } /* @@ -926,7 +794,7 @@ PUBLIC int HTVMSBrowseDir ARGS4( cp = strrchr(pathname, '/'); /* find lastslash */ StrAllocCopy(tail, (cp+1)); /* take slash off the beginning */ if (*tail != '\0') { - StrAllocCopy(title, tail); + StrAllocCopy(title, tail); *cp = '\0'; if ((cp1=strrchr(pathname, '/')) != NULL && cp1 != pathname && @@ -934,7 +802,7 @@ PUBLIC int HTVMSBrowseDir ARGS4( StrAllocCopy(parent, (cp1+1)); *cp = '/'; } else { - pathname[strlen(pathname)-1] = '\0'; + pathname[strlen(pathname)-1] = '\0'; cp = strrchr(pathname, '/'); StrAllocCopy(title, (cp+1)); pathname[strlen(pathname)] = '/'; @@ -974,19 +842,19 @@ PUBLIC int HTVMSBrowseDir ARGS4( END(HTML_H1); PUTC('\n'); if (HTDirReadme == HT_DIR_README_TOP) { - FILE * fp; + FILE * fp; if (header[strlen(header)-1] != '/') StrAllocCat(header, "/"); StrAllocCat(header, HT_DIR_README_FILE); - if ((fp = fopen(header, "r")) != NULL) { + if ((fp = fopen(header, "r")) != NULL) { START(HTML_PRE); for(;;) { - char c = fgetc(fp); - if (c == (char)EOF) + char c = fgetc(fp); + if (c == (char)EOF) break; #ifdef NOTDEFINED - switch (c) { - case '&': + switch (c) { + case '&': case '<': case '>': PUTC('&'); @@ -997,21 +865,18 @@ PUBLIC int HTVMSBrowseDir ARGS4( break; default: PUTC(c); - } + } #else PUTC(c); #endif /* NOTDEFINED */ } END(HTML_PRE); fclose(fp); - } + } } FREE(header); if (parent) { - relative = (char*) malloc(strlen(tail) + 4); - if (relative == NULL) - outofmem(__FILE__, "HTVMSBrowseDir"); - sprintf(relative, "%s/..", tail); + HTSprintf0(&relative, "%s/..", tail); HTStartAnchor(target, "", relative); PUTS("Up to "); HTUnEscape(parent); @@ -1075,9 +940,9 @@ PUBLIC int HTVMSBrowseDir ARGS4( if (HTStat(pathname, &file_info)) { /* for VMS the failure here means the file is not readable... we however continue to browse through the directory... */ - continue; + continue; } - entry_info = (VMSEntryInfo *)malloc(sizeof(VMSEntryInfo)); + entry_info = (VMSEntryInfo *)malloc(sizeof(VMSEntryInfo)); if (entry_info == NULL) outofmem(__FILE__, "HTVMSBrowseDir"); entry_info->type = 0; @@ -1103,45 +968,45 @@ PUBLIC int HTVMSBrowseDir ARGS4( StrAllocCopy(entry_info->filename, dirbuf->d_name); if (S_ISDIR(file_info.st_mode)) { - /* strip .DIR part... */ - char *dot; - dot = strstr(entry_info->filename, ".DIR"); - if (dot) - *dot = '\0'; + /* strip .DIR part... */ + char *dot; + dot = strstr(entry_info->filename, ".DIR"); + if (dot) + *dot = '\0'; LYLowerCase(entry_info->filename); StrAllocCopy(entry_info->type, "Directory"); } else { - if ((cp = strstr(entry_info->filename, "READ")) == NULL) { - cp = entry_info->filename; + if ((cp = strstr(entry_info->filename, "READ")) == NULL) { + cp = entry_info->filename; } else { cp += 4; if (!strncmp(cp, "ME", 2)) { - cp += 2; + cp += 2; while (cp && *cp && *cp != '.') { cp++; } } else if (!strncmp(cp, ".ME", 3)) { - cp = (entry_info->filename + + cp = (entry_info->filename + strlen(entry_info->filename)); } else { - cp = entry_info->filename; + cp = entry_info->filename; } } LYLowerCase(cp); if (((len = strlen(entry_info->filename)) > 2) && entry_info->filename[len-1] == 'z') { if (entry_info->filename[len-2] == '.' || - entry_info->filename[len-2] == '_') + entry_info->filename[len-2] == '_') entry_info->filename[len-1] = 'Z'; } } /* Get the date */ { - char *t = (char *)ctime((CONST time_t *)&file_info.st_ctime); + char *t = (char *)ctime((CONST time_t *)&file_info.st_ctime); *(t+24) = '\0'; - StrAllocCopy(entry_info->date, (t+4)); + StrAllocCopy(entry_info->date, (t+4)); *((entry_info->date)+7) = '\0'; if ((atoi((t+19))) < atoi(ThisYear)) StrAllocCat(entry_info->date, (t+19)); @@ -1153,16 +1018,16 @@ PUBLIC int HTVMSBrowseDir ARGS4( /* Get the size */ if (!S_ISDIR(file_info.st_mode)) - entry_info->size = (unsigned int)file_info.st_size; + entry_info->size = (unsigned int)file_info.st_size; else - entry_info->size = 0; + entry_info->size = 0; /* Now, update the BTree etc. */ if(entry_info->display) { - CTRACE(tfp,"Adding file to BTree: %s\n", - entry_info->filename); - HTBTree_add(bt, (VMSEntryInfo *)entry_info); + CTRACE((tfp,"Adding file to BTree: %s\n", + entry_info->filename)); + HTBTree_add(bt, (VMSEntryInfo *)entry_info); } } /* End while HTVMSreaddir() */ @@ -1186,8 +1051,8 @@ PUBLIC int HTVMSBrowseDir ARGS4( /* Output the date */ if(entry_info->date) { - PUTS(entry_info->date); - PUTS(" "); + PUTS(entry_info->date); + PUTS(" "); } else PUTS(" * "); @@ -1196,9 +1061,9 @@ PUBLIC int HTVMSBrowseDir ARGS4( if(entry_info->type) { for(i = 0; entry_info->type[i] != '\0' && i < 15; i++) - PUTC(entry_info->type[i]); + PUTC(entry_info->type[i]); for(; i < 17; i++) - PUTC(' '); + PUTC(' '); } @@ -1207,10 +1072,10 @@ PUBLIC int HTVMSBrowseDir ARGS4( PUTS(entry_info->filename); END(HTML_A); - /* Output the size */ + /* Output the size */ if(entry_info->size) { - if(entry_info->size < 1024) + if(entry_info->size < 1024) sprintf(string_buffer," %d bytes", entry_info->size); else diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.h index c5bcb666662..2720125eba3 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMSUtils.h @@ -87,26 +87,7 @@ PUBLIC BOOL HTVMS_checkAccess PARAMS(( ** */ PUBLIC char * HTVMS_wwwName PARAMS(( - char * vmsname)); - -/* PUBLIC HTVMS_name() -** CONVERTS WWW name into a VMS name -** ON ENTRY: -** nn Node Name (optional) -** fn WWW file name -** -** ON EXIT: -** returns vms file specification -** -** Bug: Returns pointer to static -- non-reentrant -*/ -PUBLIC char * HTVMS_name PARAMS(( - CONST char * nn, - CONST char * fn)); - -PUBLIC int HTStat PARAMS(( - CONST char * filename, - struct stat * info)); + CONST char * vmsname)); PUBLIC int HTVMSBrowseDir PARAMS(( CONST char * address, diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisProt.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisProt.c index 760814072e6..9fddc10b74f 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisProt.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisProt.c @@ -865,6 +865,7 @@ char* buffer; size -= (buf - originalBuf); } } + /* FALLTHRU */ case DT_Source: buf = readString(&source,buf); break; @@ -1204,6 +1205,7 @@ char* buffer; size -= (buf - originalBuf); } } + /* FALLTHRU */ case DT_Source: buf = readString(&source,buf); break; @@ -2193,7 +2195,7 @@ query_term** terms; docTerm = terms[termNum]; if (docTerm == NULL) - break; /* we're done converting */; + break; /* we're done converting */ typeTerm = terms[termNum + 1]; /* get the lead Term if it exists */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.c index 1f9ffcccd18..6f0811c0430 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.c @@ -40,7 +40,7 @@ #include <HTVMS_WaisProt.h> #include <HTTCP.h> -#undef MAXINT /* we don't need it here, and tcp.h may conflict */ +#undef MAXINT /* we don't need it here, and www_tcp.h may conflict */ #include <math.h> #include <LYexit.h> @@ -220,7 +220,7 @@ transport_message( if( request_length + HEADER_LENGTH != NETWRITE(connection,request_message, - (int)( request_length +HEADER_LENGTH)) ) + (int)( request_length +HEADER_LENGTH)) ) return 0; /* read for the first '0' */ @@ -650,22 +650,22 @@ void* queryInfo) query->ReplaceIndicator = replace; query->ResultSetName = s_strdup(name); query->DatabaseNames = NULL; - if (databases != NULL) - { for (i = 0, ptr = databases[i]; ptr != NULL; ptr = databases[++i]) - { if (query->DatabaseNames == NULL) + if (databases != NULL) { + for (i = 0, ptr = databases[i]; ptr != NULL; ptr = databases[++i]) { + if (query->DatabaseNames == NULL) query->DatabaseNames = (char**)s_malloc((size_t)(sizeof(char*) * 2)); else query->DatabaseNames = (char**)s_realloc((char*)query->DatabaseNames, (size_t)(sizeof(char*) * (i + 2))); query->DatabaseNames[i] = s_strdup(ptr); query->DatabaseNames[i+1] = NULL; - } - } + } + } query->QueryType = s_strdup(type); query->ElementSetNames = NULL; - if (elements != NULL) - { for (i = 0, ptr = elements[i]; ptr != NULL; ptr = elements[++i]) - { if (query->ElementSetNames == NULL) + if (elements != NULL) { + for (i = 0, ptr = elements[i]; ptr != NULL; ptr = elements[++i]) { + if (query->ElementSetNames == NULL) query->ElementSetNames = (char**)s_malloc((size_t)(sizeof(char*) * 2)); else query->ElementSetNames = (char**)s_realloc((char*)query->ElementSetNames, @@ -717,9 +717,9 @@ writeSearchAPDU(SearchAPDU* query, char* buffer, long* len) buf = writeBoolean(query->ReplaceIndicator,buf,len); buf = writeString(query->ResultSetName,DT_ResultSetName,buf,len); /* write database names */ - if (query->DatabaseNames != NULL) - { for (i = 0,scratch = NULL, ptr = query->DatabaseNames[i]; ptr != NULL; ptr = query->DatabaseNames[++i]) - { if (scratch == NULL) + if (query->DatabaseNames != NULL) { + for (i = 0,scratch = NULL, ptr = query->DatabaseNames[i]; ptr != NULL; ptr = query->DatabaseNames[++i]) { + if (scratch == NULL) scratch = s_strdup(ptr); else { size_t newScratchSize = (size_t)(strlen(scratch) + strlen(ptr) + 2); @@ -727,16 +727,16 @@ writeSearchAPDU(SearchAPDU* query, char* buffer, long* len) s_strncat(scratch,DB_DELIMITER,2,newScratchSize); s_strncat(scratch,ptr,strlen(ptr) + 1,newScratchSize); } - } + } buf = writeString(scratch,DT_DatabaseNames,buf,len); s_free(scratch); } buf = writeString(query->QueryType,DT_QueryType,buf,len); /* write element set names */ - if (query->ElementSetNames != NULL) - { for (i = 0,scratch = NULL, ptr = query->ElementSetNames[i]; ptr != NULL; ptr = query->ElementSetNames[++i]) - { if (scratch == NULL) - { if (query->ElementSetNames[i+1] == NULL) /* there is a single element set name */ + if (query->ElementSetNames != NULL) { + for (i = 0,scratch = NULL, ptr = query->ElementSetNames[i]; ptr != NULL; ptr = query->ElementSetNames[++i]) { + if (scratch == NULL) { + if (query->ElementSetNames[i+1] == NULL) /* there is a single element set name */ { scratch = (char*)s_malloc((size_t)strlen(ptr) + 2); strncpy(scratch,ES_DELIMITER_1,2); s_strncat(scratch,ptr,strlen(ptr) + 1,strlen(ptr) + 2); @@ -749,7 +749,7 @@ writeSearchAPDU(SearchAPDU* query, char* buffer, long* len) s_strncat(scratch,ES_DELIMITER_1,2,newScratchSize); s_strncat(scratch,ptr,strlen(ptr) + 1,newScratchSize); } - } + } else { char* esPtr = query->ElementSetNames[++i]; /* the element set name */ size_t newScratchSize = (size_t)(strlen(scratch) + strlen(ptr) + strlen(esPtr) + 3); @@ -953,11 +953,11 @@ makeDiag(boolean surrogate, char* code, char* addInfo) void freeDiag(diagnosticRecord* diag) { - if (diag != NULL) - { if (diag->ADDINFO != NULL) + if (diag != NULL) { + if (diag->ADDINFO != NULL) s_free(diag->ADDINFO); - s_free(diag); - } + s_free(diag); + } } /*----------------------------------------------------------------------*/ @@ -2032,10 +2032,10 @@ readQuery(any *info) query_term** terms = NULL; query_term* qt = NULL; long numTerms = 0L; -char tmp[100]; + char tmp[100]; -sprintf(tmp,"readquery: bytes: %ld",info->size); -log_write(tmp); + sprintf(tmp,"readquery: bytes: %ld",info->size); + log_write(tmp); while (readPos < info->bytes + info->size) { readPos = readQueryTerm(&qt,readPos); @@ -2048,7 +2048,7 @@ log_write(tmp); (query_term**)s_realloc((char*)terms, (size_t)(sizeof(query_term*)*(numTerms+2))); } -if(qt==NULL) + if (qt == NULL) log_write("qt = null"); terms[numTerms++] = qt; terms[numTerms] = NULL; diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.h index 150e108df86..474b943d7bc 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTVMS_WaisUI.h @@ -183,10 +183,6 @@ typedef unsigned long data_tag; #define ACCEPT TRUE #define REJECT FALSE -/* values for SearchAPDU replace indicator element */ -#define ON TRUE -#define OFF FALSE - /* values for SearchResponseAPDU search status element */ #define SUCCESS 0 /* intuitive huh? */ #define FAILURE 1 diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWAIS.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWAIS.c index 6eea24ee3c4..86e8701d1df 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWAIS.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWAIS.c @@ -75,6 +75,7 @@ /* FROM WWW ** -------- */ +#include <LYUtils.h> #include <LYLeaks.h> #define DIRECTORY "/cnidr.org:210/directory-of-servers" @@ -86,11 +87,6 @@ #define HEX_ESCAPE '%' -extern HTCJKlang HTCJK; - -extern int WWW_TraceFlag; /* Control diagnostic output */ -extern FILE * logfile; /* Log file output */ - PRIVATE BOOL as_gate; /* Client is using us as gateway */ PRIVATE char line[2048]; /* For building strings to display */ @@ -119,36 +115,37 @@ struct _HTStream { /* ------------------------------------------------------------------------ */ /* Returns 1 on success, 0 on fail, -1 on interrupt. */ PRIVATE int fd_mosaic_connect_to_server ARGS3( - char *, host_name, + char *, host_name, long, port, - long *, fd) + long *, fd) { - /* - ** New version. - */ - char dummy[256]; + char *dummy = NULL; int status; + int result; - sprintf (dummy, "wais://%s:%d/", host_name, port); + HTSprintf0(&dummy, "wais://%s:%d/", host_name, port); status = HTDoConnect (dummy, "WAIS", 210, (int *)fd); if (status == HT_INTERRUPTED) { - return -1; + result = -1; + } else if (status < 0) { + result = 0; + } else { + result = 1; } - if (status < 0) - return 0; - return 1; + FREE(dummy); + return result; } /* Returns 1 on success, 0 on fail, -1 on interrupt. */ #ifdef VMS PRIVATE int mosaic_connect_to_server ARGS3( - char *, host_name, + char *, host_name, long, port, - long *, fdp) + long *, fdp) #else PRIVATE int mosaic_connect_to_server ARGS3( - char *, host_name, + char *, host_name, long, port, FILE **, fp) #endif /* VMS */ @@ -225,18 +222,18 @@ PRIVATE void init_acceptable NOARGS ** ** ** On exit, -** returns nil if error +** returns nil if error ** pointer to malloced string (must be freed) if ok */ PRIVATE char * WWW_from_archie ARGS1( - char *, file) + char *, file) { char * end; char * result; char * colon; for(end=file; *end > ' '; end++); /* assumes ASCII encoding*/ result = (char *)malloc(10 + (end-file)); - if (!result) return result; /* Malloc error */ + if (!result) return result; /* Malloc error */ strcpy(result, "file://"); strncat(result, file, end-file); colon = strchr(result+7, ':'); /* Expect colon after host */ @@ -253,7 +250,7 @@ PRIVATE char * WWW_from_archie ARGS1( ** The format of the docid MUST be good! ** ** On exit, -** returns nil if error +** returns nil if error ** pointer to malloced string (must be freed) if ok */ PRIVATE char hex [17] = "0123456789ABCDEF"; @@ -264,7 +261,9 @@ PRIVATE char * WWW_from_WAIS ARGS1( static char buf[BIG]; char * q = buf; char * p = (docid->bytes); + char * result = NULL; int i, l; + if (TRACE) { char *p; fprintf(tfp, "WAIS id (%d bytes) is ", (int)docid->size); @@ -278,9 +277,9 @@ PRIVATE char * WWW_from_WAIS ARGS1( } for (p = docid->bytes; (p < docid->bytes+docid->size) && (q < &buf[BIG]);) { - CTRACE(tfp, " Record type %d, length %d\n", p[0], p[1]); + CTRACE((tfp, " Record type %d, length %d\n", p[0], p[1])); if (*p > 10) { - CTRACE(tfp, "Eh? DOCID record type of %d!\n", *p); + CTRACE((tfp, "Eh? DOCID record type of %d!\n", *p)); return 0; } { /* Bug fix -- allow any byte value 15 Apr 93 */ @@ -300,7 +299,7 @@ PRIVATE char * WWW_from_WAIS ARGS1( l = *p++; /* Length */ for (i = 0; i < l; i++, p++){ if (!acceptable[*p]) { - *q++ = HEX_ESCAPE; /* Means hex commming */ + *q++ = HEX_ESCAPE; /* Means hex coming */ *q++ = hex[(*p) >> 4]; *q++ = hex[(*p) & 15]; } @@ -309,21 +308,16 @@ PRIVATE char * WWW_from_WAIS ARGS1( *q++= ';'; /* Terminate field */ } *q++ = 0; /* Terminate string */ - CTRACE(tfp, "WWW form of id: %s\n", buf); - { - char * result = (char *)malloc(strlen(buf)+1); - if (!result) - outofmem(__FILE__, "WWW_from_WAIS"); - strcpy(result, buf); - return result; - } + CTRACE((tfp, "WWW form of id: %s\n", buf)); + StrAllocCopy(result, buf); + return result; } /* WWW_from_WAIS */ /* Transform URL into WAIS document identifier ** ------------------------------------------- ** ** On entry, -** docname points to valid name produced originally by +** docname points to valid name produced originally by ** WWW_from_WAIS ** On exit, ** docid->size is valid @@ -331,7 +325,7 @@ PRIVATE char * WWW_from_WAIS ARGS1( */ PRIVATE any * WAIS_from_WWW ARGS2( any *, docid, - char *, docname) + char *, docname) { char *z; /* Output pointer */ char *sor; /* Start of record - points to size field. */ @@ -340,7 +334,7 @@ PRIVATE any * WAIS_from_WWW ARGS2( char *s; /* Position of semicolon */ int n; /* size */ - CTRACE(tfp, "WWW id (to become WAIS id): %s\n", docname); + CTRACE((tfp, "WWW id (to become WAIS id): %s\n", docname)); for (n = 0, p = docname; *p; p++) { /* Count sizes of strings */ n++; if (*p == ';') @@ -357,7 +351,7 @@ PRIVATE any * WAIS_from_WWW ARGS2( for (p = docname; *p; ) { /* Convert of strings */ /* Record type */ - *z = 0; /* Initialize record type */ + *z = 0; /* Initialize record type */ while (*p >= '0' && *p <= '9') { *z = *z*10 + (*p++ - '0'); /* Decode decimal record type */ } @@ -413,8 +407,8 @@ PRIVATE any * WAIS_from_WWW ARGS2( ** -------------------------------------- */ PRIVATE void output_text_record ARGS4( - HTStream *, target, - WAISDocumentText *, record, + HTStream *, target, + WAISDocumentText *, record, boolean, quote_string_quotes, boolean, binary) { @@ -438,7 +432,7 @@ PRIVATE void output_text_record ARGS4( /* if the next letter is '(' or ')', then ignore two letters */ if ('(' == record->DocumentText->bytes[count + 1] || ')' == record->DocumentText->bytes[count + 1]) - count += 1; /* it is a term marker */ + count += 1; /* it is a term marker */ else count += 4; /* it is a paragraph marker */ } else if (ch == '\n' || ch == '\r') { PUTC('\n'); @@ -448,7 +442,7 @@ PRIVATE void output_text_record ARGS4( } } /* output text record */ -/* Format A Search response for the client display_search_response +/* Format A Search response for the client display_search_response ** --------------------------------------- */ /* modified from tracy shen's version in wutil.c @@ -463,9 +457,9 @@ PRIVATE void display_search_response ARGS4( WAISSearchResponse *info; long i, k; - BOOL archie = strstr(database, "archie")!=0; /* Specical handling */ + BOOL archie = strstr(database, "archie")!=0; /* Special handling */ - CTRACE(tfp, "HTWAIS: Displaying search response\n"); + CTRACE((tfp, "HTWAIS: Displaying search response\n")); PUTS(gettext("Index ")); START(HTML_EM); PUTS(database); @@ -497,17 +491,17 @@ PRIVATE void display_search_response ARGS4( WAISDocumentHeader* head = info->DocHeaders[k]; char * headline = trim_junk(head->Headline); any * docid = head->DocumentID; - char * docname; /* printable version of docid */ + char * docname; /* printable version of docid */ i++; /* ** Make a printable string out of the document id. */ - CTRACE(tfp, "HTWAIS: %2ld: Score: %4ld, lines:%4ld '%s'\n", + CTRACE((tfp, "HTWAIS: %2ld: Score: %4ld, lines:%4ld '%s'\n", i, (long int)(info->DocHeaders[k]->Score), (long int)(info->DocHeaders[k]->Lines), - headline); + headline)); START(HTML_LI); @@ -525,21 +519,24 @@ PRIVATE void display_search_response ARGS4( } else { /* Not archie */ docname = WWW_from_WAIS(docid); if (docname) { - char * dbname = HTEscape(database, URL_XPALPHAS); - sprintf(line, - "/%s/%s/%d/%s", /* W3 address */ - dbname, - head->Types ? head->Types[0] : "TEXT", - (int)(head->DocumentLength), - docname); - HTStartAnchor(target, NULL, - ((head->Types) && - (!strcmp(head->Types[0], "URL"))) - ? - headline : line); /* NT, Sep 93 */ + if ((head->Types) && + (!strcmp(head->Types[0], "URL"))) { + HTStartAnchor(target, NULL, headline); + } else{ + char * dbname = HTEscape(database, URL_XPALPHAS); + char * w3_address = NULL; + HTSprintf0(&w3_address, + "/%s/%s/%d/%s", + dbname, + head->Types ? head->Types[0] : "TEXT", + (int)(head->DocumentLength), + docname); + HTStartAnchor(target, NULL, w3_address); + FREE(w3_address); + FREE(dbname); + } PUTS(headline); END(HTML_A); - FREE(dbname); FREE(docname); } else { PUTS(gettext("(bad doc id)")); @@ -616,17 +613,15 @@ PUBLIC int HTLoadWAIS ARGS4( #define MAXDOCS 200 { - static CONST char * error_header = -"<h1>Access error</h1>\nThe following error occured in accesing a WAIS server:<P>\n"; - char * key; /* pointer to keywords in URL */ + char * key; /* pointer to keywords in URL */ char* request_message = NULL; /* arbitrary message limit */ char* response_message = NULL; /* arbitrary message limit */ long request_buffer_length; /* how of the request is left */ SearchResponseAPDU *retrieval_response = 0; char keywords[MAX_KEYWORDS_LENGTH + 1]; char *server_name; - char *wais_database = NULL; /* name of current database */ - char *www_database; /* Same name escaped */ + char *wais_database = NULL; /* name of current database */ + char *www_database; /* Same name escaped */ char *service; char *doctype; char *doclength; @@ -650,7 +645,7 @@ PUBLIC int HTLoadWAIS ARGS4( /* Decipher and check syntax of WWW address: ** ---------------------------------------- ** - ** First we remove the "wais:" if it was spcified. 920110 + ** First we remove the "wais:" if it was specified. 920110 */ names = HTParse(arg, "", PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION); key = strchr(names, '?'); @@ -663,7 +658,7 @@ PUBLIC int HTLoadWAIS ARGS4( } if (names[0] == '/') { server_name = names+1; - if (as_gate =(*server_name == '/')) + if ((as_gate =(*server_name == '/')) != 0) server_name++; /* Accept one or two */ www_database = strchr(server_name,'/'); if (www_database) { @@ -695,7 +690,7 @@ PUBLIC int HTLoadWAIS ARGS4( if (!ok) return HTLoadError(sink, 500, gettext("Syntax error in WAIS URL")); - CTRACE(tfp, "HTWAIS: Parsed OK\n"); + CTRACE((tfp, "HTWAIS: Parsed OK\n")); service = strchr(names, ':'); if (service) @@ -712,16 +707,16 @@ PUBLIC int HTLoadWAIS ARGS4( } else if (!(key && !*key)) { int status; - CTRACE (tfp, "===WAIS=== calling mosaic_connect_to_server\n"); + CTRACE((tfp, "===WAIS=== calling mosaic_connect_to_server\n")); status = mosaic_connect_to_server(server_name, atoi(service), &connection); if (status == 0) { - CTRACE (tfp, "===WAIS=== connection failed\n"); + CTRACE((tfp, "===WAIS=== connection failed\n")); FREE(names); return HT_NOT_LOADED; } else if (status == -1) { - CTRACE (tfp, "===WAIS=== connection interrupted\n"); + CTRACE((tfp, "===WAIS=== connection interrupted\n")); FREE(names); return HT_NOT_LOADED; } @@ -734,11 +729,9 @@ PUBLIC int HTLoadWAIS ARGS4( ** This below fixed size stuff is terrible. */ #ifdef VMS - if (!(request_message = - (char*)calloc((size_t)MAX_MESSAGE_LEN*sizeof(char),1))) + if ((request_message = typecallocn(char, MAX_MESSAGE_LEN)) == 0) outofmem(__FILE__, "HTLoadWAIS"); - if (!(response_message = - (char*)calloc((size_t)MAX_MESSAGE_LEN*sizeof(char),1))) + if ((response_message = typecallocn(char, MAX_MESSAGE_LEN)) == 0) outofmem(__FILE__, "HTLoadWAIS"); #else request_message = (char*)s_malloc((size_t)MAX_MESSAGE_LEN * sizeof(char)); @@ -750,9 +743,9 @@ PUBLIC int HTLoadWAIS ARGS4( ** the user has followed a link to the index itself. It would be ** appropriate at this point to send him the .SRC file - how? */ - if (key && !*key) { /* I N D E X */ + if (key && !*key) { /* I N D E X */ #ifdef CACHE_FILE_PREFIX - char filename[256]; + char * filename = NULL; FILE * fp; #endif HTStructured * target = HTML_new(anAnchor, format_out, sink); @@ -789,14 +782,14 @@ PUBLIC int HTLoadWAIS ARGS4( ** If we have seen a source file for this database, use that. */ #ifdef CACHE_FILE_PREFIX - sprintf(filename, "%sWSRC-%s:%s:%.100s.txt", + HTSprintf0(&filename, "%sWSRC-%s:%s:%.100s.txt", CACHE_FILE_PREFIX, server_name, service, www_database); fp = fopen(filename, "r"); /* Have we found this already? */ - CTRACE(tfp, "HTWAIS: Description of server %s %s.\n", + CTRACE((tfp, "HTWAIS: Description of server %s %s.\n", filename, - fp ? "exists already" : "does NOT exist!"); + fp ? "exists already" : "does NOT exist!")); if (fp) { char c; @@ -806,6 +799,7 @@ PUBLIC int HTLoadWAIS ARGS4( END(HTML_PRE); fclose(fp); } + FREE(filename); #endif START(HTML_P); PUTS(gettext("\nEnter the 's'earch command and then specify search words.\n")); @@ -816,7 +810,8 @@ PUBLIC int HTLoadWAIS ARGS4( HTStructured * target; strncpy(keywords, key, MAX_KEYWORDS_LENGTH); - while(p=strchr(keywords, '+')) *p = ' '; + while ((p = strchr(keywords, '+')) != 0) + *p = ' '; /* ** Send advance title to get something fast to the other end. @@ -850,8 +845,8 @@ PUBLIC int HTLoadWAIS ARGS4( PUTC('\n'); request_buffer_length = MAX_MESSAGE_LEN; /* Amount left */ - CTRACE(tfp, "HTWAIS: Search for `%s' in `%s'\n", - keywords, wais_database); + CTRACE((tfp, "HTWAIS: Search for `%s' in `%s'\n", + keywords, wais_database)); if(NULL == generate_search_apdu(request_message + HEADER_LENGTH, &request_buffer_length, @@ -909,8 +904,8 @@ PUBLIC int HTLoadWAIS ARGS4( any doc_chunk; any * docid = &doc_chunk; - CTRACE(tfp, "HTWAIS: Retrieve document id `%s' type `%s' length %ld\n", - docname, doctype, document_length); + CTRACE((tfp, "HTWAIS: Retrieve document id `%s' type `%s' length %ld\n", + docname, doctype, document_length)); format_in = !strcmp(doctype, "WSRC") ? HTAtom_for("application/x-wais-source") : @@ -946,7 +941,7 @@ PUBLIC int HTLoadWAIS ARGS4( char *type = s_strdup(doctype); /* Gets freed I guess */ #endif /* VMS */ request_buffer_length = MAX_MESSAGE_LEN; /* Amount left */ - CTRACE(tfp, "HTWAIS: Slice number %ld\n", count); + CTRACE((tfp, "HTWAIS: Slice number %ld\n", count)); if (HTCheckForInterrupt()) { HTAlert (TRANSFER_INTERRUPTED); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWSRC.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWSRC.c index 3388b100cf2..9d69669b7d5 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWSRC.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTWSRC.c @@ -22,8 +22,6 @@ #define PARAM_MAX BIG #define CACHE_PERIOD (7*86400) /* Time to keep .src file in seconds */ -#define HEX_ESCAPE '%' - struct _HTStructured { CONST HTStructuredClass * isa; /* ... */ @@ -110,10 +108,10 @@ PUBLIC CONST char * hex = "0123456789ABCDEF"; PUBLIC char from_hex ARGS1(char, c) { - return (c>='0')&&(c<='9') ? c-'0' + return (char) ( (c>='0')&&(c<='9') ? c-'0' : (c>='A')&&(c<='F') ? c-'A'+10 : (c>='a')&&(c<='f') ? c-'a'+10 - : 0; + : 0); } @@ -159,8 +157,8 @@ PRIVATE void WSRCParser_put_character ARGS2(HTStream*, me, char, c) } } if (!par_name[me->param_number]) { /* Unknown field */ - CTRACE(tfp, "HTWSRC: Unknown field `%s' in source file\n", - me->param); + CTRACE((tfp, "HTWSRC: Unknown field `%s' in source file\n", + me->param)); me->param_number = PAR_UNKNOWN; me->state = before_value; /* Could be better ignore */ return; @@ -244,28 +242,32 @@ PRIVATE void WSRCParser_put_character ARGS2(HTStream*, me, char, c) PRIVATE BOOL write_cache ARGS1(HTStream *, me) { FILE * fp; - char cache_file_name[256]; + char * cache_file_name = NULL; char * www_database; + int result = NO; + if (!me->par_value[PAR_DATABASE_NAME] || !me->par_value[PAR_IP_NAME] ) return NO; www_database = HTEscape(me->par_value[PAR_DATABASE_NAME], URL_XALPHAS); - sprintf(cache_file_name, "%sWSRC-%s:%s:%.100s.txt", + HTSprintf0(&cache_file_name, "%sWSRC-%s:%s:%.100s.txt", CACHE_FILE_PREFIX, me->par_value[PAR_IP_NAME], me->par_value[PAR_TCP_PORT] ? me->par_value[PAR_TCP_PORT] : "210", www_database); + + if ((fp = fopen(cache_file_name, TXT_W)) != 0) { + result = YES; + if (me->par_value[PAR_DESCRIPTION]) + fputs(me->par_value[PAR_DESCRIPTION], fp); + else + fputs("Description not available\n", fp); + fclose(fp); + } FREE(www_database); - fp = fopen(cache_file_name, "w"); - if (!fp) return NO; - - if (me->par_value[PAR_DESCRIPTION]) - fputs(me->par_value[PAR_DESCRIPTION], fp); - else - fputs("Description not available\n", fp); - fclose(fp); - return YES; + FREE(cache_file_name); + return result; } #endif @@ -329,11 +331,11 @@ PRIVATE void WSRC_gen_html ARGS2(HTStream *, me, BOOL, source_file) if (me->par_value[PAR_IP_NAME] && me->par_value[PAR_DATABASE_NAME]) { - char WSRC_address[256]; + char * WSRC_address = NULL; char * www_database; www_database = HTEscape(me->par_value[PAR_DATABASE_NAME], URL_XALPHAS); - sprintf(WSRC_address, "wais://%s%s%s/%s", + HTSprintf0(&WSRC_address, "wais://%s%s%s/%s", me->par_value[PAR_IP_NAME], me->par_value[PAR_TCP_PORT] ? ":" : "", me->par_value[PAR_TCP_PORT] ? me->par_value[PAR_TCP_PORT] :"", @@ -346,6 +348,7 @@ PRIVATE void WSRC_gen_html ARGS2(HTStream *, me, BOOL, source_file) PUTS(gettext(" (or via proxy server, if defined)")); FREE(www_database); + FREE(WSRC_address); } else { give_parameter(me, PAR_IP_NAME); diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HText.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HText.h index 7258a34331d..b1a11ba4d1f 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HText.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HText.h @@ -83,7 +83,7 @@ extern void HText_setStyle PARAMS((HText * text, HTStyle * style)); ADD ONE CHARACTER */ -extern void HText_appendCharacter PARAMS((HText * text, char ch)); +extern void HText_appendCharacter PARAMS((HText * text, int ch)); /* @@ -126,7 +126,7 @@ extern int HText_beginAnchor PARAMS(( BOOL underline, HTChildAnchor * anc)); extern void HText_endAnchor PARAMS((HText * text, int number)); - +extern BOOL HText_isAnchorBlank PARAMS((HText * text, int number)); /* diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTioctl.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTioctl.h new file mode 100644 index 00000000000..95e914e60ac --- /dev/null +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTioctl.h @@ -0,0 +1,11 @@ +/* +** A routine to mimic the ioctl function for UCX. +** Bjorn S. Nilsson, 25-Nov-1993. Based on an example in the UCX manual. +*/ +#include <iodef.h> +#define IOC_OUT (int)0x40000000 +extern int vaxc$get_sdc(), sys$qiow(); + +#ifndef UCX$C_IOCTL +#define UCX$C_IOCTL TCPIP$C_IOCTL +#endif diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/LYLeaks.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/LYLeaks.h index 5ecf8e67d2b..fe995fb669c 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/LYLeaks.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/LYLeaks.h @@ -32,12 +32,23 @@ ** string created by __FILE__ to not be dynamic in ** nature (don't free it and assume will exist at all ** times during execution). +** If you are using LY_FIND_LEAKS and LY_FIND_LEAKS_EXTENDED and +** want only normal memory tracking (not extended for +** HTSprintf/HTSprintf0) to be used in a certain file, +** define NO_EXTENDED_MEMORY_TRACKING and don't define +** NO_MEMORY_TRACKING before including this file. ** Revision History: ** 05-26-94 created for Lynx 2-3-1, Garrett Arch Blythe ** 10-30-97 modified to handle StrAllocCopy() and ** StrAllocCat(). - KW & FM +** 1999-10-17 modified to handle HTSprintf0 and HTSprintf(), +** and to provide mark_malloced, if +** LY_FIND_LEAKS_EXTENDED is defined. - kw */ +/* Undefine this to get no improved HTSprintf0/HTSprintf tracking: */ +#define LY_FIND_LEAKS_EXTENDED + /* ** Required includes */ @@ -146,13 +157,42 @@ typedef struct AllocationList_tag { #endif /* StrAllocCat */ #define StrAllocCat(dest, src) LYLeakSACat(&(dest), src, __FILE__, __LINE__) +#define mark_malloced(a,size) LYLeak_mark_malloced(a,size, __FILE__, __LINE__) + +#if defined(LY_FIND_LEAKS_EXTENDED) && !defined(NO_EXTENDED_MEMORY_TRACKING) +#ifdef HTSprintf0 +#undef HTSprintf0 +#endif /* HTSprintf0 */ +#define HTSprintf0 (Get_htsprintf0_fn(__FILE__,__LINE__)) +#ifdef HTSprintf +#undef HTSprintf +#endif /* HTSprintf */ +#define HTSprintf (Get_htsprintf_fn(__FILE__,__LINE__)) +#endif /* LY_FIND_LEAKS_EXTENDED and not NO_EXTENDED_MEMORY_TRACKING */ + +#else /* LY_FIND_LEAKS && !NO_MEMORY_TRACKING */ + +#define mark_malloced(a,size) /* no-op */ + #endif /* LY_FIND_LEAKS && !NO_MEMORY_TRACKING */ +#if defined(LY_FIND_LEAKS) +#define PUBLIC_IF_FIND_LEAKS PUBLIC +#else +#define PUBLIC_IF_FIND_LEAKS PRIVATE +#endif /* ** Function declarations ** See the appropriate source file for usage. */ extern void LYLeaks NOPARAMS; +#ifdef LY_FIND_LEAKS_EXTENDED +extern AllocationList *LYLeak_mark_malloced PARAMS(( + void * vp_alloced, + size_t st_bytes, + CONST char * cp_File, + CONST short ssi_Line)); +#endif /* LY_FIND_LEAKS_EXTENDED */ extern void *LYLeakMalloc PARAMS(( size_t st_bytes, CONST char * cp_File, @@ -182,4 +222,17 @@ extern char * LYLeakSACat PARAMS(( CONST char * cp_File, CONST short ssi_Line)); +#ifdef LY_FIND_LEAKS_EXTENDED +/* Trick to get tracking of var arg functions without relying + on var arg preprocessor macros: */ + +typedef char * HTSprintflike PARAMS((char **, CONST char *, ...)); +extern HTSprintflike *Get_htsprintf_fn PARAMS(( + CONST char * cp_File, + CONST short ssi_Line)); +extern HTSprintflike *Get_htsprintf0_fn PARAMS(( + CONST char * cp_File, + CONST short ssi_Line)); +#endif /* LY_FIND_LEAKS_EXTENDED */ + #endif /* __LYLEAKS_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/LYexit.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/LYexit.h index 235b3e0b146..347ee0d364b 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/LYexit.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/LYexit.h @@ -51,12 +51,8 @@ /* * Function declarations */ -extern void exit_immediately PARAMS((int status)); /* in LYMain.c */ -extern void LYexit PARAMS((int status)); -#ifdef __STDC__ -extern int LYatexit(void (*function)(void)); -#else -extern int LYatexit(); -#endif /* __STDC__ */ +extern void exit_immediately PARAMS((int status)) GCC_NORETURN; +extern void LYexit PARAMS((int status)) GCC_NORETURN; +extern int LYatexit PARAMS((void (*function)(void))); #endif /* __LYEXIT_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.c index 7d436284bef..6497f8ea1d2 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.c @@ -35,13 +35,13 @@ #ifdef USE_COLOR_STYLE # include <LYStyle.h> #endif -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC # include <LYPrettySrc.h> #endif #define INVALID (-1) -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC # define PSRC(x) if (psrc_view) { x }; # define NPSRC(x) if (!psrc_view) { x }; @@ -76,7 +76,7 @@ PRIVATE void fake_put_character ARGS2( if (ch->size >= ch->allocated) {\ ch->allocated = ch->allocated + ch->growby;\ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)\ - : (char *)calloc(1, ch->allocated);\ + : typecallocn(char, ch->allocated);\ if (!ch->data)\ outofmem(__FILE__, "HTChunkPutc");\ }\ @@ -86,9 +86,8 @@ PRIVATE void fake_put_character ARGS2( #define PUTS(str) ((*context->actions->put_string)(context->target, str)) -#define OPT 0 /* don't make it 1 otherwise something wrong will be with - TagSoup parser mode - I was unable to undestand why it works incorrectly -HV*/ -#define OPT1 1 /* set to 1 for several optimizations */ +#define OPT 1 + /*the following macros are used for pretty source view. */ #define IS_C(attr) (attr.type == HTMLA_CLASS) @@ -121,6 +120,51 @@ struct _HTElement { HTTag* tag; /* The tag at this level */ }; +typedef enum { + S_text = 0 + ,S_attr + ,S_attr_gap + ,S_comment + ,S_cro + ,S_doctype + ,S_dollar + ,S_dollar_dq + ,S_dollar_paren + ,S_dollar_paren_dq + ,S_dollar_paren_sq + ,S_dollar_sq + ,S_dquoted + ,S_end + ,S_entity + ,S_equals + ,S_ero + ,S_esc + ,S_esc_dq + ,S_esc_sq + ,S_exclamation + ,S_in_kanji + ,S_incro + ,S_junk_pi + ,S_junk_tag + ,S_litteral + ,S_marked + ,S_nonascii_text + ,S_nonascii_text_dq + ,S_nonascii_text_sq + ,S_paren + ,S_paren_dq + ,S_paren_sq + ,S_pcdata + ,S_script + ,S_sgmlatt + ,S_sgmlele + ,S_sgmlent + ,S_squoted + ,S_tag + ,S_tag_gap + ,S_tagname_slash + ,S_value +} sgml_state; /* Internal Context Data Structure ** ------------------------------- @@ -134,24 +178,15 @@ struct _HTStream { HTStructured *target; /* target object */ HTTag *current_tag; + HTTag *slashedtag; CONST HTTag *unknown_tag; BOOL inSELECT; + BOOL no_lynx_specialcodes; int current_attribute_number; HTChunk *string; HTElement *element_stack; - enum sgml_state { S_text, S_litteral, - S_tag, S_tag_gap, S_attr, S_attr_gap, S_equals, S_value, - S_ero, S_cro, S_incro, - S_exclamation, S_comment, S_doctype, S_marked, - S_sgmlent, S_sgmlele, S_sgmlatt, - S_squoted, S_dquoted, S_end, S_entity, - S_esc, S_dollar, S_paren, S_nonascii_text, - S_dollar_paren, - S_esc_sq, S_dollar_sq, S_paren_sq, S_nonascii_text_sq, - S_dollar_paren_sq, - S_esc_dq, S_dollar_dq, S_paren_dq, S_nonascii_text_dq, - S_dollar_paren_dq, - S_in_kanji, S_junk_tag} state; + sgml_state state; + unsigned char kanji_buf; #ifdef CALLERDATA void * callerData; #endif /* CALLERDATA */ @@ -181,21 +216,79 @@ struct _HTStream { char * recover; int recover_index; char * include; + char * active_include; int include_index; char * url; char * csi; int csi_index; -} ; +#ifdef USE_PRETTYSRC + BOOL cur_attr_is_href; + BOOL cur_attr_is_name; + BOOL seen_nonwhite_in_junk_tag; +#endif +}; + +#ifndef NO_LYNX_TRACE +PRIVATE char *state_name ARGS1(sgml_state, n) +{ + char *result = "?"; + switch (n) { + case S_attr: result = "S_attr"; break; + case S_attr_gap: result = "S_attr_gap"; break; + case S_comment: result = "S_comment"; break; + case S_cro: result = "S_cro"; break; + case S_doctype: result = "S_doctype"; break; + case S_dollar: result = "S_dollar"; break; + case S_dollar_dq: result = "S_dollar_dq"; break; + case S_dollar_paren: result = "S_dollar_paren"; break; + case S_dollar_paren_dq: result = "S_dollar_paren_dq"; break; + case S_dollar_paren_sq: result = "S_dollar_paren_sq"; break; + case S_dollar_sq: result = "S_dollar_sq"; break; + case S_dquoted: result = "S_dquoted"; break; + case S_end: result = "S_end"; break; + case S_entity: result = "S_entity"; break; + case S_equals: result = "S_equals"; break; + case S_ero: result = "S_ero"; break; + case S_esc: result = "S_esc"; break; + case S_esc_dq: result = "S_esc_dq"; break; + case S_esc_sq: result = "S_esc_sq"; break; + case S_exclamation: result = "S_exclamation"; break; + case S_in_kanji: result = "S_in_kanji"; break; + case S_incro: result = "S_incro"; break; + case S_junk_pi: result = "S_junk_pi"; break; + case S_junk_tag: result = "S_junk_tag"; break; + case S_litteral: result = "S_litteral"; break; + case S_marked: result = "S_marked"; break; + case S_nonascii_text: result = "S_nonascii_text"; break; + case S_nonascii_text_dq: result = "S_nonascii_text_dq"; break; + case S_nonascii_text_sq: result = "S_nonascii_text_sq"; break; + case S_paren: result = "S_paren"; break; + case S_paren_dq: result = "S_paren_dq"; break; + case S_paren_sq: result = "S_paren_sq"; break; + case S_pcdata: result = "S_pcdata"; break; + case S_script: result = "S_script"; break; + case S_sgmlatt: result = "S_sgmlatt"; break; + case S_sgmlele: result = "S_sgmlele"; break; + case S_sgmlent: result = "S_sgmlent"; break; + case S_squoted: result = "S_squoted"; break; + case S_tag: result = "S_tag"; break; + case S_tag_gap: result = "S_tag_gap"; break; + case S_tagname_slash: result = "S_tagname_slash"; break; + case S_text: result = "S_text"; break; + case S_value: result = "S_value"; break; + } + return result; +} +#endif -#ifdef USE_PSRC -static BOOL seen_letter_in_junk_tag; +#ifdef USE_PRETTYSRC PRIVATE void HTMLSRC_apply_markup ARGS3( HTStream *, context, - HTlexem, lexem, + HTlexeme, lexeme, BOOL, start) { - HT_tagspec* ts = *( ( start ? lexem_start : lexem_end ) + lexem); + HT_tagspec* ts = *( ( start ? lexeme_start : lexeme_end ) + lexeme); while (ts) { #ifdef USE_COLOR_STYLE @@ -206,7 +299,7 @@ PRIVATE void HTMLSRC_apply_markup ARGS3( force_classname = TRUE; } #endif - CTRACE(tfp,ts->start ? "SRCSTART %d\n" : "SRCSTOP %d\n",(int)lexem); + CTRACE((tfp,ts->start ? "SRCSTART %d\n" : "SRCSTOP %d\n",(int)lexeme)); if (ts->start) (*context->actions->start_element)( context->target, @@ -224,11 +317,16 @@ PRIVATE void HTMLSRC_apply_markup ARGS3( } } +#if ANSI_PREPRO # define PSRCSTART(x) HTMLSRC_apply_markup(context,HTL_##x,START) # define PSRCSTOP(x) HTMLSRC_apply_markup(context,HTL_##x,STOP) +#else +# define PSRCSTART(x) HTMLSRC_apply_markup(context,HTL_/**/x,START) +# define PSRCSTOP(x) HTMLSRC_apply_markup(context,HTL_/**/x,STOP) +#endif -PRIVATE BOOL cur_attr_is_href; -PRIVATE BOOL cur_attr_is_name; +#define attr_is_href context->cur_attr_is_href +#define attr_is_name context->cur_attr_is_name #endif PRIVATE void set_chartrans_handling ARGS3( @@ -239,7 +337,7 @@ PRIVATE void set_chartrans_handling ARGS3( if (chndl < 0) { /* ** Nothing was set for the parser in earlier stages, - ** so the HTML parser's UCLYhndl should still be it's + ** so the HTML parser's UCLYhndl should still be its ** default. - FM */ chndl = HTAnchor_getUCLYhndl(anchor, UCT_STAGE_STRUCTURED); @@ -360,17 +458,17 @@ PRIVATE void handle_attribute_name ARGS2( attr * attributes = tag->attributes; int high, low, i, diff; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { - cur_attr_is_href = FALSE; - cur_attr_is_name = FALSE; + attr_is_href = FALSE; + attr_is_name = FALSE; } #endif /* ** Ignore unknown tag. - KW */ if (tag == context->unknown_tag) { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) context->current_attribute_number = 1; /* anything !=INVALID */ #endif @@ -387,28 +485,24 @@ PRIVATE void handle_attribute_name ARGS2( diff = strcasecomp(attributes[i].name, s); if (diff == 0) { /* success: found it */ context->current_attribute_number = i; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) { #endif context->present[i] = YES; FREE(context->value[i]); #ifdef USE_COLOR_STYLE -# ifdef USE_PSRC -# if !OPT1 - current_is_class = (!strcasecomp("class", s)); -# else +# ifdef USE_PRETTYSRC current_is_class = IS_C(attributes[i]); -# endif # else current_is_class = (!strcasecomp("class", s)); # endif - CTRACE(tfp, "SGML: found attribute %s, %d\n", s, current_is_class); + CTRACE((tfp, "SGML: found attribute %s, %d\n", s, current_is_class)); #endif -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC } else { - cur_attr_is_name = (attributes[i].type == HTMLA_ANAME); - cur_attr_is_href = (attributes[i].type == HTMLA_HREF); + attr_is_name = (BOOL) (attributes[i].type == HTMLA_ANAME); + attr_is_href = (BOOL) (attributes[i].type == HTMLA_HREF); } #endif return; @@ -416,8 +510,8 @@ PRIVATE void handle_attribute_name ARGS2( } /* for */ - CTRACE(tfp, "SGML: Unknown attribute %s for tag %s\n", - s, context->current_tag->name); + CTRACE((tfp, "SGML: Unknown attribute %s for tag %s\n", + s, context->current_tag->name)); context->current_attribute_number = INVALID; /* Invalid */ } @@ -435,15 +529,15 @@ PRIVATE void handle_attribute_value ARGS2( if (current_is_class) { strncpy (class_string, s, TEMPSTRINGSIZE); - CTRACE(tfp, "SGML: class is '%s'\n", s); + CTRACE((tfp, "SGML: class is '%s'\n", s)); } else { - CTRACE(tfp, "SGML: attribute value is '%s'\n", s); + CTRACE((tfp, "SGML: attribute value is '%s'\n", s)); } #endif } else { - CTRACE(tfp, "SGML: Attribute value %s ***ignored\n", s); + CTRACE((tfp, "SGML: Attribute value %s ***ignored\n", s)); } context->current_attribute_number = INVALID; /* can't have two assignments! */ } @@ -463,11 +557,19 @@ PRIVATE BOOL put_special_unicodes ARGS2( HTStream *, context, UCode_t, code) { + /* (Tgf_nolyspcl) */ + if (context->no_lynx_specialcodes) { + /* + ** We were asked by a "DTD" flag to not generate lynx specials. - kw + */ + return NO; + } + if (code == CH_NBSP) { /* S/390 -- gil -- 0657 */ /* ** Use Lynx special character for nbsp. */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) #endif PUTC(HT_NON_BREAK_SPACE); @@ -475,7 +577,7 @@ PRIVATE BOOL put_special_unicodes ARGS2( /* ** Use Lynx special character for shy. */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) #endif PUTC(LY_SOFT_HYPHEN); @@ -490,9 +592,10 @@ PRIVATE BOOL put_special_unicodes ARGS2( ** in the context of line wrapping. Unfortunately, if we use ** HT_EN_SPACE we override the chartrans tables for those spaces ** with a single '32' for all (but do line wrapping more fancy). - ** Assume emsp as two ensp (below). + ** + ** We may treat emsp as one or two ensp (below). */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) #endif PUTC(HT_EN_SPACE); @@ -500,12 +603,12 @@ PRIVATE BOOL put_special_unicodes ARGS2( /* ** Use Lynx special character for emsp. */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) { #endif /* PUTC(HT_EN_SPACE); let's stay with a single space :) */ PUTC(HT_EN_SPACE); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC } #endif } else { @@ -557,7 +660,7 @@ PRIVATE void handle_entity ARGS2( ** Check for special Unicodes. - FM */ if (put_special_unicodes(context, code)) { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { HTMLSRC_apply_markup(context,HTL_entity,START); PUTC('&'); @@ -578,7 +681,7 @@ PRIVATE void handle_entity ARGS2( uck < 256 && (uck < 127 || uck >= LYlowest_eightbit[context->outUCLYhndl])) { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { HTMLSRC_apply_markup(context,HTL_entity,START); PUTC('&'); PUTS(entity_string); if (term) PUTC(term); @@ -596,7 +699,7 @@ PRIVATE void handle_entity ARGS2( */ (uck = UCTransUniCharStr(replace_buf, 60, code, context->outUCLYhndl, 0) >= 0)) { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { HTMLSRC_apply_markup(context,HTL_entity,START); PUTC('&'); @@ -614,7 +717,7 @@ PRIVATE void handle_entity ARGS2( /* ** If we're displaying UTF-8, try that now. - FM */ -#ifndef USE_PSRC +#ifndef USE_PRETTYSRC if (context->T.output_utf8 && PUTUTF8(code)) { FoundEntity = TRUE; return; @@ -622,7 +725,7 @@ PRIVATE void handle_entity ARGS2( #else if (context->T.output_utf8 && (psrc_view ? (UCPutUtf8_charstring((HTStream *)context->target, - (putc_func_t*)(&fake_put_character), code)): PUTUTF8(code) ) ) { + (putc_func_t*)(fake_put_character), code)): PUTUTF8(code) ) ) { if (psrc_view) { HTMLSRC_apply_markup(context,HTL_entity,START); @@ -638,7 +741,7 @@ PRIVATE void handle_entity ARGS2( ** If it's safe ASCII, use it. - FM */ if (code >= 32 && code < 127) { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { HTMLSRC_apply_markup(context,HTL_entity,START); PUTC('&'); @@ -661,8 +764,8 @@ PRIVATE void handle_entity ARGS2( */ if (!strcmp(s, "zwnj") || !strcmp(s, "zwj")) { - CTRACE(tfp, "handle_entity: Ignoring '%s'.\n", s); -#ifdef USE_PSRC + CTRACE((tfp, "handle_entity: Ignoring '%s'.\n", s)); +#ifdef USE_PRETTYSRC if (psrc_view) { HTMLSRC_apply_markup(context,HTL_entity,START); PUTC('&'); @@ -680,8 +783,8 @@ PRIVATE void handle_entity ARGS2( */ if (!strcmp(s, "lrm") || !strcmp(s, "rlm")) { - CTRACE(tfp, "handle_entity: Ignoring '%s'.\n", s); -#ifdef USE_PSRC + CTRACE((tfp, "handle_entity: Ignoring '%s'.\n", s)); +#ifdef USE_PRETTYSRC if (psrc_view) { HTMLSRC_apply_markup(context,HTL_entity,START); PUTC('&'); @@ -699,18 +802,18 @@ PRIVATE void handle_entity ARGS2( /* ** If entity string not found, display as text. */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif - CTRACE(tfp, "SGML: Unknown entity '%s' %ld %ld\n", s, (long)code, uck); /* S/390 -- gil -- 0695 */ + CTRACE((tfp, "SGML: Unknown entity '%s' %ld %ld\n", s, (long)code, uck)); /* S/390 -- gil -- 0695 */ PUTC('&'); for (p = s; *p; p++) { PUTC(*p); } if (term != '\0') PUTC(term); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif @@ -725,7 +828,7 @@ PRIVATE void handle_comment ARGS1( { CONST char *s = context->string->data; - CTRACE(tfp, "SGML Comment:\n<%s>\n", s); + CTRACE((tfp, "SGML Comment:\n<%s>\n", s)); if (context->csi == NULL && strncmp(s, "!--#", 4) == 0 && @@ -747,7 +850,7 @@ PRIVATE void handle_identifier ARGS1( { CONST char *s = context->string->data; - CTRACE(tfp, "SGML Identifier:\n<%s>\n", s); + CTRACE((tfp, "SGML Identifier:\n<%s>\n", s)); return; } @@ -761,11 +864,15 @@ PRIVATE void handle_doctype ARGS1( { CONST char *s = context->string->data; - CTRACE(tfp, "SGML Doctype:\n<%s>\n", s); + CTRACE((tfp, "SGML Doctype:\n<%s>\n", s)); return; } +PRIVATE void SGML_write PARAMS(( + HTStream * me, + CONST char * s, + int l)); /* Handle marked ** ------------- @@ -775,8 +882,21 @@ PRIVATE void handle_marked ARGS1( { CONST char *s = context->string->data; - CTRACE(tfp, "SGML Marked Section:\n<%s>\n", s); + CTRACE((tfp, "SGML Marked Section:\n<%s>\n", s)); + if (!strncmp(context->string->data, "![INCLUDE[", 10)) { + context->string->data[context->string->size - 3] = '\0'; + StrAllocCat(context->include, context->string->data + 10); + /* @@@ This needs to take charset into account! @@@ + the wrong assumptions will be made about the data's + charset once it is in include - kw */ + + } else if (!strncmp(context->string->data, "![CDATA[", 8)) { + (*context->actions->_write)(context->target, + context->string->data + 8, + context->string->size - 11); + + } return; } @@ -789,7 +909,7 @@ PRIVATE void handle_sgmlent ARGS1( { CONST char *s = context->string->data; - CTRACE(tfp, "SGML Entity Declaration:\n<%s>\n", s); + CTRACE((tfp, "SGML Entity Declaration:\n<%s>\n", s)); return; } @@ -803,7 +923,7 @@ PRIVATE void handle_sgmlele ARGS1( { CONST char *s = context->string->data; - CTRACE(tfp, "SGML Element Declaration:\n<%s>\n", s); + CTRACE((tfp, "SGML Element Declaration:\n<%s>\n", s)); return; } @@ -817,11 +937,41 @@ PRIVATE void handle_sgmlatt ARGS1( { CONST char *s = context->string->data; - CTRACE(tfp, "SGML Attribute Declaration:\n<%s>\n", s); + CTRACE((tfp, "SGML Attribute Declaration:\n<%s>\n", s)); return; } +/* + * Convenience macros - tags (elements) are identified sometimes + * by an int or enum value ('TAGNUM'), sometimes + * by a pointer to HTTag ('TAGP'). - kw + */ +#define TAGNUM_OF_TAGP(t) (t - context->dtd->tags) +#define TAGP_OF_TAGNUM(e) (context->dtd->tags + e) + +/* + * The following implement special knowledge about OBJECT. + * As long as HTML_OBJECT is the only tag for which an alternative + * variant exist, they can be simple macros. - kw + */ +/* does 'TAGNUM' e have an alternative (variant) parsing mode? */ +#define HAS_ALT_TAGNUM(e) (e == HTML_OBJECT) + +/* return 'TAGNUM' of the alternative mode for 'TAGNUM' e, if any. */ +#define ALT_TAGNUM(e) ((e == HTML_OBJECT) ? HTML_ALT_OBJECT : e) + +/* return 'TAGNUM' of the normal mode for 'TAGNUM' e which may be alt. */ +#define NORMAL_TAGNUM(e) ((e >= HTML_ELEMENTS) ? HTML_OBJECT : e) + +/* More convenience stuff. - kw */ +#define ALT_TAGP_OF_TAGNUM(e) TAGP_OF_TAGNUM(ALT_TAGNUM(e)) +#define NORMAL_TAGP_OF_TAGNUM(e) TAGP_OF_TAGNUM(NORMAL_TAGNUM(e)) + +#define ALT_TAGP(t) ALT_TAGP_OF_TAGNUM(TAGNUM_OF_TAGP(t)) +#define NORMAL_TAGP(t) NORMAL_TAGP_OF_TAGNUM(TAGNUM_OF_TAGP(t)) + + #ifdef EXTENDED_HTMLDTD PRIVATE BOOL element_valid_within ARGS3( @@ -835,10 +985,10 @@ PRIVATE BOOL element_valid_within ARGS3( usecontains = (direct ? stacked_tag->contains : stacked_tag->icontains); usecontained = (direct ? new_tag->contained : new_tag->icontained); if (new_tag == stacked_tag) - return ((Tgc_same & usecontains) && + return (BOOL) ((Tgc_same & usecontains) && (Tgc_same & usecontained)); else - return ((new_tag->tagclass & usecontains) && + return (BOOL) ((new_tag->tagclass & usecontains) && (stacked_tag->tagclass & usecontained)); } @@ -869,17 +1019,24 @@ PRIVATE void do_close_stacked ARGS1( HTStream *, context) { HTElement * stacked = context->element_stack; + HTMLElement e; if (!stacked) return; /* stack was empty */ if (context->inSELECT && !strcasecomp(stacked->tag->name, "SELECT")) { context->inSELECT = FALSE; } + e = NORMAL_TAGNUM(TAGNUM_OF_TAGP(stacked->tag)); +#ifdef USE_PRETTYSRC + if (!psrc_view) /* Don't actually pass call on if viewing psrc - kw */ +#endif (*context->actions->end_element)( context->target, - stacked->tag - context->dtd->tags, + e, (char **)&context->include); context->element_stack = stacked->next; FREE(stacked); + context->no_lynx_specialcodes = context->element_stack ? + (context->element_stack->tag->flags & Tgf_nolyspcl) : NO; } PRIVATE int is_on_stack ARGS2( @@ -889,7 +1046,8 @@ PRIVATE int is_on_stack ARGS2( HTElement * stacked = context->element_stack; int i = 1; for (; stacked; stacked = stacked->next, i++) { - if (stacked->tag == old_tag) + if (stacked->tag == old_tag || + stacked->tag == ALT_TAGP(old_tag)) return i; } return 0; @@ -913,36 +1071,36 @@ PRIVATE void end_element ARGS2( while (canclose_check != close_NO && context->element_stack && (stackpos > 1 || (!extra_action_taken && stackpos == 0))) { + if (stackpos == 0 && (old_tag->flags & Tgf_startO) && + element_valid_within(old_tag, context->element_stack->tag, YES)) { + CTRACE((tfp, "SGML: </%s> ignored\n", old_tag->name)); + return; + } canclose_check = can_close(old_tag, context->element_stack->tag); if (canclose_check != close_NO) { - CTRACE(tfp, "SGML: End </%s> \t<- %s end </%s>\n", + CTRACE((tfp, "SGML: End </%s> \t<- %s end </%s>\n", context->element_stack->tag->name, canclose_check == close_valid ? "supplied," : "***forced by", - old_tag->name); + old_tag->name)); do_close_stacked(context); extra_action_taken = YES; stackpos = is_on_stack(context, old_tag); - } else { - CTRACE(tfp, "SGML: Still open %s \t<- ***invalid end </%s>\n", - context->element_stack->tag->name, - old_tag->name); - return; } } if (stackpos == 0 && old_tag->contents != SGML_EMPTY) { - CTRACE(tfp, "SGML: Still open %s, ***no open %s for </%s>\n", + CTRACE((tfp, "SGML: Still open %s, ***no open %s for </%s>\n", context->element_stack ? context->element_stack->tag->name : "none", old_tag->name, - old_tag->name); + old_tag->name)); return; } if (stackpos > 1) { - CTRACE(tfp, "SGML: Nesting <%s>...<%s> \t<- ***invalid end </%s>\n", + CTRACE((tfp, "SGML: Nesting <%s>...<%s> \t<- ***invalid end </%s>\n", old_tag->name, context->element_stack->tag->name, - old_tag->name); + old_tag->name)); return; } } @@ -964,18 +1122,18 @@ PRIVATE void end_element ARGS2( /* ** Ignore the end tag. - FM */ - CTRACE(tfp, "SGML: ***Ignoring end tag </%s> in SELECT block.\n", - old_tag->name); + CTRACE((tfp, "SGML: ***Ignoring end tag </%s> in SELECT block.\n", + old_tag->name)); return; } } /* ** Handle the end tag. - FM */ - CTRACE(tfp, "SGML: End </%s>\n", old_tag->name); + CTRACE((tfp, "SGML: End </%s>\n", old_tag->name)); if (old_tag->contents == SGML_EMPTY) { - CTRACE(tfp, "SGML: ***Illegal end tag </%s> found.\n", - old_tag->name); + CTRACE((tfp, "SGML: ***Illegal end tag </%s> found.\n", + old_tag->name)); return; } #ifdef WIND_DOWN_STACK @@ -984,24 +1142,47 @@ PRIVATE void end_element ARGS2( if (context->element_stack) /* Substitute and remove one stack element */ #endif /* WIND_DOWN_STACK */ { + int status = HT_OK; + HTMLElement e; HTElement * N = context->element_stack; - HTTag * t = N->tag; + HTTag * t = (N->tag != old_tag) ? NORMAL_TAGP(N->tag) : N->tag; if (old_tag != t) { /* Mismatch: syntax error */ if (context->element_stack->next) { /* This is not the last level */ - CTRACE(tfp, "SGML: Found </%s> when expecting </%s>. </%s> ***assumed.\n", - old_tag->name, t->name, t->name); + CTRACE((tfp, "SGML: Found </%s> when expecting </%s>. </%s> ***assumed.\n", + old_tag->name, t->name, t->name)); } else { /* last level */ - CTRACE(tfp, "SGML: Found </%s> when expecting </%s>. </%s> ***Ignored.\n", - old_tag->name, t->name, old_tag->name); + CTRACE((tfp, "SGML: Found </%s> when expecting </%s>. </%s> ***Ignored.\n", + old_tag->name, t->name, old_tag->name)); return; /* Ignore */ } } - context->element_stack = N->next; /* Remove from stack */ - FREE(N); - (*context->actions->end_element)(context->target, - t - context->dtd->tags, (char **)&context->include); + e = NORMAL_TAGNUM(TAGNUM_OF_TAGP(t)); + CTRACE2(TRACE_SGML, (tfp, "tagnum(%p) = %d\n", t, e)); +#ifdef USE_PRETTYSRC + if (!psrc_view) /* Don't actually pass call on if viewing psrc - kw */ +#endif + status = (*context->actions->end_element)(context->target, + e, (char **)&context->include); + if (status == HT_PARSER_REOPEN_ELT) { + CTRACE((tfp, "SGML: Restart <%s>\n", t->name)); + (*context->actions->start_element)( + context->target, + e, + NULL, + NULL, + context->current_tag_charset, + (char **)&context->include); + } else if (status == HT_PARSER_OTHER_CONTENT) { + CTRACE((tfp, "SGML: Continue with other content model for <%s>\n", t->name)); + context->element_stack->tag = ALT_TAGP_OF_TAGNUM(e); + } else { + context->element_stack = N->next; /* Remove from stack */ + FREE(N); + } + context->no_lynx_specialcodes = context->element_stack ? + (context->element_stack->tag->flags & Tgf_nolyspcl) : NO; #ifdef WIND_DOWN_STACK if (old_tag == t) return; /* Correct sequence */ @@ -1012,8 +1193,8 @@ PRIVATE void end_element ARGS2( /* Syntax error path only */ } - CTRACE(tfp, "SGML: Extra end tag </%s> found and ignored.\n", - old_tag->name); + CTRACE((tfp, "SGML: Extra end tag </%s> found and ignored.\n", + old_tag->name)); } @@ -1022,11 +1203,10 @@ PRIVATE void end_element ARGS2( PRIVATE void start_element ARGS1( HTStream *, context) { + int status; HTTag * new_tag = context->current_tag; -#if OPT1 - HTMLElement e = new_tag - context->dtd->tags; + HTMLElement e = TAGNUM_OF_TAGP(new_tag); BOOL ok = FALSE; -#endif #ifdef EXTENDED_HTMLDTD @@ -1044,27 +1224,27 @@ PRIVATE void start_element ARGS1( direct_container))) { canclose_check = can_close(new_tag, context->element_stack->tag); if (canclose_check != close_NO) { - CTRACE(tfp, "SGML: End </%s> \t<- %s start <%s>\n", + CTRACE((tfp, "SGML: End </%s> \t<- %s start <%s>\n", context->element_stack->tag->name, canclose_check == close_valid ? "supplied," : "***forced by", - new_tag->name); + new_tag->name)); do_close_stacked(context); extra_action_taken = YES; if (canclose_check == close_error) direct_container = NO; } else { - CTRACE(tfp, "SGML: Still open %s \t<- ***invalid start <%s>\n", + CTRACE((tfp, "SGML: Still open %s \t<- ***invalid start <%s>\n", context->element_stack->tag->name, - new_tag->name); + new_tag->name)); } } if (context->element_stack && !valid && (context->element_stack->tag->flags & Tgf_strict) && !(valid = element_valid_within(new_tag, context->element_stack->tag, direct_container))) { - CTRACE(tfp, "SGML: Still open %s \t<- ***ignoring start <%s>\n", + CTRACE((tfp, "SGML: Still open %s \t<- ***ignoring start <%s>\n", context->element_stack->tag->name, - new_tag->name); + new_tag->name)); return; } @@ -1075,10 +1255,10 @@ PRIVATE void start_element ARGS1( for (; i< new_tag->number_of_attributes && !has_attributes; i++) has_attributes = context->present[i]; if (!has_attributes) { - CTRACE(tfp, "SGML: Still open %s, ***converting invalid <%s> to </%s>\n", + CTRACE((tfp, "SGML: Still open %s, ***converting invalid <%s> to </%s>\n", context->element_stack->tag->name, new_tag->name, - new_tag->name); + new_tag->name)); end_element(context, new_tag); return; } @@ -1090,9 +1270,9 @@ PRIVATE void start_element ARGS1( new_tag, context->element_stack->tag, direct_container))) { - CTRACE(tfp, "SGML: Still open %s \t<- ***invalid start <%s>\n", + CTRACE((tfp, "SGML: Still open %s \t<- ***invalid start <%s>\n", context->element_stack->tag->name, - new_tag->name); + new_tag->name)); } } /* Fall through to the non-extended code - kw */ @@ -1124,16 +1304,6 @@ PRIVATE void start_element ARGS1( /* ** Ugh, it is not an OPTION. - FM */ -#if !OPT1 - if (!strcasecomp(new_tag->name, "INPUT") || - !strcasecomp(new_tag->name, "TEXTAREA") || - !strcasecomp(new_tag->name, "SELECT") || - !strcasecomp(new_tag->name, "BUTTON") || - !strcasecomp(new_tag->name, "FIELDSET") || - !strcasecomp(new_tag->name, "LABEL") || - !strcasecomp(new_tag->name, "LEGEND") || - !strcasecomp(new_tag->name, "FORM")) { -#else switch (e) { case HTML_INPUT: case HTML_TEXTAREA: case HTML_SELECT: case HTML_BUTTON: case HTML_FIELDSET: case HTML_LABEL: @@ -1143,21 +1313,21 @@ PRIVATE void start_element ARGS1( default: break; } - if (ok) { -#endif + if (ok) + { /* ** It is another form-related start tag, so terminate ** the current SELECT block and fall through. - FM */ - CTRACE(tfp, "SGML: ***Faking SELECT end tag before <%s> start tag.\n", - new_tag->name); + CTRACE((tfp, "SGML: ***Faking SELECT end tag before <%s> start tag.\n", + new_tag->name)); end_element(context, SGMLFindTag(context->dtd, "SELECT")); } else { /* ** Ignore the start tag. - FM */ - CTRACE(tfp, "SGML: ***Ignoring start tag <%s> in SELECT block.\n", - new_tag->name); + CTRACE((tfp, "SGML: ***Ignoring start tag <%s> in SELECT block.\n", + new_tag->name)); return; } } @@ -1165,14 +1335,16 @@ PRIVATE void start_element ARGS1( /* ** Handle the start tag. - FM */ - CTRACE(tfp, "SGML: Start <%s>\n", new_tag->name); - (*context->actions->start_element)( + CTRACE((tfp, "SGML: Start <%s>\n", new_tag->name)); + status = (*context->actions->start_element)( context->target, - new_tag - context->dtd->tags, + TAGNUM_OF_TAGP(new_tag), context->present, (CONST char**) context->value, /* coerce type for think c */ context->current_tag_charset, (char **)&context->include); + if (status == HT_PARSER_OTHER_CONTENT) + new_tag = ALT_TAGP(new_tag); /* this is only returned for OBJECT */ if (new_tag->contents != SGML_EMPTY) { /* i.e., tag not empty */ HTElement * N = (HTElement *)malloc(sizeof(HTElement)); if (N == NULL) @@ -1180,11 +1352,9 @@ PRIVATE void start_element ARGS1( N->next = context->element_stack; N->tag = new_tag; context->element_stack = N; -#if !OPT - } else if (!strcasecomp(new_tag->name, "META")) { -#else + context->no_lynx_specialcodes = (new_tag->flags & Tgf_nolyspcl); + } else if (e == HTML_META ) { -#endif /* ** Check for result of META tag. - KW & FM */ @@ -1220,7 +1390,7 @@ PUBLIC HTTag * SGMLFindTag ARGS2( return &dtd->tags[i]; } } - if (isalpha((unsigned char)string[0])) { + if (IsNmStart(string[0])) { /* ** Unrecognized, but may be valid. - KW */ @@ -1251,6 +1421,7 @@ PRIVATE void SGML_free ARGS1( FREE(context->url); FREE(context->csi); FREE(context->include); + FREE(context->active_include); /* ** Wind down stack if any elements are open. - FM @@ -1260,8 +1431,12 @@ PRIVATE void SGML_free ARGS1( t = cur->tag; context->element_stack = cur->next; /* Remove from stack */ FREE(cur); - (*context->actions->end_element)(context->target, - t - context->dtd->tags, (char **)&context->include); +#ifdef USE_PRETTYSRC + if (!psrc_view) /* Don't actually call on target if viewing psrc - kw */ +#endif + (*context->actions->end_element)(context->target, + NORMAL_TAGNUM(TAGNUM_OF_TAGP(t)), + (char **)&context->include); FREE(context->include); } @@ -1278,7 +1453,7 @@ PRIVATE void SGML_free ARGS1( FREE(context->value[i]); FREE(context); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC sgml_in_psrc_was_initialized =FALSE; #endif } @@ -1300,6 +1475,7 @@ PRIVATE void SGML_abort ARGS2( */ FREE(context->recover); FREE(context->include); + FREE(context->active_include); FREE(context->url); FREE(context->csi); @@ -1320,7 +1496,7 @@ PRIVATE void SGML_abort ARGS2( FREE(context->value[i]); FREE(context); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC sgml_in_psrc_was_initialized =FALSE; #endif @@ -1358,9 +1534,14 @@ PRIVATE void SGML_character ARGS2( HTChunk *string = context->string; CONST char * EntityName; char * p; + HTTag * testtag = NULL; BOOLEAN chk; /* Helps (?) walk through all the else ifs... */ UCode_t clong, uck = 0; /* Enough bits for UCS4 ... */ +#ifdef CJK_EX + unsigned char c; +#else char c; +#endif char saved_char_in = '\0'; /* @@ -1371,7 +1552,7 @@ PRIVATE void SGML_character ARGS2( #define unsign_c clong c = c_in; - clong = (unsigned char)c; /* a.k.a. unsign_c */ + clong = UCH(c); /* a.k.a. unsign_c */ if (context->T.decode_utf8) { /* @@ -1379,7 +1560,7 @@ PRIVATE void SGML_character ARGS2( ** Incomplete characters silently ignored. ** From Linux kernel's console.c. - KW */ - if (TOASCII((unsigned char)c) > 127) { /* S/390 -- gil -- 0710 */ + if (TOASCII(UCH(c)) > 127) { /* S/390 -- gil -- 0710 */ /* ** We have an octet from a multibyte character. - FM */ @@ -1543,6 +1724,9 @@ PRIVATE void SGML_character ARGS2( ** its recover buffer, but it might not be for ** stuff other functions added to the insert or ** csi buffer, so bear that in mind. - FM +** Stuff from the recover buffer is now handled +** as UTF-8 if we can expect that's what it is, +** and in that case we don't come back up here. - kw */ top: saved_char_in = '\0'; @@ -1555,7 +1739,7 @@ top: */ top0a: *(context->utf_buf) = '\0'; - clong = (unsigned char)c; + clong = UCH(c); /* ** We jump to here from above if we have converted ** the input, or a multibyte sequence across calls, @@ -1577,7 +1761,7 @@ top1: if (TOASCII(unsign_c) < 32 && c != '\t' && c != '\n' && c != '\r' && HTCJK == NOCJK) - return; + goto after_switch; /* ** Ignore 127 if we don't have HTPassHighCtrlRaw @@ -1587,7 +1771,7 @@ top1: unsign_c >= LYlowest_eightbit[context->inUCLYhndl]) if (TOASCII(c) == 127 && /* S/390 -- gil -- 0830 */ !(PASSHICTRL || HTCJK != NOCJK)) - return; + goto after_switch; /* ** Ignore 8-bit control characters 128 - 159 if @@ -1595,11 +1779,34 @@ top1: */ if (TOASCII(unsign_c) > 127 && TOASCII(unsign_c) < 160 && /* S/390 -- gil -- 0847 */ !(PASSHICTRL || HTCJK != NOCJK)) - return; + goto after_switch; + + /* Almost all CJK characters are double byte but only Japanese + * JIS X0201 Kana is single byte. To prevent to fail SGML parsing + * we have to care them here. -- TH + */ + if ((HTCJK==JAPANESE) && (context->state==S_in_kanji) && + !IS_JAPANESE_2BYTE(context->kanji_buf, UCH(c))) { +#ifdef CONV_JISX0201KANA_JISX0208KANA + if (IS_SJIS_X0201KANA(context->kanji_buf)) { + unsigned char sjis_hi, sjis_lo; + JISx0201TO0208_SJIS(context->kanji_buf, &sjis_hi, &sjis_lo); + PUTC(sjis_hi); + PUTC(sjis_lo); + } + else +#endif + PUTC(context->kanji_buf); + context->state = S_text; + } /* ** Handle character based on context->state. */ + CTRACE2(TRACE_SGML, (tfp, "SGML before %s|%.*s|%c\n", + state_name(context->state), + string->size, + string->data != NULL ? string->data : "", UCH(c))); switch(context->state) { case S_in_kanji: @@ -1614,9 +1821,22 @@ top1: ** (see below). - FM */ context->state = S_text; + PUTC(context->kanji_buf); PUTC(c); break; + case S_tagname_slash: + /* + * We had something link "<name/" so far, set state to S_text + * but keep context->slashedtag as as a flag; except if we get + * '>' directly after the "<name/", and really have a tag for + * that name in context->slashedtag, in which case keep state as + * is and let code below deal with it. - kw + */ + if (!(c == '>' && context->slashedtag && TOASCII(unsign_c) < 127)) { + context->state = S_text; + } /* fall through in any case! */ + case S_text: if (HTCJK != NOCJK && (TOASCII(c) & 0200) != 0) { /* S/390 -- gil -- 0864 */ /* @@ -1630,7 +1850,7 @@ top1: ** to having raw mode off with CJK. - FM */ context->state = S_in_kanji; - PUTC(c); + context->kanji_buf = c; break; } else if (HTCJK != NOCJK && TOASCII(c) == '\033') { /* S/390 -- gil -- 0881 */ /* @@ -1641,13 +1861,28 @@ top1: PUTC(c); break; } + + if (c == '&' || c == '<') { +#ifdef USE_PRETTYSRC + if (psrc_view) { /*there is nothing useful in the element_stack*/ + testtag = context->current_tag; + } else +#endif + { + testtag = context->element_stack ? + context->element_stack->tag : NULL; + } + } + if (c == '&' && TOASCII(unsign_c) < 127 && /* S/390 -- gil -- 0898 */ - (!context->element_stack || - (context->element_stack->tag && - (context->element_stack->tag->contents == SGML_MIXED || - context->element_stack->tag->contents == SGML_ELEMENT || - context->element_stack->tag->contents == SGML_PCDATA || - context->element_stack->tag->contents == SGML_RCDATA)))) { + (!testtag || + (testtag->contents == SGML_MIXED || + testtag->contents == SGML_ELEMENT || + testtag->contents == SGML_PCDATA || +#ifdef USE_PRETTYSRC + testtag->contents == SGML_EMPTY || +#endif + testtag->contents == SGML_RCDATA))) { /* ** Setting up for possible entity, without the leading '&'. - FM */ @@ -1658,17 +1893,88 @@ top1: ** Setting up for possible tag. - FM */ string->size = 0; - context->state = (context->element_stack && - context->element_stack->tag && - context->element_stack->tag->contents == SGML_LITTERAL) - ? - S_litteral : S_tag; + if (testtag && testtag->contents == SGML_PCDATA) { + context->state = S_pcdata; + } else if (testtag && (testtag->contents == SGML_LITTERAL + || testtag->contents == SGML_CDATA)) { + context->state = S_litteral; + } else if (testtag && (testtag->contents == SGML_SCRIPT)) { + context->state = S_script; + } else { + context->state = S_tag; + } + context->slashedtag = NULL; + } else if (context->slashedtag && + (c == '/' || + (c == '>' && context->state == S_tagname_slash)) && + TOASCII(unsign_c) < 127) { + /* + ** We got either the second slash of a pending "<NAME/blah blah/" + ** shortref construct, or the '>' of a mere "<NAME/>". In both + ** cases generate a "</NAME>" end tag in the recover buffer for + ** reparsing unless NAME is really an empty element. - kw + */ +#ifdef USE_PRETTYSRC + if (psrc_view) { + PSRCSTART(abracket); + PUTC(c); + PSRCSTOP(abracket); + } else +#endif + if (context->slashedtag != context->unknown_tag && + !ReallyEmptyTag(context->slashedtag)) { + if (context->recover == NULL) { + StrAllocCopy(context->recover, "</"); + context->recover_index = 0; + } else { + StrAllocCat(context->recover, "</"); + } + StrAllocCat(context->recover, context->slashedtag->name); + StrAllocCat(context->recover, ">"); + } + context->slashedtag = NULL; + + } else if (context->element_stack && + (context->element_stack->tag->flags & Tgf_frecyc)) { + /* + * The element stack says we are within the contents of an + * element that the next stage (HTML.c) may want to feed + * us back again (via the *include string). So try to output + * text in UTF-8 if possible, using the same logic as for + * attribute values (which should be in line with what + * context->current_tag_charset indicates). - kw + */ + if (context->T.decode_utf8 && + *context->utf_buf) { + PUTS(context->utf_buf); + context->utf_buf_p = context->utf_buf; + *(context->utf_buf_p) = '\0'; + } else if (HTCJK == NOCJK && + (context->T.output_utf8 || + context->T.trans_from_uni)) { + if (LYIsASCII(clong)) { + PUTC(c); + } else if (clong == 0xfffd && saved_char_in && + HTPassEightBitRaw && + UCH(saved_char_in) >= + LYlowest_eightbit[context->outUCLYhndl]) { + PUTUTF8((0xf000 | UCH(saved_char_in))); + } else { + PUTUTF8(clong); + } + } else if (saved_char_in && context->T.use_raw_char_in) { + PUTC(saved_char_in); + } else { + PUTC(c); + } + #define PASS8859SPECL context->T.pass_160_173_raw /* ** Convert 160 (nbsp) to Lynx special character if ** neither HTPassHighCtrlRaw nor HTCJK is set. - FM */ } else if (unsign_c == CH_NBSP && /* S/390 -- gil -- 0932 */ + !context->no_lynx_specialcodes && !(PASS8859SPECL || HTCJK != NOCJK)) { PUTC(HT_NON_BREAK_SPACE); /* @@ -1676,6 +1982,7 @@ top1: ** neither HTPassHighCtrlRaw nor HTCJK is set. - FM */ } else if (unsign_c == CH_SHY && /* S/390 -- gil -- 0949 */ + !context->no_lynx_specialcodes && !(PASS8859SPECL || HTCJK != NOCJK)) { PUTC(LY_SOFT_HYPHEN); /* @@ -1693,12 +2000,12 @@ top1: /****************************************************************** * I. LATIN-1 OR UCS2 TO DISPLAY CHARSET ******************************************************************/ - } else if ((chk = (context->T.trans_from_uni && TOASCII(unsign_c) >= 160)) && /* S/390 -- gil -- 0968 */ + } else if ((chk = (BOOL) (context->T.trans_from_uni && TOASCII(unsign_c) >= 160)) && /* S/390 -- gil -- 0968 */ (uck = UCTransUniChar(unsign_c, context->outUCLYhndl)) >= ' ' && uck < 256) { - CTRACE(tfp, "UCTransUniChar returned 0x%.2lX:'%c'.\n", - uck, FROMASCII((char)uck)); + CTRACE((tfp, "UCTransUniChar returned 0x%.2lX:'%c'.\n", + uck, FROMASCII((char)uck))); /* ** We got one octet from the conversions, so use it. - FM */ @@ -1743,7 +2050,7 @@ top1: !(PASSHI8BIT || HTCJK != NOCJK) && !IncludesLatin1Enc) { int i; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC int psrc_view_backup = 0; #endif @@ -1752,14 +2059,14 @@ top1: for (i = 0; EntityName[i]; i++) HTChunkPutc(string, EntityName[i]); HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC /* we need to disable it temporary*/ if (psrc_view) { psrc_view_backup =1; psrc_view =0; } #endif handle_entity(context, '\0'); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC /* we need to disable it temporary*/ if (psrc_view_backup) psrc_view = TRUE; @@ -1791,8 +2098,8 @@ top1: ** Check for a strippable koi8-r 8-bit character. - FM */ } else if (context->T.strip_raw_char_in && saved_char_in && - ((unsigned char)saved_char_in >= 0xc0) && - ((unsigned char)saved_char_in < 255)) { + (UCH(saved_char_in) >= 0xc0) && + (UCH(saved_char_in) < 255)) { /* ** KOI8 special: strip high bit, gives (somewhat) readable ** ASCII or KOI7 - it was constructed that way! - KW @@ -1804,7 +2111,7 @@ top1: ** If we don't actually want the character, ** make it safe and output that now. - FM */ - } else if (TOASCII((unsigned char)c) < /* S/390 -- gil -- 0997 */ + } else if (TOASCII(UCH(c)) < /* S/390 -- gil -- 0997 */ LYlowest_eightbit[context->outUCLYhndl] || (context->T.trans_from_uni && !HTPassEightBitRaw)) { #ifdef NOTUSED_FOTEMODS @@ -1857,29 +2164,139 @@ top1: break; /* + ** Found '<' in SGML_PCDATA content; treat this mode nearly like + ** S_litteral, but recognize '<!' and '<?' to filter out comments + ** and processing instructions. - kw + */ + case S_pcdata: + if (!string->size && TOASCII(unsign_c) < 127) { /* first after '<' */ + if (c == '!') { /* <! */ + /* + ** Terminate and set up for possible comment, + ** identifier, declaration, or marked section + ** as under S_tag. - kw + */ + context->state = S_exclamation; + context->lead_exclamation = TRUE; + context->doctype_bracket = FALSE; + context->first_bracket = FALSE; + HTChunkPutc(string, c); + break; + } else if (c == '?') { /* <? - ignore as a PI until '>' - kw */ + CTRACE((tfp, + "SGML: Found PI in PCDATA, junking it until '>'\n")); +#ifdef USE_PRETTYSRC + if (psrc_view) { + PSRCSTART(abracket);PUTS("<?");PSRCSTOP(abracket); + context->seen_nonwhite_in_junk_tag = TRUE; /* show all */ + } +#endif + context->state = S_junk_pi; + break; + } + } + goto case_S_litteral; + + /* + ** Found '<' in SGML_SCRIPT content; treat this mode nearly like + ** S_litteral, but recognize '<!' to allow the content to be treated + ** as a comment by lynx. + */ + case S_script: + if (!string->size && TOASCII(unsign_c) < 127) { /* first after '<' */ + if (c == '!') { /* <! */ + /* + ** Terminate and set up for possible comment, + ** identifier, declaration, or marked section + ** as under S_tag. - kw + */ + context->state = S_exclamation; + context->lead_exclamation = TRUE; + context->doctype_bracket = FALSE; + context->first_bracket = FALSE; + HTChunkPutc(string, c); + break; + } + } + goto case_S_litteral; + + /* ** In litteral mode, waits only for specific end tag (for ** compatibility with old servers, and for Lynx). - FM */ + case_S_litteral: case S_litteral: /*PSRC:this case not understood completely by HV, not done*/ HTChunkPutc(string, c); +#ifdef USE_PRETTYSRC + if (psrc_view) { /*there is nothing useful in the element_stack*/ + testtag = context->current_tag; + } else +#endif + testtag = context->element_stack ? + context->element_stack->tag : NULL; + if (TOUPPER(c) != ((string->size == 1) ? '/' : - context->element_stack->tag->name[string->size-2])) { + testtag->name[string->size-2])) { int i; /* ** If complete match, end litteral. */ - if ((c == '>') && - (!context->element_stack->tag->name[string->size-2])) { + if ((c == '>') && testtag && + string->size > 1 && !testtag->name[string->size-2]) { +#ifdef USE_PRETTYSRC + if (psrc_view) { + PSRCSTART(abracket);PUTC('<');PUTC('/');PSRCSTOP(abracket); + PSRCSTART(tag); + strcpy(string->data,context->current_tag->name); + if (tagname_transform != 1) { + if (tagname_transform == 0) + LYLowerCase(string->data); + else + LYUpperCase(string->data); + } + PUTS(string->data); + PSRCSTOP(tag); + PSRCSTART(abracket);PUTC('>');PSRCSTOP(abracket); + + context->current_tag = NULL; + string->size = 0; + context->current_attribute_number = INVALID; + context->state = S_text; + break; + } +#endif end_element(context, context->element_stack->tag); string->size = 0; context->current_attribute_number = INVALID; context->state = S_text; break; } + + if (((testtag->contents != SGML_LITTERAL && + (testtag->flags & Tgf_strict)) || + (context->state == S_pcdata && + (testtag->flags & (Tgf_strict|Tgf_endO)))) && + (string->size > 1 && + (c == '>' || string->size > 2 || IsNmStart(c)))) { + context->state = S_end; + string->size--; + for (i = 0; i < string->size; i++) /* remove '/' */ + string->data[i] = string->data[i+1]; + if ((string->size == 1) ? IsNmStart(c) : IsNmChar(c)) + break; + string->size--; + goto top1; + } + if (context->state == S_pcdata && + (testtag->flags & (Tgf_strict|Tgf_endO)) && + (string->size == 1 && IsNmStart(c))) { + context->state = S_tag; + break; + } /* - ** If Mismatch: recover string. + ** If Mismatch: recover string literally. */ PUTC('<'); for (i = 0; i < string->size-1; i++) /* recover, except last c */ @@ -1908,7 +2325,10 @@ top1: */ case S_entity: if (TOASCII(unsign_c) < 127 && (string->size ? /* S/390 -- gil -- 1029 */ - isalnum((unsigned char)c) : isalpha((unsigned char)c))) { + isalnum(UCH(c)) : isalpha(UCH(c)))) { + /* Should probably use IsNmStart/IsNmChar above (is that right?), + but the world is not ready for that - there's  : (note + colon!) and stuff around. */ /* ** Accept valid ASCII character. - FM */ @@ -1918,12 +2338,12 @@ top1: ** It was an ampersand that's just text, so output ** the ampersand and recycle this character. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif PUTC('&'); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif @@ -1934,11 +2354,11 @@ top1: ** Terminate entity name and try to handle it. - FM */ HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC entity_string = string->data; #endif /* S/390 -- gil -- 1039 */ - /* CTRACE(tfp, "%s: %d: %s\n", __FILE__, __LINE__, string->data); */ + /* CTRACE((tfp, "%s: %d: %s\n", __FILE__, __LINE__, string->data)); */ if (!strcmp(string->data, "zwnj") && (!context->element_stack || (context->element_stack->tag && @@ -1948,7 +2368,7 @@ top1: */ char temp[8]; - CTRACE(tfp, "SGML_character: Handling 'zwnj' entity as 'WBR' element.\n"); + CTRACE((tfp, "SGML_character: Handling 'zwnj' entity as 'WBR' element.\n")); if (c != ';') { sprintf(temp, "<WBR>%c", c); @@ -1975,7 +2395,7 @@ top1: ** via handle_entity(), or if the terminator is ** not the "standard" semi-colon for HTML. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view && FoundEntity && c == ';') { HTMLSRC_apply_markup(context,HTL_entity, START); PUTC(c); @@ -1991,10 +2411,10 @@ top1: ** Check for a numeric entity. */ case S_cro: - if (TOASCII(unsign_c) < 127 && TOLOWER((unsigned char)c) == 'x') { /* S/390 -- gil -- 1060 */ + if (TOASCII(unsign_c) < 127 && TOLOWER(UCH(c)) == 'x') { /* S/390 -- gil -- 1060 */ context->isHex = TRUE; context->state = S_incro; - } else if (TOASCII(unsign_c) < 127 && isdigit((unsigned char)c)) { + } else if (TOASCII(unsign_c) < 127 && isdigit(UCH(c))) { /* ** Accept only valid ASCII digits. - FM */ @@ -2006,13 +2426,13 @@ top1: ** No 'x' or digit following the "&#" so recover ** them and recycle the character. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif PUTC('&'); PUTC('#'); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif @@ -2025,11 +2445,11 @@ top1: ** Handle a numeric entity. */ case S_incro: - /* S/390 -- gil -- 1075 */ /* CTRACE(tfp, "%s: %d: numeric %d %d\n", - __FILE__, __LINE__, unsign_c, c); */ + /* S/390 -- gil -- 1075 */ /* CTRACE((tfp, "%s: %d: numeric %d %d\n", + __FILE__, __LINE__, unsign_c, c)); */ if ((TOASCII(unsign_c) < 127) && - (context->isHex ? isxdigit((unsigned char)c) : - isdigit((unsigned char)c))) { + (context->isHex ? isxdigit(UCH(c)) : + isdigit(UCH(c)))) { /* ** Accept only valid hex or ASCII digits. - FM */ @@ -2039,14 +2459,14 @@ top1: ** No hex digit following the "&#x" so recover ** them and recycle the character. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif PUTC('&'); PUTC('#'); PUTC('x'); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif @@ -2060,7 +2480,7 @@ top1: UCode_t code; int i; HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC entity_string = string->data; #endif if ((context->isHex ? sscanf(string->data, "%lx", &code) : @@ -2213,7 +2633,7 @@ top1: */ char temp[8]; - CTRACE(tfp, "SGML_character: Handling '8204' (zwnj) reference as 'WBR' element.\n"); + CTRACE((tfp, "SGML_character: Handling '8204' (zwnj) reference as 'WBR' element.\n")); /* ** Include the terminator if it is not @@ -2243,7 +2663,7 @@ top1: ** We handled the value as a special character, ** so recycle the terminator or break. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(entity); PUTS( (context->isHex ? "&#x" : "&#") ); @@ -2268,11 +2688,11 @@ top1: uck < 256 && (uck < 127 || uck >= LYlowest_eightbit[context->outUCLYhndl])) { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) { #endif PUTC(FROMASCII((char)uck)); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC } else { PSRCSTART(entity); PUTS( (context->isHex ? "&#x" : "&#") ); @@ -2290,7 +2710,7 @@ top1: (uck = UCTransUniCharStr(replace_buf, 60, code, context->outUCLYhndl, 0) >= 0)) { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(entity); PUTS( (context->isHex ? "&#x" : "&#") ); @@ -2323,7 +2743,7 @@ top1: /* ** Got an ASCII character (yippey). - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(entity); PUTS( (context->isHex ? "&#x" : "&#") ); @@ -2342,7 +2762,7 @@ top1: /* ** Got a replacement string (yippey). - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(entity); PUTS( (context->isHex ? "&#x" : "&#") ); @@ -2371,7 +2791,7 @@ top1: (context->isHex ? "&#x" : "&#"), replace_buf); } -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(badseq); PUTS( (context->isHex ? "&#x" : "&#") ); @@ -2413,7 +2833,7 @@ top1: ** "&#" or "&#x" and digit(s), and recycle ** the terminator. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(badseq); } @@ -2427,7 +2847,7 @@ top1: string->size--; for (i = 0; i < string->size; i++) /* recover */ PUTC(string->data[i]); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTOP(badseq); } @@ -2442,7 +2862,7 @@ top1: /* ** No conversion needed. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(entity); PUTS( (context->isHex ? "&#x" : "&#") ); @@ -2476,7 +2896,7 @@ top1: ** Our conversion failed, so recover the "&#" ** and digit(s), and recycle the terminator. - FM */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif @@ -2489,7 +2909,7 @@ top1: string->size--; for (i = 0; i < string->size; i++) /* recover */ PUTC(string->data[i]); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif @@ -2522,13 +2942,13 @@ top1: string->size--; HTChunkPutc(string, c); HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif PUTC('&'); PUTC('#'); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif @@ -2555,7 +2975,7 @@ top1: */ case S_tag: /* new tag */ if (TOASCII(unsign_c) < 127 && (string->size ? /* S/390 -- gil -- 1179 */ - isalnum((unsigned char)c) : isalpha((unsigned char)c))) { + IsNmChar(c) : IsNmStart(c))) { /* ** Add valid ASCII character. - FM */ @@ -2583,12 +3003,12 @@ top1: ** So recover the '<' and following character as data. - FM & KW */ context->state = S_text; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif PUTC('<'); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif @@ -2599,43 +3019,65 @@ top1: */ HTTag * t; if (c == '/') { - if (string->size != 0) - CTRACE(tfp,"SGML: `<%s/' found!\n", string->data); - context->state = S_end; - break; + if (string->size == 0) { + context->state = S_end; + break; + } + CTRACE((tfp,"SGML: `<%.*s/' found!\n", string->size, string->data)); } HTChunkTerminate(string) ; t = SGMLFindTag(dtd, string->data); - if (t == context->unknown_tag && c == ':' && - 0 == strcasecomp(string->data, "URL")) { + if (t == context->unknown_tag && + ((c == ':' && + string->size == 4 && 0 == strcasecomp(string->data, "URL")) || + (string->size > 4 && 0 == strncasecomp(string->data, "URL:", 4)))) { /* ** Treat <URL: as text rather than a junk tag, ** so we display it and the URL (Lynxism 8-). - FM */ - int i; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(badseq); #endif PUTC('<'); - for (i = 0; i < 3; i++) /* recover */ - PUTC(string->data[i]); + PUTS(string->data); /* recover */ PUTC(c); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTOP(badseq); #endif - CTRACE(tfp, "SGML: Treating <%s%c as text\n", - string->data, c); + CTRACE((tfp, "SGML: Treating <%s%c as text\n", + string->data, c)); string->size = 0; context->state = S_text; break; - } else if (!t) { - CTRACE(tfp, "SGML: *** Invalid element %s\n", - string->data); + } + if (c == '/' && t) { + /* + * Element name was ended by '/'. Remember the tag that + * ended thusly, we'll interpret this as either an indication + * of an empty element (if '>' follows directly) or do + * some SGMLshortref-ish treatment. - kw + */ + context->slashedtag = t; + } + if (!t) { + if (c == '?' && string->size <= 1) { + CTRACE((tfp, "SGML: Found PI, junking it until '>'\n")); +#ifdef USE_PRETTYSRC + if (psrc_view) { + PSRCSTART(abracket);PUTS("<?");PSRCSTOP(abracket); + context->seen_nonwhite_in_junk_tag = TRUE; /*show all*/ + } +#endif + context->state = S_junk_pi; + break; + } + CTRACE((tfp, "SGML: *** Invalid element %s\n", + string->data)); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(abracket);PUTC('<');PSRCSTOP(abracket); PSRCSTART(badtag); @@ -2646,18 +3088,19 @@ top1: LYUpperCase(string->data); } PUTS(string->data); - if (c == '>' ) { PSRCSTOP(badtag); PSRCSTART(abracket);PUTC('>');PSRCSTOP(abracket); + } else { + PUTC(c); } } #endif context->state = (c == '>') ? S_text : S_junk_tag; break; } else if (t == context->unknown_tag) { - CTRACE(tfp, "SGML: *** Unknown element %s\n", - string->data); + CTRACE((tfp, "SGML: *** Unknown element %s\n", + string->data)); /* ** Fall through and treat like valid ** tag for attribute parsing. - KW @@ -2666,10 +3109,7 @@ top1: } context->current_tag = t; - /* - ** Clear out attributes. - */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(abracket);PUTC('<');PSRCSTOP(abracket); if (t != context->unknown_tag) @@ -2683,42 +3123,46 @@ top1: LYUpperCase(string->data); } PUTS(string->data); + if (t != context->unknown_tag) + PSRCSTOP(tag); + else + PSRCSTOP(badtag); } if (!psrc_view) /*don't waste time */ #endif { -#if !OPT1 - int i; - for (i = 0; i < context->current_tag->number_of_attributes; i++) - context->present[i] = NO; -#else + /* + ** Clear out attributes. + */ memset( (void*)context->present, 0 , sizeof(BOOL)* context->current_tag->number_of_attributes); -#endif } string->size = 0; context->current_attribute_number = INVALID; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { - if (c == '>') { - if (t != context->unknown_tag) - PSRCSTOP(tag); - else - PSRCSTOP(badtag); - PSRCSTART(abracket); - PUTC('>'); - PSRCSTOP(abracket); - context->state = S_text; + if (c == '>' || c == '<' || (c == '/' && context->slashedtag)) { + if (c != '<') { + PSRCSTART(abracket); + PUTC(c); + PSRCSTOP(abracket); + context->state = (c == '>') ? S_text : S_tagname_slash; + } else { + context->state = S_tag; + } } else { + if (!WHITE(c)) + PUTC(c); context->state = S_tag_gap; } } else #endif - if (c == '>') { + if (c == '>' || c == '<' || (c == '/' && context->slashedtag)) { if (context->current_tag->name) start_element(context); - context->state = S_text; + context->state = (c == '>') ? S_text : + (c == '<') ? S_tag : S_tagname_slash; } else { context->state = S_tag_gap; } @@ -2764,7 +3208,7 @@ top1: ** Try to handle identifier. - FM */ HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(sgmlspecial); PUTC('<'); @@ -2833,11 +3277,11 @@ top1: */ if (c == '>') { HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(comm); PUTC('<'); - PUTS(string->data); + PUTS_TR(string->data); PUTC('>'); PSRCSTOP(comm); } else @@ -2849,8 +3293,7 @@ top1: context->state = S_text; break; } - HTChunkPutc(string, c); - break; + goto S_comment_put_c; } if (!context->first_dash && c == '-') { HTChunkPutc(string, c); @@ -2875,16 +3318,16 @@ top1: ** Terminate and handle the comment. - FM */ HTChunkTerminate(string); -#ifdef USE_PSRC - if (psrc_view) { - PSRCSTART(comm); - PUTC('<'); - PUTS(string->data); - PUTC('>'); - PSRCSTOP(comm); - } else +#ifdef USE_PRETTYSRC + if (psrc_view) { + PSRCSTART(comm); + PUTC('<'); + PUTS_TR(string->data); + PUTC('>'); + PSRCSTOP(comm); + } else #endif - handle_comment(context); + handle_comment(context); string->size = 0; context->end_comment = FALSE; context->first_dash = FALSE; @@ -2892,9 +3335,32 @@ top1: break; } context->first_dash = FALSE; - if (context->end_comment && !isspace(c)) + if (context->end_comment && !isspace(UCH(c))) context->end_comment = FALSE; - HTChunkPutc(string, c); + + S_comment_put_c: + if (context->T.decode_utf8 && + *context->utf_buf) { + HTChunkPuts(string, context->utf_buf); + context->utf_buf_p = context->utf_buf; + *(context->utf_buf_p) = '\0'; + } else if (HTCJK == NOCJK && + (context->T.output_utf8 || + context->T.trans_from_uni)) { + if (clong == 0xfffd && saved_char_in && + HTPassEightBitRaw && + UCH(saved_char_in) >= + LYlowest_eightbit[context->outUCLYhndl]) { + HTChunkPutUtf8Char(string, + (0xf000 | UCH(saved_char_in))); + } else { + HTChunkPutUtf8Char(string, clong); + } + } else if (saved_char_in && context->T.use_raw_char_in) { + HTChunkPutc(string, saved_char_in); + } else { + HTChunkPutc(string, c); + } break; case S_doctype: /* Expecting DOCTYPE. - FM */ @@ -2911,7 +3377,7 @@ top1: } if (c == '>') { HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(sgmlspecial); PUTC('<'); @@ -2943,7 +3409,7 @@ top1: } if (!context->second_bracket && c == '>') { HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(sgmlspecial); PUTC('<'); @@ -2977,7 +3443,7 @@ top1: } if (context->end_comment && c == '>') { HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(sgmlspecial); PUTC('<'); @@ -3014,7 +3480,7 @@ top1: } if (context->end_comment && c == '>') { HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(sgmlspecial); PUTC('<'); @@ -3051,7 +3517,7 @@ top1: } if (context->end_comment && c == '>') { HTChunkTerminate(string); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(sgmlspecial); PUTC('<'); @@ -3075,17 +3541,13 @@ top1: if (WHITE(c)) break; /* Gap between attributes */ if (c == '>') { /* End of tag */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) #endif if (context->current_tag->name) start_element(context); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { - if (context->current_tag != context->unknown_tag) - PSRCSTOP(tag); - else - PSRCSTOP(badtag); PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); @@ -3103,7 +3565,7 @@ top1: if (WHITE(c) || (c == '>') || (c == '=')) { /* End of word */ HTChunkTerminate(string); handle_attribute_name(context, string->data); -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (!psrc_view) { #endif string->size = 0; @@ -3113,8 +3575,8 @@ top1: context->state = S_text; break; } -#ifdef USE_PSRC - } else { +#ifdef USE_PRETTYSRC + } else { PUTC(' '); if (context->current_attribute_number == INVALID) PSRCSTART(badattr); @@ -3127,18 +3589,12 @@ top1: LYUpperCase(string->data); } PUTS(string->data); - if (c == '=' || c == '>') { - if (c == '=' ) PUTC('='); - if (context->current_attribute_number == INVALID) - PSRCSTOP(badattr); - else - PSRCSTOP(attrib); - } + if (c == '=' ) PUTC('='); + if (context->current_attribute_number == INVALID) + PSRCSTOP(badattr); + else + PSRCSTOP(attrib); if (c == '>') { - if (context->current_tag != context->unknown_tag) - PSRCSTOP(tag); - else - PSRCSTOP(badtag); PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); @@ -3158,45 +3614,36 @@ top1: if (WHITE(c)) break; /* Gap after attribute */ if (c == '>') { /* End of tag */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { - if (context->current_attribute_number == INVALID) + if (context->current_attribute_number == INVALID) { PSRCSTOP(badattr); - else + } else { PSRCSTOP(attrib); - if (context->current_tag != context->unknown_tag) - PSRCSTOP(tag); - else - PSRCSTOP(badtag); + } PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); - } else + } else #endif if (context->current_tag->name) start_element(context); context->state = S_text; break; } else if (c == '=') { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PUTC('='); - if (context->current_attribute_number == INVALID) + if (context->current_attribute_number == INVALID) { PSRCSTOP(badattr); - else + } else { PSRCSTOP(attrib); + } } #endif context->state = S_equals; break; } -#ifdef USE_PSRC - /* we are here because this char seemed the beginning of attrname */ - if (psrc_view && context->current_attribute_number == INVALID) { - PSRCSTOP(badattr); - PUTC(' '); - } -#endif HTChunkPutc(string, c); context->state = S_attr; /* Get next attribute */ break; @@ -3205,13 +3652,9 @@ top1: if (WHITE(c)) break; /* Before attribute value */ if (c == '>') { /* End of tag */ - CTRACE(tfp, "SGML: found = but no value\n"); -#ifdef USE_PSRC + CTRACE((tfp, "SGML: found = but no value\n")); +#ifdef USE_PRETTYSRC if (psrc_view) { - if (context->current_tag != context->unknown_tag) - PSRCSTOP(tag); - else - PSRCSTOP(badtag); PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); @@ -3223,7 +3666,7 @@ top1: break; } else if (c == '\'') { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(attrval); PUTC(c); @@ -3233,7 +3676,7 @@ top1: break; } else if (c == '"') { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(attrval); PUTC(c); @@ -3242,31 +3685,31 @@ top1: context->state = S_dquoted; break; } -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) PSRCSTART(attrval); #endif context->state = S_value; - /* no break! fall through to S_value and proccess current `c` */ + /* no break! fall through to S_value and process current `c` */ case S_value: if (WHITE(c) || (c == '>')) { /* End of word */ HTChunkTerminate(string) ; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { /*PSRCSTART(attrval);*/ - if (cur_attr_is_name) { + if (attr_is_name) { HTStartAnchor(context->target, string->data, NULL); (*context->actions->end_element)( context->target, HTML_A, (char **)&context->include); - } else if (cur_attr_is_href) { + } else if (attr_is_href) { PSRCSTART(href); HTStartAnchor(context->target,NULL,string->data); } PUTS_TR(string->data); - if (cur_attr_is_href) { + if (attr_is_href) { (*context->actions->end_element)( context->target, HTML_A, @@ -3276,15 +3719,22 @@ top1: PSRCSTOP(attrval); } else #endif +#ifdef CJK_EX /* Quick hack. - JH7AYN */ + { char jis_buf[512]; + if (string->data[0] == '$') { + if (string->data[1] == 'B' || string->data[1] == '@') { + jis_buf[0] = '\033'; + strcpy(jis_buf + 1, string->data); + TO_EUC((CONST unsigned char *)jis_buf, (unsigned char *)string->data); + } + } + } +#endif handle_attribute_value(context, string->data); string->size = 0; if (c == '>') { /* End of tag */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { - if (context->current_tag != context->unknown_tag) - PSRCSTOP(tag); - else - PSRCSTOP(badtag); PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); @@ -3306,10 +3756,10 @@ top1: context->T.trans_from_uni)) { if (clong == 0xfffd && saved_char_in && HTPassEightBitRaw && - (unsigned char)saved_char_in >= + UCH(saved_char_in) >= LYlowest_eightbit[context->outUCLYhndl]) { HTChunkPutUtf8Char(string, - (0xf000 | (unsigned char)saved_char_in)); + (0xf000 | UCH(saved_char_in))); } else { HTChunkPutUtf8Char(string, clong); } @@ -3323,21 +3773,21 @@ top1: case S_squoted: /* Quoted attribute value */ if (c == '\'') { /* End of attribute value */ HTChunkTerminate(string) ; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { /*PSRCSTART(attrval);*/ - if (cur_attr_is_name) { + if (attr_is_name) { HTStartAnchor(context->target,string->data,NULL); (*context->actions->end_element)( context->target, HTML_A, (char **)&context->include); - } else if (cur_attr_is_href) { + } else if (attr_is_href) { PSRCSTART(href); HTStartAnchor(context->target,NULL,string->data); } PUTS_TR(string->data); - if (cur_attr_is_href) { + if (attr_is_href) { (*context->actions->end_element)( context->target, HTML_A, @@ -3368,10 +3818,10 @@ top1: context->T.trans_from_uni)) { if (clong == 0xfffd && saved_char_in && HTPassEightBitRaw && - (unsigned char)saved_char_in >= + UCH(saved_char_in) >= LYlowest_eightbit[context->outUCLYhndl]) { HTChunkPutUtf8Char(string, - (0xf000 | (unsigned char)saved_char_in)); + (0xf000 | UCH(saved_char_in))); } else { HTChunkPutUtf8Char(string, clong); } @@ -3387,21 +3837,21 @@ top1: (soft_dquotes && /* If emulating old Netscape bug, treat '>' */ c == '>')) { /* as a co-terminator of dquoted and tag */ HTChunkTerminate(string) ; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { /*PSRCSTART(attrval);*/ - if (cur_attr_is_name) { + if (attr_is_name) { HTStartAnchor(context->target,string->data,NULL); (*context->actions->end_element)( context->target, HTML_A, (char **)&context->include); - } else if (cur_attr_is_href) { + } else if (attr_is_href) { PSRCSTART(href); HTStartAnchor(context->target,NULL,string->data); } PUTS_TR(string->data); - if (cur_attr_is_href) { + if (attr_is_href) { (*context->actions->end_element)( context->target, HTML_A, @@ -3435,10 +3885,10 @@ top1: context->T.trans_from_uni)) { if (clong == 0xfffd && saved_char_in && HTPassEightBitRaw && - (unsigned char)saved_char_in >= + UCH(saved_char_in) >= LYlowest_eightbit[context->outUCLYhndl]) { HTChunkPutUtf8Char(string, - (0xf000 | (unsigned char)saved_char_in)); + (0xf000 | UCH(saved_char_in))); } else { HTChunkPutUtf8Char(string, clong); } @@ -3450,11 +3900,12 @@ top1: break; case S_end: /* </ */ - if (TOASCII(unsign_c) < 127 && isalnum((unsigned char)c)) { /* S/390 -- gil -- 1247 */ + if (TOASCII(unsign_c) < 127 && (string->size ? /* S/390 -- gil -- 1247 */ + IsNmChar(c) : IsNmStart(c))) { HTChunkPutc(string, c); } else { /* End of end tag name */ HTTag * t = 0; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC BOOL psrc_tagname_processed = FALSE; #endif @@ -3466,8 +3917,8 @@ top1: t = SGMLFindTag(dtd, string->data); } if (!t || t == context->unknown_tag) { - CTRACE(tfp, "Unknown end tag </%s>\n", string->data); -#ifdef USE_PSRC + CTRACE((tfp, "Unknown end tag </%s>\n", string->data)); +#ifdef USE_PRETTYSRC if (psrc_view) { PSRCSTART(abracket); PUTC('<'); @@ -3480,25 +3931,34 @@ top1: else LYUpperCase(string->data); } - PUTS(string->data); PSRCSTOP(badtag); - PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); + PUTS(string->data); + if (c != '>') { + PUTC(c); + } else { + PSRCSTOP(badtag); + PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); + } psrc_tagname_processed=TRUE; } } else if (psrc_view) { #endif } else { - BOOL tag_OK = (c == '>' || WHITE(c)); + BOOL tag_OK = (BOOL) (c == '>' || WHITE(c)); #if OPT - HTMLElement e = context->current_tag - context->dtd->tags; + HTMLElement e = TAGNUM_OF_TAGP(t); int branch = 2; /* it can be 0,1,2*/ #endif context->current_tag = t; + if (HAS_ALT_TAGNUM(TAGNUM_OF_TAGP(t)) && + context->element_stack && + ALT_TAGP(t) == context->element_stack->tag) + context->element_stack->tag = NORMAL_TAGP(context->element_stack->tag); #if OPT + if (tag_OK #ifdef EXTENDED_HTMLDTD - if (tag_OK && Old_DTD) { -#else - if (tag_OK) { + && Old_DTD #endif + ) { switch (e) { case HTML_DD: case HTML_DT: case HTML_LI: case HTML_LH : case HTML_TD: case HTML_TH: case HTML_TR: case HTML_THEAD: @@ -3511,6 +3971,8 @@ top1: case HTML_P: case HTML_STRONG: case HTML_TT: case HTML_U: branch = 1; break; + default: + break; } } #endif @@ -3524,9 +3986,10 @@ top1: } else #endif /* EXTENDED_HTMLDTD */ - -#if !OPT if (tag_OK && +#if OPT + (branch == 0) +#else (!strcasecomp(string->data, "DD") || !strcasecomp(string->data, "DT") || !strcasecomp(string->data, "LI") || @@ -3537,26 +4000,28 @@ top1: !strcasecomp(string->data, "THEAD") || !strcasecomp(string->data, "TFOOT") || !strcasecomp(string->data, "TBODY") || - !strcasecomp(string->data, "COLGROUP"))) { -#else - if (tag_OK && branch == 0) { + !strcasecomp(string->data, "COLGROUP")) #endif + ) { /* ** Don't treat these end tags as invalid, ** nor act on them. - FM */ - CTRACE(tfp, "SGML: `</%s%c' found! ***Ignoring it.\n", - string->data, c); + CTRACE((tfp, "SGML: `</%s%c' found! Ignoring it.\n", + string->data, c)); string->size = 0; context->current_attribute_number = INVALID; if (c != '>') { context->state = S_junk_tag; } else { + context->current_tag = NULL; context->state = S_text; } break; -#if !OPT } else if (tag_OK && +#if OPT + (branch == 1) +#else (!strcasecomp(string->data, "A") || !strcasecomp(string->data, "B") || !strcasecomp(string->data, "BLINK") || @@ -3568,10 +4033,9 @@ top1: !strcasecomp(string->data, "P") || !strcasecomp(string->data, "STRONG") || !strcasecomp(string->data, "TT") || - !strcasecomp(string->data, "U"))) { -#else - } else if (tag_OK && branch == 1) { + !strcasecomp(string->data, "U")) #endif + ) { /* ** Handle end tags for container elements declared ** as SGML_EMPTY to prevent "expected tag substitution" @@ -3587,22 +4051,25 @@ top1: /* ** It is not at FORM end tag, so ignore it. - FM */ - CTRACE(tfp, "SGML: ***Ignoring end tag </%s> in SELECT block.\n", - string->data); + CTRACE((tfp, "SGML: ***Ignoring end tag </%s> in SELECT block.\n", + string->data)); } else { /* ** End the SELECT block and then ** handle the FORM end tag. - FM */ - CTRACE(tfp, "SGML: ***Faking SELECT end tag before </%s> end tag.\n", - string->data); + CTRACE((tfp, "SGML: ***Faking SELECT end tag before </%s> end tag.\n", + string->data)); end_element(context, SGMLFindTag(context->dtd, "SELECT")); - CTRACE(tfp, "SGML: End </%s>\n", string->data); + CTRACE((tfp, "SGML: End </%s>\n", string->data)); +#ifdef USE_PRETTYSRC + if (!psrc_view) /* Don't actually call if viewing psrc - kw */ +#endif (*context->actions->end_element) (context->target, - (context->current_tag - context->dtd->tags), + TAGNUM_OF_TAGP(context->current_tag), (char **)&context->include); } } else if (!strcasecomp(string->data, "P")) { @@ -3610,8 +4077,8 @@ top1: ** Treat a P end tag like a P start tag (Ugh, ** what a hack! 8-). - FM */ - CTRACE(tfp, "SGML: `</%s%c' found! ***Treating as '<%s%c'.\n", - string->data, c, string->data, c); + CTRACE((tfp, "SGML: `</%s%c' found! Treating as '<%s%c'.\n", + string->data, c, string->data, c)); { int i; for (i = 0; @@ -3623,11 +4090,14 @@ top1: if (context->current_tag->name) start_element(context); } else { - CTRACE(tfp, "SGML: End </%s>\n", string->data); + CTRACE((tfp, "SGML: End </%s>\n", string->data)); +#ifdef USE_PRETTYSRC + if (!psrc_view) /* Don't actually call if viewing psrc - kw */ +#endif (*context->actions->end_element) (context->target, - (context->current_tag - context->dtd->tags), + TAGNUM_OF_TAGP(context->current_tag), (char **)&context->include); } string->size = 0; @@ -3635,6 +4105,7 @@ top1: if (c != '>') { context->state = S_junk_tag; } else { + context->current_tag = NULL; context->state = S_text; } break; @@ -3646,7 +4117,7 @@ top1: } } -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view && !psrc_tagname_processed) { PSRCSTART(abracket); PUTC('<'); @@ -3660,9 +4131,10 @@ top1: LYUpperCase(string->data); } PUTS(string->data); PSRCSTOP(tag); - if ( c != '>' ) + if ( c != '>' ) { PSRCSTART(badtag); - else { + PUTC(c); + } else { PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); @@ -3674,9 +4146,10 @@ top1: context->current_attribute_number = INVALID; if (c != '>') { if (!WHITE(c)) - CTRACE(tfp,"SGML: `</%s%c' found!\n", string->data, c); + CTRACE((tfp,"SGML: `</%s%c' found!\n", string->data, c)); context->state = S_junk_tag; } else { + context->current_tag = NULL; context->state = S_text; } } @@ -3728,6 +4201,8 @@ top1: context->state = S_esc; } PUTC(c); + if (c < 32) + context->state = S_text; break; case S_esc_sq: /* Expecting '$'or '(' following CJK ESC. */ @@ -3825,32 +4300,61 @@ top1: break; case S_junk_tag: + case S_junk_pi: if (c == '>') { -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { - PSRCSTOP(badtag); + if (context->state == S_junk_tag) { + PSRCSTOP(badtag); + } PSRCSTART(abracket); PUTC('>'); PSRCSTOP(abracket); - seen_letter_in_junk_tag = FALSE; + context->seen_nonwhite_in_junk_tag = FALSE; } #endif + context->current_tag = NULL; context->state = S_text; } -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC else if (psrc_view) { /*pack spaces until first non-space is seen*/ - if (!seen_letter_in_junk_tag) { + if (!context->seen_nonwhite_in_junk_tag) { if (!WHITE(c)) { - seen_letter_in_junk_tag = TRUE; + context->seen_nonwhite_in_junk_tag = TRUE; PUTC(c); - }; + } } else PUTC(c); - }; + } #endif } /* switch on context->state */ + CTRACE2(TRACE_SGML, (tfp, "SGML after %s|%.*s|%c\n", + state_name(context->state), + string->size, + string->data != NULL ? string->data : "", UCH(c))); + +after_switch: + /* + ** Check whether an external function has added + ** anything to the include buffer. If so, move the + ** new stuff to the beginning of active_include. - kw + */ + if (context->include != NULL) { + if (context->include[0] == '\0') { + FREE(context->include); + } else { + if (context->active_include && + context->active_include[context->include_index] != '\0') + StrAllocCat(context->include, + context->active_include + context->include_index); + FREE(context->active_include); + context->active_include = context->include; + context->include_index = 0; + context->include = NULL; + } + } /* ** Check whether we've added anything to the recover buffer. - FM @@ -3867,17 +4371,42 @@ top1: } /* - ** Check whether an external function has added - ** anything to the include buffer. - FM + ** Check whether an external function had added + ** anything to the include buffer; it should now be + ** in active_include. - FM / kw */ - if (context->include != NULL) { - if (context->include[context->include_index] == '\0') { - FREE(context->include); + if (context->active_include != NULL) { + if (context->active_include[context->include_index] == '\0') { + FREE(context->active_include); context->include_index = 0; } else { - c = context->include[context->include_index]; - context->include_index++; - goto top; + if (context->current_tag_charset == UTF8 || + context->T.trans_from_uni) { + /* + * If it looks like we would have fed UTF-8 to the + * next processing stage, assume that whatever we were + * fed back is in UTF-8 form, too. This won't be always + * true for all uses of the include buffer, but it's a + * start. - kw + */ + char *puni = context->active_include + context->include_index; + c = *puni; + clong = UCGetUniFromUtf8String(&puni); + if (clong < 256 && clong >= 0) { + c = ((char)(clong & 0xff)); + } + saved_char_in = '\0'; + context->include_index = puni - context->active_include + 1; + goto top1; + } else { + /* + * Otherwise assume no UTF-8 - do charset-naive processing + * and hope for the best. - kw + */ + c = context->active_include[context->include_index]; + context->include_index++; + goto top; + } } } @@ -3961,9 +4490,13 @@ PUBLIC HTStream* SGML_new ARGS3( context->actions = (CONST HTStructuredClass*)(((HTStream*)target)->isa); /* Ugh: no OO */ context->unknown_tag = &HTTag_unrecognized; +/* context->extra_tags = dtd->tags + dtd->number_of_tags; */ + context->current_tag = context->slashedtag = NULL; context->state = S_text; + context->kanji_buf = '\0'; context->element_stack = 0; /* empty */ context->inSELECT = FALSE; + context->no_lynx_specialcodes = NO; /* special codes normally generated */ #ifdef CALLERDATA context->callerData = (void*) callerData; #endif /* CALLERDATA */ @@ -4001,20 +4534,22 @@ PUBLIC HTStream* SGML_new ARGS3( context->recover = NULL; context->recover_index = 0; context->include = NULL; + context->active_include = NULL; context->include_index = 0; context->url = NULL; context->csi = NULL; context->csi_index = 0; -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC if (psrc_view) { psrc_view = FALSE; - SGML_string(context, "<HTML><HEAD><TITLE>source</TITLE></HEAD>" - "<BODY><PRE>") ; + mark_htext_as_source = TRUE; + SGML_string(context, + "<HTML><HEAD><TITLE>source</TITLE></HEAD><BODY><PRE>"); psrc_view = TRUE; psrc_convert_string = FALSE; sgml_in_psrc_was_initialized = TRUE; - seen_letter_in_junk_tag = FALSE; + context->seen_nonwhite_in_junk_tag = FALSE; } #endif @@ -4132,20 +4667,35 @@ PUBLIC void JISx0201TO0208_EUC ARGS4( } } +PRIVATE int IS_SJIS_STR ARGS1(CONST unsigned char *, str) +{ + CONST unsigned char *s; + unsigned char ch; + int is_sjis = 0; + + s = str; + while ((ch = *s++) != '\0') { + if (ch & 0x80) + if (IS_SJIS(ch, *s, is_sjis)) + return 1; + } + return 0; +} + PUBLIC unsigned char * SJIS_TO_JIS1 ARGS3( register unsigned char, HI, register unsigned char, LO, register unsigned char *, JCODE) { - HI -= (HI <= 0x9F) ? 0x71 : 0xB1; - HI = (HI << 1) + 1; + HI -= UCH((HI <= 0x9F) ? 0x71 : 0xB1); + HI = UCH((HI << 1) + 1); if (0x7F < LO) LO--; if (0x9E <= LO) { - LO -= 0x7D; + LO -= UCH(0x7D); HI++; } else { - LO -= 0x1F; + LO -= UCH(0x1F); } JCODE[0] = HI; JCODE[1] = LO; @@ -4158,15 +4708,15 @@ PUBLIC unsigned char * JIS_TO_SJIS1 ARGS3( register unsigned char *, SJCODE) { if (HI & 1) - LO += 0x1F; + LO += UCH(0x1F); else - LO += 0x7D; + LO += UCH(0x7D); if (0x7F <= LO) LO++; - HI = ((HI - 0x21) >> 1) + 0x81; + HI = UCH(((HI - 0x21) >> 1) + 0x81); if (0x9F < HI) - HI += 0x40; + HI += UCH(0x40); SJCODE[0] = HI; SJCODE[1] = LO; return SJCODE; @@ -4177,8 +4727,9 @@ PUBLIC unsigned char * EUC_TO_SJIS1 ARGS3( unsigned char, LO, register unsigned char *, SJCODE) { - if (HI == 0x8E) JISx0201TO0208_EUC(HI, LO, &HI, &LO); - JIS_TO_SJIS1(HI&0x7F, LO&0x7F, SJCODE); + if (HI == 0x8E) + JISx0201TO0208_EUC(HI, LO, &HI, &LO); + JIS_TO_SJIS1(UCH(HI & 0x7F), UCH(LO & 0x7F), SJCODE); return SJCODE; } @@ -4189,8 +4740,8 @@ PUBLIC void JISx0201TO0208_SJIS ARGS3( { unsigned char SJCODE[2]; - JISx0201TO0208_EUC(216, I, OHI, OLO); - JIS_TO_SJIS1(*OHI&0x7F, *OLO&0x7F, SJCODE); + JISx0201TO0208_EUC(0x8E, I, OHI, OLO); + JIS_TO_SJIS1(UCH(*OHI & 0x7F), UCH(*OLO & 0x7F), SJCODE); *OHI = SJCODE[0]; *OLO = SJCODE[1]; } @@ -4213,17 +4764,17 @@ PUBLIC unsigned char * SJIS_TO_EUC ARGS2( register unsigned char hi, lo, *sp, *dp; register int in_sjis = 0; - for (sp = src, dp = dst; (0 != (hi = sp[0]));) { + in_sjis = IS_SJIS_STR(src); + for (sp = src, dp = dst; (hi = sp[0]) != '\0';) { lo = sp[1]; if (TREAT_SJIS && IS_SJIS(hi, lo, in_sjis)) { - SJIS_TO_JIS1(hi,lo,dp); + SJIS_TO_JIS1(hi, lo, dp); dp[0] |= 0x80; dp[1] |= 0x80; dp += 2; sp += 2; - } else { + } else *dp++ = *sp++; - } } *dp = 0; return dst; @@ -4238,7 +4789,7 @@ PUBLIC unsigned char * EUC_TO_SJIS ARGS2( for (sp = src, dp = dst; *sp;) { if (*sp & 0x80) { if (sp[1] && (sp[1] & 0x80)) { - JIS_TO_SJIS1(sp[0]&0x7F, sp[1]&0x7F, dp); + JIS_TO_SJIS1(UCH(sp[0] & 0x7F), UCH(sp[1] & 0x7F), dp); dp += 2; sp += 2; } else { @@ -4252,7 +4803,9 @@ PUBLIC unsigned char * EUC_TO_SJIS ARGS2( return dst; } -PUBLIC unsigned char * EUC_TO_JIS ARGS4( +#define Strcpy(a,b) (strcpy((char*)a,(CONST char*)b),&a[strlen((CONST char*)a)]) + +PUBLIC unsigned char *EUC_TO_JIS ARGS4( unsigned char *, src, unsigned char *, dst, CONST char *, toK, @@ -4262,87 +4815,151 @@ PUBLIC unsigned char * EUC_TO_JIS ARGS4( register unsigned char cch; register unsigned char *sp = src; register unsigned char *dp = dst; - register int i; + int is_JIS = 0; - while (0 != (cch = *sp++)) { + while ((cch = *sp++) != '\0') { if (cch & 0x80) { + if (!IS_EUC(cch, *sp)) { + if (cch == 0xA0 && is_JIS) /* ignore NBSP */ + continue; + is_JIS++; + *dp++ = cch; + continue; + } if (!kana_mode) { - kana_mode = ~kana_mode; - for (i = 0; toK[i]; i++) { - *dp++ = (unsigned char)toK[i]; - } + kana_mode = UCH(~kana_mode); + dp = Strcpy(dp, toK); } if (*sp & 0x80) { - *dp++ = cch & ~0x80; - *dp++ = *sp++ & ~0x80; + *dp++ = UCH(cch & ~0x80); + *dp++ = UCH(*sp++ & ~0x80); } } else { if (kana_mode) { - kana_mode = ~kana_mode; - for (i = 0; toA[i]; i++) { - *dp++ = (unsigned char)toA[i]; - *dp = '\0'; - } + kana_mode = UCH(~kana_mode); + dp = Strcpy(dp, toA); } *dp++ = cch; } } - if (kana_mode) { - for (i = 0; toA[i]; i++) { - *dp++ = (unsigned char)toA[i]; - } - } + if (kana_mode) + dp = Strcpy(dp, toA); if (dp) *dp = 0; return dst; } -PUBLIC unsigned char * TO_EUC ARGS2( +#define IS_JIS7(c1,c2) (0x20<(c1)&&(c1)<0x7F && 0x20<(c2)&&(c2)<0x7F) +#define SO ('N'-0x40) +#define SI ('O'-0x40) + +PUBLIC int repair_JIS = 0; + +PRIVATE CONST unsigned char *repairJIStoEUC ARGS2( + CONST unsigned char *, src, + unsigned char **, dstp) +{ + CONST unsigned char *s; + unsigned char *d, ch1, ch2; + + d = *dstp; + s = src; + while ((ch1 = s[0]) && (ch2 = s[1])) { + s += 2; + if (ch1 == '(') + if (ch2 == 'B' || ch2 == 'J') { + *dstp = d; + return s; + } + if (!IS_JIS7(ch1, ch2)) + return 0; + + *d++ = UCH(0x80 | ch1); + *d++ = UCH(0x80 | ch2); + } + return 0; +} + +PUBLIC unsigned char *TO_EUC ARGS2( CONST unsigned char *, jis, unsigned char *, euc) { register CONST unsigned char *s; - register unsigned char *d, c, jis_stat; + register unsigned char c, jis_stat; + unsigned char *d; register int to1B, to2B; register int in_sjis = 0; + static int nje; + int n8bits; + int is_JIS; + nje++; + n8bits = 0; s = jis; d = euc; jis_stat = 0; to2B = TO_2BCODE; to1B = TO_1BCODE; - - while (0 != (c = *s++)) { + in_sjis = IS_SJIS_STR(jis); + is_JIS = 0; + + while ((c = *s++) != '\0') { + if (c == 0x80) + continue; /* ignore it */ + if (c == 0xA0 && is_JIS) + continue; /* ignore Non-breaking space */ + + if (c == to2B && jis_stat == 0 && repair_JIS) { + if (*s == 'B' || *s == '@') { + CONST unsigned char *ts; + if ((ts = repairJIStoEUC(s + 1, &d)) != NULL) { + s = ts; + continue; + } + } + } if (c == ESC) { if (*s == to2B) { - if ((s[1] == 'B') || (s[1] == '@') || (s[1] == 'A')) { + if ((s[1] == 'B') || (s[1] == '@')) { jis_stat = 0x80; s += 2; - continue; - } else if ((s[1] == '(') && s[2] && (s[2] == 'C')) { - jis_stat = 0x80; - s += 3; + is_JIS++; continue; } - } else { - if (*s == to1B) { - if ((s[1]=='B') || (s[1]=='J') || - (s[1]=='H') || (s[1]=='T')) { - jis_stat = 0; - s += 2; - continue; - } + jis_stat = 0; + } else if (*s == to1B) { + jis_stat = 0; + if ((s[1] == 'B') || (s[1] == 'J') || (s[1] == 'H')) { + s += 2; + continue; } + } else if (*s == ',') { /* MULE */ + jis_stat = 0; } } - if (IS_SJIS(c,*s,in_sjis)) { + if (c & 0x80) + n8bits++; + + if (IS_SJIS(c, *s, in_sjis)) { SJIS_TO_EUC1(c, *s, d); d += 2; s++; + is_JIS++; + } else if (jis_stat) { + if (c <= 0x20 || 0x7F <= c) { + *d++ = c; + if (c == '\n') + jis_stat = 0; + } else { + if (IS_JIS7(c, *s)) { + *d++ = jis_stat | c; + *d++ = jis_stat | *s++; + } else + *d++ = c; + } } else { - if (jis_stat && (0x20 < c)) { - *d++ = jis_stat | c; + if (n8bits == 0 && (c == SI || c == SO)) { } else { *d++ = c; } @@ -4352,22 +4969,47 @@ PUBLIC unsigned char * TO_EUC ARGS2( return euc; } +#define non94(ch) ((ch) <= 0x20 || (ch) == 0x7F) + +PRIVATE int is_EUC_JP ARGS1(unsigned char *, euc) +{ + unsigned char *cp; + int ch1, ch2; + + for (cp = euc; (ch1 = *cp) != '\0'; cp++) { + if (ch1 & 0x80) { + ch2 = cp[1] & 0xFF; + if ((ch2 & 0x80) == 0) { + /* sv1log("NOT_EUC1[%x][%x]\n",ch1,ch2); */ + return 0; + } + if (non94(ch1 & 0x7F) || non94(ch2 & 0x7F)) { + /* sv1log("NOT_EUC2[%x][%x]\n",ch1,ch2); */ + return 0; + } + cp++; + } + } + return 1; +} + PUBLIC void TO_SJIS ARGS2( CONST unsigned char *, any, unsigned char *, sjis) { unsigned char *euc; - if (!any || !sjis) - return; - - euc = (unsigned char*)malloc(strlen((CONST char *)any)+1); - if (euc == NULL) + euc = malloc(strlen((CONST char *) any) + 1); +#ifdef CJK_EX + if (!euc) outofmem(__FILE__, "TO_SJIS"); - +#endif TO_EUC(any, euc); - EUC_TO_SJIS(euc, sjis); - FREE(euc); + if (is_EUC_JP(euc)) + EUC_TO_SJIS(euc, sjis); + else + strcpy((char *) sjis, (CONST char *) any); + free(euc); } PUBLIC void TO_JIS ARGS2( @@ -4376,14 +5018,18 @@ PUBLIC void TO_JIS ARGS2( { unsigned char *euc; - if (!any || !jis) + if (any[0] == 0) { + jis[0] = 0; return; - - euc = (unsigned char*)malloc(strlen((CONST char *)any)+1); - if (euc == NULL) + } + euc = malloc(strlen((CONST char *) any) + 1); +#ifdef CJK_EX + if (!euc) outofmem(__FILE__, "TO_JIS"); - +#endif TO_EUC(any, euc); + is_EUC_JP(euc); EUC_TO_JIS(euc, jis, TO_KANJI, TO_ASCII); - FREE(euc); + + free(euc); } diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.h index 9ae3ae365dd..315b5ee1059 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/SGML.h @@ -19,28 +19,36 @@ #include <HTStream.h> #include <HTAnchor.h> +#include <LYJustify.h> /* SGML content types */ -typedef enum _SGMLContent { +typedef enum { SGML_EMPTY, /* No content. */ SGML_LITTERAL, /* Literal character data. Recognize exact close tag only. Old www server compatibility only! Not SGML */ - SGML_CDATA, /* Character data. Recognize </ only. */ - SGML_RCDATA, /* Replaceable character data. Recognize </ and &ref; */ + SGML_CDATA, /* Character data. Recognize </ only. + (But we treat it just as SGML_LITTERAL.) */ + SGML_SCRIPT, /* Like CDATA, but allow it to be a comment */ + SGML_RCDATA, /* Replaceable character data. Should recognize </ and &ref; + (but we treat it like SGML_MIXED for old times' sake). */ SGML_MIXED, /* Elements and parsed character data. Recognize all markup. */ - SGML_ELEMENT, /* Any data found will be returned as an error. */ - SGML_PCDATA /* Added by KW. */ + SGML_ELEMENT, /* Any data found should be regarded as an error. + (But we treat it just like SGML_MIXED.) */ + SGML_PCDATA /* Should contain no elements but &ref; is parsed. + (We treat it like SGML_CDATA wrt. contained tags + i.e. pass them on literally, i.e. like we should + treat SGML_RCDATA) (added by KW). */ } SGMLContent; typedef struct { char * name; /* The (constant) name of the attribute */ -#ifdef USE_PSRC +#ifdef USE_PRETTYSRC char type; /* code of the type of the attribute. Code values are in HTMLDTD.h */ #endif @@ -69,7 +77,7 @@ typedef int TagClass; text directly */ /* insertions */ #define Tgc_BRlike 0x01000 /* BR,IMG,TAB allowed in any text */ -#define Tgc_APPLETlike 0x02000 /* APPLET,OBJECT,EMBED,SCRIPT */ +#define Tgc_APPLETlike 0x02000 /* APPLET,OBJECT,EMBED,SCRIPT;BUTTON */ #define Tgc_HRlike 0x04000 /* HR,MARQUEE can contain all kinds of things and/or are not allowed (?) in running text */ #define Tgc_MAPlike 0x08000 /* MAP,AREA some specials that never contain @@ -89,9 +97,17 @@ typedef int TagFlags; #define Tgf_mafse 0x00004 /* Make Attribute-Free Start-tag End instead (if found invalid) */ #define Tgf_strict 0x00008 /* Ignore contained invalid elements, - don't pass them on */ + don't pass them on; or other variant + handling for some content types */ #define Tgf_nreie 0x00010 /* Not Really Empty If Empty, used by color style code */ +#define Tgf_frecyc 0x00020 /* Pass element content on in a form that + allows recycling, i.e. don't translate to + output (display) character set yet (treat + content similar to attribute values) */ +#define Tgf_nolyspcl 0x00040 /* Don't generate lynx special characters + for soft hyphen and various spaces (nbsp, + ensp,..) */ /* A tag structure describes an SGML element. ** ----------------------------------------- @@ -113,6 +129,9 @@ struct _tag{ #ifdef USE_COLOR_STYLE int name_len; /* The length of the name */ #endif +#ifdef EXP_JUSTIFY_ELTS + BOOL can_justify; /* justification allowed?*/ +#endif attr * attributes; /* The list of acceptable attributes */ int number_of_attributes; /* Number of possible attributes */ SGMLContent contents; /* End only on end tag @@ */ @@ -196,7 +215,7 @@ typedef struct _HTStructuredClass{ CONST char * str, int len)); - void (*start_element) PARAMS(( + int (*start_element) PARAMS(( HTStructured* me, int element_number, CONST BOOL* attribute_present, @@ -204,7 +223,7 @@ typedef struct _HTStructuredClass{ int charset, char ** include)); - void (*end_element) PARAMS(( + int (*end_element) PARAMS(( HTStructured* me, int element_number, char ** include)); @@ -213,7 +232,7 @@ typedef struct _HTStructuredClass{ HTStructured* me, int entity_number)); -}HTStructuredClass; +} HTStructuredClass; /* Equivalents to the following functions possibly could be generalised diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/UCAux.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/UCAux.h index 50cdf9baedd..44c9e881d01 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/UCAux.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/UCAux.h @@ -34,7 +34,7 @@ typedef struct _UCTransParams UCTransParams; #endif /* UCDEFS_H */ extern void UCSetTransParams PARAMS(( - UCTransParams * pT, + UCTransParams * pT, int cs_in, CONST LYUCcharset * p_in, int cs_out, @@ -66,9 +66,11 @@ extern BOOL UCPutUtf8_charstring PARAMS(( HTStream * target, putc_func_t * actions, UCode_t code)); - + extern BOOL UCConvertUniToUtf8 PARAMS(( UCode_t code, char * buffer)); +extern UCode_t UCGetUniFromUtf8String PARAMS((char ** ppuni)); + #endif /* UCAUX_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/UCDefs.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/UCDefs.h index 53c3a807a5e..19007f75aa1 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/UCDefs.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/UCDefs.h @@ -12,7 +12,8 @@ typedef struct _LYUCcharset { CONST char * MIMEname; int enc; - int codepage; /* IBM OS/2 specific number */ + int codepage; /* if positive, an IBM OS/2 specific number; + if negative, flag for no table translation */ /* parameters below are not used by chartrans mechanism, */ /* they describe some relationships against built-in Latin1 charset...*/ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/UCMap.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/UCMap.h index 80ee73e7092..b412dc1e58a 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/UCMap.h +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/UCMap.h @@ -51,6 +51,9 @@ extern int LATIN1; /* UCGetLYhndl_byMIME("iso-8859-1") */ extern int US_ASCII; /* UCGetLYhndl_byMIME("us-ascii") */ extern int UTF8; /* UCGetLYhndl_byMIME("utf-8") */ +#undef TRANSPARENT /* defined on Solaris in <sys/stream.h> */ +extern int TRANSPARENT; /* UCGetLYhndl_byMIME("x-transparent") */ + /* In general, Lynx translates letters from document charset to display charset. If document charset is not specified or not recognized by Lynx, we fall back diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/makefile.in b/gnu/usr.bin/lynx/WWW/Library/Implementation/makefile.in index 19def689e85..26b117514e1 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/makefile.in +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/makefile.in @@ -19,6 +19,7 @@ LYFLAGS = # FIXME: set in parent makefile CC = @CC@ DEFS = @DEFS@ CPPFLAGS = @CPPFLAGS@ +_O = .o INTLDIR_CPPFLAGS= @INTLDIR_CPPFLAGS@ -I$(top_srcdir)/intl @@ -50,7 +51,7 @@ VC = 2.14 # (originally CommonMakefile) # If this env var is set to something else Some makes will use that instead -SHELL = /bin/sh +SHELL = @CONFIG_SHELL@ RANLIB = @RANLIB@ @@ -78,7 +79,7 @@ LOB = . # uncomment these and fill in WAISINC for adding direct wais access # to Lynx. #HTWAIS_c = $(CMN)/HTWAIS.c -#HTWAIS_o = $(LOB)/HTWAIS.o +#HTWAIS_o = $(LOB)/HTWAIS$(_O) #WAIS = YES #WAISINC = -I../../../../freeWAIS-0.202/ir #WAISCFLAGS = -DDIRECT_WAIS @@ -91,21 +92,21 @@ CFLAGS2 = $(CFLAGS) $(LYFLAGS) $(WAISCFLAGS) -I$(CMN) -DXMOSAIC_HACK -DACCESS_AU COMPILE = $(ECHO) $(CC) $(CFLAGS2) -c -COMMON = $(LOB)/HTParse.o $(LOB)/HTAccess.o $(LOB)/HTTP.o \ - $(LOB)/HTFile.o $(LOB)/HTBTree.o $(LOB)/HTFTP.o $(LOB)/HTTCP.o \ - $(LOB)/SGML.o $(LOB)/HTMLDTD.o $(LOB)/HTChunk.o \ - $(LOB)/HTPlain.o \ - $(LOB)/HTMLGen.o \ - $(LOB)/HTAtom.o $(LOB)/HTAnchor.o $(LOB)/HTStyle.o \ - $(LOB)/HTList.o $(LOB)/HTString.o \ - $(LOB)/HTRules.o $(LOB)/HTFormat.o $(LOB)/HTMIME.o \ - $(LOB)/HTNews.o $(LOB)/HTGopher.o \ - $(LOB)/HTTelnet.o $(LOB)/HTFinger.o $(LOB)/HTWSRC.o $(HTWAIS_o) \ - $(LOB)/HTAAUtil.o $(LOB)/HTAABrow.o \ - $(LOB)/HTGroup.o \ - $(LOB)/HTAAProt.o \ - $(LOB)/HTAssoc.o $(LOB)/HTLex.o $(LOB)/HTUU.o \ - $(LOB)/HTDOS.o +COMMON = $(LOB)/HTParse$(_O) $(LOB)/HTAccess$(_O) $(LOB)/HTTP$(_O) \ + $(LOB)/HTFile$(_O) $(LOB)/HTBTree$(_O) $(LOB)/HTFTP$(_O) $(LOB)/HTTCP$(_O) \ + $(LOB)/SGML$(_O) $(LOB)/HTMLDTD$(_O) $(LOB)/HTChunk$(_O) \ + $(LOB)/HTPlain$(_O) \ + $(LOB)/HTMLGen$(_O) \ + $(LOB)/HTAtom$(_O) $(LOB)/HTAnchor$(_O) $(LOB)/HTStyle$(_O) \ + $(LOB)/HTList$(_O) $(LOB)/HTString$(_O) \ + $(LOB)/HTRules$(_O) $(LOB)/HTFormat$(_O) $(LOB)/HTMIME$(_O) \ + $(LOB)/HTNews$(_O) $(LOB)/HTGopher$(_O) \ + $(LOB)/HTTelnet$(_O) $(LOB)/HTFinger$(_O) $(LOB)/HTWSRC$(_O) $(HTWAIS_o) \ + $(LOB)/HTAAUtil$(_O) $(LOB)/HTAABrow$(_O) \ + $(LOB)/HTGroup$(_O) \ + $(LOB)/HTAAProt$(_O) \ + $(LOB)/HTAssoc$(_O) $(LOB)/HTLex$(_O) $(LOB)/HTUU$(_O) \ + $(LOB)/HTDOS$(_O) CFILES = $(CMN)HTParse.c $(CMN)HTAccess.c $(CMN)HTTP.c $(CMN)HTFile.c \ $(CMN)HTBTree.c \ @@ -135,7 +136,7 @@ HFILES = $(CMN)HTParse.h $(CMN)HTAccess.h $(CMN)HTTP.h $(CMN)HTFile.h \ $(CMN)HTFormat.h $(CMN)HTInit.h \ $(CMN)HTMIME.h $(CMN)HTNews.h \ $(CMN)HTGopher.h \ - $(CMN)HTUtils.h $(CMN)tcp.h $(CMN)HText.h \ + $(CMN)HTUtils.h $(CMN)www_tcp.h $(CMN)HText.h \ $(CMN)HTTelnet.h $(CMN)HTFinger.h \ $(CMN)HTWAIS.h $(CMN)HTWSRC.h \ $(CMN)HTAABrow.h \ @@ -148,9 +149,9 @@ all : $(LOB)/libwww.a lint: $(LINT) $(LINTOPTS) $(CPPOPTS) $(srcdir)/../Implementation/*.c > ../../../lint.libwww -.SUFFIXES: .i .h .html +.SUFFIXES: $(_O) .i .h .html -.c.o: +.c$(_O): @RULE_CC@ @ECHO_CC@$(CC) $(CPPOPTS) $(CFLAGS) -c $(srcdir)/$*.c @@ -171,135 +172,136 @@ $(LOB)/libwww.a : $(COMMON) # Clean up everything generatable except final products clean : - rm $(LOB)/*.o + rm -f core *.core *.leaks *.[oi] *.bak tags TAGS + rm $(LOB)/*$(_O) # Common code # ----------- -$(LOB)/HTList.o : $(OE) $(CMN)HTList.c $(CMN)HTUtils.h $(CMN)HTList.h +$(LOB)/HTList$(_O) : $(OE) $(CMN)HTList.c $(CMN)HTUtils.h $(CMN)HTList.h $(COMPILE) $(CMN)HTList.c -$(LOB)/HTAnchor.o : $(OE) $(CMN)HTAnchor.c $(CMN)HTUtils.h $(CMN)HTList.h +$(LOB)/HTAnchor$(_O) : $(OE) $(CMN)HTAnchor.c $(CMN)HTUtils.h $(CMN)HTList.h $(COMPILE) $(CMN)HTAnchor.c -$(LOB)/HTFormat.o : $(OE) $(CMN)HTFormat.c $(CMN)HTUtils.h $(CMN)HTList.h +$(LOB)/HTFormat$(_O) : $(OE) $(CMN)HTFormat.c $(CMN)HTUtils.h $(CMN)HTList.h $(COMPILE) $(CMN)HTFormat.c -$(LOB)/HTMIME.o : $(OE) $(CMN)HTMIME.c $(CMN)HTUtils.h $(CMN)HTList.h +$(LOB)/HTMIME$(_O) : $(OE) $(CMN)HTMIME.c $(CMN)HTUtils.h $(CMN)HTList.h $(COMPILE) $(CMN)HTMIME.c -$(LOB)/HTNews.o : $(OE) $(CMN)HTNews.c $(CMN)HTUtils.h $(CMN)HTList.h\ +$(LOB)/HTNews$(_O) : $(OE) $(CMN)HTNews.c $(CMN)HTUtils.h $(CMN)HTList.h\ $(CMN)HTMLDTD.h $(COMPILE) $(CMN)HTNews.c -$(LOB)/HTGopher.o : $(OE) $(CMN)HTGopher.c $(CMN)HTUtils.h $(CMN)HTList.h \ +$(LOB)/HTGopher$(_O) : $(OE) $(CMN)HTGopher.c $(CMN)HTUtils.h $(CMN)HTList.h \ $(CMN)HTMLDTD.h $(COMPILE) $(CMN)HTGopher.c -$(LOB)/HTTelnet.o : $(OE) $(CMN)HTTelnet.c $(CMN)HTUtils.h $(CMN)HTTelnet.h $(CMN)../../../userdefs.h +$(LOB)/HTTelnet$(_O) : $(OE) $(CMN)HTTelnet.c $(CMN)HTUtils.h $(CMN)HTTelnet.h $(CMN)../../../userdefs.h $(COMPILE) $(CMN)HTTelnet.c -$(LOB)/HTFinger.o : $(OE) $(CMN)HTFinger.c $(CMN)HTUtils.h $(CMN)HTList.h \ +$(LOB)/HTFinger$(_O) : $(OE) $(CMN)HTFinger.c $(CMN)HTUtils.h $(CMN)HTList.h \ $(CMN)HTMLDTD.h $(COMPILE) $(CMN)HTFinger.c -$(LOB)/HTStyle.o : $(OE) $(CMN)HTStyle.c $(CMN)HTUtils.h +$(LOB)/HTStyle$(_O) : $(OE) $(CMN)HTStyle.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTStyle.c -$(LOB)/HTAtom.o : $(OE) $(CMN)HTAtom.c $(CMN)HTUtils.h $(CMN)HTList.h +$(LOB)/HTAtom$(_O) : $(OE) $(CMN)HTAtom.c $(CMN)HTUtils.h $(CMN)HTList.h $(COMPILE) $(CMN)HTAtom.c -$(LOB)/HTChunk.o : $(OE) $(CMN)HTChunk.c $(CMN)HTUtils.h +$(LOB)/HTChunk$(_O) : $(OE) $(CMN)HTChunk.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTChunk.c -$(LOB)/HTString.o : $(OE) $(CMN)HTString.c $(CMN)HTUtils.h $(CMN)Version.make +$(LOB)/HTString$(_O) : $(OE) $(CMN)HTString.c $(CMN)HTUtils.h $(CMN)Version.make $(COMPILE) -DVC=\"$(VC)\" $(CMN)HTString.c -$(LOB)/HTRules.o : $(OE) $(CMN)HTRules.c $(CMN)HTUtils.h $(CMN)Version.make \ +$(LOB)/HTRules$(_O) : $(OE) $(CMN)HTRules.c $(CMN)HTUtils.h $(CMN)Version.make \ $(CMN)HTAAProt.h $(COMPILE) -DVC=\"$(VC)\" $(CMN)HTRules.c -$(LOB)/SGML.o : $(OE) $(CMN)SGML.c $(CMN)HTUtils.h $(CMN)UCAux.h +$(LOB)/SGML$(_O) : $(OE) $(CMN)SGML.c $(CMN)HTUtils.h $(CMN)UCAux.h $(COMPILE) $(CMN)SGML.c -$(LOB)/HTMLGen.o : $(OE) $(CMN)HTMLGen.c $(CMN)HTUtils.h $(CMN)HTMLDTD.h +$(LOB)/HTMLGen$(_O) : $(OE) $(CMN)HTMLGen.c $(CMN)HTUtils.h $(CMN)HTMLDTD.h $(COMPILE) $(CMN)HTMLGen.c -$(LOB)/HTMLDTD.o : $(OE) $(CMN)HTMLDTD.c $(CMN)SGML.h +$(LOB)/HTMLDTD$(_O) : $(OE) $(CMN)HTMLDTD.c $(CMN)SGML.h $(COMPILE) $(CMN)HTMLDTD.c -$(LOB)/HTPlain.o : $(OE) $(CMN)HTPlain.c $(CMN)HTPlain.h $(CMN)HTStream.h \ +$(LOB)/HTPlain$(_O) : $(OE) $(CMN)HTPlain.c $(CMN)HTPlain.h $(CMN)HTStream.h \ $(CMN)UCAux.h $(COMPILE) $(CMN)HTPlain.c -$(LOB)/HTWAIS.o : $(OE) $(CMN)HTWAIS.c $(CMN)HTUtils.h $(CMN)HTList.h +$(LOB)/HTWAIS$(_O) : $(OE) $(CMN)HTWAIS.c $(CMN)HTUtils.h $(CMN)HTList.h $(COMPILE) $(WAISINC) $(CMN)HTWAIS.c -$(LOB)/HTWSRC.o : $(OE) $(CMN)HTWSRC.c $(CMN)HTUtils.h $(CMN)HTList.h +$(LOB)/HTWSRC$(_O) : $(OE) $(CMN)HTWSRC.c $(CMN)HTUtils.h $(CMN)HTList.h $(COMPILE) $(CMN)HTWSRC.c # Access Authorization -$(LOB)/HTAAUtil.o : $(OE) $(CMN)HTAAUtil.c $(CMN)HTAAUtil.h \ +$(LOB)/HTAAUtil$(_O) : $(OE) $(CMN)HTAAUtil.c $(CMN)HTAAUtil.h \ $(CMN)HTUtils.h $(CMN)HTString.h $(COMPILE) $(CMN)HTAAUtil.c -$(LOB)/HTGroup.o : $(OE) $(CMN)HTGroup.c $(CMN)HTGroup.h \ +$(LOB)/HTGroup$(_O) : $(OE) $(CMN)HTGroup.c $(CMN)HTGroup.h \ $(CMN)HTAAUtil.h \ $(CMN)HTAssoc.h $(CMN)HTLex.h $(COMPILE) $(CMN)HTGroup.c -$(LOB)/HTAABrow.o : $(OE) $(CMN)HTAABrow.c $(CMN)HTAABrow.h \ +$(LOB)/HTAABrow$(_O) : $(OE) $(CMN)HTAABrow.c $(CMN)HTAABrow.h \ $(CMN)HTAAUtil.h $(CMN)HTUU.h \ $(CMN)HTUtils.h $(CMN)HTString.h \ $(CMN)HTParse.h $(CMN)HTList.h \ $(CMN)HTAssoc.h $(COMPILE) $(CMN)HTAABrow.c -$(LOB)/HTAAProt.o : $(OE) $(CMN)HTAAProt.c $(CMN)HTAAProt.h \ +$(LOB)/HTAAProt$(_O) : $(OE) $(CMN)HTAAProt.c $(CMN)HTAAProt.h \ $(CMN)HTUtils.h $(CMN)HTAAUtil.h \ $(CMN)HTAssoc.h $(CMN)HTLex.h $(COMPILE) $(CMN)HTAAProt.c -$(LOB)/HTAssoc.o : $(OE) $(CMN)HTAssoc.c $(CMN)HTAssoc.h \ +$(LOB)/HTAssoc$(_O) : $(OE) $(CMN)HTAssoc.c $(CMN)HTAssoc.h \ $(CMN)HTUtils.h $(CMN)HTString.h $(CMN)HTList.h $(COMPILE) $(CMN)HTAssoc.c -$(LOB)/HTLex.o : $(OE) $(CMN)HTLex.c $(CMN)HTLex.h $(CMN)HTUtils.h +$(LOB)/HTLex$(_O) : $(OE) $(CMN)HTLex.c $(CMN)HTLex.h $(CMN)HTUtils.h $(COMPILE) $(CMN)HTLex.c -$(LOB)/HTUU.o : $(OE) $(CMN)HTUU.c $(CMN)HTUU.h $(CMN)HTUtils.h +$(LOB)/HTUU$(_O) : $(OE) $(CMN)HTUU.c $(CMN)HTUU.h $(CMN)HTUtils.h $(COMPILE) $(CMN)HTUU.c # Communications & Files -$(LOB)/HTTP.o : $(OE) $(CMN)HTTP.c $(CMN)HTUtils.h $(CMN)HTAABrow.h +$(LOB)/HTTP$(_O) : $(OE) $(CMN)HTTP.c $(CMN)HTUtils.h $(CMN)HTAABrow.h $(COMPILE) $(CMN)HTTP.c -$(LOB)/HTTCP.o : $(OE) $(CMN)HTTCP.c $(CMN)HTUtils.h +$(LOB)/HTTCP$(_O) : $(OE) $(CMN)HTTCP.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTTCP.c -$(LOB)/HTFile.o : $(OE) $(CMN)HTFile.c $(CMN)HTUtils.h \ +$(LOB)/HTFile$(_O) : $(OE) $(CMN)HTFile.c $(CMN)HTUtils.h \ $(CMN)HTMLDTD.h $(COMPILE) $(CMN)HTFile.c -$(LOB)/HTBTree.o : $(OE) $(CMN)HTBTree.c $(CMN)HTUtils.h +$(LOB)/HTBTree$(_O) : $(OE) $(CMN)HTBTree.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTBTree.c -$(LOB)/HTFTP.o : $(OE) $(CMN)HTFTP.c $(CMN)HTUtils.h +$(LOB)/HTFTP$(_O) : $(OE) $(CMN)HTFTP.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTFTP.c -$(LOB)/HTAccess.o : $(OE) $(CMN)HTAccess.c $(CMN)HTUtils.h +$(LOB)/HTAccess$(_O) : $(OE) $(CMN)HTAccess.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTAccess.c -$(LOB)/HTParse.o : $(OE) $(CMN)HTParse.c $(CMN)HTUtils.h +$(LOB)/HTParse$(_O) : $(OE) $(CMN)HTParse.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTParse.c -$(LOB)/HTVMS_WaisUI.o : $(OE) $(CMN)HTVMS_WaisUI.c $(CMN)HTUtils.h +$(LOB)/HTVMS_WaisUI$(_O) : $(OE) $(CMN)HTVMS_WaisUI.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTVMS_WaisUI.c -$(LOB)/HTDOS.o : $(OE) $(CMN)HTDOS.c $(CMN)HTUtils.h +$(LOB)/HTDOS$(_O) : $(OE) $(CMN)HTDOS.c $(CMN)HTUtils.h $(COMPILE) $(CMN)HTDOS.c # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/www_tcp.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/www_tcp.h new file mode 100644 index 00000000000..f3f5ac65a45 --- /dev/null +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/www_tcp.h @@ -0,0 +1,843 @@ +/* System dependencies in the W3 library + SYSTEM DEPENDENCIES + + System-system differences for TCP include files and macros. This + file includes for each system the files necessary for network and + file I/O. It should be used in conjunction with HTUtils.h to help + ensure portability across as many platforms and flavors of platforms + as possible. + + AUTHORS + + TBL Tim Berners-Lee, W3 project, CERN, <timbl@info.cern.ch> + EvA Eelco van Asperen <evas@cs.few.eur.nl> + MA Marc Andreessen NCSA + AT Aleksandar Totic <atotic@ncsa.uiuc.edu> + SCW Susan C. Weber <sweber@kyle.eitech.com> + + HISTORY: + 22 Feb 91 Written (TBL) as part of the WWW library. + 16 Jan 92 PC code from EvA + 22 Apr 93 Merged diffs bits from xmosaic release + 29 Apr 93 Windows/NT code from SCW + 20 May 94 A.Harper Add support for VMS CMU TCP/IP transport + 3 Oct 94 A.Harper Add support for VMS SOCKETSHR/NETLIB + 15 Jul 95 S. Bjorndahl Gnu C for VMS Globaldef/ref support + +*/ + +#ifndef TCP_H +#define TCP_H + +/* + +Default values + + These values may be reset and altered by system-specific sections + later on. there are also a bunch of defaults at the end . + + */ +/* Default values of those: */ +#define NETCLOSE close /* Routine to close a TCP-IP socket */ +#define NETREAD HTDoRead /* Routine to read from a TCP-IP socket */ +#define NETWRITE write /* Routine to write to a TCP-IP socket */ +#define SOCKET_READ read /* normal socket read routine */ +#define IOCTL ioctl /* normal ioctl routine for sockets */ +#define SOCKET_ERRNO errno /* normal socket errno */ + +/* Unless stated otherwise, */ +#define SELECT /* Can handle >1 channel. */ +#define GOT_SYSTEM /* Can call shell with string */ + +#ifdef UNIX +#define GOT_PIPE +#endif /* UNIX */ + +#define INVSOC (-1) /* Unix invalid socket */ + /* NB: newer libwww has something different for Windows */ + +#ifndef VMS + +#include <sys/types.h> + +#if defined(__BORLANDC__) +#define DECL_ERRNO +#endif + +#if defined(__DJGPP__) || defined(__BORLANDC__) +#undef HAVE_DIRENT_H +#define HAVE_DIRENT_H +#undef HAVE_SYS_FILIO_H +#endif /* DJGPP or __BORLANDC__ */ + +#if defined(_MSC_VER) +#undef HAVE_DIRENT_H +#define HAVE_DIRENT_H +#undef HAVE_SYS_FILIO_H +#endif /* _MSC_VER */ + +#ifdef HAVE_DIRENT_H +# include <dirent.h> +# define D_NAMLEN(dirent) strlen((dirent)->d_name) +# define STRUCT_DIRENT struct dirent +#else +# define D_NAMLEN(dirent) (dirent)->d_namlen +# define STRUCT_DIRENT struct direct +# ifdef HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# ifdef HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# ifdef HAVE_NDIR_H +# include <ndir.h> +# endif +#endif /* HAVE_DIRENT_H */ +#endif /* !VMS */ + +#ifdef TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + +#if defined(_AIX) && !defined(AIX) +#define AIX +#endif /* _AIX */ + +#ifdef __CYGWIN__ +#define _WINDOWS_NSL +#define WIN_EX +#else +#ifdef WIN_EX +#define HAVE_FTIME 1 +#define HAVE_SYS_TIMEB_H 1 +#endif +#endif /* __CYGWIN__ */ + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#else +#ifdef HAVE_SYS_FCNTL_H +#include <sys/fcntl.h> +#endif +#endif + +#ifdef HAVE_STRING_H +#include <string.h> /* For bzero etc */ +#endif /* HAVE_STRING_H */ + +/* + + MACROS FOR CONVERTING CHARACTERS + + */ +#ifndef TOASCII +#ifdef EBCDIC /* S/390 -- gil -- 1327 */ + +extern char un_IBM1047[]; +extern unsigned char IBM1047[]; +/* For debugging +#include <assert.h> +#define TOASCII(c) (assert((c)>=0 && (c)<256), un_IBM1047[c]) +*/ /* for production */ +#define TOASCII(c) (un_IBM1047[c]) + +#define FROMASCII(c) (IBM1047[c]) + +#else /* EBCDIC */ + +#if '0' != 48 + error Host character set is not ASCII. +#endif + +#define TOASCII(c) (c) +#define FROMASCII(c) (c) + +#endif /* EBCDIC */ +#endif /* !TOASCII */ + +/* convert a char to an unsigned, needed if we have signed characters for ctype.h */ +#define UCH(ch) ((unsigned char)(ch)) + +/* +IBM-PC running Windows NT + + These parameters providede by Susan C. Weber <sweber@kyle.eitech.com>. +*/ + +#ifdef _WINDOWS +#define _WINDOWS_NSL +#include <fcntl.h> /* For HTFile.c */ +#include <sys\types.h> /* For HTFile.c */ +#include <sys\stat.h> /* For HTFile.c */ +#undef NETREAD +#undef NETWRITE +#undef NETCLOSE +#undef IOCTL +extern int ws_netread(int fd, char *buf, int len); +#define NETREAD(s,b,l) ws_netread((s),(b),(l)) /* 1997/11/06 (Thu) */ +#define NETWRITE(s,b,l) send((s),(b),(l),0) +#define NETCLOSE(s) closesocket(s) +#define IOCTL ioctlsocket +#include <io.h> +#include <string.h> +#include <process.h> +#include <time.h> +#include <errno.h> +#include <direct.h> + +#ifdef USE_WINSOCK2_H +#include <winsock2.h> /* normally included in windows.h */ + +#undef EINPROGRESS +#undef EALREADY +#undef EISCONN +#undef EINTR +#undef EAGAIN +#undef ENOTCONN +#undef ECONNRESET +#undef ETIMEDOUT + +#define EINPROGRESS WSAEINPROGRESS +#define EALREADY WSAEALREADY +#define EISCONN WSAEISCONN +#define EINTR WSAEINTR +/* fine EAGAIN WSAEAGAIN */ +#define ENOTCONN WSAENOTCONN +#define ECONNRESET WSAECONNRESET +#define ETIMEDOUT WSAETIMEDOUT + +#else /* USE_WINSOCK_H */ + +#include <winsock.h> +typedef struct sockaddr_in SockA; /* See netinet/in.h */ + +#if defined(_MSC_VER) || defined(__MINGW32__) +#undef EINTR +#undef EAGAIN +#endif /* _MSC_VER */ + +#define EINPROGRESS (WSABASEERR+36) +#define EALREADY (WSABASEERR+37) +#define EISCONN (WSABASEERR+56) +#define EINTR (WSABASEERR+4) +#define EAGAIN (WSABASEERR+1002) +#define ENOTCONN (WSABASEERR+57) +#define ECONNRESET (WSABASEERR+54) +#define ETIMEDOUT WSAETIMEDOUT /* 1997/11/10 (Mon) */ + +#undef SOCKET_ERRNO /* 1997/10/19 (Sun) 18:01:46 */ +#define SOCKET_ERRNO WSAGetLastError() + +#endif /* USE_WINSOCK_H */ + +#define INCLUDES_DONE +#define TCP_INCLUDES_DONE +#endif /* WINDOWS */ + + + +/* + +VAX/VMS + + Under VMS, there are many versions of TCP-IP. Define one if you do + not use Digital's UCX product: + + UCX DEC's "Ultrix connection" (default) + CMU_TCP Available via FTP from sacusr.mp.usbr.gov + SOCKETSHR Eckhart Meyer's interface to NETLIB + WIN_TCP From Wollongong, now GEC software. + MULTINET From SRI, became TGV, then Cisco. + DECNET Cern's TCP socket emulation over DECnet + + The last three do not interfere with the + unix i/o library, and so they need special calls to read, write and + close sockets. In these cases the socket number is a VMS channel + number, so we make the @@@ HORRIBLE @@@ assumption that a channel + number will be greater than 10 but a unix file descriptor less than + 10. It works. + + */ +#ifdef VMS + +#ifdef UCX +#undef IOCTL +#define IOCTL HTioctl +#endif /* UCX */ + +#ifdef WIN_TCP +#undef SOCKET_READ +#undef NETWRITE +#undef NETCLOSE +#define SOCKET_READ(s,b,l) ((s)>10 ? netread((s),(b),(l)) : read((s),(b),(l))) +#define NETWRITE(s,b,l) ((s)>10 ? netwrite((s),(b),(l)) : write((s),(b),(l))) +#define NETCLOSE(s) ((s)>10 ? netclose(s) : close(s)) +#undef IOCTL +#define IOCTL(a,b,c) -1 /* disables ioctl function */ +#define NO_IOCTL /* flag to check if ioctl is disabled */ +#endif /* WIN_TCP */ + +#ifdef CMU_TCP +#undef SOCKET_READ +#undef NETREAD +#undef NETWRITE +#undef NETCLOSE +#define SOCKET_READ(s,b,l) (cmu_get_sdc((s)) != 0 ? cmu_read((s),(b),(l)) : read((s),(b),(l))) +#define NETREAD(s,b,l) (cmu_get_sdc((s)) != 0 ? HTDoRead((s),(b),(l)) : read((s),(b),(l))) +#define NETWRITE(s,b,l) (cmu_get_sdc((s)) != 0 ? cmu_write((s),(b),(l)) : write((s),(b),(l))) +#define NETCLOSE(s) (cmu_get_sdc((s)) != 0 ? cmu_close((s)) : close((s))) +#endif /* CMU_TCP */ + +#ifdef MULTINET +#undef NETCLOSE +#undef SOCKET_READ +#undef NETWRITE +#undef IOCTL +#undef SOCKET_ERRNO +/* +** Delete these socket_foo() prototypes as MultiNet adds them +** to it's socket library headers. Compiler warnings due to +** the absence of arguments in the generic prototypes here will +** include the names of those which can be deleted. - FM +*/ +extern int socket_read(); +extern int socket_write(); +extern int socket_close(); +extern int socket_ioctl(); + +#define SOCKET_READ(s,b,l) ((s)>10 ? socket_read((s),(b),(l)) : \ + read((s),(b),(l))) +#define NETWRITE(s,b,l) ((s)>10 ? socket_write((s),(b),(l)) : \ + write((s),(b),(l))) +#define NETCLOSE(s) ((s)>10 ? socket_close(s) : close(s)) +#define IOCTL socket_ioctl +#define SOCKET_ERRNO socket_errno +#endif /* MULTINET */ + +#ifdef SOCKETSHR_TCP +#undef SOCKET_READ +#undef NETREAD +#undef NETWRITE +#undef NETCLOSE +#undef IOCTL +#define SOCKET_READ(s,b,l) (si_get_sdc((s)) != 0 ? si_read((s),(b),(l)) : \ + read((s),(b),(l))) +#define NETREAD(s,b,l) (si_get_sdc((s)) != 0 ? HTDoRead((s),(b),(l)) : \ + read((s),(b),(l))) +#define NETWRITE(s,b,l) (si_get_sdc((s)) != 0 ? si_write((s),(b),(l)) : \ + write((s),(b),(l))) +#define NETCLOSE(s) (si_get_sdc((s)) != 0 ? si_close((s)) : close((s))) +#define IOCTL si_ioctl +#endif /* SOCKETSHR_TCP */ + +#include <string.h> + +#include <file.h> +#include <stat.h> +#include <unixio.h> +#include <unixlib.h> + +#define INCLUDES_DONE + +#ifdef MULTINET /* Include from standard Multinet directories */ +/* +** Delete any of these multinet_foo() and associated prototypes +** as MultiNet adds them to its socket library headers. You'll +** get compiler warnings about them, due the absence of arguments +** in the generic prototyping here, and the warnings will include +** the names of the functions whose prototype entries can be +** deleted here. - FM +*/ +extern int multinet_accept(); +extern int multinet_bind(); +extern int multinet_connect(); +extern int multinet_gethostname(); +extern int multinet_getsockname(); +extern unsigned short multinet_htons(unsigned short __val); +extern unsigned short multinet_ntohs(unsigned short __val); +extern int multinet_listen(); +extern int multinet_select(); +extern int multinet_socket(); +extern char *vms_errno_string(); + +#ifndef __SOCKET_TYPEDEFS +#define __SOCKET_TYPEDEFS 1 +#endif /* !__SOCKET_TYPEDEFS */ +#include <time.h> +#include <types.h> +#ifdef __TIME_T +#undef __TYPES +#define __TYPES 1 +#define __TYPES_LOADED 1 +#endif /* __TIME_T */ +#ifdef __SOCKET_TYPEDEFS +#undef __SOCKET_TYPEDEFS +#endif /* __SOCKET_TYPEDEFS */ +#include "multinet_root:[multinet.include.sys]types.h" +#ifndef __SOCKET_TYPEDEFS +#define __SOCKET_TYPEDEFS 1 +#endif /* !__SOCKET_TYPEDEFS */ +#include "multinet_root:[multinet.include]errno.h" +#ifdef __TYPES +#undef __TIME_T +#define __TIME_T 1 +#endif /* __TYPE */ +#ifdef __TIME_LOADED +#undef __TIME +#define __TIME 1 /* to avoid double definitions in in.h */ +#endif /* __TIME_LOADED */ +#include "multinet_root:[multinet.include.sys]time.h" +#define MULTINET_NO_PROTOTYPES /* DECC is compatible-but-different */ +#include "multinet_root:[multinet.include.sys]socket.h" +#undef MULTINET_NO_PROTOTYPES +#include "multinet_root:[multinet.include.netinet]in.h" +#include "multinet_root:[multinet.include.arpa]inet.h" +#include "multinet_root:[multinet.include]netdb.h" +#include "multinet_root:[multinet.include.sys]ioctl.h" +#define TCP_INCLUDES_DONE +/* +** Uncomment this if you get compiler messages +** about struct timeval having no linkage. - FM +*/ +/*#define NO_TIMEVAL*/ +#ifdef NO_TIMEVAL +struct timeval { + long tv_sec; /* seconds since Jan. 1, 1970 */ + long tv_usec; /* microseconds */ +}; +#endif /* NO_TIMEVAL */ +#endif /* MULTINET */ + + +#ifdef DECNET +#include <types.h> +#include <errno.h> +#include <time.h> +#include <types.h> /* for socket.h */ +#include <socket.h> +#include <dn> +#include <dnetdb> +/* #include "vms.h" */ +#define TCP_INCLUDES_DONE +#endif /* DECNET */ + + +#ifdef UCX +#include <types.h> +#include <errno.h> +#include <time.h> +#include <socket.h> +#include <in.h> +#include <inet.h> +#if defined(TCPWARE) && !defined(__DECC) +#include "tcpware_include:netdb.h" +#include "tcpware_include:ucx$inetdef.h" +#else +#include <netdb.h> +#include <ucx$inetdef.h> +#endif /* TCPWARE */ +#define TCP_INCLUDES_DONE +#endif /* UCX */ + + +#ifdef CMU_TCP +#include <types.h> +#include <errno.h> +#include "cmuip_root:[syslib]time.h" +#include "cmuip_root:[syslib]socket.h" +#include <in.h> +#include <inet.h> +#include <netdb.h> +#include "cmuip_root:[syslib]ioctl.h" +#define TCP_INCLUDES_DONE +#endif /* CMU_TCP */ + + +#ifdef SOCKETSHR_TCP +#include <types.h> +#include <errno.h> +#include <time.h> +#include <socket.h> +#include <in.h> +#include <inet.h> +#include <netdb.h> +#include "socketshr_library:socketshr.h" +#include "socketshr_library:ioctl.h" +#define TCP_INCLUDES_DONE +#endif /* SOCKETSHR_TCP */ + +#ifdef WIN_TCP +#include <types.h> +#include <errno.h> +#include <time.h> +#include <socket.h> +#include <in.h> +#include <inet.h> +#include <netdb.h> +#ifndef NO_IOCTL +#include <ioctl.h> +#endif /* !NO_IOCTL */ +#define TCP_INCLUDES_DONE +#endif /* WIN_TCP */ + +#ifndef TCP_INCLUDES_DONE +#include <types.h> +#include <errno.h> +#include <time.h> +#ifdef VMS_SOCKET_HEADERS +/* +** Not all versions of VMS have the full set of headers +** for socket library functions, because the TCP/IP +** packages were layered products. If we want these +** specifically, instead of those for the above packages, +** the module should be compiled with VMS_SOCKET_HEADERS +** defined instead of layered product definitions, above. +** If the module is not using socket library functions, +** none of the definitions need be used, and we include +** only the above three headers. - FM +*/ +#include <socket.h> +#include <in.h> +#include <inet.h> +#include <netdb.h> +#include <ioctl.h> +#endif /* VMS_SOCKET_HEADERS */ +#define TCP_INCLUDES_DONE +#endif /* !TCP_INCLUDES_DONE */ + +/* + + On VMS machines, the linker needs to be told to put global data sections into + a data + segment using these storage classes. (MarkDonszelmann) + + */ +#if defined(VAXC) && !defined(__DECC) +#define GLOBALDEF globaldef +#define GLOBALREF globalref +#else +#ifdef __GNUC__ /* this added by Sterling Bjorndahl */ +#define GLOBALREF_IS_MACRO 1 +#define GLOBALDEF_IS_MACRO 1 +#include <gnu_hacks.h> /* defines GLOBALREF and GLOBALDEF for GNUC on VMS */ +#endif /* __GNUC__ */ +#endif /* VAXC && !DECC */ + +#include <perror.h> +#ifndef errno +extern int errno; +#endif /* !errno */ + +#endif /* VMS */ + +/* + * On non-VMS machines and for DECC on VMS, the GLOBALDEF and GLOBALREF + * storage types default to normal C storage types. + */ +#ifndef GLOBALREF +#define GLOBALDEF +#define GLOBALREF extern +#endif /* !GLOBALREF */ + +#ifdef __DJGPP__ +#undef SELECT +#define TCP_INCLUDES_DONE +#define NO_IOCTL +#define DECL_ERRNO +#include <errno.h> +#include <sys/types.h> +#include <socket.h> +#include <io.h> +#ifdef WATT32 +#include <arpa/inet.h> +#include <tcp.h> +#ifdef word +#undef word +#endif /* word */ +#define select select_s +#endif /* WATT32 */ + +#undef NETWRITE +#define NETWRITE write_s +#undef NETREAD +#define NETREAD read_s +#undef NETCLOSE +#define NETCLOSE close_s +#ifndef WATT32 +#define getsockname getsockname_s +#endif /* !WATT32 */ +#ifdef HAVE_GETTEXT +#define gettext gettext__ +#endif +#endif /* DJGPP */ + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#ifdef HAVE_SYS_FILIO_H +#include <sys/filio.h> +#endif /* HAVE_SYS_FILIO_H */ + +#if !defined(HAVE_LSTAT) && !defined(lstat) +#define lstat(path,block) stat(path,block) +#endif + +#if defined(DECL_ERRNO) && !defined(errno) +extern int errno; +#endif /* DECL_ERRNO */ + +/* +Regular BSD unix versions +========================= + These are a default unix where not already defined specifically. + */ +#ifndef INCLUDES_DONE +#include <sys/types.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif /* HAVE_STRING_H */ +#include <errno.h> /* independent */ +#ifdef __MVS__ /* S/390 -- gil -- 1361 */ +#include <time.h> +#endif /* __MVS__ */ +#ifdef SCO +#include <sys/timeb.h> +#include <time.h> +#endif /* SCO */ +#if defined(AIX) || defined(SVR4) +#include <time.h> +#endif /* AIX || SVR4 */ +#include <sys/time.h> /* independent */ +#include <sys/stat.h> +#ifndef __MVS__ /* S/390 -- gil -- 1373 */ +#include <sys/param.h> +#endif /* __MVS__ */ +#include <sys/file.h> /* For open() etc */ + +#if defined(NeXT) || defined(sony_news) +#ifndef mode_t +typedef unsigned short mode_t; +#endif /* !mode_t */ + +#ifndef pid_t +typedef int pid_t; +#endif /* !pid_t */ + +#endif /* NeXT || sony_news */ + +#define INCLUDES_DONE +#endif /* Normal includes */ + +/* FIXME: this should be autoconf'd */ +/* Interactive UNIX for i386 and i486 -- Thanks to jeffrey@itm.itm.org */ +#ifdef ISC +#include <net/errno.h> +#include <sys/types.h> +#include <sys/tty.h> +#include <sys/sioctl.h> +#include <sys/bsdtypes.h> +#ifndef MERGE +#define MERGE +#include <sys/pty.h> +#undef MERGE +#else +#include <sys/pty.h> +#endif /* !MERGE */ +#ifndef USE_DIRENT +#define USE_DIRENT /* sys V style directory open */ +#endif /* USE_DIRENT */ +#include <sys/dirent.h> +#endif /* ISC */ + +/* Directory reading stuff - BSD or SYS V +*/ +#ifdef HAVE_CONFIG_H + +# ifdef HAVE_LIMITS_H +# include <limits.h> +# endif /* HAVE_LIMITS_H */ +# if !defined(MAXINT) && defined(INT_MAX) +# define MAXINT INT_MAX +# endif /* !MAXINT && INT_MAX */ + +#else + +#if !(defined(VM) || defined(VMS) || defined(THINK_C) || defined(PCNFS) || defined(__MINGW32__)) +#define DECL_SYS_ERRLIST 1 +#endif + +#endif /* !HAVE_CONFIG_H */ + +#ifdef HAVE_LIBINTL_H +#include <libintl.h> +#endif + +#define N_(s) (s) + +#ifndef HAVE_GETTEXT +#define gettext(s) s +#endif + +/* +Defaults +======== + INCLUDE FILES FOR TCP + */ +#ifndef TCP_INCLUDES_DONE +#ifndef NO_IOCTL +#include <sys/ioctl.h> /* EJB */ +#endif /* !NO_IOCTL */ +#include <sys/socket.h> +#include <netinet/in.h> +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> /* Must be after netinet/in.h */ +#endif +#include <netdb.h> +#endif /* TCP includes */ + +typedef unsigned short PortNumber; + +#ifndef S_ISLNK +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#endif /* S_ISLNK */ + +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif /* S_ISDIR */ + +#ifndef S_ISREG +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif /* S_ISREG */ + +#ifndef S_ISUID +#define S_ISUID 0004000 +#endif +#ifndef S_ISGID +#define S_ISGID 0002000 +#endif +#ifndef S_ISVTX +#define S_ISVTX 0001000 +#endif + +#ifndef S_IRWXU +#define S_IRWXU 00700 +#endif + +#ifndef S_IRUSR +#define S_IRUSR 00400 +#endif +#ifndef S_IWUSR +#define S_IWUSR 00200 +#endif +#ifndef S_IXUSR +#define S_IXUSR 00100 +#endif + +#ifndef S_IRWXG +#define S_IRWXG 00070 +#endif + +#ifndef S_IRGRP +#define S_IRGRP 00040 +#endif +#ifndef S_IWGRP +#define S_IWGRP 00020 +#endif +#ifndef S_IXGRP +#define S_IXGRP 00010 +#endif + +#ifndef S_IRWXO +#define S_IRWXO 00007 +#endif + +#ifndef S_IROTH +#define S_IROTH 00004 +#endif +#ifndef S_IWOTH +#define S_IWOTH 00002 +#endif +#ifndef S_IXOTH +#define S_IXOTH 00001 +#endif + +/* + +ROUGH ESTIMATE OF MAX PATH LENGTH + +*/ +#ifndef HT_MAX_PATH +#ifdef MAXPATHLEN +#define HT_MAX_PATH MAXPATHLEN +#else +#ifdef PATH_MAX +#define HT_MAX_PATH PATH_MAX +#else +#define HT_MAX_PATH 1024 /* Any better ideas? */ +#endif +#endif +#endif /* HT_MAX_PATH */ + +#if HT_MAX_PATH < 256 +#undef HT_MAX_PATH +#define HT_MAX_PATH 256 +#endif + +/* + MACROS FOR MANIPULATING MASKS FOR SELECT() + */ +#ifdef SELECT +#ifndef FD_SET +typedef unsigned int fd_set; +#define FD_SET(fd,pmask) (*(pmask)) |= (1<<(fd)) +#define FD_CLR(fd,pmask) (*(pmask)) &= ~(1<<(fd)) +#define FD_ZERO(pmask) (*(pmask))=0 +#define FD_ISSET(fd,pmask) (*(pmask) & (1<<(fd))) +#endif /* !FD_SET */ +#endif /* SELECT */ + +/* + * Macro for setting errno - only define this if you really can do it. + */ +#if defined(CAN_SET_ERRNO) || (!defined(errno) && (!defined(VMS) || defined(UCX))) +#define set_errno(value) errno = value +#else +#define set_errno(value) /* we do not know how */ +#endif + +/* IPv6 support */ +#if defined(HAVE_GETADDRINFO) && defined(HAVE_GAI_STRERROR) && defined(ENABLE_IPV6) +# define INET6 +#endif /* HAVE_GETADDRINFO && HAVE_GAI_STRERROR && ENABLE_IPV6 */ + +#if !defined(__MINGW32__) +#ifdef INET6 +typedef struct sockaddr_storage SockA; /* See netinet/in.h */ +#else +typedef struct sockaddr_in SockA; /* See netinet/in.h */ +#endif /* INET6 */ +#endif + +#ifdef INET6 +#ifdef SIN6_LEN +#define SOCKADDR_LEN(soc_address) ((struct sockaddr *)&soc_address)->sa_len +#else +#ifndef SA_LEN +#define SA_LEN(x) (((x)->sa_family == AF_INET6)?sizeof(struct sockaddr_in6): \ + (((x)->sa_family == AF_INET)?sizeof(struct sockaddr_in):sizeof(struct sockaddr))) +#endif +#define SOCKADDR_LEN(soc_address) SA_LEN((struct sockaddr *)&soc_address) +#endif /* SIN6_LEN */ +#else +#define SOCKADDR_LEN(soc_address) sizeof(soc_address) +#endif /* INET6 */ + +#endif /* TCP_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/www_wait.h b/gnu/usr.bin/lynx/WWW/Library/Implementation/www_wait.h new file mode 100644 index 00000000000..730b3ec5428 --- /dev/null +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/www_wait.h @@ -0,0 +1,26 @@ +#ifndef WWW_WAIT_H +#define WWW_WAIT_H 1 + +#include <HTUtils.h> + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#ifndef WEXITSTATUS +# ifdef HAVE_TYPE_UNIONWAIT +# define WEXITSTATUS(status) (status.w_retcode) +# else +# define WEXITSTATUS(status) (((status) & 0xff00) >> 8) +# endif +#endif + +#ifndef WTERMSIG +# ifdef HAVE_TYPE_UNIONWAIT +# define WTERMSIG(status) (status.w_termsig) +# else +# define WTERMSIG(status) ((status) & 0x7f) +# endif +#endif + +#endif /* WWW_WAIT_H */ diff --git a/gnu/usr.bin/lynx/WWW/Library/djgpp/CommonMakefile b/gnu/usr.bin/lynx/WWW/Library/djgpp/CommonMakefile index f4bdad38263..99dc1f6a7b5 100644 --- a/gnu/usr.bin/lynx/WWW/Library/djgpp/CommonMakefile +++ b/gnu/usr.bin/lynx/WWW/Library/djgpp/CommonMakefile @@ -116,7 +116,7 @@ HFILES = $(CMN)HTParse.h $(CMN)HTAccess.h $(CMN)HTTP.h $(CMN)HTFile.h \ $(CMN)HTFormat.h $(CMN)HTInit.h \ $(CMN)HTMIME.h $(CMN)HTNews.h \ $(CMN)HTGopher.h \ - $(CMN)HTUtils.h $(CMN)tcp.h $(CMN)HText.h \ + $(CMN)HTUtils.h $(CMN)www_tcp.h $(CMN)HText.h \ $(CMN)HTTelnet.h $(CMN)HTFinger.h \ $(CMN)HTWAIS.h $(CMN)HTWSRC.h \ $(CMN)HTAAUtil.h $(CMN)HTAABrow.h \ @@ -130,9 +130,6 @@ SOURCES = $(CFILES) $(HFILES) $(CMN)Version.make \ SPECIFIC = $(WWW)/All/*/Makefile.include $(WWW)/All/Implementation/Makefile* \ $(VMS)/descrip.mms $(VMS)/build_multinet.com \ $(VMS)/COPYING.LIB $(VMS)/setup.com $(VMS)/multinet.opt \ - $(VMS)/patchlevel.h $(VMS)/ufc-crypt.h \ - $(VMS)/crypt.c $(VMS)/crypt_util.c \ - $(VMS)/getline.c $(VMS)/getpass.c \ $(VMS)/HTVMSUtils.h $(VMS)/HTVMSUtils.c @@ -146,13 +143,12 @@ $(LOB)/libwww.a : $(COMMON) # Clean up everything generatable except final products clean : - rm $(LOB)/*.o - -rmdir $(LOB) + rm -f $(LOB)/*.o # Clean up everything generatable including final products cleanall : clean - rm $(LOB)/libwww.a + rm -f $(LOB)/libwww.a # Install W3 library into system space (not normally necessary) diff --git a/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile b/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile index 06e6f2e782b..893f6cdb29b 100644 --- a/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile +++ b/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile @@ -7,17 +7,45 @@ WWW_MACH = djgpp # The ASIS repository's name for the machine we are on #ASIS_MACH = hardware/os -CFLAGS = -O3 -DUSE_ZLIB -DDOSPATH -DNOUSERS -DDISP_PARTIAL \ --DSOURCE_CACHE -DUSE_PSRC \ --I../Implementation \ --I../../../djgpp/tcplib/include \ --I../../../djgpp/tcplib/include/tcp \ --I../../../curses \ --I../../../src \ --I../../.. +# Use this option to enable optional and *experimental* color style. +#ENABLE_COLOR_STYLE = \ + -DUSE_COLOR_STYLE \ + -DUSE_HASH \ + -DLINKEDSTYLES + +# comment this line to suppress DIRED support +DIRED_DEFS = -DDIRED_SUPPORT + +CFLAGS= -O2 $(MCFLAGS) $(INTLFLAGS) $(SSLFLAGS) $(SSLINC) + +MCFLAGS = \ + $(DIRED_DEFS) \ + $(ENABLE_COLOR_STYLE) \ + -DDISP_PARTIAL \ + -DDOSPATH \ + -DEXP_FILE_UPLOAD \ + -DNOUSERS \ + -DSOURCE_CACHE \ + -DUSE_PRETTYSRC \ + -DUSE_ZLIB \ + -DWATT32 \ + -I../Implementation \ + -I../../../src \ + -I../../.. \ + -I/djgpp/pdcur24 \ + -I/djgpp/watt32/inc \ + -I/djgpp/watt32/inc/sys + LFLAGS = CC = gcc +# Uncomment the following to enable Internationalization. +#INTLFLAGS = -DHAVE_GETTEXT -DHAVE_LIBINTL_H + +# Uncomment the following to enable SSL. +#SSLFLAGS = -DUSE_SSL +#SSLINC = -I/djgpp/include/openssl + # Directory for installed binary: !BINDIR = /usr/local/bin diff --git a/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile.sla b/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile.sla index 67e3171a74f..540f9a33cba 100644 --- a/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile.sla +++ b/gnu/usr.bin/lynx/WWW/Library/djgpp/makefile.sla @@ -7,11 +7,11 @@ WWW_MACH = djgpp # The ASIS repository's name for the machine we are on #ASIS_MACH = hardware/os -CFLAGS = -O3 -DUSE_SLANG -DUSE_ZLIB -DDOSPATH -DNOUSERS -DDISP_PARTIAL \ --DSOURCE_CACHE -DUSE_PSRC \ +CFLAGS = -O1 -DUSE_SLANG -DUSE_ZLIB -DDOSPATH -DNOUSERS -DDISP_PARTIAL \ +-DDIRED_SUPPORT -DSOURCE_CACHE -DUSE_PRETTYSRC \ +-DWATT32 \ -I../Implementation \ --I../../../djgpp/tcplib/include \ --I../../../djgpp/tcplib/include/tcp \ +-I../../../djgpp/watt32/inc -I../../../djgpp/watt32/inc/sys \ -I../../../src \ -I../../.. $(SLANGINC) $(INTLFLAGS) LFLAGS = diff --git a/gnu/usr.bin/lynx/WWW/Library/vms/descrip.mms b/gnu/usr.bin/lynx/WWW/Library/vms/descrip.mms index 6bbdaaba63e..cff613c83e3 100644 --- a/gnu/usr.bin/lynx/WWW/Library/vms/descrip.mms +++ b/gnu/usr.bin/lynx/WWW/Library/vms/descrip.mms @@ -163,7 +163,7 @@ CFLAGS = $(DEBUGFLAGS) /Define = ($(EXTRADEFINES), MULTINET) $(INCLUDES) CC = gcc .endif -!HEADERS = HTUtils.h, HTStream.h, tcp.h, HText.h - +!HEADERS = HTUtils.h, HTStream.h, www_tcp.h, HText.h - ! HTParse.h, HTAccess.h, HTTP.h, HTFile.h, - ! HTBTree.h, HTTCP.h, SGML.h, - ! HTML.h, HTMLDTD.h, HTChunk.h, HTPlain.h, - @@ -175,15 +175,15 @@ CC = gcc ! HTFinger.h, HTAABrow.h, - ! HTAAProt.h, HTAAUtil.h, - ! HTAssoc.h, HTUU.h, - -! HTVMSUtils.h, ufc-crypt.h, patchlevel.h +! HTVMSUtils.h, MODULES = HTParse, HTAccess, HTTP, HTFile, HTBTree, HTFTP, HTTCP, HTString, - SGML, HTMLDTD, HTChunk, HTPlain, HTMLGen, - HTAtom, HTAnchor, HTStyle, HTList, HTRules, HTFormat, - HTMIME, HTNews, HTGopher, HTTelnet, HTFinger, - HTWSRC, HTAAUtil, HTAABrow, HTGroup, - - HTAAProt, HTAssoc, HTLex, HTUU, HTVMSUtils, getpass, - - getline, crypt, crypt_util, HTWAIS, HTVMS_WaisUI, HTVMS_WaisProt + HTAAProt, HTAssoc, HTLex, HTUU, HTVMSUtils, - + HTWAIS, HTVMS_WaisUI, HTVMS_WaisProt !.ifdef DECNET ! Strip FTP, Gopher, News, WAIS !HEADERS = $(COMMON_HEADERS) @@ -212,7 +212,7 @@ clean : ! Simple Dependencies -!HTString.obj : HTString.c HTString.h tcp.h Version.make HTUtils.h +!HTString.obj : HTString.c HTString.h www_tcp.h Version.make HTUtils.h !HTAtom.obj : HTAtom.c HTAtom.h HTUtils.h HTString.h !HTChunk.obj : HTChunk.c HTChunk.h HTUtils.h !HTList.obj : HTList.c HTList.h HTUtils.h @@ -235,7 +235,7 @@ clean : !HTNews.obj : HTNews.c HTNews.h HTUtils.h HTList.h !HTParse.obj : HTParse.c HTParse.h HTUtils.h !HTStyle.obj : HTStyle.c HTStyle.h HTUtils.h -!HTTCP.obj : HTTCP.c HTTCP.h HTUtils.h tcp.h +!HTTCP.obj : HTTCP.c HTTCP.h HTUtils.h www_tcp.h !HTTP.obj : HTTP.c HTTP.h HTUtils.h !SGML.obj : SGML.c SGML.h HTUtils.h !HTAABrow.obj : HTAABrow.c HTUtils.h @@ -245,6 +245,4 @@ clean : !HTLex.obj : HTLex.c HTUtils.h !HTAssoc.obj : HTAssoc.c HTAssoc.h HTAAUtil.h HTString.h !HTUU.obj : HTUU.c HTUU.h HTUtils.h -!crypt.obj : crypt.c ufc-crypt.h !HTVMSUtils.obj : HTVMSUtils.c HTVMSUtils.h HTUtils.h -!crypt_util.obj : crypt_util.c ufc-crypt.h patchlevel.h diff --git a/gnu/usr.bin/lynx/WWW/Library/vms/libmake.com b/gnu/usr.bin/lynx/WWW/Library/vms/libmake.com index d0bd31eed7e..4ad07d1941f 100644 --- a/gnu/usr.bin/lynx/WWW/Library/vms/libmake.com +++ b/gnu/usr.bin/lynx/WWW/Library/vms/libmake.com @@ -176,10 +176,6 @@ $ cc [-.Implementation]HTAssoc.c $ cc [-.Implementation]HTLex.c $ cc [-.Implementation]HTUU.c $ cc [-.Implementation]HTVMSUtils.c -$ cc [-.Implementation]getpass.c -$ cc [-.Implementation]getline.c -$ cc [-.Implementation]crypt.c -$ cc [-.Implementation]crypt_util.c $ cc [-.Implementation]HTWAIS.c $ cc [-.Implementation]HTVMS_WaisUI.c $ cc [-.Implementation]HTVMS_WaisProt.c |