DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦3e34d1e14⟧ TextFile

    Length: 20666 (0x50ba)
    Types: TextFile
    Names: »rd_rfchdr.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« 
        └─⟦e5a54fb17⟧ 
            └─⟦this⟧ »pp-5.0/Src/submit/rd_rfchdr.c« 

TextFile

/* rd_rfchdr.c: parse 822 headers */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/rd_rfchdr.c,v 5.0 90/09/20 16:23:08 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/rd_rfchdr.c,v 5.0 90/09/20 16:23:08 pp Exp Locker: pp $
 *
 * $Log:	rd_rfchdr.c,v $
 * Revision 5.0  90/09/20  16:23:08  pp
 * rcsforce : 5.0 public release
 * 
 */



#include "head.h"
#include <isode/cmd_srch.h>
#include "q.h"
#include "tb_q.h"
#include "or.h"
#include "ap.h"

extern void err_abrt();
static int hdr_parse ();
static int hdr_type (), fillin_DomId();
static void hdr_rcv ();
static void hdr_via ();
static void hdr_check ();
static void hdr_subject ();
static void hdr_date ();
static void hdr_msgid ();
static void hdr_remcomm ();
static void hdr_trace ();
static int getline ();
static int ua_id_set_by_subject = FALSE;
static void 	hdr_x400_content_id(),
		hdr_priority(),
		hdr_x400_mts_id(),
		hdr_dl_history(),
		hdr_conversion(),
		hdr_convert_with_loss(),
		hdr_x400_received(),
		hdr_def_deliv(),
		hdr_latest_time(),
		hdr_orig_eit ();
#define ub_content_id_length	16

/* -- basic states for the state machine -- */
#define HDV_EOH			0
#define HDV_NEW			1
#define HDV_MORE		2

/* -- munge the header lines of the message -- */
#define HDR_FROM		1
#define HDR_SENDER		2
#define HDR_REPLYTO		3
#define HDR_RECEIVED		4
#define HDR_VIA			5
#define HDR_DATE		6
#define HDR_MESSAGEID		7
#define HDR_SUBJECT		8

/* rfc 1138 fields */
/* mts */
#define HDR_X400_MTS_ID		9
#define	HDR_ORIG_EIT		10
#define HDR_CONTENT_IDENTIFIER	11
#define HDR_PRIORITY		12
#define HDR_DL_HISTORY		13
#define HDR_CONVERSION		18
#define HDR_CONVERT_WITH_LOSS	14
/* mta */
#define HDR_X400_RECEIVED	15
#define HDR_DEF_DELIV		16
#define HDR_LAST_DELIV		17

static	CMD_TABLE  htbl_rfc [] = {
	"from",			HDR_FROM,
	"sender",		HDR_SENDER,
	"reply-to",		HDR_REPLYTO,
	"received",		HDR_RECEIVED,
	"via",			HDR_VIA,
	"date",			HDR_DATE,
	"message-id",		HDR_MESSAGEID,
	"subject",		HDR_SUBJECT,
/* rfc 1138 */
	"x400-mts-identifier",	HDR_X400_MTS_ID,
	"original-encoded-information-types",	HDR_ORIG_EIT,
	"content-identifier",	HDR_CONTENT_IDENTIFIER,
	"priority",		HDR_PRIORITY,
	"dl-expansion-history",	HDR_DL_HISTORY,
	"conversion",		HDR_CONVERSION,
	"conversion-with-loss",	HDR_CONVERT_WITH_LOSS,
	"x400-received",	HDR_X400_RECEIVED,
	"deferred-delivery",	HDR_DEF_DELIV,
	"latest-delivery-time",	HDR_LAST_DELIV,
	0,			0
	};


/* -- statics -- */
static	FILE			*hdr_fp;
static	time_t			read_time();
static	int			from_count,
				trace_count,
				date_count,
				hdr_prefix,
				redistributed_mail,
				sender_count;
static	Trace			*gettrace ();

/* -- externals -- */
extern	Q_struct		Qstruct;
extern CHAN *ch_inbound;
extern char *loc_dom_mta;




