/* :ts=4
 * Usenet header parsing and remembering.
 *
 *	$Log$
 */

#include <stdio.h>
#ifdef unix
# include <sys/types.h>
#endif /* unix */
#include "libc.h"
#include "news.h"
#include "control.h"
#include "case.h"
#include "fileart.h"
#include "headers.h"
#include "hdrint.h"

/*
 * Parse (assumed) RFC822/850/1036 header in "line" (ishdr(line) can
 * verify this) into "hdrs" using hdrlst set of keywords by retaining the
 * value of any matching keyword.  Keyword matching is case-insensitive.
 * If the keyword in "line" matches one in hdrlst, store the value in
 * *malloc'ed memory* (N.B.) pointed to by a member of "hdrs".
 * freeheader() will free this memory.
 */
void
hdrparse(hdrs, line, hdrlst)
register struct headers *hdrs;
char *line;
hdrlist hdrlst;				/* headers of positive utility */
{
	register struct hdrdef **hpp;
	register char *hackline = hackhybrid(line);

	for (hpp = hdrlst; *hpp != NULL; hpp++) {
		register CONST char *hdrnm = (*hpp)->hdrnm;

		if (CISTREQN(hackline, hdrnm, (int)(*hpp)->hdrlen) &&
		    (*hpp)->hdroff >= 0)	/* paranoia */
			break;
	}
	if (*hpp != NULL) {
		register char **ptrp = (char **)((char *)hdrs+(*hpp)->hdroff);

		nnfree(ptrp);		/* free prev. value in this article */
		*ptrp = strsave(skipsp(&hackline[(*hpp)->hdrlen]));
		if (*ptrp != NULL)
			trim(*ptrp);		/* cut trailing \n */
	}
	free(hackline);
}

/*
 * default missing header values
 *
 * If strsave ever returns NULL on failure, instead of exiting,
 * then the strsave calls need to check for failure.
 *
 * An article lacking a Message-ID: but possessing an (obsolete)
 * Article-I.D.: gets the transformed Article-I.D. as its Message-ID:.
 *
 * We support control message *backwards* compatibility: if no Control:
 * header exists and the newsgroup matches all.all.ctl, use the Subject:
 * as the control message.  Ugh.
 */
void
hdrdeflt(hdrs)
register struct headers *hdrs;
{
	if (hdrs->h_ngs == NULL)
		hdrs->h_ngs = strsave(JUNK);
	if (hdrs->h_distr == NULL)
		hdrs->h_distr = strsave(DEFDIST);

	if (hdrs->h_msgid == NULL && hdrs->h_artid != NULL)
		hdrs->h_msgid = str3save("<", hdrs->h_artid, ">");
	if (hdrs->h_msgid == NULL || hdrs->h_msgid[0] == '\0') {
		nnfree(&hdrs->h_msgid);
		hdrs->h_msgid = strsave(DEFMSGID);
	}

	if (hdrs->h_expiry == NULL || hdrs->h_expiry[0] == '\0') {
		nnfree(&hdrs->h_expiry);
		hdrs->h_expiry = strsave(DEFEXP);
	}

	if (hdrs->h_subj == NULL)
		hdrs->h_subj = strsave("");
	hackoldctl(hdrs);				/* NCMP */
}
