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 p

⟦7bfbac2ca⟧ TextFile

    Length: 17819 (0x459b)
    Types: TextFile
    Names: »p2explode.c«

Derivation

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

TextFile

/* p2explode: explode a P2 structure up into component parts in hierachy */

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

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



#include <isode/psap.h>
#include "util.h"
#include "retcode.h"
#include <isode/cmd_srch.h>
#include "tb_bpt88.h"
#include "P2-types.h"
#include <varargs.h>
#include "q.h"
#include "list_bpt.h"
static int process();
static char curdir[FILNSIZE];   /* directory stack */
int	fatal = NOTOK;

extern CMD_TABLE bptbl_body_parts88[/* x400 84 body_parts */];
extern char *quedfldir;
extern char *mquedir;
extern char *hdr_p22_bp, *hdr_p2_bp, *hdr_ipn_bp, *cont_p22, *cont_p2;
LIST_BPT	*outbound_bpts = NULLIST_BPT;

FILE *open_P2_file();

extern int encode_P2_TLXBodyPart (), 
	encode_P2_VoiceBodyPart (), 
	encode_P2_G3FacsimileBodyPart (),
	encode_P2_G4Class1BodyPart (), 
	encode_P2_TeletexBodyPart (), 
	encode_P2_VideotexBodyPart (),
	encode_P2_NationallyDefinedBodyPart (), 
	encode_P2_EncryptedBodyPart (),
	encode_P2_SFDBodyPart (), 
	encode_P2_MixedModeBodyPart (),
	encode_P2_BilaterallyDefinedBodyPart (),
	encode_P2_ExternallyDefinedBodyPart (),
	encode_P2_ISO6937TextBodyPart(),
	encode_P2_UnidentifiedBodyPart();

void    advise ();
void    adios ();
#define ps_advise(ps, f) \
	advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s",\
		(f), ps_error ((ps) -> ps_errno))
char	*makename();

unflatten(old, new, x40084, qp, perr)
char	*old,
	*new;
int	x40084;
Q_struct	*qp;
char		**perr;
{
	char    curpart[LINESIZE], buf[BUFSIZ];
	
	setname (new);       /* set initial directory */
	msg_rinit(old);
	fatal = NOTOK;
	if (!(msg_rfile(curpart) == RP_OK && isP2(curpart, x40084))) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("Chans/p2explode cannot find p2 file in '%s'",old));
		(void) sprintf (buf,
				"Unable to find p2 file in '%s'",
				old);
		*perr = strdup(buf);
		return NOTOK;
	}
	if (process (curpart, x40084, qp, perr) == NOTOK)
		return NOTOK;
	return OK;
}

/*
 * isP2: check to see if the current body part should be
 * processed or not.
 */

isP2(curpart, x40084)
char    *curpart;
int	x40084;
{
	char	*cp;

	if (cp = rindex(curpart,'/'))
		cp ++;
	else cp = curpart;

	return (strcmp(cp, ((x40084 == TRUE) ? cont_p2 : cont_p22)) == 0);
}

extern  errno;

/* linkthem: no reformatting needed so just link across */

linkthem(src, dest, perr)
char    *src, *dest, **perr;
{
	char	buf[BUFSIZ];

	if(link(src, dest) < 0 && errno != EEXIST) {
		PP_SLOG(LLOG_EXCEPTIONS, "link",
			("cannot link %s to %s", src, dest));
		(void) sprintf (buf,
				"Unable to link %s to %s",
				src, dest);
		*perr = strdup(buf);
		return NOTOK;
	}
	return OK;
}

