diff options
Diffstat (limited to 'WWW/Library/Implementation')
21 files changed, 1479 insertions, 861 deletions
diff --git a/WWW/Library/Implementation/HTAAFile.c b/WWW/Library/Implementation/HTAAFile.c index 15c2d547..a55b2f89 100644 --- a/WWW/Library/Implementation/HTAAFile.c +++ b/WWW/Library/Implementation/HTAAFile.c @@ -188,7 +188,7 @@ PUBLIC int HTAAFile_readList ARGS3(FILE *, fp, int, max_len) { char *item = NULL; - char terminator; + int terminator; int cnt = 0; do { diff --git a/WWW/Library/Implementation/HTAAUtil.c b/WWW/Library/Implementation/HTAAUtil.c index c1af8c24..512a0d0d 100644 --- a/WWW/Library/Implementation/HTAAUtil.c +++ b/WWW/Library/Implementation/HTAAUtil.c @@ -52,15 +52,6 @@ #include "HTTCP.h" #include "HTAlert.h" -#ifdef USE_SSL -#ifdef VMS -#include "[-.-.-.refssl]ssl.h" -#else -#include "../../../refssl/ssl.h" -#endif /* VMS */ -PRIVATE SSLHandle * ssl_handle=NULL; /* The SSL handle */ -#endif /* USE_SSL */ - #include "LYLeaks.h" /* PUBLIC HTAAScheme_enum() @@ -526,9 +517,6 @@ PUBLIC void HTAA_setupReader ARGS4(char *, start_of_headers, end_pointer = start_pointer; } in_soc = soc; -#ifdef USE_SSL - ssl_handle = (SSLHandle *)handle; -#endif /* USE_SSL */ } @@ -573,14 +561,7 @@ PUBLIC char *HTAA_getUnfoldedLine NOARGS /* Reading from socket */ if (start_pointer >= end_pointer) {/*Read the next block and continue*/ -#ifdef USE_SSL - if (ssl_handle) - count = SSL_Read(ssl_handle, buffer, BUFFER_SIZE); - else - count = NETREAD(in_soc, buffer, BUFFER_SIZE); -#else count = NETREAD(in_soc, buffer, BUFFER_SIZE); -#endif /* USE_SSL */ if (count <= 0) { in_soc = -1; return line; diff --git a/WWW/Library/Implementation/HTAccess.c b/WWW/Library/Implementation/HTAccess.c index 1d9725f5..330e40e0 100644 --- a/WWW/Library/Implementation/HTAccess.c +++ b/WWW/Library/Implementation/HTAccess.c @@ -193,7 +193,9 @@ PRIVATE BOOL override_proxy ARGS1(CONST char *, addr) { CONST char * no_proxy = getenv("no_proxy"); char * p = NULL; + char * at = NULL; char * host = NULL; + char * Host = NULL; char * access = NULL; int port = 0; int h_len = 0; @@ -220,14 +222,15 @@ PRIVATE BOOL override_proxy ARGS1(CONST char *, addr) FREE(host); return NO; } + Host = (((at = strchr(host, '@')) != NULL) ? (at+1) : host); if((access = HTParse(addr, "", PARSE_ACCESS))) { if (0==strcmp("file", access) && - (0==strcmp(host, "localhost") || + (0==strcmp(Host, "localhost") || #ifdef VMS - 0==strcasecomp(host, HTHostName()))) + 0==strcasecomp(Host, HTHostName()))) #else - 0==strcmp(host, HTHostName()))) + 0==strcmp(Host, HTHostName()))) #endif /* VMS */ { FREE(host); @@ -242,7 +245,7 @@ PRIVATE BOOL override_proxy ARGS1(CONST char *, addr) return NO; } - if (NULL != (p = strchr(host, ':'))) { /* Port specified */ + if (NULL != (p = strrchr(Host, ':'))) { /* Port specified */ *p++ = 0; /* Chop off port */ port = atoi(p); } else { /* Use default port */ @@ -263,7 +266,7 @@ PRIVATE BOOL override_proxy ARGS1(CONST char *, addr) } if (!port) port = 80; /* Default */ - h_len = strlen(host); + h_len = strlen(Host); while (*no_proxy) { CONST char * end; @@ -290,7 +293,7 @@ PRIVATE BOOL override_proxy ARGS1(CONST char *, addr) if ((!templ_port || templ_port == port) && (t_len > 0 && t_len <= h_len && - !strncmp(host + h_len - t_len, no_proxy, t_len))) { + !strncmp(Host + h_len - t_len, no_proxy, t_len))) { FREE(host); return YES; } diff --git a/WWW/Library/Implementation/HTAlert.h b/WWW/Library/Implementation/HTAlert.h index 8ce0be53..dc470cfd 100644 --- a/WWW/Library/Implementation/HTAlert.h +++ b/WWW/Library/Implementation/HTAlert.h @@ -81,6 +81,20 @@ extern void HTPromptUsernameAndPassword PARAMS(( char ** username, char ** password)); + +/* Confirm redirection of POST HTConfirmPostRedirect() +** +** On entry, +** redirecting_url is the Location. +** +** On exit, +** Returns 0 on cancel, +** 1 for redirect of POST with content, +** 303 for redirect as GET without content +*/ +extern int HTConfirmPostRedirect PARAMS(( + CONST char * redirecting_url)); + /* */ diff --git a/WWW/Library/Implementation/HTAnchor.c b/WWW/Library/Implementation/HTAnchor.c index 3172f1a2..a206f70f 100644 --- a/WWW/Library/Implementation/HTAnchor.c +++ b/WWW/Library/Implementation/HTAnchor.c @@ -65,21 +65,30 @@ PRIVATE HTList **adult_table = 0; /* Point to table of lists of all parents */ ** consistency, we insist that you furnish more information about the ** anchor you are creating : use newWithParent or newWithAddress. */ - PRIVATE HTParentAnchor * HTParentAnchor_new NOARGS { HTParentAnchor *newAnchor = (HTParentAnchor *)calloc(1, sizeof(HTParentAnchor)); /* zero-filled */ newAnchor->parent = newAnchor; + 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->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->cache_control = NULL; /* Cache-Control. - FM */ newAnchor->no_cache = FALSE; /* no-cache? - FM */ newAnchor->content_type = NULL; /* Content-Type. - FM */ newAnchor->content_language = NULL; /* Content-Language. - FM */ newAnchor->content_encoding = NULL; /* Compression algorith. - FM */ - newAnchor->RevTitle = NULL; /* TITLE for a LINK with REV. - FM */ + newAnchor->content_base = NULL; /* Content-Base. - FM */ + newAnchor->content_disposition = NULL; /* Content-Disposition. - FM */ + newAnchor->content_location = NULL; /* Content-Location. - FM */ + newAnchor->content_md5 = NULL; /* Content-MD5. - FM */ + newAnchor->date = NULL; /* Date. - FM */ + newAnchor->expires = NULL; /* Expires. - FM */ + newAnchor->last_modified = NULL; /* Last-Modified. - FM */ + newAnchor->server = NULL; /* Server. - FM */ return newAnchor; } @@ -99,7 +108,6 @@ PRIVATE HTChildAnchor * HTChildAnchor_new NOARGS ** returns YES if the strings are equivalent ignoring case ** NO if they differ in more than their case. */ - PRIVATE BOOL HTEquivalent ARGS2( CONST char *, s, CONST char *, t) @@ -127,7 +135,6 @@ PRIVATE BOOL HTEquivalent ARGS2( ** returns YES if the strings are identical or both NULL ** NO if they differ. */ - PRIVATE BOOL HTIdentical ARGS2( CONST char *, s, CONST char *, t) @@ -152,7 +159,6 @@ PRIVATE BOOL HTIdentical ARGS2( ** Me one is for a new anchor being edited into an existing ** document. The parent anchor must already exist. */ - PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2( HTParentAnchor *, parent, CONST char *, tag) @@ -225,6 +231,7 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4( parsed_doc.address = HTParse(href, relative_to, PARSE_ALL); parsed_doc.post_data = NULL; parsed_doc.post_content_type = NULL; + parsed_doc.bookmark = NULL; parsed_doc.isHEAD = FALSE; dest = HTAnchor_findAddress(&parsed_doc); @@ -274,7 +281,6 @@ PRIVATE void free_adult_table NOARGS ** Note: You are not guaranteed a new anchor -- you might get an old one, ** like with fonts. */ - PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( CONST DocAddress *, newdoc) { @@ -297,6 +303,7 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION); parsed_doc.post_data = newdoc->post_data; parsed_doc.post_content_type = newdoc->post_content_type; + parsed_doc.bookmark = newdoc->bookmark; parsed_doc.isHEAD = newdoc->isHEAD; foundParent = (HTParentAnchor *) HTAnchor_findAddress (&parsed_doc); @@ -337,12 +344,13 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( #ifdef CASE_INSENSITIVE_ANCHORS if (HTEquivalent(foundAnchor->address, newdoc->address) && HTEquivalent(foundAnchor->post_data, newdoc->post_data) && - foundAnchor->isHEAD == newdoc->isHEAD) { + foundAnchor->isHEAD == newdoc->isHEAD) #else if (HTIdentical(foundAnchor->address, newdoc->address) && HTIdentical(foundAnchor->post_data, newdoc->post_data) && - foundAnchor->isHEAD == newdoc->isHEAD) { + foundAnchor->isHEAD == newdoc->isHEAD) #endif /* CASE_INSENSITIVE_ANCHORS */ + { if (TRACE) fprintf(stderr, "Anchor %p with address `%s' already exists.\n", @@ -365,6 +373,8 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( if (newdoc->post_content_type) StrAllocCopy(foundAnchor->post_content_type, newdoc->post_content_type); + if (newdoc->bookmark) + StrAllocCopy(foundAnchor->bookmark, newdoc->bookmark); foundAnchor->isHEAD = newdoc->isHEAD; HTList_addObject (adults, foundAnchor); return (HTAnchor *) foundAnchor; @@ -381,7 +391,6 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1( ** We also try to delete the targets whose documents are not loaded. ** If this anchor's source list is empty, we delete it and its children. */ - PRIVATE void deleteLinks ARGS1( HTAnchor *, me) { @@ -609,6 +618,7 @@ PUBLIC BOOL HTAnchor_delete ARGS1( FREE(me->physical); FREE(me->post_data); FREE(me->post_content_type); + FREE(me->bookmark); FREE(me->owner); FREE(me->RevTitle); if (me->FileCache) { @@ -619,11 +629,20 @@ PUBLIC BOOL HTAnchor_delete ARGS1( } FREE(me->FileCache); } + FREE(me->SugFname); FREE(me->cache_control); FREE(me->content_type); FREE(me->content_language); FREE(me->content_encoding); - + FREE(me->content_base); + FREE(me->content_disposition); + FREE(me->content_location); + FREE(me->content_md5); + FREE(me->date); + FREE(me->expires); + FREE(me->last_modified); + FREE(me->server); + /* * Remove ourselves from the hash table's list. */ @@ -662,7 +681,6 @@ PUBLIC BOOL HTAnchor_delete ARGS1( ** This is to ensure that an anchor which might have already existed ** is put in the correct order as we load the document. */ - PUBLIC void HTAnchor_makeLastChild ARGS1( HTChildAnchor *, me) { @@ -676,7 +694,6 @@ PUBLIC void HTAnchor_makeLastChild ARGS1( /* Data access functions ** --------------------- */ - PUBLIC HTParentAnchor * HTAnchor_parent ARGS1( HTAnchor *, me) { @@ -775,12 +792,12 @@ PUBLIC BOOL HTAnchor_hasChildren ARGS1( return me ? ! HTList_isEmpty(me->children) : NO; } -/* Title handling +/* Title handling. */ PUBLIC CONST char * HTAnchor_title ARGS1( HTParentAnchor *, me) { - return me ? me->title : 0; + return me ? me->title : NULL; } PUBLIC void HTAnchor_setTitle ARGS2( @@ -817,12 +834,28 @@ PUBLIC void HTAnchor_appendTitle ARGS2( } } -/* Owner handling +/* Bookmark handling. +*/ +PUBLIC CONST char * HTAnchor_bookmark ARGS1( + HTParentAnchor *, me) +{ + return me ? me->bookmark : NULL; +} + +PUBLIC void HTAnchor_setBookmark ARGS2( + HTParentAnchor *, me, + CONST char *, bookmark) +{ + if (me) + StrAllocCopy(me->bookmark, bookmark); +} + +/* Owner handling. */ PUBLIC CONST char * HTAnchor_owner ARGS1( HTParentAnchor *, me) { - return (me ? me->owner : 0); + return (me ? me->owner : NULL); } PUBLIC void HTAnchor_setOwner ARGS2( @@ -834,12 +867,12 @@ PUBLIC void HTAnchor_setOwner ARGS2( } } -/* TITLE handling in LINKs with REV="made" or REV="owner" +/* TITLE handling in LINKs with REV="made" or REV="owner". - FM */ PUBLIC CONST char * HTAnchor_RevTitle ARGS1( HTParentAnchor *, me) { - return (me ? me->RevTitle : 0); + return (me ? me->RevTitle : NULL); } PUBLIC void HTAnchor_setRevTitle ARGS2( @@ -859,10 +892,43 @@ PUBLIC void HTAnchor_setRevTitle ARGS2( } } +/* Suggested filename handling. - FM +** (will be loaded if we had a Content-disposition +** header with file; filename=name.suffix) +*/ +PUBLIC CONST char * HTAnchor_SugFname ARGS1( + HTParentAnchor *, me) +{ + return me ? me->SugFname : NULL; +} + +/* Last-Modified header handling. - FM +*/ +PUBLIC CONST char * HTAnchor_last_modified ARGS1( + HTParentAnchor *, me) +{ + return me ? me->last_modified : NULL; +} + +/* Date header handling. - FM +*/ +PUBLIC CONST char * HTAnchor_date ARGS1( + HTParentAnchor *, me) +{ + return me ? me->date : NULL; +} + +/* Server header handling. - FM +*/ +PUBLIC CONST char * HTAnchor_server ARGS1( + HTParentAnchor *, me) +{ + return me ? me->server : NULL; +} + /* Link me Anchor to another given one ** ------------------------------------- */ - PUBLIC BOOL HTAnchor_link ARGS3( HTAnchor *, source, HTAnchor *, destination, @@ -896,7 +962,6 @@ PUBLIC BOOL HTAnchor_link ARGS3( /* Manipulation of links ** --------------------- */ - PUBLIC HTAnchor * HTAnchor_followMainLink ARGS1( HTAnchor *, me) { @@ -952,7 +1017,6 @@ PUBLIC BOOL HTAnchor_makeMainLink ARGS2( /* Methods List ** ------------ */ - PUBLIC HTList * HTAnchor_methods ARGS1( HTParentAnchor *, me) { @@ -965,7 +1029,6 @@ PUBLIC HTList * HTAnchor_methods ARGS1( /* Protocol ** -------- */ - PUBLIC void * HTAnchor_protocol ARGS1( HTParentAnchor *, me) { @@ -982,7 +1045,6 @@ PUBLIC void HTAnchor_setProtocol ARGS2( /* Physical Address ** ---------------- */ - PUBLIC char * HTAnchor_physical ARGS1( HTParentAnchor *, me) { diff --git a/WWW/Library/Implementation/HTAnchor.h b/WWW/Library/Implementation/HTAnchor.h index e9a137cb..92bf6716 100644 --- a/WWW/Library/Implementation/HTAnchor.h +++ b/WWW/Library/Implementation/HTAnchor.h @@ -84,8 +84,9 @@ struct _HTParentAnchor { HTList * sources; /* List of anchors pointing to this, if any */ HyperDoc * document; /* The document within which this is an anchor */ char * address; /* Absolute address of this node */ - char * post_data; /* posting data */ - char * post_content_type; /* type of post data */ + char * post_data; /* Posting data */ + char * post_content_type; /* Type of post data */ + char * bookmark; /* Bookmark filname */ HTFormat format; /* Pointer to node format descriptor */ char * charset; /* Pointer to character set (kludge, for now */ BOOL isIndex; /* Acceptance of a keyword search */ @@ -102,11 +103,20 @@ struct _HTParentAnchor { BOOL isISMAPScript; /* Script for clickable image map */ BOOL isHEAD; /* Document is headers from a HEAD request */ char * FileCache; /* Path to a disk-cached copy */ + char * SugFname; /* Suggested filename */ char * cache_control; /* Cache-Control */ BOOL no_cache; /* Cache-Control, Pragma or META "no-cache"? */ - char * content_type; /* Content-Type */ - char * content_language; /* Content-Language */ - char * content_encoding; /* Compression algorithm */ + char * content_type; /* Content-Type */ + char * content_language; /* Content-Language */ + char * content_encoding; /* Compression algorithm */ + char * content_base; /* Content-Base */ + char * content_disposition; /* Content-Dispositon */ + char * content_location; /* Content-Location */ + char * content_md5; /* Content-MD5 */ + char * date; /* Date */ + char * expires; /* Expires */ + char * last_modified; /* Last-Modified */ + char * server; /* Server */ }; typedef struct { @@ -128,6 +138,7 @@ typedef struct _DocAddress { char * address; char * post_data; char * post_content_type; + char * bookmark; BOOL isHEAD; } DocAddress; @@ -263,7 +274,7 @@ extern BOOL HTAnchor_hasChildren (HTParentAnchor *me) ); -/* Title handling +/* Title handling. */ extern CONST char * HTAnchor_title PARAMS( @@ -280,7 +291,19 @@ extern void HTAnchor_appendTitle (HTParentAnchor *me, CONST char * title) ); -/* Owner handling +/* Bookmark handling. +*/ +extern CONST char * HTAnchor_bookmark + PARAMS( + (HTParentAnchor * me) + ); + +extern void HTAnchor_setBookmark + PARAMS( + (HTParentAnchor *me, CONST char * bookmark) + ); + +/* Owner handling. */ extern CONST char * HTAnchor_owner PARAMS( @@ -292,7 +315,7 @@ extern void HTAnchor_setOwner (HTParentAnchor *me, CONST char * owner) ); -/* TITLE handling in LINKs with REV="made" or REV="owner" +/* TITLE handling in LINKs with REV="made" or REV="owner". - FM */ extern CONST char * HTAnchor_RevTitle PARAMS( @@ -304,6 +327,36 @@ extern void HTAnchor_setRevTitle (HTParentAnchor *me, CONST char * title) ); +/* Suggested filename handling. - FM +** (will be loaded if we had a Content-disposition +** header with file; filename=name.suffix) +*/ +extern CONST char * HTAnchor_SugFname + PARAMS( + (HTParentAnchor *me) + ); + +/* Last-Modified header handling. - FM +*/ +extern CONST char * HTAnchor_last_modified + PARAMS( + (HTParentAnchor *me) + ); + +/* Date header handling. - FM +*/ +extern CONST char * HTAnchor_date + PARAMS( + (HTParentAnchor *me) + ); + +/* Server header handling. - FM +*/ +extern CONST char * HTAnchor_server + PARAMS( + (HTParentAnchor *me) + ); + /* Link this Anchor to another given one ** ------------------------------------- */ diff --git a/WWW/Library/Implementation/HTFTP.c b/WWW/Library/Implementation/HTFTP.c index 9d19610f..27d929f7 100644 --- a/WWW/Library/Implementation/HTFTP.c +++ b/WWW/Library/Implementation/HTFTP.c @@ -1887,6 +1887,7 @@ PRIVATE EntryInfo * parse_dir_entry ARGS2( case PETER_LEWIS_SERVER: case MACHTEN_SERVER: case MSDOS_SERVER: + case WINDOWS_NT_SERVER: /* ** Check for EPLF output (local times). */ @@ -2004,6 +2005,7 @@ PRIVATE EntryInfo * parse_dir_entry ARGS2( */ break; +#ifdef NOTDEFINED case WINDOWS_NT_SERVER: /* ** Interpret and edit LIST output from MS_WINDOWS server @@ -2024,6 +2026,7 @@ PRIVATE EntryInfo * parse_dir_entry ARGS2( ** Goto the bottom and get real type. */ break; +#endif /* NOTDEFINED */ case CMS_SERVER: { diff --git a/WWW/Library/Implementation/HTFile.c b/WWW/Library/Implementation/HTFile.c index 9148f5d1..a41f0526 100644 --- a/WWW/Library/Implementation/HTFile.c +++ b/WWW/Library/Implementation/HTFile.c @@ -997,8 +997,16 @@ PUBLIC void HTDirEntry ARGS3( CONST char *, tail, CONST char *, entry) { - char * relative; - char * escaped = HTEscape(entry, URL_XPALPHAS); + char * relative = NULL; + char * escaped = NULL; + + if (0 == strcmp(entry,"../")) + /* + * Undo slash appending for anchor creation. + */ + StrAllocCopy(escaped,".."); + else + escaped = HTEscape(entry, URL_XPALPHAS); if (tail == NULL || *tail == '\0') { @@ -1006,7 +1014,7 @@ PUBLIC void HTDirEntry ARGS3( HTStartAnchor(target, NULL, escaped); } else { /* If empty tail, gives absolute ref below */ - relative = (char*) malloc(strlen(tail) + strlen(escaped)+2); + relative = (char*)malloc(strlen(tail) + strlen(escaped)+2); if (relative == NULL) outofmem(__FILE__, "DirRead"); sprintf(relative, "%s/%s", tail, escaped); @@ -1038,6 +1046,7 @@ PUBLIC void HTDirTitles ARGS2( TOUPPER(*(cp+6)) == 'I') *cp = '\0'; } + cp = NULL; } current = strrchr(path, '/'); /* last part or "" */ @@ -1056,7 +1065,7 @@ PUBLIC void HTDirTitles ARGS2( FREE(cp); } #else - StrAllocCopy(printable, (current + 1)); + StrAllocCopy(printable, (current ? current + 1 : "")); #endif /* DIRED_SUPPORT */ START(HTML_HEAD); @@ -1100,9 +1109,10 @@ PUBLIC void HTDirTitles ARGS2( */ if (current && current[1]) { /* was a slash AND something else too */ - char * parent; - char * relative; - *current++ = 0; + char * parent = NULL; + char * relative = NULL; + + *current++ = '\0'; parent = strrchr(path, '/'); /* penultimate slash */ if ((parent && 0 == strncasecomp(parent, "/%2F", 4)) || @@ -1126,10 +1136,36 @@ PUBLIC void HTDirTitles ARGS2( * HTVMSBrowseDir(). */ extern BOOLEAN LYisLocalFile PARAMS((char *logical)); - DIR * dp=NULL; + DIR * dp = NULL; if (LYisLocalFile(logical)) { - if ((dp = opendir(relative)) == NULL) { + /* + * We need an absolute file path for the opendir. + * We also need to unescape for this test. + * Don't worry about %2F now, they presumably have been + * dealt with above, and shouldn't appear for local + * files anyway... Assume OS / filesystem will just + * ignore superfluous slashes. - KW + */ + char * fullparentpath = NULL; + + /* + * Path has been shortened above + */ + StrAllocCopy(fullparentpath, path); + + /* + * Guard against weirdness. + */ + if (0 == strcmp(current,"..")) { + StrAllocCat(fullparentpath,"/../.."); + } else if (0 == strcmp(current,".")) { + StrAllocCat(fullparentpath,"/.."); + } + + HTUnEscape(fullparentpath); + if ((dp = opendir(fullparentpath)) == NULL) { + FREE(fullparentpath); FREE(logical); FREE(relative); FREE(path); @@ -1137,6 +1173,7 @@ PUBLIC void HTDirTitles ARGS2( } if (dp) closedir(dp); + FREE(fullparentpath); } } #endif /* !VMS */ @@ -1151,10 +1188,16 @@ PUBLIC void HTDirTitles ARGS2( #ifdef DIRED_SUPPORT if (dir_list_style == MIXED_STYLE) { PUTS("../"); - } else { -#else - { + } else #endif /* DIRED_SUPPORT */ + if ((0 == strcmp(current,".")) || + (0 == strcmp(current,".."))) { + /* + * Should not happen, but if it does. + * at least avoid giving misleading info. - KW + */ + PUTS(".."); + } else { char * printable = NULL; StrAllocCopy(printable, parent + 1); HTUnEscape(printable); @@ -1588,7 +1631,7 @@ forget_multi: while ((dirbuf = readdir(dp))!=0) { /* while there are directory entries to be read */ - HTBTElement * dirname = NULL; + char * dirname = NULL; extern BOOLEAN no_dotfiles, show_dotfiles; if (dirbuf->d_ino == 0) @@ -1607,8 +1650,7 @@ forget_multi: * begins with '.' */ continue; - dirname = (HTBTElement *)malloc( - strlen(dirbuf->d_name) + 4); + dirname = (char *)malloc(strlen(dirbuf->d_name) + 4); if (dirname == NULL) outofmem(__FILE__,"DirRead"); StrAllocCopy(tmpfilename,localname); diff --git a/WWW/Library/Implementation/HTFormat.c b/WWW/Library/Implementation/HTFormat.c index f25d36b3..75b60f39 100644 --- a/WWW/Library/Implementation/HTFormat.c +++ b/WWW/Library/Implementation/HTFormat.c @@ -11,7 +11,6 @@ ** */ - #include "HTUtils.h" #include "tcp.h" @@ -30,10 +29,9 @@ PUBLIC int loading_length= -1; #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 -#endif - + /* Full pathname would be better! */ +#endif /* NeXT */ +#endif /* unix */ #include "HTML.h" #include "HTMLDTD.h" @@ -65,7 +63,7 @@ struct _HTStream { CONST HTStreamClass* isa; /* ... */ }; -#endif +#endif /* ORIGINAL */ /* this version used by the NetToText stream */ struct _HTStream { @@ -74,11 +72,9 @@ struct _HTStream { HTStream * sink; }; - /* Presentation methods ** -------------------- */ - PUBLIC HTList * HTPresentations = NULL; PUBLIC HTPresentation * default_presentation = NULL; @@ -129,7 +125,6 @@ PUBLIC void HTSetPresentation ARGS6( } } - /* Define a built-in function for a content-type ** --------------------------------------------- */ @@ -201,7 +196,6 @@ PRIVATE void HTFreePresentations NOARGS HTPresentations = NULL; } - /* File buffering ** -------------- ** @@ -216,7 +210,6 @@ PRIVATE char * input_pointer; PRIVATE char * input_limit; PRIVATE int input_file_number; - /* Set up the buffering ** ** These routines are public because they are in fact needed by @@ -236,21 +229,22 @@ PUBLIC char HTGetCharacter NOARGS interrupted_in_htgetcharacter = 0; do { if (input_pointer >= input_limit) { - int status = NETREAD( - input_file_number, input_buffer, INPUT_BUFFER_SIZE); + int status = NETREAD(input_file_number, + input_buffer, INPUT_BUFFER_SIZE); if (status <= 0) { - if (status == 0) return (char)EOF; - if (status == HT_INTERRUPTED) - { - if (TRACE) - fprintf (stderr, - "HTFormat: Interrupted in HTGetCharacter\n"); - interrupted_in_htgetcharacter = 1; - return (char)EOF; + if (status == 0) + return (char)EOF; + if (status == HT_INTERRUPTED) { + if (TRACE) + fprintf(stderr, + "HTFormat: Interrupted in HTGetCharacter\n"); + interrupted_in_htgetcharacter = 1; + return (char)EOF; } - if (TRACE) fprintf(stderr, - "HTFormat: File read error %d\n", status); - return (char)EOF; /* -1 is returned by UCX at end of HTTP link */ + if (TRACE) + fprintf(stderr, "HTFormat: File read error %d\n", status); + return (char)EOF; /* -1 is returned by UCX + at end of HTTP link */ } input_pointer = input_buffer; input_limit = input_buffer + status; @@ -267,12 +261,12 @@ PUBLIC int HTOutputBinary ARGS2( int, input, FILE *, output) { do { - int status = NETREAD( - input, input_buffer, INPUT_BUFFER_SIZE); + int status = NETREAD(input, input_buffer, INPUT_BUFFER_SIZE); if (status <= 0) { - if (status == 0) return 0; - if (TRACE) fprintf(stderr, - "HTFormat: File read error %d\n", status); + if (status == 0) + return 0; + if (TRACE) + fprintf(stderr, "HTFormat: File read error %d\n", status); return 2; /* Error */ } fwrite(input_buffer, sizeof(char), status, output); @@ -287,21 +281,20 @@ PRIVATE int half_match ARGS2(char *,trial_type, char *,target) char *cp=strchr(trial_type,'/'); /* if no '/' or no '*' */ - if(!cp || *(cp+1) != '*') + if (!cp || *(cp+1) != '*') return 0; - if(TRACE) + if (TRACE) fprintf(stderr,"HTFormat: comparing %s and %s for half match\n", trial_type, target); /* main type matches */ - if(!strncmp(trial_type, target, (cp-trial_type)-1)) + if (!strncmp(trial_type, target, (cp-trial_type)-1)) return 1; return 0; } - /* Create a filter stack ** --------------------- ** @@ -320,20 +313,21 @@ PUBLIC HTStream * HTStreamStack ARGS4( { HTAtom * wildcard = HTAtom_for("*"); - if (TRACE) fprintf(stderr, - "HTFormat: Constructing stream stack for %s to %s\n", - HTAtom_name(rep_in), - HTAtom_name(rep_out)); + if (TRACE) + fprintf(stderr, + "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 (rep_out == WWW_SOURCE || - rep_out == rep_in) return sink; LJM */ + /* don't return on WWW_SOURCE some people might like + * to make use of the source!!!! LJM + *//* + if (rep_out == WWW_SOURCE || rep_out == rep_in) + return sink; LJM */ - if(rep_out == rep_in) return sink; + if (rep_out == rep_in) + return sink; - /* don't do anymore do it in the Lynx code at startup LJM */ + /* don't do anymore do it in the Lynx code at startup LJM */ /* if (!HTPresentations) HTFormatInit(); */ /* set up the list */ { @@ -345,46 +339,52 @@ PUBLIC HTStream * HTStreamStack ARGS4( *last_default_match=0, *strong_subtype_wildcard_match=0; - for(i=0; i<n; i++) { + for (i = 0; i < n; i++) { pres = (HTPresentation *)HTList_objectAt(HTPresentations, i); if (pres->rep == rep_in) { if (pres->rep_out == rep_out) { - if(TRACE) - fprintf(stderr,"StreamStack: found exact match: %s\n",HTAtom_name(pres->rep)); + if (TRACE) + fprintf(stderr, + "StreamStack: found exact match: %s\n", + HTAtom_name(pres->rep)); return (*pres->converter)(pres, anchor, sink); } else if (pres->rep_out == wildcard) { - if(!strong_wildcard_match) + if (!strong_wildcard_match) strong_wildcard_match = pres; /* otherwise use the first one */ - if(TRACE) - fprintf(stderr,"StreamStack: found strong wildcard match: %s\n",HTAtom_name(pres->rep)); + if (TRACE) + fprintf(stderr, + "StreamStack: found strong wildcard match: %s\n", + HTAtom_name(pres->rep)); } - } else if(half_match(HTAtom_name(pres->rep), - HTAtom_name(rep_in))) { - + } else if (half_match(HTAtom_name(pres->rep), + HTAtom_name(rep_in))) { if (pres->rep_out == rep_out) { - if(!strong_subtype_wildcard_match) - strong_subtype_wildcard_match = pres; + if (!strong_subtype_wildcard_match) + strong_subtype_wildcard_match = pres; /* otherwise use the first one */ - if(TRACE) - fprintf(stderr,"StreamStack: found strong subtype wildcard match: %s\n",HTAtom_name(pres->rep)); + if (TRACE) + fprintf(stderr, + "StreamStack: found strong subtype wildcard match: %s\n", + HTAtom_name(pres->rep)); } } if (pres->rep == WWW_SOURCE) { - if(pres->rep_out == rep_out) { - if(!weak_wildcard_match) + if (pres->rep_out == rep_out) { + if (!weak_wildcard_match) weak_wildcard_match = pres; /* otherwise use the first one */ - if(TRACE) - fprintf(stderr,"StreamStack: found weak wildcard match: %s\n",HTAtom_name(pres->rep_out)); - + if (TRACE) + fprintf(stderr, + "StreamStack: found weak wildcard match: %s\n", + HTAtom_name(pres->rep_out)); } - if(pres->rep_out == wildcard) { - if(!last_default_match) - last_default_match = pres; + if (pres->rep_out == wildcard) { + if (!last_default_match) + last_default_match = pres; /* otherwise use the first one */ } } @@ -396,20 +396,20 @@ PUBLIC HTStream * HTStreamStack ARGS4( last_default_match; if (match) { - HTPresentation temp; - temp = *match; /* Specific instance */ - temp.rep = rep_in; /* yuk */ - temp.rep_out = rep_out; /* yuk */ - if(TRACE) - fprintf(stderr,"StreamStack: Using %s\n",HTAtom_name(temp.rep_out)); - return (*match->converter)(&temp, anchor, sink); + HTPresentation temp; + temp = *match; /* Specific instance */ + temp.rep = rep_in; /* yuk */ + temp.rep_out = rep_out; /* yuk */ + if (TRACE) + fprintf(stderr, + "StreamStack: Using %s\n", HTAtom_name(temp.rep_out)); + return (*match->converter)(&temp, anchor, sink); } } return NULL; } - /* Find the cost of a filter stack ** ------------------------------- ** @@ -426,26 +426,25 @@ PUBLIC float HTStackValue ARGS4( { HTAtom * wildcard = HTAtom_for("*"); - if (TRACE) fprintf(stderr, - "HTFormat: Evaluating stream stack for %s worth %.3f to %s\n", - HTAtom_name(rep_in), initial_value, - HTAtom_name(rep_out)); + if (TRACE) + fprintf(stderr, + "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; + if (rep_out == WWW_SOURCE || rep_out == rep_in) + return 0.0; - /* don't do anymore do it in the Lynx code at startup LJM */ + /* don't do anymore do it in the Lynx code at startup LJM */ /* if (!HTPresentations) HTFormatInit(); */ /* set up the list */ { int n = HTList_count(HTPresentations); int i; HTPresentation * pres; - for(i=0; i<n; i++) { + for (i = 0; i < n; i++) { pres = (HTPresentation *)HTList_objectAt(HTPresentations, i); - if (pres->rep == rep_in && ( - pres->rep_out == rep_out || - pres->rep_out == wildcard)) { + if (pres->rep == rep_in && + (pres->rep_out == rep_out || pres->rep_out == wildcard)) { float value = initial_value * pres->quality; if (HTMaxSecs != 0.0) value = value - (length*pres->secs_per_byte + pres->secs) @@ -459,7 +458,6 @@ PUBLIC float HTStackValue ARGS4( } - /* Push data from a socket down a stream ** ------------------------------------- ** @@ -471,7 +469,6 @@ PUBLIC float HTStackValue ARGS4( ** when the format is textual. ** */ - PUBLIC int HTCopy ARGS3( int, file_number, void*, handle, @@ -479,7 +476,7 @@ PUBLIC int HTCopy ARGS3( { HTStreamClass targetClass; char line[256]; - int bytes=0; + int bytes = 0; int rv = 0; char * msg; @@ -490,17 +487,16 @@ PUBLIC int HTCopy ARGS3( msg = "Read %d of %d bytes of data."; -/* Push the data down the stream -** -*/ + /* Push the data down the stream + */ targetClass = *(sink->isa); /* Copy pointers to procedures */ /* Push binary from socket down sink ** - ** This operation could be put into a main event loop + ** This operation could be put into a main event loop */ - for(;;) { - int status; + for (;;) { + int status; extern char LYCancelDownload; if (LYCancelDownload) { @@ -510,62 +506,76 @@ PUBLIC int HTCopy ARGS3( goto finished; } - if (HTCheckForInterrupt()) - { - _HTProgress ("Data transfer interrupted."); - (*targetClass._abort)(sink, NULL); - if(bytes) - rv = HT_INTERRUPTED; + if (HTCheckForInterrupt()) { + _HTProgress ("Data transfer interrupted."); + (*targetClass._abort)(sink, NULL); + if (bytes) + rv = HT_INTERRUPTED; else rv = -1; goto finished; - } - + } status = NETREAD(file_number, input_buffer, INPUT_BUFFER_SIZE); if (status <= 0) { - if (status == 0) - break; - else if (status == HT_INTERRUPTED) - { - _HTProgress ("Data transfer interrupted."); - (*targetClass._abort)(sink, NULL); - if(bytes) - rv = HT_INTERRUPTED; - else + if (status == 0) { + break; + } else if (status == HT_INTERRUPTED) { + _HTProgress ("Data transfer interrupted."); + (*targetClass._abort)(sink, NULL); + if (bytes) + rv = HT_INTERRUPTED; + else rv = -1; - goto finished; - } - else if (SOCKET_ERRNO == ENOTCONN || SOCKET_ERRNO == ECONNRESET - || SOCKET_ERRNO == EPIPE) - { - /* Arrrrgh, HTTP 0/1 compability problem, maybe. */ - rv = -2; - goto finished; - } - break; + goto finished; + } else if (SOCKET_ERRNO == ENOTCONN || + SOCKET_ERRNO == ECONNRESET || + SOCKET_ERRNO == EPIPE) { + /* + * Arrrrgh, HTTP 0/1 compability problem, maybe. + */ + if (bytes <= 0) { + /* + * Don't have any data, so let the calling + * function decide what to do about it. - FM + */ + rv = -2; + goto finished; + } else { + /* + * Treat what we've gotten already + * as the complete transmission. - FM + */ + if (TRACE) + fprintf(stderr, + "HTCopy: Unexpected server disconnect. Treating as completed.\n"); + status = 0; + break; + } + } + break; } #ifdef NOT_ASCII { char * p; - for(p = input_buffer; p < input_buffer+status; p++) { + for (p = input_buffer; p < input_buffer+status; p++) { *p = FROMASCII(*p); } } -#endif +#endif /* NOT_ASCII */ (*targetClass.put_block)(sink, input_buffer, status); bytes += status; - sprintf(line, msg, bytes, loading_length); - HTProgress(line); + sprintf(line, msg, bytes, loading_length); + HTProgress(line); } /* next bufferload */ _HTProgress("Data transfer complete"); - NETCLOSE(file_number); + (void)NETCLOSE(file_number); rv = HT_LOADED; finished: @@ -574,8 +584,6 @@ finished: } - - /* Push data from a file pointer down a stream ** ------------------------------------- ** @@ -590,20 +598,22 @@ PUBLIC void HTFileCopy ARGS2( { HTStreamClass targetClass; -/* Push the data down the stream -** -*/ + /* Push the data down the stream + */ targetClass = *(sink->isa); /* Copy pointers to procedures */ - + /* Push binary from socket down sink */ - for(;;) { - int status = fread( - input_buffer, 1, INPUT_BUFFER_SIZE, fp); + for (;;) { + int status = fread(input_buffer, 1, INPUT_BUFFER_SIZE, fp); + if (status == 0) { /* EOF or error */ - if (ferror(fp) == 0) break; - if (TRACE) fprintf(stderr, - "HTFormat: Read error, read returns %d\n", ferror(fp)); + if (ferror(fp) == 0) + break; + if (TRACE) + fprintf(stderr, + "HTFormat: Read error, read returns %d\n", + ferror(fp)); break; } (*targetClass.put_block)(sink, input_buffer, status); @@ -611,9 +621,6 @@ PUBLIC void HTFileCopy ARGS2( } - - - /* Push data from a socket down a stream STRIPPING CR ** -------------------------------------------------- ** @@ -630,28 +637,26 @@ PUBLIC void HTCopyNoCR ARGS2( HTStream*, sink) { HTStreamClass targetClass; - -/* Push the data, ignoring CRLF, down the stream -** -*/ + char character; + + /* Push the data, ignoring CRLF, down the stream + */ targetClass = *(sink->isa); /* Copy pointers to procedures */ -/* Push text from telnet socket down sink -** -** @@@@@ To push strings could be faster? (especially is we -** cheat and don't ignore CR! :-} -*/ + /* Push text from telnet socket down sink + ** + ** @@@@@ To push strings could be faster? (especially is we + ** cheat and don't ignore CR! :-} + */ HTInitInput(file_number); - for(;;) { - char character; + for (;;) { character = HTGetCharacter(); - if (character == (char)EOF) break; + if (character == (char)EOF) + break; (*targetClass.put_character)(sink, character); } } - - /* Parse a socket given format and file number ** ** This routine is responsible for creating and PRESENTING any @@ -674,9 +679,7 @@ PUBLIC int HTParseSocket ARGS5( int rv; extern char LYCancelDownload; - stream = HTStreamStack(rep_in, - format_out, - sink , anchor); + stream = HTStreamStack(rep_in, format_out, sink, anchor); if (!stream) { char buffer[1024]; /* @@@@@@@@ */ @@ -686,13 +689,14 @@ PUBLIC int HTParseSocket ARGS5( } sprintf(buffer, "Sorry, can't convert from %s to %s.", HTAtom_name(rep_in), HTAtom_name(format_out)); - if (TRACE) fprintf(stderr, "HTFormat: %s\n", buffer); + if (TRACE) + fprintf(stderr, "HTFormat: %s\n", buffer); return HTLoadError(sink, 501, buffer); /* returns -501 */ } -/* -** Push the data, don't worry about CRLF we can strip them later. -*/ + /* + ** Push the data, don't worry about CRLF we can strip them later. + */ targetClass = *(stream->isa); /* Copy pointers to procedures */ rv = HTCopy(file_number, NULL, stream); if (rv != -1 && rv != HT_INTERRUPTED) @@ -701,8 +705,6 @@ PUBLIC int HTParseSocket ARGS5( return rv; /* full: HT_LOADED; partial: HT_INTERRUPTED; no bytes: -1 */ } - - /* Parse a file given format and file pointer ** ** This routine is responsible for creating and PRESENTING any @@ -736,17 +738,17 @@ PUBLIC int HTParseFile ARGS5( } sprintf(buffer, "Sorry, can't convert from %s to %s.", HTAtom_name(rep_in), HTAtom_name(format_out)); - if (TRACE) fprintf(stderr, "HTFormat(in HTParseFile): %s\n", buffer); + if (TRACE) + fprintf(stderr, "HTFormat(in HTParseFile): %s\n", buffer); return HTLoadError(sink, 501, buffer); } -/* Push the data down the stream -** -** -** @@ Bug: This decision ought to be made based on "encoding" -** rather than on content-type. @@@ When we handle encoding. -** The current method smells anyway. -*/ + /* Push the data down the stream + ** + ** @@ Bug: This decision ought to be made based on "encoding" + ** rather than on content-type. @@@ When we handle encoding. + ** The current method smells anyway. + */ targetClass = *(stream->isa); /* Copy pointers to procedures */ HTFileCopy(fp, stream); (*targetClass._free)(stream); @@ -754,7 +756,6 @@ PUBLIC int HTParseFile ARGS5( return HT_LOADED; } - /* Converter stream: Network Telnet to internal character text ** ----------------------------------------------------------- ** @@ -765,12 +766,11 @@ PUBLIC int HTParseFile ARGS5( ** C representation of a new line. */ - PRIVATE void NetToText_put_character ARGS2(HTStream *, me, char, net_char) { char c = FROMASCII(net_char); if (me->had_cr) { - if (c==LF) { + if (c == LF) { me->sink->isa->put_character(me->sink, '\n'); /* Newline */ me->had_cr = NO; return; @@ -778,7 +778,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 = (c == CR); if (!me->had_cr) me->sink->isa->put_character(me->sink, c); /* normal */ } @@ -787,14 +787,16 @@ PRIVATE void NetToText_put_string ARGS2(HTStream *, me, CONST char *, s) { CONST char * p; - for (p=s; *p; p++) + for (p = s; *p; p++) NetToText_put_character(me, *p); } PRIVATE void NetToText_put_block ARGS3(HTStream *, me, CONST char*, s, int, l) { CONST char * p; - for(p=s; p<(s+l); p++) NetToText_put_character(me, *p); + + for (p = s; p < (s+l); p++) + NetToText_put_character(me, *p); } PRIVATE void NetToText_free ARGS1(HTStream *, me) @@ -825,6 +827,7 @@ PRIVATE HTStreamClass NetToTextClass = { PUBLIC HTStream * HTNetToText ARGS1(HTStream *, sink) { HTStream* me = (HTStream*)malloc(sizeof(*me)); + if (me == NULL) outofmem(__FILE__, "NetToText"); me->isa = &NetToTextClass; diff --git a/WWW/Library/Implementation/HTGroup.c b/WWW/Library/Implementation/HTGroup.c index e281a578..c7abb13e 100644 --- a/WWW/Library/Implementation/HTGroup.c +++ b/WWW/Library/Implementation/HTGroup.c @@ -76,7 +76,7 @@ PRIVATE void syntax_error ARGS3(FILE *, fp, { char buffer[41]; int cnt = 0; - char ch; + int ch; while ((ch = getc(fp)) != EOF && ch != '\n') if (cnt < 40) buffer[cnt++] = ch; diff --git a/WWW/Library/Implementation/HTMIME.c b/WWW/Library/Implementation/HTMIME.c index 313c34b9..96e6ffb4 100644 --- a/WWW/Library/Implementation/HTMIME.c +++ b/WWW/Library/Implementation/HTMIME.c @@ -49,6 +49,7 @@ typedef enum _MIME_state { miCONNECTION, miCONTENT_, miCONTENT_BASE, + miCONTENT_DISPOSITION, miCONTENT_ENCODING, miCONTENT_FEATURES, miCONTENT_L, @@ -75,7 +76,10 @@ typedef enum _MIME_state { miPROXY_AUTHENTICATE, miPUBLIC, miRETRY_AFTER, + miS, + miSE, miSERVER, + miSET_COOKIE, miT, miTITLE, miTRANSFER_ENCODING, @@ -227,7 +231,7 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) me->state = miCHECK; if (TRACE) fprintf(stderr, - "HTMIME: Got 'S' at beginning of line, checking for 'eep-alive:'\n"); + "HTMIME: Got 'K' at beginning of line, checking for 'eep-alive:'\n"); break; case 'l': @@ -258,12 +262,10 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) case 's': case 'S': - me->check_pointer = "erver:"; - me->if_ok = miSERVER; - me->state = miCHECK; + me->state = miS; if (TRACE) - fprintf(stderr, - "HTMIME: Got 'S' at beginning of line, checking for 'erver'\n"); + fprintf (stderr, + "HTMIME: Got 'S' at beginning of line, state now S\n"); break; case 't': @@ -535,12 +537,12 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) switch (c) { case 'l': case 'L': - me->check_pointer = "low:"; + me->check_pointer = "ow:"; me->if_ok = miALLOW; me->state = miCHECK; if (TRACE) fprintf(stderr, - "HTMIME: Was AL, found L, checking for 'low:'\n"); + "HTMIME: Was AL, found L, checking for 'ow:'\n"); break; case 't': @@ -629,12 +631,12 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) switch (c) { case 'n': case 'N': - me->check_pointer = "nection:"; + me->check_pointer = "ection:"; me->if_ok = miCONNECTION; me->state = miCHECK; if (TRACE) fprintf(stderr, - "HTMIME: Was CON, found N, checking for 'nection:'\n"); + "HTMIME: Was CON, found N, checking for 'ection:'\n"); break; case 't': @@ -740,12 +742,12 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) case 'R': me->state = miPR; if (TRACE) - fprintf(stderr, "HTMIME: Was P, found O, state now PR'\n"); + fprintf(stderr, "HTMIME: Was P, found R, state now PR'\n"); break; case 'u': case 'U': - me->check_pointer = "lic:"; + me->check_pointer = "blic:"; me->if_ok = miPUBLIC; me->state = miCHECK; if (TRACE) @@ -768,12 +770,12 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) switch (c) { case 'a': case 'A': - me->check_pointer = "agma:"; + me->check_pointer = "gma:"; me->if_ok = miPRAGMA; me->state = miCHECK; if (TRACE) fprintf(stderr, - "HTMIME: Was PR, found A, checking for 'agma'\n"); + "HTMIME: Was PR, found A, checking for 'gma'\n"); break; case 'o': @@ -797,6 +799,59 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) } /* switch on character */ break; + case miS: /* Check for 'e' */ + switch (c) { + case 'e': + case 'E': + me->state = miSE; + if (TRACE) + fprintf(stderr, "HTMIME: Was S, found E, state now SE'\n"); + break; + + default: + if (TRACE) + fprintf(stderr, + "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'e'"); + goto bad_field_name; + break; + + } /* switch on character */ + break; + + case miSE: /* Check for 'r' or 't' */ + switch (c) { + case 'r': + case 'R': + me->check_pointer = "ver:"; + me->if_ok = miSERVER; + me->state = miCHECK; + if (TRACE) + fprintf(stderr, + "HTMIME: Was SE, found R, checking for 'ver'\n"); + break; + + case 't': + case 'T': + me->check_pointer = "-cookie:"; + me->if_ok = miSET_COOKIE; + me->state = miCHECK; + if (TRACE) + fprintf(stderr, + "HTMIME: Was SE, found T, checking for '-cookie'\n"); + break; + + default: + if (TRACE) + fprintf(stderr, + "HTMIME: Bad character `%c' found where `%s' expected\n", + c, "'r' or 't'"); + goto bad_field_name; + break; + + } /* switch on character */ + break; + case miT: /* Check for 'i' or 'r' */ switch (c) { case 'i': @@ -957,6 +1012,16 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) "HTMIME: Was CONTENT_, found B, checking for 'ase:'\n"); break; + case 'd': + case 'D': + me->check_pointer = "isposition:"; + me->if_ok = miCONTENT_DISPOSITION; + me->state = miCHECK; + if (TRACE) + fprintf(stderr, + "HTMIME: Was CONTENT_, found D, checking for 'isposition:'\n"); + break; + case 'e': case 'E': me->check_pointer = "ncoding:"; @@ -1101,6 +1166,7 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) case miCOOKIE: case miCONNECTION: case miCONTENT_BASE: + case miCONTENT_DISPOSITION: case miCONTENT_ENCODING: case miCONTENT_FEATURES: case miCONTENT_LANGUAGE: @@ -1122,6 +1188,7 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) case miPUBLIC: case miRETRY_AFTER: case miSERVER: + case miSET_COOKIE: case miTITLE: case miTRANSFER_ENCODING: case miUPGRADE: @@ -1183,6 +1250,8 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "HTMIME: PICKED UP Cache-Control: '%s'\n", me->value); + if (!(me->value && *me->value)) + break; /* ** Convert to lowercase and indicate in anchor. - FM */ @@ -1212,6 +1281,49 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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: + if (TRACE) + fprintf(stderr, + "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); + /* + ** If it includes file; filename=name.suffix + ** load the me->SugFname element. - FM + */ + cp = me->anchor->content_disposition; + while (*cp != '\0' && strncasecomp(cp, "file;", 5)) + cp++; + if (*cp != '\0') { + cp += 5; + while (*cp != '\0' && WHITE(*cp)) + cp++; + if (*cp != '\0') { + while (*cp != '\0' && strncasecomp(cp, "filename=", 9)) + cp++; + if (*cp != '\0') { + StrAllocCopy(me->anchor->SugFname, (cp + 9)); + 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: if (TRACE) @@ -1256,6 +1368,8 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "HTMIME: PICKED UP Content-Language: '%s'\n", me->value); + if (!(me->value && *me->value)) + break; /* ** Convert to lowercase and indicate in anchor. - FM */ @@ -1264,12 +1378,23 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) StrAllocCopy(me->anchor->content_language, me->value); break; case miCONTENT_LENGTH: + if (TRACE) + fprintf(stderr, + "HTMIME: PICKED UP Content-Length: '%s'\n", + me->value); + if (!(me->value && *me->value)) + break; + /* + ** Convert to integer and indicate in anchor. - FM + */ me->content_length = atoi(me->value); - /* This is TEMPORARY. */ + /* + ** This is TEMPORARY. + */ loading_length = me->content_length; if (TRACE) fprintf(stderr, - "HTMIME: PICKED UP Content-Length: '%d'\n", + " Converted to integer: '%d'\n", me->content_length); break; case miCONTENT_LOCATION: @@ -1277,12 +1402,24 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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: if (TRACE) fprintf(stderr, "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: if (TRACE) @@ -1295,6 +1432,8 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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 @@ -1308,6 +1447,8 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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. - FM @@ -1325,6 +1466,12 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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: if (TRACE) @@ -1337,6 +1484,12 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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: if (TRACE) @@ -1349,6 +1502,12 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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: if (TRACE) @@ -1367,6 +1526,8 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "HTMIME: PICKED UP Pragma: '%s'\n", me->value); + if (!(me->value && *me->value)) + break; /* * Check whether to set no_cache for the anchor. - FM */ @@ -1396,6 +1557,18 @@ PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c) fprintf(stderr, "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_COOKIE: + if (TRACE) + fprintf(stderr, + "HTMIME: PICKED UP Set-Cookie: '%s'\n", + me->value); break; case miTITLE: if (TRACE) @@ -1579,9 +1752,18 @@ PUBLIC HTStream* HTMIMEConvert ARGS3( me->anchor = anchor; me->anchor->no_cache = FALSE; FREE(me->anchor->cache_control); + FREE(me->anchor->SugFname); FREE(me->anchor->charset); FREE(me->anchor->content_language); FREE(me->anchor->content_encoding); + FREE(me->anchor->content_base); + FREE(me->anchor->content_disposition); + FREE(me->anchor->content_location); + FREE(me->anchor->content_md5); + FREE(me->anchor->date); + FREE(me->anchor->expires); + FREE(me->anchor->last_modified); + FREE(me->anchor->server); me->target = NULL; me->state = miBEGINNING_OF_LINE; /* @@ -1919,7 +2101,7 @@ PUBLIC int HTrjis ARGS2( */ /* * RJIS ( Recover JIS code from broken file ) - * $Header: /usr/build/VCS/lynx/WWW/Library/Implementation/RCS/HTMIME.c,v 1.1 1996/09/02 00:21:10 tom Exp $ + * @Header: rjis.c,v 0.2 92/09/04 takahasi Exp @ * Copyright (C) 1992 1994 * Hironobu Takahashi (takahasi@tiny.or.jp) * diff --git a/WWW/Library/Implementation/HTMLDTD.c b/WWW/Library/Implementation/HTMLDTD.c index 3a982b2f..403c79f1 100644 --- a/WWW/Library/Implementation/HTMLDTD.c +++ b/WWW/Library/Implementation/HTMLDTD.c @@ -249,9 +249,9 @@ static attr body_attr[] = { /* BODY attributes */ { "ID" }, { "LANG" }, { "LINK" }, - { "STYLE" }, { "ONLOAD" }, { "ONUNLOAD" }, + { "STYLE" }, { "TEXT" }, { "VLINK" }, { 0 } /* Terminate list */ @@ -600,8 +600,8 @@ static attr list_attr[] = { /* LI attributes */ { "ID" }, { "LANG" }, { "MD" }, - { "SRC" }, { "SKIP" }, + { "SRC" }, { "STYLE" }, { "TYPE" }, { "VALUE" }, @@ -747,10 +747,10 @@ static attr param_attr[] = { /* PARAM attribures */ { "ACCEPT-ENCODING" }, { "CLASS" }, { "CLEAR" }, + { "DATA" }, { "DIR" }, { "ID" }, { "LANG" }, - { "DATA" }, { "NAME" }, { "OBJECT" }, { "REF" }, @@ -774,8 +774,8 @@ static attr script_attr[] = { /* SCRIPT attribures */ { "NAME" }, { "SCRIPTENGINE" }, { "SRC" }, - { "TYPE" }, { "STYLE" }, + { "TYPE" }, { 0 } /* Terminate list */ }; diff --git a/WWW/Library/Implementation/HTMLDTD.h b/WWW/Library/Implementation/HTMLDTD.h index a176e59b..aad12417 100644 --- a/WWW/Library/Implementation/HTMLDTD.h +++ b/WWW/Library/Implementation/HTMLDTD.h @@ -1,11 +1,12 @@ -/* The HTML DTD -- software interface in libwww +/* The HTML DTD -- software interface in libwww HTML DTD - SOFTWARE INTERFACE - SGML purists should excuse the use of the term "DTD" in this file to represent - DTD-related information which is not exactly a DTD itself. + SGML purists should excuse the use of the term "DTD" in this file to + represent DTD-related information which is not exactly a DTD itself. - The C modular structure doesn't work very well here, as the dtd is partly in the .h and - partly in the .c which are not very independent. Tant pis. + The C modular structure doesn't work very well here, as the dtd is + partly in the .h and partly in the .c which are not very independent. + Tant pis. */ #ifndef HTMLDTD_H @@ -252,20 +253,20 @@ Attribute numbers #define HTML_BQ_STYLE 6 #define HTML_BQ_ATTRIBUTES 7 -#define HTML_BODYTEXT_CLASS 1 -#define HTML_BODYTEXT_CLEAR 2 -#define HTML_BODYTEXT_DATA 3 -#define HTML_BODYTEXT_DIR 4 -#define HTML_BODYTEXT_ID 5 -#define HTML_BODYTEXT_LANG 6 -#define HTML_BODYTEXT_NAME 7 -#define HTML_BODYTEXT_OBJECT 8 -#define HTML_BODYTEXT_REF 9 -#define HTML_BODYTEXT_STYLE 10 -#define HTML_BODYTEXT_TYPE 11 -#define HTML_BODYTEXT_VALUE 12 -#define HTML_BODYTEXT_VALUETYPE 13 -#define HTML_BODYTEXT_ATTRIBUTES 14 +#define HTML_BODYTEXT_CLASS 0 +#define HTML_BODYTEXT_CLEAR 1 +#define HTML_BODYTEXT_DATA 2 +#define HTML_BODYTEXT_DIR 3 +#define HTML_BODYTEXT_ID 4 +#define HTML_BODYTEXT_LANG 5 +#define HTML_BODYTEXT_NAME 6 +#define HTML_BODYTEXT_OBJECT 7 +#define HTML_BODYTEXT_REF 8 +#define HTML_BODYTEXT_STYLE 9 +#define HTML_BODYTEXT_TYPE 10 +#define HTML_BODYTEXT_VALUE 11 +#define HTML_BODYTEXT_VALUETYPE 12 +#define HTML_BODYTEXT_ATTRIBUTES 13 #define HTML_BODY_ALINK 0 #define HTML_BODY_BACKGROUND 1 @@ -555,8 +556,8 @@ Attribute numbers #define HTML_LI_ID 4 #define HTML_LI_LANG 5 #define HTML_LI_MD 6 -#define HTML_LI_SRC 7 -#define HTML_LI_SKIP 8 +#define HTML_LI_SKIP 7 +#define HTML_LI_SRC 8 #define HTML_LI_STYLE 9 #define HTML_LI_TYPE 10 #define HTML_LI_VALUE 11 @@ -671,8 +672,8 @@ Attribute numbers #define HTML_P_DIR 3 #define HTML_P_ID 4 #define HTML_P_LANG 5 -#define HTML_P_STYLE 6 -#define HTML_P_NOWRAP 7 +#define HTML_P_NOWRAP 6 +#define HTML_P_STYLE 7 #define HTML_P_ATTRIBUTES 8 #define HTML_PARAM_ACCEPT 0 diff --git a/WWW/Library/Implementation/HTNews.c b/WWW/Library/Implementation/HTNews.c index 7eeb7c2a..73406922 100644 --- a/WWW/Library/Implementation/HTNews.c +++ b/WWW/Library/Implementation/HTNews.c @@ -38,8 +38,9 @@ PUBLIC int HTNewsMaxChunk = 40; /* Largest number of articles in one window */ #define SERVER_FILE "/usr/local/lib/rn/server" #endif -#define NEWS_NETREAD NETREAD #define NEWS_NETWRITE NETWRITE +#define NEWS_NETCLOSE NETCLOSE +#define NEXT_CHAR HTGetCharacter() #include <ctype.h> @@ -57,7 +58,6 @@ struct _HTStructured { /* ... */ }; -#define NEXT_CHAR HTGetCharacter() #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; @@ -184,7 +184,7 @@ PRIVATE int response ARGS1(CONST char *,command) if (status < 0){ if (TRACE) fprintf(stderr, "HTNews: Unable to send command. Disconnecting.\n"); - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; return status; } /* if bad status */ @@ -202,7 +202,7 @@ PRIVATE int response ARGS1(CONST char *,command) if ((ch = *(p-1)) == (char)EOF) { if (TRACE) fprintf(stderr, "HTNews: EOF on read, closing socket %d\n", s); - NETCLOSE(s); /* End of file, close socket */ + NEWS_NETCLOSE(s); /* End of file, close socket */ return s = -1; /* End of file on response */ } } /* Loop over characters */ @@ -453,7 +453,7 @@ PRIVATE void abort_socket NOARGS if (TRACE) fprintf(stderr, "HTNews: EOF on read, closing socket %d\n", s); - NETCLOSE(s); /* End of file, close socket */ + NEWS_NETCLOSE(s); /* End of file, close socket */ PUTS("Network Error: connection lost"); PUTC('\n'); s = -1; /* End of file on response */ @@ -1308,6 +1308,7 @@ PUBLIC int HTLoadNews ARGS4( HTStream*, stream) { char command[260]; /* The whole command */ + char proxycmd[260]; /* The proxy command */ char groupName[GROUP_NAME_LENGTH]; /* Just the group name */ int status; /* tcp return */ int retries; /* A count of how hard we have tried */ @@ -1342,8 +1343,8 @@ PUBLIC int HTLoadNews ARGS4( ** xxxxx News group (no "@") ** group/n1-n2 Articles n1 to n2 in group */ - group_wanted = (strchr(arg, '@')==0) && (strchr(arg, '*')==0); - list_wanted = (strchr(arg, '@')==0) && (strchr(arg, '*')!=0); + group_wanted = (strchr(arg, '@') == NULL) && (strchr(arg, '*') == NULL); + list_wanted = (strchr(arg, '@') == NULL) && (strchr(arg, '*') != NULL); /* p1 = HTParse(arg, "", PARSE_PATH | PARSE_PUNCTUATION); */ /* @@ -1361,19 +1362,19 @@ PUBLIC int HTLoadNews ARGS4( } if (!(cp = HTParse(arg, "", PARSE_HOST)) || *cp == '\0') { if (s >= 0 && NewsHost && strcasecomp(NewsHost, HTNewsHost)) { - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; } StrAllocCopy(NewsHost, HTNewsHost); } else { if (s >= 0 && NewsHost && strcasecomp(NewsHost, cp)) { - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; } StrAllocCopy(NewsHost, cp); } FREE(cp); - sprintf(command, "nntp://%s/", NewsHost); + sprintf(command, "nntp://%.250s/", NewsHost); StrAllocCopy(NewsHREF, command); } else if (!strncasecomp(arg, "snews:", 6)) { @@ -1390,30 +1391,60 @@ PUBLIC int HTLoadNews ARGS4( } if (!(cp = HTParse(arg, "", PARSE_HOST)) || *cp == '\0') { if (s >= 0 && NewsHost && strcasecomp(NewsHost, HTNewsHost)) { - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; } StrAllocCopy(NewsHost, HTNewsHost); } else { if (s >= 0 && NewsHost && strcasecomp(NewsHost, cp)) { - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; } StrAllocCopy(NewsHost, cp); } FREE(cp); - sprintf(command, "news://%s/", NewsHost); + sprintf(command, "news://%.250s/", NewsHost); StrAllocCopy(NewsHREF, command); - } - else { + } else { p1 = arg + 5; /* Skip "news:" prefix */ if (s >= 0 && NewsHost && strcasecomp(NewsHost, HTNewsHost)) { - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; } StrAllocCopy(NewsHost, HTNewsHost); StrAllocCopy(NewsHREF, "news:"); } + + /* + * Set up any proxy for snews URLs that returns NNTP + * responses for Lynx to convert to HTML, instead of + * doing the conversion itself. - TZ & FM + */ + proxycmd[0] = '\0'; + if (!strncasecomp (p1, "snews://", 8)) { + if ((cp = strchr((p1+8), '/')) != NULL) + *cp = '\0'; + sprintf(command, "%.258s/", p1); + StrAllocCopy(NewsHREF, command); + sprintf(proxycmd, "GET %.250s%c%c%c%c", p1, CR, LF, CR, LF); + if ((cp == NULL) || *(cp+1) == '\0') { + p1 = "*"; + group_wanted = FALSE; + list_wanted = TRUE; + } else { + p1 = (cp+1); + } + if (cp != NULL) + *cp = '/'; + if (TRACE) + fprintf(stderr, + "HTNews: Proxy command is '%.*s'\n", + (strlen(proxycmd) - 4), proxycmd); + } + + /* + * Set up command for a listing or article request. - FM + */ if (list_wanted) { strcpy(command, "LIST NEWSGROUPS"); } else if (group_wanted) { @@ -1453,10 +1484,12 @@ PUBLIC int HTLoadNews ARGS4( { char * p = command + strlen(command); + /* + * Teminate command with CRLF, as in RFC 977. + */ *p++ = CR; /* Macros to be correct on Mac */ *p++ = LF; *p++ = 0; - /* strcat(command, "\r\n"); */ /* CR LF, as in rfc 977 */ } StrAllocCopy(ListArg, p1); } /* scope of p1 */ @@ -1509,7 +1542,7 @@ PUBLIC int HTLoadNews ARGS4( } if (status < 0) { char message[256]; - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; if (TRACE) fprintf(stderr, @@ -1526,9 +1559,16 @@ PUBLIC int HTLoadNews ARGS4( fprintf(stderr, "HTNews: Connected to news host %s.\n", NewsHost); HTInitInput(s); /* set up buffering */ + if (proxycmd[0]) { + status = NEWS_NETWRITE(s, proxycmd, strlen(proxycmd)); + if (TRACE) + fprintf(stderr, + "HTNews: Proxy command returned status '%d'.\n", + status); + } if ((response(NULL) / 100) != 2) { char message[BIG]; - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; if (retries < 1) continue; @@ -1576,7 +1616,7 @@ Send_NNTP_command: HTAlert(response_text); else _HTProgress(response_text); - NETCLOSE(s); + NEWS_NETCLOSE(s); s = -1; /* * Message might be a leftover "Timeout-disconnected", diff --git a/WWW/Library/Implementation/HTParse.c b/WWW/Library/Implementation/HTParse.c index 463488f7..5c455a65 100644 --- a/WWW/Library/Implementation/HTParse.c +++ b/WWW/Library/Implementation/HTParse.c @@ -585,6 +585,10 @@ PUBLIC char * HTUnEscape ARGS1( { char * p = str; char * q = str; + + if (!(p && *p)) + return str; + while (*p) { if (*p == HEX_ESCAPE) { p++; @@ -603,4 +607,43 @@ PUBLIC char * HTUnEscape ARGS1( } /* HTUnEscape */ +/* Decode some %xx escaped characters HTUnEscapeSome() +** ---------------------------------- Klaus Weide +** (kweide@tezcat.com) +** This function takes a pointer to a string in which some +** characters may have been encoded in %xy form, where xy is +** the acsii hex code for character 16x+y, and a pointer to +** a second string containing one or more characters which +** should be unescaped if escaped in the first string. +** The first string is converted in place, as it will never grow. +*/ +PUBLIC char * HTUnEscapeSome ARGS2( + char *, str, + CONST char *, do_trans) +{ + char * p = str; + char * q = str; + char testcode; + + if (!(p && *p) || !(do_trans && *do_trans)) + return str; + + while (*p) { + 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 = 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++ = FROMASCII(testcode); + p += 3; + } else { + *q++ = *p++; + } + } + + *q++ = '\0'; + return str; + +} /* HTUnEscapeSome */ diff --git a/WWW/Library/Implementation/HTParse.h b/WWW/Library/Implementation/HTParse.h index 669837c2..30cb74f5 100644 --- a/WWW/Library/Implementation/HTParse.h +++ b/WWW/Library/Implementation/HTParse.h @@ -1,9 +1,10 @@ -/* HTParse: URL parsing in the WWW Library - HTPARSE - - This module of the WWW library contains code to parse URLs and various related things. +/* HTParse: URL parsing in the WWW Library + HTPARSE + + This module of the WWW library contains code to parse URLs and various + related things. Implemented by HTParse.c . - + */ #ifndef HTPARSE_H #define HTPARSE_H @@ -14,9 +15,9 @@ /* - The following are flag bits which may be ORed together to form a number to give the - 'wanted' argument to HTParse. - + The following are flag bits which may be ORed together to form a number to + give the 'wanted' argument to HTParse. + */ #define PARSE_ACCESS 16 #define PARSE_HOST 8 @@ -30,21 +31,21 @@ HTParse: Parse a URL relative to another URL - This returns those parts of a name which are given (and requested) substituting bits - from the related name where necessary. - + This returns those parts of a name which are given (and requested) + substituting bits from the related name where necessary. + ON ENTRY - + aName A filename given - + relatedName A name relative to which aName is to be parsed - + wanted A mask for the bits which are wanted. - + ON EXIT, - + returns A pointer to a malloc'd string which MUST BE FREED - + */ extern char * HTParse PARAMS(( @@ -58,11 +59,11 @@ extern char * HTParse PARAMS(( HTStrip: Strip white space off a string ON EXIT - + Return value points to first non-white character, or to 0 if none. - + All trailing white space is OVERWRITTEN with zero. - + */ extern char * HTStrip PARAMS(( char * s)); @@ -71,11 +72,11 @@ extern char * HTStrip PARAMS(( HTSimplify: Simplify a UTL - A URL is allowed to contain the seqeunce xxx/../ which may be replaced by "" , and the - seqeunce "/./" which may be replaced by "/". Simplification helps us recognize - duplicate filenames. It doesn't deal with soft links, though. The new (shorter) - filename overwrites the old. - + A URL is allowed to contain the seqeunce xxx/../ which may be replaced by + "" , and the seqeunce "/./" which may be replaced by "/". Simplification + helps us recognize duplicate filenames. It doesn't deal with soft links, + though. The new (shorter) filename overwrites the old. + */ /* ** Thus, /etc/junk/../fred becomes /etc/fred @@ -89,19 +90,20 @@ extern void HTSimplify PARAMS(( HTRelative: Make Relative (Partial) URL - This function creates and returns a string which gives an expression of one address as - related to another. Where there is no relation, an absolute address is retured. - + This function creates and returns a string which gives an expression of one + address as related to another. Where there is no relation, an absolute + address is retured. + ON ENTRY, - + Both names must be absolute, fully qualified names of nodes (no anchor bits) - + ON EXIT, - - The return result points to a newly allocated name which, if parsed by HTParse relative - to relatedName, will yield aName. The caller is responsible for freeing the resulting - name later. - + + The return result points to a newly allocated name which, if parsed by + HTParse relative to relatedName, will yield aName. The caller is + responsible for freeing the resulting name later. + */ extern char * HTRelative PARAMS(( CONST char * aName, @@ -112,10 +114,11 @@ extern char * HTRelative PARAMS(( HTEscape: Encode unacceptable characters in string - This funtion takes a string containing any sequence of ASCII characters, and returns a - malloced string containing the same infromation but with all "unacceptable" characters - represented in the form %xy where X and Y are two hex digits. - + This function takes a string containing any sequence of ASCII characters, + and returns a malloced string containing the same infromation but with all + "unacceptable" characters represented in the form %xy where X and Y are two + hex digits. + */ extern char * HTEscape PARAMS(( CONST char * str, @@ -128,8 +131,9 @@ extern char * HTEscapeSP PARAMS(( /* - The following are valid mask values. The terms are the BNF names in the URL document. - + 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 @@ -140,15 +144,31 @@ extern char * HTEscapeSP PARAMS(( HTUnEscape: Decode %xx escaped characters - This function takes a pointer to a string in which character smay have been encoded in - %xy form, where xy is the acsii hex code for character 16x+y. The string is converted - in place, as it will never grow. - + This function takes a pointer to a string in which character smay have been + encoded in %xy form, where xy is the acsii hex code for character 16x+y. + The string is converted in place, as it will never grow. + */ extern char * HTUnEscape PARAMS(( char * str)); +/* + +HTUnEscapeSome: Decode some %xx escaped characters - KW + + This function takes a pointer to a string in which some characters may have + been encoded in %xy form, where xy is the acsii hex code for character + 16x+y, and a pointer to a second string containing one or more characters + which should be unescaped if escaped in the first string. + The first string is converted in place, as it will never grow. + + */ +extern char * HTUnEscapeSome PARAMS(( + char * str, + CONST char * do_trans)); + + #endif /* HTPARSE_H */ diff --git a/WWW/Library/Implementation/HTPasswd.c b/WWW/Library/Implementation/HTPasswd.c index 58ae62c8..e08bfbeb 100644 --- a/WWW/Library/Implementation/HTPasswd.c +++ b/WWW/Library/Implementation/HTPasswd.c @@ -218,7 +218,7 @@ PUBLIC int HTAAFile_readPasswdRec ARGS3(FILE *, fp, char *, out_username, char *, out_password) { - char terminator; + int terminator; terminator = HTAAFile_readField(fp, out_username, MAX_USERNAME_LEN); diff --git a/WWW/Library/Implementation/HTTCP.c b/WWW/Library/Implementation/HTTCP.c index 45d8a979..2ea6906c 100644 --- a/WWW/Library/Implementation/HTTCP.c +++ b/WWW/Library/Implementation/HTTCP.c @@ -23,6 +23,11 @@ #include "HTParse.h" #include "HTAlert.h" +#ifdef NSL_FORK +#include <signal.h> +#include <sys/wait.h> +#endif /* NSL_FORM */ + #define FREE(x) if (x) {free(x); x = NULL;} extern int HTCheckForInterrupt NOPARAMS; @@ -48,7 +53,7 @@ PUBLIC int BSDselect PARAMS((int nfds, fd_set * readfds, fd_set * writefds, #define HTInetStatus HTInStat #define HTInetString HTInStri #define HTParseInet HTPaInet -#endif +#endif /* SHORT_NAMES */ #ifndef FD_SETSIZE #if defined(UCX) || defined(SOCKETSHR_TCP) || defined(CMU_TCP) @@ -56,17 +61,15 @@ PUBLIC int BSDselect PARAMS((int nfds, fd_set * readfds, fd_set * writefds, #else #define FD_SETSIZE 256 #endif /* Limit # sockets to 32 for UCX, BSN - also SOCKETSHR and CMU, AH */ -#endif +#endif /* FD_SETSIZE */ /* Module-Wide variables */ - PRIVATE char *hostname = NULL; /* The name of this host */ /* PUBLIC VARIABLES */ - #ifdef SOCKS extern BOOLEAN socks_flag; PUBLIC unsigned long socks_bind_remoteAddr; /* for long Rbind */ @@ -122,60 +125,52 @@ extern int sys_nerr; #define IOC_OUT (int)0x40000000 extern int vaxc$get_sdc(), sys$qiow(); -PUBLIC int HTioctl ARGS3 - (int, d, +PUBLIC int HTioctl ARGS3( + int, d, int, request, int *, argp) { - int sdc, status; - unsigned short fun, iosb[4]; - char *p5, *p6; - struct comm - { - int command; - char *addr; + int sdc, status; + unsigned short fun, iosb[4]; + char *p5, *p6; + struct comm { + int command; + char *addr; } ioctl_comm; - struct it2 - { - unsigned short len; - unsigned short opt; - struct comm *addr; + struct it2 { + unsigned short len; + unsigned short opt; + struct comm *addr; } ioctl_desc; - if ((sdc = vaxc$get_sdc (d)) == 0) - { - errno = EBADF; - return -1; - } - ioctl_desc.opt = UCX$C_IOCTL; - ioctl_desc.len = sizeof(struct comm); - ioctl_desc.addr = &ioctl_comm; - if (request & IOC_OUT) - { - fun = IO$_SENSEMODE; - p5 = 0; - p6 = (char *)&ioctl_desc; + + if ((sdc = vaxc$get_sdc (d)) == 0) { + errno = EBADF; + return -1; } - else - { - fun = IO$_SETMODE; - p5 = (char *)&ioctl_desc; - p6 = 0; + ioctl_desc.opt = UCX$C_IOCTL; + ioctl_desc.len = sizeof(struct comm); + ioctl_desc.addr = &ioctl_comm; + if (request & IOC_OUT) { + fun = IO$_SENSEMODE; + p5 = 0; + p6 = (char *)&ioctl_desc; + } else { + fun = IO$_SETMODE; + p5 = (char *)&ioctl_desc; + p6 = 0; } - ioctl_comm.command = request; - 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; - return -1; + ioctl_comm.command = request; + 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; + return -1; } - if (!(iosb[0] & 01)) - { - errno = iosb[0]; - return -1; + if (!(iosb[0] & 01)) { + errno = iosb[0]; + return -1; } - return 0; + return 0; } #endif /* VMS && UCX */ @@ -188,50 +183,52 @@ PUBLIC int HTInetStatus ARGS1( { #ifdef VMS #ifdef MULTINET - SOCKET_ERRNO = vmserrno; + 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 */ - + SOCKET_ERRNO, where, + /* third arg is transport/platform specific */ #ifdef VM - "(Error number not translated)"); /* What Is the VM equiv? */ + "(Error number not translated)"); /* What Is the VM equiv? */ #define ER_NO_TRANS_DONE #endif /* VM */ #ifdef VMS #ifdef MULTINET - vms_errno_string()); + vms_errno_string()); #else - ((SOCKET_ERRNO > 0 && SOCKET_ERRNO <= 65) ? - strerror(SOCKET_ERRNO) : "(Error number not translated)")); + ((SOCKET_ERRNO > 0 && SOCKET_ERRNO <= 65) ? + strerror(SOCKET_ERRNO) : "(Error number not translated)")); #endif /* MULTINET */ #define ER_NO_TRANS_DONE #endif /* VMS */ #if defined(NeXT) || defined(THINK_C) - strerror(SOCKET_ERRNO)); + strerror(SOCKET_ERRNO)); #define ER_NO_TRANS_DONE #endif /* NeXT || THINK_C */ #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(BSDI) - strerror(SOCKET_ERRNO)); + strerror(SOCKET_ERRNO)); #define ER_NO_TRANS_DONE #endif /* __NetBSD__ || __FreeBSD__ || BSDI */ #ifndef ER_NO_TRANS_DONE - (SOCKET_ERRNO < sys_nerr ? - sys_errlist[SOCKET_ERRNO] : "Unknown error" )); + (SOCKET_ERRNO < sys_nerr ? + sys_errlist[SOCKET_ERRNO] : "Unknown error" )); #endif /* !ER_NO_TRANS_DONE */ #ifdef VMS #ifndef MULTINET CTRACE(tfp, - " Unix error number (SOCKET_ERRNO) = %ld dec\n", SOCKET_ERRNO); + " Unix error number (SOCKET_ERRNO) = %ld dec\n", + SOCKET_ERRNO); CTRACE(tfp, - " VMS error (vaxc$errno) = %lx hex\n", vaxc$errno); + " VMS error (vaxc$errno) = %lx hex\n", + vaxc$errno); #endif /* MULTINET */ #endif /* VMS */ @@ -267,16 +264,17 @@ PUBLIC unsigned int HTCardinal ARGS3 char **, pp, unsigned int, max_value) { - int n; - if ( (**pp<'0') || (**pp>'9')) { /* Null string is error */ + int n; + if ((**pp<'0') || (**pp>'9')) { /* Null string is error */ *pstatus = -3; /* No number where one expeceted */ return 0; } - n=0; - while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0'; + n = 0; + while ((**pp >= '0') && (**pp <= '9')) + n = n*10 + *((*pp)++) - '0'; - if (n>max_value) { + if (n > max_value) { *pstatus = -4; /* Cardinal outside range */ return 0; } @@ -326,6 +324,7 @@ PUBLIC int HTParseInet ARGS2( { char *port; char *host = NULL; + int dotcount_ip = 0; /* for dotted decimal IP addr */ struct hostent *phost; /* Pointer to host - See netdb.h */ if (!str) { @@ -359,9 +358,9 @@ PUBLIC int HTParseInet ARGS2( struct servent * serv = getservbyname(port, (char*)0); if (serv) sin->sin_port = serv->s_port; else if (TRACE) fprintf(stderr, "TCP: Unknown service %s\n", port); -#endif +#endif /* SUPPRESS */ } - } + } #ifdef DECNET /* read Decnet node name. @@ Should know about DECnet addresses, but it's @@ -377,26 +376,45 @@ PUBLIC int HTParseInet ARGS2( #else /* parse Internet host */ + if (*host >= '0' && *host <= '9') { /* Test for numeric node address: */ + char *strptr = host; + while (*strptr) { + if (*strptr == '.') + dotcount_ip++; + else if (!isdigit(*strptr)) + break; + strptr++; + } + if (*strptr) /* found non-numeric, assume domain name */ + dotcount_ip = 0; + } + /* Parse host number if present. */ - if (*host >= '0' && *host <= '9') { /* Numeric node address: */ + if (dotcount_ip == 3) { /* Numeric node address: */ #ifdef DGUX_OLD sin->sin_addr.s_addr = inet_addr(host).s_addr; /* See arpa/inet.h */ #else +#ifdef GUSI + sin->sin_addr = inet_addr(host); /* See netinet/in.h */ +#else sin->sin_addr.s_addr = inet_addr(host); /* See arpa/inet.h */ +#endif /* GUSI */ #endif /* DGUX_OLD */ FREE(host); } else { /* Alphanumeric node name: */ #ifdef MVS /* Oustanding problem with crash in MVS gethostbyname */ - if(TRACE) + if (TRACE) fprintf(stderr, "HTTCP: Calling gethostbyname(%s)\n", host); -#endif - phost=gethostbyname(host); /* See netdb.h */ +#endif /* MVS */ + +#ifndef NSL_FORK + phost = gethostbyname(host); /* See netdb.h */ #ifdef MVS - if(TRACE) + if (TRACE) fprintf(stderr, "HTTCP: gethostbyname() returned %d\n", phost); -#endif +#endif /* MVS */ if (!phost) { if (TRACE) fprintf(stderr, @@ -418,6 +436,95 @@ PUBLIC int HTParseInet ARGS2( #else memcpy((void *)&sin->sin_addr, phost->h_addr, phost->h_length); #endif /* VMS && CMU_TCP */ + +#else /* NSL_FORK */ + /* + * Start block for fork-based gethostbyname() with + * checks for interrupts. - Tom Zerucha (tz@execpc.com) + */ + { + /* + * pipe, child pid, status buffers + */ + int pfd[2], fpid, cstat, cst1; + + pipe(pfd); + + if ((fpid = fork()) == 0 ) { + /* + * child - for the long call + */ + phost = gethostbyname(host); + cst1 = 0; + /* + * return value (or nulls) + */ + if (phost != NULL) + write(pfd[1], phost->h_addr, phost->h_length); + else + write(pfd[1], &cst1, 4); + /* + * return an error code + */ + _exit(phost == NULL); + } + + /* + * (parent) wait until lookup finishes, or interrupt + */ + cstat = 0; + while (cstat <= 0) { + /* + * exit when data sent + */ + IOCTL(pfd[0], FIONREAD, &cstat); + if (cstat > 0) + break; + /* + * exit if child exited + */ + if (waitpid(fpid, &cst1, WNOHANG) > 0) + break; + /* + * abort if interrupt key pressed + */ + if (HTCheckForInterrupt()) { + if (TRACE) + fprintf (stderr, "*** INTERRUPTED gethostbyname.\n"); + kill(fpid , SIGKILL); + FREE(host); + return HT_INTERRUPTED; + } + /* + * be nice to the system + */ + sleep(1); + } + waitpid(fpid, &cst1, WNOHANG); + /* + * read as much as we can - should be the address + */ + IOCTL(pfd[0], FIONREAD, &cstat); + if (cstat < 4) + cstat = read(pfd[0], (void *)&sin->sin_addr , 4); + else + cstat = read(pfd[0], (void *)&sin->sin_addr , cstat); + close(pfd[0]); + } + + if (sin->sin_addr.s_addr == 0) { + if (TRACE) + fprintf(stderr, + "HTTPAccess: Can't find internet node name `%s'.\n",host); + FREE(host); + return -1; + } +#ifdef MVS + if (TRACE) + fprintf(stderr, "HTTCP: gethostbyname() returned %d\n", phost); +#endif /* MVS */ + FREE(host); +#endif /* NSL_FORK */ } if (TRACE) @@ -457,10 +564,10 @@ PRIVATE void get_host_details NOARGS char name[MAXHOSTNAMELEN+1]; /* The name of this host */ #ifdef UCX char *domain_name; /* The name of this host domain */ -#endif +#endif /* UCX */ #ifdef NEED_HOST_ADDRESS /* no -- needs name server! */ struct hostent * phost; /* Pointer to host -- See netdb.h */ -#endif +#endif /* NEED_HOST_ADDRESS */ int namelength = sizeof(name); if (hostname) @@ -472,9 +579,9 @@ 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) { + if (domain_name != NULL) { StrAllocCat(hostname, "."); StrAllocCat(hostname, domain_name); } @@ -483,8 +590,8 @@ PRIVATE void get_host_details NOARGS 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! */ - phost=gethostbyname(name); /* See netdb.h */ +#ifdef NEED_HOST_ADDRESS /* no -- needs name server! */ + phost = gethostbyname(name); /* See netdb.h */ if (!phost) { if (TRACE) fprintf(stderr, "TCP: Can't find my own internet node address for `%s'!!\n", @@ -517,320 +624,284 @@ PUBLIC int HTDoConnect ARGS4( int, default_port, int *, s) { - struct sockaddr_in soc_address; - struct sockaddr_in *sin = &soc_address; - int status; - char *line = NULL; - - /* Set up defaults: */ - sin->sin_family = AF_INET; - sin->sin_port = htons(default_port); - - /* Get node name and optional port number: */ - { - char *p1 = HTParse(url, "", PARSE_HOST); - char *at_sign; - char *host = NULL; + struct sockaddr_in soc_address; + struct sockaddr_in *sin = &soc_address; int status; + char *line = NULL; - /* if there's an @ then use the stuff after it as a hostname */ - if((at_sign = strchr(p1,'@')) != NULL) - StrAllocCopy(host, at_sign+1); - else - StrAllocCopy(host, p1); - - line = (char *)malloc(strlen(host) + strlen(protocol) + 128); - if (line == NULL) - outofmem(__FILE__, "HTDoConnect"); - sprintf (line, "Looking up %s.", host); - _HTProgress (line); - - status = HTParseInet(sin, host); - if (status) - { - sprintf (line, "Unable to locate remote host %s.", host); - _HTProgress(line); - FREE(p1); - FREE(host); - FREE(line); - return HT_NO_DATA; - } + /* Set up defaults: */ + sin->sin_family = AF_INET; + sin->sin_port = htons(default_port); + + /* Get node name and optional port number: */ + { + char *p1 = HTParse(url, "", PARSE_HOST); + char *at_sign; + char *host = NULL; + int status; + + /* if there's an @ then use the stuff after it as a hostname */ + if ((at_sign = strchr(p1,'@')) != NULL) + StrAllocCopy(host, at_sign+1); + else + StrAllocCopy(host, p1); + + line = (char *)malloc(strlen(host) + strlen(protocol) + 128); + if (line == NULL) + outofmem(__FILE__, "HTDoConnect"); + sprintf (line, "Looking up %s.", host); + _HTProgress (line); + + status = HTParseInet(sin, host); + if (status) { + sprintf (line, "Unable to locate remote host %s.", host); + _HTProgress(line); + FREE(p1); + FREE(host); + FREE(line); + return HT_NO_DATA; + } - sprintf (line, "Making %s connection to %s.", protocol, host); - _HTProgress (line); - FREE(p1); - FREE(host); - } + sprintf (line, "Making %s connection to %s.", protocol, host); + _HTProgress (line); + FREE(p1); + FREE(host); + } - /* Now, let's get a socket set up from the server for the data: */ - *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + /* Now, let's get a socket set up from the server for the data: */ + *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (*s == -1) - { + if (*s == -1) { HTAlert("socket failed."); FREE(line); return HT_NO_DATA; - } + } - /* - * Make the socket non-blocking, so the connect can be canceled. - * This means that when we issue the connect we should NOT - * have to wait for the accept on the other end. - */ -#if !defined(NO_IOCTL) - { - int ret; - int val = 1; - - ret = IOCTL(*s, FIONBIO, &val); - if (ret == -1) - { - sprintf (line, "Could not make connection non-blocking."); - _HTProgress(line); - } - } -#endif /* not NO_IOCTL */ -#if defined(USE_FCNTL) - { - int ret; - - ret = fcntl(*s, F_SETFL, O_NONBLOCK); - if (ret == -1) - { - sprintf (line, "Could not make connection non-blocking."); - _HTProgress(line); - } - } +#if !defined(NO_IOCTL) || defined(USE_FCNTL) + /* + * Make the socket non-blocking, so the connect can be canceled. + * This means that when we issue the connect we should NOT + * have to wait for the accept on the other end. + */ + { +#ifdef USE_FCNTL + int ret = fcntl(*s, F_SETFL, O_NONBLOCK); +#else + int val = 1; + int ret = IOCTL(*s, FIONBIO, &val); #endif /* USE_FCNTL */ + if (ret == -1) + _HTProgress("Could not make connection non-blocking."); +#endif /* !NO_IOCTL || USE_FCNTL */ + } - /* - * Issue the connect. Since the server can't do an instantaneous accept - * and we are non-blocking, this will almost certainly return a negative - * status. - */ + /* + * Issue the connect. Since the server can't do an instantaneous + * accept and we are non-blocking, this will almost certainly return + * a negative status. + */ #ifdef SOCKS - if (socks_flag) { - status = Rconnect(*s, (struct sockaddr*)&soc_address, - sizeof(soc_address)); - socks_bind_remoteAddr = soc_address.sin_addr.s_addr; /* for long Rbind */ - } - else + if (socks_flag) { + status = Rconnect(*s, (struct sockaddr*)&soc_address, + sizeof(soc_address)); + /* For long Rbind. */ + socks_bind_remoteAddr = soc_address.sin_addr.s_addr; + } else #endif /* SOCKS */ - status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address)); - - /* - * According to the Sun man page for connect: - * EINPROGRESS The socket is non-blocking and the con- - * nection cannot be completed immediately. - * It is possible to select(2) for comple- - * tion by selecting the socket for writ- - * ing. - * According to the Motorola SVR4 man page for connect: - * EAGAIN The socket is non-blocking and the con- - * nection cannot be completed immediately. - * It is possible to select for completion - * by selecting the socket for writing. - * However, this is only possible if the - * socket STREAMS module is the topmost - * module on the protocol stack with a - * write service procedure. This will be - * the normal case. - */ - if ((status < 0) && - (SOCKET_ERRNO == EINPROGRESS || SOCKET_ERRNO == EAGAIN)) - { - struct timeval timeout; - int ret; - int tries=0; - - ret = 0; - while (ret <= 0) - { - fd_set writefds; - - /* - * Protect against an infinite loop. - */ - if (tries++ >= 180000) { - HTAlert("Connection failed for 180,000 tries."); - FREE(line); - return HT_NO_DATA; - } - - timeout.tv_sec = 0; - timeout.tv_usec = 100000; - FD_ZERO(&writefds); - FD_SET(*s, &writefds); + status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address)); + /* + * According to the Sun man page for connect: + * EINPROGRESS The socket is non-blocking and the con- + * nection cannot be completed immediately. + * It is possible to select(2) for comple- + * tion by selecting the socket for writ- + * ing. + * According to the Motorola SVR4 man page for connect: + * EAGAIN The socket is non-blocking and the con- + * nection cannot be completed immediately. + * It is possible to select for completion + * by selecting the socket for writing. + * However, this is only possible if the + * socket STREAMS module is the topmost + * module on the protocol stack with a + * write service procedure. This will be + * the normal case. + */ + if ((status < 0) && + (SOCKET_ERRNO == EINPROGRESS || SOCKET_ERRNO == EAGAIN)) { + struct timeval timeout; + int ret; + int tries=0; + + ret = 0; + while (ret <= 0) { + fd_set writefds; + + /* + * Protect against an infinite loop. + */ + if (tries++ >= 180000) { + HTAlert("Connection failed for 180,000 tries."); + FREE(line); + return HT_NO_DATA; + } + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + FD_ZERO(&writefds); + FD_SET(*s, &writefds); #ifdef SOCKS - if (socks_flag) - ret = Rselect(FD_SETSIZE, NULL, - (void *)&writefds, NULL, &timeout); - else + if (socks_flag) + ret = Rselect(FD_SETSIZE, NULL, + (void *)&writefds, NULL, &timeout); + else #endif /* SOCKS */ - ret = select(FD_SETSIZE, NULL, (void *)&writefds, NULL, &timeout); - /* - * Again according to the Sun and Motorola man pagse for connect: - * EALREADY The socket is non-blocking and a previ- - * ous connection attempt has not yet been - * completed. - * Thus if the SOCKET_ERRNO is NOT EALREADY we have a real error, and - * should break out here and return that error. - * Otherwise if it is EALREADY keep on trying to complete the - * connection. - */ - if ((ret < 0) && (SOCKET_ERRNO != EALREADY)) - { - status = ret; - break; - } - else if (ret > 0) - { - /* - * Extra check here for connection success, if we try to connect - * again, and get EISCONN, it means we have a successful - * connection. - */ + ret = select(FD_SETSIZE, NULL, (void *)&writefds, NULL, &timeout); + /* + * Again according to the Sun and Motorola man pagse for connect: + * EALREADY The socket is non-blocking and a previ- + * ous connection attempt has not yet been + * completed. + * Thus if the SOCKET_ERRNO is NOT EALREADY we have a real error, + * and should break out here and return that error. + * Otherwise if it is EALREADY keep on trying to complete the + * connection. + */ + if ((ret < 0) && (SOCKET_ERRNO != EALREADY)) { + status = ret; + break; + } else if (ret > 0) { + /* + * Extra check here for connection success, if we try to + * connect again, and get EISCONN, it means we have a + * successful connection. But don't check with SOCKS. + */ #ifdef SOCKS - if (socks_flag) - status = Rconnect(*s, (struct sockaddr*)&soc_address, - sizeof(soc_address)); - else + if (socks_flag) { + status = 0; + } else { #endif /* SOCKS */ - status = connect(*s, (struct sockaddr*)&soc_address, - sizeof(soc_address)); -#ifndef UCX - if ((status < 0)&&(SOCKET_ERRNO == EISCONN)) + status = connect(*s, (struct sockaddr*)&soc_address, + sizeof(soc_address)); +#ifdef UCX + /* + * A UCX feature: Instead of returning EISCONN + * UCX returns EADDRINUSE. + * Test for this status also. + */ + if ((status < 0) && ((SOCKET_ERRNO == EISCONN) || + (SOCKET_ERRNO == EADDRINUSE))) #else -/* - * A UCX feature: Instead of returning EISCONN UCX returns EADDRINUSE. - * Test for this status also. - */ - if ((status < 0)&&((SOCKET_ERRNO == EISCONN) || - (SOCKET_ERRNO == EADDRINUSE))) -#endif /* VMS, UCX, BSN */ + if ((status < 0) && (SOCKET_ERRNO == EISCONN)) +#endif /* UCX */ { - status = 0; + status = 0; } - if (status && (SOCKET_ERRNO == EALREADY)) /* new stuff LJM */ - ret=0; /* keep going */ - else - break; - } - /* - * The select says we aren't ready yet. Try to connect again to - * make sure. If we don't get EALREADY or EISCONN, something has - * gone wrong. Break out and report it. - * - * For some reason, SVR4 returns EAGAIN here instead of EALREADY, - * even though the man page says it should be EALREADY. - * - * For some reason, UCX pre 3 apparently returns errno = 18242 - * instead the EALREADY or EISCONN values. - */ - else - { + if (status && (SOCKET_ERRNO == EALREADY)) /* new stuff LJM */ + ret = 0; /* keep going */ + else + break; +#ifdef SOCKS + } +#endif /* SOCKS */ + } #ifdef SOCKS - if (socks_flag) - status = Rconnect(*s, (struct sockaddr*)&soc_address, - sizeof(soc_address)); - else + else if (!socks_flag) +#else + else #endif /* SOCKS */ - status = connect(*s, (struct sockaddr*)&soc_address, + { + /* + * The select says we aren't ready yet. Try to connect + * again to make sure. If we don't get EALREADY or EISCONN, + * something has gone wrong. Break out and report it. + * + * For some reason, SVR4 returns EAGAIN here instead of + * EALREADY, even though the man page says it should be + * EALREADY. + * + * For some reason, UCX pre 3 apparently returns + * errno = 18242 instead the EALREADY or EISCONN. + */ + status = connect(*s, (struct sockaddr*)&soc_address, sizeof(soc_address)); - if ((status < 0) && - (SOCKET_ERRNO != EALREADY && SOCKET_ERRNO != EAGAIN) && + if ((status < 0) && + (SOCKET_ERRNO != EALREADY && SOCKET_ERRNO != EAGAIN) && #ifdef UCX - (SOCKET_ERRNO != 18242) && + (SOCKET_ERRNO != 18242) && #endif /* UCX */ - (SOCKET_ERRNO != EISCONN)) - { - break; + (SOCKET_ERRNO != EISCONN)) { + break; } } - if(HTCheckForInterrupt()) - { - if (TRACE) - fprintf (stderr, "*** INTERRUPTED in middle of connect.\n"); - status = HT_INTERRUPTED; - SOCKET_ERRNO = EINTR; - break; + if (HTCheckForInterrupt()) { + if (TRACE) + fprintf(stderr, "*** INTERRUPTED in middle of connect.\n"); + status = HT_INTERRUPTED; + SOCKET_ERRNO = EINTR; + break; } } } - /* - * Make the socket blocking again on good connect - */ - if (status >= 0) - { -#if !defined(NO_IOCTL) - int ret; - int val = 0; - - ret = IOCTL(*s, FIONBIO, &val); - if (ret == -1) - { - sprintf (line, "Could not restore socket to blocking."); - _HTProgress(line); - } -#endif /* not NO_IOCTL */ -#if defined(USE_FCNTL) - { - int ret; - - ret = fcntl(*s, F_SETFL, 0); - if (ret == -1) - { - sprintf (line, "Could not restore socket to blocking."); - _HTProgress(line); - } - } -#endif /* USE_FCNTL */ - } - /* - * Else the connect attempt failed or was interrupted. - * so close up the socket. - */ - else - { + if (status < 0) { + /* + * The connect attempt failed or was interrupted, + * so close up the socket. + */ NETCLOSE(*s); } +#if !defined(NO_IOCTL) || defined(USE_FCNTL) + else { + /* + * Make the socket blocking again on good connect. + */ +#ifdef USE_FCNTL + int ret = fcntl(*s, F_SETFL, 0); +#else + int val = 0; + int ret = IOCTL(*s, FIONBIO, &val); +#endif /* USE_FCNTL */ + if (ret == -1) + _HTProgress("Could not restore socket to blocking."); + } +#endif /* !NO_IOCTL || USE_FCNTL */ - FREE(line); - return status; + FREE(line); + return status; } -/* This is so interruptible reads can be implemented cleanly. */ +/* +** This is so interruptible reads can be implemented cleanly. +*/ PUBLIC int HTDoRead ARGS3( int, fildes, void *, buf, unsigned, nbyte) { - int ready, ret; - fd_set readfds; - struct timeval timeout; - int tries=0; + int ready, ret; + fd_set readfds; + struct timeval timeout; + int tries=0; #ifdef UCX - int nb; + int nb; #endif /* UCX, BSN */ - if (fildes <= 0) - return -1; + if (fildes <= 0) + return -1; - if (HTCheckForInterrupt()) - { + if (HTCheckForInterrupt()) { SOCKET_ERRNO = EINTR; return (HT_INTERRUPTED); } #if !defined(NO_IOCTL) - ready = 0; + ready = 0; #else - ready = 1; + ready = 1; #endif /* bypass for NO_IOCTL */ - while (!ready) - { + while (!ready) { /* * Protect against an infinite loop. */ @@ -850,37 +921,36 @@ PUBLIC int HTDoRead ARGS3( else #endif /* SOCKS */ ret = select(FD_SETSIZE, (void *)&readfds, NULL, NULL, &timeout); - if (ret < 0) - { - return -1; - } - else if (ret > 0) - { - ready = 1; - } - else if(HTCheckForInterrupt()) - { - SOCKET_ERRNO = EINTR; - return HT_INTERRUPTED; - } + if (ret < 0) { + return -1; + } else if (ret > 0) { + ready = 1; + } else if (HTCheckForInterrupt()) { + SOCKET_ERRNO = EINTR; + return HT_INTERRUPTED; + } } #if !defined(UCX) || !defined(VAXC) - return SOCKET_READ (fildes, buf, nbyte); -#else /* VAXC and UCX problem only */ - 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); - if ((nb <= 0) && TRACE) - perror ("HTTCP.C:HTDoRead:read"); /* RJF */ - /* - * An errno value of EPIPE and nb < 0 indicates end-of-file on VAXC - */ - if ((nb <= 0) && (errno == EPIPE)) { - nb = 0; - errno = 0; - } - return nb; + return SOCKET_READ (fildes, buf, nbyte); +#else + /* + * VAXC and UCX problem only. + */ + 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); + if ((nb <= 0) && TRACE) + perror ("HTTCP.C:HTDoRead:read"); /* RJF */ + /* + * An errno value of EPIPE and nb < 0 indicates end-of-file on VAXC. + */ + if ((nb <= 0) && (errno == EPIPE)) { + nb = 0; + errno = 0; + } + return nb; #endif /* UCX, BSN */ } @@ -914,42 +984,50 @@ PUBLIC int HTDoRead ARGS3( #include <sys/time.h> #include <sys/select.h> - -PUBLIC int BSDselect ARGS5 (int,nfds, fd_set *,readfds,fd_set *,writefds, - fd_set *,exceptfds, struct timeval *,timeout) +PUBLIC int BSDselect ARGS5( + int, nfds, + fd_set *, readfds, + fd_set *, writefds, + fd_set *, exceptfds, + struct timeval *, timeout) { - int rval, - i; + int rval, + i; #ifdef SOCKS - if (socks_flag) - rval = Rselect(nfds, readfds, writefds, exceptfds, timeout); - else + if (socks_flag) + rval = Rselect(nfds, readfds, writefds, exceptfds, timeout); + else #endif /* SOCKS */ - rval = select(nfds, readfds, writefds, exceptfds, timeout); - - switch(rval) { - case -1: return(rval); - break; - - case 0: if(readfds != NULL) - FD_ZERO(readfds); - if(writefds != NULL) - FD_ZERO(writefds); - if(exceptfds != NULL) - FD_ZERO(exceptfds); - - return(rval); - break; - - default: for(i=0, rval=0; i < nfds; i++) { - if((readfds != NULL) && FD_ISSET(i, readfds)) rval++; - if((writefds != NULL) && FD_ISSET(i, writefds)) rval++; - if((exceptfds != NULL) && FD_ISSET(i, exceptfds)) rval++; - - } - return(rval); - } + rval = select(nfds, readfds, writefds, exceptfds, timeout); + + switch (rval) { + case -1: + return(rval); + break; + + case 0: + if (readfds != NULL) + FD_ZERO(readfds); + if (writefds != NULL) + FD_ZERO(writefds); + if (exceptfds != NULL) + FD_ZERO(exceptfds); + return(rval); + break; + + default: + for (i = 0, rval = 0; i < nfds; i++) { + if ((readfds != NULL) && FD_ISSET(i, readfds)) + rval++; + if ((writefds != NULL) && FD_ISSET(i, writefds)) + rval++; + if ((exceptfds != NULL) && FD_ISSET(i, exceptfds)) + rval++; + + } + return(rval); + } /* Should never get here */ } #endif /* SVR4_BSDSELECT */ diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c index 10a484f6..ed77809e 100644 --- a/WWW/Library/Implementation/HTTP.c +++ b/WWW/Library/Implementation/HTTP.c @@ -16,9 +16,6 @@ #define HTTPS_PORT 443 #define SNEWS_PORT 563 -#define HTTP_NETREAD NETREAD -#define HTTP_NETWRITE NETWRITE - #define INIT_LINE_SIZE 1024 /* Start with line buffer this big */ #define LINE_EXTEND_THRESH 256 /* Minimum read size */ #define VERSION_LENGTH 20 /* for returned protocol version */ @@ -68,6 +65,10 @@ extern BOOL dump_output_immediately; /* TRUE if no interactive user */ extern char * HTLoadedDocumentURL NOPARAMS; extern int HTCheckForInterrupt NOPARAMS; +#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) + /* Load Document from HTTP Server HTLoadHTTP() ** ============================== @@ -119,6 +120,8 @@ PUBLIC int HTLoadHTTP ARGS4 ( int already_retrying = 0; int len = 0; + void * handle = NULL; + if (anAnchor->isHEAD) do_head = TRUE; else if (anAnchor->post_data) @@ -405,15 +408,16 @@ PUBLIC int HTLoadHTTP ARGS4 ( { if (TRACE) fprintf (stderr, "HTTP: Doing post, content-type '%s'\n", - anAnchor->post_content_type); + 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); + : "lose", CR, LF); StrAllocCat(command, line); { int content_length; if (!anAnchor->post_data) - content_length = 4; /* 4 == "lose" :-) */ + content_length = 0; else content_length = strlen (anAnchor->post_data); sprintf (line, "Content-length: %d%c%c", @@ -421,12 +425,12 @@ PUBLIC int HTLoadHTTP ARGS4 ( StrAllocCat(command, line); } - StrAllocCat(command, crlf); /* Blank line means "end" */ + StrAllocCat(command, crlf); /* Blank line means "end" of headers */ StrAllocCat(command, anAnchor->post_data); } - - StrAllocCat(command, crlf); /* Blank line means "end" */ + else + StrAllocCat(command, crlf); /* Blank line means "end" of headers */ if (TRACE) fprintf (stderr, "Writing:\n%s----------------------------------\n", @@ -434,7 +438,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( _HTProgress ("Sending HTTP request."); - status = HTTP_NETWRITE(s, command, (int)strlen(command)); + status = HTTP_NETWRITE(s, command, (int)strlen(command), handle); FREE(command); if (status <= 0) { @@ -455,7 +459,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( fprintf (stderr, "HTTP: BONZO ON WRITE Trying again with HTTP0 request.\n"); _HTProgress ("Retrying as HTTP0 request."); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); extensions = NO; already_retrying = 1; goto try_again; @@ -465,7 +469,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( if (TRACE) fprintf (stderr, "HTTP: Hit unexpected network WRITE error; aborting connection.\n"); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = -1; HTAlert("Unexpected network write error; connection aborted."); goto done; @@ -500,7 +504,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( fprintf (stderr, "HTTP: Trying to read %d\n", buffer_length - length - 1); status = HTTP_NETREAD(s, line_buffer + length, - buffer_length - length - 1); + buffer_length - length - 1, handle); if (TRACE) fprintf (stderr, "HTTP: Read %d\n", status); if (status <= 0) @@ -524,7 +528,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( if (TRACE) fprintf (stderr, "HTTP: BONZO Trying again with HTTP0 request.\n"); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); FREE(line_buffer); FREE(line_kept_clean); @@ -540,7 +544,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( "HTTP: Hit unexpected network read error; aborting connection; status %d.\n", status); HTAlert("Unexpected network read error; connection aborted."); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = -1; goto clean_up; } @@ -609,7 +613,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( already_retrying = 1; if (TRACE) fprintf(stderr, "HTTP: close socket %d to retry with HTTP0\n", s); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); /* print a progress message */ _HTProgress ("Retrying as HTTP0 request."); goto try_again; @@ -755,7 +759,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( * document. - FM */ HTAlert(line_buffer); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = HT_NO_DATA; goto done; break; @@ -873,7 +877,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( * Don't redirect POST content without approval * from an interactive user. - FM */ - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = -1; HTAlert( "Redirection of POST content requires user approval."); @@ -887,11 +891,12 @@ PUBLIC int HTLoadHTTP ARGS4 ( * any, and then close the connection. - FM */ while ((status = HTTP_NETREAD(s, line_buffer, - INIT_LINE_SIZE)) > 0) { + INIT_LINE_SIZE, + handle)) > 0) { line_buffer[status] = '\0'; StrAllocCat(line_kept_clean, line_buffer); } - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); if (status == HT_INTERRUPTED) { /* * Impatient user. - FM @@ -1014,22 +1019,37 @@ PUBLIC int HTLoadHTTP ARGS4 ( } /* * Make sure the user wants to redirect - * the POST content. - FM + * the POST content, or treat as GET - FM & DK */ - if (!HTConfirm( - "Redirection for POST content. Proceed?")) { - doing_redirect = 0; - FREE(redirecting_url); - status = HT_NO_DATA; - goto clean_up; - } - /* - * Set the flag to retain the POST content - * and go back to check out the URL. - FM - */ - redirect_post_content = TRUE; - status = HT_REDIRECTING; - goto clean_up; + switch (HTConfirmPostRedirect(redirecting_url)) { + /* + * User failed to confirm. + * Abort the fetch. + */ + case 0: + doing_redirect = 0; + 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 { @@ -1070,11 +1090,12 @@ PUBLIC int HTLoadHTTP ARGS4 ( * Otherwise, issue a statusline message and * restore the current document. - FM */ - if (HTAA_shouldRetryWithAuth(start_of_data, length, NULL, s)) + if (HTAA_shouldRetryWithAuth(start_of_data, length, + (void *)handle, s)) { extern char *authentication_info[2]; - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); if (dump_output_immediately && !authentication_info[0]) { fprintf(stderr, "HTTP: Access authorization required.\n"); @@ -1100,7 +1121,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( { HTAlert( "Can't retry with authorization! Contact the server's WebMaster."); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = -1; goto clean_up; } @@ -1115,7 +1136,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( */ HTAlert( "Proxy Authentication Required. Sorry, not yet supported."); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = HT_NO_DATA; goto done; break; @@ -1126,7 +1147,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( * and restore the current document. - FM */ HTAlert(line_buffer); - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = HT_NO_DATA; goto done; break; @@ -1154,7 +1175,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( */ HTAlert(line_buffer); if (traversal) { - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = -1; goto clean_up; } @@ -1187,7 +1208,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( HTAlert("Unknown status reply from server!"); HTAlert(line_buffer); if (traversal) { - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); status = -1; goto clean_up; } @@ -1213,7 +1234,7 @@ PUBLIC int HTLoadHTTP ARGS4 ( { char buffer[1024]; /* @@@@@@@@ */ - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); sprintf(buffer, "Sorry, no known way of converting %s to %s.", HTAtom_name(format_in), HTAtom_name(format_out)); _HTProgress (buffer); @@ -1225,61 +1246,69 @@ PUBLIC int HTLoadHTTP ARGS4 ( (*target->isa->put_block)(target, start_of_data, length); /* Go pull the bulk of the data down. */ - rv = HTCopy(s, NULL, target); + rv = HTCopy(s, (void *)handle, target); - if (rv == -1) - { - /* Intentional interrupt before data were received, not an error */ + if (rv == -1) { + /* + * Intentional interrupt before data were received, not an error + */ /* (*target->isa->_abort)(target, NULL); */ /* already done in HTCopy */ status = HT_INTERRUPTED; - (void)NETCLOSE(s); + HTTP_NETCLOSE(s, handle); goto clean_up; - } - if (rv == -2 && !already_retrying && !do_post) - { - /* Aw hell, a REAL error, maybe cuz it's a dumb HTTP0 server */ - if (TRACE) - fprintf (stderr, "HTTP: Trying again with HTTP0 request.\n"); - /* May as well consider it an interrupt -- right? */ + } + + if (rv == -2) { + /* + * Aw hell, a REAL error, maybe cuz it's a dumb HTTP0 server + */ (*target->isa->_abort)(target, NULL); - (void)NETCLOSE(s); - FREE(line_buffer); - FREE(line_kept_clean); - extensions = NO; - already_retrying = 1; - _HTProgress ("Retrying as HTTP0 request."); - goto try_again; - } + HTTP_NETCLOSE(s, handle); + if (!already_retrying && !do_post) { + if (TRACE) + fprintf (stderr, "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 = 1; + _HTProgress ("Retrying as HTTP0 request."); + goto try_again; + } else { + status = HT_NO_DATA; + goto clean_up; + } + } /* - * Close socket if partial transmission (was freed on abort) - * Free if complete transmission (socket was closed before return) + * Free if complete transmission (socket was closed before return). + * Close socket if partial transmission (was freed on abort). */ - if (rv == HT_INTERRUPTED) - { - (void)NETCLOSE(s); - } - else + if (rv != HT_INTERRUPTED) { (*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 - */ - { + 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; - } - else - { - /* If any data were received, treat as a complete transmission */ + } else { + /* + * If any data were received, treat as a complete transmission + */ status = HT_LOADED; - } + } /* Clean up */ diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c index 9cddd35a..32ba06b8 100644 --- a/WWW/Library/Implementation/SGML.c +++ b/WWW/Library/Implementation/SGML.c @@ -468,33 +468,48 @@ PUBLIC HTTag * SGMLFindTag ARGS2( /* Could check that we are back to bottom of stack! @@ */ - +/* Do check! - FM */ +/* */ PUBLIC void SGML_free ARGS1( HTStream *, context) { int i; HTElement * cur; HTElement * next; + HTTag * t; - (*context->actions->_free)(context->target); - HTChunkFree(context->string); - - /* free strings */ - for (i = 0; i < MAX_ATTRIBUTES; i++) - FREE(context->value[i]); - + /* + ** Free the buffers. - FM + */ FREE(context->recover); - FREE(context->include); FREE(context->url); FREE(context->csi); + FREE(context->include); - cur = context->element_stack; - while (cur) { - next = cur->next; + /* + ** Wind down stack if any elements are open. - FM + */ + while (context->element_stack) { + cur = context->element_stack; + t = cur->tag; + context->element_stack = cur->next; /* Remove from stack */ FREE(cur); - cur = next; + (*context->actions->end_element)(context->target, + t - context->dtd->tags, (char **)&context->include); + FREE(context->include); } + /* + ** Finish off the target. - FM + */ + (*context->actions->_free)(context->target); + + /* + ** Free the strings and context structure. - FM + */ + HTChunkFree(context->string); + for (i = 0; i < MAX_ATTRIBUTES; i++) + FREE(context->value[i]); FREE(context); } @@ -504,18 +519,25 @@ PUBLIC void SGML_abort ARGS2( { int i; + /* + ** Abort the target. - FM + */ (*context->actions->_abort)(context->target, e); - HTChunkFree(context->string); - - /* free strings */ - for (i = 0; i < MAX_ATTRIBUTES; i++) - FREE(context->value[i]); + /* + ** Free the buffers. - FM + */ FREE(context->recover); FREE(context->include); FREE(context->url); FREE(context->csi); + /* + ** Free the strings and context structure. - FM + */ + HTChunkFree(context->string); + for (i = 0; i < MAX_ATTRIBUTES; i++) + FREE(context->value[i]); FREE(context); } diff --git a/WWW/Library/Implementation/tcp.h b/WWW/Library/Implementation/tcp.h index 2e5ada8d..b67a1510 100644 --- a/WWW/Library/Implementation/tcp.h +++ b/WWW/Library/Implementation/tcp.h @@ -76,6 +76,11 @@ typedef struct sockaddr_in SockA; /* See netinet/in.h */ #define USE_DIRENT /* sys V style directory open */ #endif /* _IBMR2 */ +#ifdef _SYSV3 +#include <fcntl.h> +#include <dirent.h> +#endif /* _SYSV3 */ + /* Solaris. */ #if defined(sun) && defined(__svr4__) && !defined(USE_DIRENT) #define USE_DIRENT /* sys V style directory open */ @@ -169,6 +174,15 @@ VAX/VMS #undef NETWRITE #undef IOCTL #undef SOCKET_ERRNO +/* +** Remove these socket_foo() prototypes if +** MultiNet someday actually does this. - 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)) : \ @@ -209,6 +223,23 @@ VAX/VMS #define INCLUDES_DONE #ifdef MULTINET /* Include from standard Multinet directories */ +/* +** Remove these multinet_foo() and associated prototypes +** if MultiNet someday actually does this. - FM +*/ +extern int multinet_accept(); +extern int multinet_bind(); +extern int bzero(); +extern int multinet_connect(); +extern int multinet_gethostname(); +extern int multinet_getsockname(); +extern unsigned short multinet_htons(); +extern unsigned short multinet_ntohs(); +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 */ @@ -238,6 +269,17 @@ VAX/VMS #include "multinet_root:[multinet.include.arpa]inet.h" #include "multinet_root:[multinet.include]netdb.h" #include "multinet_root:[multinet.include.sys]ioctl.h" +/* +** 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 */ |