Article View: net.notes
Article #22Re: Bug in newsinput.c - (nf)
From: utzoodecvaxpur-eeuiucdcsessick
Date: Fri, 30 Jul 1982 10:28
Date: Fri, 30 Jul 1982 10:28
485 lines
16095 bytes
16095 bytes
#R:cmcl2:-808200:uiucdcs:23300010:004:15212
uiucdcs!essick Jul 30 09:48:00 1982
As promised, here is a version of newsinput that handles
(maybe not perfectly, but a lot closer) the various problems that
were there before. In particular, Malcolm Slaney was kind enough to
provide the code to parse the "Re:" prefixes of news articles. The
problem where articles having both "Re:" and "- (nf)" has also been
taken care of.
To use this new routine, one has to modify "tsearch.c", a copy
of which is in another response. The makefile should also be modified
so that "tsearch.o" is included as a dependency for newsinput and
is loaded with newsinput.
This version seems to be working for me.
Ray Essick
- - - - - - -
#include "structs.h"
#include "globs.h"
#include "newsgate.h"
/*
* newsinput.c
*
* This program will accept an article according the the
* 'A' protocol for news(I). The article will then be inserted in
* the notefile which matches the newsgroup.
* The program will not insert an article into multiple newsgroups!
*
* Modified April 1982:
* The newer version is somewhat more streamlined. It still uses the
* A protocol for intersystem transfer, but since the B news release
* still accepts this stuff, I don't mind. I also am too lazy to bother
* rewriting the header parser to grab the B format. ( someone could
* probably figure a way to simply steal the code out of B news and
* deposit it here, but I have other things I would rather do)
*
* So, the other major difference in the new version is that if the
* title is of the form:
* some title - (nf)
* (or if the suffix is "- (nf)"
* we decide that it has been generated by notesfiles. This means that
* we are allowed to skip text up to a # and then we have a special
* ALMOST generic notesfile format. The header information is
* slightly different.
* see canon.h for the new format examples
*
* Original Coding: Ray Essick Feb 1982
* Modified extensively: Ray Essick April 1982
* Modified to add some neat things
* Malcolm Slaney July 1982
* added code to catch misformed articles
* Ray Essick July 27, 1982
*
*/
main (argc, argv)
char **argv;
{
struct io_f io;
char title[TITLEN + 40]; /* title */
char nf[NNLEN]; /* the notefile */
char fname[WDLEN]; /* hold scratch file name */
char ngroup[100]; /* newsgroup name */
char fromsys[SYSSZ],
origsys[SYSSZ];
char *p,
*q,
*r;
char *suffix;
int count,
atcount, /* count ARPA hosts */
status;
int c;
int i,
j,
stat,
length, /* of title */
notenum;
struct note_f note;
struct note_f note2;
struct auth_f auth;
long newsseq;
struct id_f respid;
struct when_f entered,
whentime;
struct id_f newsid;
char line[WDLEN + 1]; /* scratch */
struct daddr_f where;
FILE * rawnews; /* raw news read from here */
FILE * scr; /* scratch file for holding article */
#include "main.i" /* common init code and such */
rawnews = stdin; /* read from the right file */
/* Parse the header
*/
if (getc (rawnews) != 'A')
{
fprintf (stderr, "Article not protocol A\n");
exit (BAD); /* wrong protocol */
}
fscanf (rawnews, "%[^.].%ld", origsys, &newsseq);
while (getc (rawnews) != '\n'); /* skip to next line */
/* grab the 'newsgroup'
*/
for (i = 0; (i < 99) && ((c = getc (rawnews)) != '\n') && (c != ','); i++)
ngroup[i] = c;
ngroup[++i] = '\0'; /* null terminate */
if (c != '\n')
while (getc (rawnews) != '\n'); /* skip to eol */
/* now the author line
*/
for (i = 0; (i < WDLEN) && ((c = getc (rawnews)) != '\n'); i++)
line[i] = c; /* grab the whole line */
line[i] = '\0'; /* terminate it */
if (c != '\n')
while (getc (rawnews) != '\n'); /* make sure is end */
j = i; /* start at rhs */
while (j && (line[j] != '!') && (line[j] != ':') && (line[j] != '.'))
j--; /* back to sys */
atcount = 0; /* count ARPA hosts parsed */
for (i = 0, j++; (i < NAMESZ); i++)
if ((auth.aname[i] = line[j + i]) == '@' && atcount++)
{
auth.aname[i] = '\0';
break; /* only parse 1 ARPA host */
}
else
if (auth.aname[i] == ' ')
{
auth.aname[i] = '\0'; /* null terminate */
break; /* and get out of here */
}
else
if (auth.aname[i] == 0)
break;
/* build the from system */
for (i = 0; (i < SYSSZ - 1) && line[i] != '!' && line[i] != ':' && line[i] != '.'; i++)
fromsys[i] = line[i];
fromsys[i] = '\0';
/* get the date written
*/
i = 0;
while ((line[i++] = getc (rawnews)) != '\n');
line[i] = '\0'; /* build this line */
getdate (line, &entered); /* and grab it */
/* now the title line
*/
for (i = 0; (i < TITLEN + 39) && ((c = getc (rawnews)) != '\n'); i++)
title[i] = c;
title[i] = '\0'; /* null terminator there */
if (c != '\n')
while (getc (rawnews) != '\n'); /* skip eol */
/* The header is now parsed, all left is text. Check existence
* of the notesfile, permission to write and other things like that
*/
newsgroup (ngroup, nf, NEWSNF); /* alias the bugger */
if (init (&io, nf) < 0) /* well is it there? */
{
printf ("No notesfile: %s\n", nf);
#ifdef NOSUCHWARN
sprintf (line, "Notesfile: %s, newsgroup %s\n", ngroup, nf);
nfcomment (NOSUCHWARN, line, "unknown newsgroup", 0, 0);
#endif
#ifdef NEWNEWS /* save those new ones */
/* this code courtesy of malcolm... */
printf ("Inserting into nfmaint\n");
sprintf (title, "New Newsgroup: %s", nf); /* Blow away old title */
strcpy (nf, NEWNEWS); /* Change the newsgroup */
if (init (&io, nf) < 0)
exit (BAD); /* Give UP */
printf ("Open of %s suceeded\n", nf);
#else
exit (BAD); /* apparently not */
#endif
}
if ((io.descr.d_stat & NETWRKD) == 0) /* networked ? */
{
printf ("Notesfile %s is not networked\n", nf);
exit (BAD);
}
r = q = title;
while (*r) /* look for last '-' */
{
if (*r == '-')
q = r; /* this is new last */
r++; /* on to the next */
}
suffix = q; /* save the pointer for possible later use */
/* like misformed articles with "- (nf)" */
length = q - title; /* non-nulls before '-' */
if (streq (q, NFSUFFIX) != 0 &&
streq (q, OLDSUFFIX) != 0)
/* so is not nf generated */
{
/*
* we come back up to here if the article had the notesfile
* suffix and was not properly formatted.
* This is a stopgap measure due to the fact that I misdesigned
* the system so that notes used a right associative rule
* to determine its articles, while news programs used a
* left associative rule. Oh well.
* - Ray Essick July 27, 1982
*/
badform: /* come here if no "#" in a "- (nf)" article */
getperms (&io, 1, origsys);
if (allow (&io, WRITOK) == 0)
{
printf ("System %s not allowed to write notes\n", origsys);
exit (BAD);
}
strmove (origsys, newsid.sys); /* build uniq id */
newsid.uniqid = (-newsseq * 100) - 1;
/* is not there yet */
strmove (origsys, note.n_id.sys);
note.n_id.uniqid = (-100 * newsseq); /* build the note descriptor */
copydate (&entered, ¬e.n_date);
strmove (fromsys, note.n_from);
stat = FRMNEWS; /* came from news system */
i = 0; /* fix up the title */
while (title[i++]); /* get to the end */
for (i--; i < TITLEN; i++)
title[i] = ' '; /* space pad */
lock (&io, 'n');
if ((notenum = chknote (&io, ¬e.n_id, ¬e2)) == 0)
{
if (!strncmp (title, "Re:", 3)) /* see if a "followup" */
{
p = title;
do
{
p + = 3;
while (*p == ' ')
p++; /* Skip Spaces */
} while (!strncmp (p, "Re:", 3)); /* get all re's */
strcpy (io.xstring, p);
notenum = findtitle (&io, io.descr.d_nnote);
if (notenum > 0 && !chkresp (&io, &newsid, ¬e2, notenum))
{
pagein (&io, rawnews, &where);
gettime (&whentime);
putresp (&io, &where, stat, notenum, &entered, &auth,
¬e, NOLOCKIT, &newsid, NOADDID, fromsys, ADDTIME,
&whentime);
}
else
if (notenum < 1)
{
pagein (&io, rawnews, &where);
notenum = putnote (&io, &where, title, stat, ¬e, &auth,
NOPOLICY, NOLOCKIT, NOADDID, fromsys, ADDTIME);
io.nnotrcvd++; /* count as networked in */
}
else
{
printf ("Duplicate Response handed back by news\n");
}
}
else
{
pagein (&io, rawnews, &where);
notenum = putnote (&io, &where, title, stat, ¬e, &auth,
NOPOLICY, NOLOCKIT, NOADDID, fromsys, ADDTIME);
io.nnotrcvd++; /* count as networked in */
}
}
else
if (note2.n_stat & ORPHND) /* replace foste parent */
{
pagein (&io, rawnews, ¬e2.n_addr); /* collect text */
gettime (¬e2.n_rcvd); /* current tod */
gettime (¬e2.n_lmod); /* last touched */
copyauth (&auth, ¬e2.n_auth); /* fill in the author */
note2.n_stat | = FRMNEWS; /* brand it */
for (i = 0; i < TITLEN; i++)
note2.ntitle[i] = title[i]; /* move new title */
copydate (&entered, ¬e2.n_date); /* written date */
strcpy (note2.n_from, fromsys); /* and who gave it to us */
putnrec (&io, notenum, ¬e2); /* and replace */
}
else
{
printf ("Duplicate news article received\n");
}
unlock (&io, 'n');
}
else
{ /* nf generated article */
sprintf (fname, "/tmp/nfn%d", getpid ()); /* generate name */
scr = fopen (fname, "w"); /* open scratch file */
while ((c = getc (rawnews)) != '#' && c != EOF) /* find start */
if (scr != NULL)
putc (c, scr); /* hold it in the scratch file */
if (c == EOF)
{
fclose (scr); /* flush what is there */
if ((rawnews = fopen (fname, "r")) == NULL)
{
printf ("Article lost in file system: %s\n", fname);
unlink (fname); /* remove the file */
closenf (&io); /* close the notesfile */
exit (BAD);
}
*--suffix = '\0'; /* remove " - (nf)" suffix */
unlink (fname); /* only link is the file descriptor */
goto badform; /* reparse as a news article */
}
fclose (scr); /* close and */
unlink (fname); /* toss the scratch file */
switch (getc (rawnews))
{
case 'N': /* base note coming through news */
if (fscanf (rawnews, ":%[^:]:%ld:%o:%d", note.n_id.sys,
¬e.n_id.uniqid, &status, &count) != 4)
goto toobad; /* bad form */
while (getc (rawnews) != '\n'); /* skip eol */
for (i = length; i < TITLEN; i++)
title[i] = ' '; /* space fill */
while ((c = getc (rawnews)) != '!'); /* skip sys name, got elsewhere */
for (i = 0; (i < NAMESZ - 1) && ((c = getc (rawnews)) != ' '); i++)
auth.aname[i] = c; /* get the author */
i = 0;
while ((line[i] = getc (rawnews)) != '\n');
/* grab date */
getdate (line, ¬e.n_date); /* use secret decoder ring */
while (getc (rawnews) != '\n'); /* loop in case trash on line */
/* in theory this line is empty */
getperms (&io, 1, note.n_id.sys); /* see if he's allowed */
if (allow (&io, WRITOK) == 0) /* not a chance */
{
closenf (&io);
exit (BAD);
}
lock (&io, 'n'); /* get exclusive mining rights */
if ((notenum = chknote (&io, ¬e.n_id, ¬e2)) == 0)
/* is it there? */
{
pagein (&io, rawnews, &where); /* grab text */
status | = FRMNEWS; /* came through news! */
strmove (fromsys, note.n_from);
putnote (&io, &where, title, status, ¬e, &auth, NOPOLICY,
NOLOCKIT, NOADDID, fromsys, ADDTIME);
io.nnotrcvd++; /* count it */
}
else
if ((note2.n_stat & ORPHND) && NOT (status & ORPHND))
{ /* extant is orphan, new isnt */
pagein (&io, rawnews, ¬e2.n_addr);
/* grab text */
gettime (¬e2.n_rcvd);
gettime (¬e2.n_lmod); /* time stamp it */
copyauth (&auth, ¬e2.n_auth);
/* put correct author */
note2.n_stat = status + FRMNEWS;
/* correct status */
for (i = 0; i < TITLEN; i++)
note2.ntitle[i] = title[i];
copydate (&entered, ¬e2.n_date);
strmove (fromsys, note2.n_from);
putnrec (&io, notenum, ¬e2); /* and replace */
}
else
{ /* duplicate */
printf ("Duplicate note handed back by news\n");
}
unlock (&io, 'n'); /* open to the rest of world */
break;
case 'R': /* response coming through news */
if (fscanf (rawnews, ":%[^:]:%ld:%[^:]:%ld:%o:%d", note.n_id.sys,
¬e.n_id.uniqid, respid.sys, &respid.uniqid, &status, &count) != 6)
goto toobad; /* bad form */
while (getc (rawnews) != '\n'); /* skip eol */
getperms (&io, 1, respid.sys); /* see if he's allowed */
if (allow (&io, RESPOK) == 0) /* not a chance */
{
closenf (&io);
exit (BAD);
}
while ((c = getc (rawnews)) != '!'); /* skip sys name, got elsewhere */
for (i = 0; (i < NAMESZ - 1) && ((c = getc (rawnews)) != ' '); i++)
auth.aname[i] = c; /* get the author */
i = 0;
while ((line[i] = getc (rawnews)) != '\n');
/* grab date */
getdate (line, &entered); /* use secret decoder ring */
while (getc (rawnews) != '\n'); /* loop in case trash on line */
/* in theory this line is empty */
lock (&io, 'n'); /* lock it up */
notenum = chknote (&io, ¬e.n_id, ¬e2);
if (notenum == 0) /* build foster parent */
{
printf ("Orphaned response handed in by news\n");
strmove (fromsys, note.n_from);
note.n_nresp = 0;
note.n_auth.aid = ANONUID;
strcpy (note.n_auth.aname, "Unknown");
copydate (&entered, ¬e.n_date);
gettime (&whentime); /* get current time */
status = ORPHND + FRMNEWS; /* combo there */
for (i = 0, p = "Orphaned Response"; (i < TITLEN) && *p; p++, i++)
note.ntitle[i] = *p;
for (; i < TITLEN; i++)
note.ntitle[i] = ' ';
/* pad */
where.addr = 0; /* no text */
notenum = putnote (&io, &where, note.ntitle, status,
¬e, ¬e.n_auth, NOPOLICY, NOLOCKIT, NOADDID, fromsys, ADDTIME);
io.norphans++; /* census of orphans */
getnrec (&io, notenum, ¬e2); /* get good one */
}
if (chkresp (&io, &respid, ¬e2, notenum) == 0)
{ /* none, insert it */
status | = FRMNEWS;
pagein (&io, rawnews, &where);
putresp (&io, &where, status, notenum, &entered, &auth,
¬e, NOLOCKIT, &respid, NOADDID, fromsys, ADDTIME, &whentime);
io.nrsprcvd++; /* count him in */
}
else
{
printf ("Duplicate response handed back by news\n");
}
unlock (&io, 'n');
break;
default: /* bad news coming through news */
toobad: /* label for bad format jumps */
printf ("Some sort of failure caused jump to toobad\n");
closenf (&io);
exit (BAD);
}
} /* end of nf coming back in */
lock (&io, 'n');
getdscr (&io, &io.descr);
io.descr.netwrkins++; /* count as net in */
putdscr (&io, &io.descr);
unlock (&io, 'n');
finish (&io);
exit (GOOD);
}
Technical Details
Message-ID:
<bnews.uiucdcs.297>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
From: utzoo!decvax!pur-ee!uiucdcs!essick Newsgroups: net.notes Title: Re: Bug in newsinput.c - (nf) Article-I.D.: uiucdcs.297 Posted: Fri Jul 30 10:28:39 1982 Received: Sat Jul 31 05:17:52 1982 Subject: Re: Bug in newsinput.c - (nf) Date: Fri, 30 Jul 1982 10:28:39 +0000 Message-ID: <bnews.uiucdcs.297>