|
|
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;
}