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 c

⟦633757334⟧ TextFile

    Length: 15745 (0x3d81)
    Types: TextFile
    Names: »c-P2toRFC.c«

Derivation

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

TextFile

/* c-P2toRfc.c: rfc987(P2toRFC) filter channel */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Format/rfc1148/RCS/c-P2toRFC.c,v 5.0 90/09/20 16:01:38 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Format/rfc1148/RCS/c-P2toRFC.c,v 5.0 90/09/20 16:01:38 pp Exp Locker: pp $
 *
 * $Log:	c-P2toRFC.c,v $
 * Revision 5.0  90/09/20  16:01:38  pp
 * rcsforce : 5.0 public release
 * 
 */



#include "util.h"
#include "retcode.h"
#include "qmgr.h"
#include "q.h"
#include "prm.h"
#include "chan.h"
#include "ap.h"
#include "dr.h"
#include <isode/cmd_srch.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <isode/usr.dirent.h>


extern char	*mquedir;
extern char	*quedfldir;
extern char 	*chndfldir;
extern char	*cont_p2, *hdr_p2_bp, *hdr_p22_bp, *hdr_822_bp, *hdr_ipn_bp;
extern void	rd_end(), sys_init(), or_myinit(), err_abrt();
extern int	convertresult;

CHAN 		*mychan;
char		*this_msg = NULL, *this_chan = NULL;

static struct type_Qmgr_DeliveryStatus *process ();
static int initialise ();
static int filterMsg();
static int x40084;
static int doFilter();
static int link_rest();
static int security_check ();
static void dirinit ();
static struct type_Qmgr_DeliveryStatus *new_DeliveryStatus();
static ADDR *getnthrecip ();
int fatal;
int order_pref;
extern int ap_outtype;

/* \f

 */
/* main routine */
 
main (argc, argv)
int 	argc;
char	**argv;
{
	sys_init(argv[0]);
	or_myinit();
	dirinit ();
#ifdef PP_DEBUG
	if (argc>1 && (strcmp(argv[1],"debug") == 0))
		debug_channel_control(argc,argv,initialise,process,NULLIFP);
	else
#endif
		channel_control (argc, argv, initialise, process,NULLIFP);
}

/* \f

 */
/* routine to move to correct place in file system */

static void dirinit ()
{
	if (chdir (quedfldir) < 0)
		err_abrt (RP_LIO, " Unable to change directory to '%s'",
			  quedfldir);
}

/* \f

 */
/* channel initialise routine */

static int initialise (arg)
struct type_Qmgr_Channel *arg;
{
	char *name = NULL;

	name = qb2str(arg);

	if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
		PP_OPER(NULLCP,
		       ("Chans/rfc987 : Channel '%s' not known",name));
		if (name != NULL) free(name);
		return NOTOK;
	}
	
	order_pref = CH_USA_PREF;
	ap_outtype = AP_PARSE_SAME;
	if (mychan->ch_info != NULLCP &&
	    lexequ (mychan->ch_info, "uk") == 0) {
		order_pref = CH_UK_PREF;
		ap_outtype |= AP_PARSE_BIG;
	}
	/* check if a rfc987 channel */
	if (name != NULL) free(name);

	ap_use_percent();
	ap_norm_all_domains();

	return OK;
}

/* \f

 */
/* routine to check if allowed to rfc987 filter this message */
static int security_check (msg)
struct type_Qmgr_ProcMsg *msg;
{
	char *msg_file = NULL, *msg_chan = NULL;
	int result;

	result = TRUE;
	msg_file = qb2str (msg->qid);
	msg_chan = qb2str (msg->channel);

	if ((mychan == NULLCHAN) || (strcmp(msg_chan,mychan->ch_name) !=0)) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("Chans/rfc987 channel err: '%s'",msg_chan));
		result = FALSE;
	}
	if (msg_file != NULL) free(msg_file);
	if (msg_chan != NULL) free(msg_chan);
	return result;
}

/* \f

 */
/* routine called to do rfc987 filter */

