about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>1997-02-09 22:44:52 -0500
committerThomas E. Dickey <dickey@invisible-island.net>1997-02-09 22:44:52 -0500
commit6f66219647d92d2af2427d416e00e6f2a8f825dc (patch)
tree0560172642638a687023c25b3f0b3739df2bb8e5
parent9c63ba04a5785f8ad069bf660402530617451a06 (diff)
downloadlynx-snapshots-6f66219647d92d2af2427d416e00e6f2a8f825dc.tar.gz
snapshot of project "lynx", label v2_6fm_970209
-rw-r--r--CHANGES27
-rw-r--r--INSTALLATION46
-rw-r--r--LYMessages_en.h2
-rw-r--r--WWW/Library/Implementation/HTAccess.c37
-rw-r--r--WWW/Library/Implementation/HTNews.c481
-rw-r--r--WWW/Library/Implementation/HTNews.h8
-rw-r--r--lynx.cfg58
-rw-r--r--lynx_help/Lynx_users_guide.html14
-rw-r--r--lynx_help/lynx_url_support.html51
-rw-r--r--samples/lynx.cfg58
-rw-r--r--src/GridText.c97
-rw-r--r--src/HTAlert.c2
-rw-r--r--src/LYCharSets.c2
-rw-r--r--src/LYCookie.c101
-rw-r--r--src/LYGetFile.c20
-rw-r--r--src/LYGlobalDefs.h9
-rw-r--r--src/LYMain.c53
-rw-r--r--src/LYMainLoop.c25
-rw-r--r--src/LYNews.c543
-rw-r--r--src/LYNews.h2
-rw-r--r--src/LYReadCFG.c76
-rw-r--r--src/LYUtils.c74
-rw-r--r--src/LYUtils.h20
-rw-r--r--userdefs.h55
24 files changed, 1314 insertions, 547 deletions
diff --git a/CHANGES b/CHANGES
index 8cfb9aa0..50137901 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,30 @@
+02-09-97
+* Enhanced the Set-Cookie header parser to handle values that contain
+  spaces but were not enclosed in double-quotes, and to use such
+  quoting or not when sending Cookie headers, depending on whether
+  this was done in the Set-Cookie header.  Also added anti-crash
+  checks should the parser's efforts to handle both historical (a.k.a.
+  original Netscape) cookies and Version 1 cookies go awry (does deal
+  successfully now with all the cookies which had been reported as
+  problematic). - FM
+* Mods of the screen handling in LYNews.c for cleaning up any screen
+  trash created by the external editor. - FM
+* Tracked down an uninitialized pointer in LYNews.c that probably was
+  behind reports of crashes when posting to newsgroups. - FM
+* Plugged a memory leak in LYMainLoop.c. - TJC
+* Added posting ability to the news gateway, in lieu of the previous,
+  variably reliable, use of a spawned news client for posting.  The
+  news, nntp, and snews URLs now all return links for posting new
+  messages or followups (replies) to the server from which a newsgroup
+  listing or news article was retrieved, unless the server indicates
+  that it does not accept posts from the site at which Lynx is running.
+  See the updated INSTALLATION, userdefs.h, and lynx.cfg files, the
+  "USENET News posting" section of the Users Guide, and "Supported URLs"
+  page of the online 'h'elp for more information.
+* Fixed typo for e-dieresis in the KOI8-R charset. - AJF
+* Replaced an inappropriate _user_message() call in HTConfirmCookie()
+  of HTAlert.c with a _statusline() call.  The original code could
+  cause crashes with some cookie values. - FM
 02-06-97
 * Added support for both hex escaped and unescaped white characters
   in lynxexec and lynxprog URLs.  Normally, Lynx strips out any white
diff --git a/INSTALLATION b/INSTALLATION
index fb72777a..0f746567 100644
--- a/INSTALLATION
+++ b/INSTALLATION
@@ -2,7 +2,7 @@ For a description of Lynx please read the README file.
 
         Lynx Installation guide.
 
-        Last Updated August 1996
+        Last Updated February 1997
 
 UNIX & VMS Step 1a. 
     Most of the variables that you are likely to change are in the
@@ -43,25 +43,19 @@ UNIX Step 1d.  (WAIS support is built into Lynx for VMS, skip to step 1e)
     in the library.  If everything goes well you should
     be able to make and have direct WAIS access.
 
-UNIX Step 1e.
+UNIX & VMS Step 1e.
     Adding NEWS support.
-    To enable news reading ability via Lynx, set the environment variable
-    NNTPSERVER so that it points to your site's NNTP server (see Step 5).
-
-    To enable news posting ability from Lynx, in userdefs.h (and optionally
-    in lynx.cfg) define INEWS to the full path and name of the inews program.
-    A "mini" inews has been included in the utils directory.  Note that INN
-    may require the -h switch following the path.
-
-VMS Step 1e.
-    Adding NEWS support.
-    To enable news reading ability via Lynx, set the environment variable
-    NNTPSERVER so that it points to your site's NNTP server (see Step 5).
-
-    To enable news posting ability from Lynx, in userdefs.h (and optionally
-    in lynx.cfg) define INEWS to the foreign command for invoking news via
-    your ANU-NEWS client (presumably, "NEWS").  The ANU-NEWS software is
-    available from ftp.cc.ukans.edu.
+    To set your site's NTTP server as the default host for news reading
+    and posting via Lynx, set the environment variable NNTPSERVER so that
+    it points to its Internet address (see Step 5).
+
+    For news posting ability to be enabled in Lynx, in userdefs.h (and
+    optionally in lynx.cfg) the NEWS_POSTING symbol must be defined to
+    TRUE.  Also define LYNX_SIG_FILE in usersdefs.h or lynx.cfg so that
+    it points to users' signature files for appending to posted messages.
+    For the Organization: header in news postings, Lynx checks for an
+    ORGANIZATION or NEWS_ORGANIZATION environment variable.  On Unix,
+    Lynx also checks for an /etc/organization file.
 
 UNIX Step 1f. (Sun systems)
     Sun resolv library.
@@ -251,7 +245,7 @@ UNIX and VMS Step 5.
     Lynx uses some environment variables to regulate it's behavior.
     
     The variable "NNTPSERVER" is used to specify the host which will
-    be used for news URLs.
+    be used as the default for news URLs.
     
 	UNIX
 		setenv NNTPSERVER "news.server.dom"
@@ -260,6 +254,10 @@ UNIX and VMS Step 5.
 		define/system NNTPSERVER "news.server.dom"
 
 
+    The environment variables "ORGANIZATION" or "NEWS_ORGANIZATION", if set,
+    will be used for the Organization: header in news postings.
+
+
     The environment variable "LYNX_CFG", if set, will override the default
     location and name of the global configuration file (lynx.cfg) that was
     defined via the constant "LYNX_CFG_FILE" in userdefs.h.  See userdefs.h
@@ -299,7 +297,11 @@ UNIX and VMS Step 5.
                 setenv ftp_proxy "http://some.server.dom:port/"
                 setenv gopher_proxy "http://some.server.dom:port/"
                 setenv news_proxy "http://some.server.dom:port/"
+                setenv newspost_proxy "http://some.server.dom:port/"
+                setenv newsreply_proxy "http://some.server.dom:port/"
                 setenv snews_proxy "http://some.server.dom:port/"
+                setenv snewspost_proxy "http://some.server.dom:port/"
+                setenv snewsreply_proxy "http://some.server.dom:port/"
                 setenv nntp_proxy "http://some.server.dom:port/"
                 setenv wais_proxy "http://some.server.dom:port/"
                 setenv finger_proxy "http://some.server.dom:port/"
@@ -311,7 +313,11 @@ UNIX and VMS Step 5.
                 define "ftp_proxy" "http://some.server.dom:port/"
                 define "gopher_proxy" "http://some.server.dom:port/"
                 define "news_proxy" "http://some.server.dom:port/"
+                define "newspost_proxy" "http://some.server.dom:port/"
+                define "newsreply_proxy" "http://some.server.dom:port/"
                 define "snews_proxy" "http://some.server.dom:port/"
+                define "snewspost_proxy" "http://some.server.dom:port/"
+                define "snewsreply_proxy" "http://some.server.dom:port/"
                 define "nntp_proxy" "http://some.server.dom:port/"
                 define "wais_proxy" "http://some.server.dom:port/"
                 define "finger_proxy" "http://some.server.dom:port/"
diff --git a/LYMessages_en.h b/LYMessages_en.h
index 1b0324f4..5c5c042b 100644
--- a/LYMessages_en.h
+++ b/LYMessages_en.h
@@ -392,6 +392,8 @@
 #define SPAWNING_EDITOR_FOR_NEWS \
  "Spawning your selected editor to edit news message"
 #define POST_MSG_PROMPT "Post this message? (y/n) "
+#define APPEND_SIG_FILE "Append '%s'?  (y/n) "
+#define POSTING_TO_NEWS "Posting to newsgroup(s)..."
 #ifdef VMS
 #define HAVE_UNREAD_MAIL_MSG "*** You have unread mail. ***"
 #else
diff --git a/WWW/Library/Implementation/HTAccess.c b/WWW/Library/Implementation/HTAccess.c
index 45eb96b8..52a18870 100644
--- a/WWW/Library/Implementation/HTAccess.c
+++ b/WWW/Library/Implementation/HTAccess.c
@@ -135,7 +135,11 @@ extern GLOBALREF (HTProtocol, HTRlogin);
 extern GLOBALREF (HTProtocol, HTFTP);
 extern GLOBALREF (HTProtocol, HTNews);
 extern GLOBALREF (HTProtocol, HTNNTP);
+extern GLOBALREF (HTProtocol, HTNewsPost);
+extern GLOBALREF (HTProtocol, HTNewsReply);
 extern GLOBALREF (HTProtocol, HTSNews);
+extern GLOBALREF (HTProtocol, HTSNewsPost);
+extern GLOBALREF (HTProtocol, HTSNewsReply);
 extern GLOBALREF (HTProtocol, HTGopher);
 extern GLOBALREF (HTProtocol, HTCSO);
 extern GLOBALREF (HTProtocol, HTFinger);
@@ -146,8 +150,9 @@ extern GLOBALREF (HTProtocol, HTWAIS);
 #else
 GLOBALREF HTProtocol HTTP, HTTPS, HTFile, HTTelnet, HTTn3270, HTRlogin;
 #ifndef DECNET
-GLOBALREF  HTProtocol HTFTP, HTNews, HTNNTP, HTSNews, HTGopher, HTCSO;
-GLOBALREF HTProtocol HTFinger;
+GLOBALREF HTProtocol HTFTP, HTNews, HTNNTP, HTNewsPost, HTNewsReply;
+GLOBALREF HTProtocol HTSNews, HTSNewsPost, HTSNewsReply;
+GLOBALREF HTProtocol HTGopher, HTCSO, HTFinger;
 #ifdef DIRECT_WAIS
 GLOBALREF  HTProtocol HTWAIS;
 #endif /* DIRECT_WAIS */
@@ -163,7 +168,11 @@ GLOBALREF  HTProtocol HTWAIS;
     HTRegisterProtocol(&HTFTP);
     HTRegisterProtocol(&HTNews);
     HTRegisterProtocol(&HTNNTP);
+    HTRegisterProtocol(&HTNewsPost);
+    HTRegisterProtocol(&HTNewsReply);
     HTRegisterProtocol(&HTSNews);
+    HTRegisterProtocol(&HTSNewsPost);
+    HTRegisterProtocol(&HTSNewsReply);
     HTRegisterProtocol(&HTGopher);
     HTRegisterProtocol(&HTCSO);
     HTRegisterProtocol(&HTFinger);
@@ -254,16 +263,20 @@ PRIVATE BOOL override_proxy ARGS1(
     } else {					/* Use default port */
         access = HTParse(addr, "", PARSE_ACCESS);
         if (access != NULL) {
-            if      (!strcmp(access, "http"))	port = 80;
-            else if (!strcmp(access, "https"))	port = 443;
-            else if (!strcmp(access, "ftp"))	port = 21;
-            else if (!strcmp(access, "gopher"))	port = 70;
-            else if (!strcmp(access, "cso"))	port = 105;
-	    else if (!strcmp(access, "news"))	port = 119;
-	    else if (!strcmp(access, "snews"))	port = 563;
-	    else if (!strcmp(access, "nntp"))	port = 119;
-	    else if (!strcmp(access, "wais"))	port = 210;
-	    else if (!strcmp(access, "finger"))	port = 79;
+            if      (!strcmp(access, "http"))		port = 80;
+            else if (!strcmp(access, "https"))		port = 443;
+            else if (!strcmp(access, "ftp"))		port = 21;
+            else if (!strcmp(access, "gopher"))		port = 70;
+            else if (!strcmp(access, "cso"))		port = 105;
+	    else if (!strcmp(access, "news"))		port = 119;
+	    else if (!strcmp(access, "nntp"))		port = 119;
+	    else if (!strcmp(access, "newspost"))	port = 119;
+	    else if (!strcmp(access, "newsreply"))	port = 119;
+	    else if (!strcmp(access, "snews"))		port = 563;
+	    else if (!strcmp(access, "snewspost"))	port = 563;
+	    else if (!strcmp(access, "snewsreply"))	port = 563;
+	    else if (!strcmp(access, "wais"))		port = 210;
+	    else if (!strcmp(access, "finger"))		port = 79;
             FREE(access);
         }
     }
diff --git a/WWW/Library/Implementation/HTNews.c b/WWW/Library/Implementation/HTNews.c
index dd39093f..5a86151e 100644
--- a/WWW/Library/Implementation/HTNews.c
+++ b/WWW/Library/Implementation/HTNews.c
@@ -33,10 +33,10 @@ PUBLIC int HTNewsMaxChunk = 40;	/* Largest number of articles in one window */
 
 #ifndef DEFAULT_NEWS_HOST
 #define DEFAULT_NEWS_HOST "news"
-#endif
+#endif /* DEFAULE_NEWS_HOST */
 #ifndef SERVER_FILE
 #define SERVER_FILE "/usr/local/lib/rn/server"
-#endif
+#endif /* SERVER_FILE */
 
 #define NEWS_NETWRITE  NETWRITE
 #define NEWS_NETCLOSE  NETCLOSE
@@ -69,10 +69,11 @@ extern int interrupted_in_htgetcharacter;
 /*
 **  Module-wide variables.
 */
-PUBLIC  char * HTNewsHost = NULL;
-PRIVATE char * NewsHost = NULL;
-PRIVATE char * NewsHREF = NULL;
+PUBLIC  char * HTNewsHost = NULL;		/* Default host */
+PRIVATE char * NewsHost = NULL;			/* Current host */
+PRIVATE char * NewsHREF = NULL;			/* Current HREF prefix */
 PRIVATE int s;					/* Socket for NewsHost */
+PRIVATE HTCanPost = FALSE;			/* Current POST permission */
 PRIVATE char response_text[LINE_LENGTH+1];	/* Last response */
 /* PRIVATE HText *	HT;	*/		/* the new hypertext */
 PRIVATE HTStructured * target;			/* The output sink */
@@ -182,7 +183,7 @@ PRIVATE int response ARGS1(CONST char *,command)
 	}
 #else
         status = NEWS_NETWRITE(s, (char *)command, length);
-#endif
+#endif /* NOT_ASCII */
 	if (status < 0){
 	    if (TRACE) fprintf(stderr,
 	        "HTNews: Unable to send command. Disconnecting.\n");
@@ -479,9 +480,166 @@ PRIVATE void abort_socket NOARGS
     s = -1;		/* End of file on response */
 }
 
