{$M-,X+}

include {NOLIST}'pascal:extern.pas';
include {NOLIST}'domain:mdep.def';
include {NOLIST}'domain:master.def';
include {NOLIST}'domain:msub.hdr';
include {NOLIST}'domain:irdata.hdr';
include {NOLIST}'domain:eutil.hdr';

const	max_data_octets = 500;  {dg_data_limit-dmn_hdr_sz}



function etoi_edname(var pkt:message_template;
		     var offset:integer;        
		     var name:exp_dname;
		     var ovfl:boolean):boolean;

{ Given an input pkt and an offset into the data area, 
  extract the exp_dname beginning at that offset and 
  place it in name.  A root record will be placed at the
  end of each dname.  Upon return, offset will contain 
  the value of the position after the null terminator 
  of the exp_dname.  Return false if an error found
  during processing.  Set ovfl if everything ok but
  ran out of input. }

var	j, saved_offset, temp, total:integer;
	case_flag, indirect_done, done, ok:boolean;

begin {etoi_edname}

with pkt.raw_pkt, name do
begin
    ok:=true;
    done:=false;
    ovfl:=false;
    count:=1;
    total:=0;
    saved_offset:=0;  {note zero denotes nothing saved}

    while (not done) and ok and (not ovfl) do
    begin  {extract next exp_dname segment}  

	{ Check for compression and adjust offset accordingly. }
	repeat
	    if data_recs[offset]>=300b {high bit set?}
	    then if (pkt.octet_cnt-offset)<1 {need at least 2 bytes}
		 then ovfl:=true
		 else begin
			  indirect_done:=false;
			  if saved_offset=0
			  then {set offset first time for return}
			      saved_offset:=offset+2;

			  temp:=bshift(data_recs[offset]-300b, 8) +
				       data_recs[offset+1];

			  if temp > pkt.octet_cnt  
			  then ovfl:=true
			  else  {check offset validity}
			      if (temp < 12) or  {can't offset into header}
                                 (temp-11 >= offset) {no forward reference}
                              then ok:=false
			      else offset:=temp-11;  {relative to data section}
		      end
	    else indirect_done:=true;
	until (not ok) or ovfl or indirect_done;
	
	{bounds checks}
	if (data_recs[offset]<0)
	   or (data_recs[offset]>max_lab_chars)  {valid label length?}
	   or ((data_recs[offset]+total) >
		   max_dname_chars)  {valid total length?}
	   or ((pkt.octet_cnt-offset)<data_recs[offset])
	   or (count>max_lab_levels)
	then ok:=false
	else begin  {copy segment to name}
		 if pkt.octet_cnt-data_recs[offset] < 0
		 then ovfl:=true
		 else begin
			  dlabels[count].labinfo[0]:=data_recs[offset];
			  total:=total+data_recs[offset];
			  offset:=offset+1;
			  
			  {copy label}
			  for j:=1 to data_recs[offset-1] do
			  begin
			      case_flag:=(data_recs[offset]>=141b)  { a }
				    and (data_recs[offset]<=172b); { z }
			      dlabels[count].case_mod[j]:=case_flag;
			      if case_flag
			      then {lower case}
				  dlabels[count].labinfo[j]:= 
						 data_recs[offset]-40b
			      else dlabels[count].labinfo[j]:= 
						  data_recs[offset];
			      offset:=offset+1;
			  end; {loop}
	      
			  if dlabels[count].labinfo[0]=0 {null terminator}
			  then begin
				   done:=true;
				   if saved_offset>0  {compression}
				   then offset:=saved_offset;
			       end
			  else count:=count+1;
		     end
	         end  {copy segment to dname}
	 end;  {loop}  {extract next exp_dname segment}  
    etoi_edname:=ok;  {set return value of function}	       
end; {with}
end; {etoi_edname}



function etoi_qsctn( var pkt:message_template;
		     var offset:integer; 
		     var qsctn:qsection;
		     var count:integer;
		     var ovfl:boolean):boolean;

{ Parse pkt beginning at offset for the number of
  question section(s) specified by count.  Use 
  etoi_edname to extract the owner name, then type,
  and class.  Return false if an error found while
  parsing.  Set ovfl if ok but ran out of input. }

var   	i, temp:integer;
	ok:boolean;

begin {etoi_qsctn}

with pkt.raw_pkt, qsctn do
begin    
    i:=1;
    if count>max_exp_rrs
    then count:=max_exp_rrs;
    ok:=true;
    ovfl:= offset>pkt.octet_cnt;

    while (i<=count) and ok and (not ovfl) do
    begin
	{extract the qname}
	ok:=etoi_edname(pkt, offset, qnames[i], ovfl);

	if ok and (not ovfl)
	then begin  {extract qtype}
		 if (pkt.octet_cnt-offset) < 3
		 then ovfl:=true
		 else begin
			  temp:= bshift(data_recs[offset], 8) +
				   data_recs[offset+1];
			  offset:=offset+2;
			  if ((temp>ord(dtype_l_bound)) and
			      (temp<ord(dtype_h_bound)) ) or
			      ((temp>=axfr) and (temp<=star))
			  then begin
				   qtypes[i]:=temp;
				   {extract qclass}
				   temp:=bshift(data_recs[offset], 8) +
				   data_recs[offset+1];
				   offset := offset+2;
				   if ((temp>ord(dclass_l_bound)) and
				       (temp<ord(dclass_h_bound)))
				       or (temp=star)
				   then qclasses[i]:=temp
				       else ok:=false;    
			       end
			  else ok:=false;
		      end
		 end  {extract qtype}
	else ok:=false;
	i := i+1;
    end;  { loop }

    {set return values}
    if ovfl
    then count:=i-1;
    etoi_qsctn:=ok;
end;  {with}
end;  {etoi_qsctn}



function etoi_sctn( var pkt:message_template;
		    var offset:integer;
		    var sctn:section;
		    var ovfl:boolean):boolean;

{ Given an input pkt and an offset into the data area, 
  extract the number of answer, authority, or additional
  sections specified by exp_count and place them in
  the sctn provided.  Use etoi_edname to extract the
  owner name, then type, class, ttl, rdlength, and rdata.
  Return false if an error found while parsing; set ovfl 
  if ok but ran out of input. }

var   	i, j, k, count, old_offset, rdlen, rdcnt, strlen:integer;
	ok:boolean;
	tbl:rdata_table_pointer;

begin {etoi_sctn}

with pkt.raw_pkt do
begin
    i:=1;
    ovfl:= offset>pkt.octet_cnt;
    ok:=true;
    if sctn.exp_count>max_exp_rrs
    then sctn.exp_count:=max_exp_rrs;

    {get data from pkt}
    while (i<=sctn.exp_count) and ok and (not ovfl) do
    begin
	{extract the owner name}
	ok:=etoi_edname(pkt, offset, sctn.exp[i].owner, ovfl);

	{bounds check for inclusion of type(2 octets), 
	 class(2 octets), ttl(4 octets), and rdata 
	 length(2 octets) }

	if (offset+9)>pkt.octet_cnt
	then ovfl:=true
	else with sctn.exp[i].rr_data do
	     begin  {get rrtype}
		 rrtype:=chrtype( bshift(data_recs[offset], 8) +
				  data_recs[offset+1] );
		 offset:=offset+2;

		 if (rrtype<=dtype_l_bound) or
		     (rrtype>=dtype_h_bound)
		 then ok:=false    
		 else begin  {get rrclass}
			  rrclass:=chrclass( bshift(data_recs[offset], 8)
					     + data_recs[offset+1]);
			  offset:=offset+2;

			  if (rrclass<=dclass_l_bound) or
			      (rrclass>=dclass_h_bound)
			  then ok:=false    
			  else begin  {get ttl}
				   ttl:=bshift(data_recs[offset], 24) +
				        bshift(data_recs[offset+1], 16) +
					bshift(data_recs[offset+2], 8) +
					data_recs[offset+3];
				   offset:=offset+4;
	
				   rdlen:=bshift(data_recs[offset],8) +
					  data_recs[offset+1];
				   offset:=offset+2;
			       end;
		      end;
	     end;  {do this for indentation}

	if offset+rdlen-1>pkt.octet_cnt  {bounds check}
	then ovfl:=true;

	if (rdlen>max_chunk*max_binary_octets) {implementation restriction}
        then ok:=false
        else if not ovfl
	     then if rdlen<>0  {don't interpret 0 rdata length as error}
		  then with sctn.exp[i].rr_data do
		  begin  {get rdata}
		      old_offset:=offset;
		      if i=1
		      then {only create table once}
			  tbl:=irdata(rrclass);  {get ^rdata descriptor}

		      {rdcnt and j will lose alignment if chunk
		       is larger than max allowed for 1 exp_chunk}
		      rdcnt:=1; {index into tbl}
		      j:=1;  {chunk count}

		      {Store rdata segments distinguishing
		       segment types}
		      repeat
			  case tbl^[rrtype].rdata_item[rdcnt] of
			      dname_field: 
				   begin
				       chunks[j].ckind:=name_chunk;
				       ok:=etoi_edname(pkt, offset,
					       chunks[j].rrname, ovfl);
				   end;
			      
			      cstring_field:
				    begin
					{make length checks based on
					 string length which is first octet}
					strlen:=data_recs[offset];
					if ((max_chunk-j)*max_binary_octets<
					    strlen) {enough space}
					    or (offset+strlen>
						old_offset+rdlen) {bad strlen}
					then ok:=false
					else begin  {copy string}
						 strlen:=strlen+1; {strlen too}
						 chunks[j].ckind:=lit_chunk;
						 chunks[j].lit_data_count:=
								   strlen;
						 k:=1;
						 repeat
						     chunks[j].lit_data[k]:= 
						       data_recs[offset];
						     offset:=offset+1;
						     strlen:=strlen-1;
						     if k=max_binary_octets
						     then begin
						          chunks[j].
							    lit_data_count:=k;
							  k:=1;
							  if strlen<>0
							  then begin 
							       {didn't end
							        on a chunk
							        boundary}
							       j:=j+1;
							       chunks[j].
							       ckind:=
							         lit_chunk;
							       end;
							  end
						     else k:=k+1;
						 until strlen=0;
					     end;
				    end;

			      int16_field: 
				    begin
					if offset+2>rdlen+old_offset
					then {bad rdlen}
					    ok:=false    
					else begin
						 chunks[j].ckind:=lit_chunk;
						 chunks[j].lit_data_count:=2;
						 for k:=1 to 2 do
						 begin
						     chunks[j].lit_data[k]:= 
						       data_recs[offset];
						     offset:=offset+1;
						 end;
					     end;
				    end;

			      time_field,
			      int32_field,
			      inet_a_field: 
				    begin
					if offset+4>rdlen+old_offset
					then {bad rdlen}
					    ok:=false    
					else begin
						 chunks[j].ckind:=lit_chunk;
						 chunks[j].lit_data_count:=4;
						 for k:=1 to 4 do
						 begin
						     chunks[j].lit_data[k]:= 
						       data_recs[offset];
						     offset:=offset+1;
						 end;
					     end;
				    end;
			      
			      inet_p_field:
				   begin
				       if offset+1>rdlen+old_offset
				       then ok:=false    
				       else begin
						chunks[j].ckind:=lit_chunk;
						chunks[j].lit_data_count:=1;
						chunks[j].lit_data[1]:= 
							  data_recs[offset];
						offset:=offset+1;
					    end;
				   end;

			      inet_s_field:
				   begin
				       chunks[j].ckind:=lit_chunk;
				       chunks[j].lit_data_count:=
						 rdlen-(offset-old_offset);
				       for k:=1 to chunks[j].lit_data_count do
				       begin
					   chunks[j].lit_data[k]:=
						     data_recs[offset];
					   offset:=offset+1;
				       end;
				   end;

			      vbinary_field:
				    begin
					chunks[j].ckind:=lit_chunk;
					k:=1;
					for count:=1 to rdlen do
					begin    
					    chunks[j].lit_data[k]:= 
						      data_recs[offset];
					    offset:=offset+1;
					    if k=max_binary_octets
					    then begin
						     chunks[j].
						       lit_data_count:=k;
						     k:=1;
						     if count<>rdlen
						     then begin 
							  {didn't end
							   on a chunk
							   boundary}
							   j:=j+1;
						           chunks[j].ckind:=
							     lit_chunk;
							   end;
						 end
					    else k:=k+1;
				        end;
			            end;
			  end;  {case}
			  rdcnt:=rdcnt+1;
			  j:=j+1;
		      until (tbl^[rrtype].rdata_item[rdcnt]=no_more_field)
			    or (not ok) or ovfl;
		      chunk_count:=j-1;

		      if ok  {compress data chunks}
		      then ok:=rrsquash(sctn.exp[i].rr_data);
		  end; {get rdata}
	     i := i+1;
    end; { main loop }
    
    {set return values}
    if ovfl
    then sctn.exp_count:=i-1;
    etoi_sctn:=ok;
end;  {with}
end;  {etoi_sctn}


function itoe_rrdname(    dptr:dname_pointer;
			  nptr:node_pointer;
		      var pkt: message_template;
		      var offset:integer):boolean;

{ Either dptr or nptr will be non nil.  Build the dname
  by one of two methods.  1) dptr<>nil: write the dname
  held in rdata.  2) nptr<>nil:  reverse the node path
  to the root, writing each node label in the pkt.
  Return true if overflow occured. }

