INN commit: trunk/nnrpd (article.c nnrpd.c nnrpd.h)

INN Commit Russ_Allbery at isc.org
Fri Sep 5 19:13:28 UTC 2008


    Date: Friday, September 5, 2008 @ 12:13:28
  Author: iulius
Revision: 8003

* Add support for OVER (though not the OVER MSGID capability).
* Correctly parse the arguments before anything else.
* Fix XOVER which could send empty replies with 224 (not allowed
  even by RFC 2980).
* More user-friendly answers.
* Also fix a bug in the replies of XOVER/XHDR/XPAT when the group
  is empty.  Two initial replies were sent (420 followed by 224).

Modified:
  trunk/nnrpd/article.c
  trunk/nnrpd/nnrpd.c
  trunk/nnrpd/nnrpd.h

-----------+
 article.c |   98 +++++++++++++++++++++++++++++++++++++++++-------------------
 nnrpd.c   |    4 +-
 nnrpd.h   |   12 +++----
 3 files changed, 76 insertions(+), 38 deletions(-)

Modified: article.c
===================================================================
--- article.c	2008-09-04 20:36:11 UTC (rev 8002)
+++ article.c	2008-09-05 19:13:28 UTC (rev 8003)
@@ -877,12 +877,13 @@
 }
 
 /*
-**  XOVER, another extension.  Dump parts of the overview database.
+**  Dump parts of the overview database with the OVER command.
+**  The legacy XOVER is also kept.
 */
 void