static struct type_Qmgr_DeliveryStatus *process (arg)
struct type_Qmgr_ProcMsg *arg;
{
	struct prm_vars	prm;
	Q_struct	que;
	ADDR		*sender = NULL;
	ADDR		*recips = NULL;
	int 		rcount, first_failureDR, retval;
	struct type_Qmgr_UserList 	*ix;
	ADDR				*adr;
	char		*error = NULLCP;

	bzero((char *) &que,sizeof(que));
	first_failureDR = TRUE;
	delivery_init(arg->users);
	delivery_setall(int_Qmgr_status_messageFailure);
	
	if (security_check(arg) != TRUE)
		return deliverystate;

	if (this_msg != NULL) free(this_msg);
	if (this_chan != NULL) free(this_chan);

	this_msg = qb2str(arg->qid);
	this_chan = qb2str(arg->channel);

	PP_LOG(LLOG_NOTICE,
	       ("Chans/rfc987 filtering msg '%s' through '%s'",this_msg, this_chan));

	if (rp_isbad(rd_msg(this_msg,&prm,&que,&sender,&recips,&rcount))) {
		PP_LOG(LLOG_EXCEPTIONS,
			("Chans/rfc987 rd_msg err: '%s'",this_msg));
		rd_end();
		return delivery_setallstate (int_Qmgr_status_messageFailure,
					     "Can't read message");
	}

	/* check each recipient for processing */
	for (ix = arg->users; ix; ix = ix->next) {
		if ((adr = getnthrecip(&que,ix->RecipientId->parm)) == NULL) {
			PP_LOG(LLOG_EXCEPTIONS,
				("Chans/rfc987 : failed to find recipient %d of msg '%s'",ix->RecipientId->parm, this_msg));

 			delivery_setstate(ix->RecipientId->parm,
					  int_Qmgr_status_messageFailure,
					  "Unable to find specified recipient");
			continue;
		}
	
		switch (chan_acheck(adr, mychan, 1, (char **)NULL)) {
		    case OK:
			if (filterMsg(this_msg,adr,&que, &error) == NOTOK) {
				if (convertresult == NOTOK) {
					PP_LOG(LLOG_EXCEPTIONS,
					       ("Chans/rfc1138 : completely failed to filter msg '%s' for recip '%d' on channel '%s'. Sending a DR",
						this_msg, adr->ad_no, this_chan));
					set_1dr(&que, adr->ad_no,
						DRR_CONVERSION_NOT_PERFORMED,
						DRD_CONTENT_SYNTAX_ERROR,
						(error == NULLCP) ? "Unable to parse the p2 header" : error);
					delivery_set(adr->ad_no,
						     (first_failureDR == TRUE) ? int_Qmgr_status_negativeDR : int_Qmgr_status_failureSharedDR);
					first_failureDR = FALSE;
				} else {
					PP_LOG(LLOG_EXCEPTIONS,
					       ("Chans/rfc987 : failed to filter msg '%s' for recip '%d' on channel '%s'",this_msg, adr->ad_no, this_chan));
					delivery_setstate(adr->ad_no,
							  int_Qmgr_status_messageFailure,
							  (error == NULLCP) ? "Problems doing 1138 conversion" : error);
				}
			} else {
				/* CHANGE update adr->ad_rcnt in struct and in file */
				adr->ad_rcnt++;
				wr_ad_rcntno(adr,adr->ad_rcnt);
				delivery_set(adr->ad_no,
					     int_Qmgr_status_success);
			}
			break;
		    default:
			break;
		}
		if (error != NULLCP) {
			free(error);
			error = NULLCP;
		}
	}
	if (rp_isbad(retval = wr_q2dr(&que, this_msg))) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("%s wr_q2dr failure '%d'",mychan->ch_name,retval));
		delivery_resetDRs(int_Qmgr_status_messageFailure);
	}
	rd_end();
	return deliverystate;
}

/* \f

 */
