$title('dcsndmsg - send a data chain message to a known port') $compact /******************************************************************** * * MODULE NAME: dcsndmsg * * DESCRIPTION: Send a data chain message. * *********************************************************************/ dcsndmsg: DO; $include(:rmx:inc/rmxplm.ext) $include(dcom.ext) $include (dcom.lit) $include(:rmx:inc/error.lit) $include(err.ext) DECLARE /* Literals */ dc_el LITERALLY 'STRUCTURE( /* data chain element */ b_size WORD, /* buffer size */ buf_offset WORD, /* buffer pointer */ buf_sel SELECTOR, res WORD)', /* reserved */ REMPORT LITERALLY '801H', /* Port id of remote port */ REMHOST LITERALLY '05', /* Host id of remote host */ CONBUF LITERALLY '16', /* size of a control buffer */ TSTPORT LITERALLY '801H', /* well-known port */ MSIZE LITERALLY '46', /* message size */ BUFSIZE LITERALLY '100', /* buffer size */ NOEXCEPT LITERALLY '0', /* no exception handling by system */ DCBUFSIZE LITERALLY '8'; /* data chain buffer size */ DECLARE /* Global vars */ status WORD, port_t TOKEN, /* Token for local port */ messock socket, /* socket to which message is sent */ msock DWORD AT (@messock), /* dword alias for messock */ con_buf (CONBUF) BYTE, /* control buffer */ mess_size WORD, /* number of bytes in data message */ bpool TOKEN, /* buffer pool attached to port */ off_set WORD, /* buffer off_set where chain buffer starts */ sflags WORD, /* transmission flags */ dc_seg_size WORD, /* segment size for data chain */ dc_seg_t TOKEN, /* token for data chain segment */ dc_ptr POINTER, /* pointer to data chain segment */ d_chain based dc_ptr(1) dc_el, /* data chain */ dc_idx WORD, /* data chain index */ trans_id WORD; /* transaction id */ DECLARE dc_buf (BUFSIZE) BYTE INITIAL (45,'This is a data chain message sent by server',0dh,0ah); CALL set$exception(NOEXCEPT); port_t = get$dport(TSTPORT, @bpool, CHAIN, @status); messock.host_id = REMHOST; messock.port_id = REMPORT; /* create data chain with at least enough blocks for each message buffer + a terminating block */ mess_size = SIZE(dc_buf); /* * Calculate the size of the segment that will contain the data chain. * The message is divided into pieces whose size is DCBUFSIZE so the total * number of elements in the data chain is mess_size/DCBUFSIZE + 2. * The additional 2 includes one possible piece of the message less than * DCBUFSIZE and the terminating data chain element. * */ dc_seg_size = (mess_size/DCBUFSIZE + 2)*(size(d_chain)); dc_seg_t = rq$create$segment(dc_seg_size, @status); dc_ptr = build$ptr(dc_seg_t,0); /* Fill in the fields of the data blocks for each buffer containing a part of the message */ off_set = 0; dc_idx = 0; DO WHILE off_set < mess_size; d_chain(dc_idx).b_size = DCBUFSIZE; d_chain(dc_idx).buf_offset = LOW(OFFSET$OF(@dc_buf(off_set))); d_chain(dc_idx).buf_sel = SELECTOR$OF(@dc_buf(off_set)); off_set = off_set + DCBUFSIZE; dc_idx = dc_idx + 1; END; d_chain(dc_idx).b_size = 0; d_chain(dc_idx).buf_offset = 0; d_chain(dc_idx).buf_sel = SELECTOR$OF(NIL); /* send data chain */ sflags = DATACHAIN OR SYNCHTRANS; trans_id = rq$send(port_t,msock, @con_buf, @d_chain, mess_size, sflags, @status); CALL error$check(100, status); CALL rq$exit$io$job(0,NIL,@status); END dcsndmsg;