about summary refs log tree commit diff stats
path: root/WWW
diff options
context:
space:
mode:
Diffstat (limited to 'WWW')
-rw-r--r--WWW/Library/Implementation/HTAAProt.c18
-rw-r--r--WWW/Library/Implementation/HTCJK.h2
-rw-r--r--WWW/Library/Implementation/HTMIME.c17
-rw-r--r--WWW/Library/Implementation/HTMLDTD.c10
-rw-r--r--WWW/Library/Implementation/HTParse.c20
-rw-r--r--WWW/Library/Implementation/HTPlain.c44
-rw-r--r--WWW/Library/Implementation/HTString.c243
-rw-r--r--WWW/Library/Implementation/HTString.h19
-rw-r--r--WWW/Library/Implementation/HTTP.c22
-rw-r--r--WWW/Library/Implementation/HTTelnet.c112
-rw-r--r--WWW/Library/Implementation/HTUtils.h23
-rw-r--r--WWW/Library/Implementation/HTVMSUtils.c12
-rw-r--r--WWW/Library/Implementation/SGML.c109
-rw-r--r--WWW/Library/Implementation/tcp.h27
14 files changed, 526 insertions, 152 deletions
diff --git a/WWW/Library/Implementation/HTAAProt.c b/WWW/Library/Implementation/HTAAProt.c
index abe9687b..ceda12cb 100644
--- a/WWW/Library/Implementation/HTAAProt.c
+++ b/WWW/Library/Implementation/HTAAProt.c
@@ -127,7 +127,12 @@ PUBLIC int HTAA_getUid NOARGS
 		CTRACE(tfp, "%s(%s) returned (%s:%s:%d:%d:...)\n",
 			    "HTAA_getUid: getpwuid",
 			    current_prot->uid_name,
-			    pw->pw_name, pw->pw_passwd,
+				   pw->pw_name,
+#ifndef __MVS__  /* S/390 -- gil -- 0018 */
+				                pw->pw_passwd,
+#else
+				                "(none)",
+#endif /* __MVS __ */
 			    (int) pw->pw_uid, (int) pw->pw_gid);
 		return pw->pw_uid;
 	    }
@@ -137,7 +142,12 @@ PUBLIC int HTAA_getUid NOARGS
 		CTRACE(tfp, "%s(\"%s\") %s (%s:%s:%d:%d:...)\n",
 			    "HTAA_getUid: getpwnam",
 			    current_prot->uid_name, "returned",
-			    pw->pw_name, pw->pw_passwd,
+				   pw->pw_name,
+#ifndef __MVS__  /* S/390 -- gil -- 0040 */
+				                pw->pw_passwd,
+#else
+				                "(none)",
+#endif /* __MVS __ */
 			    (int) pw->pw_uid, (int) pw->pw_gid);
 		return pw->pw_uid;
 	    }
