* header.c - header functions plus some other goodies
* TAKEN FROM BNEWS 2.10 6/24/83
static char *SccsId
= "@(#)header.c 2.20 6/24/83";
static char *RCSid
= "$Header: bnewshead.c,v 1.7.0.1 85/03/06 20:03:00 notes Rel $";
#include "parms.h" /* from notes */
#include "structs.h" /* ditto */
static char bfr
[PATHLEN
]; /* header buffer */
* Read header from file fp into *hp. If wholething is FALSE,
* it's an incremental read, otherwise start from scratch.
* Return (FILE *) if header okay, else NULL.
newsheader (hp
, fp
, wholething
)
register struct hbuf
*hp
;
if (wholething
) /* from scratch */
bclear ((char *) hp
, sizeof (*hp
));
* Check that it's a B news style header.
if (((hfgets (bfr
, PATHLEN
, fp
) != NULL
&&
*bfr
>= 'A' && *bfr
<= 'Z') && index (bfr
, ':')))
* It's not. Try A news (begins with PROTO).
* Read in an A news format article.
strncpy (hp
-> oident
, &(bfr
[1]), NAMELEN
); /* file name */
if (!nstrip (hp
-> oident
))
hfgets (hp
-> nbuf
, BUFLEN
, fp
); /* newsgroup list */
if (!nstrip (hp
-> nbuf
))
ngcat (hp
-> nbuf
); /* trailing delim */
hfgets (hp
-> path
, PATHLEN
, fp
); /* source path */
if (!nstrip (hp
-> path
))
hfgets (hp
-> subdate
, DATELEN
, fp
); /* date */
if (!nstrip (hp
-> subdate
))
hfgets (hp
-> title
, BUFLEN
, fp
); /* title */
if (!nstrip (hp
-> title
))
* strip off sys! from front of path.
if (strncmp (bfr
, hp
-> path
, (len
= strlen (bfr
))) == 0
&& index (NETCHRS
, hp
-> path
[len
]))
strcpy (hp
-> path
, &(hp
-> path
[len
+ 1]));
if (wholething
&& hp
-> from
[0] == '\0') /* intuit the from: */
intuitfrom (hp
); /* if wasn't there */
if (wholething
) /* Get message ID's. */
* Get header info from mail-format file.
* Return non-zero on success.
register struct hbuf
*hp
;
for (iu
= 0; iu
< NUNREC
; iu
++)
getfield (hp
-> subdate
);
getfield (hp
-> recdate
);
getfield (hp
-> expdate
);
getfield (hp
-> replyto
);
getfield (hp
-> followid
);
getfield (hp
-> followto
);
getfield (hp
-> postversion
);
getfield (hp
-> distribution
);
getfield (hp
-> organization
);
getfield (hp
-> numlines
);
hp
-> intnumlines
= atoi (hp
-> numlines
);
getfield (hp
-> keywords
);
getfield (hp
-> approved
);
case NLINE1
: /* notes-specific */
case NLINE2
: /* notes-specific */
* Only believe a relay version if it's the first
* line, otherwise it probably got passed through
getfield (hp
-> relayversion
);
hp
-> unrec
[unreccnt
] = malloc (strlen (bfr
) + 1);
strcpy (hp
-> unrec
[unreccnt
], bfr
);
} while ((i
= type (hfgets (bfr
, LBUFLEN
, fp
))) > 0);
printf ("Bizzaro header line: %s\n", bfr
);
* Check to see if the REQUIRED headers are present. If so, return
* that we found a message. Otherwise barf.
if ((hp
-> from
[0] || hp
-> path
[0]) &&
(hp
-> ident
[0] || hp
-> oident
[0]))
* There was no From: line in the message (because it was generated by
* an old news program). Guess what it should have been and create it.
register struct hbuf
*hp
;
/* Check for an existing Internet address on the end. */
strcpy (hp
-> from
, user
);
/* @ signs are illegal except for the biggie, so */
host
= index (tp
, '!') + 1;
sprintf (hp
-> from
, "%s@%s.%s", user
, host
, DFLTDOMAIN
);
fullname
= index (hp
-> path
, '(');
strcat (hp
-> from
, fullname
);
* If the message has only one of ident/oident, guess what
* the other one should be and fill them both in.
register struct hbuf
*hp
;
if (hp
-> ident
[0] == '\0' && hp
-> oident
[0] != '\0')
strcpy (lbuf
, hp
-> oident
);
strcpy (hp
-> ident
, hp
-> oident
);
* It may seem strange that we hardwire ".UUCP" in
* here instead of DFLTDOMAIN. However, we are trying
* to guess what the domain was on the posting system,
* not the local system. Since we don't really know
* what the posting system does, we just go with the
* majority - almost everyone will be a .UUCP if they
* didn't fill in their Message-ID.
sprintf (hp
-> ident
, "<%s@%s%s>", p
, lbuf
, ".UUCP");
if (hp
-> oident
[0] == '\0' && hp
-> ident
[0] != '\0')
strcpy (lbuf
, hp
-> ident
);
strcpy (hp
-> oident
, hp
-> ident
);
sprintf (hp
-> oident
, "%s.%s", p
, lbuf
+ 1);
* Get the given field of a header (char * parm) from bfr, but only
* if there's something actually there (after the colon). Don't
* bother if we already have an entry for this field.
for (ptr
= index (bfr
, ':'); isspace (*++ptr
);)
* Determine the type of the header
#define its(type) (!strncmp(ptr,type,strlen(type)))
if (!isalpha (*ptr
) && strncmp (ptr
, "From ", 5))
colon
= index (ptr
, ':');
space
= index (ptr
, ' ');
if (!colon
|| colon
+ 1 != space
)
if (index (ptr
, '@') && !index (ptr
, '!') && seenrelay
)
if (its ("Newsgroups: "))
if (its ("Subject: ") || its ("Title: "))
if (its ("Posted: ") || its ("Date: "))
if (its ("Date-Received: ") || its ("Received: "))
if (its ("Article-I.D.: "))
if (its ("Message-ID: "))
if (its ("References: "))
if (its ("Followup-To: "))
if (its ("Posting-Version: "))
if (its ("Relay-Version: "))
if (its ("Distribution: "))
if (its ("Organization: "))
* Set nc bytes, starting at cp, to zero.
* Strip trailing newlines, blanks, and tabs from 's'.
* Return TRUE if newline was found, else FALSE.
while (--p
>= s
&& (*p
== '\n' || *p
== ' ' || *p
== '\t'));
* Append NGDELIM to string.
* Return a compact representation of the person who posted the given
* message. A sender or internet name will be used, otherwise
* the last part of the path is used preceeded by an optional ".."
static char resultbuf
[BUFLEN
];
* This only happens for articles posted by old news software
* in non-internet format.
strcpy (pathbuf
, hp
-> path
);
p
= index (pathbuf
, ' ');
*p
= '\0'; /* Chop off trailing " (name)" */
r
= rindex (pathbuf
, '!');
while (r
> pathbuf
&& *--r
!= '!')
strcpy (resultbuf
, "..!");
* hfgets is like fgets, but deals with continuation lines.
* It also ensures that even if a line that is too long is
* received, the remainder of the line is thrown away
* instead of treated like a second line.
char *hfgets (buf
, len
, fp
)
cp
= fgets (buf
, len
, fp
);
* Line too long - part read didn't fit into a newline
while ((c
= getc (fp
)) != '\n' && c
!= EOF
)
*--tp
= '\0'; /* clobber newline */
while ((c
= getc (fp
)) == ' ' || c
== '\t') /* continuation */
while ((c
= getc (fp
)) == ' ' || c
== '\t') /* skip white space */
while ((c
= getc (fp
)) != '\n' && c
!= EOF
)
ungetc (c
, fp
); /* push back char */