|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 17819 (0x459b)
Types: TextFile
Names: »p2explode.c«
└─⟦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«
/* 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