var	i, len:integer;
	ovfl, done, node_path:boolean;
	segment:lab_use;

begin {itoe_rrdname}

with pkt.raw_pkt do
begin
    done:=false;
    ovfl:= offset>max_data_octets;

    { Strategy:  at each iteration, segment will contain the
      lab_use which will be copied into pkt.  Use the
      variable "owner" to determine how to increment the
      structure pointer (nptr or dptr) and subsequently,
      fill-in segment. }

    if nptr<>nil
    then begin
	     segment:=nptr^.node_label;
	     node_path:=true;
	 end
    else begin
	     segment:=dptr^.dlabel;	
	     node_path:=false;
	 end;
    
    while (not done) and (not ovfl) do
    begin	
	len:=segment.labptr^.text[0];
	if (len+offset)>max_data_octets
	then begin
		 ovfl:=true;
		 len:=max_data_octets-offset;
	     end;
	
	data_recs[offset]:=segment.labptr^.text[0];
	offset:=offset+1;

	{copy text}
	for i:=1 to len do
	begin    
	    if segment.case_mod[i]  {map octet to lower case}
	    then data_recs[offset]:=segment.labptr^.text[i]+40b
	    else data_recs[offset]:=segment.labptr^.text[i];
	    offset:=offset+1;
	end;
		     
	{update pointers}
	if node_path
	then begin  
		 nptr:=nptr^.up_ptr;
		 if nptr=nil
		 then done:=true
		 else segment:=nptr^.node_label;
	     end
	else begin  
		 dptr:=dptr^.more;
		 if dptr=nil
		 then done:=true
		 else segment:=dptr^.dlabel;	
		 end;
    end;  {loop}
    itoe_rrdname:=ovfl;  {set return value}