/* ---------------------  Begin	 Routines  -------------------------------- */




void rd_rfchdr (file)  /* -- basic processing of incoming header lines -- */
char			*file;
{
	char	*bp,
		*name = NULLCP,	   /* hdr content location */
		*contents = NULLCP;
	int	retval = NOTOK,
		type;


	PP_DBG (("submit/rd_rfchdr (%s)", file));

	sender_count		= 0;
	from_count		= 0;
	trace_count		= 0;
	date_count		= 0;
	redistributed_mail	= FALSE;
	ua_id_set_by_subject 	= FALSE;

	if ((hdr_fp = fopen (file, "r")) == NULL)
		err_abrt (RP_FIO,
			"submit/rd_rfchdr/Unable to open '%s'", file);


	while (getline (&bp, hdr_fp) == OK) {
		hdr_prefix = FALSE;

		switch (retval = hdr_parse (bp, &name, &contents)) {
		    case HDV_MORE:
			continue;
		    case HDV_NEW:
			if ((type = hdr_type (name)) > 0)
				hdr_check (type, contents);
			continue;
		    case HDV_EOH:
			break;
		    case NOTOK:
			err_abrt(RP_USER, "submit/rd_rfchdr: Unable to parse '%s' as key:field", bp);
			break;
		}
		break;
	}

	(void) fclose (hdr_fp);

	if (retval != HDV_EOH)
		PP_DBG (("submit/rd_rfchdr/retval (%d) != hdr_eoh", retval));

	if (ch_inbound -> ch_access == CH_MTS &&
	    sender_count == 0 && from_count == 0)
		err_abrt (RP_USER, "submit/rd_rfchdr/No sender given");
	if (date_count == 0)
		err_abrt (RP_USER, "submit/rd_rfchdr/No date field given");
}

/* ---------------------  Static  Routines  ------------------------------- */

static int hdr_parse (txt, name, contents)    /* -- parse one header line -- */
register char		*txt;		  /* -- a line of header text -- */
char			**name;		  /* -- location of field's name -- */
char			**contents;    /* -- location of field's contents -- */
{
	extern char	*compress();
	char		linetype;


	PP_DBG (("submit/hdr_parse (%s)", txt));


	if (isspace (*txt)) {
		/* -- continuation text -- */
		if (*txt == '\n' || *txt == '\0')
			return (HDV_EOH);
		linetype = HDV_MORE;
	}
	else  {
		linetype = HDV_NEW;

		*name = txt;
		while (*txt && *txt != ':')
			txt ++;
		if (*txt == '\0' || *txt == '\n')
			return NOTOK;
		*txt ++ = '\0';

		(void) compress (*name, *name);
	}


	*contents = txt;
	compress (*contents, *contents);

	return (linetype);
}

static int hdr_type (name)    /* -- return the type of the component  -- */
char	*name;
{
	PP_DBG (("submit/hdr_type (%s)",name));

	if (prefix ("Resent-", name)) {
		name += 7;
		goto doremail;
	}
	if (prefix ("Remailed-", name)) {
		name += 9;
		goto doremail;
	}
	if (prefix ("Redistributed-", name)) {
		name += 14;
doremail:
		hdr_prefix = TRUE;
		if (!redistributed_mail) {
			sender_count = from_count = 0;
			redistributed_mail = TRUE;
		}
	}

	return (cmd_srch (name, htbl_rfc));
}

