$title('dcrcvmsg - receive a 2K data chain message') $compact /******************************************************************** * * MODULE NAME: dcrcvmsg * * DESCRIPTION: When a message is received, determine whether it is in data * chain or buffer form. If data chain, compress the chain into * a single segment. Expect a 2K message with a printable * part at the first and second 1K + 2 boundaries. Write the * printable part to the console. * *********************************************************************/ dcrcvmsg: DO; $include(:rmx:inc/rmxplm.ext) $include(dcom.ext) $include(dcom.lit) $include(:rmx:inc/error.lit) $include(err.ext) DECLARE /* Literals */ TSTPORT LITERALLY '801H', /* well-known port */ NOEXCEPT LITERALLY '0'; /* no exception handling by system */ DECLARE /* Global vars */ status WORD, port_t TOKEN, /* Token for local port */ local_host WORD, /* local host id */ info rec_info, /* info block on message received */ bpool TOKEN, /* buffer pool */ dcmsg_ptr POINTER, /* pointer to data chain message */ msg_ptr POINTER, /* pointer to received message */ msg BASED dcmsg_ptr (1) BYTE; $subtitle('get$dc$data') /******************************************************************** * * PROC NAME: get$dc$data * * DESCRIPTION: This procedure takes a data chain and copies the data described * by it into a single segment. This procedure only works if the * data is less than 64K in size. Data chains can describe data * greater than 64K. * * CALL: mbuf_ptr = get$dc$data(dc_ptr, status_ptr) * * INPUTS: dc_ptr - points to a data chain * status_ptr - points to a status word * * RETURNS: mbuf_ptr - points to a segment containing the data * described by a data chain *********************************************************************/ get$dc$data: PROCEDURE(dc_ptr, status_ptr) POINTER PUBLIC; DECLARE /* Params */ dc_ptr POINTER, /* points to data chain */ status_ptr POINTER; /* points to status word */ DECLARE /* Locals */ buf_ptr POINTER, dc BASED dc_ptr (1) blk_struc, status BASED status_ptr WORD, num_bytes WORD, /* number of bytes in data chain */ cpybuf_tok TOKEN, /* buffer to hold data chain data */ cpybuf_ptr POINTER, /* points to cpybuf */ cpybuf BASED cpybuf_ptr c_buf, i WORD, /* local index */ cpyidx WORD; /* index into cpybuf */ num_bytes = 0; i = 0; /* get the size of the data described by the data chain */ DO WHILE dc(i).b_size <> 0; num_bytes = num_bytes + dc(i).b_size; i = i + 1; END; /* add 2 to num_bytes for the size field in c_buf */ num_bytes = num_bytes + 2; cpybuf_tok = rq$create$segment(num_bytes, status_ptr); CALL error$check(100, status); cpybuf_ptr = build$ptr(cpybuf_tok, 0); cpybuf.size = num_bytes - 2; i = 0; cpyidx = 0; DO WHILE dc(i).b_size <> 0; buf_ptr = BUILD$PTR(dc(i).buf_sel, DOUBLE(dc(i).buf_offset)); CALL movb(buf_ptr, @cpybuf.buf(cpyidx), dc(i).b_size); cpyidx = cpyidx + dc(i).b_size; i = i + 1; END; RETURN cpybuf_ptr; END get$dc$data; /* Start main */ CALL set$exception(NOEXCEPT); port_t = get$dport(TSTPORT, @bpool, CHAIN, @status); msg_ptr = rq$receive(port_t, WAITFOREVER, @info, @status); CALL error$check(110, status); IF (info.flags AND DATACHAIN) = DATACHAIN THEN DO; dcmsg_ptr = get$dc$data(msg_ptr, @status); CALL error$check(120, status); /* * print message that was contained at start of the buffer described * by the first element in the data chain * */ CALL rqc$send$eo$response(NIL,0,@msg(2),@status); CALL error$check(130, status); /* * print message that was contained at start of the buffer described * by the second element in the data chain * */ CALL rqc$send$eo$response(NIL,0,@msg(1028),@status); CALL error$check(140, status); END; ELSE DO; CALL rqc$send$eo$response(NIL,0,msg_ptr,@status); CALL error$check(150, status); END; CALL rq$release$buffer(bpool, SELECTOR$OF(msg_ptr), (info.flags AND 3), @status); CALL rq$exit$io$job(0,NIL,@status); END dcrcvmsg;