@@ -174,7 +184,7 @@ PUBLIC int HTAA_getGid NOARGS
     if (current_prot  &&  current_prot->gid_name) {
 	if (isNumber(current_prot->gid_name)) {
 	    if (NULL != (gr = getgrgid(atoi(current_prot->gid_name)))) {
-#ifndef __EMX__	/* no gr_passwd */
+#if !defined(__EMX__) && !defined(__MVS__)  /* no gr_passwd  S/390 -- gil -- 0061 */
 		CTRACE(tfp, "%s(%s) returned (%s:%s:%d:...)\n",
 			    "HTAA_getGid: getgrgid",
 			    current_prot->gid_name,
@@ -185,7 +195,7 @@ PUBLIC int HTAA_getGid NOARGS
 	}
 	else {	/* Group name (not number) */
 	    if (NULL != (gr = getgrnam(current_prot->gid_name))) {
-#ifndef __EMX__	/* no gr_passwd */
+#if !defined(__EMX__) && !defined(__MVS__)  /* no gr_passwd  S/390 -- gil -- 0078 */
 		CTRACE(tfp, "%s(\"%s\") returned (%s:%s:%d:...)\n",
 			    "HTAA_getGid: getgrnam",
 			    current_prot->gid_name,
diff --git a/WWW/Library/Implementation/HTCJK.h b/WWW/Library/Implementation/HTCJK.h
index bc2c3aac..7722f522 100644
--- a/WWW/Library/Implementation/HTCJK.h
+++ b/WWW/Library/Implementation/HTCJK.h
@@ -19,7 +19,7 @@
 #ifdef ESC
 #undef ESC
 #endif /* ESC */
-#define ESC		'\033'
+#define ESC		CH_ESC  /* S/390 -- gil -- 0098 */
 #define TO_2BCODE	'$'
 #define TO_1BCODE	'('
 
diff --git a/WWW/Library/Implementation/HTMIME.c b/WWW/Library/Implementation/HTMIME.c
index 64c77444..6e64fb1d 100644
--- a/WWW/Library/Implementation/HTMIME.c
+++ b/WWW/Library/Implementation/HTMIME.c
@@ -190,7 +190,17 @@ PRIVATE void HTMIME_put_character ARGS2(
     **	See NetToText for an implementation which preserves single CR or LF.
     */
     if (me->net_ascii) {
+	/*
+	** <sigh> This is evidence that at one time, this code supported
+	** local character sets other than ASCII.  But there is so much
+	** code in HTTP.c that depends on line_buffer's having been
+	** translated to local character set that I needed to put the
+	** FROMASCII translation there, leaving this translation purely
+	** destructive.  -- gil
+	*/  /* S/390 -- gil -- 0118 */
+#ifndef   NOT_ASCII
 	c = FROMASCII(c);
+#endif /* NOT_ASCII */
 	if (c == CR)
 	    return;
 	else if (c == LF)
@@ -1150,11 +1160,11 @@ PRIVATE void HTMIME_put_character ARGS2(
 	/* Fall through to store first character */
 
     case miGET_VALUE:
-	if (WHITE(c) && c != 32) {			/* End of field */
+    	if (WHITE(c) && c != ' ') {			/* End of field */
 	    char *cp;
 	    *me->value_pointer = '\0';
 	    cp = (me->value_pointer - 1);
-	    while ((cp >= me->value) && *cp == 32)
+	    while ((cp >= me->value) && *cp == ' ')  /* S/390 -- gil -- 0146 */
 		/*
 		**  Trim trailing spaces.
 		*/
@@ -1833,7 +1843,8 @@ PUBLIC HTStream* HTNetMIME ARGS3(
 #ifdef ESC
 #undef ESC
 #endif /* ESC */
-#define ESC	'\033'
+#include "LYCharVals.h"  /* S/390 -- gil -- 0163 */
+#define ESC	CH_ESC
 
 PRIVATE char HTmm64[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ;
diff --git a/WWW/Library/Implementation/HTMLDTD.c b/WWW/Library/Implementation/HTMLDTD.c
index 966697a8..4b4cc542 100644
--- a/WWW/Library/Implementation/HTMLDTD.c
+++ b/WWW/Library/Implementation/HTMLDTD.c
@@ -1499,16 +1499,26 @@ static CONST HTTag tags_new[HTML_ELEMENTS] = {
     { "FORM"	, form_attr,	HTML_FORM_ATTRIBUTES,	SGML_MIXED,T_FORM},
     { "FRAME"	, frame_attr,	HTML_FRAME_ATTRIBUTES,	SGML_EMPTY,T_FRAME},
     { "FRAMESET", frameset_attr,HTML_FRAMESET_ATTRIBUTES, SGML_ELEMENT,T_FRAMESET},
+#ifndef   EBCDIC  /* S/390 -- gil -- 0177 */
     { "H1"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H1},
     { "H2"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H2},
     { "H3"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H3},
     { "H4"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H4},
     { "H5"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H5},
     { "H6"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H6},
+#endif /* EBCDIC  S/390 -- gil -- 0187 */
     { "HEAD"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_ELEMENT,T_HEAD},
     { "HR"	, hr_attr,	HTML_HR_ATTRIBUTES,	SGML_EMPTY,T_HR},
     { "HTML"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_HTML},
     { "HY"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_EMPTY,T_HY},
+#ifdef    EBCDIC
+    { "H1"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H1},
+    { "H2"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H2},
+    { "H3"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H3},
+    { "H4"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H4},
+    { "H5"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H5},
+    { "H6"	, h_attr,	HTML_H_ATTRIBUTES,	SGML_MIXED,T_H6},
+#endif /* EBCDIC <heavy sigh> -- gil */
     { "I"	, gen_attr,	HTML_GEN_ATTRIBUTES,	SGML_MIXED,T_I},
     { "IFRAME"	, iframe_attr,	HTML_IFRAME_ATTRIBUTES, SGML_MIXED,T_IFRAME},
     { "IMG"	, img_attr,	HTML_IMG_ATTRIBUTES,	SGML_EMPTY,T_IMG},
diff --git a/WWW/Library/Implementation/HTParse.c b/WWW/Library/Implementation/HTParse.c
index 7362a59a..04a1d446 100644
--- a/WWW/Library/Implementation/HTParse.c
+++ b/WWW/Library/Implementation/HTParse.c
@@ -773,7 +773,11 @@ PUBLIC char * HTUnEscape ARGS1(
 	    if (*p)
 	        *q = from_hex(*p++) * 16;
 	    if (*p)
-	        *q = FROMASCII(*q + from_hex(*p++));
+		/*
+		** Careful! FROMASCII() may evaluate its arg more than once!
+		*/  /* S/390 -- gil -- 0221 */
+		*q =           *q + from_hex(*p++) ;
+		*q = FROMASCII(*q                 );
 	    q++;
 	} else {
 	    *q++ = *p++;
@@ -854,7 +858,7 @@ PUBLIC void HTMake822Word ARGS1(
 	return;
     }
     for (p = *str; *p; p++) {
-	a = *p;
+	a = TOASCII(*p);  /* S/390 -- gil -- 0240 */
 	if (a < 32 || a >= 128 ||
 	    ((crfc[a-32]) & 1)) {
 	    if (!added)
@@ -873,13 +877,19 @@ PUBLIC void HTMake822Word ARGS1(
     if (result == NULL)
 	outofmem(__FILE__, "HTMake822Word");
     result[0] = '"';
+    /*
+    ** Having converted the character to ASCII, we can't use symbolic
+    ** escape codes, since they're in the host character set, which
+    ** is not necessarily ASCII.  Thus we use octal escape codes instead.
+    ** -- gil (Paul Gilmartin) <pg@sweng.stortek.com>
+    */  /* S/390 -- gil -- 0268 */
     for (q = result + 1, p = *str; *p; p++) {
 	a = TOASCII(*p);
-	if ((a != '\t') && ((a & 127) < 32 ||
+	if ((a != '\011') && ((a & 127) < 32 ||
 			    ( a < 128 && ((crfc[a-32]) & 2))))
-	    *q++ = '\\';
+	    *q++ = '\033';
 	*q++ = *p;
-	if (a == '\n' || (a == '\r' && (TOASCII(*(p+1)) != '\n')))
+	if (a == '\012' || (a == '\015' && (TOASCII(*(p+1)) != '\012')))
 	    *q++ = ' ';
     }
     *q++ = '"';
diff --git a/WWW/Library/Implementation/HTPlain.c b/WWW/Library/Implementation/HTPlain.c
index 81e46d72..832aa360 100644
--- a/WWW/Library/Implementation/HTPlain.c
+++ b/WWW/Library/Implementation/HTPlain.c
@@ -9,6 +9,7 @@
 */
 
 #include <HTUtils.h>
+#include <LYCharVals.h>  /* S/390 -- gil -- 0288 */
 
 #include <HTPlain.h>
 
@@ -135,7 +136,7 @@ PRIVATE void HTPlain_put_character ARGS2(
     HTPlain_lastraw = c;
     if (c == '\r') {
 	HText_appendCharacter(me->text, '\n');
-    } else if ((unsigned char)c >= 127) {
+    } else if (TOASCII((unsigned char)c) >= 127) {  /* S/390 -- gil -- 0305 */
 	/*
 	**  For now, don't repeat everything here
 	**  that has been done below - KW
@@ -143,23 +144,23 @@ PRIVATE void HTPlain_put_character ARGS2(
 	HTPlain_write(me, &c, 1);
     } else if (HTCJK != NOCJK) {
 	HText_appendCharacter(me->text, c);
-    } else if ((unsigned char)c >= 127 && (unsigned char)c < 161 &&
+    } else if (TOASCII((unsigned char)c) >= 127 && TOASCII((unsigned char)c) < 161 &&
 	       HTPassHighCtrlRaw) {
 	HText_appendCharacter(me->text, c);
-    } else if ((unsigned char)c == 160) {
+    } else if ((unsigned char)c == CH_NBSP) {  /* S/390 -- gil -- 0341 */
 	HText_appendCharacter(me->text, ' ');
-    } else if ((unsigned char)c == 173) {
+    } else if ((unsigned char)c == CH_SHY) {
 	return;
-    } else if (((unsigned char)c >= 32 && (unsigned char)c < 127) ||
+    } else if (((unsigned char)c >= ' ' && TOASCII((unsigned char)c) < 127) ||
 	       c == '\n' || c == '\t') {
 	HText_appendCharacter(me->text, c);
-    } else if ((unsigned char)c > 160) {
+    } else if (TOASCII((unsigned char)c) > 160) {
 	if (!HTPassEightBitRaw &&
 	    !((me->outUCLYhndl == LATIN1) ||
 	      (me->outUCI->enc & (UCT_CP_SUPERSETOF_LAT1)))) {
 	    int len, high, low, i, diff = 1;
 	    CONST char * name;
-	    UCode_t value = (UCode_t)((unsigned char)c - 160);
+	    UCode_t value = (UCode_t)FROMASCII((TOASCII((unsigned char)c) - 160));
 
 	    name = HTMLGetEntityName(value);
 	    len =  strlen(name);
@@ -262,7 +263,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 	    **	Incomplete characters silently ignored.
 	    **	from Linux kernel's console.c - KW
 	    */
-	    if (c_unsign > 127) {
+	    if (TOASCII(c_unsign) > 127) {  /* S/390 -- gil -- 0371 */
 		/*
 		**  We have an octet from a multibyte character. - FM
 		*/
@@ -356,8 +357,8 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 		saved_char_in = c;
 #endif /* NOTDEFINED */
 	if (me->T.trans_to_uni &&
-	    (code >= LYlowest_eightbit[me->inUCLYhndl] ||
-	     (code < 32 && code != 0 &&
+	    (TOASCII(code) >= LYlowest_eightbit[me->inUCLYhndl] ||  /* S/390 -- gil -- 0389 */
+	     (code < ' ' && code != 0 &&
 	     me->T.trans_C0_to_uni))) {
 		/*
 		**  Convert the octet to Unicode. - FM
@@ -441,27 +442,27 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 	**  document matches and pass 127-160 8-bit characters.  If it
 	**  doesn't match, the user should toggle raw/CJK mode off. - FM
 	*/
-	} else if (code >= 127 && code < 161 &&
+	} else if (TOASCII(code) >= 127 && TOASCII(code) < 161 &&  /* S/390 -- gil -- 0427 */
 		   PASSHICTRL && PASS8859SPECL) {
 	    HText_appendCharacter(me->text, c);
-	} else if (code == 173 && PASS8859SPECL) {
+	} else if (code == CH_SHY && PASS8859SPECL) {
 	    HText_appendCharacter(me->text, c);
 	/*
 	**  If neither HTPassHighCtrlRaw nor CJK is set, play it safe
 	**  and treat 160 (nbsp) as an ASCII space (32). - FM
 	*/
-	} else if (code == 160) {
+	} else if (code == CH_NBSP) {
 	    HText_appendCharacter(me->text, ' ');
 	/*
 	**  If neither HTPassHighCtrlRaw nor CJK is set, play it safe
 	**  and ignore 173 (shy). - FM
 	*/
-	} else if (code == 173) {
+	} else if (code == CH_SHY) {
 	    continue;
 	/*
 	**  If we get to here, pass the displayable ASCII characters. - FM
 	*/
-	} else if ((code >= 32 && code < 127) ||
+	} else if ((code >= ' ' && TOASCII(code) < 127) ||
 		   (PASSHI8BIT &&
 		    c >= LYlowest_eightbit[me->outUCLYhndl]) ||
 		   *p == '\n' || *p == '\t') {
@@ -481,14 +482,14 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l)
  ******************************************************************/
 	} else if ((chk = (me->T.trans_from_uni && code >= 160)) &&
 		   (uck = UCTransUniChar(code,
-					 me->outUCLYhndl)) >= 32 &&
+					 me->outUCLYhndl)) >= ' ' &&  /* S/390 -- gil -- 0464 */
 		   uck < 256) {
 	    CTRACE(tfp, "UCTransUniChar returned 0x%.2lX:'%c'.\n",
 			uck, FROMASCII((char)uck));
 	    HText_appendCharacter(me->text, ((char)(uck & 0xff)));
 	} else if (chk &&
 		   (uck == -4 ||
-		    (me->T.repl_translated_C0 && uck > 0 && uck < 32)) &&
+		    (me->T.repl_translated_C0 && uck > 0 && uck < ' ')) &&  /* S/390 -- gil -- 0481 */
 		   /*
 		   **  Not found; look for replacement string.
 		   */
@@ -503,7 +504,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 	**  If we get to here, and should have translated,
 	**  translation has failed so far.
 	*/
-	} else if (chk && code > 127 && me->T.output_utf8) {
+	} else if (chk && TOASCII(code) > 127 && me->T.output_utf8) {  /* S/390 -- gil -- 0498 */
 	    /*
 	    **	We want UTF-8 output, so do it now. - FM
 	    */
@@ -514,7 +515,10 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 	    } else if (UCConvertUniToUtf8(code, replace_buf)) {
 		HText_appendText(me->text, replace_buf);
 	    } else {
-		sprintf(replace_buf, "U%.2lX", code);
+		/*
+		**  Out of luck, so use the UHHH notation (ugh). - gil
+		*/  /* S/390 -- gil -- 0517 */
+		sprintf(replace_buf, "U%.2lX", TOASCII(code));
 		HText_appendText(me->text, replace_buf);
 	    }
 #ifdef NOTDEFINED
@@ -544,7 +548,7 @@ PRIVATE void HTPlain_write ARGS3(HTStream *, me, CONST char*, s, int, l)
 			UCGetLYhndl_byMIME("us-ascii"))) &&
 		   (uck = UCTransUniChar(code,
 					 UCGetLYhndl_byMIME("us-ascii")))
-				      >= 32 && uck < 127) {
+				      >= ' ' && TOASCII(uck) < 127) {  /* S/390 -- gil -- 0535 */
 		/*
 		**  Got an ASCII character (yippey). - FM
 		*/
diff --git a/WWW/Library/Implementation/HTString.c b/WWW/Library/Implementation/HTString.c
index 00f70a6c..8174a059 100644
--- a/WWW/Library/Implementation/HTString.c
+++ b/WWW/Library/Implementation/HTString.c
@@ -5,6 +5,7 @@
 **	02-Dec-91 (JFG) Added stralloccopy and stralloccat
 **	23 Jan 92 (TBL) Changed strallocc* to 8 char HTSAC* for VM and suchlike
 **	 6 Oct 92 (TBL) Moved WWW_TraceFlag in here to be in library
+**	15 Nov 98 (TD)  Added HTSprintf.
 */
 
 #include <HTUtils.h>
@@ -339,3 +340,245 @@ PUBLIC char * HTNextTok ARGS4(
     *pstr = p;
     return start;
 }
+
+PRIVATE char *HTAlloc ARGS2(char *, ptr, size_t, length)
+{
+    if (ptr != 0)
+	ptr = (char *)realloc(ptr, length);
+    else
+	ptr = (char *)malloc(length);
+    if (ptr == 0)
+	outofmem(__FILE__, "HTAlloc");
+    return ptr;
+}
+
+/*
+ * Replacement for sprintf, allocates buffer on the fly according to what's needed
+ * for its arguments.  Unlike sprintf, this always concatenates to the destination
+ * buffer, so we do not have to provide both flavors.
+ */
+typedef enum { Flags, Width, Prec, Type, Format } PRINTF;
+
+#define VA_INTGR(type) ival = va_arg(ap, type)
+#define VA_FLOAT(type) fval = va_arg(ap, type)
+#define VA_POINT(type) pval = (void *)va_arg(ap, type)
+
+#define NUM_WIDTH 10	/* allow for width substituted for "*" in "%*s" */
+#define GROW_EXPR(n) (((n) * 3) / 2)
+#define GROW_SIZE 256
+
+PRIVATE char * StrAllocVsprintf ARGS4(
+	char **,	pstr,
+	size_t,		dst_len,
+	CONST char *,	fmt,
+	va_list,	ap)
+{
+    size_t tmp_len = GROW_SIZE;
+    size_t have, need;
+    char *tmp_ptr;
+    char *fmt_ptr;
+    char *dst_ptr = *pstr;
+
+    if (fmt == 0 || *fmt == '\0')
+	return 0;
+
+    need = strlen(fmt) + 1;
+    if ((fmt_ptr = malloc(need*NUM_WIDTH)) == 0
+     || (tmp_ptr = malloc(tmp_len)) == 0) {
+	outofmem(__FILE__, "StrAllocVsprintf");
+    }
+
+    if (dst_ptr == 0) {
+	dst_ptr = HTAlloc(dst_ptr, have = GROW_SIZE + need);
+    } else {
+	have = strlen(dst_ptr) + 1;
+	if (have < need)
+	    dst_ptr = HTAlloc(dst_ptr, have = GROW_SIZE + need);
+    }
+
+    while (*fmt != '\0') {
+	if (*fmt == '%') {
+	    static char dummy[] = "";
+	    PRINTF state = Flags;
+	    char *pval   = dummy;	/* avoid const-cast */
+	    double fval  = 0.0;
+	    int done     = FALSE;
+	    int ival     = 0;
+	    int prec     = -1;
+	    int type     = 0;
+	    int used     = 0;
+	    int width    = -1;
+	    size_t f     = 0;
+
+	    fmt_ptr[f++] = *fmt;
+	    while (*++fmt != '\0' && dst_len != 0 && !done) {
+		fmt_ptr[f++] = *fmt;
+
+		if (isdigit(*fmt)) {
+		    int num = *fmt - '0';
+		    if (state == Flags && num != 0)
+			state = Width;
+		    if (state == Width) {
+			if (width < 0)
+			    width = 0;
+			width = (width * 10) + num;
+		    } else if (state == Prec) {
+			if (prec < 0)
+			    prec = 0;
+			prec = (prec * 10) + num;
+		    }
+		} else if (*fmt == '*') {
+		    VA_INTGR(int);
+		    if (state == Flags)
+			state = Width;
+		    if (state == Width) {
+			width = ival;
+		    } else if (state == Prec) {
+			prec = ival;
+		    }
+		    sprintf(&fmt_ptr[--f], "%d", ival);
+		    f = strlen(fmt_ptr);
+		} else if (isalpha(*fmt)) {
+		    done = TRUE;
+		    switch (*fmt) {
+		    case 'Z': /* FALLTHRU */
+		    case 'h': /* FALLTHRU */
+		    case 'l': /* FALLTHRU */
+		    case 'L': /* FALLTHRU */
+			done = FALSE;
+			type = *fmt;
+			break;
+		    case 'i': /* FALLTHRU */
+		    case 'd': /* FALLTHRU */
+		    case 'u': /* FALLTHRU */
+		    case 'x': /* FALLTHRU */
+		    case 'X': /* FALLTHRU */
+			if (type == 'l')
+			    VA_INTGR(long);
+			else if (type == 'Z')
+			    VA_INTGR(size_t);
+			else
+			    VA_INTGR(int);
+			used = 'i';
+			break;
+		    case 'f': /* FALLTHRU */
+		    case 'e': /* FALLTHRU */
+		    case 'E': /* FALLTHRU */
+		    case 'g': /* FALLTHRU */
+		    case 'G': /* FALLTHRU */
+			if (type == 'L')
+			    VA_FLOAT(long double);
+			else
+			    VA_FLOAT(double);
+			used = 'f';
+			break;
+		    case 'c':
+			VA_INTGR(int);
+			used = 'i';
+			break;
+		    case 's':
+			VA_POINT(char *);
+			if (prec < 0)
+			    prec = strlen(pval);
+			if (prec > (int)tmp_len) {
+			    tmp_len = GROW_EXPR(tmp_len + prec);
+			    tmp_ptr = HTAlloc(tmp_ptr, tmp_len);
+			}
+			used = 'p';
+			break;
+		    case 'p':
+			VA_POINT(void *);
+			used = 'p';
+			break;
+		    case 'n':
+			VA_POINT(int *);
+			used = 0;
+			break;
+		    default:
+			break;
+		    }
+		} else if (*fmt == '.') {
+		    state = Prec;
+		} else if (*fmt == '%') {
+		    done = TRUE;
+		    used = 'p';
+		}
+	    }
+	    fmt_ptr[f] = '\0';
+	    switch (used) {
+	    case 'i':
+		sprintf(tmp_ptr, fmt_ptr, ival);
+		break;
+	    case 'f':
+		sprintf(tmp_ptr, fmt_ptr, fval);
+		break;
+	    default:
+		sprintf(tmp_ptr, fmt_ptr, pval);
+		break;
+	    }
+	    need = dst_len + strlen(tmp_ptr) + 1;
+	    if (need >= have) {
+		dst_ptr = HTAlloc(dst_ptr, have = GROW_EXPR(need));
+	    }
+	    strcpy(dst_ptr + dst_len, tmp_ptr);
+	    dst_len += strlen(tmp_ptr);
+	} else {
+	    dst_ptr[dst_len++] = *fmt++;
+	}
+    }
+
+    free(tmp_ptr);
+    free(fmt_ptr);
+    dst_ptr[dst_len] = '\0';
+    if (pstr)
+    	*pstr = dst_ptr;
+    return (dst_ptr);
+}
+
+/*
+ * Replacement for sprintf, allocates buffer on the fly according to what's needed
+ * for its arguments.  Unlike sprintf, this always concatenates to the destination
+ * buffer.
+ */
+#if USE_STDARG_H
+PUBLIC char * HTSprintf (char ** pstr, CONST char * fmt, ...)
+#else
+PUBLIC char * HTSprintf (pstr, fmt, va_alist)
+    char **		pstr;
+    CONST char *	fmt;
+    va_dcl
+#endif
+{
+    va_list ap;
+
+    LYva_start(ap,fmt);
+    StrAllocVsprintf(pstr, (pstr && *pstr) ? strlen(*pstr) : 0, fmt, ap);
+    va_end(ap);
+
+    return (*pstr);
+}
+
+/*
+ * Replacement for sprintf, allocates buffer on the fly according to what's
+ * needed for its arguments.  Like sprintf, this always resets the destination
+ * buffer.
+ */
+#if USE_STDARG_H
+PUBLIC char * HTSprintf0 (char ** pstr, CONST char * fmt, ...)
+#else
+PUBLIC char * HTSprintf0 (pstr, fmt, va_alist)
+    char **		pstr;
+    CONST char *	fmt;
+    va_dcl
+#endif
+{
+    va_list ap;
+
+    LYva_start(ap,fmt);
+    if (pstr != 0 && *pstr != 0)
+     	*pstr = 0;
+    StrAllocVsprintf(pstr, 0, fmt, ap);
+    va_end(ap);
+
+    return (*pstr);
+}
diff --git a/WWW/Library/Implementation/HTString.h b/WWW/Library/Implementation/HTString.h
index 0609cb00..85ca5d7f 100644
--- a/WWW/Library/Implementation/HTString.h
+++ b/WWW/Library/Implementation/HTString.h
@@ -1,4 +1,4 @@
-/*                                                                 String handling for libwww
+/*                                                   String handling for libwww
                                          STRINGS
                                              
    Case-independent string comparison and allocations with copies etc
@@ -51,11 +51,16 @@ extern char * HTNextField PARAMS ((char** pstr));
 
 /* A more general parser - kw */
 extern char * HTNextTok PARAMS((char ** pstr,
-		      const char * delims, const char * bracks, char * found));
-
+		      CONST char * delims, CONST char * bracks, char * found));
+
+#if USE_STDARG_H
+extern char * HTSprintf PARAMS((char ** pstr, CONST char * fmt, ...))
+			GCC_PRINTFLIKE(2,3);
+extern char * HTSprintf0 PARAMS((char ** pstr, CONST char * fmt, ...))
+			 GCC_PRINTFLIKE(2,3);
+#else
+extern char * HTSprintf PARAMS((char ** pstr, CONST char * fmt, va_alist));
+extern char * HTSprintf0 PARAMS((char ** pstr, CONST char * fmt, va_alist));
 #endif
-/*
 
-   end
-   
-    */
+#endif /* HTSTRING_H */
diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c
index 04016e47..4ee74ace 100644
--- a/WWW/Library/Implementation/HTTP.c
+++ b/WWW/Library/Implementation/HTTP.c
@@ -584,6 +584,13 @@ try_again:
 
   _HTProgress (gettext("Sending HTTP request."));
 
+#ifdef    NOT_ASCII  /* S/390 -- gil -- 0548 */
+  {   char *p;
+
+      for ( p = command; p < command + strlen(command); p++ )
+	  *p = TOASCII(*p);
+  }
+#endif /* NOT_ASCII */
   status = HTTP_NETWRITE(s, command, (int)strlen(command), handle);
   FREE(command);
   if (status <= 0) {
@@ -679,6 +686,14 @@ try_again:
 	    }
 	}
 
+#ifdef    NOT_ASCII  /* S/390 -- gil -- 0564 */
+	{   char *p;
+
+	    for ( p = line_buffer + length; p < line_buffer + length + status; p++ )
+		*p = FROMASCII(*p);
+	}
+#endif /* NOT_ASCII */
+
 	bytes_already_read += status;
 	HTReadProgress (bytes_already_read, 0);
 
@@ -1062,6 +1077,13 @@ try_again:
 	      while ((status = HTTP_NETREAD(s, line_buffer,
 					    (INIT_LINE_SIZE - 1),
 					    handle)) > 0) {
+#ifdef    NOT_ASCII  /* S/390 -- gil -- 0581 */
+	      {   char *p;
+
+		  for ( p = line_buffer; p < line_buffer + status; p++ )
+		      *p = FROMASCII(*p);
+	      }
+#endif /* NOT_ASCII */
 		  line_buffer[status] = '\0';
 		  StrAllocCat(line_kept_clean, line_buffer);
 	      }
diff --git a/WWW/Library/Implementation/HTTelnet.c b/WWW/Library/Implementation/HTTelnet.c
index 5de48da1..51096e3a 100644
--- a/WWW/Library/Implementation/HTTelnet.c
+++ b/WWW/Library/Implementation/HTTelnet.c
@@ -37,6 +37,12 @@
 
 #define HT_NO_DATA -9999
 
+PRIVATE void do_system ARGS1(char *, command)
+{
+    CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
+    system(command);
+    free(command);
+}
 
 /*	Telnet or "rlogin" access
 **	-------------------------
@@ -48,7 +54,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 	char * cp;
 	char * hostname;
 	char * port;
-	char   command[256];
+	char * command;
 	enum _login_protocol { telnet, rlogin, tn3270 } login_protocol =
 		strcmp(acc_method, "rlogin") == 0 ? rlogin :
 		strcmp(acc_method, "tn3270") == 0 ? tn3270 : telnet;
@@ -101,10 +107,10 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 	if (HTSecure) {
 
 #ifdef TELNETHOPPER_MAIL
-	    sprintf(command,
+	    HTSprintf0(&command,
 	      "finger @%s | mail -s \"**telnethopper %s\" tbl@dxcern.cern.ch",
 	       HTClientHost, HTClientHost);
-	    system(command);
+	    do_system(command);
 #endif
 	    printf("\n\nSorry, but the service you have selected is one\n");
 	    printf("to which you have to log in.  If you were running www\n");
@@ -135,14 +141,13 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
  *		You may need to define this yourself.
  */
 #if	defined(NeXT) && defined(NeXTSTEP) && NeXTSTEP<=20100
-	sprintf(command, "%s%s%s %s %s", TELNET_COMMAND,
+	HTSprintf0(&command, "%s%s%s %s %s", TELNET_COMMAND,
 		user ? " -l " : "",
 		user ? user : "",
 		hostname,
 		port ? port : "");
 
-	CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	system(command);
+	do_system(command);
 	return HT_NO_DATA;		/* Ok - it was done but no data */
 #define TELNET_DONE
 #endif
@@ -151,28 +156,27 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 #if defined(unix) || defined(DOSPATH)
 #ifndef TELNET_DONE
 	if (login_protocol == rlogin) {
-	    sprintf(command, "%s %s%s%s", RLOGIN_COMMAND,
+	    HTSprintf0(&command, "%s %s%s%s", RLOGIN_COMMAND,
 		hostname,
 		user ? " -l " : "",
 		user ? user : "");
 
 	} else if (login_protocol == tn3270) {
-	    sprintf(command, "%s %s %s", TN3270_COMMAND,
+	    HTSprintf0(&command, "%s %s %s", TN3270_COMMAND,
 		hostname,
 		port ? port : "");
 
 	} else {  /* TELNET */
-	    sprintf(command, "%s %s %s", TELNET_COMMAND,
+	    HTSprintf0(&command, "%s %s %s", TELNET_COMMAND,
 		hostname,
 		port ? port : "");
 	}
 
-	CTRACE(tfp, "HTTelnet: Normal: Command is: %s\n\n", command);
 #ifdef __DJGPP__
        __djgpp_set_ctrl_c(0);
        _go32_want_ctrl_break(1);
 #endif /* __DJGPP__ */
-	system(command);
+	do_system(command);
 #ifdef __DJGPP__
        __djgpp_set_ctrl_c(1);
        _go32_want_ctrl_break(0);
@@ -185,7 +189,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 /* VMS varieties */
 #if defined(MULTINET)
 	if (login_protocol == rlogin) {
-	    sprintf(command, "RLOGIN%s%s%s%s%s %s",  /*lm 930713 */
+	    HTSprintf0(&command, "RLOGIN%s%s%s%s%s %s",  /*lm 930713 */
 		user ? "/USERNAME=\"" : "",
 		user ? user : "",
 		user ? "\"" : "",
@@ -194,20 +198,19 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 		hostname);
 
 	} else if (login_protocol == tn3270) {
-	    sprintf(command, "TELNET/TN3270 %s%s %s",
+	    HTSprintf0(&command, "TELNET/TN3270 %s%s %s",
 		port ? "/PORT=" : "",
 		port ? port : "",
 		hostname);
 
 	} else {  /* TELNET */
-	    sprintf(command, "TELNET %s%s %s",
+	    HTSprintf0(&command, "TELNET %s%s %s",
 		port ? "/PORT=" : "",
 		port ? port : "",
 		hostname);
 	}
 
-	CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	system(command);
+	do_system(command);
 	return HT_NO_DATA;		/* Ok - it was done but no data */
 #define TELNET_DONE
 #endif /* MULTINET */
@@ -219,7 +222,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 	    if ((cp=getenv("WINTCP_COMMAND_STYLE")) != NULL &&
 		0==strncasecomp(cp, "VMS", 3)) { /* VMS command syntax */
 		if (login_protocol == rlogin) {
-		    sprintf(command, "RLOGIN%s%s%s%s%s %s",  /*lm 930713 */
+		    HTSprintf0(&command, "RLOGIN%s%s%s%s%s %s",  /*lm 930713 */
 			user ? "/USERNAME=\"" : "",
 			user ? user : "",
 			user ? "\"" : "",
@@ -228,13 +231,13 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 			hostname);
 
 		} else if (login_protocol == tn3270) {
-		    sprintf(command, "TELNET/TN3270 %s%s %s",
+		    HTSprintf0(&command, "TELNET/TN3270 %s%s %s",
 			port ? "/PORT=" : "",
 			port ? port : "",
 			hostname);
 
 		} else {  /* TELNET */
-		    sprintf(command, "TELNET %s%s %s",
+		    HTSprintf0(&command, "TELNET %s%s %s",
 			port ? "/PORT=" : "",
 			port ? port : "",
 			hostname);
@@ -242,7 +245,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 
 	    } else { /* UNIX command syntax */
 	       if (login_protocol == rlogin) {
-		   sprintf(command, "RLOGIN %s%s%s%s%s",
+		   HTSprintf0(&command, "RLOGIN %s%s%s%s%s",
 		       hostname,
 		       user ? " -l " : "",
 		       user ? "\"" : "",
@@ -250,19 +253,18 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 		       user ? "\"" : "");
 
 		} else if (login_protocol == tn3270) {
-		    sprintf(command, "TN3270 %s %s",
+		    HTSprintf0(&command, "TN3270 %s %s",
 			hostname,
 			port ? port : "");
 
 		} else {  /* TELNET */
-		    sprintf(command, "TELNET %s %s",
+		    HTSprintf0(&command, "TELNET %s %s",
 			hostname,
 			port ? port : "");
 		}
 	    }
 
-	    CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	    system(command);
+	    do_system(command);
 	    return HT_NO_DATA;		/* Ok - it was done but no data */
 	}
 #define TELNET_DONE
@@ -270,7 +272,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 
 #ifdef UCX
 	if (login_protocol == rlogin) {
-	    sprintf(command, "RLOGIN%s%s%s %s %s",
+	    HTSprintf0(&command, "RLOGIN%s%s%s %s %s",
 		user ? "/USERNAME=\"" : "",
 		user ? user : "",
 		user ? "\"" : "",
@@ -278,30 +280,28 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 		port ? port : "");
 
 	} else if (login_protocol == tn3270) {
-	    sprintf(command, "TN3270 %s %s",
+	    HTSprintf0(&command, "TN3270 %s %s",
 		hostname,
 		port ? port : "");
 
 	} else {  /* TELNET */
-	    sprintf(command, "TELNET %s %s",
+	    HTSprintf0(&command, "TELNET %s %s",
 		hostname,
 		port ? port : "");
 	}
 
-	CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	system(command);
+	do_system(command);
 	return HT_NO_DATA;		/* Ok - it was done but no data */
 #define TELNET_DONE
 #endif /* UCX */
 
 #ifdef CMU_TCP
 	if (login_protocol == telnet) {
-	    sprintf(command, "TELNET %s%s %s",
+	    HTSprintf0(&command, "TELNET %s%s %s",
 		port ? "/PORT=" : "",
 		port ? port : "",
 		hostname);
-	    CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	    system(command);
+	    do_system(command);
 	}
 	else {
 	    extern BOOLEAN HadVMSInterrupt;
@@ -323,7 +323,7 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 
     if (getenv("MULTINET_SOCKET_LIBRARY") != NULL) {
 	if (login_protocol == rlogin) {
-	    sprintf(command, "MULTINET RLOGIN%s%s%s%s %s",  /*lm 930713 */
+	    HTSprintf0(&command, "MULTINET RLOGIN%s%s%s%s %s",  /*lm 930713 */
 		user ? "/USERNAME=" : "",
 		user ? user : "",
 		port ? "/PORT=" : "",
@@ -331,94 +331,90 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 		hostname);
 
 	} else if (login_protocol == tn3270) {
-	    sprintf(command, "MULTINET TELNET/TN3270 %s%s %s",
+	    HTSprintf0(&command, "MULTINET TELNET/TN3270 %s%s %s",
 		port ? "/PORT=" : "",
 		port ? port : "",
 		hostname);
 
 	} else {  /* TELNET */
-	    sprintf(command, "MULTINET TELNET %s%s %s",
+	    HTSprintf0(&command, "MULTINET TELNET %s%s %s",
 		port ? "/PORT=" : "",
 		port ? port : "",
 		hostname);
 	}
 
-	CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	system(command);
+	do_system(command);
 	return HT_NO_DATA;		/* Ok - it was done but no data */
     }
     else if ((cp=getenv("WINTCP_COMMAND_STYLE")) != NULL) {
 	if (0==strncasecomp(cp, "VMS", 3)) { /* VMS command syntax */
 	    if (login_protocol == rlogin) {
-		sprintf(command, "RLOGIN%s%s%s%s %s",  /*lm 930713 */
+		HTSprintf0(&command, "RLOGIN%s%s%s%s %s",  /*lm 930713 */
 		    user ? "/USERNAME=" : "",
 		    user ? user : "",
 		    port ? "/PORT=" : "",
 		    port ? port : "",
 		    hostname);
 	    } else if (login_protocol == tn3270) {
-		sprintf(command, "TELNET/TN3270 %s%s %s",
+		HTSprintf0(&command, "TELNET/TN3270 %s%s %s",
 		    port ? "/PORT=" : "",
 		    port ? port : "",
 		    hostname);
 	    } else {  /* TELNET */
-		sprintf(command, "TELNET %s%s %s",
+		HTSprintf0(&command, "TELNET %s%s %s",
 		    port ? "/PORT=" : "",
 		    port ? port : "",
 		    hostname);
 	    }
 	} else { /* UNIX command syntax */
 	    if (login_protocol == rlogin) {
-		sprintf(command, "RLOGIN %s%s%s",
+		HTSprintf0(&command, "RLOGIN %s%s%s",
 		    hostname,
 		    user ? " -l " : "",
 		    user ? user : "");
 	    } else if (login_protocol == tn3270) {
-		sprintf(command, "TN3270 %s %s",
+		HTSprintf0(&command, "TN3270 %s %s",
 		    hostname,
 		    port ? port : "");
 	    } else {  /* TELNET */
-		sprintf(command, "TELNET %s %s",
+		HTSprintf0(&command, "TELNET %s %s",
 		    hostname,
 		    port ? port : "");
 	    }
 	}
 
-	CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	system(command);
+	do_system(command);
 	return HT_NO_DATA;		/* Ok - it was done but no data */
     }
     else if (getenv("UCX$DEVICE") != NULL) {
 	if (login_protocol == rlogin) {
-	    sprintf(command, "RLOGIN%s%s %s %s",
+	    HTSprintf0(&command, "RLOGIN%s%s %s %s",
 		user ? "/USERNAME=" : "",
 		user ? user : "",
 		hostname,
 		port ? port : "");
 
 	} else if (login_protocol == tn3270) {
-	    sprintf(command, "TN3270 %s %s",
+	    HTSprintf0(&command, "TN3270 %s %s",
 		hostname,
 		port ? port : "");
 
 	} else {  /* TELNET */
-	    sprintf(command, "TELNET %s %s",
+	    HTSprintf0(&command, "TELNET %s %s",
 		hostname,
 		port ? port : "");
 	}
 
-	CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	system(command);
+	do_system(command);
 	return HT_NO_DATA;		/* Ok - it was done but no data */
     }
     else if (getenv("CMUTEK_ROOT") != NULL) {
 	if (login_protocol == telnet) {
-	    sprintf(command, "TELNET %s%s %s",
+	    HTSprintf0(&command, "TELNET %s%s %s",
 		port ? "/PORT=" : "",
 		port ? port : "",
 		hostname);
-	    CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	    system(command);
+	    do_system(command);
 	}
 	else {
 	    extern BOOLEAN HadVMSInterrupt;
@@ -434,12 +430,11 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
     }
     else {
 	if (login_protocol == telnet) {
-	    sprintf(command, "TELNET %s%s %s",
+	    HTSprintf0(&command, "TELNET %s%s %s",
 		port ? "/PORT=" : "",
 		port ? port : "",
 		hostname);
-	    CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	    system(command);
+	    do_system(command);
 	}
 	else {
 	    extern BOOLEAN HadVMSInterrupt;
@@ -462,10 +457,9 @@ PRIVATE int remote_session ARGS2(char *, acc_method, char *, host)
 #endif
 #ifdef SIMPLE_TELNET
 	if (login_protocol == telnet) { 		/* telnet only */
-	    sprintf(command, "TELNET  %s",	/* @@ Bug: port ignored */
+	    HTSprintf0(&command, "TELNET  %s",	/* @@ Bug: port ignored */
 		hostname);
-	    CTRACE(tfp, "HTTelnet: Command is: %s\n\n", command);
-	    system(command);
+	    do_system(command);
 	    return HT_NO_DATA;		/* Ok - it was done but no data */
 	}
 #endif
diff --git a/WWW/Library/Implementation/HTUtils.h b/WWW/Library/Implementation/HTUtils.h
index 16fc0eb2..29417483 100644
--- a/WWW/Library/Implementation/HTUtils.h
+++ b/WWW/Library/Implementation/HTUtils.h
@@ -317,19 +317,34 @@ Sucess (>=0) and failure (<0) codes
 #define HT_INTERNAL     -12             /* Weird -- should never happen. */
 #define HT_BAD_EOF      -12             /* Premature EOF */
 
-
-#include <HTString.h>   /* String utilities */
-
 #ifndef va_arg
 #if defined(__STDC__) || defined(VMS)
 #include <stdarg.h>
-#define LYva_start(ap,format) va_start(ap,format)
 #else
 #include <varargs.h>
+#endif
+#endif
+
+#if defined(__STDC__) || defined(VMS)
+#define LYva_start(ap,format) va_start(ap,format)
+#define USE_STDARG_H 1
+#else
 #define LYva_start(ap,format) va_start(ap)
+#define USE_STDARG_H 0
 #endif
+
+/*
+ * GCC can be told that some functions are like printf (and do type-checking on
+ * their parameters).
+ */
+#if	GCC_PRINTF
+#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
+#else
+#define GCC_PRINTFLIKE(fmt,var) /*nothing*/
 #endif
 
+#include <HTString.h>   /* String utilities */
+
 /*
 
 Out Of Memory checking for malloc() return:
diff --git a/WWW/Library/Implementation/HTVMSUtils.c b/WWW/Library/Implementation/HTVMSUtils.c
index bf173870..20033864 100644
--- a/WWW/Library/Implementation/HTVMSUtils.c
+++ b/WWW/Library/Implementation/HTVMSUtils.c
@@ -1267,12 +1267,24 @@ int HTVMS_remove(char *filename)
 void HTVMS_purge(char *filename)
 {
     char *older_file = 0;
+    char *oldest_file = 0;
+    struct stat sb;
 
     StrAllocCopy(older_file, filename);
     StrAllocCat(older_file, ";-1");
 
     while (remove(older_file) == 0)
 	;
+    /*
+     * If we do not have any more older versions, it is safe to rename the
+     * current file to version #1.
+     */
+    if (stat(older_file, &sb) != 0) {
+	StrAllocCopy(oldest_file, filename);
+	StrAllocCat(oldest_file, ";1");
+	rename(older_file, oldest_file);
+	FREE(oldest_file);
+    }
 
     FREE(older_file);
 }
diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c
index 7f6324a0..aa99eafe 100644
--- a/WWW/Library/Implementation/SGML.c
+++ b/WWW/Library/Implementation/SGML.c
@@ -28,6 +28,7 @@
 #include <HTChunk.h>
 
 #include <LYCharSets.h>
+#include <LYCharVals.h>  /* S/390 -- gil -- 0635 */
 #include <LYStrings.h>
 #include <LYLeaks.h>
 
@@ -332,12 +333,12 @@ PRIVATE BOOL put_special_unicodes ARGS2(
 	HTStream *,	context,
 	UCode_t,	code)
 {
-    if (code == 160) {
+    if (code == CH_NBSP) {  /* S/390 -- gil -- 0657 */
 	/*
 	**  Use Lynx special character for nbsp.
 	*/
 	PUTC(HT_NON_BREAK_SPACE);
-    } else  if (code == 173) {
+    } else  if (code == CH_SHY) {
 	/*
 	**  Use Lynx special character for shy.
 	*/
@@ -419,6 +420,7 @@ PRIVATE void handle_entity ARGS2(
 	**  Seek a translation from the chartrans tables.
 	*/
 	if ((uck = UCTransUniChar(code, context->outUCLYhndl)) >= 32 &&
+/* =============== work in ASCII below here ===============  S/390 -- gil -- 0672 */
 	    uck < 256 &&
 	    (uck < 127 ||
 	     uck >= LYlowest_eightbit[context->outUCLYhndl])) {
@@ -453,6 +455,7 @@ PRIVATE void handle_entity ARGS2(
 	    FoundEntity = TRUE;
 	    return;
 	}
+/* =============== work in ASCII above here ===============  S/390 -- gil -- 0682 */
 	/*
 	**  Ignore zwnj (8204) and zwj (8205), if we get to here.
 	**  Note that zwnj may have been handled as <WBR>
@@ -478,7 +481,7 @@ PRIVATE void handle_entity ARGS2(
     /*
     **	If entity string not found, display as text.
     */
-    CTRACE(tfp, "SGML: Unknown entity '%s'\n", s);
+    CTRACE(tfp, "SGML: Unknown entity '%s' %d %d\n", s, code, uck); /* S/390 -- gil -- 0695 */
     PUTC('&');
     for (p = s; *p; p++) {
 	PUTC(*p);
@@ -1117,12 +1120,12 @@ PRIVATE void SGML_character ARGS2(
 	**  Incomplete characters silently ignored.
 	**  From Linux kernel's console.c. - KW
 	*/
-	if ((unsigned char)c > 127) {
+	if (TOASCII((unsigned char)c) > 127) { /* S/390 -- gil -- 0710 */
 	    /*
 	    **	We have an octet from a multibyte character. - FM
 	    */
-	    if (context->utf_count > 0 && (c & 0xc0) == 0x80) {
-		context->utf_char = (context->utf_char << 6) | (c & 0x3f);
+	    if (context->utf_count > 0 && (TOASCII(c) & 0xc0) == 0x80) {
+		context->utf_char = (context->utf_char << 6) | (TOASCII(c) & 0x3f);
 		context->utf_count--;
 		*(context->utf_buf_p) = c;
 		(context->utf_buf_p)++;
@@ -1188,7 +1191,7 @@ PRIVATE void SGML_character ARGS2(
 	    *(context->utf_buf_p) = '\0';
 		    /*	goto top;  */
 	}
-    }
+    } /* end of context->T.decode_utf8  S/390 -- gil -- 0726 */
 
 #ifdef NOTDEFINED
     /*
@@ -1206,8 +1209,8 @@ PRIVATE void SGML_character ARGS2(
     **	to Unicode, try that now. - FM
     */
     if (context->T.trans_to_uni &&
-	((unsign_c >= LYlowest_eightbit[context->inUCLYhndl]) ||
-	 (unsign_c < 32 && unsign_c != 0 &&
+	((TOASCII(unsign_c) >= LYlowest_eightbit[context->inUCLYhndl]) ||  /* S/390 -- gil -- 0744 */
+	 (unsign_c < ' ' && unsign_c != 0 &&
 	  context->T.trans_C0_to_uni))) {
 	/*
 	**  Convert the octet to Unicode. - FM
@@ -1220,13 +1223,13 @@ PRIVATE void SGML_character ARGS2(
 	    }
 	}
 	goto top1;
-    } else if (unsign_c < 32 && unsign_c != 0 &&
+    } else if (unsign_c < ' ' && unsign_c != 0 &&  /* S/390 -- gil -- 0768 */
 	       context->T.trans_C0_to_uni) {
 	/*
 	**  This else if may be too ugly to keep. - KW
 	*/
 	if (context->T.trans_from_uni &&
-	    (((clong = UCTransToUni(c, context->inUCLYhndl)) >= 32) ||
+	    (((clong = UCTransToUni(c, context->inUCLYhndl)) >= ' ') ||
 	     (context->T.transp &&
 	      (clong = UCTransToUni(c, context->inUCLYhndl)) > 0))) {
 	    saved_char_in = c;
@@ -1262,7 +1265,7 @@ PRIVATE void SGML_character ARGS2(
 	    }
 	    goto top0a;
 	} /*  Next line end of ugly stuff for C0. - KW */
-    } else {
+    } else {  /* end of context->T.trans_to_uni  S/390 -- gil -- 0791 */
 	goto top0a;
     }
 
@@ -1309,8 +1312,11 @@ top1:
     **	Ignore low ISO 646 7-bit control characters
     **	if HTCJK is not set. - FM
     */
-    if (unsign_c < 32 &&
-	c != 9 && c != 10 && c != 13 &&
+    /*
+    ** Works for both ASCII and EBCDIC. -- gil
+    */  /* S/390 -- gil -- 0811 */
+    if (TOASCII(unsign_c) < 32 &&
+	c != '\t' && c != '\n' && c != '\r' &&
 	HTCJK == NOCJK)
 	return;
 
@@ -1320,7 +1326,7 @@ top1:
     */
 #define PASSHICTRL (context->T.transp || \
 		    unsign_c >= LYlowest_eightbit[context->inUCLYhndl])
-    if (c == 127 &&
+    if (TOASCII(c) == 127 &&  /* S/390 -- gil -- 0830 */
 	!(PASSHICTRL || HTCJK != NOCJK))
 	return;
 
@@ -1328,7 +1334,7 @@ top1:
     **	Ignore 8-bit control characters 128 - 159 if
     **	neither HTPassHighCtrlRaw nor HTCJK is set. - FM
     */
-    if (unsign_c > 127 && unsign_c < 160 &&
+    if (TOASCII(unsign_c) > 127 && TOASCII(unsign_c) < 160 &&  /* S/390 -- gil -- 0847 */
 	!(PASSHICTRL || HTCJK != NOCJK))
 	return;
 
@@ -1353,7 +1359,7 @@ top1:
 	break;
 
     case S_text:
-	if (HTCJK != NOCJK && (c & 0200) != 0) {
+	if (HTCJK != NOCJK && (TOASCII(c) & 0200) != 0) {  /* S/390 -- gil -- 0864 */
 	    /*
 	    **	Setting up for Kanji multibyte handling (based on
 	    **	Takuya ASADA's (asada@three-a.co.jp) CJK Lynx).
@@ -1367,7 +1373,7 @@ top1:
 	    context->state = S_in_kanji;
 	    PUTC(c);
 	    break;
-	} else if (HTCJK != NOCJK && c == '\033') {
+	} else if (HTCJK != NOCJK && TOASCII(c) == '\033') {  /* S/390 -- gil -- 0881 */
 	    /*
 	    **	Setting up for CJK escape sequence handling (based on
 	    **	Takuya ASADA's (asada@three-a.co.jp) CJK Lynx). - FM
@@ -1376,7 +1382,7 @@ top1:
 	    PUTC(c);
 	    break;
 	}
-	if (c == '&' && unsign_c < 127	&&
+	if (c == '&' && TOASCII(unsign_c) < 127  &&  /* S/390 -- gil -- 0898 */
 	    (!context->element_stack ||
 	     (context->element_stack->tag  &&
 	      (context->element_stack->tag->contents == SGML_MIXED ||
@@ -1387,7 +1393,7 @@ top1:
 	    */
 	    string->size = 0;
 	    context->state = S_ero;
-	} else if (c == '<' && unsign_c < 127) {
+	} else if (c == '<' && TOASCII(unsign_c) < 127) {  /* S/390 -- gil -- 0915 */
 	    /*
 	    **	Setting up for possible tag. - FM
 	    */
@@ -1402,14 +1408,14 @@ top1:
 	**  Convert 160 (nbsp) to Lynx special character if
 	**  neither HTPassHighCtrlRaw nor HTCJK is set. - FM
 	*/
-	} else if (unsign_c == 160 &&
+	} else if (unsign_c == CH_NBSP &&  /* S/390 -- gil -- 0932 */
 		   !(PASS8859SPECL || HTCJK != NOCJK)) {
 	    PUTC(HT_NON_BREAK_SPACE);
 	/*
 	**  Convert 173 (shy) to Lynx special character if
 	**  neither HTPassHighCtrlRaw nor HTCJK is set. - FM
 	*/
-	} else if (unsign_c == 173 &&
+	} else if (unsign_c == CH_SHY &&  /* S/390 -- gil -- 0949 */
 		   !(PASS8859SPECL || HTCJK != NOCJK)) {
 	    PUTC(LY_SOFT_HYPHEN);
 	/*
@@ -1427,9 +1433,9 @@ top1:
 /******************************************************************
  *   I. LATIN-1 OR UCS2  TO  DISPLAY CHARSET
  ******************************************************************/
-	} else if ((chk = (context->T.trans_from_uni && unsign_c >= 160)) &&
+	} else if ((chk = (context->T.trans_from_uni && TOASCII(unsign_c) >= 160)) &&  /* S/390 -- gil -- 0968 */
 		   (uck = UCTransUniChar(unsign_c,
-					 context->outUCLYhndl)) >= 32 &&
+					 context->outUCLYhndl)) >= ' ' &&
 		   uck < 256) {
 	    CTRACE(tfp, "UCTransUniChar returned 0x%.2lX:'%c'.\n",
 			uck, FROMASCII((char)uck));
@@ -1491,7 +1497,7 @@ top1:
 	**  If we get to here and have an ASCII char,
 	**  pass the character. - KW
 	*/
-	} else if (unsign_c < 127 && unsign_c > 0) {
+	} else if (TOASCII(unsign_c) < 127 && unsign_c > 0) {  /* S/390 -- gil -- 0987 */
 	    PUTC(c);
 	/*
 	**  If we get to here, and should have translated,
@@ -1523,7 +1529,7 @@ top1:
 	**  If we don't actually want the character,
 	**  make it safe and output that now. - FM
 	*/
-	} else if ((unsigned char)c <
+	} else if (TOASCII((unsigned char)c) <   /* S/390 -- gil -- 0997 */
 			LYlowest_eightbit[context->outUCLYhndl] ||
 		   (context->T.trans_from_uni && !HTPassEightBitRaw)) {
 #ifdef NOTUSED_FOTEMODS
@@ -1537,11 +1543,11 @@ top1:
 			UCGetLYhndl_byMIME("us-ascii"))) &&
 		(uck = UCTransUniChar(unsign_c,
 				      UCGetLYhndl_byMIME("us-ascii")))
-				      >= 32 && uck < 127) {
+				      >= ' ' && TOASCII(uck) < 127) {  /* S/390 -- gil -- 1008 */
 		/*
 		**  Got an ASCII character (yippey). - FM
 		*/
-		PUTC(((char)(uck & 0xff)));
+		PUTC(((char)FROMASCII(TOASCII(uck) & 0xff)));
 	    } else if ((chk && uck == -4) &&
 		       (uck = UCTransUniCharStr(replace_buf,
 						60, clong,
@@ -1557,8 +1563,9 @@ top1:
 		/*
 		**  Out of luck, so use the UHHH notation (ugh). - FM
 		*/
+			/* S/390 -- gil -- 1018 */
 			/* do not print UHHH for now
-		sprintf(replace_buf, "U%.2lX", unsign_c);
+		sprintf(replace_buf, "U%.2lX", TOASCII(unsign_c));
 		for (p = replace_buf; *p; p++) {
 		    PUTC(*p);
 		}
@@ -1624,7 +1631,7 @@ top1:
     **	Handle possible named entity.
     */
     case S_entity:
-	if (unsign_c < 127 && (string->size ?
+	if (TOASCII(unsign_c) < 127 && (string->size ?  /* S/390 -- gil -- 1029 */
 		  isalnum((unsigned char)c) : isalpha((unsigned char)c))) {
 	    /*
 	    **	Accept valid ASCII character. - FM
@@ -1643,6 +1650,8 @@ top1:
 	    **	Terminate entity name and try to handle it. - FM
 	    */
 	    HTChunkTerminate(string);
+	    /* S/390 -- gil -- 1039 */
+	    /* CTRACE(tfp, "%s: %d: %s\n", __FILE__, __LINE__, string->data); */
 	    if (!strcmp(string->data, "zwnj") &&
 		(!context->element_stack ||
 		 (context->element_stack->tag  &&
@@ -1688,10 +1697,10 @@ top1:
     **	Check for a numeric entity.
     */
     case S_cro:
-	if (unsign_c < 127 && TOLOWER((unsigned char)c) == 'x') {
+	if (TOASCII(unsign_c) < 127 && TOLOWER((unsigned char)c) == 'x') {  /* S/390 -- gil -- 1060 */
 	    context->isHex = TRUE;
 	    context->state = S_incro;
-	} else if (unsign_c < 127 && isdigit((unsigned char)c)) {
+	} else if (TOASCII(unsign_c) < 127 && isdigit((unsigned char)c)) {
 	    /*
 	    **	Accept only valid ASCII digits. - FM
 	    */
@@ -1714,7 +1723,9 @@ top1:
     **	Handle a numeric entity.
     */
     case S_incro:
-	if ((unsign_c < 127) &&
+	/* S/390 -- gil -- 1075 */ /* CTRACE(tfp, "%s: %d: numeric %d %d\n",
+			    __FILE__, __LINE__, unsign_c, c); */
+	if ((TOASCII(unsign_c) < 127) &&
 	    (context->isHex ? isxdigit((unsigned char)c) :
 			      isdigit((unsigned char)c))) {
 	    /*
@@ -1741,6 +1752,7 @@ top1:
 	    HTChunkTerminate(string);
 	    if ((context->isHex ? sscanf(string->data, "%lx", &code) :
 				  sscanf(string->data, "%ld", &code)) == 1) {
+/* =============== work in ASCII below here ===============  S/390 -- gil -- 1092 */
 		if ((code == 1) ||
 		    (code > 127 && code < 156)) {
 		    /*
@@ -1963,11 +1975,12 @@ top1:
 				   UCGetLYhndl_byMIME("us-ascii"))) &&
 			   (uck = UCTransUniChar(code,
 				   UCGetLYhndl_byMIME("us-ascii")))
-				  >= 32 && uck < 127) {
+				  >= ' ' && uck < 127) {
 		    /*
 		    **	Got an ASCII character (yippey). - FM
 		    */
-		    PUTC(((char)(uck & 0xff)));
+		    PUTC(((char)FROMASCII(uck & 0xff)));
+/* =============== work in ASCII above here ===============  S/390 -- gil -- 1118 */
 		} else if ((chk && uck == -4) &&
 			   (uck = UCTransUniCharStr(replace_buf,
 						    60, code,
@@ -2016,12 +2029,12 @@ top1:
 		**  - FM
 		*/
 		} else if ((code > 255) ||
-			   (code < 32 &&
-			    code != 9 && code != 10 && code != 13 &&
+			   (code < ' ' &&  /* S/390 -- gil -- 1140 */
+			    code != '\t' && code != '\n' && code != '\r' &&
 			    HTCJK == NOCJK) ||
-			   (code == 127 &&
+			   (TOASCII(code) == 127 &&
 			    !(HTPassHighCtrlRaw || HTCJK != NOCJK)) ||
-			   (code > 127 && code < 160 &&
+			   (TOASCII(code) > 127 && code < 160 &&
 			    !HTPassHighCtrlNum)) {
 			/*
 			**  Unhandled or illegal value.  Recover the
@@ -2041,7 +2054,7 @@ top1:
 			context->isHex = FALSE;
 			context->state = S_text;
 			goto top1;
-		} else if (code < 161 ||
+		} else if (TOASCII(code) < 161 ||  /* S/390 -- gil -- 1162 */
 			   HTPassEightBitNum ||
 			   IncludesLatin1Enc) {
 		    /*
@@ -2134,7 +2147,7 @@ top1:
     **	Tag
     */
     case S_tag: 				/* new tag */
-	if (unsign_c < 127 && (string->size ?
+	if (TOASCII(unsign_c) < 127 && (string->size ?  /* S/390 -- gil -- 1179 */
 		  isalnum((unsigned char)c) : isalpha((unsigned char)c))) {
 	    /*
 	    **	Add valid ASCII character. - FM
@@ -2152,7 +2165,7 @@ top1:
 	    HTChunkPutc(string, c);
 	    break;
 	} else if (!string->size &&
-		   (unsign_c <= 160 &&
+		   (TOASCII(unsign_c) <= 160 &&  /* S/390 -- gil -- 1196 */
 		    (c != '/' && c != '?' && c != '_' && c != ':'))) {
 	    /*
 	    **	'<' must be followed by an ASCII letter to be a valid
@@ -2616,7 +2629,7 @@ top1:
 	    handle_attribute_value(context, string->data);
 	    string->size = 0;
 	    context->state = S_tag_gap;
-	} else if (c == '\033') {
+	} else if (TOASCII(c) == '\033') {  /* S/390 -- gil -- 1213 */
 	    /*
 	    **	Setting up for possible single quotes in CJK escape
 	    **	sequences. - Takuya ASADA (asada@three-a.co.jp)
@@ -2657,7 +2670,7 @@ top1:
 	    context->state = S_tag_gap;
 	    if (c == '>')	/* We emulated the Netscape bug, so we go  */
 		goto top1;	/* back and treat it as the tag terminator */
-	} else if (c == '\033') {
+	} else if (TOASCII(c) == '\033') {  /* S/390 -- gil -- 1230 */
 	    /*
 	    **	Setting up for possible double quotes in CJK escape
 	    **	sequences. - Takuya ASADA (asada@three-a.co.jp)
@@ -2689,7 +2702,7 @@ top1:
 	break;
 
     case S_end: 				/* </ */
-	if (unsign_c < 127 && isalnum((unsigned char)c)) {
+	if (TOASCII(unsign_c) < 127 && isalnum((unsigned char)c)) {  /* S/390 -- gil -- 1247 */
 	    HTChunkPutc(string, c);
 	} else {				/* End of end tag name */
 	    HTTag * t = 0;
@@ -2881,7 +2894,7 @@ top1:
 	break;
 
     case S_nonascii_text: /* Expecting CJK ESC after non-ASCII text. */
-	if (c == '\033') {
+	if (TOASCII(c) == '\033') {  /* S/390 -- gil -- 1264 */
 	    context->state = S_esc;
 	}
 	PUTC(c);
@@ -2928,7 +2941,7 @@ top1:
 	break;
 
     case S_nonascii_text_sq: /* Expecting CJK ESC after non-ASCII text. */
-	if (c == '\033') {
+	if (TOASCII(c) == '\033') {  /* S/390 -- gil -- 1281 */
 	    context->state = S_esc_sq;
 	}
 	HTChunkPutc(string, c);
@@ -2975,7 +2988,7 @@ top1:
 	break;
 
     case S_nonascii_text_dq: /* Expecting CJK ESC after non-ASCII text. */
-	if (c == '\033') {
+	if (TOASCII(c) == '\033') {  /* S/390 -- gil -- 1298 */
 	    context->state = S_esc_dq;
 	}
 	HTChunkPutc(string, c);
diff --git a/WWW/Library/Implementation/tcp.h b/WWW/Library/Implementation/tcp.h
index 64f1de86..7fe9a22b 100644
--- a/WWW/Library/Implementation/tcp.h
+++ b/WWW/Library/Implementation/tcp.h
@@ -115,12 +115,32 @@ typedef struct sockaddr_in SockA;  /* See netinet/in.h */
 
 /*
 
-  M ACROS FOR CONVERTING CHARACTERS
+  MACROS FOR CONVERTING CHARACTERS
 
  */
 #ifndef TOASCII
+#ifdef EBCDIC  /* S/390 -- gil -- 1327 */
+
+extern       char un_IBM1047[];
+extern unsigned char IBM1047[];
+/* For debugging
+#include <assert.h>
+#define   TOASCII(c) (assert((c)>=0 && (c)<256), un_IBM1047[c])
+*/ /* for production */
+#define   TOASCII(c) (un_IBM1047[c])
+
+#define FROMASCII(c) (IBM1047[c])
+
+#else  /* EBCDIC */
+
+#if '0' != 48
+#error Host character set is not ASCII.
+#endif
+
 #define TOASCII(c) (c)
 #define FROMASCII(c) (c)
+
+#endif /* EBCDIC */
 #endif /* !TOASCII */
 
 
@@ -505,6 +525,9 @@ Regular BSD unix versions
 #include <string.h>
 #endif /* HAVE_STRING_H */
 #include <errno.h>          /* independent */
+#ifdef __MVS__  /* S/390 -- gil -- 1361 */
+#include <time.h>
+#endif /* __MVS__ */
 #ifdef SCO
 #include <sys/timeb.h>
 #include <time.h>
@@ -514,7 +537,9 @@ Regular BSD unix versions
 #endif /* AIX || SVR4 */
 #include <sys/time.h>       /* independent */
 #include <sys/stat.h>
+#ifndef __MVS__  /* S/390 -- gil -- 1373 */
 #include <sys/param.h>
+#endif /* __MVS__ */
 #include <sys/file.h>       /* For open() etc */
 
 #if defined(NeXT) || defined(sony_news)