static void hdr_check (type, body)
char	*body;
int	type;
{
	AP_ptr	ap;

	PP_DBG (("submit/hdr_check (%d,%s)", type, body));

	if (type <= 0)
		return;		/* -- for all unknown types -- */

	switch (type) {
	    case HDR_SENDER:
		if (redistributed_mail && !hdr_prefix)
			break;
		if ((ap = ap_s2t (body)) == NULLAP)
			err_abrt (RP_USER, "submit/rd_rfchdr syntactically invalid address for sender '%s'", body);
		else
			ap_free(ap);
		sender_count++;
		break;
	    case HDR_FROM:
		if (redistributed_mail && !hdr_prefix)
			break;
		if ((ap = ap_s2t (body)) == NULLAP)
			err_abrt (RP_USER, "submit/rd_rfchdr syntactically invalid address for from field '%s'", body);
		else
			ap_free(ap);
		from_count++;
		break;
	    case HDR_REPLYTO:
		if (redistributed_mail && !hdr_prefix)
			break;
		break;
	    case HDR_VIA:
		hdr_via (body);
		break;
	    case HDR_RECEIVED:
		hdr_rcv (body);
		break;
	    case HDR_MESSAGEID:
		hdr_msgid (body);
		break;
	    case HDR_DATE:
		hdr_date (body);
		date_count++;
		break;
	    case HDR_SUBJECT:
		hdr_subject (body);
		break;
	    case HDR_X400_MTS_ID:
		hdr_x400_mts_id (body);
		break;
	    case HDR_ORIG_EIT:
		hdr_orig_eit (body);
		break;
	    case HDR_CONTENT_IDENTIFIER:
		hdr_x400_content_id (body);
		break;
	    case HDR_PRIORITY:
		hdr_priority(body);
		break;
	    case HDR_DL_HISTORY:
		hdr_dl_history(body);
		break;
	    case HDR_CONVERSION:
		hdr_conversion(body);
		break;
	    case HDR_CONVERT_WITH_LOSS:
		hdr_convert_with_loss(body);
		break;
	    case HDR_X400_RECEIVED:
		hdr_x400_received (body);
		break;
	    case HDR_DEF_DELIV:
		hdr_def_deliv (body);
		break;
	    case HDR_LAST_DELIV:
		hdr_latest_time (body);
		break;
	    default:
		break;
	}			/* -- switch  -- */
}

static void hdr_subject (str)
char	*str;
{
	char	buf[BUFSIZ];

	if (Qstruct.ua_id != NULLCP)
		return;
	bzero (buf, sizeof buf);
	if (strlen(str) >= ub_content_id_length) {
		(void) strncat (buf, str, (ub_content_id_length-strlen("...")));
		(void) strcat (buf, "...");
	} else
		(void) strcat (buf, str);
	Qstruct.ua_id = strdup (buf);
	ua_id_set_by_subject = TRUE;
}

static void hdr_x400_content_id (str)
char	*str;
{
	char	buf[BUFSIZ];

	if (Qstruct.ua_id != NULLCP)
		free(Qstruct.ua_id);
	bzero (buf, sizeof buf);
	if (strlen(str) >= ub_content_id_length) {
		(void) strncat (buf, str, (ub_content_id_length-strlen("...")));
		(void) strcat (buf, "...");
	} else
		(void) strncat (buf, str, strlen(str));
	Qstruct.ua_id = strdup (buf);
}

static void hdr_priority (str)
char	*str;
{
	compress(str, str);
	if (lexequ(str, "normal") == 0)
		Qstruct.priority = PRIO_NORMAL;
	else if (lexequ(str, "urgent") == 0)
		Qstruct.priority = PRIO_URGENT;
	else if (lexequ(str, "non-urgent") == 0
		|| lexequ(str, "nonurgent") == 0)
		Qstruct.priority = PRIO_NONURGENT;
}

static void hdr_dl_history (str)
char	*str;
{
	register DLHistory	*dlp;
	char	*start, *end, *tmp;
	tmp = strdup (str);
	start = tmp;
	compress(start, start);
	
	while (start != NULLCP && *start != '\0') {
		dlp = (DLHistory *) smalloc (sizeof(DLHistory));
		bzero ((char *)dlp, sizeof(*dlp));
		
	end = start;
	while (!isspace(*end)) end++;
	*end++ = '\0';
	
		dlp -> dlh_addr = strdup(start);
		while (isspace(*end)) end++;
		start = end;
		if (*start = '(') {
			start++;
			if ((end = index(start, ')')) == NULLCP)
				return;
			*end++ = '\0';
			if (rfc2UTC(start, &dlp -> dlh_time) != OK)
				return;
			start = end;
		}
		
		dlp -> dlh_next = Qstruct.dl_expansion_history;
		Qstruct.dl_expansion_history = dlp;
	}
	free(tmp);
}	

