|
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: 12788 (0x31f4) Types: TextFile Names: »x400in84.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Chans/x40084/x400in84.c«
/* x400in84.c: receives the incomming x400 messages */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40084/RCS/x400in84.c,v 5.0 90/09/20 15:56:30 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Chans/x40084/RCS/x400in84.c,v 5.0 90/09/20 15:56:30 pp Exp Locker: pp $ * * $Log: x400in84.c,v $ * Revision 5.0 90/09/20 15:56:30 pp * rcsforce : 5.0 public release * */ #include "head.h" #include "prm.h" #include "dr.h" #include "q.h" #include "RTS84-types.h" #include <sys/stat.h> #include <isode/rtsap.h> #include <isode/psap.h> #include <isode/isoservent.h> #include <isode/cmd_srch.h> /* -- defines -- */ /* --- hex dump of msg --- */ #define qb2postie(qb) (send2postie (NULLPE, qb, 0)) /* --- splat of msg --- */ #define pe2postie1(pe) (send2postie (pe, (struct qbuf *)0, 1)) /* --- pretty print of msg --- */ #define pe2postie(pe) (send2postie (pe, (struct qbuf *)0, 2)) #define RTS_MAX_NO_OF_TURNS 5 #define RTS_SENT_TURN 'S' #define SUBMIT_NOT_CALLED 1 /* -- externals -- */ extern int errno, body_len; extern char *isodesetailor(), *hdr_p2_bp, *cont_p2, *loc_dom_site, *quedfldir, *body_string, *rcmd_srch(), *remote_site; extern int hdrproc(), bodyproc(), msgfinished(); extern void isodetailor(); extern ADDR *adr_new(); extern Q_struct *PPQuePtr; extern DRmpdu *DRptr; extern CMD_TABLE qtbl_mt_type[]; extern IFP asn_procfnx; /* -- statics -- */ static struct timeval data_timer; static int data_bytes=0, initial_mode, initial_turn, nturns=0, rts_uptrans(); int submit_running = 0; static char turn_status=' '; CHAN *mychan; /* -- globals -- */ char *myname = "x400in84"; #ifdef PP_DEBUG static int do_debug_transfer(); #endif /* -- local routines -- */ void set_msg_adrs(); static int qblen(); static int rts_uptrans(); static int rts_do_turn(); static void rts_get_request(); static void rts_abort(); static void rts_close(); static void rts_get_request(); static void rts_indication(); /* --------------------- Main Routine ---------------------------------- */ /*ARGSUSED)*/ main (argc, argv, envp) int argc; char **argv, **envp; { int sd; struct RtSAPstart rtss; register struct RtSAPstart *rts = &rtss; struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; register struct RtSAPabort *rta = &rti -> rti_abort; struct SSAPaddr *sai = &rts -> rts_initiator.rta_addr; struct TSAPaddr *tai = &sai -> sa_addr; struct NSAPaddr *nai = tai -> ta_addrs; PE accept_pe = NULLPE; struct type_RTS84_Request *request = 0; int retval; RP_Buf rps, *rp = &rps; int opt; extern char *optarg; extern int optind; /* -- Reading of the tailor file info -- */ if (myname = rindex (argv[0], '/')) myname++; if (myname == NULL || *myname == NULL) myname = argv[0]; while ((opt = getopt (argc, argv, "c:")) != EOF) { switch (opt) { case 'c': myname = optarg; break; default: adios (NULLCP, "Unknown argument -%c", opt); } } chan_init (myname); if ((mychan = ch_nm2struct (myname)) == NULLCHAN) adios (NULLCP, "No such channel %s", myname); pp_setuserid(); (void) chdir (quedfldir); or_myinit(); PP_NOTICE (("Starting %s (%s)", mychan->ch_name, mychan->ch_show)); /* --- *** --- Since isode/isoservices calls x400in84, the RTS connection needs to be terminated, if an error occurs, otherwise the connection hangs ... the remote initiator waits for a response and none is forthcoming ... --- *** --- */ #if PP_DEBUG if (argv[optind] && strcmp (argv[optind], "debug") == 0) { do_debug_transfer(); exit (0); } #endif if (RtBInit (argc, argv, rts, rti) == NOTOK) { rts_exceptions (rta, "RtBInit"); exit (NOTOK); } /* --- And lots & lots of tracing! --- */ PP_TRACE (("RT-BEGIN.INDICATION: <%d, %s, %s, %d, 0x%x>", rts->rts_sd, rts->rts_mode == RTS_TWA ? "twa" : "mon", rts->rts_turn == RTS_RESPONDER ? "responder" : "initiator", ntohs (rts->rts_port), rts->rts_data)); PP_TRACE (("Calling addresses: <<%s, %s>, %s>", na2str (nai), sel2str (tai->ta_selector, tai->ta_selectlen, 1), sel2str (sai->sa_selector, sai->sa_selectlen, 1))); PP_TRACE (("more .... <<%s, '%s' '%d'>, '%s' '%d'>", na2str (nai), &tai->ta_selector[0], tai->ta_selectlen, &sai->sa_selector[0], sai->sa_selectlen)); /* -- Important in determining the logic of the RTS turns -- */ initial_mode = rts->rts_mode; initial_turn = rts->rts_turn; sd = rts -> rts_sd; /* -- x400in84 never transmits information -- */ if (initial_turn == RTS_RESPONDER && initial_mode == RTS_MONOLOGUE) { do_reason ("main/turn=responder && mode=monologue"); RtBeginResponse (sd, RTS_REJECT, NULLPE, rti); exit (NOTOK); } if (rts->rts_data == NULLPE) { do_reason ("main/Rejected -- no user data parameter"); RtBeginResponse (sd, RTS_REJECT, NULLPE, rti); exit (NOTOK); } PP_PDU (print_RTS84_Request, rts -> rts_data, "RTS84.Request", PDU_READ); if ((retval = rts_decode_request (rts, &accept_pe, &request, mychan)) != OK) { RtBeginResponse (sd, retval, NULLPE, rti); exit (NOTOK); } PP_PDU (print_RTS84_Request, accept_pe, "RRTS84.Response", PDU_WRITE); if (RtBeginResponse (sd, RTS_ACCEPT, accept_pe, rti) == NOTOK) { rts_advise (rta, "RT-BEGIN.RESPONSE Accept"); RtBeginResponse (sd, RTS_REMOTE, NULLPE, rti); exit (NOTOK); } if (accept_pe) pe_free (accept_pe); if (request) free_RTS84_Request (request); /* --- *** --- Initialise submit as late as possible so if error occurs earlier on x400in and submit are not both running. --- *** --- */ if (rp_isbad (io_init(rp))) adios (NULLCP, "io_init error: %s", rp -> rp_line); submit_running = 1; /* -- Returns the turn. x400in84 never transmits info -- */ if (initial_turn == RTS_RESPONDER) { if (RtGTurnRequest (sd, rti) == NOTOK) rts_adios (rta, "RT-TURN-GIVE.REQUEST"); turn_status = RTS_SENT_TURN; nturns++; } RTSFREE (rts); /* -- Sets up the RTS to receive incomming data -- */ if (RtSetUpTrans (sd, rts_uptrans, rti) == NOTOK) rts_adios (rta, "RtSetUpTrans upcall"); rts_get_request (sd); do_reason ("main/Impossible to arrive here!"); exit (NOTOK); } void set_msg_adrs() { ADDR *ap; for (ap = PPQuePtr->Raddress; ap; ap = ap->ad_next) if (ap->ad_resp == NO) ap->ad_status = AD_STAT_DONE; } /* --------------------- Static Routines ------------------------------- */ static void rts_get_request (sd) int sd; { struct RtSAPindication rti; int loop_forever = TRUE, result; while (loop_forever) { switch (result = RtWaitRequest (sd, NOTOK, &rti)) { case NOTOK: case OK: case DONE: PP_TRACE (("rts_get_request (%d)", result)); rts_indication (sd, &rti); break; default: do_reason ("rts_get_request/result='%d'", result); } } } static void rts_indication (sd, rti) int sd; struct RtSAPindication *rti; { switch (rti->rti_type) { case RTI_TURN: PP_TRACE (("RTI_TURN")); if (rts_do_turn (sd, &rti->rti_turn) == NOTOK) rts_abort (sd, &rti->rti_abort); break; case RTI_TRANSFER: PP_TRACE (("RTI_TRANSFER")); /* -- rts_uptrans() does all the work -- */ timer_end (&data_timer, data_bytes, "Transfer Completed"); break; case RTI_ABORT: PP_TRACE (("RTI_ABORT")); rts_abort (sd, &rti->rti_abort); break; case RTI_CLOSE: PP_TRACE (("RTI_CLOSE")); rts_close (sd, &rti->rti_close); break; default: do_reason ("rts_indication/'%d' unknown", rti->rti_type); rts_abort (sd, &rti->rti_abort); break; } } static int rts_do_turn (sd, rtu) int sd; struct RtSAPturn *rtu; { struct RtSAPindication rti; PP_TRACE (("rts_do_turn %s %s %d %s", initial_mode == RTS_TWA ? "twa" : "mon", initial_turn == RTS_RESPONDER ? "responder" : "initiator", nturns, turn_status == RTS_SENT_TURN ? "send" : "received")); /* -- Remote site is requesting the turn which x400in84 -- */ /* -- already possesses -- */ if (rtu->rtu_please) if (turn_status == RTS_SENT_TURN) { do_reason ("rts_do_turn/Already sent turn!"); return NOTOK; } else { /* -- should never have turn! but left for now -- */ do_reason ("rts_do_turn/Should not have turn!"); return NOTOK; } /* -- Remote site is transferring the turn to x400in84 -- */ if (initial_turn == RTS_INITIATOR && initial_mode == RTS_MONOLOGUE) { do_reason ("rts_do_turn/Should not give turn in Monologue!"); return NOTOK; } if (nturns > RTS_MAX_NO_OF_TURNS) { do_reason ("rts_do_turn/Too many turns occurred!"); return NOTOK; } /* -- Returns turn but keeps count to prevent turn looping -- */ if (RtGTurnRequest (sd, &rti) == NOTOK) { do_reason ("rts_do_turn/RT-TURN-GIVE.REQUEST failed"); return NOTOK; } turn_status = RTS_SENT_TURN; nturns++; return OK; } /*ARGSUSED*/ static void rts_abort (sd, rta) int sd; register struct RtSAPabort *rta; { if (submit_running) io_end (NOTOK); if (rta->rta_peer) rts_adios (rta, "RT-U-ABORT.INDICATION"); if (RTS_FATAL (rta->rta_reason)) rts_adios (rta, "RT-P-ABORT.INDICATION"); rts_adios (rta, "RT-P-ABORT.INDICATION (error)"); } /* ARGSUSED */ static void rts_close (sd, rtc) int sd; struct RtSAPclose *rtc; { struct RtSAPindication rtis; register struct RtSAPindication *rti = &rtis; register struct RtSAPabort *rta = &rti->rti_abort; PP_TRACE (("RT-END.INDICATION %d", sd)); if (RtEndResponse (sd, rti) == NOTOK) rts_adios (rta, "RT-END-RESPONSE.REQUEST error"); if (submit_running) io_end (OK); PP_NOTICE (("Connection successfully terminated")); exit (0); } static struct qbuf *fullqb = NULL; /*ARGSUSED)*/ static int rts_uptrans (sd, type, addr, rti) int sd; int type; caddr_t addr; struct RtSAPindication *rti; { register struct SSAPactivity *sv = (struct SSAPactivity *) addr; register struct SSAPsync *sn = (struct SSAPsync *) addr; register struct SSAPreport *sp = (struct SSAPreport *) addr; register struct qbuf *qbp = (struct qbuf *) addr; PE pe = NULLPE; int len; PP_TRACE (("rts_uptrans()")); switch (type) { case SI_DATA: PP_TRACE (("SI_DATA")); len = qblen (qbp); data_bytes += len; PP_TRACE (("Data %d bytes (%d so far)", len, data_bytes)); switch ((*asn_procfnx)(qbp)) { case NOTOK: default: io_end (NOTOK); submit_running = 0; return rtsaplose (rti, RTS_TRANSFER, NULLCP, "process data failed"); case OK: case DONE: break; } break; case SI_SYNC: PP_TRACE (("S-MINOR-SYNC.INDICATION: %ld", sn->sn_ssn)); break; case SI_ACTIVITY: switch (sv->sv_type) { case SV_START: PP_TRACE (("S-ACTIVITY-START.INDICATION")); data_bytes = 0; timer_start (&data_timer); asn_init (hdrproc, bodyproc, 0); break; case SV_INTRIND: case SV_DISCIND: PP_LOG (LLOG_EXCEPTIONS, ("activity %s: %s", sv->sv_type == SV_INTRIND ? "interrupted" : "discarded", SReportString (sv->sv_reason))); break; case SV_ENDIND: PP_TRACE (("S-ACTIVITY-END.INDICATION")); PP_TRACE (("Accumulated '%d'", data_bytes)); if (msgfinished() == NOTOK) return rtsaplose (rti, RTS_TRANSFER, NULLCP, "data termination failed"); break; default: return (rtsaplose (rti, RTS_TRANSFER, NULLCP, "unexpected activity indication=0x%x", sv->sv_type)); } break; case SI_REPORT: if (!sp->sp_peer) return (rtsaplose (rti, RTS_TRANSFER, NULLCP, "unexpected provider-initiated SI_REPORT")); do_reason ("rts_uptrans/Exception Report: '%s'", SReportString (sp->sp_reason)); if (pe) pe_free (pe); break; default: return (rtsaplose (rti, RTS_TRANSFER, NULLCP, "unknown rts_uptrans type=0x%x", type)); } return OK; } static int qblen (qbstart) struct qbuf *qbstart; { int len; register struct qbuf *qb; for (len = 0, qb = qbstart->qb_forw; qb != qbstart; qb = qb->qb_forw) len += qb -> qb_len; return len; } /* --------------------- Postmaster Routines ---------------------------- */ #if PP_DEBUG static int do_debug_transfer() { char buf[BUFSIZ]; int n; int result = NOTOK; struct qbuf *qb; struct SSAPactivity ssa; struct RtSAPindication rti; bzero ((char *)&ssa, sizeof ssa); bzero ((char *)&rti, sizeof rti); ssa.sv_type = SV_START; rts_uptrans (0, SI_ACTIVITY, (caddr_t)&ssa, &rti); while ((n = fread (buf, 1, sizeof buf, stdin)) > 0) { qb = str2qb (buf, n, 1); rts_uptrans (0, SI_DATA, (caddr_t)qb, &rti); qb_free (qb); } ssa.sv_type = SV_ENDIND; rts_uptrans (0, SI_ACTIVITY, (caddr_t)&ssa, &rti); if (result != DONE) advise (NULLCP, "Read message - not parsed"); } #endif