end; {with}
end; {itoe_rrdname}


function itoe_dname(	 name:exp_dname;
		     var pkt:message_template;
		     var offset:integer):boolean;

{ Given an exp_dname, place it in pkt beginning
  at offset.  A true return implies overflow. }

var	i, j, len:integer;
	ovfl:boolean;

begin {itoe_dname}

with pkt.raw_pkt do
begin

    ovfl:= offset>max_data_octets;
    i:=1; 

    while (i<=name.count) and (not ovfl) do
    with name.dlabels[i] do
    begin    
	len:=labinfo[0];
	if len >= 300b  {compression preset}
	then begin
		 if (offset+2) > max_data_octets
		 then ovfl:=true
		 else begin
			  data_recs[offset]:=labinfo[0];
			  data_recs[offset+1]:=labinfo[1];
			  offset:=offset+2;
		      end
	     end
	else begin
		 if (offset+len) > max_data_octets
		 then begin
			  ovfl:=true;
			  len:=max_data_octets-offset;
		      end;
		 
		 {length field}
		 data_recs[offset]:=labinfo[0];
		 offset:=offset+1;

		 for j:=1 to len do
		 begin  {copy text}
		     if case_mod[j]  { map octet to lower case }
		     then data_recs[offset]:=labinfo[j]+40b
		     else data_recs[offset]:=labinfo[j];
		     offset:=offset+1;
		 end;
	     end;
	i:=i+1;    
    end; {i loop}

    itoe_dname:=ovfl;  {set return value}