/* process: start the splitting operation on the given file */
static int     process (file, x40084, qp, perr)
register char  *file;
int		x40084;
Q_struct	*qp;
char		**perr;
{
	register PE     pe;
	register PS     psin;
	FILE    	*fp;
	char		buf[BUFSIZ];
	int		retval = NOTOK;
	struct type_P2_InformationObject *infoob;

	if((fp = fopen (file, "r")) == (FILE *)0) {
		PP_SLOG(LLOG_EXCEPTIONS, file,
		       ("Can't open file"));
		(void) sprintf (buf,
				"Unable to open input file '%s'",
				file);
		*perr = strdup(buf);
		return NOTOK;
	}

	if ((psin = ps_alloc (std_open)) == NULLPS)
	{
		(void) fclose (fp);
		ps_advise (psin, "ps_alloc");
		return NOTOK;
	}

	if (std_setup (psin, fp) == NOTOK)
	{
		ps_free (psin);
		(void) fclose (fp);
		advise (LLOG_EXCEPTIONS, NULLCP, "%s: std_setup loses", file);
		return NOTOK;
	}

	if ((pe = ps2pe (psin)) == NULLPE) { /* EOF or error? */
		(void) fclose (fp);
		fatal = OK;
		(void) sprintf(buf,
			"Unable to parse the p2 - ps2pe failed");
		*perr = strdup(buf);
		ps_done(psin, "ps2pe");
		return NOTOK;
	}
	PY_pepy[0] = 0;

	if(decode_P2_InformationObject(pe, 1, NULLIP, NULLVP, &infoob) == NOTOK) {
		PP_LOG(LLOG_EXCEPTIONS,
		       ("decode_P2_InformationObject failure [%s]", 
			PY_pepy));
		pe_done(pe, "Parse failure P2_InformationObject");
		fatal = OK;
		(void) sprintf (buf,
				"Unable to parse the p2 [%s]",
				PY_pepy);
		*perr = strdup (buf);
		(void) fclose(fp);
		return NOTOK;
	}
	if (PY_pepy[0] != 0)
		PP_LOG(LLOG_EXCEPTIONS,
		       ("parse_P2_InformationObject non fatal failure [%s]",
			PY_pepy));
	if (write_out_parts (infoob, x40084, qp, perr) == OK)
		retval = OK;
	if( pe != NULLPE)
		pe_free (pe);
	(void) fclose (fp);
	return retval;
}

write_out_parts (infoob, x40084, qp, perr)
struct type_P2_InformationObject *infoob;
int	x40084;
Q_struct	*qp;
char		**perr;
{
	char	buf[BUFSIZ];

	switch (infoob -> offset) {
	    case type_P2_InformationObject_ipm:
		return write_ipm (infoob -> un.ipm, x40084, qp, perr);

	    case type_P2_InformationObject_ipn:
		return write_ipn (infoob -> un.ipn, x40084, qp, perr);

	    default:
		PP_LOG (LLOG_EXCEPTIONS,
			("Unknown P2 type %d", infoob -> offset));
		(void) sprintf (buf,
				"Unknown P2 type %d",
				infoob -> offset);
		*perr = strdup(buf);
		return NOTOK;
	}
}

int	write_ipm (ipm, x40084, qp, perr)
struct type_P2_IPM *ipm;
int x40084;
Q_struct	*qp;
char		**perr;
{
	if (write_bp ((x40084 == TRUE) ? hdr_p2_bp : hdr_p22_bp, 
		      ipm -> heading, perr) == NOTOK) 
		return NOTOK;

	return write_bodies (ipm -> body, 1, x40084, qp, perr);
}

