[news.software.anu-news] "Superseding items not forwarded" bug -- analysis and quick fix

gih900@UUNET.UU.NET (Geoff Huston) (09/21/89)

I had the following mail from Jamie Hanrahan, regarding problems with
processing the Supersedes: header.... (i.e. it worked on the local system, but
such items are never propagated to downstream sites)
     
Jamie's description of the problem is correct:
     
>The problem is in NEWSADD.C, routine mail_add_item().  The "supersedes"
>processing is done before the "distribution" processing.  Distribution
>is handled by calling sys_remote_send, which needs the filename of the
>item to be distributed in itm_fname.  But the supersedes logic, which
>runs prior to the call to sys_remote_send, calls del_id().  del_id()
>in turn calls do_oitem().  And do_oitem overwrites itm_fname (presumably
>with the file name of the item being deleted).
     
I had found a similar problem with del_id(), but missed the call into
do_oitem() which also alters the global variable "itm_fname:
     
>So by the time we call sys_remote_send, the itm_fname value we need is
>gone -- it's been replaced with the file name of the deleted item, and
>when sys_remote_send does a stat on it, it finds that the file is missing,
>and simply returns.
>
>I have a "quick hack" fix, which seems to work.  We add a temporary string
>variable within the block that handles supersedes, copy itm_fname into this
>string at the beginning of the block, and restore itm_fname at the end.
     
This fix seems to be the appropriate one
     
>A better fix (it seems to me) would be to move the supersedes processing
>so that it follows the distribution processing, but I'm not sure how to do
>this.  I don't understand why the supersedes processing is controlled by
>the test of (*cre_grp), and so I'm not sure if I can simply move the
>supersedes block to later in mail_add_item() (seems to me it should be
>just about the last thing that's done) without breaking something else.
     
The location of the block of code is positioned within the following top level
algorithm:
     
	if the newsgroups of the incoming message matches at least one locally
	   defined newsgroup then
     
	  if the item was added successfully into the local database then
     
	    if the item has a supersedes: header delete the referenced item
     
     
	the actual code is slightly different:
     
     
	if (*cre_grp)  (i.e. there IS a newsgroup match)
     
	  if (do_new_item() returns an error then
	     process the error
     
	  else if the item has a supercedes: header then
	     delete the superseded item
     
     
If the block of code is moved then you lose the context of only acting on the
supersedes: header locally only if the new item was sucessfuly added to the
local database.
     
I have made 1 change to Janie's code - the variable save_itm_fname is extended
to 256 chars to allow maximal sized file names
     
NEWSADD.C:
     
    else if (*itm[SUPERSEDES]) {
      char *id,
           *ide,
           *mail_sender = itm[SENDER],
           net_sender[132],			/* changed trailing ; to , */
	   save_itm_fname[256];			/* new */
     
      strcpy(save_itm_fname, itm_fname);	/* new */
      if ((id = strchr(itm[SUPERSEDES],'<'))
            && (ide = strchr(itm[SUPERSEDES],'>'))) {
        *(ide + 1) = '\0';
        if (!*mail_sender) mail_sender = itm[FROM];
        if (ide = strchr(mail_sender,'<')) {
          strcpy(net_sender,++ide);
          if (ide = strchr(net_sender,'>')) *ide = '\0';
          if (ide = strchr(net_sender,'\n')) *ide = '\0';
          }
        else {
          char *cp = net_sender,
               *cp1 = mail_sender;
     
          while (isspace(*cp1)) cp1++;
          while ((*cp1) && (!isspace(*cp1))) *cp++ = *cp1++;
          *cp = '\0';
          if (cp = strchr(net_sender,'(')) *cp = '\0';
          }
        if (!del_id(id,net_sender)) hist_add(id);
        printf(" (Supersedes %s)",itm[SUPERSEDES]);
        }
      strcpy(itm_fname, save_itm_fname);	/* new */
      }
    }
  if (*itm_fname)
 sys_remote_send(itm[PATH],itm[NEWSGROUPS],itm[DISTRIBUTION],itm_fname,itm[MESSA
 GE_ID],!mod_add);
     
     
     
my thanks to Jamie for this work - its greatly appreciated
     
     
Geoff Huston
gih900@csc.anu.oz.au