-CMDxover(int ac, char *av[])
+CMDover(int ac, char *av[])
 {
-    bool	        DidReply;
+    bool	        DidReply, HasNotReplied;
     ARTRANGE		range;
     struct timeval	stv, etv;
     ARTNUM		artnum;
@@ -892,7 +893,28 @@
     int			len, useIOb = 0;
     TOKEN		token;
     struct cvector *vector = NULL;
+    bool                xover, mid;
 
+    xover = (strcasecmp(av[0], "XOVER") == 0);
+    mid = (ac > 1 && IsValidMessageID(av[1]));
+
+    /* Check the syntax of the arguments first.
+     * We do not accept a message-ID for XOVER, contrary to OVER.  A range
+     * is accepted for both of them. */
+    if (ac > 1
+        && (xover || !mid)
+        && !CMDisrange(av[1])) {
+        Reply("%d Syntax error in arguments\r\n", NNTP_ERR_SYNTAX);
+        return;
+    }
+
+    if (mid) {
+        /* FIXME:  We still do not support OVER MSGID, sorry! */
+        Reply("%d Overview by message-ID unsupported\r\n", NNTP_ERR_UNAVAILABLE);
+        return;
+    }
+
+    /* Check authorizations. */
     if (!PERMcanread) {
 	Reply("%d Read access denied\r\n", NNTP_ERR_ACCESS);
 	return;
@@ -904,26 +926,25 @@
 	return;
     }
 
-    /* Parse range. */
-    if (!CMDgetrange(ac, av, &range, &DidReply)) {
-	if (!DidReply) {
-	    Reply("%d data follows\r\n", NNTP_OK_OVER);
-	    Printf(".\r\n");
-	    return;
-	}
-    }
+    /* Parse range.  CMDgetrange() correctly sets the range when
+     * there is no argument. */
+    if (!CMDgetrange(ac, av, &range, &DidReply))
+        if (DidReply)
+            return;
 
     if (PERMaccessconf->nnrpdoverstats) {
         OVERcount++;
         gettimeofday(&stv, NULL);
     }
     if ((handle = (void *)OVopensearch(GRPcur, range.Low, range.High)) == NULL) {
-	if (av[1] != NULL)
-	    Reply("%d %s fields follow\r\n", NNTP_OK_OVER, av[1]);
-	else
-	    Reply("%d %d fields follow\r\n", NNTP_OK_OVER, ARTnumber);
-        Printf(".\r\n");
-	return;
+        /* The response code is different if a range is provided.  For OVER only. */
+        if (ac > 1)
+            Reply("%d No articles in %s\r\n",
+                  xover ? NNTP_FAIL_NO_ARTICLE : NNTP_FAIL_BAD_ARTICLE, av[1]);
+        else
+            Reply("%d Current article number %d is invalid\r\n",
+                  NNTP_FAIL_NO_ARTICLE, ARTnumber);
+        return;
     }
     if (PERMaccessconf->nnrpdoverstats) {
 	gettimeofday(&etv, NULL);
@@ -931,11 +952,6 @@
 	OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
     }
 
-    if (av[1] != NULL)
-	Reply("%d %s fields follow\r\n", NNTP_OK_OVER, av[1]);
-    else
-	Reply("%d %d fields follow\r\n", NNTP_OK_OVER, ARTnumber);
-    fflush(stdout);
     if (PERMaccessconf->nnrpdoverstats)
 	gettimeofday(&stv, NULL);
 
@@ -944,6 +960,7 @@
        SendIOb because it copies the data. */
     OVctl(OVSTATICSEARCH, &useIOb);
 
+    HasNotReplied = true;
     while (OVsearch(handle, &artnum, &data, &len, &token, NULL)) {
 	if (PERMaccessconf->nnrpdoverstats) {
 	    gettimeofday(&etv, NULL);
@@ -961,6 +978,18 @@
 	    OVERhit++;
 	    OVERsize += len;
 	}
+
+        if (HasNotReplied) {
+            if (ac > 1)
+                Reply("%d Overview information for %s follows\r\n",
+                      NNTP_OK_OVER, av[1]);
+            else
+                Reply("%d Overview information for %d follows\r\n",
+                      NNTP_OK_OVER, ARTnumber);
+            fflush(stdout);
+            HasNotReplied = false;
+        }
+
 	vector = overview_split(data, len, NULL, vector);
 	r = overview_getheader(vector, OVERVIEW_MESSAGE_ID, OVextra);
 	cache_add(HashMessageID(r), token);
@@ -1002,13 +1031,23 @@
     if (vector)
         cvector_free(vector);
 
-    if(useIOb) {
-	SendIOb(".\r\n", 3);
-	PushIOb();
+    if (HasNotReplied) {
+        if (ac > 1)
+            Reply("%d No articles in %s\r\n",
+                  xover ? NNTP_FAIL_NO_ARTICLE : NNTP_FAIL_BAD_ARTICLE, av[1]);
+        else
+            Reply("%d Current article number %d is invalid\r\n",
+                  NNTP_FAIL_NO_ARTICLE, ARTnumber);
     } else {
-	SendIOv(".\r\n", 3);
-	PushIOv();
+        if(useIOb) {
+            SendIOb(".\r\n", 3);
+            PushIOb();
+        } else {
+            SendIOv(".\r\n", 3);
+            PushIOv();
+        }
     }
+
     if (PERMaccessconf->nnrpdoverstats)
 	gettimeofday(&stv, NULL);
     OVclosesearch(handle);
@@ -1089,10 +1128,7 @@
 
 	/* Range specified. */
 	if (!CMDgetrange(ac - 1, av + 1, &range, &DidReply)) {
-	    if (!DidReply) {
-		Reply("%d %s no matches follow (range)\r\n",
-		      NNTP_OK_HEAD, header);
-		Printf(".\r\n");
+	    if (DidReply) {
 		break;
 	    }
 	}

Modified: nnrpd.c
===================================================================
--- nnrpd.c	2008-09-04 20:36:11 UTC (rev 8002)
+++ nnrpd.c	2008-09-05 19:13:28 UTC (rev 8003)
@@ -138,6 +138,8 @@
 	"wildmat [yy]yymmdd hhmmss [GMT]" },
     {	"NEXT",		CMDnextlast,	true,	1,	1,
 	NULL },
+    {   "OVER",         CMDover,        true,   1,      2,
+        "[range]" },
     {	"POST",		CMDpost,	true,	1,	1,
 	NULL },
     {   "QUIT",         CMDquit,        false,  1,      1,
@@ -156,7 +158,7 @@
 	"[group_pattern]" },
     {	"XHDR",		CMDpat,		true,	2,	3,
 	"header [range|messageID]" },
-    {	"XOVER",	CMDxover,	true,	1,	2,
+    {	"XOVER",	CMDover,	true,	1,	2,
 	"[range]" },
     {	"XPAT",		CMDpat,		true,	4,	CMDany,
 	"header range|messageID pat [morepat...]" },

Modified: nnrpd.h
===================================================================
--- nnrpd.h	2008-09-04 20:36:11 UTC (rev 8002)
+++ nnrpd.h	2008-09-05 19:13:28 UTC (rev 8003)
@@ -182,11 +182,11 @@
 EXTERN long	ARTget;
 EXTERN long	ARTgettime;
 EXTERN long	ARTgetsize;
-EXTERN long	OVERcount;	/* number of XOVER commands */
-EXTERN long	OVERhit;	/* number of XOVER records found in .overview */
-EXTERN long	OVERmiss;	/* number of XOVER records found in articles */
-EXTERN long	OVERtime;	/* number of ms spent sending XOVER data */
-EXTERN long	OVERsize;	/* number of bytes of XOVER data sent	*/
+EXTERN long	OVERcount;	/* number of (X)OVER commands */
+EXTERN long	OVERhit;	/* number of (X)OVER records found in .overview */
+EXTERN long	OVERmiss;	/* number of (X)OVER records found in articles */
+EXTERN long	OVERtime;	/* number of ms spent sending (X)OVER data */
+EXTERN long	OVERsize;	/* number of bytes of (X)OVER data sent	*/
 EXTERN long	OVERdbz;	/* number of ms spent reading dbz data	*/
 EXTERN long	OVERseek;	/* number of ms spent seeking history	*/
 EXTERN long	OVERget;	/* number of ms spent reading history	*/
@@ -243,10 +243,10 @@
 extern void		CMDnewgroups (int ac, char** av);
 extern void		CMDnewnews   (int ac, char** av);
 extern void		CMDnextlast  (int ac, char** av);
+extern void             CMDover      (int ac, char** av);
 extern void		CMDpost      (int ac, char** av);
 extern void             CMDquit      (int ac, char** av);
 extern void		CMDxgtitle   (int ac, char** av);
-extern void		CMDxover     (int ac, char** av);
 extern void		CMDpat       (int ac, char** av);
 extern void		CMD_unimp    (int ac, char** av);
 #ifdef HAVE_SSL



More information about the inn-committers mailing list