-/*	Read in an Article					read_article
+/*
+**  Determine if a line is a valid header line.			valid_header
+**  -------------------------------------------
+*/
+PRIVATE BOOLEAN valid_header ARGS1(
+	char *,		line)
+{
+    char *colon, *space;
+
+    /*
+    **  Blank or tab in first position implies
+    **  this is a continuation header.
+    */
+    if (line[0] == ' ' || line[0] == '\t')
+	return(TRUE);
+
+    /*
+    **  Just check for initial letter, colon, and space to make
+    **  sure we discard only invalid headers.
+    */
+    colon = strchr(line, ':');
+    space = strchr(line, ' ');
+    if (isalpha(line[0]) && colon && space == colon + 1)
+        return(TRUE);
+
+    /*
+    **  Anything else is a bad header -- it should be ignored.
+    */
+    return(FALSE);
+}
+
+/*	post in an Article					post_article
 **	------------------
+**  			(added by FM, modeled on Lynx's previous mini inews)
 **
+**	Note the termination condition of a single dot on a line by itself.
+**
+**  On entry,
+**	s		Global socket number is OK
+**	postfile	file with header and article to post.
+*/ 
+PRIVATE void post_article ARGS1(
+	char *,		postfile)
+{
+    char line[512];
+    char buf[512];
+    char crlf[3];
+    char *cp;
+    int status;
+    FILE *fd;
+    int in_header = 1, seen_header = 0, seen_fromline = 0;
+    int blen = 0, llen = 0;
+
+
+    /*
+    **  Open the temporary file with the
+    **  nntp headers and message body. - FM
+    */
+    if ((fd = fopen((postfile ? postfile : ""), "r")) == NULL) {
+	HTAlert("Cannot open temporary file for news POST.");
+	return;
+    }
+
+    /*
+    **  Read the temporary file and post
+    **  in maximum 512 byte chunks. - FM
+    */
+    buf[0] = '\0';
+    sprintf(crlf, "%c%c", CR, LF);
+    while (fgets(line, sizeof(line), fd) != NULL) {
+	if ((cp = strchr(line, '\n')) != NULL)
+	    *cp = '\0';
+	if (line[0] == '.') {
+	    /*
+	    **  A single '.' means end of transmission
+	    **  for nntp.  Lead dots on lines normally
+	    **  are trimmed and the EOF is not registered
+	    **  if the dot was not followed by CRLF.
+	    **  We prepend an extra dot for any line
+	    **  beginning with one, to retain the one
+	    **  intended, as well as avoid a false EOF
+	    **  signal.  We know we have room for it in
+	    **  the buffer, because we normally send when
+	    **  it would exceed 510. - FM
+	    */
+	    strcat(buf, ".");
+	    blen++;
+	}
+	llen = strlen(line);
+	if (in_header && !strncasecomp(line, "From:", 5)) {
+	    seen_header = 1;
+	    seen_fromline = 1;
+	}
+	if (in_header && line[0] == '\0') {
+	    if (seen_header) {
+		in_header = 0;
+		if (!seen_fromline) {
+		    if (blen < 475) {
+		        strcat(buf, "From: anonymous@nowhere.you.know");
+			strcat(buf, crlf);
+			blen += 34;
+		    } else {
+			NEWS_NETWRITE(s, buf, blen);
+			sprintf(buf,
+				"From: anonymous@nowhere.you.know%s", crlf);
+			blen = 34;
+		    }
+		}
+	     } else {
+		continue;
+	    }
+	} else if (in_header) {
+	    if (valid_header(line)) {
+		seen_header = 1;
+	    } else {
+		continue;
+	    }
+	}
+	strcat(line, crlf);
+	llen += 2;
+	if ((blen + llen) < 511) {
+	    strcat(buf, line);
+	    blen += llen;
+	} else {
+	    NEWS_NETWRITE(s, buf, blen);
+	    strcpy(buf, line);
+	    blen = llen;
+	}
+    }
+
+    /*
+    **  Send the nntp EOF and get the server's response. - FM
+    */
+    if (blen < 508) {
+        strcat(buf, ".");
+	strcat(buf, crlf);
+	blen += 3;
+	NEWS_NETWRITE(s, buf, blen);
+    } else {
+        NEWS_NETWRITE(s, buf, blen);
+	sprintf(buf, ".%s", crlf);
+	blen = 3;
+	NEWS_NETWRITE(s, buf, blen);
+    }
+    status = response(NULL);
+    if (status == 240) {
+        /*
+	**  Successful post. - FM
+	*/
+        HTProgress(response_text);
+    } else {
+        /*
+	**  Shucks, something went wrong. - FM
+	*/
+        HTAlert(response_text);
+    }
+}
+
+/*	Read in an Article					read_article
+**	------------------
 **
 **	Note the termination condition of a single dot on a line by itself.
 **	RFC 977 specifies that the line "folding" of RFC850 is not used, so we
@@ -698,9 +856,18 @@ PRIVATE int read_article NOARGS
 	    FREE(organization);
 	}
 
-	if (newsgroups && !strncmp(NewsHREF, "news:", 5)) {
-	    /* make posting possible */
-	    StrAllocCopy(href,"newsreply:");
+	if (newsgroups && HTCanPost) {
+	    /*
+	    **  We have permission to POST to this host,
+	    **  so add a link for posting followups for
+	    **  this article. - FM
+	    */
+	    if (!strncasecomp(NewsHREF, "snews:", 6))
+	        StrAllocCopy(href,"snewsreply://");
+	    else
+	        StrAllocCopy(href,"newsreply://");
+	    StrAllocCat(href, NewsHost);
+	    StrAllocCat(href, "/");
 	    StrAllocCat(href, (followupto ? followupto : newsgroups));
 
 	    START(HTML_DT);
@@ -1223,7 +1390,7 @@ PRIVATE int read_group ARGS3(
 		sprintf(buffer, "HEAD %d%c%c", art+1, CR, LF);
 		status = response(buffer);
 	    }
-#else	/* NOT OVERLAP: */
+#else	/* Not OVERLAP: */
 	    sprintf(buffer, "HEAD %d%c%c", art, CR, LF);
 	    status = response(buffer);
 #endif	/* OVERLAP */
@@ -1394,11 +1561,22 @@ PRIVATE int read_group ARGS3(
     }
 
 add_post:
-    if (!strncmp(NewsHREF, "news:", 5)) {
+    if (HTCanPost) {
+	/*
+	**  We have permission to POST to this host,
+	**  so add a link for posting messages to
+	**  this newsgroup. - FM
+	*/
 	char *href = NULL;
+
 	START(HTML_HR);
 	PUTC('\n');
-	StrAllocCopy(href,"newspost:");
+	if (!strncasecomp(NewsHREF, "snews:", 6))
+	    StrAllocCopy(href,"snewspost://");
+	else
+	    StrAllocCopy(href,"newspost://");
+	StrAllocCat(href, NewsHost);
+	StrAllocCat(href, "/");
 	StrAllocCat(href,groupName);
 	start_anchor(href);
 	PUTS("Post to ");
@@ -1428,9 +1606,14 @@ PUBLIC int HTLoadNews ARGS4(
     int retries;			/* A count of how hard we have tried */ 
     BOOL group_wanted;		/* Flag: group was asked for, not article */
     BOOL list_wanted;		/* Flag: list was asked for, not article */
+    BOOL post_wanted;		/* Flag: new post to group was asked for */
+    BOOL reply_wanted;		/* Flag: followup post was asked for */
+    BOOL spost_wanted;		/* Flag: new SSL post to group was asked for */
+    BOOL sreply_wanted;		/* Flag: followup SSL post was asked for */
     int first, last;		/* First and last articles asked for */
     char *cp;
     char *ListArg = NULL;
+    char *postfile = NULL;
 
     diagnostic = (format_out == WWW_SOURCE ||	/* set global flag */
     		  format_out == HTAtom_for("www/download") ||
@@ -1461,8 +1644,71 @@ PUBLIC int HTLoadNews ARGS4(
 	**  	xxxxx			News group (no "@")
 	**  	group/n1-n2		Articles n1 to n2 in group
 	*/
-	group_wanted = (strchr(arg, '@') == NULL) && (strchr(arg, '*') == NULL);
-	list_wanted  = (strchr(arg, '@') == NULL) && (strchr(arg, '*') != NULL);
+	post_wanted = (strstr(arg, "newspost:") != NULL);
+	reply_wanted = ((!post_wanted) &&
+			strstr(arg, "newsreply:") != NULL);
+	spost_wanted = (!(post_wanted || reply_wanted) &&
+			strstr(arg, "snewspost:") != NULL);
+	sreply_wanted = (!(post_wanted || reply_wanted ||
+			   spost_wanted) &&
+			 strstr(arg, "newsreply:") != NULL);
+	group_wanted = (!(post_wanted || reply_wanted ||
+			  spost_wanted || sreply_wanted) &&
+			strchr(arg, '@') == NULL) && (strchr(arg, '*') == NULL);
+	list_wanted  = (!(post_wanted || reply_wanted) &&
+			strchr(arg, '@') == NULL) && (strchr(arg, '*') != NULL);
+
+	if (!strncasecomp(arg, "snewspost:", 10) ||
+	    !strncasecomp(arg, "snewsreply:", 11)) {
+	    HTAlert(
+	"This client does not contain support for posting to news with SSL.");
+	    return HT_NOT_LOADED;
+	}
+	if (post_wanted || reply_wanted || spost_wanted || sreply_wanted) {
+	    /*
+	    **  Make sure we have a non-zero path for the newsgroup(s). - FM
+	    */
+	    if ((p1 = strrchr(arg, '/')) != NULL) {
+	        p1++;
+	    } else if ((p1 = strrchr(arg, ':')) != NULL) {
+	        p1++;
+	    }
+	    if (!(p1 && *p1)) {
+	    	HTAlert("Invalid URL!");
+		return(HT_NO_DATA);
+	    }
+	    if (!(cp = HTParse(arg, "", PARSE_HOST)) || *cp == '\0') {
+		if (s >= 0 && NewsHost && strcasecomp(NewsHost, HTNewsHost)) {
+		    NEWS_NETCLOSE(s);
+		    s = -1;
+		}
+		StrAllocCopy(NewsHost, HTNewsHost);
+	    } else {
+		if (s >= 0 && NewsHost && strcasecomp(NewsHost, cp)) {
+		    NEWS_NETCLOSE(s);
+		    s = -1;
+		}
+		StrAllocCopy(NewsHost, cp);
+	    }
+	    FREE(cp);
+	    sprintf(command, "%s://%.245s/",
+	    		     (post_wanted ?
+			       "newspost" :
+			    (reply_wanted ?
+			       "newreply" :
+			    (spost_wanted ?
+			      "snewspost" : "snewsreply"))), NewsHost);
+	    StrAllocCopy(NewsHREF, command);
+
+	    /*
+	    **  If the SSL daemon is being used as a proxy,
+	    **  reset p1 to the start of the proxied URL
+	    **  rather than to the start of the newsgroup(s). - FM
+	    */
+	    if (spost_wanted && strncasecomp(arg, "snewspost:", 10))
+	        p1 = strstr(arg, "snewspost:");
+	    if (sreply_wanted && strncasecomp(arg, "snewsreply:", 11))
+	        p1 = strstr(arg, "snewsreply:");
 
 	/* p1 = HTParse(arg, "", PARSE_PATH | PARSE_PUNCTUATION); */
 	/*
@@ -1470,7 +1716,7 @@ PUBLIC int HTLoadNews ARGS4(
 	**  rules. For instance, if the article reference contains a '#',
 	**  the rest of it is lost -- JFG 10/7/92, from a bug report
 	*/
- 	if (!strncasecomp (arg, "nntp:", 5)) {
+ 	} else if (!strncasecomp (arg, "nntp:", 5)) {
 	    if (((*(arg + 5) == '\0') ||
 	         (!strcmp((arg + 5), "/") ||
 		  !strcmp((arg + 5), "//") ||
@@ -1556,9 +1802,12 @@ PUBLIC int HTLoadNews ARGS4(
 	/*
 	**  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
+	**  doing the conversion itself, and for handling posts
+	**  or followups.  - TZ & FM
 	*/
- 	if (!strncasecomp (p1, "snews:", 6)) {
+ 	if (!strncasecomp(p1, "snews:", 6) ||
+	    !strncasecomp(p1, "snewpost:", 10) ||
+	    !strncasecomp(p1, "snewsreply:", 11)) {
 	    if ((cp = HTParse(p1, "", PARSE_HOST)) != NULL && *cp != '\0')
 		sprintf(command, "snews://%.250s", cp);
 	    else
@@ -1572,19 +1821,36 @@ PUBLIC int HTLoadNews ARGS4(
 			(strlen(proxycmd) - 4), proxycmd);
 	    strcat(command, "/");
 	    StrAllocCopy(NewsHREF, command);
-	    if (!(cp = strrchr((p1 + 6), '/')) || *(cp + 1) == '\0') {
-	        p1 = "*";
-	        group_wanted = FALSE;
-	        list_wanted = TRUE;
+	    if (spost_wanted || sreply_wanted) {
+	        /*
+		**  Reset p1 so that it points to the newsgroup(s).
+		*/
+		if ((p1 = strrchr(arg, '/')) != NULL) {
+		    p1++;
+		} else {
+		    p1 = (strrchr(arg, ':') + 1);
+		}
 	    } else {
-	        p1 = (cp + 1);
+	        /*
+		**  Reset p1 so that it points to the newgroup
+		**  (or a wildcard), or the article.
+		*/
+		if (!(cp = strrchr((p1 + 6), '/')) || *(cp + 1) == '\0') {
+		    p1 = "*";
+		    group_wanted = FALSE;
+		    list_wanted = TRUE;
+		} else {
+		    p1 = (cp + 1);
+		}
 	    }
 	}
 
 	/*
-	**  Set up command for a listing or article request. - FM
+	**  Set up command for a post, listing, or article request. - FM
 	*/
-	if (list_wanted) {
+	if (post_wanted || reply_wanted || spost_wanted || sreply_wanted) {
+	    strcpy(command, "POST");
+	} else if (list_wanted) {
 	    strcpy(command, "LIST NEWSGROUPS");
 	} else if (group_wanted) {
 	    char * slash = strchr(p1, '/');
@@ -1642,9 +1908,11 @@ PUBLIC int HTLoadNews ARGS4(
     /*
     **  Make a hypertext object with an anchor list.
     */
-    node_anchor = anAnchor;
-    target = HTML_new(anAnchor, format_out, stream);
-    targetClass = *target->isa;	/* Copy routine entry points */
+    if (!(post_wanted || reply_wanted || spost_wanted || sreply_wanted)) {
+        node_anchor = anAnchor;
+	target = HTML_new(anAnchor, format_out, stream);
+	targetClass = *target->isa;	/* Copy routine entry points */
+    }
 
     /*
     **  Now, let's get a stream setup up from the NewsHost.
@@ -1671,10 +1939,21 @@ PUBLIC int HTLoadNews ARGS4(
 		    fprintf(stderr,
 		     "HTNews: Interrupted on connect; recovering cleanly.\n");
 		_HTProgress("Connection interrupted.");
-		(*targetClass._abort)(target, NULL);
+		if (!(post_wanted || reply_wanted ||
+		      spost_wanted || sreply_wanted))
+		    (*targetClass._abort)(target, NULL);
 		FREE(NewsHost);
 		FREE(NewsHREF);
 		FREE(ListArg);
+		if (postfile) {
+#ifdef VMS
+		    while (remove(postfile) == 0)
+			; /* loop through all versions */
+#else
+		    remove(postfile);
+#endif /* VMS */
+		    FREE(postfile);
+		}
                 return HT_NOT_LOADED;
             }
 	    if (status < 0) {
@@ -1690,6 +1969,15 @@ PUBLIC int HTLoadNews ARGS4(
 		FREE(NewsHost);
 		FREE(NewsHREF);
 		FREE(ListArg);
+		if (postfile) {
+#ifdef VMS
+		    while (remove(postfile) == 0)
+			; /* loop through all versions */
+#else
+		    remove(postfile);
+#endif /* VMS */
+		    FREE(postfile);
+		}
 		return HTLoadError(stream, 500, message);
 	    } else {
 		if (TRACE)
@@ -1709,10 +1997,21 @@ PUBLIC int HTLoadNews ARGS4(
 			s = -1;
 			if (status == HT_INTERRUPTED) {
 			    _HTProgress("Connection interrupted.");
-			    (*targetClass._abort)(target, NULL);
+			    if (!(post_wanted || reply_wanted ||
+				  spost_wanted || sreply_wanted))
+			        (*targetClass._abort)(target, NULL);
 			    FREE(NewsHost);
 			    FREE(NewsHREF);
 			    FREE(ListArg);
+			    if (postfile) {
+#ifdef VMS
+			        while (remove(postfile) == 0)
+				    ; /* loop through all versions */
+#else
+			        remove(postfile);
+#endif /* VMS */
+			        FREE(postfile);
+			    }
 			    return(HT_NOT_LOADED);
 			}
 			if (retries < 1)
@@ -1722,18 +2021,68 @@ PUBLIC int HTLoadNews ARGS4(
 		  		NewsHost, response_text);
 		        return HTLoadError(stream, 500, message);
 		}
+		if (status == 200) {
+		    HTCanPost = TRUE;
+		} else {
+		    HTCanPost = FALSE;
+		    if (post_wanted || reply_wanted ||
+		        spost_wanted || sreply_wanted) {
+			HTAlert("Cannot POST to this host.");
+			FREE(NewsHREF);
+			FREE(ListArg);
+			if (postfile) {
+#ifdef VMS
+			    while (remove(postfile) == 0)
+				; /* loop through all versions */
+#else
+			    remove(postfile);
+#endif /* VMS */
+			    FREE(postfile);
+			}
+			return(HT_NOT_LOADED);
+		    }
+		}
 	    }
 	} /* If needed opening */
 	
-        /*
-	**  Ensure reader mode, but don't bother checking the
-	**  status for anything but HT_INERRUPTED, because if
-	**  if the reader mode command is not needed, the server
-	**  probably return a 500, which is irrelevant at this
-	**  point. - FM
-	*/
-	{
+	if (post_wanted || reply_wanted ||
+	     spost_wanted || sreply_wanted) {
+	    if (!HTCanPost) {
+		HTAlert("Cannot POST to this host.");
+		FREE(NewsHREF);
+		FREE(ListArg);
+		if (postfile) {
+#ifdef VMS
+		    while (remove(postfile) == 0)
+			; /* loop through all versions */
+#else
+		    remove(postfile);
+#endif /* VMS */
+		    FREE(postfile);
+		}
+		return(HT_NOT_LOADED);
+	    }
+	    if (postfile == NULL) {
+	        extern char *LYNewsPost PARAMS((char *newsgroups,
+						BOOLEAN followup));
+		postfile = LYNewsPost(ListArg, (reply_wanted || sreply_wanted));
+	    }
+	    if (postfile == NULL) {
+		HTProgress("Cancelled!");
+		FREE(NewsHREF);
+		FREE(ListArg);
+		return(HT_NOT_LOADED);
+	    }
+        } else {
+	    /*
+	    **  Ensure reader mode, but don't bother checking the
+	    **  status for anything but HT_INERRUPTED, because if
+	    **  if the reader mode command is not needed, the server
+	    **  probably return a 500, which is irrelevant at this
+	    **  point. - FM
+	    */
 	    char buffer[20];
+
 	    sprintf(buffer, "mode reader%c%c", CR, LF);
 	    if ((status = response(buffer)) == HT_INTERRUPTED) {
 		_HTProgress("Connection interrupted.");
@@ -1753,7 +2102,8 @@ Send_NNTP_command:
 	        break;
 	    }
 	}
-	if ((status/100) != 2) {
+	if ((status/100) != 2 &&
+	    status != 340) {
 	    if (retries)
 	        HTAlert(response_text);
 	    else
@@ -1768,9 +2118,16 @@ Send_NNTP_command:
 	}
   
 	/*
-	**  Load a group, article, etc
+	**  Post or load a group, article, etc
 	*/
-	if (list_wanted) {
+	if (post_wanted || reply_wanted || spost_wanted || sreply_wanted) {
+	    if (status != 340) {
+		HTAlert("Cannot POST to this host.");
+	    } else {
+	        post_article(postfile);
+	    }
+	    status = HT_NOT_LOADED;
+	} else if (list_wanted) {
 	    _HTProgress("Reading list of available newsgroups.");
 	    status = read_list(ListArg);
 	} else if (group_wanted) {
@@ -1798,9 +2155,20 @@ Send_NNTP_command:
 	    _HTProgress("Connection interrupted.");
 	    status = HT_LOADED;
 	}
-	(*targetClass._free)(target);
+	if (!(post_wanted || reply_wanted ||
+	      spost_wanted || sreply_wanted))
+	    (*targetClass._free)(target);
 	FREE(NewsHREF);
 	FREE(ListArg);
+	if (postfile) {
+#ifdef VMS
+	    while (remove(postfile) == 0)
+		; /* loop through all versions */
+#else
+	    remove(postfile);
+#endif /* VMS */
+	    FREE(postfile);
+	}
 	return status;
     } /* Retry loop */
     
@@ -1809,9 +2177,20 @@ Send_NNTP_command:
 /*    NXRunAlertPanel(NULL, "Sorry, could not load `%s'.",
 	    NULL,NULL,NULL, arg);No -- message earlier wil have covered it */
 
-    (*targetClass._abort)(target, NULL);
+    if (!(post_wanted || reply_wanted ||
+	  spost_wanted || sreply_wanted))
+        (*targetClass._abort)(target, NULL);
     FREE(NewsHREF);
     FREE(ListArg);
+    if (postfile) {
+#ifdef VMS
+	while (remove(postfile) == 0)
+	    ; /* loop through all versions */
+#else
+	remove(postfile);
+#endif /* VMS */
+	FREE(postfile);
+    }
     return HT_NOT_LOADED;
 }
 
@@ -1820,10 +2199,22 @@ Send_NNTP_command:
 GLOBALDEF (HTProtocol,HTNews,_HTNEWS_C_1_INIT);
 #define _HTNEWS_C_2_INIT { "nntp", HTLoadNews, NULL }
 GLOBALDEF (HTProtocol,HTNNTP,_HTNEWS_C_2_INIT);
-#define _HTNEWS_C_3_INIT { "snews", HTLoadNews, NULL }
-GLOBALDEF (HTProtocol,HTSNews,_HTNEWS_C_1_INIT);
+#define _HTNEWS_C_3_INIT { "newspost", HTLoadNews, NULL }
+GLOBALDEF (HTProtocol,HTNewsPost,_HTNEWS_C_3_INIT);
+#define _HTNEWS_C_4_INIT { "newsreply", HTLoadNews, NULL }
+GLOBALDEF (HTProtocol,HTNewsReply,_HTNEWS_C_4_INIT);
+#define _HTNEWS_C_5_INIT { "snews", HTLoadNews, NULL }
+GLOBALDEF (HTProtocol,HTSNews,_HTNEWS_C_5_INIT);
+#define _HTNEWS_C_6_INIT { "snewspost", HTLoadNews, NULL }
+GLOBALDEF (HTProtocol,HTSNewsPost,_HTNEWS_C_6_INIT);
+#define _HTNEWS_C_7_INIT { "snewsreply", HTLoadNews, NULL }
+GLOBALDEF (HTProtocol,HTSNewsReply,_HTNEWS_C_7_INIT);
 #else
 GLOBALDEF PUBLIC HTProtocol HTNews = { "news", HTLoadNews, NULL };
 GLOBALDEF PUBLIC HTProtocol HTNNTP = { "nntp", HTLoadNews, NULL };
+GLOBALDEF PUBLIC HTProtocol HTNewsPost = { "newspost", HTLoadNews, NULL };
+GLOBALDEF PUBLIC HTProtocol HTNewsReply = { "newsreply", HTLoadNews, NULL };
 GLOBALDEF PUBLIC HTProtocol HTSNews = { "snews", HTLoadNews, NULL };
+GLOBALDEF PUBLIC HTProtocol HTSNewsPost = { "snewspost", HTLoadNews, NULL };
+GLOBALDEF PUBLIC HTProtocol HTSNewsReply = { "snewsreply", HTLoadNews, NULL };
 #endif /* GLOBALDEF_IS_MACRO */
diff --git a/WWW/Library/Implementation/HTNews.h b/WWW/Library/Implementation/HTNews.h
index 4bc998af..bffaeb1b 100644
--- a/WWW/Library/Implementation/HTNews.h
+++ b/WWW/Library/Implementation/HTNews.h
@@ -16,11 +16,19 @@
 #ifdef GLOBALREF_IS_MACRO
 extern GLOBALREF(HTProtocol, HTNews);
 extern GLOBALREF(HTProtocol, HTNNTP);
+extern GLOBALREF(HTProtocol, HTNewsPost);
+extern GLOBALREF(HTProtocol, HTNewsReply);
 extern GLOBALREF(HTProtocol, HTSNews);
+extern GLOBALREF(HTProtocol, HTSNewsPost);
+extern GLOBALREF(HTProtocol, HTSNewsReply);
 #else
 GLOBALREF HTProtocol HTNews;
 GLOBALREF HTProtocol HTNNTP;
+GLOBALREF HTProtocol HTNewsPost;
+GLOBALREF HTProtocol HTNewsReply;
 GLOBALREF HTProtocol HTSNews;
+GLOBALREF HTProtocol HTSNewsPost;
+GLOBALREF HTProtocol HTSNewsReply;
 #endif /* GLOBALREF_IS_MACRO */
 
 extern void HTSetNewsHost PARAMS((CONST char *value));
diff --git a/lynx.cfg b/lynx.cfg
index 2c82138c..90b4cff6 100644
--- a/lynx.cfg
+++ b/lynx.cfg
@@ -499,6 +499,29 @@ CHARACTER_SET:ISO Latin 1
 #NEWS_CHUNK_SIZE:30
 #NEWS_MAX_CHUNK:40
 
+# Set NEWS_POSTING to FALSE if you do not want to support posting to
+# news groups via Lynx.  If left TRUE, Lynx will use its news gateway to
+# post new messages or followups to news groups, using the URL schemes
+# described in the "Supported URL" section of the online 'h'elp.  The
+# posts will be attempted via the nntp server specified in the URL, or
+# if none was specified, via the NNTPSERVER configuration or environment
+# variable.  Links with these URLs for posting or sending followups are
+# created by the news gateway when reading group listings or articles
+# from nntp servers if the server indicates that it permits posting.
+# The compilation default set in userdefs.h can be changed here.  If
+# the default is TRUE, posting can still be disallowed via the
+# -restrictions command line switch.
+# 
+#NEWS_POSTING:TRUE
+
+# LYNX_SIG_FILE defines the name of a file containing a signature which
+# can be appended to news postings or followups.  The user will be prompted
+# whether to append it.  It is sought in the home directory.  If it is in
+# a subdirectory, begin it with a dot-slash (e.g., ./lynx/.lynxsig).  The
+# definition is set in userdefs.h and can be changed here.
+#
+#LYNX_SIG_FILE:.lynxsig
+
 # If USE_SELECT_POPUPS is set FALSE, Lynx will present a vertical list of
 # radio buttons for the OPTIONs in SELECT blocks which lack the MULTIPLE
 # attribute, instead of using a popup menu.  Note that if the MULTIPLE
@@ -526,37 +549,6 @@ CHARACTER_SET:ISO Latin 1
 
 # VMS:
 #=====
-# INEWS is the foreign command for the ANU-NEWS client (normally defined
-# as "NEWS" in userdefs.h) which serves as a transparent vector for posting
-# to newsgroups from Lynx via the ANU-NEWS client's server.  The account
-# running Lynx must have access to the ANU-NEWS client, which in turn must
-# have posting privileges (the news server could also be ANU-NEWS, or any
-# other server to which the ANU-NEWS client has access).  You can disable
-# news posting by setting INEWS to "none", or via -restrictions switches.
-# The default is defined in userdefs.h and can be overridden here.
-# The ANU-NEWS software for VMS is available from ftp.cc.ukans.edu.  Note
-# that posting is supported only for news: (not nntp: or snews:) URLs, and
-# only via the default nntp server defined with the NNTPSERVER configuration
-# (see above) or environment variable.
-#
-#INEWS:NEWS
-
-# Unix:
-#======
-# Set INEWS to the full path and name of your program for posting to
-# newsgroups.  A "mini" inews is included in the utils subdirectory of
-# the Lynx distribution.  You can disable news posting by setting INEWS
-# to "none", or via -restrictions switches.  The default is defined in
-# userdefs.h and can be overridden here.  Note that some news software,
-# such as INN's inews, requires an -h switch added to the path.  Also
-# note that posting is supported only for news: (not nntp: or snews:)
-# URLs, and only via the default nntp server defined with the NNTPSERVER
-# configuration (see above) or environment variable.
-#
-#INEWS:inews
-
-# VMS:
-#=====
 # The mail command is defined in userdefs.h.  It will be spawned as a
 # subprocess of lynx and used to send replies and error messages.
 # It can be re-defined here.  Your mailer must be able to accept a
@@ -712,7 +704,11 @@ CHARACTER_SET:ISO Latin 1
 #ftp_proxy:http://some.server.dom:port/
 #gopher_proxy:http://some.server.dom:port/
 #news_proxy:http://some.server.dom:port/
+#newspost_proxy:http://some.server.dom:port/
+#newsreply_proxy:http://some.server.dom:port/
 #snews_proxy:http://some.server.dom:port/
+#snewspost_proxy:http://some.server.dom:port/
+#snewsreply_proxy:http://some.server.dom:port/
 #nntp_proxy:http://some.server.dom:port/
 #wais_proxy:http://some.server.dom:port/
 #finger_proxy:http://some.server.dom:port/
diff --git a/lynx_help/Lynx_users_guide.html b/lynx_help/Lynx_users_guide.html
index 74122162..0c9dd4b6 100644
--- a/lynx_help/Lynx_users_guide.html
+++ b/lynx_help/Lynx_users_guide.html
@@ -746,7 +746,8 @@ press '<em>n</em>' the message will be deleted. [<A HREF="#TOC">ToC</A>]
 While reading <a
 href="http://www.w3.org/hypertext/DataSources/News/Groups/Overview.html"
 >news</a> articles with Lynx you should see a link that says
-<em>Reply to: user@host</em> and a link that says
+<em>Reply to: user@host</em> and, if the nntp server from which you
+received the article supports posting from your site, a link that says
 <em>Followup to: newsgroup(s)</em>
     
 <dl>
@@ -760,10 +761,15 @@ href="http://www.w3.org/hypertext/DataSources/News/Groups/Overview.html"
     <dt>Followup to newsgroup(s)
         <dd>Selecting this link will allow you to post back to the
             newsgroup that you are currently reading and any newsgroups
-            that the message may be cross-posted to.  You will be given
+            to which the message was cross-posted.  You will be given
             the option of including the original message in your reply.
-            Once you have typed in your message the <em>inews</em> program
-            will be called to post your message to your news host. 
+            Once you have typed in your message, you will be asked for
+	    confirmation of whether to proceed with the posting, and
+	    whether to append your signature file if one was defined in
+	    lynx.cfg and is accessible.  See <a
+	    href="lynx_url_support.html">Supported URLs</a> for more
+	    information about the URL schemes for posting or sending
+	    followups (replies) to nntp servers with Lynx.
             [<A HREF="#TOC">ToC</A>]
 </dl>
 
diff --git a/lynx_help/lynx_url_support.html b/lynx_help/lynx_url_support.html
index 61800f4f..c90550f4 100644
--- a/lynx_help/lynx_url_support.html
+++ b/lynx_help/lynx_url_support.html
@@ -14,6 +14,7 @@
 <a href="#ftp">ftp</a> <em>|</em>
 <a href="#wais">wais</a> <em>|</em>
 <a href="#news">news, nntp, snews</a> <em>|</em>
+<a href="#newspost">newspost, newsreply, snewspost, snewsreply</a> <em>|</em>
 <a href="#mailto">mailto</a> <em>|</em>
 <a href="#finger">finger</a> <em>|</em>
 <a href="#cso">cso</a> <em>|</em>
@@ -296,10 +297,10 @@ hierarchies or sub-hierarchies, e.g.:<BR>
 (snews same as nntp, but the default port is <em>:563</em>)<BR>
 This is not in RFC1738 and may not be supported by all other clients.
 
-<p>For news URLs, Lynx allows you both to <em>reply</em> to the author
-of a message via email, and, if news posting has been enabled, to send
-a <em>followup</em> message to the newsgroup.  Only email replies to the
-author are permitted via nntp URLs.
+<p>Lynx allows you both to <em>reply</em> to the author of a news message
+via email, and, if news posting has been enabled, to send a <em>followup</em>
+message to the newsgroup (see <a href="#newspost">newspost, newsreply,
+snewspost, snewsreply</a>).
 
 <p>Lynx converts any strings in news messages which appear to be a URL
 with a supported scheme into a link for accessing that URL.
@@ -317,6 +318,48 @@ are specific to each nntp server, unlike the unique identifiers for
 news messages.
 <HR WIDTH="100%">
 
+<H2><a name="newspost"
+>The <em>newspost</em>, <em>newsreply</em>, <em>snewspost</em>, and
+<em>snewsreply</em> URLs:</a></H2>
+
+When Lynx receives group listings or articles via <em>news</em>,
+<em>nntp</em> or <em>snews</em> URLs, it also checks whether the
+nntp server supports posting from the Lynx user's site, and if so,
+includes links for posting new messages to that server, or for posting
+followups (replies) to previously posted messages.  RFC1738, and IETF
+URL drafts through this release of Lynx, do not include any schemes
+for posting to news groups.  Lynx has long supported newspost and
+newreply URL schemes for posting new messages or sending followups,
+respectively, to standard nntp servers, with default port <em>:119</em>.
+Lynx now also supports homologous snewspost and snewsreply URLs for use
+with SSL capable nntp servers, but the latter requires patches for built
+in SSL support, or use of a daemon which handles the secure communications
+on behalf of Lynx. 
+
+<p>The formats are:<BR>
+<tab indent="12"><em>newspost://host:port/newsgroup(s)</em>&nbsp;&nbsp;<tab
+id="ngp">(post a new message)<BR>
+<tab indent="12"><em>newsreply://host:port/newsgroup(s)</em> <tab
+to="ngp">(post a followup message)<BR>
+(snewspost and snewsreply have the same formats, but the default port is
+<em>:563</em>)
+
+<p>If the host field is omitted, it defaults to that pointed to by the
+NNTPSERVER configuration or environmental variable.  Inclusion of at
+least one newsgroup in the URL is required, and additional groups can
+be specified as a comma-separated list.  Wildcarding of newgroup names
+is not supported for these URLs.  For newsreply and snewsreply URLs, the
+user is offered the option to include the currently displayed document,
+which presumeably is a news article with a <em>followup</em> link that
+was activated, and if confirmed, each line of that document is prefixed
+with a right-angle-bracket.  These URLs can be used as command line
+startfiles (in which case, Lynx will exit after posting the message,
+and the newreply or snewsreply URLs degrade to newspost or snewpost
+URLs, respectively).  They also can be used as HREF attribute values
+in any HTML document homologously to <a href="#mailto">mailto</a> URLs,
+with the qualification that they presently are supported only by Lynx. 
+<HR WIDTH="100%">
+
 <H2><a name="mailto">The <em>mailto</em> URL:</a></H2>
 
 The mailto URL is used to provide links that when activated can be
diff --git a/samples/lynx.cfg b/samples/lynx.cfg
index 2c82138c..90b4cff6 100644
--- a/samples/lynx.cfg
+++ b/samples/lynx.cfg
@@ -499,6 +499,29 @@ CHARACTER_SET:ISO Latin 1
 #NEWS_CHUNK_SIZE:30
 #NEWS_MAX_CHUNK:40
 
+# Set NEWS_POSTING to FALSE if you do not want to support posting to
+# news groups via Lynx.  If left TRUE, Lynx will use its news gateway to
+# post new messages or followups to news groups, using the URL schemes
+# described in the "Supported URL" section of the online 'h'elp.  The
+# posts will be attempted via the nntp server specified in the URL, or
+# if none was specified, via the NNTPSERVER configuration or environment
+# variable.  Links with these URLs for posting or sending followups are
+# created by the news gateway when reading group listings or articles
+# from nntp servers if the server indicates that it permits posting.
+# The compilation default set in userdefs.h can be changed here.  If
+# the default is TRUE, posting can still be disallowed via the
+# -restrictions command line switch.
+# 
+#NEWS_POSTING:TRUE
+
+# LYNX_SIG_FILE defines the name of a file containing a signature which
+# can be appended to news postings or followups.  The user will be prompted
+# whether to append it.  It is sought in the home directory.  If it is in
+# a subdirectory, begin it with a dot-slash (e.g., ./lynx/.lynxsig).  The
+# definition is set in userdefs.h and can be changed here.
+#
+#LYNX_SIG_FILE:.lynxsig
+
 # If USE_SELECT_POPUPS is set FALSE, Lynx will present a vertical list of
 # radio buttons for the OPTIONs in SELECT blocks which lack the MULTIPLE
 # attribute, instead of using a popup menu.  Note that if the MULTIPLE
@@ -526,37 +549,6 @@ CHARACTER_SET:ISO Latin 1
 
 # VMS:
 #=====
-# INEWS is the foreign command for the ANU-NEWS client (normally defined
-# as "NEWS" in userdefs.h) which serves as a transparent vector for posting
-# to newsgroups from Lynx via the ANU-NEWS client's server.  The account
-# running Lynx must have access to the ANU-NEWS client, which in turn must
-# have posting privileges (the news server could also be ANU-NEWS, or any
-# other server to which the ANU-NEWS client has access).  You can disable
-# news posting by setting INEWS to "none", or via -restrictions switches.
-# The default is defined in userdefs.h and can be overridden here.
-# The ANU-NEWS software for VMS is available from ftp.cc.ukans.edu.  Note
-# that posting is supported only for news: (not nntp: or snews:) URLs, and
-# only via the default nntp server defined with the NNTPSERVER configuration
-# (see above) or environment variable.
-#
-#INEWS:NEWS
-
-# Unix:
-#======
-# Set INEWS to the full path and name of your program for posting to
-# newsgroups.  A "mini" inews is included in the utils subdirectory of
-# the Lynx distribution.  You can disable news posting by setting INEWS
-# to "none", or via -restrictions switches.  The default is defined in
-# userdefs.h and can be overridden here.  Note that some news software,
-# such as INN's inews, requires an -h switch added to the path.  Also
-# note that posting is supported only for news: (not nntp: or snews:)
-# URLs, and only via the default nntp server defined with the NNTPSERVER
-# configuration (see above) or environment variable.
-#
-#INEWS:inews
-
-# VMS:
-#=====
 # The mail command is defined in userdefs.h.  It will be spawned as a
 # subprocess of lynx and used to send replies and error messages.
 # It can be re-defined here.  Your mailer must be able to accept a
@@ -712,7 +704,11 @@ CHARACTER_SET:ISO Latin 1
 #ftp_proxy:http://some.server.dom:port/
 #gopher_proxy:http://some.server.dom:port/
 #news_proxy:http://some.server.dom:port/
+#newspost_proxy:http://some.server.dom:port/
+#newsreply_proxy:http://some.server.dom:port/
 #snews_proxy:http://some.server.dom:port/
+#snewspost_proxy:http://some.server.dom:port/
+#snewsreply_proxy:http://some.server.dom:port/
 #nntp_proxy:http://some.server.dom:port/
 #wais_proxy:http://some.server.dom:port/
 #finger_proxy:http://some.server.dom:port/
diff --git a/src/GridText.c b/src/GridText.c
index da643f91..28f23420 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -2032,8 +2032,13 @@ PUBLIC HTChildAnchor * HText_childNumber ARGS1(
 	int,		number)
 {
     TextAnchor * a;
+
+    if (!HTMainText)
+        return (HTChildAnchor *)0;	/* Fail */
+
     for (a = HTMainText->first_anchor; a; a = a->next) {
-        if (a->number == number) return(a->anchor);
+        if (a->number == number)
+	    return(a->anchor);
     }
     return (HTChildAnchor *)0;	/* Fail */
 }
@@ -2049,6 +2054,9 @@ PUBLIC int HTGetLinkInfo ARGS3(
     TextAnchor * a;
     HTAnchor *link_dest;
 
+    if (!HTMainText)
+        return(NO);
+
     for (a = HTMainText->first_anchor; a; a = a->next) {
         if (a->number == number) {
 	    *hightext= a->hightext;
@@ -2079,7 +2087,7 @@ PUBLIC int HTGetLinkInfo ARGS3(
  */
 PUBLIC int HText_getNumOfLines NOARGS
 {
-     return(HTMainText->Lines);
+     return(HTMainText ? HTMainText->Lines : 0);
 }
 
 /*
@@ -2088,7 +2096,8 @@ PUBLIC int HText_getNumOfLines NOARGS
  */
 PUBLIC char * HText_getTitle NOARGS
 {
-   return((char *) HTAnchor_title(HTMainText->node_anchor));
+   return(HTMainText ?
+   	  (char *) HTAnchor_title(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2098,7 +2107,8 @@ PUBLIC char * HText_getTitle NOARGS
  */
 PUBLIC char * HText_getSugFname NOARGS
 {
-   return((char *) HTAnchor_SugFname(HTMainText->node_anchor));
+   return(HTMainText ?
+   	  (char *) HTAnchor_SugFname(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2107,7 +2117,8 @@ PUBLIC char * HText_getSugFname NOARGS
  */
 PUBLIC char * HText_getLastModified NOARGS
 {
-   return((char *) HTAnchor_last_modified(HTMainText->node_anchor));
+   return(HTMainText ?
+   	  (char *) HTAnchor_last_modified(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2116,7 +2127,8 @@ PUBLIC char * HText_getLastModified NOARGS
  */
 PUBLIC char * HText_getDate NOARGS
 {
-   return((char *) HTAnchor_date(HTMainText->node_anchor));
+   return(HTMainText ?
+   	  (char *) HTAnchor_date(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2125,7 +2137,8 @@ PUBLIC char * HText_getDate NOARGS
  */
 PUBLIC char * HText_getServer NOARGS
 {
-   return((char *) HTAnchor_server(HTMainText->node_anchor));
+   return(HTMainText ?
+   	  (char *)HTAnchor_server(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2773,11 +2786,15 @@ PUBLIC void print_wwwfile_to_fd ARGS2(
 	int,		is_reply)
 {
       register int i;
-      HTLine * line = HTMainText->last_line->next;
+      HTLine * line;
 #ifdef VMS
       extern BOOLEAN HadVMSInterrupt;
 #endif /* VMS */
 
+      if (!HTMainText)
+          return;
+
+      line = HTMainText->last_line->next;
       for (;; line = line->next) {
 
 	  if (is_reply)
@@ -2828,11 +2845,15 @@ PUBLIC void print_crawl_to_fd ARGS3(
 	char *,		thetitle)
 {
     register int i;
-    HTLine * line = HTMainText->last_line->next;
+    HTLine * line;
 #ifdef VMS
     extern BOOLEAN HadVMSInterrupt;
 #endif /* VMS */
 
+    if (!HTMainText)
+        return;
+
+    line = HTMainText->last_line->next;
     fprintf(fp,"THE_URL:%s\n",thelink);
     if (thetitle != NULL)fprintf(fp,"THE_TITLE:%s\n",thetitle);;
       
@@ -2866,11 +2887,18 @@ PUBLIC void www_user_search ARGS2(
 	int,		start_line,
 	char *,		target)
 {
-    register HTLine * line = HTMainText->last_line->next;
+    register HTLine * line;
     register int count;
     extern BOOLEAN case_sensitive;
 
-    /* advance to the start line */
+    if (!HTMainText) {
+        return;
+    }
+
+    /*
+     *  Advance to the start line.
+     */
+    line = HTMainText->last_line->next;
     for (count = 1; count <= start_line; line = line->next, count++) {
         if (line == HTMainText->last_line) {
 	    line = HTMainText->last_line->next; /* set to first line */
@@ -2916,8 +2944,6 @@ PUBLIC void www_user_search ARGS2(
 		count++;
 	    }
     }
-
-
 }
 
 PUBLIC void user_message ARGS2(
@@ -2952,7 +2978,8 @@ PUBLIC void user_message ARGS2(
  */
 PUBLIC char * HText_getOwner NOARGS
 {
-    return((char *)HTAnchor_owner(HTMainText->node_anchor));
+    return(HTMainText ?
+    	   (char *)HTAnchor_owner(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2975,7 +3002,8 @@ PUBLIC void HText_setMainTextOwner ARGS1(
  */
 PUBLIC char * HText_getRevTitle NOARGS
 {
-    return((char *)HTAnchor_RevTitle(HTMainText->node_anchor));
+    return(HTMainText ?
+    	   (char *)HTAnchor_RevTitle(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2984,7 +3012,8 @@ PUBLIC char * HText_getRevTitle NOARGS
  */
 PUBLIC char * HText_getContentBase NOARGS
 {
-    return((char *)HTAnchor_content_base(HTMainText->node_anchor));
+    return(HTMainText ?
+    	   (char *)HTAnchor_content_base(HTMainText->node_anchor) : NULL);
 }
 
 /*
@@ -2993,15 +3022,20 @@ PUBLIC char * HText_getContentBase NOARGS
  */
 PUBLIC char * HText_getContentLocation NOARGS
 {
-    return((char *)HTAnchor_content_location(HTMainText->node_anchor));
+    return(HTMainText ?
+	   (char *)HTAnchor_content_location(HTMainText->node_anchor) : NULL);
 }
 
 PUBLIC void HTuncache_current_document NOARGS
 {
-    /* should remove current document from memory */
-    HTList_removeObject(loaded_texts, HTMainText);
-    HText_free(HTMainText);
-    HTMainText = NULL;
+    /*
+     *  Should remove current document from memory.
+     */
+    if (HTMainText) {
+        HTList_removeObject(loaded_texts, HTMainText);
+	HText_free(HTMainText);
+	HTMainText = NULL;
+    }
 }
 
 PUBLIC int HTisDocumentSource NOARGS
@@ -3955,7 +3989,7 @@ PUBLIC void HText_SubmitForm ARGS4(
 	char *,		link_name,
 	char *,		link_value)
 {
-    TextAnchor *anchor_ptr = HTMainText->first_anchor;
+    TextAnchor *anchor_ptr;
     int form_number = submit_item->number;
     FormInfo *form_ptr;
     int len, i;
@@ -3969,6 +4003,9 @@ PUBLIC void HText_SubmitForm ARGS4(
     char *Boundary = NULL;
     char *MultipartContentType = NULL;
 
+    if (!HTMainText)
+        return;
+
     if (submit_item->submit_action) {
         /*
 	 *  If we're mailing, make sure it's a mailto ACTION. - FM
@@ -4020,6 +4057,7 @@ PUBLIC void HText_SubmitForm ARGS4(
     /*
      *  Go through list of anchors and get size first.
      */
+    anchor_ptr = HTMainText->first_anchor;
     while (anchor_ptr) {
         if (anchor_ptr->link_type == INPUT_ANCHOR) {
    	    if (anchor_ptr->input_field->number == form_number) {
@@ -4674,13 +4712,16 @@ PUBLIC void HText_SubmitForm ARGS4(
 
 PUBLIC void HText_DisableCurrentForm NOARGS
 {
-    TextAnchor * anchor_ptr = HTMainText->first_anchor;
+    TextAnchor * anchor_ptr;
 
     HTFormDisabled = TRUE;
+    if (!HTMainText)
+        return;
 
     /*
      *  Go through list of anchors and set the disabled flag.
      */
+    anchor_ptr = HTMainText->first_anchor;
     while (anchor_ptr) {
         if (anchor_ptr->link_type == INPUT_ANCHOR &&
             anchor_ptr->input_field->number == HTFormNumber) {
@@ -4701,13 +4742,16 @@ PUBLIC void HText_DisableCurrentForm NOARGS
 PUBLIC void HText_ResetForm ARGS1(
 	FormInfo *,	form)
 {
-    TextAnchor * anchor_ptr = HTMainText->first_anchor;
+    TextAnchor * anchor_ptr;
 
     _statusline(RESETTING_FORM);
+    if (!HTMainText)
+        return;
 
     /*
      *  Go through list of anchors and reset values.
      */
+    anchor_ptr = HTMainText->first_anchor;
     while (anchor_ptr) {
         if (anchor_ptr->link_type == INPUT_ANCHOR) {
             if (anchor_ptr->input_field->number == form->number) {
@@ -4749,9 +4793,12 @@ PUBLIC void HText_ResetForm ARGS1(
 PUBLIC void HText_activateRadioButton ARGS1(
 	FormInfo *,	form)
 {
-    TextAnchor * anchor_ptr = HTMainText->first_anchor;
+    TextAnchor * anchor_ptr;
     int form_number = form->number;
 
+    if (!HTMainText)
+        return;
+    anchor_ptr = HTMainText->first_anchor;
     while (anchor_ptr) {
         if (anchor_ptr->link_type == INPUT_ANCHOR &&
                 anchor_ptr->input_field->type == F_RADIO_TYPE) {
diff --git a/src/HTAlert.c b/src/HTAlert.c
index 46243c37..2d40ea51 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -311,7 +311,7 @@ PUBLIC BOOL HTConfirmCookie ARGS6(
     }
     sprintf(message, ADVANCED_COOKIE_CONFIRMATION,
     	    server, namelen, name, valuelen, value);
-    _user_message(message, "");
+    _statusline(message);
     while (1) {
 	ch = LYgetch();
 #ifdef VMS
diff --git a/src/LYCharSets.c b/src/LYCharSets.c
index 7c239128..7e3b57ae 100644
--- a/src/LYCharSets.c
+++ b/src/LYCharSets.c
@@ -1098,7 +1098,7 @@ PRIVATE char * KOI8_R[] = {
 	"-",	/* dash the width of ensp - endash */
         "\002",	/* ensp NEVER CHANGE THIS - ensp */
         "e",	/* small eth, Icelandic eth */
-	"\263",	/* small e, dieresis or umlaut mark - euml */
+	"\243",	/* small e, dieresis or umlaut mark - euml */
 	" 1/2",	/* fraction 1/2 (&#189;) - frac12 */
 	" 1/4",	/* fraction 1/4 (&#188;) - frac14 */
 	" 3/4",	/* fraction 3/4 (&#190;) - frac34 */
diff --git a/src/LYCookie.c b/src/LYCookie.c
index 957314bf..88a4e6fc 100644
--- a/src/LYCookie.c
+++ b/src/LYCookie.c
@@ -81,6 +81,7 @@ struct _cookie {
     int pathlen;   /* Length of the path */
     int flags;     /* Various flags */
     time_t expires;   /* The time when this cookie expires */
+    BOOL quoted;   /* Was a value quoted in the Set-Cookie header? */
 };
 typedef struct _cookie cookie;
 
@@ -97,11 +98,16 @@ PRIVATE void MemAllocCopy ARGS3(
 	CONST char *,	start,
 	CONST char *,	end)
 {
-    char *temp = (char *)calloc(1, ((end - start) + 1));
+    char *temp;
+    
+    if (!(start && end) || (end <= start)) {
+        HTSACopy(dest, "");
+	return;
+    }
 
+    temp = (char *)calloc(1, ((end - start) + 1));
     if (temp == NULL)
         outofmem(__FILE__, "MemAllocCopy");
-
     LYstrncpy(temp, (char *)start, (end - start));
     HTSACopy(dest, temp);
     FREE(temp);
@@ -218,8 +224,13 @@ PRIVATE void store_cookie ARGS3(
      *  Section 4.3.2, condition 1: The value for the Path attribute is
      *  not a prefix of the request-URI.
      */
-    if (strncmp(co->path, path, co->pathlen) != 0)
+    if (strncmp(co->path, path, co->pathlen) != 0) {
+	if (TRACE)
+	    fprintf(stderr,
+	    "store_cookie: Rejecting because '%s' is not a prefix of '%s'.\n",
+		    co->path, path);
         return;
+    }
     /*
      *  The next 4 conditions do NOT apply if the domain is still 
      *  the default of request-host.
@@ -228,26 +239,46 @@ PRIVATE void store_cookie ARGS3(
         /*
 	 *  The hostname does not contain a dot.
 	 */
-	if (strchr(hostname, '.') == NULL)
+	if (strchr(hostname, '.') == NULL) {
+	    if (TRACE)
+		fprintf(stderr,
+			"store_cookie: Rejecting because '%s' has no dot.\n",
+			hostname);
 	    return;
+	}
 
 	/*
 	 *  Section 4.3.2, condition 2: The value for the Domain attribute
 	 *  contains no embedded dots or does not start with a dot. 
 	 *  (A dot is embedded if it's neither the first nor last character.) 
 	 */
-	if (co->domain[0] != '.' || co->domain[1] == '\0')
+	if (co->domain[0] != '.' || co->domain[1] == '\0') {
+	    if (TRACE)
+		fprintf(stderr,
+			"store_cookie: Rejecting domain '%s'.\n",
+			co->domain);
 	    return;
+	}
 	ptr = strchr((co->domain + 1), '.');
-	if (ptr == NULL || ptr[1] == '\0')
+	if (ptr == NULL || ptr[1] == '\0') {
+	    if (TRACE)
+		fprintf(stderr,
+			"store_cookie: Rejecting domain '%s'.\n",
+			co->domain);
 	    return;
+	}
       
         /*
 	 *  Section 4.3.2, condition 3: The value for the request-host does
 	 *  not domain-match the Domain attribute.
 	 */
-	if (!host_matches(hostname, co->domain))
+	if (!host_matches(hostname, co->domain)) {
+	    if (TRACE)
+		fprintf(stderr,
+			"store_cookie: Rejecting domain '%s' for host '%s'.\n",
+			co->domain, hostname);
 	    return;
+	}
 
         /*
 	 *  Section 4.3.2, condition 4: The request-host is a FQDN (not IP
@@ -255,8 +286,13 @@ PRIVATE void store_cookie ARGS3(
 	 *  attribute, and H is a string that contains one or more dots.
 	 */
 	ptr = ((hostname + strlen(hostname)) - strlen(co->domain));
-	if (strchr(hostname, '.') < ptr)
+	if (strchr(hostname, '.') < ptr) {
+	    if (TRACE)
+		fprintf(stderr,
+			"store_cookie: Rejecting domain '%s' for host '%s'.\n",
+			co->domain, hostname);
 	    return;
+	}
     }
 
     /*
@@ -388,6 +424,7 @@ PRIVATE char * scan_cookie_sublist ARGS6(
     HTList *hl = sublist, *next = NULL;
     cookie *co;
     time_t now = time(NULL);
+    BOOL Quoted = FALSE;
 
     while (hl) {
 	co = (cookie *)hl->object;
@@ -460,7 +497,15 @@ PRIVATE char * scan_cookie_sublist ARGS6(
 	     */
 	    StrAllocCat(header, co->name);
 	    StrAllocCat(header, "=");
+	    if (co->quoted && strchr(co->value, ' ')) {
+	    	StrAllocCat(header, "\"");
+		Quoted = TRUE;
+	    }
 	    StrAllocCat(header, co->value);
+	    if (Quoted) {
+	    	StrAllocCat(header, "\"");
+		Quoted = FALSE;
+	    }
 	    /*
 	     *  For Version 1 (or greater) cookies, add
 	     *  attributes for the cookie. - FM
@@ -471,14 +516,30 @@ PRIVATE char * scan_cookie_sublist ARGS6(
 		     *  Append the path attribute. - FM
 		     */
 		    StrAllocCat(header, "; $Path=");
+		    if (co->quoted && strchr(co->path, ' ')) {
+		        StrAllocCat(header, "\"");
+			Quoted = TRUE;
+		    }
 		    StrAllocCat(header, co->path);
+		    if (Quoted) {
+		        StrAllocCat(header, "\"");
+			Quoted = FALSE;
+		    }
 		}
 		if (co->domain) {
 		    /*
 		     *  Append the domain attribute. - FM
 		     */
 		    StrAllocCat(header, "; $Domain=");
+		    if (co->quoted && strchr(co->domain, ' ')) {
+		        StrAllocCat(header, "\"");
+			Quoted = TRUE;
+		    }
 		    StrAllocCat(header, co->domain);
+		    if (Quoted) {
+		        StrAllocCat(header, "\"");
+			Quoted = FALSE;
+		    }
 		}
 	    }
 	}
@@ -497,6 +558,7 @@ PUBLIC void LYSetCookie ARGS2(
     cookie *cur_cookie = NULL;
     int port = 80;
     int length = 0;
+    BOOL Quoted = FALSE;
 
     /*
      *  Get the hostname, port and path of the address, and report
@@ -552,6 +614,7 @@ PUBLIC void LYSetCookie ARGS2(
 	       *p != '=' && *p != ';' && *p != ',')
 	    p++;
 	attr_end = p;
+	SKIP_SPACES;
       
 	if (*p == '=') {
 	    /*
@@ -595,28 +658,40 @@ PUBLIC void LYSetCookie ARGS2(
 		value_end = p;
 		if (*p == '"')
 		    p++;
+		Quoted = TRUE;
 	    } else {
 		/*
 		 *   Otherwise, it's an unquoted string.
 		 */
-		SKIP_SPACES;
 		value_start = p;
-		while (*p != '\0' && !isspace((unsigned char)*p) && *p != ';')
+		while (*p != '\0' && *p != ';' && *p != ',')
 		    p++;
 		value_end = p;
+		/*
+		 *  Trim trailing spaces.
+		 */
+		if ((value_end > value_start) &&
+		    isspace((unsigned char)*(value_end - 1))) {
+		    value_end--;
+		    while ((value_end > (value_start + 1)) &&
+		    	   isspace((unsigned char)*value_end) &&
+			   isspace((unsigned char)*(value_end - 1))) {
+		        value_end--;
+		    }
+		}
 	    }
 	}
 
 	/*
 	 *  Check for a separator character, and skip it.
 	 */
-	if (*p == ';')
+	if (*p == ';' || *p == ',')
 	    p++;
 
 	/*
 	 *  Now, we can handle this attribute/value pair.
 	 */
-	if (attr_end != attr_start) {
+	if (attr_end > attr_start) {
 	    int len = (attr_end - attr_start);
 	    BOOLEAN known_attr = NO;
 	    char *value = NULL;
@@ -719,6 +794,8 @@ PUBLIC void LYSetCookie ARGS2(
 		cur_cookie->port = port;
 		MemAllocCopy(&(cur_cookie->name), attr_start, attr_end);
 		MemAllocCopy(&(cur_cookie->value), value_start, value_end);
+		cur_cookie->quoted = Quoted;
+		Quoted = FALSE;
 	    }
 	    FREE(value);
 	}
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index fa6b0c3e..45212601 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -166,6 +166,8 @@ Try_Redirected_URL:
 			  url_type == MAILTO_URL_TYPE ||
 			  url_type == NEWSPOST_URL_TYPE ||
 			  url_type == NEWSREPLY_URL_TYPE ||
+			  url_type == SNEWSPOST_URL_TYPE ||
+			  url_type == SNEWSREPLY_URL_TYPE ||
 			  (!LYUserSpecifiedURL &&
 			   (url_type == LYNXEXEC_URL_TYPE ||
 			    url_type == LYNXPROG_URL_TYPE ||
@@ -205,26 +207,18 @@ Try_Redirected_URL:
 		} else if (url_type == LYNXPRINT_URL_TYPE) {
 		    return(printfile(doc));
 
-		} else if (url_type == NEWSPOST_URL_TYPE) {
+		} else if (url_type == NEWSPOST_URL_TYPE ||
+			   url_type == NEWSREPLY_URL_TYPE ||
+			   url_type == SNEWSPOST_URL_TYPE ||
+			   url_type == SNEWSREPLY_URL_TYPE) {
 
 		    if (no_newspost) {
 			_statusline(NEWSPOSTING_DISABLED);
 			sleep(MessageSecs);
 			return(NULLFILE);
 		    } else {
-		        BOOLEAN followup = FALSE;
-		        return(LYNewsPost(doc, followup));
-		    }
-
-		} else if (url_type == NEWSREPLY_URL_TYPE) {
-
-		    if (no_newspost) {
-			_statusline(NEWSPOSTING_DISABLED);
-			sleep(MessageSecs);
+		        HTLoadAbsolute(&WWWDoc);
 			return(NULLFILE);
-		    } else {
-		        BOOLEAN followup = TRUE;
-		        return(LYNewsPost(doc, followup));
 		    }
 
 		} else if (url_type == LYNXDOWNLOAD_URL_TYPE) {
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index 005dda32..afd6f53a 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -36,7 +36,11 @@ extern char *ftp_proxy_putenv_cmd;
 extern char *gopher_proxy_putenv_cmd;
 extern char *cso_proxy_putenv_cmd;
 extern char *news_proxy_putenv_cmd;
+extern char *newspost_proxy_putenv_cmd;
+extern char *newsreply_proxy_putenv_cmd;
 extern char *snews_proxy_putenv_cmd;
+extern char *snewspost_proxy_putenv_cmd;
+extern char *snewsreply_proxy_putenv_cmd;
 extern char *nntp_proxy_putenv_cmd;
 extern char *wais_proxy_putenv_cmd;
 extern char *finger_proxy_putenv_cmd;
@@ -115,8 +119,9 @@ extern char *lynxlistfile;
 extern char *lynxlinksfile;
 extern char *display;
 extern char *language;
-extern char *pref_charset; /* Lynx's preferred character set - MM */
-extern char *inews_path;
+extern char *pref_charset;	/* Lynx's preferred character set - MM */
+extern BOOLEAN LYNewsPosting;	/* News posting supported if TRUE */
+extern char *LynxSigFile;	/* Signature file, in or off home */
 extern char *system_mail;
 extern char *lynx_temp_space;
 extern char *lynx_save_space;
diff --git a/src/LYMain.c b/src/LYMain.c
index 85167077..22d299a7 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -70,7 +70,11 @@ PUBLIC char *ftp_proxy_putenv_cmd = NULL;    /* lynx.cfg defined ftp_proxy */
 PUBLIC char *gopher_proxy_putenv_cmd = NULL; /* lynx.cfg defined gopher_proxy */
 PUBLIC char *cso_proxy_putenv_cmd = NULL;    /* lynx.cfg defined cso_proxy */
 PUBLIC char *news_proxy_putenv_cmd = NULL;   /* lynx.cfg defined news_proxy */
+PUBLIC char *newspost_proxy_putenv_cmd = NULL;
+PUBLIC char *newsreply_proxy_putenv_cmd = NULL;
 PUBLIC char *snews_proxy_putenv_cmd = NULL;  /* lynx.cfg defined snews_proxy */
+PUBLIC char *snewspost_proxy_putenv_cmd = NULL;
+PUBLIC char *snewsreply_proxy_putenv_cmd = NULL;
 PUBLIC char *nntp_proxy_putenv_cmd = NULL;   /* lynx.cfg defined nntp_proxy */
 PUBLIC char *wais_proxy_putenv_cmd = NULL;   /* lynx.cfg defined wais_proxy */
 PUBLIC char *finger_proxy_putenv_cmd = NULL; /* lynx.cfg defined finger_proxy */
@@ -247,10 +251,11 @@ PUBLIC char *global_extension_map = NULL;  /* global mime.types */
 PUBLIC char *personal_extension_map = NULL;/* .mime.types */
 PUBLIC char *language = NULL;	    /* preferred language */
 PUBLIC char *pref_charset = NULL;   /* preferred character set */
-PUBLIC char *inews_path = NULL;	    /* the path for posting to news */
-PUBLIC char *system_mail = NULL;    /* the path for sending mail */
-PUBLIC char *lynx_temp_space = NULL; /* the prefix for temporary file paths */
-PUBLIC char *lynx_save_space = NULL; /* the prefix for save to disk paths */
+PUBLIC BOOLEAN LYNewsPosting = NEWS_POSTING; /* News posting supported? */
+PUBLIC char *LynxSigFile = NULL;    /* Signature file, in or off home */
+PUBLIC char *system_mail = NULL;    /* The path for sending mail */
+PUBLIC char *lynx_temp_space = NULL; /* The prefix for temporary file paths */
+PUBLIC char *lynx_save_space = NULL; /* The prefix for save to disk paths */
 PUBLIC char *LYHostName = NULL;		/* treat as a local host name */
 PUBLIC char *LYLocalDomain = NULL;	/* treat as a local domain tail */
 PUBLIC BOOLEAN clickable_images = MAKE_LINKS_FOR_ALL_IMAGES;
@@ -348,7 +353,11 @@ PRIVATE void free_lynx_globals NOARGS
     FREE(gopher_proxy_putenv_cmd);
     FREE(cso_proxy_putenv_cmd);
     FREE(news_proxy_putenv_cmd);
+    FREE(newspost_proxy_putenv_cmd);
+    FREE(newsreply_proxy_putenv_cmd);
     FREE(snews_proxy_putenv_cmd);
+    FREE(snewspost_proxy_putenv_cmd);
+    FREE(snewsreply_proxy_putenv_cmd);
     FREE(nntp_proxy_putenv_cmd);
     FREE(wais_proxy_putenv_cmd);
     FREE(finger_proxy_putenv_cmd);
@@ -375,7 +384,7 @@ PRIVATE void free_lynx_globals NOARGS
     FREE(personal_extension_map);
     FREE(language);
     FREE(pref_charset);
-    FREE(inews_path);
+    FREE(LynxSigFile);
     FREE(system_mail);
     FREE(LYUserAgent);
     FREE(LYUserAgentDefault);
@@ -422,6 +431,7 @@ PUBLIC int main ARGS2(
     char *temp = NULL;
     char *cp;
     FILE *fp;
+    char filename[256];
 
     /*
      *  Set up the argument list.
@@ -519,7 +529,6 @@ PUBLIC int main ARGS2(
     StrAllocCopy(personal_extension_map, PERSONAL_EXTENSION_MAP);
     StrAllocCopy(language, PREFERRED_LANGUAGE);
     StrAllocCopy(pref_charset, PREFERRED_CHARSET);
-    StrAllocCopy(inews_path, INEWS);
     StrAllocCopy(system_mail, SYSTEM_MAIL);
     if ((cp = getenv("LYNX_TEMP_SPACE")) != NULL)
         StrAllocCopy(lynx_temp_space, cp);
@@ -611,6 +620,14 @@ PUBLIC int main ARGS2(
     HTMLSetRawModeDefault(i);
 
     /*
+     *  Disable news posting if the compilation-based
+     *  LYNewsPosting value is FALSE.  This may be changed
+     *  further down via lynx.cfg or the -restriction
+     *  command line switch. - FM
+     */
+    no_newspost = (LYNewsPosting == FALSE);
+
+    /*
      *  Set up trace, the anonymous account defaults, and/or
      *  the nosocks flag, if requested, and an alternate
      *  configuration file, if specified, NOW.  Also, if
@@ -727,6 +744,22 @@ PUBLIC int main ARGS2(
 #endif /* USE_SLANG */
 
     /*
+     *  Set the compilation default signature file. - FM
+     */
+    strcpy(filename, LYNX_SIG_FILE);
+    if (LYPathOffHomeOK(filename, sizeof(filename))) {
+    	StrAllocCopy(LynxSigFile, filename);
+	LYAddPathToHome(filename, sizeof(filename), LynxSigFile);
+	StrAllocCopy(LynxSigFile, filename);
+	if (TRACE)
+	    fprintf(stderr, "LYNX_SIG_FILE set to '%s'\n", LynxSigFile);
+    } else {
+	if (TRACE)
+	    fprintf(stderr, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n",
+	    		    LYNX_SIG_FILE);
+    }
+
+    /*
      *  Process the configuration file.
      */
     read_cfg(lynx_cfg_file);
@@ -908,12 +941,6 @@ PUBLIC int main ARGS2(
     }
 
     /*
-     *  Disable news posting if no posting command.
-     */
-    if (*inews_path == '\0' || !strcasecomp(inews_path,"none"))
-        no_newspost = TRUE;
-
-    /*
      *  Disable multiple bookmark support if not interactive,
      *  so it doesn't crash on curses functions, or if the
      *  support was blocked via userdefs.h and/or lynx.cfg,
@@ -1781,7 +1808,7 @@ PRIVATE void parse_arg ARGS3(
    jump            disable the 'j' (jump) command\n\
    mail            disallow mail\n\
    multibook       disallow multiple bookmark files\n\
-   news_post       disallow USENET News posting setting in the O)ptions menu\n\
+   news_post       disallow USENET News posting.\n\
    option_save     disallow saving options in .lynxrc\n");
 #if defined(NO_UTMP) || defined(VMS) /* not selective */
 	        printf("\
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 0cb80d9a..da7c818f 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -775,8 +775,8 @@ try_again:
 		} else if (check_realm) {
 		    StrAllocCopy(traversal_host, startrealm);
 		} else {
-		    char *temp = HTParse(curdoc.address, "",
-		    		 PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
+		    temp = HTParse(curdoc.address, "",
+		    		   PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION);
 		    if (!temp || *temp == '\0') {
 		        StrAllocCopy(traversal_host, "None");
 		    } else {
@@ -2196,7 +2196,7 @@ check_recall:
 	    if (!strncasecomp(user_input_buffer, "lynxexec:", 9) ||
 	        !strncasecomp(user_input_buffer, "lynxprog:", 9)) {
 		/*
-		 *  The original implementions of these schemes expected
+		 *  The original implementations of these schemes expected
 		 *  white space without hex escaping, and did not check
 		 *  for hex escaping, so we'll continue to support that,
 		 *  until that code is redone in conformance with SGML
@@ -2774,29 +2774,30 @@ check_recall:
 			 *  and offer it to the user. - FM
 			 */
 		        char *address = NULL;
-			char *path = HTParse(curdoc.address, "", PARSE_PATH);
+			temp = HTParse(curdoc.address, "", PARSE_PATH);
 
-			if (path != NULL) {
-			    HTUnEscape(path);
-			    if (*path == '~' && strlen(path) > 1) {
+			if (temp != NULL) {
+			    HTUnEscape(temp);
+			    if (*temp == '~' && strlen(temp) > 1) {
 			        /*
 				 *  It's a ~user URL so guess user@host. - FM
 				 */
-			        if ((cp = strchr((path+1), '/')) != NULL)
+			        if ((cp = strchr((temp+1), '/')) != NULL)
 				    *cp = '\0';
 				StrAllocCopy(address, "mailto:");
-				StrAllocCat(address, (path+1));
+				StrAllocCat(address, (temp+1));
 				StrAllocCat(address, "@");
 			    }
-			    FREE(path);
+			    FREE(temp);
 			}
 			if (address == NULL)
 			    /*
 			     *  Wasn't a ~user URL so guess WebMaster@host. - FM
 			     */
 		            StrAllocCopy(address, "mailto:WebMaster@");
-		        StrAllocCat(address,
-		       		    HTParse(curdoc.address, "", PARSE_HOST));
+			temp = HTParse(curdoc.address, "", PARSE_HOST);
+		        StrAllocCat(address, temp);
+			FREE(temp);
 			_user_message(NO_OWNER_USE, address);
 			c = LYgetch();
 			if (TOUPPER(c) == 'Y') {
diff --git a/src/LYNews.c b/src/LYNews.c
index b852e484..77ef81cc 100644
--- a/src/LYNews.c
+++ b/src/LYNews.c
@@ -21,285 +21,336 @@
 
 #define FREE(x) if (x) {free(x); x = NULL;}
 
-/* global variable for async i/o */
-BOOLEAN term_message;
+/*
+**  Global variable for async i/o.
+*/
+BOOLEAN term_message = FALSE;
 PRIVATE void terminate_message  PARAMS((int sig));
 
-PUBLIC int LYNewsPost ARGS2(document *,newdoc, BOOLEAN,followup)
+/*
+**  This function is called from HTLoadNews() to have the user
+**  create a file with news headers and a body for posting of
+**  a new message (based on a newspost://nntp_host/newsgroups
+**  or snewspost://secure_nntp_host/newsgroups URL), or to post
+**  a followup (based on a newsreply://nntp_host/newsgroups or
+**  snewsreply://secure_nntp_host/newsgroups URL). The group
+**  or comma-separated list of newsgroups is passed without
+**  a lead slash, and followup is TRUE for newsreply or
+**  snewsreply URLs.  - FM
+*/
+PUBLIC char *LYNewsPost ARGS2(
+	char *,		newsgroups,
+	BOOLEAN,	followup)
 {
-	char *newsgroups=NULL;
-	char user_input[1024];
-	FILE *fd;
-	char *tmptr;
-	int c=0;  /* user input */
-	char tmpfile[100];
-#ifdef VMS
-	FILE *fdcom;
-	char tmpcom[128];
-	char tmpaddress[128];
-	char tmpsubject[128];
-#endif /* VMS */
-	char cmd[130];
-        DocAddress WWWDoc;
-
-	StrAllocCopy(newsgroups, strchr(newdoc->address,':')+1);
- 	term_message=FALSE;
-
-	/* pop previous document off of stack and load into main memory */
-	LYpop(newdoc);
-	WWWDoc.address = newdoc->address;
-	WWWDoc.post_data = newdoc->post_data;
-	WWWDoc.post_content_type = newdoc->post_content_type;
-	WWWDoc.bookmark = newdoc->bookmark;
-	WWWDoc.isHEAD = newdoc->isHEAD;
-	WWWDoc.safe = newdoc->safe;
-        if(!HTLoadAbsolute(&WWWDoc)) {
-	    FREE(newsgroups);
-            return(NOT_FOUND);
+    char user_input[1024];
+    char *cp = NULL;
+    int c = 0;  /* user input */
+    FILE *fd;
+    char tmpfile[256];
+    char *postfile = NULL;
+    char *NewsGroups = NULL;
+    char *org = NULL;
+    FILE *fp;
+
+    /*
+     *  Make sure a non-zero length newspost, newsreply,
+     *  snewspost or snewsreply path was sent to us. - FM
+     */
+    if (!(newsgroups && *newsgroups))
+	return(postfile);
+
+    /*
+     *  Open a temporary file for the headers
+     *  and message body. - FM
+     */ 
+    tempname(tmpfile, NEW_FILE);
+    if ((fd = fopen(tmpfile, "w")) == NULL) {
+	HTAlert(CANNOT_OPEN_TEMP);
+	return(postfile);
+    }
+
+    /*
+     *  The newsgroups could be a comma-seperated list.
+     *  It need not have spaces, but deal with any that
+     *  may also have been hex escaped. - FM
+     */
+    StrAllocCopy(NewsGroups, newsgroups);
+    HTUnEscape(NewsGroups);
+
+    /*
+     *  Allow ^C to cancel the posting,
+     *  i.e., don't let SIGINTs exit Lynx.
+     */
+    signal(SIGINT, terminate_message);
+    term_message = FALSE;
+
+    /*
+     *  Show the list of newsgroups. - FM
+     */
+    clear();
+    move(2,0);
+    scrollok(stdscr, TRUE);	/* Enable scrolling. */
+    addstr("You will be posting to:");
+    addstr("\n	");
+    addstr(NewsGroups);
+    addch('\n');
+
+    /*
+     *  Get the mail address for the From header,
+     *  offering personal_mail_address as default.
+     */
+    addstr("\n\n Please provide your mail address for the From: header\n");
+    strcpy(user_input, "From: ");
+    if (personal_mail_address)
+	strcat(user_input, personal_mail_address);
+    if (LYgetstr(user_input, VISIBLE,
+		 sizeof(user_input), NORECALL) < 0 ||
+	term_message) {
+        _statusline(NEWS_POST_CANCELLED);
+	sleep(InfoSecs);
+	fclose(fd);		/* close the temp file */
+	scrollok(stdscr,FALSE);	/* Stop scrolling.    */
+	goto cleanup;
+    }
+    fprintf(fd, "%s\n", user_input);
+
+    /*
+     *  Get the Subject header, offering the current
+     *  document's title as the default if this is a
+     *  followup rather than a new post. - FM
+     */
+    addstr("\n\n Please provide or edit the Subject: header\n");
+    strcpy(user_input, "Subject: ");
+    if ((followup == TRUE && nhist > 0) &&
+        (cp = HText_getTitle()) != NULL) {
+	/*
+	 *  Add the default subject.
+	 */
+	while (isspace(*cp))
+	    cp++;
+	if (strncasecomp(cp, "Re:", 3))
+            strcat(user_input, "Re: ");
+        strcat(user_input, cp);
+	cp = NULL;
+    }
+    if (LYgetstr(user_input, VISIBLE,
+		 sizeof(user_input), NORECALL) < 0 ||
+	term_message) {
+        _statusline(NEWS_POST_CANCELLED);
+        sleep(InfoSecs);
+        fclose(fd);		/* close the temp file */
+	scrollok(stdscr,FALSE);	/* Stop scrolling.    */
+        goto cleanup;
+    }
+    fprintf(fd,"%s\n",user_input);
+
+    /*
+     *  Add Organization: header.
+     */
+    StrAllocCopy(cp, "Organization: ");
+    if (((org = getenv("ORGANIZATION")) != NULL) && *org != '\0') {
+	StrAllocCat(cp, org);
+    } else if (((org = getenv("NEWS_ORGANIZATION")) != NULL) &&
+    	       *org != '\0') {
+	StrAllocCat(cp, org);
+#ifndef VMS
+    } else if (fp = fopen("/etc/organization", "r")) {
+	if (fgets(user_input, sizeof(user_input), fp) != NULL) {
+	    if ((cp = strchr(user_input, '\n')) != NULL)
+	        *cp = '\0';
+	    if (user_input[0] != '\0')
+	        StrAllocCat(cp, user_input);
 	}
+	fclose(fp);
+#endif /* !VMS */
+    }
+    strcpy(user_input, cp);
+    FREE(cp); 
+    addstr("\n\n Please provide or edit the Organization: header\n");
+    if (LYgetstr(user_input, VISIBLE,
+		 sizeof(user_input), NORECALL) < 0 ||
+	term_message) {
+        _statusline(NEWS_POST_CANCELLED);
+        sleep(InfoSecs);
+        fclose(fd);		/* close the temp file */
+	scrollok(stdscr,FALSE);	/* Stop scrolling.    */
+        goto cleanup;
+    }
+    fprintf(fd,"%s\n",user_input);
+
+    /*
+     *  Add Newsgroups Summary and Keywords headers.
+     */
+    fprintf(fd,"Newsgroups: %s\nSummary: \nKeywords: \n\n", NewsGroups);
+
+    /*
+     *  Have the user create the message body.
+     */
+    if (!no_editor && editor && *editor != '\0') {
+        /*
+	 *  Use an external editor.
+	 */
+	char *editor_arg = "";
+
+	if (followup && nhist > 0) {
+	    /*
+	     *  Ask if the user wants to include the original message.
+	     */
+	    _statusline(INC_ORIG_MSG_PROMPT);
+	    c = 0;
+	    while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
+	    	   !term_message && c != 7 && c != 3)
+	        c = LYgetch();
+	    if (TOUPPER(c) == 'Y')
+	        /*
+		 *  The 1 will add the reply ">" in front of every line.
+		 */
+	        print_wwwfile_to_fd(fd, 1);
+	}
+	fclose(fd);
+	scrollok(stdscr,FALSE);	/* Stop scrolling.    */
+	if (term_message || c == 7 || c == 3)
+	    goto cleanup;
 
-	clear();
-	move(2,0);
-
-	tempname(tmpfile,NEW_FILE);
-	if((fd = fopen(tmpfile,"w")) == NULL) {
-	    HTAlert(CANNOT_OPEN_TEMP);
-	    FREE(newsgroups);
-	    return(NORMAL);
+	/*
+	 *  Spawn the user's editor on the news file.
+	 */
+	if (strstr(editor, "pico")) {
+	    editor_arg = " -t"; /* No prompt for filename to use */
 	}
-#ifdef VMS
-	sprintf(tmpcom, "%s_post", tmpfile);
-	if((fdcom = fopen(tmpcom,"w")) == NULL) {
-	    HTAlert(CANNOT_OPEN_COMFILE);
-	    FREE(newsgroups);
-	    fclose(fd);
-	    remove(tmpfile);
-	    return(NORMAL);
+	sprintf(user_input,"%s%s %s", editor, editor_arg, tmpfile);
+	_statusline(SPAWNING_EDITOR_FOR_NEWS);
+	stop_curses();
+	if (system(user_input)) {
+	    start_curses();
+	    _statusline(ERROR_SPAWNING_EDITOR);
+	    sleep(AlertSecs);
 	} else {
-	    fprintf(fdcom, "$ v = f$verify(1)\n$!\n");
-	    fprintf(fdcom, "$! POSTing via ANU-NEWS\n$!\n");
-	    fprintf(fdcom, "$ on error then goto end\n");
-	    fprintf(fdcom, "$ %s/noscreen POST/noedit/noself-\n", inews_path);
-	    fprintf(fdcom, " /newsgroups=\"%s\"-\n", newsgroups);
+	    start_curses();
 	}
-#endif /* VMS */
-	addstr("You will be posting to:");
-	addstr("\n	");
-	addstr(newsgroups);
-	addch('\n');
-
-	/* Use ^C to cancel mailing of comment */
-	/* and don't let sigints exit lynx     */
-        signal(SIGINT, terminate_message);
-
-	term_message=FALSE;
-
-	addstr("\n\n Please enter your mail address\n");
-	strcpy(user_input,"From: ");
-	/* add the mail address if there is one */
-	if(personal_mail_address)
-	    strcat(user_input,personal_mail_address);
-
+    } else {
+        /*
+	 *  Use the built in line editior.
+	 */
+	addstr("\n\n Please enter your message below.");
+	addstr("\n When you are done, press enter and put a single period (.)");
+	addstr("\n on a line and press enter again.");
+	addstr("\n\n");
+	refresh();
+        *user_input = '\0';
 	if (LYgetstr(user_input, VISIBLE,
-		     sizeof(user_input), NORECALL) < 0 ||
+	    	     sizeof(user_input), NORECALL) < 0 ||
 	    term_message) {
-            _statusline(NEWS_POST_CANCELLED);
+	    _statusline(NEWS_POST_CANCELLED);
 	    sleep(InfoSecs);
-	    fclose(fd);		/* close the temp file */
-#ifdef VMS
-	    fclose(fdcom);	/* close the command file */
-#endif /* VMS */
+	    fclose(fd);	/* close the temp file */
+	    scrollok(stdscr,FALSE);	/* Stop scrolling.    */
 	    goto cleanup;
 	}
-#ifdef VMS
-	if(LYstrstr(user_input, "From:"))
-	    strcpy(tmpaddress, HTStrip(strchr(user_input,':')+1));
-	else
-	    strcpy(tmpaddress, HTStrip(user_input));
-#else
-	fprintf(fd,"%s\n",user_input);
-#endif /* VMS */
-
-        addstr("\n\n Please enter a subject line\n");
-        strcpy(user_input,"Subject: ");
-
-	if (followup) {
-	    /* add the default subject */
-	    tmptr = newdoc->title;
-	    while(isspace(*tmptr)) tmptr++;
-	    if(strncasecomp(tmptr, "Re:",3))
-                strcat(user_input, "Re: ");
-            strcat(user_input, newdoc->title);
-	}
-
-        if (LYgetstr(user_input, VISIBLE,
-		     sizeof(user_input), NORECALL) < 0 ||
-	    term_message) {
-            _statusline(NEWS_POST_CANCELLED);
-            sleep(InfoSecs);
-            fclose(fd);		/* close the temp file */
-#ifdef VMS
-	    fclose(fdcom);	/* close the command file */
-#endif /* VMS */
-            goto cleanup;
-        }
-
-#ifdef VMS
-	if(LYstrstr(user_input, "Subject:"))
-	    strcpy(tmpsubject, HTStrip(strchr(user_input,':')+1));
-	else
-	    strcpy(tmpsubject, HTStrip(user_input));
-	fprintf(fdcom, " /subject=\"%s\"-\n", tmpsubject);
-	fprintf(fdcom, " /headers %s\n", tmpfile);
-	fprintf(fdcom, "\n%s\n", tmpaddress);
-	fprintf(fdcom, "%s\n", newsgroups);
-	fprintf(fdcom, "\n\n\ny\nexit\n");
-	fprintf(fdcom, "$ v = 'f$verify(0)'\n$ exit\n$end:\n");
-	fprintf(fdcom, "$ wait 00:00:10\n$ v = 'f$verify(0)'\n$ exit\n");
-	fclose(fdcom);
-#else
-	fprintf(fd,"%s\n",user_input);
-
-	/*
-	 *  Add Organization: header.
-	 */
-	{
-	    FILE *fp;
-	    char *org;
-
-	    if ((org = getenv("ORGANIZATION")) != NULL && *org != '\0') {
-	        fprintf(fd, "Organization: %s\n", org);
-	    } else if (fp = fopen("/etc/organization", "r")) {
-	        if (fgets(user_input, sizeof(user_input), fp) != NULL)
-		    fprintf(fd, "Organization: %s", user_input);
-		fclose(fp);
-	    }
-	}
-
-	/* add Newsgroups: summary: and Keywords: */
-	fprintf(fd,"Newsgroups: %s\nSummary: \nKeywords: \n\n",newsgroups);
-#endif /* VMS */
-
-	if(!no_editor && editor && *editor != '\0') {
-	    if (followup) {
-	        /* ask if the user wants to include the original message */
-	        _statusline(INC_ORIG_MSG_PROMPT);
-	        c = 0;
-	        while(TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-	    	      !term_message && c != 7 && c != 3)
-	            c = LYgetch();
-	        if(TOUPPER(c) == 'Y')
-	            /* the 1 will add the reply ">" in front of every line */
-	            print_wwwfile_to_fd(fd,1);
-	    }
-
-	    fclose(fd);
-
-	    if (term_message || c == 7 || c == 3)
-	        goto cleanup;
-
-	    /* spawn the users editor on the news file */
-	    sprintf(user_input,"%s %s",editor,tmpfile);
-	    _statusline(SPAWNING_EDITOR_FOR_NEWS);
-	    stop_curses();
-	    if(system(user_input)) {
-		_statusline(ERROR_SPAWNING_EDITOR);
-	  	sleep(AlertSecs);
-	    }
-	    start_curses();
-
-	} else {
-	
-	    addstr("\n\n Please enter your message below.");
-	    addstr("\n When you are done, press enter and put a single period (.)");
-	    addstr("\n on a line and press enter again.");
-	    addstr("\n\n");
-	    scrollok(stdscr,TRUE);
-	    refresh();
-    	    *user_input = '\0';
+	while (!STREQ(user_input,".") && !term_message) { 
+	    addch('\n');
+	    fprintf(fd,"%s\n",user_input);
+	    *user_input = '\0';
 	    if (LYgetstr(user_input, VISIBLE,
-	    		 sizeof(user_input), NORECALL) < 0 ||
-	        term_message) {
+	       		 sizeof(user_input), NORECALL) < 0) {
 	        _statusline(NEWS_POST_CANCELLED);
 	        sleep(InfoSecs);
-	        fclose(fd);	/* close the temp file */
+	        fclose(fd);		/* close the temp file */
+		scrollok(stdscr,FALSE);	/* Stop scrolling.    */
 	        goto cleanup;
 	    }
-
-
-	    while(!STREQ(user_input,".") && !term_message) { 
-	       addch('\n');
-	       fprintf(fd,"%s\n",user_input);
-	       *user_input = '\0';
-	       if (LYgetstr(user_input, VISIBLE,
-	       		    sizeof(user_input), NORECALL) < 0) {
-	          _statusline(NEWS_POST_CANCELLED);
-	          sleep(InfoSecs);
-	          fclose(fd);		/* close the temp file */
-	          goto cleanup;
-	       }
-	    }
-
-	    fprintf(fd,"\n");
-
-	    fclose(fd);		/* close the temp file */
-	    scrollok(stdscr,FALSE);  /* stop scrolling */
-	}
-
-	_statusline(POST_MSG_PROMPT);
+ 	}
+	fprintf(fd, "\n");
+	fclose(fd);		/* close the temp file */
+	scrollok(stdscr,FALSE);  /* stop scrolling */
+    }
+
+    /*
+     *  Confirm whether to post, and if so,
+     *  whether to append the sig file. - FM
+     */
+    LYStatusLine = (LYlines - 1);
+    _statusline(POST_MSG_PROMPT);
+    c = 0;
+    LYStatusLine = -1;
+    while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
+	   !term_message && c != 7   && c != 3)
+	c = LYgetch();
+    if (TOUPPER(c) != 'Y') {
+        clear();  /* clear the screen */
+	goto cleanup;
+    }
+    if ((LynxSigFile != NULL) &&
+        (fp = fopen(LynxSigFile, "r")) != NULL) {
+	LYStatusLine = (LYlines - 1);
+	_user_message(APPEND_SIG_FILE, LynxSigFile);
 	c = 0;
-	while(TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
-	      !term_message && c != 7   && c != 3)
+        LYStatusLine = -1;
+	while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
+	       !term_message && c != 7   && c != 3)
 	    c = LYgetch();
-
-	clear();  /* clear the screen */
-
-	if(TOUPPER(c) != 'Y') {
-	   goto cleanup;
+	if (TOUPPER(c) == 'Y') {
+	    if ((fd = fopen(tmpfile, "a")) != NULL) {
+	        while (fgets(user_input, sizeof(user_input), fp) != NULL) {
+		    fputs(user_input, fd);
+		}
+		fclose(fd);
+	    }
 	}
-
-#ifdef VMS
-	sprintf(cmd,"@%s",tmpcom);
-#else
-	sprintf(cmd,"%s %s",inews_path,tmpfile);
-#endif /* VMS */
-
-        stop_curses();
-	printf("Posting your message:\n\n%s\n\nPlease wait...", cmd);
-	system(cmd);
-	sleep(MessageSecs);
-	start_curses();
-
-	/* come here to cleanup and exit */
+	fclose(fp);
+    }
+    clear();  /* clear the screen */
+    StrAllocCopy(postfile, tmpfile);
+    if (!followup)
+        /*
+	 *  If it's not a followup, the current document
+	 *  most likely is the group listing, so force a
+	 *  to have the article show up in the list after
+	 *  the posting.  Note, that if it's a followup
+	 *  via a link in a news article, the user must
+	 *  do a reload manually on returning to the
+	 *  group listing. - FM
+	 */
+        LYforce_no_cache = TRUE;
+    LYStatusLine = (LYlines - 1);
+    statusline(POSTING_TO_NEWS);
+    LYStatusLine = -1;
+    sleep(MessageSecs);
+
+    /*
+     *  Come here to cleanup and exit.
+     */
 cleanup:
 #ifndef VMS
-	signal(SIGINT, cleanup_sig);
-#else
-	remove(tmpcom);
+    signal(SIGINT, cleanup_sig);
 #endif /* !VMS */
-	term_message = FALSE;
-
-	scrollok(stdscr,FALSE);  /* stop scrolling */
+    term_message = FALSE;
+    if (!postfile) {
 #ifdef VMS
-	while (remove(tmpfile) == 0)
+        while (remove(tmpfile) == 0)
 	    ; /* loop through all versions */
 #else
 	remove(tmpfile);
 #endif /* VMS */
+    }
+    FREE(NewsGroups);
 
-	FREE(newsgroups);
-	return(NORMAL);
+    return(postfile);
 }
 
-PRIVATE void terminate_message ARGS1(int,sig)
+PRIVATE void terminate_message ARGS1(
+	int,	sig)
 {
-	term_message=TRUE;
-	/* Reassert the AST */
-	signal(SIGINT, terminate_message);
+    term_message = TRUE;
+    /*
+     *  Reassert the AST.
+     */
+    signal(SIGINT, terminate_message);
 #ifdef VMS
-        /* Refresh the screen to get rid of the "interrupt" message */
-	clearok(curscr, TRUE);
-	refresh();
+    /*
+     *  Refresh the screen to get rid of the "interrupt" message.
+     */
+    clearok(curscr, TRUE);
+    refresh();
 #endif /* VMS */
 }
-
diff --git a/src/LYNews.h b/src/LYNews.h
index cb51768c..14d0e6bd 100644
--- a/src/LYNews.h
+++ b/src/LYNews.h
@@ -7,7 +7,7 @@
 #include "LYStructs.h"
 #endif /* LYSTRUCTS_H */
 
-extern int LYNewsPost PARAMS((document *newdoc, BOOLEAN followup));
+extern char *LYNewsPost PARAMS((char *newsgroups, BOOLEAN followup));
 
 #endif /* LYNEWSPOST_H */
 
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index af340803..4af58672 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -655,12 +655,9 @@ PUBLIC void read_cfg ARGS1(
 	break;
 
 	case 'I':
-	if (!strncasecomp(buffer, "INEWS:", 6)) {
-	    StrAllocCopy(inews_path, buffer+6);
-	    if (*inews_path == '\0' || !strcasecomp(inews_path, "none"))
-		no_newspost = TRUE;
-	    else
-		no_newspost = FALSE;
+	if (!strncasecomp(buffer, "NEWS_POSTING:", 13)) {
+	    LYNewsPosting = is_true(buffer+13);
+	    no_newspost = (LYNewsPosting == FALSE);
 
 	} else if (!strncasecomp(buffer, "INFOSECS:", 9)) {
 	    strcpy(temp, buffer+9);
@@ -743,6 +740,21 @@ PUBLIC void read_cfg ARGS1(
 
 	} else if (!strncasecomp(buffer, "LYNX_HOST_NAME:", 15)) {
 	    StrAllocCopy(LYHostName, buffer+15);
+
+	} else if (!strncasecomp(buffer, "LYNX_SIG_FILE:", 14)) {
+	    strcpy(temp, (buffer+14));
+	    if (LYPathOffHomeOK(temp, 256)) {
+	        StrAllocCopy(LynxSigFile, temp);
+		LYAddPathToHome(temp, 256, LynxSigFile);
+		StrAllocCopy(LynxSigFile, temp);
+		if (TRACE)
+		    fprintf(stderr,
+		    	    "LYNX_SIG_FILE set to '%s'\n", LynxSigFile);
+    	    } else {
+	        if (TRACE)
+		    fprintf(stderr, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n",
+	    			    LYNX_SIG_FILE);
+	    }
 	}
 	break;
 
@@ -815,6 +827,32 @@ PUBLIC void read_cfg ARGS1(
 #endif /* VMS */
 	    }
 
+	} else if (!strncasecomp(buffer, "newspost_proxy:", 15)) {
+	    if (getenv("newspost_proxy") == NULL) {
+#ifdef VMS
+		strcpy(temp, "newspost_proxy");
+		Define_VMSLogical(temp, (char *)&buffer[15]);
+#else
+		strcpy(temp, "newspost_proxy=");
+		StrAllocCopy(newspost_proxy_putenv_cmd, temp);
+		StrAllocCat(newspost_proxy_putenv_cmd, (char *)&buffer[15]);
+		putenv(newspost_proxy_putenv_cmd);
+#endif /* VMS */
+	    }
+
+	} else if (!strncasecomp(buffer, "newsreply_proxy:", 16)) {
+	    if (getenv("newsreply_proxy") == NULL) {
+#ifdef VMS
+		strcpy(temp, "newsreply_proxy");
+		Define_VMSLogical(temp, (char *)&buffer[16]);
+#else
+		strcpy(temp, "newsreply_proxy=");
+		StrAllocCopy(newsreply_proxy_putenv_cmd, temp);
+		StrAllocCat(newsreply_proxy_putenv_cmd, (char *)&buffer[16]);
+		putenv(newsreply_proxy_putenv_cmd);
+#endif /* VMS */
+	    }
+
 	} else if (!strncasecomp(buffer, "nntp_proxy:", 11)) {
 	    if (getenv("nntp_proxy") == NULL) {
 #ifdef VMS
@@ -912,6 +950,32 @@ PUBLIC void read_cfg ARGS1(
 #endif /* VMS */
 	    }
 
+	} else if (!strncasecomp(buffer, "snewspost_proxy:", 16)) {
+	    if (getenv("snewspost_proxy") == NULL) {
+#ifdef VMS
+		strcpy(temp, "snewspost_proxy");
+		Define_VMSLogical(temp, (char *)&buffer[16]);
+#else
+		strcpy(temp, "snewspost_proxy=");
+		StrAllocCopy(snewspost_proxy_putenv_cmd, temp);
+		StrAllocCat(snewspost_proxy_putenv_cmd, (char *)&buffer[16]);
+		putenv(snewspost_proxy_putenv_cmd);
+#endif /* VMS */
+	    }
+
+	} else if (!strncasecomp(buffer, "snewsreply_proxy:", 17)) {
+	    if (getenv("snewsreply_proxy") == NULL) {
+#ifdef VMS
+		strcpy(temp, "snewsreply_proxy");
+		Define_VMSLogical(temp, (char *)&buffer[17]);
+#else
+		strcpy(temp, "snewsreply_proxy=");
+		StrAllocCopy(snewsreply_proxy_putenv_cmd, temp);
+		StrAllocCat(snewsreply_proxy_putenv_cmd, (char *)&buffer[17]);
+		putenv(snewsreply_proxy_putenv_cmd);
+#endif /* VMS */
+	    }
+
 	} else if (!strncasecomp(buffer, "SOFT_DQUOTES:", 13)) {
 	    soft_dquotes = is_true(buffer+13);
 
diff --git a/src/LYUtils.c b/src/LYUtils.c
index c479d440..debb5c33 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -843,6 +843,46 @@ PUBLIC int is_url ARGS1(
 	}
 	return(SNEWS_URL_TYPE);
 
+    } else if (!strncasecomp(cp, "newspost:", 9)) {
+	/*
+	 *  Special Lynx type to handle news posts.
+	 */
+        if (strncmp(cp, "newspost", 8)) {
+	    for (i = 0; i < 8; i++)
+	        cp[i] = TOLOWER(cp[i]);
+	}
+	return(NEWSPOST_URL_TYPE);
+
+    } else if (!strncasecomp(cp, "newsreply:", 10)) {
+	/*
+	 *  Special Lynx type to handle news replies (followups).
+	 */
+        if (strncmp(cp, "newsreply", 9)) {
+	    for (i = 0; i < 9; i++)
+	        cp[i] = TOLOWER(cp[i]);
+	}
+	return(NEWSREPLY_URL_TYPE);
+
+    } else if (!strncasecomp(cp, "snewspost:", 10)) {
+	/*
+	 *  Special Lynx type to handle snews posts.
+	 */
+        if (strncmp(cp, "snewspost", 9)) {
+	    for (i = 0; i < 9; i++)
+	        cp[i] = TOLOWER(cp[i]);
+	}
+	return(NEWSPOST_URL_TYPE);
+
+    } else if (!strncasecomp(cp, "snewsreply:", 11)) {
+	/*
+	 *  Special Lynx type to handle snews replies (followups).
+	 */
+        if (strncmp(cp, "snewsreply", 10)) {
+	    for (i = 0; i < 10; i++)
+	        cp[i] = TOLOWER(cp[i]);
+	}
+	return(NEWSREPLY_URL_TYPE);
+
     } else if (!strncasecomp(cp, "mailto:", 7)) {
         if (strncmp(cp, "mailto", 6)) {
 	    for (i = 0; i < 6; i++)
@@ -904,26 +944,6 @@ PUBLIC int is_url ARGS1(
 	}
 	return(LYNXCGI_URL_TYPE);
 
-    } else if (!strncasecomp(cp, "newspost:", 9)) {
-	/*
-	 *  Special Internal Lynx type to handle news posts.
-	 */
-        if (strncmp(cp, "newspost", 8)) {
-	    for (i = 0; i < 8; i++)
-	        cp[i] = TOLOWER(cp[i]);
-	}
-	return(NEWSPOST_URL_TYPE);
-
-    } else if (!strncasecomp(cp, "newsreply:", 10)) {
-	/*
-	 *  Special Internal Lynx type to handle news replies (followups).
-	 */
-        if (strncmp(cp, "newsreply", 9)) {
-	    for (i = 0; i < 9; i++)
-	        cp[i] = TOLOWER(cp[i]);
-	}
-	return(NEWSREPLY_URL_TYPE);
-
     } else if (!strncasecomp(cp, "LYNXPRINT:", 10)) {
 	/*
 	 *  Special Internal Lynx type.
@@ -1003,13 +1023,6 @@ PUBLIC int is_url ARGS1(
 	 */
 	return(LYCheckForProxyURL(filename));
 
-    } else if (!strncasecomp(cp, "https:", 6)) {
-        if (strncmp(cp, "https", 5)) {
-	    for (i = 0; i < 5; i++)
-	        cp[i] = TOLOWER(cp[i]);
-	}
-	return(HTTPS_URL_TYPE);
-
     } else if (!strncasecomp(cp, "http:", 5)) {
         if (strncmp(cp, "http", 4)) {
 	    for (i = 0; i < 4; i++)
@@ -1017,6 +1030,13 @@ PUBLIC int is_url ARGS1(
 	}
 	return(HTTP_URL_TYPE);
 
+    } else if (!strncasecomp(cp, "https:", 6)) {
+        if (strncmp(cp, "https", 5)) {
+	    for (i = 0; i < 5; i++)
+	        cp[i] = TOLOWER(cp[i]);
+	}
+	return(HTTPS_URL_TYPE);
+
     } else if (!strncasecomp(cp, "gopher:", 7)) {
         if (strncmp(cp, "gopher", 6)) {
 	    for (i = 0; i < 6; i++)
diff --git a/src/LYUtils.h b/src/LYUtils.h
index b03b1c1d..ea5bebc1 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -97,18 +97,20 @@ extern BOOLEAN mustshow;
 
 #define NEWSPOST_URL_TYPE	25
 #define NEWSREPLY_URL_TYPE	26
+#define SNEWSPOST_URL_TYPE	27
+#define SNEWSREPLY_URL_TYPE	28
 
-#define LYNXPRINT_URL_TYPE	27
-#define LYNXHIST_URL_TYPE	28
-#define LYNXDOWNLOAD_URL_TYPE	29
-#define LYNXKEYMAP_URL_TYPE	30
-#define LYNXIMGMAP_URL_TYPE	31
-#define LYNXCOOKIE_URL_TYPE	32
-#define LYNXDIRED_URL_TYPE	33
+#define LYNXPRINT_URL_TYPE	29
+#define LYNXHIST_URL_TYPE	30
+#define LYNXDOWNLOAD_URL_TYPE	31
+#define LYNXKEYMAP_URL_TYPE	32
+#define LYNXIMGMAP_URL_TYPE	33
+#define LYNXCOOKIE_URL_TYPE	34
+#define LYNXDIRED_URL_TYPE	35
 
-#define PROXY_URL_TYPE		34
+#define PROXY_URL_TYPE		36
 
-#define UNKNOWN_URL_TYPE	35
+#define UNKNOWN_URL_TYPE	37
 
 /*
  *  For change_sug_filename().
diff --git a/userdefs.h b/userdefs.h
index abe4f458..11ca6bdc 100644
--- a/userdefs.h
+++ b/userdefs.h
@@ -132,25 +132,6 @@
  */
 #define MAIL_ADRS "\"IN%%\"\"%s\"\"\""
 
-/*************************
- * The foreign command for the ANU-NEWS client (presumably "NEWS").
- * which serves as a transparent vector for posting to newsgroups
- * from Lynx via the ANU-NEWS client's server.  The account running
- * Lynx must have access to the ANU-NEWS client, which in turn must
- * have posting privileges (the news server could also be ANU-NEWS,
- * or any other server to which the ANU-NEWS client has access).
- *
- * The ANU-NEWS software for VMS is available from ftp.cc.ukans.edu.
- *
- * Define INEWS as "none" if you do not have access to an ANU-NEWS
- * client with a server for posting to newsgroups from Lynx.
- *
- * Note that posting is supported only for news: (not nntp: or snews:)
- * URLs, and only via the default nntp server defined with the NNTPSERVER
- * configuration or environment variable.
- */
-#define INEWS "NEWS"
-
 /*********************************
  * On VMS, CSwing (an XTree emulation for VTxxx terminals) is intended for
  * use as the Directory/File Manager (sources, objects, or executables are
@@ -288,19 +269,6 @@
  */
 #define XLOADIMAGE_COMMAND "xli %s &"
 
-/*************************
- * Set INEWS to the full path and name of your program for posting to
- * newsgroups.  A "mini" inews is included in the utils subdirectory of
- * the Lynx distribution.  You can disable news posting by setting INEWS
- * to "none", or via -restrictions switches.  The default defined here
- * can be overridden in lynx.cfg.
- * Note that some news software, such as INN's inews, requires an -h switch
- * added to the path.  Also note that posting is supported only for news:
- * (not nntp: or snews:) URLs, and only via the default nntp server defined
- * with the NNTPSERVER configuration or environment variable.
- */
-#define INEWS "inews"
-
 /**************************
  * For UNIX systems this should be sendmail
  * sendmail should be in /usr/lib 
@@ -670,6 +638,29 @@
  */
 #define LIST_NEWS_DATES FALSE
 
+/*************************
+ * Set NEWS_POSTING to FALSE if you do not want to support posting to
+ * news groups via Lynx.  If left TRUE, Lynx will use its news gateway to
+ * post new messages or followups to news groups, using the URL schemes
+ * described in the "Supported URL" section of the online 'h'elp.  The
+ * posts will be attempted via the nntp server specified in the URL, or
+ * if none was specified, via the NNTPSERVER configuration or environment
+ * variable.  Links with these URLs for posting or sending followups are
+ * created by the news gateway when reading group listings or articles
+ * from nntp servers if the server indicates that it permits posting.
+ * The setting here can be changed in lynx.cfg.
+ */
+#define NEWS_POSTING TRUE
+
+/*************************
+ * Define LYNX_SIG_FILE to the name of a file containing a signature which
+ * can be appended to news postings or followups.  The user will be prompted
+ * whether to append it.  It is sought in the home directory.  If it is in
+ * a subdirectory, begin it with a dot-slash (e.g., ./lynx/.lynxsig).  The
+ * definition here can be changed in lynx.cfg.
+ */
+#define LYNX_SIG_FILE ".lynxsig"
+
 /********************************
  * If USE_SELECT_POPUPS is set FALSE, Lynx will present a vertical list
  * of radio buttons for the OPTIONs in SELECT blocks which lack the