changeset 282:baa6408d1bbc noffle

[svn] * src/database.c,src/post.c,src/protocol.h,src/protocol.c: When posting, check the article for those headers that are specified in section 5 of the IETF draft and ensure they only occur once. * src/post.c: Clean up a conditional.
author bears
date Mon, 06 Jan 2003 18:16:18 +0000
parents 5eece4dfd945
children 39d9c19ffba4
files ChangeLog src/database.c src/post.c src/protocol.c src/protocol.h
diffstat 5 files changed, 97 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Dec 27 21:48:25 2002 +0000
+++ b/ChangeLog	Mon Jan 06 18:16:18 2003 +0000
@@ -1,3 +1,10 @@
+Mon Jan 6 2003 Jim Hague <jim.hague@acm.org>
+
+* src/database.c,src/post.c,src/protocol.h,src/protocol.c: When posting,
+  check the article for those headers that are specified in section
+  5 of the IETF draft and ensure they only occur once.
+* src/post.c: Clean up a conditional.
+	
 Fri Dec 27 2002 Jim Hague <jim.hague@acm.org>
 
 * src/log.c,src/log.h: Add Log_fatal() for reporting fatal errors
@@ -29,7 +36,7 @@
 * src/util.c: Replace the alternate Utl_mktimeGMT() implementation used when
   timegm() is not available. The previous version, as suggested by the
   glibc timegm() man page, used setenv() and unsetenv() for changing the
-  environment. These aren't POSIX function, and the POSIX putenv()
+  environment. These aren't POSIX functions, and the POSIX putenv()
   (a) is tricky to manage if the same var is being constantly update and
   memory isn't to leak, and (b) provides no way to remove an environment
   entry. So change to an implementation Wget uses. This should compile on