static void hdr_conversion (str)
char	*str;
{	
	compress (str, str);
	if (lexequ (str, "prohibited") == 0)
		Qstruct.implicit_conversion = 1;
}

static void hdr_convert_with_loss (str)
char	*str;
{	
	compress (str, str);
	if (lexequ (str, "prohibited") == 0)
		Qstruct.conversion_with_loss_prohibited = 1;
}

static void hdr_x400_received (str)
char	*str;
{
	Trace	*trace;

	PP_DBG (("submit/hdr_x400_received (%s)", str));

	trace = (Trace *) smalloc (sizeof(Trace));
	bzero ((char *) trace, sizeof(*trace));

	if (rfc2x400trace (trace, str) == OK) {
		PP_DBG (("rfc2x400trace OK"));
		trace -> trace_next = Qstruct.trace;
		Qstruct.trace = trace;
	} else
	       free((char *) trace);
}

static void hdr_def_deliv (str)
char	*str;
{
	if (Qstruct.defertime != 0)
		/* don't override */
		return;
	if (rfc2UTC (str, &Qstruct.defertime) != OK) 
		/* ignore */
		Qstruct.defertime = 0;
}

static void hdr_latest_time (str)
char	*str;
{
	if (Qstruct.latest_time != 0)
		/* don't override */
		return;
	if (rfc2UTC (str, &Qstruct.latest_time) != OK)
		Qstruct.latest_time = 0;
	else
		/* assume if present then critical */
		Qstruct.latest_time_crit = Q_LATESTTIME;
}

static void hdr_date (str)
char	*str;
{
	Trace	*tp;
	char	*adr = NULL;
	OR_ptr	or;

	tp = (Trace *) smalloc (sizeof (Trace));
	bzero ((char *)tp, sizeof(*tp));
	if (rfc2UTC (str, &(tp -> trace_DomSinfo.dsi_time)) != OK) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("submit/hdr_date unable to convert time to UTC '%s'",
			str));
		free((char *) tp);
		return;
	}
	tp->trace_DomSinfo.dsi_action = ACTION_RELAYED;
	
	if (Qstruct.Oaddress->ad_r400adr != NULL) {
		adr = strdup(Qstruct.Oaddress->ad_r400adr);
		if ((or = or_std2or(adr)) == NULLOR) {
			PP_LOG(LLOG_EXCEPTIONS,
			       ("submit/hdr_date unable to get OR tree for orig '%s'", Qstruct.Oaddress->ad_r400adr));
			free((char *)adr);
		}
	} 
	if (or == NULL && Qstruct.Oaddress->ad_r822adr != NULL) {
		adr = strdup(Qstruct.Oaddress->ad_r822adr);
		if (or_rfc2or_aux (adr, &or, CH_UK_PREF) == NOTOK) {
			PP_LOG(LLOG_EXCEPTIONS,
			       ("submit/hdr_date unable to get OR tree for orig '%s'", Qstruct.Oaddress->ad_r822adr));
			free ((char *) adr);
		}
	}

	if (or == NULL
	    || 	fillin_DomId (&tp -> trace_DomId, or, adr) == NOTOK) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("submit/hdr_date unable to create gld for orig"));
		free ((char *) tp);
	}
	
	or_free(or);
	free(adr);
	tp -> trace_next = Qstruct.trace;
	Qstruct.trace = tp;
}

static void hdr_date_987 (str)
char	*str;
{
	Trace	*tp;
	UTC	*utc;
	UTC	nutc;

	tp = gettrace ();
	utc = &tp -> trace_DomSinfo.dsi_time;
	if (rfc2UTC (str, &nutc) == OK) {
		if (*utc)
			free ((char *)*utc);
		*utc = nutc;
	}
	else if (*utc == NULLUTC)
		*utc = utcnow ();
}

