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 d

⟦a0a46c068⟧ TextFile

    Length: 8777 (0x2249)
    Types: TextFile
    Names: »dr2rfc.c«

Derivation

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

TextFile

/* dr2rfc.c - The PP DR structure to an RFC message */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/dr2rfc/RCS/dr2rfc.c,v 5.0 90/09/20 15:47:04 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Chans/dr2rfc/RCS/dr2rfc.c,v 5.0 90/09/20 15:47:04 pp Exp Locker: pp $
 *
 * $Log:	dr2rfc.c,v $
 * Revision 5.0  90/09/20  15:47:04  pp
 * rcsforce : 5.0 public release
 * 
 */



/****************************************************************************\
*                                                                            *
*  The following checks are done:                                            *
*       -  The message should not as yet be delivered.                       *
*       -  The Recipient number has a DR associated with it.                 *
*       -  All specified recipients have the same DR number.                 *
*                                                                            *
\****************************************************************************/




#include <sys/param.h>
#include "head.h"
#include "prm.h"
#include "qmgr.h"
#include "q.h"
#include "tb_a.h"
#include "ap.h"

extern  char                            *quedfldir;
extern void	rd_end(), chan_init(), err_abrt(), or_myinit();

/* -- static variables -- */
static Q_struct                         Qstruct;
Q_struct                                *PPQuePtr = &Qstruct;
static struct prm_vars                  PRMstruct;
static int                              DRno = 0;
char                                    *this_msg = NULLCP;
int					order_pref;
int					io_running;
extern	int				ap_outtype;
static int initproc ();
static int endfunc();
static void dirinit ();
static struct type_Qmgr_DeliveryStatus *process ();
static int adr_checks ();
static int Deliver ();
static void display_ProcMsg ();
char	error[BUFSIZ];
/* -- used by other files -- */
CHAN                                    *mychan;




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




main (argc, argv)
int     argc;
char    **argv;
{
	char            *myname = argv[0];

	if (*myname == '/') {
		myname = rindex (myname, '/');
		myname++;
	}

	/* -- read pp tailor file -- */
	chan_init (myname);

	/* -- check that the Q dirs are ok -- */
	dirinit();

#ifdef PP_DEBUG
	if (argc > 1 && strcmp (argv[1], "debug") == 0)
	       debug_channel_control (argc, argv, initproc, process, endfunc);
	else
#endif
	       channel_control (argc, argv, initproc, process, endfunc);


	exit (0);
}




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




static void dirinit()   /* -- Change into pp queue space -- */
{
	PP_TRACE (("dirinit()"));
	if (chdir (quedfldir) < 0)
		err_abrt (RP_LIO, "Unable to change to dir '%s'", quedfldir);
}




static int initproc (arg)
struct type_Qmgr_Channel        *arg;
{
	char                    *myname = qb2str (arg);
	RP_Buf  rps, *rp = &rps;

	PP_TRACE (("initproc (%s)", myname));

	if ((mychan = ch_nm2struct (myname)) == NULLCHAN)
		err_abrt (RP_PARM, "Channel '%s' not known", myname);

	
	/* -- other initialisations -- */
	order_pref = CH_USA_PREF;
	ap_outtype = AP_PARSE_SAME;
	if (mychan->ch_info != NULLCP &&
	    (strcmp(mychan->ch_info, "uk") == 0
	    || strcmp(mychan->ch_info, "UK") == 0)) {
		order_pref = CH_UK_PREF;
		ap_outtype |= AP_PARSE_BIG;
	}
	
	pp_setuserid();

	or_myinit();

	if (rp_isbad (io_init(rp)))
		err_abrt (RP_PARM, "io_init err %s", rp -> rp_line);
	else
		io_running = TRUE;

	PP_NOTICE (("Channel %s initialised", myname));
	free (myname);
	q_init (PPQuePtr);
	prm_init (&PRMstruct);
	return OK;
}

/* ARGSUSED */
static int endfunc (arg)
struct type_Qmgr_Channel *arg;
{
	if (io_running == TRUE)
		io_end(OK);
	io_running = FALSE;
}

stop_io()
{
	if (io_running == TRUE)
		io_end(NOTOK);
	io_running = FALSE;
}

static struct type_Qmgr_DeliveryStatus *process (arg)
struct type_Qmgr_ProcMsg                *arg;
{

	struct type_Qmgr_UserList       *up;
	ADDR                            *ad_list        = NULLADDR,
					*ad_sender      = NULLADDR,
					*ad_recip       = NULLADDR,
					*alp            = NULLADDR,
					*ap             = NULLADDR;
	int                             naddrs          = 0,
					ad_count,
					retval;

	if (this_msg)
		free (this_msg);

	this_msg = qb2str (arg->qid);
	PP_TRACE (("process (msg = '%s')", this_msg));
	delivery_init (arg->users);
	delivery_setall (int_Qmgr_status_messageFailure);

#ifdef PP_DEBUG
	display_ProcMsg (arg);
#endif


	/* -- Initialisation --*/

	DRno = 0;
	q_init (PPQuePtr);
	prm_init (&PRMstruct);


	/* -- read the addr control file -- */

	retval = rd_msg (this_msg, &PRMstruct, PPQuePtr,
			&ad_sender, &ad_recip, &ad_count);

