INN commit: trunk/expire (makehistory.c)
INN Commit
Russ_Allbery at isc.org
Mon Sep 8 20:44:11 UTC 2008
Date: Monday, September 8, 2008 @ 13:44:10
Author: iulius
Revision: 8021
Correctly generate metadata information when rebuilding the overview
database.
Modified:
trunk/expire/makehistory.c
---------------+
makehistory.c | 179 ++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 124 insertions(+), 55 deletions(-)
Modified: makehistory.c
===================================================================
--- makehistory.c 2008-09-07 18:14:44 UTC (rev 8020)
+++ makehistory.c 2008-09-08 20:44:10 UTC (rev 8021)
@@ -72,19 +72,23 @@
bool WriteStdout = false;
/* Misc variables needed for the overview creation code. */
+static char BYTES[] = "Bytes";
+static char DATE[] = "Date";
+static char EXPIRES[] = "Expires";
+static char LINES[] = "Lines";
static char MESSAGEID[] = "Message-ID";
-static char EXPIRES[] = "Expires";
-static char DATE[] = "Date";
static char XREF[] = "Xref";
static ARTOVERFIELD *ARTfields; /* overview fields listed in overview.fmt */
static size_t ARTfieldsize;
-static ARTOVERFIELD *Datep = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD *Msgidp = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD *Expp = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD *Xrefp = (ARTOVERFIELD *)NULL;
-static ARTOVERFIELD *Missfields; /* header fields not listed in
- overview.fmt, but ones that we need
- (e.g. message-id */
+static ARTOVERFIELD *Bytesp = (ARTOVERFIELD *)NULL;
+static ARTOVERFIELD *Datep = (ARTOVERFIELD *)NULL;
+static ARTOVERFIELD *Expp = (ARTOVERFIELD *)NULL;
+static ARTOVERFIELD *Linesp = (ARTOVERFIELD *)NULL;
+static ARTOVERFIELD *Msgidp = (ARTOVERFIELD *)NULL;
+static ARTOVERFIELD *Xrefp = (ARTOVERFIELD *)NULL;
+static ARTOVERFIELD *Missfields; /* Header fields not listed in
+ * overview.fmt, but ones that we need
+ * (e.g. Message-ID:). */
static size_t Missfieldsize = 0;
static void OverAddAllNewsgroups(void);
@@ -426,59 +430,89 @@
fp->Header = (char *)NULL;
fp->HasHeader = false;
fp->HeaderLength = 0;
- if (strncasecmp(buff, DATE, strlen(DATE)) == 0)
- Datep = fp;
- if (strncasecmp(buff, MESSAGEID, strlen(MESSAGEID)) == 0)
- Msgidp = fp;
- if (strncasecmp(buff, EXPIRES, strlen(EXPIRES)) == 0)
- Expp = fp;
- if (strncasecmp(buff, XREF, strlen(XREF)) == 0) {
- Xrefp = fp;
- foundxreffull = fp->NeedHeadername;
+ /* We need to keep the value of fp for :bytes and :lines
+ * because we will need them afterwards; we will then not
+ * have to compare fp->Headername to both "Bytes" and "Lines"
+ * for each fp. */
+ if (strncasecmp(buff, BYTES, strlen(BYTES)) == 0)
+ Bytesp = fp;
+ if (strncasecmp(buff, DATE, strlen(DATE)) == 0)
+ Datep = fp;
+ if (strncasecmp(buff, EXPIRES, strlen(EXPIRES)) == 0)
+ Expp = fp;
+ if (strncasecmp(buff, LINES, strlen(LINES)) == 0)
+ Linesp = fp;
+ if (strncasecmp(buff, MESSAGEID, strlen(MESSAGEID)) == 0)
+ Msgidp = fp;
+ if (strncasecmp(buff, XREF, strlen(XREF)) == 0) {
+ Xrefp = fp;
+ foundxreffull = fp->NeedHeadername;
}
fp++;
}
ARTfieldsize = fp - ARTfields;
fclose(F);
}
- if (Msgidp == (ARTOVERFIELD *)NULL)
- Missfieldsize++;
+ if (Bytesp == (ARTOVERFIELD *)NULL)
+ Missfieldsize++;
if (Datep == (ARTOVERFIELD *)NULL)
- Missfieldsize++;
+ Missfieldsize++;
if (Expp == (ARTOVERFIELD *)NULL)
+ Missfieldsize++;
+ if (Linesp == (ARTOVERFIELD *)NULL)
+ Missfieldsize++;
+ if (Msgidp == (ARTOVERFIELD *)NULL)
Missfieldsize++;
if (Overview && (Xrefp == (ARTOVERFIELD *)NULL || !foundxreffull))
die("Xref:full must be included in %s", SchemaPath);
if (Missfieldsize > 0) {
Missfields = xmalloc(Missfieldsize * sizeof(ARTOVERFIELD));
fp = Missfields;
- if (Msgidp == (ARTOVERFIELD *)NULL) {
- fp->NeedHeadername = false;
- fp->Headername = xstrdup(MESSAGEID);
- fp->HeadernameLength = strlen(MESSAGEID);
- fp->Header = (char *)NULL;
- fp->HasHeader = false;
- fp->HeaderLength = 0;
- Msgidp = fp++;
- }
- if (Datep == (ARTOVERFIELD *)NULL) {
- fp->NeedHeadername = false;
- fp->Headername = xstrdup(DATE);
- fp->HeadernameLength = strlen(DATE);
- fp->Header = (char *)NULL;
- fp->HasHeader = false;
- fp->HeaderLength = 0;
- Datep = fp++;
- }
- if (Expp == (ARTOVERFIELD *)NULL) {
- fp->NeedHeadername = false;
- fp->Headername = xstrdup(EXPIRES);
- fp->HeadernameLength = strlen(EXPIRES);
- fp->Header = (char *)NULL;
- fp->HasHeader = false;
- fp->HeaderLength = 0;
- Expp = fp++;
- }
+ if (Bytesp == (ARTOVERFIELD *)NULL) {
+ fp->NeedHeadername = false;
+ fp->Headername = xstrdup(BYTES);
+ fp->HeadernameLength = strlen(BYTES);
+ fp->Header = (char *)NULL;
+ fp->HasHeader = false;
+ fp->HeaderLength = 0;
+ Bytesp = fp++;
+ }
+ if (Datep == (ARTOVERFIELD *)NULL) {
+ fp->NeedHeadername = false;
+ fp->Headername = xstrdup(DATE);
+ fp->HeadernameLength = strlen(DATE);
+ fp->Header = (char *)NULL;
+ fp->HasHeader = false;
+ fp->HeaderLength = 0;
+ Datep = fp++;
+ }
+ if (Expp == (ARTOVERFIELD *)NULL) {
+ fp->NeedHeadername = false;
+ fp->Headername = xstrdup(EXPIRES);
+ fp->HeadernameLength = strlen(EXPIRES);
+ fp->Header = (char *)NULL;
+ fp->HasHeader = false;
+ fp->HeaderLength = 0;
+ Expp = fp++;
+ }
+ if (Linesp == (ARTOVERFIELD *)NULL) {
+ fp->NeedHeadername = false;
+ fp->Headername = xstrdup(LINES);
+ fp->HeadernameLength = strlen(LINES);
+ fp->Header = (char *)NULL;
+ fp->HasHeader = false;
+ fp->HeaderLength = 0;
+ Linesp = fp++;
+ }
+ if (Msgidp == (ARTOVERFIELD *)NULL) {
+ fp->NeedHeadername = false;
+ fp->Headername = xstrdup(MESSAGEID);
+ fp->HeadernameLength = strlen(MESSAGEID);
+ fp->Header = (char *)NULL;
+ fp->HasHeader = false;
+ fp->HeaderLength = 0;
+ Msgidp = fp++;
+ }
if (Overview && Xrefp == (ARTOVERFIELD *)NULL) {
fp->NeedHeadername = false;
fp->Headername = xstrdup(XREF);
@@ -510,8 +544,12 @@
time_t Expires;
time_t Posted;
char overdata[BIG_BUFFER];
- char bytes[BIG_BUFFER];
+ char Bytes[BIG_BUFFER];
+ char Lines[BIG_BUFFER];
struct artngnum ann;
+ int DotStuffedLines = 0;
+ int lines = 0;
+ bool hasCounts = false;
/* Set up place to store headers. */
for (fp = ARTfields, i = 0; i < ARTfieldsize; i++, fp++) {
@@ -553,6 +591,42 @@
}
}
+ /* Work out the real values for :bytes and :lines. */
+ if (RetrMode == RETR_ALL && (fp == Bytesp || fp == Linesp)) {
+ /* Parse the article only once. */
+ if (!hasCounts && (p = wire_findbody(art->data, art->len)) != NULL) {
+ end = art->data + art->len;
+ /* p is at the beginning of the body, if any. */
+ for (; *p != '\0';) {
+ /* p is at the beginning of a new line, if any. */
+ lines++;
+ if (*p == '.')
+ DotStuffedLines++;
+ if ((p = wire_nextline(p, end)) == NULL) {
+ /* p is at the final ".\r\n". */
+ lines--;
+ DotStuffedLines--;
+ break;
+ }
+ }
+ }
+
+ if (fp == Bytesp) {
+ /* :bytes does not count the final ".\r\n", so remove 3. */
+ snprintf(Bytes, sizeof(Bytes), "%lu",
+ (unsigned long) art->len - DotStuffedLines - 3);
+ fp->Header = Bytes;
+ fp->HeaderLength = strlen(Bytes);
+ } else {
+ snprintf(Lines, sizeof(Lines), "%lu", (unsigned long) lines);
+ fp->Header = Lines;
+ fp->HeaderLength = strlen(Lines);
+ }
+ fp->HasHeader = true;
+ hasCounts = true;
+ continue;
+ }
+
/* Now, if we have a header, find and record its length. */
if (fp->Header != NULL) {
fp->HasHeader = true;
@@ -565,13 +639,8 @@
peel off the \r\n (we're guaranteed we're dealing with
wire-format articles. */
fp->HeaderLength = p - fp->Header - 1;
- } else if (RetrMode == RETR_ALL
- && strcmp(fp->Headername, "Bytes") == 0) {
- snprintf(bytes, sizeof(bytes), "%lu", (unsigned long) art->len);
- fp->HasHeader = true;
- fp->Header = bytes;
- fp->HeaderLength = strlen(bytes);
}
+
}
if (Missfieldsize > 0) {
for (fp = Missfields, i = 0; i < Missfieldsize; i++, fp++) {
More information about the inn-committers
mailing list