static void hdr_x400_mts_id (str)
char	*str;
{
	if (Qstruct.msgid.mpduid_string != NULL)
		MPDUid_free(&Qstruct.msgid);
	rfc2msgid(&Qstruct.msgid, str);
}

static void hdr_orig_eit (str)
char	*str;
{
	if (Qstruct.orig_encodedinfo.eit_types != NULL)
		/* override */
		encodedinfo_free (&Qstruct.orig_encodedinfo);
	rfc2encinfo (&Qstruct.orig_encodedinfo, str);
}

static void hdr_msgid (str)
char	*str;
{
	MPDUid	*mp;

	if (Qstruct.msgid.mpduid_string == NULL)
		MPDUid_new  (&Qstruct.msgid);

	mp = &Qstruct.msgid;
	if (mp -> mpduid_string != NULLCP)
		free (mp -> mpduid_string);
	compress (str, str);
	mp -> mpduid_string = strdup (str);
}

static Trace *gettrace ()
{
	Trace	*tp;

	if (Qstruct.trace == (Trace *)NULL)
		trace_add (&Qstruct.trace, trace_new());
	tp = Qstruct.trace;

	return tp;
}

static void hdr_via_987 (contents)
char	*contents;
{
	char	*argv [25];
	char	*datestart;
	char	extraspace [LINESIZE];
	UTC	utc;

	PP_DBG (("submit/hdr_via (%s)", contents));

	trace_count ++;
	if (ch_inbound -> ch_access == CH_MTS)
		err_abrt (RP_MECH,
			  "No trace information allowed for local submission");

	if (trace_count == 1)
		return;/* we've added the first trace! */	

	if ((datestart = index (contents, ';')) != NULL)
		*datestart++ = '\0';

	/* -- rip out the comments -- */
	*extraspace = '\0';
	hdr_remcomm (contents, extraspace);
	if (datestart)
		hdr_remcomm (datestart, extraspace);

	(void) sstr2arg (contents, 25, argv, ",\t ");

	if (datestart == NULLCP || rfc2UTC (datestart, &utc) == NOTOK)
		utc = utcnow ();

	hdr_trace ((char *)NULL, argv [0], utc, extraspace);
}




/* -- take comments from 'from' & add to 'to' leaving 'from' without any -- */

static void hdr_remcomm (from, to)
char		*from;
char		*to;
{
	char	*start = from,
		*r = to,
		*s,
		*p,
		*q;


	if (start) {

		/* -- in case of NULL start ie missing date -- */

		PP_DBG (("submit/hdr_remcomm (%s,%s)", from, to));

		/* -- get to end -- */
		while (*r != '\0')
			r++;

		for (p = start ; (p = index (p, '(')) ;) {
			if ((q = index (p, ')')) == NULLCP) {
				*p = '\0';
				break;
			}

			if (*to != '\0')
				*r++ = ' ';

			for (s = p; s <= q; *r++ = *s++);

			(void) strcpy (p, q+1);

		}    /* -- for -- */

		*r = '\0';
		(void) compress (from, from);
	}  /* -- if -- */
	else
		PP_DBG (("submit/hdr_remcomm (NULL, %s)",to));
}

