'\"macro stdmacro
.if n .pH ddi_dki.copyb @(#)copyb	40.7 of 11/16/89
.\" Copyright 1989 AT&T
.de IX
.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9	\\n%
.el \\!.IX \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
..
.nr X
.if \nX=0 .ds x} copyb D3DK "STREAMS" "DDI/DKI" "\&"
.if \nX=1 .ds x} copyb D3DK "STREAMS" "DDI/DKI"
.if \nX=2 .ds x} copyb D3DK "" "\&"
.if \nX=3 .ds x} copyb "" "" "\&"
.TH \*(x}
.IX "\f4copyb\fP(D3DK)"
.SH NAME
\f4copyb\f1 \- copy a message block
.SH SYNOPSIS
.nf
.na
\f4#include <sys/stream.h>
.sp 0.5
mblk_t *copyb(mblk_t *\f2bp\f4);\f1
.ad
.fi
.SH ARGUMENT
.RS 0n 10
.IP "\f2bp\f1" 10n
Pointer to the message block from which data is copied.
.RE
.SH "DESCRIPTION" 
\f4copyb\f1 allocates a new message block, and
copies into it the data from the block pointed to by \f2bp\f1.
The new block will be at least as large as the block being copied.
The \f4b_rptr\f1 and \f4b_wptr\f1 members of \f2bp\f1
are used to determine how many bytes to copy.
.SH "RETURN VALUE" 
If successful, \f4copyb\f1 returns a pointer to
the newly allocated message block
containing the copied data.  Otherwise, it returns a \f4NULL\f1 pointer.
.SH "LEVEL" 
Base or Interrupt
.SH "SEE ALSO" 
\f2BCI Driver Development Guide\f1, Chapter 7, ``STREAMS''
.P
.na
\f4allocb\f1(D3DK)
.ad
.SH "EXAMPLE" 
.IX "\f4copyb\fP(D3DK), example"
.IX "\f4canput\fP(D3DK), example"
.IX "\f4dupmsg\fP(D3DK), example"
.IX "\f4putnext\fP(D3DK), example"
.IX "\f4freeb\fP(D3DK), example"
.P
For each message in the list, test to see if the downstream
queue is full with the \f4canput\f1(D3DK) function (line 21).
If it is not full, use \f4copyb\f1(D3DK) to copy a header message
block, and \f4dupmsg\f1(D3DK) to duplicate the data to be
retransmitted.
If either operation fails, reschedule a timeout at the next
valid interval.
.P
Update the new header block with the correct destination address
(line 34), link the message to it (line 35), and send it
downstream (line 36).
At the end of the list, reschedule this routine.
.ne 4
.P
.nf
.ft 4
.ps 7
 1  struct retrns {
 2         mblk_t *r_mp;
 3         long r_address;
 4         queue_t *r_outq;
 5         struct retrns *r_next;
 6  };
 7
 8  struct protoheader {
          . . .
 9         long h_address;
          . . .
10  };
11
12  mblk_t *header;
13
14  retransmit(ret)
15          register struct retrns *ret;
16  {
17          register mblk_t *bp, *mp;
18          struct protoheader *php;
19
20          while (ret) {
21                       if (!canput(ret->r_outq->q_next)) { /* no room */
22                            ret = ret->r_next;
23                            continue;
24                       }
25                       bp = copyb(header);  /* copy header msg. block */
26                       if (bp == NULL) 
27                               break;
28                       mp = dupmsg(ret->r_mp);      /* duplicate data */
29                       if (mp == NULL) {           /* if unsuccessful */
30                               freeb(bp);           /* free the block */
31                               break;
32                       }
33                       php = (struct protoheader *)bp->b_rptr;
34                       php->h_address = ret->r_address; /* new header */
35                       bp->bp_cont = mp;          /* link the message */
36                       putnext(ret->r_outq, bp);   /* send downstream */
37                       ret = ret->r_next;
38          }
39         timeout(retransmit, (long)ret, RETRNS_TIME);  /* reschedule */
40  }
.ps
.ft 1
.fi
.P
.FG "copyb \- copy message block"