static int filterMsg (msg,recip,qp, ep)
/* return OK if managed to filter msg through mychan for recip */
char		*msg;
ADDR		*recip;
Q_struct	*qp;
char		**ep;
{
	char	*origdir = NULL,
	        *newdir = NULL;
	int	result = OK;
	struct stat statbuf;

	if (qid2dir(msg, recip, TRUE, &origdir) != OK) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("Chans/rfc987 original directory not found for recipient %d of message '%s'",recip->ad_no, msg));
		*ep = strdup("source directory not found");
		result = NOTOK;
	}

	/* temporary change to get new directory name */
	recip->ad_rcnt++;
	if ((result == OK) 
	    && (qid2dir(msg, recip, FALSE, &newdir) != OK)) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("Chans/rfc987 couldn't construct new directory for recipient '%d' of message '%s'",recip->ad_no, msg));
		*ep = strdup("Unable to construct destination directory");
		result = NOTOK;
	}
	recip->ad_rcnt--;
	
	if ((result == OK)
	    && (stat(newdir, &statbuf) == OK)
	    && ((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
		/* directory already exists and so filter already done */

		if (origdir != NULL) free(origdir);
		if (newdir != NULL) free(newdir);
		return OK;
	}
	if (qp -> cont_type == NULL
	    || *(qp -> cont_type) == '\0')
		x40084 = -1;
	else
		x40084 = (lexequ(qp->cont_type, cont_p2) == 0) ? TRUE : FALSE;
	if ((result == OK) && (doFilter(origdir,newdir,msg, 
					qp, ep)!= OK))

		result = NOTOK;

	if (origdir != NULL) free(origdir);
	if (newdir != NULL) free(newdir);
	return result;
}

/* \f

 */
char	olddir[FILNSIZE],
	newdir[FILNSIZE],
	xtra_822hdrs[FILNSIZE];

int	*dir_flags = NULL,
	num_dir_flags = 0,
	dirlevel = 0;

#define	INC	5

static void resize_dir_flags()
{
	num_dir_flags += INC;
	if (dir_flags == NULL)
		dir_flags = (int *) calloc((unsigned int)num_dir_flags, sizeof(int));
	else
		dir_flags = (int *) realloc( (char *) dir_flags, 
					    (unsigned) (num_dir_flags * sizeof(int)));
}

static int	is822hdrfile(file)
char		*file;
{
	char	buf[LINESIZE];
	FILE	*fp;

	(void) sprintf(xtra_822hdrs, "%s/%s", olddir, file);
	if ((fp = fopen(xtra_822hdrs,"r")) == NULL)
	{
		PP_SLOG(LLOG_EXCEPTIONS, xtra_822hdrs,
			("Can't open file"));
		return FALSE;
	}

	if (fgets (buf, LINESIZE - 1, fp) == NULL)
	{
		PP_DBG (("Null file '%s'",xtra_822hdrs));
		fclose(fp);
		return FALSE;
	}

	buf [strlen(buf) - 1] = '\0'; /* remove \n */
	if (lexnequ (buf, "RFC-822-HEADERS:",
		     strlen("RFC-822-HEADERS:")) != 0)
	{
		fclose (fp);
		return FALSE;
	}

	fclose(fp);
	return TRUE;
}


static int	is_xtra_822hdrs(entry)
struct dirent	*entry;
{
	if ((strncmp(entry->d_name,"1.",2) == 0)
	    && (is822hdrfile(entry->d_name) == TRUE)) {
		(void) sprintf(xtra_822hdrs, "%s/%s", olddir, entry->d_name);
		return 1;
	}
	return 0;
}

static	char	*get_xtra_822hdrs(dir)
char	*dir;
{
	int	num;
	struct dirent	**namelist;

	num = _scandir(dir, &namelist, is_xtra_822hdrs, NULL);
	if (num == 0) {
		dir_flags[dirlevel] = FALSE;
		return NULLCP;
	} else {
		dir_flags[dirlevel] = TRUE;
		return xtra_822hdrs;
	}
}

extern char	*ia5_bp;

static doFilter (orig, new, msg, qp, ep)
/* filters orig directory through mychan to new directory */
char		*orig,
		*new,
		*msg;
Q_struct	*qp;
char		**ep;
{
	char		hdrp2[FILNSIZE],
			hdr822[FILNSIZE], *ipn_body;
	int		result = OK;
	struct stat 	statbuf;
	char		buf[BUFSIZ];
	(void) sprintf(newdir, "%s/%s/tmp.%s", 
		       mquedir, msg, mychan->ch_name);
	
	if (stat(newdir, &statbuf) == OK) {
		char	*cmd_line;
		/* exists so remove it */
		cmd_line = malloc((unsigned) (strlen("rm -rf ") +
						   strlen(newdir) + 1));
		sprintf(cmd_line, "rm -rf %s", newdir);
		system(cmd_line);
		if (cmd_line != NULL) free(cmd_line);
	}

	if (mkdir(newdir, 0777) != OK) {
		PP_SLOG(LLOG_EXCEPTIONS, newdir,
			("Can't make directory"));
		(void) sprintf(buf,
			       "Failed to make temp directory '%s'",
			       newdir);
		*ep = strdup(buf);
		result = NOTOK;
	}

	if (result == OK) {
		/* filter from orig to newdir */
		LIST_BPT	*ix = mychan -> ch_bpt_in;
		ipn_body = NULLCP;
		
		if (x40084 == -1) {
			while (ix != NULLIST_BPT) {
				sprintf(hdrp2,"%s/%s",orig, ix -> li_name);
				if (stat(hdrp2, &statbuf) == OK) {
					if (lexequ(ix -> li_name, hdr_p2_bp) == 0) 
						x40084 = TRUE;
					else if (lexequ(ix -> li_name, hdr_p22_bp) == 0)
						x40084 = FALSE;
					break;
				}
				ix = ix -> li_next;
			}
		
			if (ix == NULLIST_BPT) {
				/* try for ipn hdr */
				sprintf(hdrp2, "%s/%s", orig, hdr_ipn_bp);
				if (stat(hdrp2, &statbuf) != OK) {
					PP_OPER(NULLCP,
						("Format/P2toRFC : cannot find p2 hdr"));
					(void) sprintf (buf,
							"Cannot find p2 hdr");
					*ep = strdup(buf);
					return NOTOK;
				}
			}
		} else {
			sprintf (hdrp2, "%s/%s",
				 orig,
				 (x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp);
			if (stat(hdrp2, &statbuf) != OK) {
				/* try for ipn hdr */
				sprintf(hdrp2, "%s/%s", orig, hdr_ipn_bp);
				if (stat(hdrp2, &statbuf) != OK) {
					PP_OPER(NULLCP,
						("Format/P2toRFC : cannot find p2 hdr"));
					(void) sprintf (buf,
							"Cannot find p2 hdr");
					*ep = strdup(buf);
					return NOTOK;
				}
				
			}
		}
		sprintf(hdr822, "%s/1.%s", newdir, ia5_bp);
		ipn_body = strdup(hdr822);
		
		sprintf(hdr822,"%s/%s",newdir,hdr_822_bp);
		sprintf(olddir,"%s",orig);
		dirlevel = 0;
		resize_dir_flags();

		result = P2toRFC(hdrp2,get_xtra_822hdrs(orig),qp,
				 hdr822,ipn_body,ep,x40084);

		if (ipn_body) free(ipn_body);
		fatal = FALSE;

		link_rest(orig, ep);

		if (fatal == TRUE)
			result = NOTOK;
		/* if success rename newdir to new */

		if ((result == OK) && (rename(newdir,new) == -1)) {
			PP_SLOG(LLOG_EXCEPTIONS, "rename",
				("Can't rename directory '%s' to '%s'",
				 newdir, new));
			(void) sprintf (buf,
					"Unable to rename temp dir from '%s' to '%s'",
					newdir, new);
			*ep = strdup(buf);
			result = NOTOK;
		}
	}
	return result;
}

/* \f

 */
/* link rest across from orig to newdir */
/* may have to do some renumbering if 1.ia5 is extra headers */

/* origdir and newdir are set to current dirlevel of directories */
char	*linkerror = NULLCP;

static int	do_link(entry)
struct dirent	*entry;
{
	struct	stat statbuf;
	struct dirent	**namelist;
	int		num;
	char		oldfullname[FILNSIZE],
			newfullname[FILNSIZE],
			*ix;

	if ((strcmp(entry->d_name,".") == 0)
	    || (strcmp(entry->d_name,"..") == 0))
		return 0;

	if ((dir_flags[dirlevel] == TRUE)
	    && (strncmp(entry->d_name,"1.",2) == 0))
		/* already done so ignore */
		return 0;

	if (strcmp(entry->d_name,
		   (x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp) == 0)
		/* already dealt with */
		return 0;

	(void) sprintf(oldfullname, "%s/%s",olddir,entry->d_name);

	/* create new filename */

	if (isdigit(*(entry->d_name))
	    && (dir_flags[dirlevel] == TRUE)) {
		/* need to alter number (decrement) */
		ix = index(entry->d_name,'.');
		*ix = '\0';
		num = atoi(entry->d_name);
		*ix = '.';
		sprintf(newfullname,"%s/%d%s",newdir,--num,ix);
	} else
		/* just copy */
		sprintf(newfullname,"%s/%s",newdir,entry->d_name);
	
			
	if ((stat(oldfullname,&statbuf) == OK)
	    && ((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
		/* directory so do scandir on it */
		char		hdrp2[FILNSIZE],
				hdr822[FILNSIZE];
		struct stat 	statbuf;

		if (mkdir(newfullname, 0777) != OK) {
			PP_SLOG(LLOG_EXCEPTIONS, newfullname,
				("Can't make directory"));
			exit(-1);
		}
		dirlevel++;
		if (dirlevel >= num_dir_flags)
			resize_dir_flags();

		sprintf(olddir, "%s", oldfullname);
		sprintf(newdir, "%s", newfullname);


		/* deal with hdr.p2 in this directory if there */
		sprintf(hdrp2,"%s/%s",olddir,
			(x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp);
		if (stat(hdrp2, &statbuf) == OK) {
			sprintf(hdr822,"%s/%s",
				newdir, hdr_822_bp);

			if (P2toRFC(hdrp2,get_xtra_822hdrs(olddir),
				    (Q_struct *) NULL,
				    hdr822, NULLCP, 
				    &linkerror, x40084) != OK) {
				fatal = TRUE;
				return 0;
			}
				
		} else {
			PP_OPER(NULLCP,
			       ("Format/P2toRFC : cannot find p2 hdr '%s' for forwarded msg",hdrp2));
			fatal = TRUE;
			return 0;
		}
		num = _scandir(olddir,&namelist, do_link, NULL);
		/* rewind newdir and olddir */
		ix = rindex(olddir,'/');
		*ix = '\0';
		ix = rindex(newdir,'/');
		*ix = '\0';
		dirlevel--;

	} else
		/* just link */
		if (link(oldfullname, newfullname) == -1) {
			PP_SLOG(LLOG_EXCEPTIONS, "link",
			       ("Can't link from '%s' to '%s'",oldfullname,newfullname));
			exit(-1);
		}
	return 0;
}
	

static int link_rest(orig, ep)
char	*orig;
char	**ep;
{
	int num;
	struct dirent	**namelist;

	num = _scandir(orig,&namelist, do_link, NULL);
	if (linkerror != NULLCP) {
		if (*ep == NULLCP) 
			*ep = linkerror;
		else
			free(linkerror);
		linkerror = NULLCP;
	}
}

/* \f

 */
/* auxilary routines to extr<act from lists */
static ADDR *getnthrecip(que, num)
Q_struct	*que;
int		num;
{
	ADDR *ix = que->Raddress;
	int icount = 1;
	if (num == 0)
		return que->Oaddress;
	while ((ix != NULL) && (icount++ < num))
		ix = ix->ad_next;
	return ix;
}

void    advise (what, fmt, a, b, c, d, e, f, g, h, i, j)
char   *what,
       *fmt,
       *a,
       *b,
       *c,
       *d,
       *e,
       *f,
       *g,
       *h,
       *i,
       *j;
{
    (void) fflush (stdout);

    fprintf (stderr, "RFCtoP2 test");
    fprintf (stderr, fmt, a, b, c, d, e, f, g, h, i, j);
    if (what)
	(void) fputc (' ', stderr), perror (what);
    else
	(void) fputc ('\n', stderr);

    (void) fflush (stderr);
}


/* VARARGS 2 */
void    adios (what, fmt, a, b, c, d, e, f, g, h, i, j)
char   *what,
       *fmt,
       *a,
       *b,
       *c,
       *d,
       *e,
       *f,
       *g,
       *h,
       *i,
       *j;
{
    advise (what, fmt, a, b, c, d, e, f, g, h, i, j);
    _exit (1);
}