static void hdr_via (contents)
char	*contents;
{
	register Trace		*tp;
	char	*datestart = NULLCP,
		*argv[25], *domain, extraspace[LINESIZE];
	OR_ptr	or;

	PP_DBG (("submit/hdr_via (%s)", contents));

	trace_count++;
	if (ch_inbound -> ch_access == CH_MTS)
		err_abrt (RP_MECH,
			  "No trace information allowed for local submission");
	
	if (trace_count == 1)
		return;/* we've added the first trace! */
	
	/* -- rip out the comments -- */

	*extraspace = '\0';
	hdr_remcomm (contents, extraspace);

	if ((datestart = index (contents, ';')) != NULLCP)
		*datestart++ = '\0';

	if (sstr2arg (contents, 25, argv, ",\t ") < 1 
	    || argv[0] == NULLCP)
		return;

	domain = strdup(argv[0]);
	if (or_rbits2or ("pp", domain, &or) == NOTOK) {
		PP_TRACE(("unable to parse domain '%s' to OR tree", argv[0]));
		return;
	}
	tp = (Trace *) smalloc (sizeof (Trace));
	bzero ((char *)tp, sizeof(*tp));
	
	if (fillin_DomId (&tp -> trace_DomId, or, argv[0]) == NOTOK){
		free ((char *) tp);
		return;
	}

	or_free(or);
	free(domain);
	tp -> trace_mta = strdup(argv[0]);

	if (datestart == NULLCP || 
	    rfc2UTC(datestart,&(tp->trace_DomSinfo.dsi_time)) == NOTOK)
		tp -> trace_DomSinfo.dsi_time = utcnow();

	tp->trace_DomSinfo.dsi_action = ACTION_RELAYED;
	tp -> trace_next = Qstruct.trace;
	Qstruct.trace = tp;
}


	
	
static void hdr_rcv (contents)
char	*contents;
{
	register Trace		*tp;
	char	*bystart = NULLCP, *datestart = NULLCP,
		*argv[25], *domain, extraspace[LINESIZE];
	int	argc, i;
	OR_ptr	or;

	PP_DBG (("submit/hdr_rcv (%s)", contents));

	trace_count++;
	if (ch_inbound -> ch_access == CH_MTS)
		err_abrt (RP_MECH,
			  "No trace information allowed for local submission");
	
	if (trace_count == 1)
		return;/* we've added the first trace! */
	
	/* -- rip out the comments -- */

	*extraspace = '\0';
	hdr_remcomm (contents, extraspace);

	if ((datestart = index (contents, ';')) != NULLCP)
		*datestart++ = '\0';
	
	argc = sstr2arg (contents, 25, argv, ",\t ");
	
	for (i = 0; i < argc; i++) {
		if (lexequ (argv [i], "by") == 0) {
			if (bystart == NULLCP && i < argc -1) {
				bystart = argv [++i];
				continue;
			}
		}
	}
	
	if (bystart == NULLCP)
		return;
	domain = strdup(bystart);
	if (or_rbits2or ("pp", domain, &or) == NOTOK) {
		PP_TRACE(("unable to parse domain '%s' to OR tree", bystart));
		return;
	}
	tp = (Trace *) smalloc (sizeof (Trace));
	bzero ((char *)tp, sizeof(*tp));
	
	if (fillin_DomId (&tp -> trace_DomId, or, bystart) == NOTOK){
		free ((char *) tp);
		return;
	}

	or_free(or);
	free(domain);
	tp -> trace_mta = strdup(bystart);

	if (datestart == NULLCP || 
	    rfc2UTC(datestart,&(tp->trace_DomSinfo.dsi_time)) == NOTOK)
		tp -> trace_DomSinfo.dsi_time = utcnow();

	tp->trace_DomSinfo.dsi_action = ACTION_RELAYED;
	tp -> trace_next = Qstruct.trace;
	Qstruct.trace = tp;
}
		
static void hdr_rcv_987 (contents)
char			*contents;
{
	char		*cur_host = NULLCP,
			*prev_host = NULLCP,
			*argv [25],
			*datestart,
			extraspace [LINESIZE];
	int		argc,
			ind;
	UTC	utc;


	PP_DBG (("submit/hdr_rcv (%s)", contents));

	trace_count ++;
	if (ch_inbound -> ch_access == CH_MTS)
		err_abrt (RP_MECH,
			  "No trace information allowed for local submission");

	if ((datestart = index (contents, ';')) != NULLCP)
		*datestart++ = '\0';

	/* -- rip out the comments -- */

	*extraspace = '\0';
	hdr_remcomm (contents, extraspace);

	argc = sstr2arg (contents, 25, argv, ",\t ");


	for (ind = 0 ; ind < argc ; ind++) {
		if (lexequ ("from", argv [ind]) == 0) {
			if (prev_host == NULLCP && ind < argc - 1) {
				prev_host = argv [++ind];
				continue;
			}
		}
		else if (lexequ (argv [ind], "by") == 0) {
			if (cur_host == NULLCP && ind < argc -1) {
				cur_host = argv [++ind];
				continue;
			}
		}

		if (*extraspace)
			(void) strcat (extraspace, " ");

		(void) strcat (extraspace, argv [ind]);

	}    /* -- for completed -- */


	if (datestart)
		hdr_remcomm (datestart, extraspace);

	if (datestart == NULLCP || rfc2UTC (datestart, &utc) == NOTOK)
		utc = utcnow ();

	hdr_trace (cur_host, prev_host, utc, extraspace);
}