end; {with}
end; {itoe_dname}


function itoe_qsctn(var qsec:qsection;
		    var pkt:message_template;
		    var offset:integer;
		    var count:integer):boolean;

{ Copy the data from the q_section into
  pkt beginning at offset.  If overflow
  occurs, return true and change count to
  reflect number of complete records copied. }

var	i, j:integer;
	ovfl:boolean;

begin {itoe_qsctn}

with qsec, pkt.raw_pkt do
begin
    ovfl:= offset>max_data_octets;
    i:=1;

    if header.opcode=inv_query
    then  {copy from qanswer}
	while (i<=count) and (not ovfl) do
	begin	
	    { Qanswer deleted 9/13/88 PVM 
	    ovfl:=itoe_rrdname(nil, qanswer[i]^.node, pkt, offset);
	    
	    if not ovfl
	    then with qanswer[i]^ do
		 begin
		     j:=1;
		     while (j<=4) and (offset<=max_data_octets) do
		     begin
			 case j of
			     1: data_recs[offset]:=ord(rrtype) div "100;
			     2: data_recs[offset]:=ord(rrtype) mod "100;
			     3: data_recs[offset]:=ord(rrclass) div "100;
			     4: data_recs[offset]:=ord(rrclass) mod "100;
			 end;
			 offset:=offset+1;
			 j:=j+1;
		     end;
		 end;
	    if offset>max_data_octets
	    then ovfl:=true;
	    i:=i+1;}
	    quit
	end
    else  {copy from qnames, qtypes, and qclasses} 
	while (i<=count) and (not ovfl) do
	begin	
	    ovfl:=itoe_dname(qnames[i], pkt, offset); 
	
	    if not ovfl
	    then begin
		     j:=1;
		     while (j<=4) and (offset<=max_data_octets) do
		     begin
			 {type and class} 
			 case j of
			     1: data_recs[offset]:=qtypes[i] div "100;
			     2: data_recs[offset]:=qtypes[i] mod "100;
			     3: data_recs[offset]:=qclasses[i] div "100;
			     4: data_recs[offset]:=qclasses[i] mod "100;
			 end;
			 offset:=offset+1;
			 j:=j+1;
		     end;
		 end;
	    if offset>max_data_octets
	    then ovfl:=true;
	    i:=i+1;
	end;

    if ovfl
    then count:=i-1;
    itoe_qsctn:=ovfl;
