|
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 e
Length: 8083 (0x1f93) Types: TextFile Names: »explode_chan.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Format/p2explode/explode_chan.c«
/* p2explode: channel to explode a P2 message into body parts */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Format/p2explode/RCS/explode_chan.c,v 5.0 90/09/20 16:00:37 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Format/p2explode/RCS/explode_chan.c,v 5.0 90/09/20 16:00:37 pp Exp Locker: pp $ * * $Log: explode_chan.c,v $ * Revision 5.0 90/09/20 16:00:37 pp * rcsforce : 5.0 public release * */ #include "util.h" #include "qmgr.h" #include "q.h" #include "prm.h" #include "retcode.h" #include "tb_bpt88.h" #include "dr.h" #include <sys/stat.h> #include <sys/file.h> #include <isode/cmd_srch.h> extern CMD_TABLE bptbl_body_parts88[/* x400 84 body_parts */]; extern char *quedfldir; extern char *mquedir; extern CHAN *ch_nm2struct(); extern char *cont_p2; extern void rd_end(), sys_init(), err_abrt(); extern struct type_Qmgr_DeliveryStatus *delivery_resetDRs(); extern int fatal; static CHAN *mychan; static char *this_msg, *this_chan; static int processMsg(); static int doSplit(); static struct type_Qmgr_DeliveryStatus *process(); static int initialise(); static int security_check(), x40084; static void dirinit(); static ADDR *getnthrecip (); int first_failureDR; /* \f */ /* main routine */ main(argc, argv) int argc; char **argv; { sys_init(argv[0]); 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 */ /* 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; name = qb2str(arg); if ((mychan = ch_nm2struct(name)) == NULLCHAN) { PP_OPER(NULLCP, ("Chans/p2explode : Channel '%s' not known",name)); if (name != NULL) free(name); return NOTOK; } return OK; } /* \f */ 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/explode_chan 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 to do explode */ 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, retval; struct type_Qmgr_UserList *ix; ADDR *adr; char *error; bzero((char *)&que,sizeof(que)); bzero((char *)&prm,sizeof(prm)); 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_TRACE, ("P2 explode on 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/explode_chan rd_msg err: '%s'",this_msg)); rd_end(); return delivery_setallstate (int_Qmgr_status_messageFailure, "Can't read message"); } for (ix = arg->users; ix; ix=ix->next) { error = NULLCP; fatal = NOTOK; if ((adr = getnthrecip(&que, ix->RecipientId->parm)) == NULL) { PP_LOG(LLOG_EXCEPTIONS, ("Chans/explode_chan : failed to find recipient %d",ix->RecipientId->parm)); 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 (processMsg(this_msg,adr,&que,&error) == NOTOK) { if (fatal == OK) { PP_LOG(LLOG_EXCEPTIONS, ("Chans/explode_chan : failed to process message '%s' for recipient %d",this_msg,adr->ad_no)); set_1dr(&que, adr->ad_no, DRR_CONVERSION_NOT_PERFORMED, DRD_CONTENT_SYNTAX_ERROR, (error == NULLCP) ? "Unable to parse the p2" : error); delivery_set(adr->ad_no, (first_failureDR == TRUE) ? int_Qmgr_status_negativeDR : int_Qmgr_status_failureSharedDR); first_failureDR = FALSE; } else delivery_setstate(adr -> ad_no, int_Qmgr_status_messageFailure, (error == NULLCP) ? "" : error); } else { adr->ad_rcnt++; wr_ad_rcntno(adr, adr->ad_rcnt); delivery_set(adr->ad_no,int_Qmgr_status_success); } if (error != NULLCP) free(error); break; default: break; } } 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 */ extern LIST_BPT *outbound_bpts; /* returns ok if processed msg on mychan for recip */ static int processMsg (msg,recip, qp, perr) char *msg; ADDR *recip; Q_struct *qp; char **perr; { char *origdir = NULL, *newdir = NULL, *encr_str = NULLCP; struct stat statbuf; if (qid2dir(msg, recip, TRUE, &origdir) != OK) { PP_LOG(LLOG_EXCEPTIONS, ("Chans/explode_chan original directory not found for recipient %d of message '%s'",recip->ad_no, msg)); *perr = strdup("Unable to find source directory"); return NOTOK; } /* temporary change to get new directory name */ recip->ad_rcnt++; if (qid2dir(msg, recip, FALSE, &newdir) != OK) { PP_LOG(LLOG_EXCEPTIONS, ("Chans/explode_chan couldn't construct new directory name for recipient %d of message '%s'", recip->ad_no, msg)); *perr = strdup ("Unable to construct new directory"); return NOTOK; } recip->ad_rcnt--; if (stat(newdir, &statbuf) == OK && (statbuf.st_mode & S_IFMT) == S_IFDIR) { /* new directory already exists, os processing already done */ if (origdir != NULL) free(origdir); if (newdir != NULL) free(newdir); return OK; } x40084 = (lexequ(qp->cont_type, cont_p2) == 0) ? TRUE : FALSE; /* HACK for undeclared bodyparts that are supported by outchan */ if (recip -> ad_outchan && recip -> ad_outchan -> li_chan && recip -> ad_outchan -> li_chan -> ch_bpt_out) outbound_bpts = recip -> ad_outchan -> li_chan -> ch_bpt_out; else outbound_bpts = NULLIST_BPT; if (doSplit(origdir,newdir,msg,qp,perr) != OK) return NOTOK; if (origdir != NULL) free(origdir); if (newdir != NULL) free(newdir); return OK; } /* \f */ /* explodes p2 in orig into files in new */ static int doSplit (old, new,msg,qp,perr) char *old, *new, *msg; Q_struct *qp; char **perr; { struct stat statbuf; char tmpdir[FILNSIZE], buf[BUFSIZ]; int result = OK; (void) sprintf(tmpdir, "%s/%s/tmp.%s", mquedir,msg,mychan->ch_name); if (stat(tmpdir, &statbuf) == OK) { /* exists so remove it */ char *cmdline = malloc((unsigned) (strlen("rm -rf ") + strlen(tmpdir) + 1)); (void) sprintf(cmdline, "rm -rf %s",tmpdir); system(cmdline); if (cmdline != NULL) free(cmdline); } if (mkdir(tmpdir, 0777) != OK) { PP_SLOG(LLOG_EXCEPTIONS, tmpdir, ("Can't make directory")); (void) sprintf(buf, "Failed to make temporary directory '%s'", tmpdir); *perr = strdup(buf); return NOTOK; } result = unflatten(old,tmpdir, x40084, qp, perr); if ((result == OK) && (rename(tmpdir,new) == -1)) { PP_SLOG(LLOG_EXCEPTIONS, "rename", ("Can't rename directory '%s' to '%s'", tmpdir, new)); result = NOTOK; } return result; } 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; }