--- a/src/database.c	Fri Dec 27 21:48:25 2002 +0000
+++ b/src/database.c	Mon Jan 06 18:16:18 2003 +0000
@@ -1,7 +1,7 @@
 /*
   database.c
 
-  $Id: database.c 413 2002-12-27 21:48:25Z bears $
+  $Id: database.c 414 2003-01-06 18:16:18Z bears $
 
   Uses GNU gdbm library. Using Berkeley db (included in libc6) was
   cumbersome. It is based on Berkeley db 1.85, which has severe bugs
@@ -275,6 +275,8 @@
     /* Read header */
     while ( ( artTxt = Utl_getHeaderLn( lineEx, artTxt ) ) != NULL )
     {
+	Bool continuation;
+	
         if ( lineEx[ 0 ] == '\0' )
         {
             DynStr_appLn( db.txt, lineEx );
@@ -282,7 +284,7 @@
         }
         /* Remove fields already in overview and handle x-noffle
            headers correctly in case of cascading NOFFLEs */
-        if ( Prt_getField( field, value, lineEx ) )
+        if ( Prt_getField( field, value, &continuation, lineEx ) )
         {
             if ( strcmp( field, "x-noffle-status" ) == 0 )
             {
--- a/src/post.c	Fri Dec 27 21:48:25 2002 +0000
+++ b/src/post.c	Mon Jan 06 18:16:18 2003 +0000
@@ -1,7 +1,7 @@
 /*
   post.c
 
-  $Id: post.c 379 2002-03-26 17:52:01Z mirkol $
+  $Id: post.c 414 2003-01-06 18:16:18Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -176,21 +176,33 @@
 {
     DynStr * s;
     Str line, field, value;
-    Bool replyToFound, pathFound, orgFound;
+    Bool dateFound, fromFound, msgIdFound, subjectFound;
+    Bool newsgroupsFound, pathFound;
+    Bool replyToFound, orgFound;
+    Bool continuation;
     time_t t;
     int sigLines;
 
     s = new_DynStr( 10000 );
     article.text = s;
 
-    replyToFound = pathFound = orgFound = FALSE;
+    /* RFC says only one of these headers. */
+    dateFound = fromFound = msgIdFound = subjectFound =
+	newsgroupsFound = pathFound = FALSE;
+
+    /* Stuff we might want to add. */
+    replyToFound = orgFound = FALSE;
 
     field[ 0 ] = '\0';
 
-    /* Grab header lines first, getting overview info as we go. */
+    /*
+     * Grab header lines first, getting overview info as we go.
+     * Note that a line may be a continuation line, hence we always
+     * cat the information into the destination.
+     */
     while ( ( p = Utl_getHeaderLn( line, p ) ) != NULL
 	    && line[ 0 ] != '\0'
-	    && Prt_getField( field, value, line ) )
+	    && Prt_getField( field, value, &continuation, line ) )
     {
         if ( field [ 0 ] == '\0' )
         {
@@ -201,28 +213,61 @@
 	/* Look for headers we need to stash. */
 	if ( strcmp( field, "subject" ) == 0 )
 	{
+	    if ( !continuation && subjectFound )
+	    {
+		Log_err( "Duplicate Subject: header" );
+		return FALSE;
+	    }
 	    Utl_catStr( article.over.subject, value );
 	    DynStr_appLn( s, line );
+	    subjectFound = TRUE;
 	}
 	else if ( strcmp ( field, "from" ) == 0 )
 	{
+	    if ( !continuation && fromFound )
+	    {
+		Log_err( "Duplicate From: header" );
+		return FALSE;
+	    }
 	    Utl_catStr( article.over.from, value );
 	    DynStr_appLn( s, line );
+	    fromFound = TRUE;
 	}
 	else if ( strcmp ( field, "date" ) == 0 )
+	{
+	    if ( !continuation && dateFound )
+	    {
+		Log_err( "Duplicate Date: header" );
+		return FALSE;
+	    }	    
 	    Utl_catStr( article.over.date, value );
+	    dateFound = TRUE;
+	}
 	else if ( strcmp ( field, "references" ) == 0 )
 	{
 	    Utl_catStr( article.over.ref, value );
 	    DynStr_appLn( s, line );
 	}
 	else if ( strcmp ( field, "message-id" ) == 0 )
-	/*    Utl_catStr( article.over.msgId, value ); */
-	    Utl_cpyStr( article.over.msgId, value );
+	{
+	    if ( !continuation && msgIdFound )
+	    {
+		Log_err( "Duplicate Message-Id: header" );
+		return FALSE;
+	    }
+	    Utl_catStr( article.over.msgId, value );
+	    msgIdFound = TRUE;
+	}
 	else if ( strcmp ( field, "newsgroups" ) == 0 )
 	{
+	    if ( !continuation && newsgroupsFound )
+	    {
+		Log_err( "Duplicate Newsgroups: header" );
+		return FALSE;
+	    }
 	    article.newsgroups = new_Itl( value, " ,\n\t" );
 	    DynStr_appLn( s, line );
+	    newsgroupsFound = TRUE;
 	}
 	else if ( strcmp ( field, "control" ) == 0 )
 	{
@@ -241,6 +286,11 @@
 	}
 	else if ( strcmp ( field, "path" ) == 0 )
 	{
+	    if ( !continuation && pathFound )
+	    {
+		Log_err( "Duplicate Path: header" );
+		return FALSE;
+	    }
 	    pathFound = TRUE;
 	    DynStr_appLn( s, line );
 	}
@@ -280,7 +330,7 @@
 	    return FALSE;
 	}
     }
-    if ( article.over.subject[ 0 ] == '\0' )
+    if ( ! subjectFound )
     {
 	Log_err( "Posted message has no Subject field" );
 	return FALSE;
@@ -543,9 +593,8 @@
 	 * for example, we don't want to immediately post locally articles
 	 * destined for the moderator of a moderated group.
 	 */
-	if ( ! local && ( ! postLocal || Grp_postAllow( grp ) != 'y' ) )
-	    continue;
-	err = addToGroup( grp ) && err;
+	if ( local || ( postLocal && Grp_postAllow( grp ) == 'y' ) )
+	    err = addToGroup( grp ) && err;
     }
 
     return postExternal() && err;
--- a/src/protocol.c	Fri Dec 27 21:48:25 2002 +0000
+++ b/src/protocol.c	Mon Jan 06 18:16:18 2003 +0000
@@ -1,7 +1,7 @@
 /*
   protocol.c
 
-  $Id: protocol.c 403 2002-11-10 11:32:17Z bears $
+  $Id: protocol.c 414 2003-01-06 18:16:18Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -180,12 +180,16 @@
 }
 
 Bool
-Prt_getField( Str resultField, Str resultValue, const char* line )
+Prt_getField( Str resultField, Str resultValue,
+	      Bool* isContinuation, const char* line )
 {
     char *dst;
     const char *p;
     Str lineLower, t;
+
+    ASSERT( isContinuation );
     
+    *isContinuation = FALSE;
     Utl_cpyStr( lineLower, line );
     Utl_toLower( lineLower );
     p = Utl_stripWhiteSpace( lineLower );
@@ -204,14 +208,23 @@
             p = Utl_stripWhiteSpace( t );
             strcpy( resultValue, p );
             return TRUE;
-        }
+        } else
+	    return FALSE;	/* Not a header line */
     }
-    else        /* continued header.  */
+    else
     {
-            strcpy( resultValue, lineLower ); /* include starting whitespace */
-            return TRUE;
+	/*
+	 * If the line starts with white space, it can be a header
+	 * continuation.
+	 */
+	if( ! isspace( *line ) )
+	    return FALSE;
+	
+	Utl_cpyStr( resultValue, line );
+	*isContinuation = TRUE;
+        return TRUE;
     }
-    return FALSE;
+    /* NOTREACHED */
 }
 
 Bool
@@ -221,6 +234,7 @@
     char *dst;
     Str line, whichLower, field;
     int len;
+    Bool continuation;
     
     Utl_cpyStr( whichLower, which );
     Utl_toLower( whichLower );
@@ -242,7 +256,7 @@
         p = Utl_stripWhiteSpace( line );
         if ( *p == '\0' )
             break;
-        if ( Prt_getField( field, result, line )
+        if ( Prt_getField( field, result, &continuation, line )
              && strcmp( field, whichLower ) == 0 )
             return TRUE;
     }
--- a/src/protocol.h	Fri Dec 27 21:48:25 2002 +0000
+++ b/src/protocol.h	Mon Jan 06 18:16:18 2003 +0000
@@ -4,7 +4,7 @@
   Functions related with the NNTP protocol which are useful for both
   the server and the client.
 
-  $Id: protocol.h 413 2002-12-27 21:48:25Z bears $
+  $Id: protocol.h 414 2003-01-06 18:16:18Z bears $
 */
 
 #ifndef PRT_H
@@ -101,7 +101,8 @@
   Splits line in field and value. Field is converted to lower-case. 
 */
 Bool
-Prt_getField( Str resultField, Str resultValue, const char* line );
+Prt_getField( Str resultField, Str resultValue,
+	      Bool* isContinuation, const char* line );
 
 /* Search header. Works only with single line headers (ignores continuation
    lines */