14bff34e3Sthurlow /* 24bff34e3Sthurlow * Copyright (c) 2000, Boris Popov 34bff34e3Sthurlow * All rights reserved. 44bff34e3Sthurlow * 54bff34e3Sthurlow * Redistribution and use in source and binary forms, with or without 64bff34e3Sthurlow * modification, are permitted provided that the following conditions 74bff34e3Sthurlow * are met: 84bff34e3Sthurlow * 1. Redistributions of source code must retain the above copyright 94bff34e3Sthurlow * notice, this list of conditions and the following disclaimer. 104bff34e3Sthurlow * 2. Redistributions in binary form must reproduce the above copyright 114bff34e3Sthurlow * notice, this list of conditions and the following disclaimer in the 124bff34e3Sthurlow * documentation and/or other materials provided with the distribution. 134bff34e3Sthurlow * 3. All advertising materials mentioning features or use of this software 144bff34e3Sthurlow * must display the following acknowledgement: 154bff34e3Sthurlow * This product includes software developed by Boris Popov. 164bff34e3Sthurlow * 4. Neither the name of the author nor the names of any co-contributors 174bff34e3Sthurlow * may be used to endorse or promote products derived from this software 184bff34e3Sthurlow * without specific prior written permission. 194bff34e3Sthurlow * 204bff34e3Sthurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 214bff34e3Sthurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 224bff34e3Sthurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 234bff34e3Sthurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 244bff34e3Sthurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 254bff34e3Sthurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 264bff34e3Sthurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 274bff34e3Sthurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 284bff34e3Sthurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 294bff34e3Sthurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 304bff34e3Sthurlow * SUCH DAMAGE. 314bff34e3Sthurlow * 324bff34e3Sthurlow * $Id: mbuf.c,v 1.3 2004/12/13 00:25:22 lindak Exp $ 334bff34e3Sthurlow */ 344bff34e3Sthurlow 35*9c9af259SGordon Ross /* 36*9c9af259SGordon Ross * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37*9c9af259SGordon Ross * Use is subject to license terms. 38*9c9af259SGordon Ross */ 394bff34e3Sthurlow 404bff34e3Sthurlow #include <sys/types.h> 414bff34e3Sthurlow #include <ctype.h> 424bff34e3Sthurlow #include <errno.h> 434bff34e3Sthurlow #include <stdio.h> 444bff34e3Sthurlow #include <stdlib.h> 454bff34e3Sthurlow #include <string.h> 464bff34e3Sthurlow #include <strings.h> 474bff34e3Sthurlow #include <libintl.h> 487568150aSgwr #include <assert.h> 494bff34e3Sthurlow 504bff34e3Sthurlow #include <netsmb/smb.h> 514bff34e3Sthurlow #include <netsmb/smb_lib.h> 524bff34e3Sthurlow #include <netsmb/mchain.h> 534bff34e3Sthurlow 54*9c9af259SGordon Ross #include "private.h" 55*9c9af259SGordon Ross 564bff34e3Sthurlow #ifdef APPLE 574bff34e3Sthurlow #define __func__ "" 584bff34e3Sthurlow #define MBERROR(format, args...) \ 594bff34e3Sthurlow printf("%s(%d): "format, __func__, __LINE__, ## args) 604bff34e3Sthurlow #endif 614bff34e3Sthurlow 624bff34e3Sthurlow static int 634bff34e3Sthurlow m_get(size_t len, struct mbuf **mpp) 644bff34e3Sthurlow { 654bff34e3Sthurlow struct mbuf *m; 664bff34e3Sthurlow 677568150aSgwr assert(len < 0x100000); /* sanity */ 687568150aSgwr 694bff34e3Sthurlow len = M_ALIGN(len); 704bff34e3Sthurlow if (len < M_MINSIZE) 714bff34e3Sthurlow len = M_MINSIZE; 724bff34e3Sthurlow m = malloc(M_BASESIZE + len); 734bff34e3Sthurlow if (m == NULL) 744bff34e3Sthurlow return (ENOMEM); 754bff34e3Sthurlow bzero(m, M_BASESIZE + len); 764bff34e3Sthurlow m->m_maxlen = len; 774bff34e3Sthurlow m->m_data = M_TOP(m); 784bff34e3Sthurlow *mpp = m; 794bff34e3Sthurlow return (0); 804bff34e3Sthurlow } 814bff34e3Sthurlow 824bff34e3Sthurlow static void 834bff34e3Sthurlow m_free(struct mbuf *m) 844bff34e3Sthurlow { 854bff34e3Sthurlow free(m); 864bff34e3Sthurlow } 874bff34e3Sthurlow 884bff34e3Sthurlow static void 894bff34e3Sthurlow m_freem(struct mbuf *m0) 904bff34e3Sthurlow { 914bff34e3Sthurlow struct mbuf *m; 924bff34e3Sthurlow 934bff34e3Sthurlow while (m0) { 944bff34e3Sthurlow m = m0->m_next; 954bff34e3Sthurlow m_free(m0); 964bff34e3Sthurlow m0 = m; 974bff34e3Sthurlow } 984bff34e3Sthurlow } 994bff34e3Sthurlow 1004bff34e3Sthurlow static size_t 1014bff34e3Sthurlow m_totlen(struct mbuf *m0) 1024bff34e3Sthurlow { 1034bff34e3Sthurlow struct mbuf *m = m0; 1044bff34e3Sthurlow int len = 0; 1054bff34e3Sthurlow 1064bff34e3Sthurlow while (m) { 1074bff34e3Sthurlow len += m->m_len; 1084bff34e3Sthurlow m = m->m_next; 1094bff34e3Sthurlow } 1104bff34e3Sthurlow return (len); 1114bff34e3Sthurlow } 1124bff34e3Sthurlow 1134bff34e3Sthurlow int 1144bff34e3Sthurlow m_lineup(struct mbuf *m0, struct mbuf **mpp) 1154bff34e3Sthurlow { 1164bff34e3Sthurlow struct mbuf *nm, *m; 1174bff34e3Sthurlow char *dp; 1184bff34e3Sthurlow size_t len; 1194bff34e3Sthurlow int error; 1204bff34e3Sthurlow 1214bff34e3Sthurlow if (m0->m_next == NULL) { 1224bff34e3Sthurlow *mpp = m0; 1234bff34e3Sthurlow return (0); 1244bff34e3Sthurlow } 1254bff34e3Sthurlow if ((error = m_get(m_totlen(m0), &nm)) != 0) 1264bff34e3Sthurlow return (error); 1274bff34e3Sthurlow dp = mtod(nm, char *); 1284bff34e3Sthurlow while (m0) { 1294bff34e3Sthurlow len = m0->m_len; 1304bff34e3Sthurlow bcopy(m0->m_data, dp, len); 1314bff34e3Sthurlow dp += len; 1324bff34e3Sthurlow m = m0->m_next; 1334bff34e3Sthurlow m_free(m0); 1344bff34e3Sthurlow m0 = m; 1354bff34e3Sthurlow } 1364bff34e3Sthurlow *mpp = nm; 1374bff34e3Sthurlow return (0); 1384bff34e3Sthurlow } 1394bff34e3Sthurlow 1404bff34e3Sthurlow int 1414bff34e3Sthurlow mb_init(struct mbdata *mbp, size_t size) 1424bff34e3Sthurlow { 1434bff34e3Sthurlow struct mbuf *m; 1444bff34e3Sthurlow int error; 1454bff34e3Sthurlow 1464bff34e3Sthurlow if ((error = m_get(size, &m)) != 0) 1474bff34e3Sthurlow return (error); 1484bff34e3Sthurlow return (mb_initm(mbp, m)); 1494bff34e3Sthurlow } 1504bff34e3Sthurlow 1514bff34e3Sthurlow int 1524bff34e3Sthurlow mb_initm(struct mbdata *mbp, struct mbuf *m) 1534bff34e3Sthurlow { 1544bff34e3Sthurlow bzero(mbp, sizeof (*mbp)); 1554bff34e3Sthurlow mbp->mb_top = mbp->mb_cur = m; 1564bff34e3Sthurlow mbp->mb_pos = mtod(m, char *); 1574bff34e3Sthurlow return (0); 1584bff34e3Sthurlow } 1594bff34e3Sthurlow 1604bff34e3Sthurlow int 1614bff34e3Sthurlow mb_done(struct mbdata *mbp) 1624bff34e3Sthurlow { 1634bff34e3Sthurlow if (mbp->mb_top) { 1644bff34e3Sthurlow m_freem(mbp->mb_top); 1654bff34e3Sthurlow mbp->mb_top = NULL; 1664bff34e3Sthurlow } 1674bff34e3Sthurlow return (0); 1684bff34e3Sthurlow } 1694bff34e3Sthurlow 1704bff34e3Sthurlow int 1714bff34e3Sthurlow m_getm(struct mbuf *top, size_t len, struct mbuf **mpp) 1724bff34e3Sthurlow { 1734bff34e3Sthurlow struct mbuf *m, *mp; 1747568150aSgwr int error, ts; 1754bff34e3Sthurlow 1764bff34e3Sthurlow for (mp = top; ; mp = mp->m_next) { 1777568150aSgwr ts = M_TRAILINGSPACE(mp); 1787568150aSgwr if (len <= ts) 1797568150aSgwr goto out; 1807568150aSgwr len -= ts; 1814bff34e3Sthurlow if (mp->m_next == NULL) 1824bff34e3Sthurlow break; 1834bff34e3Sthurlow 1844bff34e3Sthurlow } 1854bff34e3Sthurlow if (len > 0) { 1864bff34e3Sthurlow if ((error = m_get(len, &m)) != 0) 1874bff34e3Sthurlow return (error); 1884bff34e3Sthurlow mp->m_next = m; 1894bff34e3Sthurlow } 1907568150aSgwr out: 1914bff34e3Sthurlow *mpp = top; 1924bff34e3Sthurlow return (0); 1934bff34e3Sthurlow } 1944bff34e3Sthurlow 1954bff34e3Sthurlow /* 1964bff34e3Sthurlow * Routines to put data in a buffer 1974bff34e3Sthurlow */ 1984bff34e3Sthurlow 1994bff34e3Sthurlow /* 2004bff34e3Sthurlow * Check if object of size 'size' fit to the current position and 2014bff34e3Sthurlow * allocate new mbuf if not. Advance pointers and increase length of mbuf(s). 2024bff34e3Sthurlow * Return pointer to the object placeholder or NULL if any error occured. 2034bff34e3Sthurlow */ 2044bff34e3Sthurlow int 2054bff34e3Sthurlow mb_fit(struct mbdata *mbp, size_t size, char **pp) 2064bff34e3Sthurlow { 2074bff34e3Sthurlow struct mbuf *m, *mn; 2084bff34e3Sthurlow int error; 2094bff34e3Sthurlow 2104bff34e3Sthurlow m = mbp->mb_cur; 2114bff34e3Sthurlow if (M_TRAILINGSPACE(m) < (int)size) { 2124bff34e3Sthurlow if ((error = m_get(size, &mn)) != 0) 2134bff34e3Sthurlow return (error); 2144bff34e3Sthurlow mbp->mb_pos = mtod(mn, char *); 2154bff34e3Sthurlow mbp->mb_cur = m->m_next = mn; 2164bff34e3Sthurlow m = mn; 2174bff34e3Sthurlow } 2184bff34e3Sthurlow m->m_len += size; 2194bff34e3Sthurlow *pp = mbp->mb_pos; 2204bff34e3Sthurlow mbp->mb_pos += size; 2214bff34e3Sthurlow mbp->mb_count += size; 2224bff34e3Sthurlow return (0); 2234bff34e3Sthurlow } 2244bff34e3Sthurlow 2254bff34e3Sthurlow int 2264bff34e3Sthurlow mb_put_uint8(struct mbdata *mbp, uint8_t x) 2274bff34e3Sthurlow { 228*9c9af259SGordon Ross uint8_t y = x; 229*9c9af259SGordon Ross return (mb_put_mem(mbp, (char *)&y, sizeof (y))); 2304bff34e3Sthurlow } 2314bff34e3Sthurlow 2324bff34e3Sthurlow int 2334bff34e3Sthurlow mb_put_uint16be(struct mbdata *mbp, uint16_t x) 2344bff34e3Sthurlow { 235*9c9af259SGordon Ross uint16_t y = htobes(x); 236*9c9af259SGordon Ross return (mb_put_mem(mbp, (char *)&y, sizeof (y))); 2374bff34e3Sthurlow } 2384bff34e3Sthurlow 2394bff34e3Sthurlow int 2404bff34e3Sthurlow mb_put_uint16le(struct mbdata *mbp, uint16_t x) 2414bff34e3Sthurlow { 242*9c9af259SGordon Ross uint16_t y = htoles(x); 243*9c9af259SGordon Ross return (mb_put_mem(mbp, (char *)&y, sizeof (y))); 2444bff34e3Sthurlow } 2454bff34e3Sthurlow 2464bff34e3Sthurlow int 2474bff34e3Sthurlow mb_put_uint32be(struct mbdata *mbp, uint32_t x) 2484bff34e3Sthurlow { 249*9c9af259SGordon Ross uint32_t y = htobel(x); 250*9c9af259SGordon Ross return (mb_put_mem(mbp, (char *)&y, sizeof (y))); 2514bff34e3Sthurlow } 2524bff34e3Sthurlow 2534bff34e3Sthurlow int 2544bff34e3Sthurlow mb_put_uint32le(struct mbdata *mbp, uint32_t x) 2554bff34e3Sthurlow { 256*9c9af259SGordon Ross uint32_t y = htolel(x); 257*9c9af259SGordon Ross return (mb_put_mem(mbp, (char *)&y, sizeof (y))); 2584bff34e3Sthurlow } 2594bff34e3Sthurlow 2604bff34e3Sthurlow int 2614bff34e3Sthurlow mb_put_uint64be(struct mbdata *mbp, uint64_t x) 2624bff34e3Sthurlow { 263*9c9af259SGordon Ross uint64_t y = htobeq(x); 264*9c9af259SGordon Ross return (mb_put_mem(mbp, (char *)&y, sizeof (y))); 2654bff34e3Sthurlow } 2664bff34e3Sthurlow 2674bff34e3Sthurlow int 2684bff34e3Sthurlow mb_put_uint64le(struct mbdata *mbp, uint64_t x) 2694bff34e3Sthurlow { 270*9c9af259SGordon Ross uint64_t y = htoleq(x); 271*9c9af259SGordon Ross return (mb_put_mem(mbp, (char *)&y, sizeof (y))); 2724bff34e3Sthurlow } 2734bff34e3Sthurlow 2744bff34e3Sthurlow int 2754bff34e3Sthurlow mb_put_mem(struct mbdata *mbp, const char *source, size_t size) 2764bff34e3Sthurlow { 2774bff34e3Sthurlow struct mbuf *m; 2784bff34e3Sthurlow char *dst; 2794bff34e3Sthurlow size_t cplen; 2804bff34e3Sthurlow int error; 2814bff34e3Sthurlow 2824bff34e3Sthurlow if (size == 0) 2834bff34e3Sthurlow return (0); 2844bff34e3Sthurlow m = mbp->mb_cur; 2854bff34e3Sthurlow if ((error = m_getm(m, size, &m)) != 0) 2864bff34e3Sthurlow return (error); 2874bff34e3Sthurlow while (size > 0) { 2884bff34e3Sthurlow cplen = M_TRAILINGSPACE(m); 2894bff34e3Sthurlow if (cplen == 0) { 2904bff34e3Sthurlow m = m->m_next; 2914bff34e3Sthurlow continue; 2924bff34e3Sthurlow } 2934bff34e3Sthurlow if (cplen > size) 2944bff34e3Sthurlow cplen = size; 2954bff34e3Sthurlow dst = mtod(m, char *) + m->m_len; 2964bff34e3Sthurlow if (source) { 2974bff34e3Sthurlow bcopy(source, dst, cplen); 2984bff34e3Sthurlow source += cplen; 2994bff34e3Sthurlow } else 3004bff34e3Sthurlow bzero(dst, cplen); 3014bff34e3Sthurlow size -= cplen; 3024bff34e3Sthurlow m->m_len += cplen; 3034bff34e3Sthurlow mbp->mb_count += cplen; 3044bff34e3Sthurlow } 3054bff34e3Sthurlow mbp->mb_pos = mtod(m, char *) + m->m_len; 3064bff34e3Sthurlow mbp->mb_cur = m; 3074bff34e3Sthurlow return (0); 3084bff34e3Sthurlow } 3094bff34e3Sthurlow 3104bff34e3Sthurlow int 3114bff34e3Sthurlow mb_put_mbuf(struct mbdata *mbp, struct mbuf *m) 3124bff34e3Sthurlow { 3134bff34e3Sthurlow mbp->mb_cur->m_next = m; 3144bff34e3Sthurlow while (m) { 3154bff34e3Sthurlow mbp->mb_count += m->m_len; 3164bff34e3Sthurlow if (m->m_next == NULL) 3174bff34e3Sthurlow break; 3184bff34e3Sthurlow m = m->m_next; 3194bff34e3Sthurlow } 3204bff34e3Sthurlow mbp->mb_pos = mtod(m, char *) + m->m_len; 3214bff34e3Sthurlow mbp->mb_cur = m; 3224bff34e3Sthurlow return (0); 3234bff34e3Sthurlow } 3244bff34e3Sthurlow 3254bff34e3Sthurlow int 3264bff34e3Sthurlow mb_put_pstring(struct mbdata *mbp, const char *s) 3274bff34e3Sthurlow { 3284bff34e3Sthurlow int error, len = strlen(s); 3294bff34e3Sthurlow 3304bff34e3Sthurlow if (len > 255) { 3314bff34e3Sthurlow len = 255; 3324bff34e3Sthurlow } 3334bff34e3Sthurlow if ((error = mb_put_uint8(mbp, len)) != 0) 3344bff34e3Sthurlow return (error); 3354bff34e3Sthurlow return (mb_put_mem(mbp, s, len)); 3364bff34e3Sthurlow } 3374bff34e3Sthurlow 3384bff34e3Sthurlow /* 3394bff34e3Sthurlow * Routines for fetching data from an mbuf chain 3404bff34e3Sthurlow */ 3414bff34e3Sthurlow #define mb_left(m, p) (mtod(m, char *) + (m)->m_len - (p)) 3424bff34e3Sthurlow 3434bff34e3Sthurlow int 3444bff34e3Sthurlow mb_get_uint8(struct mbdata *mbp, uint8_t *x) 3454bff34e3Sthurlow { 3464bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 1)); 3474bff34e3Sthurlow } 3484bff34e3Sthurlow 3494bff34e3Sthurlow int 3504bff34e3Sthurlow mb_get_uint16(struct mbdata *mbp, uint16_t *x) 3514bff34e3Sthurlow { 3524bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 2)); 3534bff34e3Sthurlow } 3544bff34e3Sthurlow 3554bff34e3Sthurlow int 3564bff34e3Sthurlow mb_get_uint16le(struct mbdata *mbp, uint16_t *x) 3574bff34e3Sthurlow { 3584bff34e3Sthurlow uint16_t v; 3594bff34e3Sthurlow int error = mb_get_uint16(mbp, &v); 3604bff34e3Sthurlow 3614bff34e3Sthurlow if (x != NULL) 3624bff34e3Sthurlow *x = letohs(v); 3634bff34e3Sthurlow return (error); 3644bff34e3Sthurlow } 3654bff34e3Sthurlow 3664bff34e3Sthurlow int 3674bff34e3Sthurlow mb_get_uint16be(struct mbdata *mbp, uint16_t *x) { 3684bff34e3Sthurlow uint16_t v; 3694bff34e3Sthurlow int error = mb_get_uint16(mbp, &v); 3704bff34e3Sthurlow 3714bff34e3Sthurlow if (x != NULL) 3724bff34e3Sthurlow *x = betohs(v); 3734bff34e3Sthurlow return (error); 3744bff34e3Sthurlow } 3754bff34e3Sthurlow 3764bff34e3Sthurlow int 3774bff34e3Sthurlow mb_get_uint32(struct mbdata *mbp, uint32_t *x) 3784bff34e3Sthurlow { 3794bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 4)); 3804bff34e3Sthurlow } 3814bff34e3Sthurlow 3824bff34e3Sthurlow int 3834bff34e3Sthurlow mb_get_uint32be(struct mbdata *mbp, uint32_t *x) 3844bff34e3Sthurlow { 3854bff34e3Sthurlow uint32_t v; 3864bff34e3Sthurlow int error; 3874bff34e3Sthurlow 3884bff34e3Sthurlow error = mb_get_uint32(mbp, &v); 3894bff34e3Sthurlow if (x != NULL) 3904bff34e3Sthurlow *x = betohl(v); 3914bff34e3Sthurlow return (error); 3924bff34e3Sthurlow } 3934bff34e3Sthurlow 3944bff34e3Sthurlow int 3954bff34e3Sthurlow mb_get_uint32le(struct mbdata *mbp, uint32_t *x) 3964bff34e3Sthurlow { 3974bff34e3Sthurlow uint32_t v; 3984bff34e3Sthurlow int error; 3994bff34e3Sthurlow 4004bff34e3Sthurlow error = mb_get_uint32(mbp, &v); 4014bff34e3Sthurlow if (x != NULL) 4024bff34e3Sthurlow *x = letohl(v); 4034bff34e3Sthurlow return (error); 4044bff34e3Sthurlow } 4054bff34e3Sthurlow 4064bff34e3Sthurlow int 4074bff34e3Sthurlow mb_get_uint64(struct mbdata *mbp, uint64_t *x) 4084bff34e3Sthurlow { 4094bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 8)); 4104bff34e3Sthurlow } 4114bff34e3Sthurlow 4124bff34e3Sthurlow int 4134bff34e3Sthurlow mb_get_uint64be(struct mbdata *mbp, uint64_t *x) 4144bff34e3Sthurlow { 4154bff34e3Sthurlow uint64_t v; 4164bff34e3Sthurlow int error; 4174bff34e3Sthurlow 4184bff34e3Sthurlow error = mb_get_uint64(mbp, &v); 4194bff34e3Sthurlow if (x != NULL) 4204bff34e3Sthurlow *x = betohq(v); 4214bff34e3Sthurlow return (error); 4224bff34e3Sthurlow } 4234bff34e3Sthurlow 4244bff34e3Sthurlow int 4254bff34e3Sthurlow mb_get_uint64le(struct mbdata *mbp, uint64_t *x) 4264bff34e3Sthurlow { 4274bff34e3Sthurlow uint64_t v; 4284bff34e3Sthurlow int error; 4294bff34e3Sthurlow 4304bff34e3Sthurlow error = mb_get_uint64(mbp, &v); 4314bff34e3Sthurlow if (x != NULL) 4324bff34e3Sthurlow *x = letohq(v); 4334bff34e3Sthurlow return (error); 4344bff34e3Sthurlow } 4354bff34e3Sthurlow 4364bff34e3Sthurlow int 4374bff34e3Sthurlow mb_get_mem(struct mbdata *mbp, char *target, size_t size) 4384bff34e3Sthurlow { 4394bff34e3Sthurlow struct mbuf *m = mbp->mb_cur; 4404bff34e3Sthurlow uint_t count; 4414bff34e3Sthurlow 4424bff34e3Sthurlow while (size > 0) { 4434bff34e3Sthurlow if (m == NULL) { 4444bff34e3Sthurlow #ifdef DEBUG 4454bff34e3Sthurlow printf( 4464bff34e3Sthurlow dgettext(TEXT_DOMAIN, "incomplete copy\n")); 4474bff34e3Sthurlow #endif 4484bff34e3Sthurlow #ifdef APPLE 4494bff34e3Sthurlow MBERROR("incomplete copy\n"); 4504bff34e3Sthurlow #endif 4514bff34e3Sthurlow return (EBADRPC); 4524bff34e3Sthurlow } 4534bff34e3Sthurlow count = mb_left(m, mbp->mb_pos); 4544bff34e3Sthurlow if (count == 0) { 4554bff34e3Sthurlow mbp->mb_cur = m = m->m_next; 4564bff34e3Sthurlow if (m) 4574bff34e3Sthurlow mbp->mb_pos = mtod(m, char *); 4584bff34e3Sthurlow continue; 4594bff34e3Sthurlow } 4604bff34e3Sthurlow if (count > size) 4614bff34e3Sthurlow count = size; 4624bff34e3Sthurlow size -= count; 4634bff34e3Sthurlow if (target) { 4644bff34e3Sthurlow if (count == 1) { 4654bff34e3Sthurlow *target++ = *mbp->mb_pos; 4664bff34e3Sthurlow } else { 4674bff34e3Sthurlow bcopy(mbp->mb_pos, target, count); 4684bff34e3Sthurlow target += count; 4694bff34e3Sthurlow } 4704bff34e3Sthurlow } 4714bff34e3Sthurlow mbp->mb_pos += count; 4724bff34e3Sthurlow } 4734bff34e3Sthurlow return (0); 4744bff34e3Sthurlow } 475