|
|
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 x
Length: 27863 (0x6cd7)
Types: TextFile
Names: »x400out88.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/x40088/x400out88.c«
/* x400out88: x400 out bout channel for 1988 stuff */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/x400out88.c,v 5.0 90/09/20 15:58:45 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/x400out88.c,v 5.0 90/09/20 15:58:45 pp Exp Locker: pp $
*
* $Log: x400out88.c,v $
* Revision 5.0 90/09/20 15:58:45 pp
* rcsforce : 5.0 public release
*
*/
#include "head.h"
#include "prm.h"
#include "q.h"
#include "qmgr.h"
#include "dr.h"
#include "rtsparams.h"
#include <sys/stat.h>
#include <sys/file.h>
#include "Transfer-types.h"
#include <isode/rtsap.h>
#include <isode/psap.h>
#include <isode/isoservent.h>
#define MAXTRIES 10
struct type_Transfer_MtsAPDU *build_p1 (), *build_dr (), *build_probe ();
static struct type_MTA_MTABindArgument *convert_prms ();
static int construct_dr (), construct_probe (), construct_msg ();
static int rts_start84 (), rts_start88 ();
static int mctx_id;
int trace_type;
extern char *loc_dom_site,
*mquedir,
*quedfldir;
/* -- statics -- */
static CHAN *mychan;
static char *this_msgid = NULLCP,
*dumpp1 = NULLCP,
*connected_to_site = NULLCP,
*current_mta = NULLCP,
*p1_string,
*p1_ptr;
static int p1_length = 0,
conn_type = NOTOK;
int rts_sd = NOTOK;
static enum { st_init, st_hdr, st_bodyinit, st_body, st_end } trans_state;
/* -- queue variables -- */
static Q_struct Qstruct;
Q_struct *PPQuePtr = &Qstruct;
static DRmpdu DRstruct;
DRmpdu *DRptr = &DRstruct;
static struct prm_vars PRMstruct;
/* -- globals -- */
char *body_string=NULLCP,
*myname;
int body_len=0;
ADDR *ad_list;
/* static functions */
static void dirinit();
static void open_body ();
static void close_body ();
static int initproc();
static int endproc();
static int rts_downtrans_all ();
static int rts_downtrans_inc ();
static int deliver ();
static int get_P2 ();
static int get_DR ();
static int do_pe2ps ();
static int rts_start ();
static int rts_encode_request ();
static int tbl2parameters ();
static int rts_connect ();
static int rts_transfer_request ();
static int parameter_checks ();
static int rts_end ();
static int initproc ();
static int endproc ();
static int read_body ();
static char *pe_flatten ();
static struct type_Qmgr_DeliveryStatus *process ();
/* --------------------- Begin Routines -------------------------------- */
#define STR2QB(s) str2qb (s, strlen (s), 1)
main (argc, argv)
int argc;
char **argv;
{
if (myname = rindex (argv[0], '/'))
myname++;
if (myname == NULL || *myname == NULL)
myname = argv[0];
/* -- read pp tailor file -- */
chan_init (myname);
or_myinit();
dirinit();
#ifdef PP_DEBUG
if (argc > 1 && strcmp (argv[1], "debug") == 0) {
if (argc > 2)
dumpp1 = argv[2];
debug_channel_control (argc, argv,
initproc, process, endproc);
} else
#endif
channel_control (argc, argv, initproc, process, endproc);
exit (0);
}
/* --------------------- Static Routines ------------------------------- */
static void dirinit() /* -- Change into pp queue space -- */
{
PP_TRACE (("dirinit()"));
if (chdir (quedfldir) < 0)
err_abrt (RP_LIO, "Unable to change to dir '%s'", quedfldir);
}
static int initproc (arg)
struct type_Qmgr_Channel *arg;
{
char *channame = qb2str (arg);
PP_TRACE (("initproc (%s)", channame));
if ((mychan = ch_nm2struct (channame)) == NULLCHAN)
adios (NULLCP, "Channel '%s' not known", channame);
PP_NOTICE (("Starting %s (%s)", mychan->ch_name, mychan->ch_show));
prm_init (&PRMstruct);
q_init (PPQuePtr);
dr_init (&DRstruct);
if (current_mta)
free (current_mta);
current_mta = NULLCP;
return OK;
}
static int endproc()
{
switch (rts_end()) {
case OK:
PP_NOTICE (("Connection successfully terminated"));
break;
case NOTOK:
PP_NOTICE (("Connection badly terminated"));
break;
case DONE:
PP_NOTICE (("Connection not made"));
break;
}
return OK;
}
static struct type_Qmgr_DeliveryStatus *process (arg)
struct type_Qmgr_ProcMsg *arg;
{
struct type_Qmgr_UserList *up;
ADDR *ad_sender = NULLADDR,
*asp,
*ad_recip = NULLADDR,
*alp = NULLADDR,
*ap = NULLADDR;
int naddrs = 0,
ad_count,
retval;
if (this_msgid)
free (this_msgid);
this_msgid = qb2str (arg->qid);
PP_NOTICE (("Reading message '%s'", this_msgid));
delivery_init (arg->users);
/* -- queue initialisation - frees memory if called many times -- */
q_free (PPQuePtr);
dr_free (&DRstruct);
prm_free (&PRMstruct);
retval = rd_msg (this_msgid, &PRMstruct, PPQuePtr,
&ad_sender, &ad_recip, &ad_count);
if (rp_isbad (retval)) {
PP_LOG (LLOG_EXCEPTIONS, ("rd_msg %s", this_msgid));
(void) rd_end ();
return (delivery_setallstate (int_Qmgr_status_messageFailure,
"Can't read message"));
}
PP_NOTICE (("Sender '%s'", ad_sender->ad_r400adr));
for (asp = ad_sender, ap = ad_recip; ap; ap = ap -> ad_next) {
for (up = arg->users; up; up = up->next) {
PP_TRACE (("'%s' '%s' ad_no=%d up_no=%d",
this_msgid, ap->ad_value, ap->ad_no,
up->RecipientId->parm));
if (up -> RecipientId -> parm != ap -> ad_no)
continue;
if (dchan_acheck (ap, asp, mychan, naddrs == 0,
¤t_mta) == NOTOK) {
continue;
}
naddrs ++;
break;
}
if (up == NULL)
continue;
if (ad_list == NULLADDR)
ad_list = alp = (ADDR *)calloc(1, sizeof *alp);
else {
alp -> ad_next = (ADDR *)calloc(1, sizeof *alp);
alp = alp -> ad_next;
}
*alp = *ap; /* struct copy */
alp -> ad_next = NULLADDR;
}
if (naddrs == 0) {
PP_LOG (LLOG_EXCEPTIONS,
("No recips to be processed in specified user list"));
rd_end ();
return deliverystate;
}
deliver (ad_list); /* deliverystate set in deliver */
for (alp = ad_list; alp; alp = ap) {
ap = alp -> ad_next;
free ((char *)alp);
}
ad_list = NULLADDR;
rd_end();
return deliverystate;
}
static int deliver (recip)
ADDR *recip;
{
int retval;
int value;
ADDR *ap;
int msgtype;
for (ap = recip; ap; ap = ap -> ad_next)
PP_NOTICE (("Recipient Address '%s'", ap->ad_r400adr));
switch (recip->ad_status) {
case AD_STAT_PEND:
case AD_STAT_DRWRITTEN:
break;
case AD_STAT_DONE:
delivery_setall (int_Qmgr_status_success);
return NOTOK;
default:
PP_LOG (LLOG_EXCEPTIONS, ("bad state"));
delivery_setallstate (int_Qmgr_status_messageFailure,
"bad state");
return NOTOK;
}
if (attempt_connect () != OK)
return NOTOK;
msgtype = Qstruct.msgtype;
if (recip -> ad_status == AD_STAT_DRWRITTEN ||
Qstruct.msgtype == MT_DMPDU) {
retval = construct_dr( &Qstruct, recip);
msgtype = MT_DMPDU;
}
else if (Qstruct.msgtype == MT_PMPDU)
retval = construct_probe (&Qstruct, recip);
else
retval = construct_msg (&Qstruct, recip);
if (retval != OK) {
delivery_setallstate (int_Qmgr_status_messageFailure,
"Can't build message");
return NOTOK;
}
value = rts_transfer_request(msgtype);
if (value == OK)
value = int_Qmgr_status_success;
else if (rts_sd == NOTOK)
value = int_Qmgr_status_mtaAndMessageFailure;
else
value = int_Qmgr_status_messageFailure;
free (p1_string);
for (ap = recip; ap; ap = ap -> ad_next) {
if (ap -> ad_resp) {
delivery_set (ap -> ad_no, value);
if (value == int_Qmgr_status_success)
wr_ad_status (ap, AD_STAT_DONE);
}
}
return OK;
}
attempt_connect ()
{
if (connected_to_site == NULLCP) {
if (rts_start() != OK) {
delivery_setallstate (int_Qmgr_status_mtaFailure,
"Connection failed");
return NOTOK;
}
connected_to_site = strdup (current_mta);
}
else if (lexequ (connected_to_site, current_mta) != 0) {
free (connected_to_site);
connected_to_site = NULLCP;
(void) rts_end();
if (rts_start() != OK) {
delivery_setallstate (int_Qmgr_status_mtaFailure,
"Connection failed");
return NOTOK;
}
connected_to_site = strdup (current_mta);
}
return OK;
}
static int rts_start ()
{
RtsParams *rp;
int retcode, i;
for (i = 0; i < MAXTRIES; i++) {
if ((rp = tb_rtsparams (mychan, current_mta)) == NULL) {
PP_LOG (LLOG_EXCEPTIONS,
("Can't find connect information for %s",
current_mta));
return NOTOK;
}
conn_type = rp -> type;
trace_type = rp -> trace_type;
if (conn_type == RTSP_1984 || conn_type == RTSP_1988_X410MODE)
retcode = rts_start84 (rp);
else
retcode = rts_start88 (rp);
switch (retcode) {
case NOTOK:
if (rp -> try_next) {
free (current_mta);
current_mta = strdup (rp -> try_next);
continue;
}
break;
case OK:
RPfree (rp);
break;
}
break;
}
return retcode;
}
static int rts_start84 (rp)
RtsParams *rp;
{
struct type_MTA_MTABindArgument *mtabind;
struct type_MTA_MTABindResult *mtaresult;
PE pe;
struct RtSAPaddr rtsapto, rtsapfrom;
struct RtSAPaddr *rtto = &rtsapto, *rtfrom = &rtsapfrom;
struct RtSAPconnect rtcs, *rtc = &rtcs;
struct RtSAPindication rtis, *rti = &rtis;
struct RtSAPabort *rta = & rti -> rti_abort;
struct SSAPaddr *sa;
if ((sa = str2saddr (rp -> their_address)) == NULLSA) {
PP_LOG (LLOG_EXCEPTIONS, ("BAD address in table, %s for %s",
rp -> their_address, current_mta));
return NOTOK;
}
rtto -> rta_addr = *sa; /* struct copy */
rtto -> rta_port = rp -> type == RTSP_1984 ? 1 : 12;
if (rp -> our_address) {
if ((sa = str2saddr (rp -> our_address)) == NULLSA) {
PP_LOG (LLOG_EXCEPTIONS,
("Bad address in table, %s for us!",
rp -> our_address));
return NOTOK;
}
rtfrom -> rta_addr = *sa; /* struct copy */
rtfrom -> rta_port = rtto -> rta_port;
}
else rtfrom = NULL;
if ((mtabind = convert_prms (rp)) == NULL)
return NOTOK;
if (encode_MTA_MTABindArgument (&pe, 1, NULLCP, 0, mtabind) == NOTOK) {
free_MTA_MTABindArgument (mtabind);
return NOTOK;
}
PP_PDU (print_MTA_MTABindArgument, pe, "MTA.BindArgument", PDU_WRITE);
PP_NOTICE (("Connecting to site %s", current_mta));
if (RtBeginRequest2 (rtto, rtfrom, rp->rts_mode, RTS_INITIATOR,
pe, rtc, rti) == NOTOK) {
rts_advise (rta, "RT-BEGIN.REQUEST");
pe_free (pe);
free_MTA_MTABindArgument (mtabind);
return NOTOK;
}
pe_free (pe);
free_MTA_MTABindArgument (mtabind);
if (rtc -> rtc_result != RTS_ACCEPT) {
PP_LOG (LLOG_EXCEPTIONS, ("Association rejected: [%s]",
RtErrString (rtc -> rtc_result)));
free_MTA_MTABindResult (mtabind);
RTCFREE (rtc);
return NOTOK;
}
PP_PDU (print_MTA_MTABindResult, rtc -> rtc_data,
"MTA.BindResult", PDU_READ);
if (decode_MTA_MTABindResult (rtc -> rtc_data, 1, NULLVP,
NULLIP, &mtaresult)
== NOTOK) {
PP_LOG (LLOG_EXCEPTIONS, ("Can't decode result [%s]", PY_pepy));
RTCFREE (rtc);
return NOTOK;
}
rts_sd = rtc -> rtc_sd;
RTCFREE (rtc);
if (check_params (rp, mtaresult) != OK) {
rts_end ();
rts_sd = NOTOK;
return NOTOK;
}
PP_NOTICE (("Connected sucessfully"));
return OK;
}
static int rts_start88 (rp)
RtsParams *rp;
{
struct type_Transfer_Bind1988Argument *mtabind;
struct type_Transfer_Bind1988Result *bindresult;
PE pe;
struct PSAPaddr pa_tos, pa_froms;
struct PSAPaddr *pa_to, *pa_from;
struct PSAPctxlist pcs;
struct PSAPctxlist *pc = &pcs;
OID a_ctx, r_ctx, m_ctx, t_ctx;
struct RtSAPconnect rtcs, *rtc = &rtcs;
struct RtSAPindication rtis, *rti = &rtis;
struct RtSAPabort *rta = &rti -> rti_abort;
int n;
if ((mtabind = convert_prms (rp)) == NULL)
return NOTOK;
if (encode_Transfer_Bind1988Argument (&pe, 1, NULLCP,
0, mtabind) == NOTOK) {
PP_LOG (LLOG_EXCEPTIONS, ("encode failed [%s]", PY_pepy));
free_Transfer_Bind1988Argument (mtabind);
return NOTOK;
}
PP_PDU (print_Transfer_Bind1988Argument, pe,
"MTA.BindArgument(1988)", PDU_WRITE);
PP_NOTICE (("Connecting to site %s", current_mta));
if ((pa_to = str2paddr (rp -> their_address)) == NULLPA) {
PP_LOG (LLOG_EXCEPTIONS, ("Can't translate %s",
rp -> their_address));
free_Transfer_Bind1988Argument (mtabind);
pe_free (pe);
return NOTOK;
}
pa_tos = *pa_to; /* struct copy */
pa_to = &pa_tos;
if (rp -> our_address) {
if ((pa_from = str2paddr (rp -> our_address)) == NULLPA) {
PP_LOG (LLOG_EXCEPTIONS, ("Can't translate %s",
rp -> our_address));
free_Transfer_Bind1988Argument (mtabind);
pe_free (pe);
return NOTOK;
}
pa_froms = *pa_from;
pa_from = &pa_froms;
}
else
pa_from = NULLPA;
#define aCSE "2.2.1.0.1"
#define rTSE "2.6.0.2.8"
#define mTSE "2.6.0.2.7"
#define tRANSFER "2.6.0.1.6"
n = 1;
if ((a_ctx = str2oid (aCSE)) == NULLOID)
adios (NULLCP, "No %s object defined", aCSE);
a_ctx = oid_cpy (a_ctx);
pc -> pc_ctx[n-1].pc_id = 2 * n - 1;
pc -> pc_ctx[n-1].pc_asn = oid_cpy (a_ctx);
pc -> pc_ctx[n-1].pc_atn = NULLOID;
n ++;
if ((r_ctx = str2oid (rTSE)) == NULLOID)
adios (NULLCP, "No %s object defined", rTSE);
r_ctx = oid_cpy (r_ctx);
pc -> pc_ctx[n-1].pc_id = 2 * n - 1;
pc -> pc_ctx[n-1].pc_asn = r_ctx;
pc -> pc_ctx[n-1].pc_atn = NULLOID;
n ++;
if ((m_ctx = str2oid (mTSE)) == NULLOID)
adios (NULLCP, "No %s object defined", mTSE);
m_ctx = oid_cpy (m_ctx);
pc -> pc_ctx[n-1].pc_id = mctx_id = 2 * n - 1;
pc -> pc_ctx[n-1].pc_asn = m_ctx;
pc -> pc_ctx[n-1].pc_atn = NULLOID;
pc -> pc_nctx = n;
if ((t_ctx = str2oid (tRANSFER)) == NULLOID)
adios (NULLCP, "No %s object defined", tRANSFER);
t_ctx = oid_cpy (t_ctx);
if (RtOpenRequest2 (rp -> rts_mode, RTS_INITIATOR, t_ctx,
NULLAEI, NULLAEI,
pa_from, pa_to, pc, a_ctx, pe, NULLQOS,
oid_cpy (r_ctx), rtc, rti) == NOTOK) {
rts_advise (rta, "RT-OPEN.REQUEST");
return NOTOK;
}
if (rtc -> rtc_result != RTS_ACCEPT) {
PP_LOG (LLOG_EXCEPTIONS, ("Association rejected: [%s]",
RtErrString (rtc -> rtc_result)));
RTCFREE (rtc);
return NOTOK;
}
rts_sd = rtc -> rtc_sd;
PP_PDU (print_Transfer_Bind1988Result, rtc -> rtc_data,
"MTA.BindResult", PDU_READ);
if (decode_Transfer_Bind1988Result (rtc -> rtc_data, 1, NULLVP,
NULLIP, &bindresult) == NOTOK) {
PP_LOG (LLOG_EXCEPTIONS,
("Can't decode result [%s]", PY_pepy));
RTCFREE (rtc);
return NOTOK;
}
if (check_params (rp, bindresult) != OK) {
RTCFREE (rtc);
free_Transfer_Bind1988Result (bindresult);
rts_end ();
return NOTOK;
}
RTCFREE (rtc);
free_Transfer_Bind1988Result (bindresult);
PP_NOTICE (("Connected Successfully"));
return OK;
}
static struct type_MTA_MTABindArgument *convert_prms (rp)
RtsParams *rp;
{
struct type_MTA_MTABindArgument *bindarg;
struct member_MTA_4 *mp;
struct type_MTA_InitiatorCredentials *ic;
bindarg = (struct type_MTA_MTABindArgument *)
smalloc (sizeof *bindarg);
bindarg -> offset = type_MTA_MTABindArgument_2;
bindarg -> un.choice_MTA_9 = mp = (struct member_MTA_4 *)
smalloc (sizeof *mp);
mp -> initiator__name = STR2QB (rp -> our_name);
mp -> initiator__credentials = ic =
(struct type_MTA_InitiatorCredentials *)
smalloc (sizeof *ic);
ic -> offset = type_MTA_InitiatorCredentials_2;
ic -> un.choice_MTA_5 = STR2QB (rp -> our_passwd);
mp -> security__context = NULL;
return bindarg;
}
check_params (rp, bindresult)
RtsParams *rp;
struct type_MTA_MTABindResult *bindresult;
{
char *str;
struct member_MTA_5 *mp;
switch (bindresult -> offset) {
case type_MTA_MTABindResult_2:
break;
case type_MTA_MTABindResult_1:
default:
PP_LOG (LLOG_EXCEPTIONS, ("Bad result type"));
return NOTOK;
}
mp = bindresult -> un.choice_MTA_11;
str = qb2str (mp -> responder__name);
if (strcmp (str, rp -> their_name) != 0) {
PP_LOG (LLOG_EXCEPTIONS, ("mta name mismatch %s %s",
str, rp -> their_name));
free (str);
return NOTOK;
}
free (str);
switch (mp -> responder__credentials -> offset) {
case type_MTA_ResponderCredentials_1:
case type_MTA_ResponderCredentials_2:
break;
default:
PP_LOG (LLOG_EXCEPTIONS, ("Not an octet string"));
return NOTOK;
}
str = qb2str (mp -> responder__credentials->un.choice_MTA_7);
if (rp -> their_passwd == NULLCP) {
PP_LOG (LLOG_EXCEPTIONS,
("No remote password specifed in table"));
return NOTOK;
}
if (strcmp (str, rp -> their_passwd) != 0) {
PP_LOG (LLOG_EXCEPTIONS, ("passwd mismatch %s %s",
str, rp -> their_passwd));
free (str);
return NOTOK;
}
free (str);
return OK;
}
static struct timeval data_timer;
static int data_bytes;
static int rts_transfer_request (type)
int type;
{
struct RtSAPindication rtis;
register struct RtSAPindication *rti = &rtis;
register struct RtSAPabort *rta = &rti -> rti_abort;
PP_TRACE (("rts_transfer_request()"));
trans_state = st_init;
switch (type) {
case MT_PMPDU:
case MT_DMPDU:
if (RtSetDownTrans (rts_sd, rts_downtrans_all, rti) == NOTOK) {
rts_advise (rta, "set DownTrans upcall");
return NOTOK;
}
break;
default:
case MT_UMPDU:
if (RtSetDownTrans (rts_sd, rts_downtrans_inc, rti) == NOTOK) {
rts_advise (rta, "set DownTrans upcall");
return NOTOK;
}
break;
}
data_bytes = 0;
timer_start (&data_timer);
if (RtTransferRequest (rts_sd, NULLPE, NOTOK, rti) == NOTOK) {
rts_advise (rta, "RT-TRANSFER.REQUEST");
return NOTOK;
}
timer_end (&data_timer, data_bytes, "Trasnfer Completed");
PP_NOTICE((">>> Message %s transfered to %s",
this_msgid, current_mta));
return OK;
}
/* ARGSUSED */
static int rts_downtrans_inc (sd, base, len, size, ssn, ack, rti)
int sd;
char **base;
int *len,
size;
long ssn,
ack;
struct RtSAPindication *rti;
{
int cc, count;
int n;
char *ptr, *p;
static char *trans_buf;
static int bsize;
PP_TRACE (("rts_downtrans_inc (%d, base, len, %d, %ld, %ld, rti)",
sd, size, ssn, ack));
if (base == NULLVP) {
PP_DBG (("RT-PLEASE.INDICATION: %d", size));
return OK;
}
if (trans_buf == NULLCP) {
if (size == 0) /* no checkpointing... */
n = BUFSIZ * 10;
else
n = size;
if ((trans_buf = malloc ((unsigned) n)) == NULL)
return (rtsaplose (rti, RTS_CONGEST,
NULLCP, "out of memory"));
PP_TRACE (("Selecting block size of %d", n));
bsize = n;
}
if (size > 0 && size < bsize) {
PP_LOG (LLOG_EXCEPTIONS, ("downtrans size decreased..."));
bsize = size;
}
for (n = bsize, p = trans_buf, count = 0; n > 0;) {
if ((cc = get_more_message (&ptr, n)) == 0)
break;
bcopy (ptr, p, cc);
p += cc;
n -= cc;
count += cc;
}
if (dumpp1)
dumptofile (trans_buf, count, dumpp1);
if (count == 0) {
*base = NULLCP;
*len = 0;
free (trans_buf);
trans_buf = NULLCP;
return OK;
}
*base = trans_buf;
*len = count;
data_bytes += count;
PP_TRACE (("rts_downtrans_inc read %d bytes (%d checkpoint)",
count, bsize));
return OK;
}
int get_more_message (dptr, dlen)
char **dptr;
int dlen;
{
static char eoc[3];
static char *ptr;
static int len = 0, inited = 0;
static char buffer[BUFSIZ * 8];
char *cp;
int n;
PE pe;
PP_TRACE (("get_more_message (%d)", dlen));
if (!inited) {
pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_UNIV_EOC);
inited = 3;
(void) pe_flatten (pe, eoc, 1, &inited);
pe_free (pe);
}
if (len <= 0) {
switch (trans_state) {
case st_init:
cp = buffer; len = 0;
if (conn_type == RTSP_1988_NORMAL) {
pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS,
PE_CONS_EXTN);
pe -> pe_len = PE_LEN_INDF;
n = sizeof buffer;
(void) pe_flatten (pe, cp, -1, &n);
pe_free (pe);
cp = buffer + n;
len += n;
pe = int2prim (mctx_id);
n = (sizeof buffer) - len;
(void) pe_flatten (pe, cp, -1, &n);
cp = cp + n;
len += n;
pe_free (pe);
pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, 0);
pe -> pe_len = PE_LEN_INDF;
n = (sizeof buffer) - len;
(void) pe_flatten (pe, cp, -1, &n);
cp = cp + n;
len += n;
pe_free (pe);
}
pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, 0);
pe -> pe_len = PE_LEN_INDF;
n = (sizeof buffer) - len;
(void) pe_flatten (pe, cp, -1, &n);
len += n;
pe_free (pe);
trans_state = st_hdr;
ptr = buffer;
break;
case st_hdr:
len = p1_length;
ptr = p1_string;
trans_state = st_bodyinit;
break;
case st_bodyinit:
pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_PRIM_OCTS);
pe -> pe_len = PE_LEN_INDF;
len = sizeof buffer;
(void) pe_flatten (pe, buffer, -1, &len);
pe_free (pe);
ptr = buffer;
open_body ();
trans_state = st_body;
break;
case st_body:
len = n;
if ((len = read_body (buffer, sizeof buffer)) != 0) {
ptr = buffer;
break;
}
close_body ();
cp = buffer;
len = 0;
if (conn_type == RTSP_1988_NORMAL) {
bcopy (eoc, cp, 2);
cp += 2; len += 2;
bcopy (eoc, cp, 2);
cp += 2; len += 2;
}
bcopy (eoc, cp, 2); /* end of octet string (contents) */
cp += 2; len += 2;
bcopy (eoc, cp, 2); /* end of hdr sequence */
cp += 2; len += 2;
ptr = buffer;
trans_state = st_end;
break;
case st_end:
return 0;
}
}
*dptr = ptr;
n = MIN (dlen, len);
len -= n;
ptr += n;
PP_TRACE (("get_more_message returneing %d bytes", n));
return n;
}
static int rts_downtrans_all (sd, base, len, size, ssn, ack, rti)
int sd;
char **base;
int *len,
size;
long ssn,
ack;
struct RtSAPindication *rti;
{
int n;
static char *trans_buf;
static int bsize;
PP_TRACE (("rts_downtrans_all (%d, base, len, %d, %ld, %ld, rti)",
sd, size, ssn, ack));
if (base == NULLVP) {
PP_DBG (("RT-PLEASE.INDICATION: %d", size));
return OK;
}
if (trans_buf == NULLCP) {
if (size == 0) /* no checkpointing... */
n = p1_length;
else
n = size;
if ((trans_buf = malloc ((unsigned) n)) == NULL)
return (rtsaplose (rti, RTS_CONGEST,
NULLCP, "out of memory"));
PP_TRACE (("Selecting block size of %d", n));
bsize = n;
}
if (size > 0 && size < bsize) {
PP_LOG (LLOG_EXCEPTIONS, ("downtrans size decreased..."));
bsize = size;
}
n = MIN(bsize, p1_length);
if (n == 0) {
free(trans_buf);
trans_buf = NULLCP;
*base = NULLCP;
*len = 0;
return OK;
}
*base = p1_ptr;
*len = n;
data_bytes += n;
p1_ptr += n;
p1_length -= n;
if (dumpp1)
dumptofile (*base, *len, dumpp1);
return OK;
}
static char *pe_flatten (pe, buffer, flag, ccp)
PE pe;
char *buffer;
int *ccp;
int flag;
{
PS ps;
char *cp;
if ((ps = ps_alloc (str_open)) == NULLPS)
adios (NULLCP, "ps_alloc failed");
if (str_setup (ps, buffer, *ccp, buffer == NULLCP ? 0 : 1) == NOTOK)
adios (NULLCP, "str_setup failed", ps_error (ps -> ps_errno));
if (pe2ps_aux (ps, pe, flag) == NOTOK)
adios (NULLCP, "pe2ps failed [%s]", ps_error (ps -> ps_errno));
*ccp = ps -> ps_ptr - ps -> ps_base;
cp = ps -> ps_base;
ps -> ps_base = NULLCP;
ps_free (ps);
return cp;
}
static int rts_end ()
{
struct RtSAPindication rtis, *rti = &rtis;
struct RtSAPabort *rta = &rti -> rti_abort;
struct AcSAPrelease acrs;
register struct AcSAPrelease *acr = &acrs;
if (rts_sd == NOTOK)
return DONE;
if (conn_type == RTSP_1988_NORMAL) {
if (RtCloseRequest (rts_sd, ACF_NORMAL, NULLPE,
acr, rti) == NOTOK) {
rts_advise (rta, "RT-CLOSE.REQUEST");
(void) RtUAbortRequest (rts_sd, NULLPE, rti);
return NOTOK;
}
if (!acr -> acr_affirmative) {
(void) RtUAbortRequest (rts_sd, NULLPE, rti);
advise (NULLCP,
"release rejected by peer: %d, %d elements",
acr -> acr_reason, acr -> acr_ninfo);
}
ACRFREE (acr);
}
else {
if (RtEndRequest (rts_sd, rti) == NOTOK) {
rts_advise (rta, "RT-END.REQUEST");
rts_sd = NOTOK;
return NOTOK;
}
}
rts_sd = NOTOK;
return OK;
}
#ifdef PP_DEBUG
dumptofile (str, n, file)
char *str;
int n;
char *file;
{
FILE *fp;
static int once_only = 0;
if ((fp = fopen (file, once_only ? "a": "w")) == NULL) {
advise (LLOG_NOTICE, NULLCP, file, "Can't open file");
return;
}
once_only ++;
fwrite (str, 1, n, fp);
(void) fclose (fp);
}
#endif
static FILE *body_fp;
static void open_body ()
{
char filename[FILNSIZE],
*msgdir = NULLCP;
if (body_fp)
close_body ();
if (qid2dir (this_msgid, ad_list, TRUE, &msgdir) == NOTOK)
adios (NULLCP, "Can't find message %s", this_msgid);
if (rp_isbad (msg_rinit (msgdir)))
adios (NULLCP, "Can't initialise directory %s", msgdir);
if (rp_isbad (msg_rfile (filename)))
adios (NULLCP, "Can't read file-name");
(void) msg_rend ();
if ((body_fp = fopen (filename, "r")) == NULL)
adios (filename, "Can't open file");
}
static int read_body (buf, size)
char *buf;
int size;
{
int len, i;
static PE pe = NULLPE;
PE pe2;
char tbuf[BUFSIZ*8];
PP_TRACE (("read_body (%d)", size));
if (pe == NULLPE)
pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_OCTS);
pe -> pe_len = size;
pe -> pe_len -= ps_get_abs (pe) - size;
for (i = 0; i < 10; i++) {
if (ps_get_abs(pe) <= size)
break;
pe -> pe_len -= 2;
}
if ( i >= 10)
adios (NULLCP, "Can't sort out asn1 length after 10 attempts");
if ((len = fread (tbuf, 1, pe -> pe_len, body_fp)) <= 0) {
if (ferror (body_fp))
adios ("fread", "error on file");
else if (feof (body_fp))
return 0;
}
pe2 = oct2prim (tbuf, len);
(void) pe_flatten (pe2, buf, 1, &size);
PP_TRACE (("octet string of length %d returned (%d)",
pe2 -> pe_len, size));
pe_free (pe2);
return size;
}
static void close_body ()
{
if (body_fp)
fclose (body_fp);
body_fp = NULL;
}
static int construct_msg (qp, recip)
Q_struct *qp;
ADDR *recip;
{
struct type_Transfer_MtsAPDU *p1;
PE pe;
if ((p1 = build_p1 (qp, recip)) == NULL) {
delivery_setallstate (int_Qmgr_status_messageFailure,
"Can't build P1 information");
return NOTOK;
}
if (encode_MTA_MessageTransferEnvelope (&pe, 1, NULLCP, 0,
p1 -> un.message -> envelope)
== NOTOK) {
PP_LOG (LLOG_EXCEPTIONS,
("Error encoding MessageTransferEnvelope [%s]",
PY_pepy));
pe_free (pe);
free_Transfer_MtsAPDU (p1);
return NOTOK;
}
PP_PDU (print_MTA_MessageTransferEnvelope, pe,
"MTA.MessageTransferEnvelope", PDU_WRITE);
p1_length = 0;
p1_string = p1_ptr = pe_flatten (pe, NULLCP, 1, &p1_length);
free_Transfer_MtsAPDU (p1);
pe_free (pe);
return OK;
}
static int construct_probe (qp, recip) /* XXX */
Q_struct *qp;
ADDR *recip;
{
struct type_Transfer_MtsAPDU *p1;
PE pe;
if ((p1 = build_probe (qp, recip)) == NULL) {
delivery_setallstate (int_Qmgr_status_messageFailure,
"Can't build probe");
return NOTOK;
}
if (encode_Transfer_MtsAPDU (&pe, 1, NULLCP, 0, p1) == NOTOK) {
PP_LOG (LLOG_EXCEPTIONS,
("Error encoding MtsAPDU [%s]", PY_pepy));
if (pe)
pe_free (pe);
free_Transfer_MtsAPDU (p1);
return NOTOK;
}
PP_PDU (print_Transfer_MtsAPDU, pe, "MTA.MtsAPDU", PDU_WRITE);
p1_length = 0;
p1_string = p1_ptr = pe_flatten (pe, NULLCP, 1, &p1_length);
free_Transfer_MtsAPDU (p1);
pe_free (pe);
return OK;
}
static int construct_dr (qp, recip)
Q_struct *qp;
ADDR *recip;
{
static DRmpdu drs;
DRmpdu *dr = &drs;
struct type_Transfer_MtsAPDU *p1dr;
PE pe = NULLPE;
dr_free (dr);
if (rp_isbad (get_dr (recip -> ad_no, this_msgid, dr))) {
PP_LOG (LLOG_EXCEPTIONS,
("Can't read delivery report for %s/%d",
this_msgid, recip -> ad_no));
delivery_setallstate (int_Qmgr_status_messageFailure,
"Can't read DR");
return NOTOK;
}
if ((p1dr = build_dr (qp, recip, dr)) == NULL) {
PP_LOG (LLOG_EXCEPTIONS,
("Can't build P1 DR structure"));
delivery_setallstate (int_Qmgr_status_messageFailure,
"Can't build DR");
return NOTOK;
}
if (encode_Transfer_MtsAPDU (&pe, 1, NULLCP, 0,
p1dr)
== NOTOK) {
PP_LOG (LLOG_EXCEPTIONS,
("Error encoding MtsAPDU [%s]",
PY_pepy));
if (pe)
pe_free (pe);
free_Transfer_MtsAPDU (p1dr);
return NOTOK;
}
PP_PDU (print_Transfer_MtsAPDU, pe,
"MTA.MtsAPDU", PDU_WRITE);
p1_length = 0;
p1_string = p1_ptr = pe_flatten (pe, NULLCP, 1, &p1_length);
free_Transfer_MtsAPDU (p1dr);
pe_free (pe);
return OK;
}