|
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