	if (rp_isbad (retval)) {
		rd_end();
		PP_LOG (LLOG_EXCEPTIONS, ("rd_msg error: %s", this_msg));
		return delivery_setallstate (int_Qmgr_status_messageFailure,
					     "Can't read message");
	}



	/* -- create a new recip list + perform addr check -- */

	for (ap = ad_recip; ap; ap = ap -> ad_next) {
		for (up = arg->users; up; up = up->next) {
			if (up -> RecipientId -> parm != ap -> ad_no)
				continue;

			if (adr_checks (ap) != OK)
				break;

			if (ad_list == NULLADDR)
				ad_list = alp =
					(ADDR *) calloc(1, sizeof *alp);
			else {
				alp -> ad_next =
					(ADDR *) calloc(1, sizeof *alp);
				alp = alp -> ad_next;
			}

			/* -- struct copy -- */
			*alp = *ap;
			alp -> ad_next = NULLADDR;
			naddrs++;
			break;
		}
	}


	if (naddrs == 0) {
		PP_LOG (LLOG_EXCEPTIONS, ("No recipients in the user list"));
		rd_end ();
		return deliverystate;
	}


	/* -- deliverystate set in deliver -- */
	Deliver (ad_sender, ad_list);
	rd_end();

	/* -- free ad_list -- */
	for (alp = ad_list; alp; alp = ap) {
		ap = alp -> ad_next;
		free ((char *)alp);
	}

	q_free (PPQuePtr);
	prm_free (&PRMstruct);

	return deliverystate;
}




static int adr_checks (ap)
ADDR    *ap;
{
	PP_TRACE (("adr_checks (%s)", ap->ad_value));

	switch (ap->ad_status) {
	    case AD_STAT_DRWRITTEN:
		break;
	    case AD_STAT_DONE:
		(void) delivery_set(ap->ad_no,
				    int_Qmgr_status_success);
		return NOTOK;
	    default:
		PP_LOG (LLOG_EXCEPTIONS, ("adr_checks - wrong status"));
		(void) delivery_setstate(ap->ad_no,
				    int_Qmgr_status_messageFailure,
				    "adr_checks - wrong status");
	       return NOTOK;
	}

	if (ap -> ad_resp == 0) {
		PP_LOG (LLOG_EXCEPTIONS,
			("responsibility bit not set for addr %d",
			 ap -> ad_no));
		(void) delivery_setstate (ap -> ad_no,
				     int_Qmgr_status_messageFailure,
				     "responsibility bit not set for addr");
		return NOTOK;
	}


	if (DRno == 0)
		DRno = ap->ad_no;
	return OK;
}




static int Deliver (orig, recip)
ADDR    *orig;
ADDR    *recip;
{
	int     retval = RP_BAD;
	int     value = int_Qmgr_status_messageFailure;
	ADDR    *ap;
	RP_Buf	rps, *rp = &rps;
	PP_TRACE (("Deliver (%s)", orig->ad_value));
	error[0] = '\0';
	if (orig->ad_outchan &&
	    orig->ad_outchan->li_chan &&
	    orig->ad_outchan->li_chan->ch_name &&
	    lexequ(orig->ad_outchan->li_chan->ch_name, mychan->ch_name) == 0) {
		   
		if (io_running == FALSE)
			if (rp_isbad(io_init(rp))) {
				PP_LOG(LLOG_EXCEPTIONS,
				       ("io_init err %s", rp -> rp_line));
				(void) sprintf (error,
						"io_init error [%s]",
						rp -> rp_line);
				goto Deliver_free;
			} else
				io_running = TRUE;
			
		if (rp_isbad (write_queue (orig)))
			goto Deliver_free;

		if (rp_isbad (write_report (orig, DRno, recip)))
			goto Deliver_free;


		value = int_Qmgr_status_success;
		retval = RP_OK;
	} else {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("Illegal setting of outbound channel for addr %d",
			orig->ad_no));
		(void) sprintf (error,
				"Illegal setting of outbound channel");
	}

    Deliver_free: ;
	for (ap = recip; ap; ap = ap -> ad_next) {
		if (ap -> ad_resp) {
			delivery_setstate (ap -> ad_no, value, error);
			if (value == int_Qmgr_status_success)
				wr_ad_status (ap, AD_STAT_DONE);
		}

	}

	if (retval == RP_OK) {
		PP_NOTICE (("Wrote DR to  '%s'", orig->ad_value));
		PP_NOTICE ((">>> %s %s done", mychan -> ch_name, this_msg));
	}
	else {
		PP_OPER (NULLCP, ("dr2rfc has failed for %s", this_msg));
		PP_NOTICE ((">>> %s %s has not been done",
			    mychan -> ch_name, this_msg));
		stop_io ();
	}

	return retval;
}




/*  --------------------  Debug Proceedures  ------------------------------ */




#ifdef PP_DEBUG
static void display_ProcMsg (pm)
struct type_Qmgr_ProcMsg        *pm;
{
	char                    *str;
	struct type_Qmgr_UserList *pmu;

	str = qb2str (pm -> qid);

	for (pmu = pm -> users; pmu; pmu = pmu -> next)
		PP_TRACE (("%s:  user(%d)",
			str, pmu -> RecipientId->parm));

	if (str) free (str);

	return;
}
#endif