int	write_bodies (bpp, number, x40084, qp, perr)
struct type_P2_Body *bpp;
int	number;
int	x40084;
Q_struct	*qp;
char		**perr;
{
	struct type_P2_BodyPart *bp;
	FILE	*fp;
	char	buf[BUFSIZ];

	while (bpp) {
		bp = bpp -> BodyPart;
		bpp = bpp->next;

		switch (bp -> offset) {
		    case type_P2_BodyPart_ia5__text:
			if ((fp = open_P2_file (BPT_IA5, number, qp, perr)) == NULL)
				return NOTOK;
			dumpCRLFstring (fp, bp -> un.ia5__text -> data);
			if (fclose (fp) == EOF)
				return NOTOK;
			break;

		    case type_P2_BodyPart_tlx:
			if (write_pefile (BPT_TLX, number,
					  (caddr_t)bp -> un.tlx,
					  encode_P2_TLXBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;

		    case type_P2_BodyPart_voice:
			if (write_pefile (BPT_VOICE, number,
					  (caddr_t) bp -> un.voice,
					  encode_P2_VoiceBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;


		    case type_P2_BodyPart_g3__facsimile:
			if (write_pefile (BPT_G3FAX, number,
					  (caddr_t) bp -> un.g3__facsimile,
					  encode_P2_G3FacsimileBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;

		    case type_P2_BodyPart_g4__class1:
			if (write_pefile (BPT_TIF0, number,
					  (caddr_t) bp -> un.g4__class1,
					  encode_P2_G4Class1BodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;

		    case type_P2_BodyPart_teletex:
			if (write_pefile (BPT_TTX, number,
					  (caddr_t) bp -> un.teletex,
					  encode_P2_TeletexBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;

		    case type_P2_BodyPart_videotex:
			if (write_pefile (BPT_VIDEOTEX, number,
					  (caddr_t) bp -> un.videotex,
					  encode_P2_VideotexBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;

		    case type_P2_BodyPart_encrypted:
			if (write_pefile (BPT_ENCRYPTED, number,
					  (caddr_t) bp -> un.encrypted,
					  encode_P2_EncryptedBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;

		    case type_P2_BodyPart_message:
			pushdir (number);
			if (do_fip (bp -> un.message, x40084, qp, perr) == NOTOK)
				return NOTOK;
			popdir ();
			break;
			
		    case type_P2_BodyPart_sfd:
			if (write_pefile (BPT_SFD, number,
					  (caddr_t) bp -> un.sfd,
					  encode_P2_SFDBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;
			
		    case type_P2_BodyPart_mixed__mode:
			if (write_pefile (BPT_TIF1, number,
					  (caddr_t) bp -> un.mixed__mode,
					  encode_P2_MixedModeBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;
		    case type_P2_BodyPart_odif:
			if (write_odif (bp -> un.odif, number, qp, perr) == NOTOK)
				return NOTOK;
			break;

		    case type_P2_BodyPart_nationally__defined:
			if (write_pefile (BPT_NATIONAL, number,
					  (caddr_t) bp -> un.nationally__defined,
					  encode_P2_NationallyDefinedBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;
			
		    case type_P2_BodyPart_bilaterally__defined:
			if (write_pefile (BPT_BILATERAL, number,
					  (caddr_t) bp -> un.bilaterally__defined,
					  encode_P2_BilaterallyDefinedBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;
			
		    case type_P2_BodyPart_externally__defined:
			if (write_pefile (BPT_EXTERNAL, number,
					  (caddr_t) bp -> un.externally__defined,
					  encode_P2_ExternallyDefinedBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;
		    
		    case type_P2_BodyPart_iso6937Text:
			if (write_pefile (BPT_ISO6937TEXT, number,
					  (caddr_t) bp -> un.iso6937Text,
					  encode_P2_ISO6937TextBodyPart,
					  qp, perr) == NOTOK)
				return NOTOK;
			break;
			
		    default:
			PP_LOG (LLOG_EXCEPTIONS,
				("Unknown body part type %d",
				 bp -> offset));
			(void) sprintf (buf,
					"Unknown body part type %d",
					bp->offset);
			*perr = strdup (buf);
			return NOTOK;
		}
		number ++;
	}
	return OK;
}

write_pefile (type, number, parm, fnx, qp, perr)
int	type, number;
caddr_t	parm;
IFP	fnx;
Q_struct	*qp;
char	**perr;
{
	FILE	*fp;
	PE	pe;
	char	buf[BUFSIZ];
	if ( (*fnx)(&pe, 1, NULL, NULLCP, parm) == NOTOK) {
		PP_LOG (LLOG_EXCEPTIONS, ("Can't encode - %s",
					  PY_pepy));
		(void) sprintf (buf,
				"Unable to encode - %s",
				PY_pepy);
		*perr = strdup(buf);
		return NOTOK;
	}

	if ((fp = open_P2_file (type, number, qp, perr)) == NULL) {
		pe_free (pe);
		return NOTOK;
	}
	if (write_pe (pe, fp) == NOTOK) {
		(void) fclose (fp);
		pe_free (pe);
		*perr = strdup("Unable to write_pefile");
		return NOTOK;
	}
	pe_free (pe);
	if (fclose (fp) == EOF)
		return NOTOK;
	return OK;
}

int	write_odif (op, number, Qp, perr)
struct type_P2_ODIFBodyPart *op;
int	number;
Q_struct	*Qp;
char	**perr;
{
	struct qbuf *qp;
	FILE	*fp;

	if ((fp = open_P2_file (BPT_ODIF, number, Qp, perr)) == NULL)
		return NOTOK;

	for (qp = op -> qb_forw; qp != op; qp = qp -> qb_forw)
		if (fwrite (qp -> qb_data, 1, qp -> qb_len, fp)
		    != qp -> qb_len) {
			(void) fclose (fp);
			return NOTOK;
		}
	if (fclose (fp) == EOF)
		return NOTOK;
	return OK;
}

write_ipn (ipn, x40084, qp, perr)
struct type_P2_IPN *ipn;
int	x40084;
Q_struct	*qp;
char	**perr;
{
	PE 	pe;
	if (ipn->choice->offset == choice_P2_0_non__receipt__fields
	    && ipn->choice->un.non__receipt__fields->returned__ipm != NULL) {
		pushdir(2);
		if (write_ipm (ipn -> choice -> un.non__receipt__fields->returned__ipm, x40084, qp, perr) == NOTOK)
			return NOTOK;
		free_P2_IPM(ipn -> choice -> un.non__receipt__fields->returned__ipm);
		ipn -> choice -> un.non__receipt__fields -> returned__ipm = NULL;
		popdir();
	}
	
	if (encode_P2_IPN (&pe, 1, 0, NULLCP, ipn) == NOTOK) 
		return NOTOK;
	
	if (write_bp (hdr_ipn_bp, pe, perr) == NOTOK)
		return NOTOK;
	return OK;
}

int	do_fip (forwarded, x40084, qp, perr)
struct type_P2_MessageBodyPart *forwarded;
int	x40084;
Q_struct	*qp;
char	**perr;
{
	PE	pe;

	if (forwarded -> parameters != NULL
	    && (forwarded -> parameters -> delivery__time != NULL
		|| forwarded -> parameters -> delivery__envelope != NULL)) {
		/* have delivery info put out */
		if (encode_P2_MessageParameters(&pe, 1, 0, 
						NULLCP, 
						forwarded -> parameters) == NOTOK) {
			*perr = strdup("Unable to encode P2_MessageParameters for forwarded message");
			return NOTOK;
		}
		if (write_bp (rcmd_srch (BPT_P2_DLIV_TXT, bptbl_body_parts88),
			      pe,perr) == NOTOK)
			return NOTOK;
	}
	return write_ipm (forwarded -> data, x40084, qp, perr);
}

/* pe_done: utility routine to do the right thing for pe errors */
int             pe_done (pe, msg)
PE              pe;
char            *msg;
{
	if (pe->pe_errno)
	{
		PP_OPER(NULLCP,
			("%s: [%s] %s",msg,PY_pepy,pe_error(pe->pe_errno)));
		pe_free (pe);
		return NOTOK;
	}
	else
	{
		pe_free (pe);
		return OK;
	}
}

/* ps_done: like pe_done */
int             ps_done (ps, msg)
PS              ps;
char           *msg;
{
	ps_advise (ps, msg);
	ps_free (ps);
	return NOTOK;
}

/* \f

 */
/* convert from \r\n to \n */

dumpCRLFstring(fp, pstr)
FILE *fp;
struct type_UNIV_IA5String *pstr;
{
	char	lastc = NULL;
	char	*cp;
	struct qbuf *qb;
	int	n;

	for (qb = pstr -> qb_forw; qb != pstr; qb = qb -> qb_forw) {
		for (n = qb -> qb_len, cp = qb -> qb_data;
		     n > 0; n--, cp++) {
			switch (*cp) {
			    case '\r':
				lastc = *cp;
				break;

			    case '\n':
				putc (*cp, fp);
				lastc = NULL;
				break;

			    default:
				if (lastc) {
					putc (lastc, fp);
					lastc = NULL;
				}
				putc (*cp, fp);
				break;
			}
		}
	}
	if (lastc) putc (lastc, fp);
}

/*
 * write_bp: write a body part contained in pe out to the file named
 * name. name is converted into the correct place in the directory
 * tree.
 */

write_bp(name, pe, perr)
char    *name;
PE      pe;
char	**perr;
{
	FILE    *fp;
	char	filename[FILNSIZE], buf[BUFSIZ];
	
	if (name[0] == '/' ||
	    strncmp (name, "./", 2) == 0 || strncmp (name, "../", 3) == 0)
		sprintf(filename,"%s",name);
	else 
		sprintf(filename, "%s/%s",curdir,name);
	PP_LOG(LLOG_TRACE,
 		("Chans/p2explode writing %s...", filename));

	if((fp = fopen(filename, "w")) == NULL)
	{
		PP_SLOG(LLOG_EXCEPTIONS, filename,
			("Can't open file"));
		(void) sprintf (buf,
				"Unable to open output file '%s'",
				filename);
		*perr = strdup(buf);
		return NOTOK;
	}

	if (write_pe (pe, fp) == NOTOK) {
		(void) sprintf (buf,
				"Failed to write output file '%s'",
				filename);
		*perr = strdup(buf);
		return NOTOK;
	}
	(void) fclose (fp);
	return OK;
}

write_pe (pe, fp)
PE	pe;
FILE	*fp;
{
	PS	psout;

	if ((psout = ps_alloc(std_open)) == NULLPS)
	{
		ps_advise (psout, "ps_alloc");
		(void) fclose (fp);
		return NOTOK;
	}
	if (std_setup (psout, fp) == NOTOK)
	{
		advise (LLOG_EXCEPTIONS, NULLCP, "std_setup loses");
		(void) fclose (fp);
		return NOTOK;
	}

	if(pe2ps(psout, pe) == NOTOK)
	{
		ps_advise(psout, "pe2ps loses");
		return NOTOK;
	}
	ps_free (psout);
	return OK;
}

/* pushdir: used in forwarded ip messages. Decend a level in the
 * directory hierachy.
 */
pushdir (n)
int     n;
{
	char    *p;
	char    name_buf[FILNSIZE];

	(void) sprintf(name_buf, "%d.ipm", n);
	p = makename (name_buf);
	setname (p);            /* clever bit - set new dir name */
	if( mkdir(p, 0755) == NOTOK)
		adios("mkdir", "Can't create directory %s", p);
	PP_LOG(LLOG_TRACE, ("Created %s\n", p));
}

/* makename: convert name into directory path */
char    *makename (name)
char    *name;
{
	static char name_buf[FILNSIZE];
	if (name[0] == '/' || strncmp (name,"./", 2) == 0 ||
	    strncmp (name, "../", 3) ==0)
		/* fullname already */
		return strdup(name);
	else 
		(void) sprintf (name_buf, "%s/%s", curdir, name);
	return name_buf;
}

/* initialise name for above */
setname (name)
char    *name;
{
	(void) strcpy (curdir, name);
/*	printf ("setname -> %s\n", curdir);*/
}

/* popdir: counterpart of pushdir */
popdir()
{
	char    *p;

	if( p = rindex(curdir, '/'))
		*p = '\0';
	else{
    		advise (LLOG_EXCEPTIONS,NULLCP, "Popdir - underflow");
 	}
}

pepy2type (type)
int	type;
{
	switch (type) {
		case 0:
			return BPT_IA5;
		case 1:
			return BPT_TLX;
		case 2:
			return BPT_VOICE;
		case 3:
			return BPT_G3FAX;
		case 4:
			return BPT_TIF0;
		case 5:
			return BPT_TTX;
		case 6:
			return BPT_VIDEOTEX;
		case 7:
			return BPT_NATIONAL;
		case 8:
			return BPT_ENCRYPTED;
/*		case 9:
			forwarded message should be dealt with else where */
		case 10:
			return BPT_SFD;
		case 11:
			return BPT_TIF1;
		case 12:
			return BPT_ODIF;
		default:
			PP_LOG(LLOG_EXCEPTIONS,
				("Chans/p2explode unknown bpt type %d\n",type));
			return BPT_UNDEFINED;
	}
}

FILE *open_P2_file(type, num, qp, perr)
int	type,
	num;
Q_struct	*qp;
char	**perr;
{
	char	*p = NULLCP,
		filename[FILNSIZE], buf[BUFSIZ];
	FILE	*fp;

	if ((p = rcmd_srch(type, bptbl_body_parts88)) != NULLCP
	    && qp != NULL 
	    && list_bpt_find (qp->encodedinfo.eit_types,
			      p) == NULLIST_BPT) {
		/* HACK for undeclared bp that are supported by outchan */
		if (!(outbound_bpts &&
		      list_bpt_find (outbound_bpts, p) != NULLIST_BPT)) {
			sprintf (buf, 
				 "body type '%s' present but undeclared in envelope",
				 p);
			*perr = strdup(buf);
			fatal = OK;
			return NULL;
		} else 
			PP_LOG(LLOG_NOTICE,
			       ("Bodypart '%s' present but undeclared. Outbound channel supports it so letting through", p));
	}
	
	if(p == NULLCP) {
		advise(LLOG_EXCEPTIONS, NULLCP, "Unknown body type %d", type);
		sprintf (filename, "%s/%d", curdir,num);
	} else
    		sprintf(filename, "%s/%d.%s", curdir,num, p);
		
	PP_LOG(LLOG_EXCEPTIONS,
	       ("Chans/p2explode writing %s",filename));

	if ((fp = fopen(filename, "w")) == NULL)
	{
		PP_SLOG(LLOG_EXCEPTIONS, filename,
			("Can't open file"));
		(void) sprintf(buf,
			       "Failed to open output file '%s'",
			       filename);
		*perr = strdup(buf);
		return NULL;
	}
	return fp;
}
/* \f

   ERRORS */

#ifndef lint
void    adios (va_alist)
va_dcl
{
	va_list ap;

	va_start (ap);

	_ll_log (pp_log_norm, LLOG_FATAL, ap);

	va_end (ap);

	_exit (1);
}
#else
/* VARARGS2 */

void    adios (what, fmt)
char   *what,
       *fmt;
{
	adios (what, fmt);
}
#endif


#ifndef lint
void    advise (va_alist)
va_dcl
{
	int     code;
	va_list ap;

	va_start (ap);

	code = va_arg (ap, int);

	_ll_log (pp_log_norm, code, ap);

	va_end (ap);
}
#else
/* VARARGS3 */

void    advise (code, what, fmt)
char   *what,
       *fmt;
int     code;
{
	advise (code, what, fmt);
}
#endif