/* -- put the trace info into a trace structure	 -- */

static void hdr_trace (cur_host, prev_host, prev_time, extra)
char			*cur_host,
			*prev_host;
UTC			prev_time;
char			*extra;
{
	register Trace	*tp;
	char		tbuf [LINESIZE];

	PP_DBG (("submit/hdr_trace (%s, %s,  %s)",
		cur_host, prev_host, extra));

	if (cur_host == NULLCP && prev_host == NULLCP)
		return;

	tp = (Trace*) smalloc (sizeof (Trace));
	bzero ((char *)tp, sizeof (*tp));

	tp -> trace_DomId.global_Country = strdup ("");
	if (cur_host != NULLCP)
		tp->trace_DomId.global_Admin = strdup (cur_host);

	(void) compress (extra, extra);

	if (prev_host != NULLCP || *extra) {
		if (*extra && prev_host)
			(void) sprintf (tbuf, "%s %s", prev_host, extra);
		else if (*extra)
			(void) strcpy (tbuf, extra);
		else
			(void) strcpy (tbuf, prev_host);

		tp->trace_DomSinfo.dsi_attempted_md.global_Admin
			= strdup (tbuf);
	}

	tp->trace_DomSinfo.dsi_time = prev_time;
	tp->trace_DomSinfo.dsi_action = ACTION_RELAYED;

	tp -> trace_next = Qstruct.trace;
	Qstruct.trace = tp;
/*	trace_add (&Qstruct.trace, tp);*/
}

static int getline (bp, fp)
char	**bp;
FILE	*fp;
{
	static char *buf;
	static int bufsiz = 0;
	int	count;
	char	*cp;
	int	c;

	if (buf == NULLCP)
		buf = smalloc (bufsiz = BUFSIZ);
	for (cp = buf, count = 0; ; count ++) {
		if (count >= bufsiz - 5) {
			int curlen = cp - buf;
			buf = realloc (buf, (unsigned) (bufsiz += BUFSIZ));
			if (buf == NULL)
				err_abrt (RP_LIO, "Out of memeory");
			cp = buf + curlen;
		}
		switch (c = getc (fp)) {
		    case '\n':
			*cp ++ = ' ';
			if ((c = getc(fp)) == ' ' || c == '\t')
				continue;
			ungetc (c, fp);
			break;
		    case EOF:
			if (cp == buf)
				return NOTOK;
			break;
		    default:
			*cp ++ = c;
			continue;
		}
		break;
	}
	*cp = '\0';
	*bp = buf;
	return OK;
}

static int fillin_DomId (domId, or, str)
GlobalDomId	*domId;
OR_ptr		or;
char		*str;
{
	OR_ptr	tmp_or;
	
	if ((tmp_or = or_find (or, OR_C, NULLCP)) == NULLOR) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("submit/fillin_DomId: no country in '%s'", str));
		return NOTOK;
	}
	domId->global_Country = strdup(tmp_or -> or_value);
	
	if ((tmp_or = or_find (or, OR_ADMD, NULLCP)) == NULLOR) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("submit/fillin_DomId: no ADMD in '%s'", str));
		free ((char *) domId -> global_Country);
		return NOTOK;
	}
	domId->global_Admin = strdup(tmp_or -> or_value);
	
	if ((tmp_or = or_find (or, OR_PRMD, NULLCP)) != NULLOR) 
		domId->global_Private = strdup(tmp_or -> or_value);
	return OK;
}