/* * Create an xdr handle for xdrrec * xdrrec_create fills in xdrs. Sendsize and recvsize are * send and recv buffer sizes (0 => use default). * tcp_handle is an opaque handle that is passed as the first parameter to * the procedures readit and writeit. Readit and writeit are read and * write respectively. They are like the system * calls expect that they take an opaque handle rather than an fd. */ void xdrrec_create(XDR *xdrs, uint_t sendsize, uint_t recvsize, caddr_t tcp_handle, int (*readit)(), int (*writeit)()) { RECSTREAM *rstrm = (RECSTREAM *)mem_alloc(sizeof (RECSTREAM)); if (rstrm == NULL) { dprintf("xdrrec_create: out of memory\n"); /* * This is bad. Should rework xdrrec_create to * return a handle, and in this case return NULL */ return; } /* * adjust sizes and allocate buffer quad byte aligned */ rstrm->sendsize = sendsize = fix_buf_size(sendsize); rstrm->recvsize = recvsize = fix_buf_size(recvsize); rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); if (rstrm->the_buffer == NULL) { dprintf("xdrrec_create: out of memory\n"); return; } for (rstrm->out_base = rstrm->the_buffer; (uintptr_t)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; rstrm->out_base++); rstrm->in_base = rstrm->out_base + sendsize; /* * now the rest ... */ xdrs->x_ops = xdrrec_ops(); xdrs->x_private = (caddr_t)rstrm; rstrm->tcp_handle = tcp_handle; rstrm->readit = readit; rstrm->writeit = writeit; rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; rstrm->frag_header = (uint32_t *)rstrm->out_base; rstrm->out_finger += sizeof (uint_t); rstrm->out_boundry += sendsize; rstrm->frag_sent = FALSE; rstrm->in_size = recvsize; rstrm->in_boundry = rstrm->in_base; rstrm->in_finger = (rstrm->in_boundry += recvsize); rstrm->fbtbc = 0; rstrm->last_frag = TRUE; }
XDR_API void xdrrec_create(XDR *xdrs, const u_int sendsize, const u_int recvsize, const caddr_t tcp_handle, int (*readit) (void *, caddr_t, int), int (*writeit) (void *, caddr_t, int)) { RECSTREAM *rstrm = malloc(sizeof (RECSTREAM)); /* * TODO: Should still rework xdrrec_create to return a handle, * and in any malloc-failure case return NULL. */ if (rstrm == NULL) { #if HAVE_SYSLOG_H (void) syslog(LOG_ERR, mem_err_msg_rec); #else (void) fprintf(stderr, "%s\n", mem_err_msg_rec); #endif return; } /* * Adjust sizes and allocate buffers; malloc(3C) * provides a buffer suitably aligned for any use, so * there's no need for us to mess around with alignment. * * Since non-blocking connections may need to reallocate the input * buffer, we use separate malloc()s for input and output. */ rstrm->sendsize = fix_buf_size(sendsize); rstrm->recvsize = fix_buf_size(recvsize); rstrm->out_base = malloc(rstrm->sendsize); if (rstrm->out_base == NULL) { #if HAVE_SYSLOG_H (void) syslog(LOG_ERR, mem_err_msg_rec); #else (void) fprintf(stderr, "%s\n", mem_err_msg_rec); #endif free(rstrm); return; } rstrm->in_base = malloc(rstrm->recvsize); if (rstrm->in_base == NULL) { #if HAVE_SYSLOG_H (void) syslog(LOG_ERR, mem_err_msg_rec); #else (void) fprintf(stderr, "%s\n", mem_err_msg_rec); #endif free(rstrm->out_base); free(rstrm); return; } /* * now the rest ... */ xdrs->x_ops = xdrrec_ops(); xdrs->x_private = (caddr_t)rstrm; rstrm->tcp_handle = tcp_handle; rstrm->readit = readit; rstrm->writeit = writeit; rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; /* LINTED pointer cast */ rstrm->frag_header = (uint32_t *)rstrm->out_base; rstrm->out_finger += sizeof (u_int); rstrm->out_boundry += rstrm->sendsize; rstrm->frag_sent = FALSE; rstrm->in_boundry = rstrm->in_base; rstrm->in_finger = (rstrm->in_boundry += rstrm->recvsize); rstrm->fbtbc = 0; rstrm->last_frag = TRUE; rstrm->firsttime = 0; rstrm->in_nonblock = 0; rstrm->in_needpoll = 1; rstrm->in_maxrecsz = 0; rstrm->in_nextrec = rstrm->in_base; rstrm->in_nextrecsz = 0; }