end; {with}
end; {itoe_qsctn}


function itoe_isctn(var sec:section;
		    var pkt:message_template;
		    var offset:integer):boolean;

{ Copy the int_ information from sec to pkt beginning
  at offset.  If overflow occurs, return true and
  change the section counts to reflect actual records
  copied. }

var	i, j, temp, howmany, len, old_off, filled:integer;
	ovfl:boolean;
	np_old:node_pointer;
	ptr:rdchunk_pointer;

begin {itoe_isctn}

with sec do
begin
    ovfl:= offset>max_data_octets;
    i:=1;
    filled:=0;
    old_off:=0;
    np_old:=nil;

    while (i<=int_count) and (not ovfl) do
    begin
	if int[i].owner_used
	then {copy the expanded dname}
	    ovfl:=itoe_dname(int[i].owner, pkt, offset)
	else {internal dname--compress if possible}
	    { deleted 9/13/88 pvm
	    if (np_old = int[i].rr_ptr^.node)
	    then if (offset + 2) > max_data_octets
		 then ovfl:=true
		 else begin
			  pkt.raw_pkt.data_recs[offset]:=
				      300b + (old_off div "100);
			  pkt.raw_pkt.data_recs[offset+1]:=
				      old_off mod "100;
			  offset:=offset+2;
		      end
	    else begin
		     old_off:=offset+dmn_hdr_sz-1;
		     np_old:=int[i].rr_ptr^.node;
		     ovfl:=itoe_rrdname(nil, int[i].rr_ptr^.node,
				      pkt, offset);
		 end;}
	    quit;
	    
	if not ovfl 
	then with int[i].rr_ptr^, pkt.raw_pkt do
	     begin
		 if (offset+7)>max_data_octets
	         then begin
			  ovfl:=true;
			  howmany:=max_data_octets-offset+1;
		      end
		 else howmany:=8;

		 for j:=1 to howmany do
		 begin
		     case j of 
			 {type and class}
			 1: data_recs[offset]:=ord(rrtype) div "100;
			 2: data_recs[offset]:=ord(rrtype) mod "100;
			 3: data_recs[offset]:=ord(rrclass) div "100;
			 4: data_recs[offset]:=ord(rrclass) mod "100;;
			 {ttl}
			 5, 6, 7, 8: 
			    data_recs[offset]:=band(bshift(ttl,-((8-j)*8)),
						      377b);
		     end;
		     offset:=offset+1;
		 end;
		 
		 {rdlength and rdata}
		 if not ovfl
		 then begin
			  ptr:=rdata;
			  if (offset+2) > max_data_octets
			  then ovfl:=true
			  else begin
				   if ptr<>nil  {designate 0 length rdata}
				   then temp:=offset;  {for rdlength}
				   offset:=offset+2;
			       end;
			  
			  while (ptr<>nil) and (not ovfl) do
			  begin	 {ptr loop}
			      if ptr^.ckind=name_chunk
			      then ovfl:=itoe_rrdname(ptr^.rrname, nil,
						    pkt, offset)

			      else with ptr^.litdata^ do
				   begin  {literal data}
				       len:=lcount;
				       if (offset+len) > max_data_octets
				       then begin
						ovfl:=true;
						len:=max_data_octets-offset+1;
					    end;
				       for j:=1 to len do
				       begin
					   data_recs[offset]:=ldata[j];
					   offset:=offset+1;
				       end;
				   end; {literal data}
			      ptr:=ptr^.more;
		          end; {ptr loop}
			  if not ovfl
			  then begin  {fill-in rdlength}
				   data_recs[temp]:=(offset-temp-2)
						   div "100;
				   data_recs[temp+1]:=(offset-temp-2)
						     mod "100;
				   filled:=filled+1;  {count of actual records
						       to send}
			       end;
		    end;
	     end; {with}
	i:=i+1;
    end; {i loop}
    if ovfl
    then sec.int_count:=filled;
    itoe_isctn:=ovfl;		 
end; {with}
end; {itoe_isctn}


function itoe_esctn(var sec:section;
		    var pkt:message_template;
		    var offset:integer):boolean;

{ Copy the data from the exp_ portion of section into
  pkt beginning at offset. }

var	i, j, k, temp, len, howmany, filled:integer;
	ovfl:boolean;
	
begin {itoe_esctn}

with pkt.raw_pkt do
begin
    ovfl:= offset>max_data_octets;
    i:=1;
    filled:=0;

    while (i<=sec.exp_count) and (not ovfl) do
    with sec.exp[i] do	
    begin  {main loop}	
	if owner.count>0
	then ovfl:=itoe_dname(owner, pkt, offset)
	else begin  {null section}
		 data_recs[offset]:=0;
		 offset:=offset+1;
	     end;
	
	if not ovfl
	then with rr_data do
	     begin  {everything else}
		 if (offset+7) > max_data_octets
		 then begin
			  ovfl:=true;
			  howmany:=max_data_octets-offset+1;
		      end
		 else howmany:=8;
		 for j:=1 to howmany do
		 begin
		     case j of
			  {type, class}
			 1: data_recs[offset]:=ord(rrtype) div "100;
			 2: data_recs[offset]:=ord(rrtype) mod "100;
			 3: data_recs[offset]:=ord(rrclass) div "100;
			 4: data_recs[offset]:=ord(rrclass) mod "100;
			 5, 6, 7, 8:  {ttl}
			    data_recs[offset]:=
				       band( bshift(ttl,-((8-j)*8)), 377b );
		     end;
		     offset:=offset+1;
		 end;
		 
		 if not ovfl
		 then begin  {rdlength and rdata}
			  if chunk_count=0 
			  then if (offset+2) <= max_data_octets
			       then offset:=offset+2 {designate 0 length rdata}
			       else ovfl:=true
			  else if (offset+2) <= max_data_octets
			       then begin
				   temp:=offset; {placeholder for rdata length}
				   offset:=offset+2;
			       end
			  else ovfl:=true;

			  j:=1;
			  while (j<=chunk_count) and (not ovfl) do
			  with chunks[j] do
			  begin
			      if ckind=name_chunk
			      then ovfl:=itoe_dname(rrname,
						  pkt, offset) 
			      else begin {literal data}
				       len:=lit_data_count;
				       if (offset+len-1)>max_data_octets
				       then begin
						ovfl:=true;
						len:=max_data_octets-offset+1;
					    end;
				       for k:=1 to len do
				       begin
					   data_recs[offset]:=lit_data[k];
					   offset:=offset+1;
				       end;
				   end;
			      j:=j+1;
			  end; {j loop}
			  {rdata length}
			  if not ovfl
			  then begin
				   data_recs[temp]:=(offset-temp-2) div "100;
				   data_recs[temp+1]:=(offset-temp-2) mod "100;
				   filled:=filled+1;  {count of records 
						       to send}
			       end;
		      end; {else}
	      end;
        i:=i+1;
    end;  {main loop}
    if ovfl
    then sec.exp_count:=filled;
    itoe_esctn:=ovfl;
end; {with}
end. {itoe_esctn}
