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 354bff34e3Sthurlow #pragma ident "%Z%%M% %I% %E% SMI" 364bff34e3Sthurlow 374bff34e3Sthurlow #include <sys/types.h> 384bff34e3Sthurlow #include <ctype.h> 394bff34e3Sthurlow #include <errno.h> 404bff34e3Sthurlow #include <stdio.h> 414bff34e3Sthurlow #include <stdlib.h> 424bff34e3Sthurlow #include <string.h> 434bff34e3Sthurlow #include <strings.h> 444bff34e3Sthurlow #include <libintl.h> 45*7568150aSgwr #include <assert.h> 464bff34e3Sthurlow 474bff34e3Sthurlow #include <netsmb/smb.h> 484bff34e3Sthurlow #include <netsmb/smb_lib.h> 494bff34e3Sthurlow #include <netsmb/mchain.h> 504bff34e3Sthurlow 514bff34e3Sthurlow #ifdef APPLE 524bff34e3Sthurlow #define __func__ "" 534bff34e3Sthurlow #define MBERROR(format, args...) \ 544bff34e3Sthurlow printf("%s(%d): "format, __func__, __LINE__, ## args) 554bff34e3Sthurlow #endif 564bff34e3Sthurlow 574bff34e3Sthurlow static int 584bff34e3Sthurlow m_get(size_t len, struct mbuf **mpp) 594bff34e3Sthurlow { 604bff34e3Sthurlow struct mbuf *m; 614bff34e3Sthurlow 62*7568150aSgwr assert(len < 0x100000); /* sanity */ 63*7568150aSgwr 644bff34e3Sthurlow len = M_ALIGN(len); 654bff34e3Sthurlow if (len < M_MINSIZE) 664bff34e3Sthurlow len = M_MINSIZE; 674bff34e3Sthurlow m = malloc(M_BASESIZE + len); 684bff34e3Sthurlow if (m == NULL) 694bff34e3Sthurlow return (ENOMEM); 704bff34e3Sthurlow bzero(m, M_BASESIZE + len); 714bff34e3Sthurlow m->m_maxlen = len; 724bff34e3Sthurlow m->m_data = M_TOP(m); 734bff34e3Sthurlow *mpp = m; 744bff34e3Sthurlow return (0); 754bff34e3Sthurlow } 764bff34e3Sthurlow 774bff34e3Sthurlow static void 784bff34e3Sthurlow m_free(struct mbuf *m) 794bff34e3Sthurlow { 804bff34e3Sthurlow free(m); 814bff34e3Sthurlow } 824bff34e3Sthurlow 834bff34e3Sthurlow static void 844bff34e3Sthurlow m_freem(struct mbuf *m0) 854bff34e3Sthurlow { 864bff34e3Sthurlow struct mbuf *m; 874bff34e3Sthurlow 884bff34e3Sthurlow while (m0) { 894bff34e3Sthurlow m = m0->m_next; 904bff34e3Sthurlow m_free(m0); 914bff34e3Sthurlow m0 = m; 924bff34e3Sthurlow } 934bff34e3Sthurlow } 944bff34e3Sthurlow 954bff34e3Sthurlow static size_t 964bff34e3Sthurlow m_totlen(struct mbuf *m0) 974bff34e3Sthurlow { 984bff34e3Sthurlow struct mbuf *m = m0; 994bff34e3Sthurlow int len = 0; 1004bff34e3Sthurlow 1014bff34e3Sthurlow while (m) { 1024bff34e3Sthurlow len += m->m_len; 1034bff34e3Sthurlow m = m->m_next; 1044bff34e3Sthurlow } 1054bff34e3Sthurlow return (len); 1064bff34e3Sthurlow } 1074bff34e3Sthurlow 1084bff34e3Sthurlow int 1094bff34e3Sthurlow m_lineup(struct mbuf *m0, struct mbuf **mpp) 1104bff34e3Sthurlow { 1114bff34e3Sthurlow struct mbuf *nm, *m; 1124bff34e3Sthurlow char *dp; 1134bff34e3Sthurlow size_t len; 1144bff34e3Sthurlow int error; 1154bff34e3Sthurlow 1164bff34e3Sthurlow if (m0->m_next == NULL) { 1174bff34e3Sthurlow *mpp = m0; 1184bff34e3Sthurlow return (0); 1194bff34e3Sthurlow } 1204bff34e3Sthurlow if ((error = m_get(m_totlen(m0), &nm)) != 0) 1214bff34e3Sthurlow return (error); 1224bff34e3Sthurlow dp = mtod(nm, char *); 1234bff34e3Sthurlow while (m0) { 1244bff34e3Sthurlow len = m0->m_len; 1254bff34e3Sthurlow bcopy(m0->m_data, dp, len); 1264bff34e3Sthurlow dp += len; 1274bff34e3Sthurlow m = m0->m_next; 1284bff34e3Sthurlow m_free(m0); 1294bff34e3Sthurlow m0 = m; 1304bff34e3Sthurlow } 1314bff34e3Sthurlow *mpp = nm; 1324bff34e3Sthurlow return (0); 1334bff34e3Sthurlow } 1344bff34e3Sthurlow 1354bff34e3Sthurlow int 1364bff34e3Sthurlow mb_init(struct mbdata *mbp, size_t size) 1374bff34e3Sthurlow { 1384bff34e3Sthurlow struct mbuf *m; 1394bff34e3Sthurlow int error; 1404bff34e3Sthurlow 1414bff34e3Sthurlow if ((error = m_get(size, &m)) != 0) 1424bff34e3Sthurlow return (error); 1434bff34e3Sthurlow return (mb_initm(mbp, m)); 1444bff34e3Sthurlow } 1454bff34e3Sthurlow 1464bff34e3Sthurlow int 1474bff34e3Sthurlow mb_initm(struct mbdata *mbp, struct mbuf *m) 1484bff34e3Sthurlow { 1494bff34e3Sthurlow bzero(mbp, sizeof (*mbp)); 1504bff34e3Sthurlow mbp->mb_top = mbp->mb_cur = m; 1514bff34e3Sthurlow mbp->mb_pos = mtod(m, char *); 1524bff34e3Sthurlow return (0); 1534bff34e3Sthurlow } 1544bff34e3Sthurlow 1554bff34e3Sthurlow int 1564bff34e3Sthurlow mb_done(struct mbdata *mbp) 1574bff34e3Sthurlow { 1584bff34e3Sthurlow if (mbp->mb_top) { 1594bff34e3Sthurlow m_freem(mbp->mb_top); 1604bff34e3Sthurlow mbp->mb_top = NULL; 1614bff34e3Sthurlow } 1624bff34e3Sthurlow return (0); 1634bff34e3Sthurlow } 1644bff34e3Sthurlow 1654bff34e3Sthurlow int 1664bff34e3Sthurlow m_getm(struct mbuf *top, size_t len, struct mbuf **mpp) 1674bff34e3Sthurlow { 1684bff34e3Sthurlow struct mbuf *m, *mp; 169*7568150aSgwr int error, ts; 1704bff34e3Sthurlow 1714bff34e3Sthurlow for (mp = top; ; mp = mp->m_next) { 172*7568150aSgwr ts = M_TRAILINGSPACE(mp); 173*7568150aSgwr if (len <= ts) 174*7568150aSgwr goto out; 175*7568150aSgwr len -= ts; 1764bff34e3Sthurlow if (mp->m_next == NULL) 1774bff34e3Sthurlow break; 1784bff34e3Sthurlow 1794bff34e3Sthurlow } 1804bff34e3Sthurlow if (len > 0) { 1814bff34e3Sthurlow if ((error = m_get(len, &m)) != 0) 1824bff34e3Sthurlow return (error); 1834bff34e3Sthurlow mp->m_next = m; 1844bff34e3Sthurlow } 185*7568150aSgwr out: 1864bff34e3Sthurlow *mpp = top; 1874bff34e3Sthurlow return (0); 1884bff34e3Sthurlow } 1894bff34e3Sthurlow 1904bff34e3Sthurlow /* 1914bff34e3Sthurlow * Routines to put data in a buffer 1924bff34e3Sthurlow */ 1934bff34e3Sthurlow #define MB_PUT(t) int error; t *p; \ 1944bff34e3Sthurlow if ((error = mb_fit(mbp, sizeof (t), (char **)&p)) != 0) \ 1954bff34e3Sthurlow return (error) 1964bff34e3Sthurlow 1974bff34e3Sthurlow /* 1984bff34e3Sthurlow * Check if object of size 'size' fit to the current position and 1994bff34e3Sthurlow * allocate new mbuf if not. Advance pointers and increase length of mbuf(s). 2004bff34e3Sthurlow * Return pointer to the object placeholder or NULL if any error occured. 2014bff34e3Sthurlow */ 2024bff34e3Sthurlow int 2034bff34e3Sthurlow mb_fit(struct mbdata *mbp, size_t size, char **pp) 2044bff34e3Sthurlow { 2054bff34e3Sthurlow struct mbuf *m, *mn; 2064bff34e3Sthurlow int error; 2074bff34e3Sthurlow 2084bff34e3Sthurlow m = mbp->mb_cur; 2094bff34e3Sthurlow if (M_TRAILINGSPACE(m) < (int)size) { 2104bff34e3Sthurlow if ((error = m_get(size, &mn)) != 0) 2114bff34e3Sthurlow return (error); 2124bff34e3Sthurlow mbp->mb_pos = mtod(mn, char *); 2134bff34e3Sthurlow mbp->mb_cur = m->m_next = mn; 2144bff34e3Sthurlow m = mn; 2154bff34e3Sthurlow } 2164bff34e3Sthurlow m->m_len += size; 2174bff34e3Sthurlow *pp = mbp->mb_pos; 2184bff34e3Sthurlow mbp->mb_pos += size; 2194bff34e3Sthurlow mbp->mb_count += size; 2204bff34e3Sthurlow return (0); 2214bff34e3Sthurlow } 2224bff34e3Sthurlow 2234bff34e3Sthurlow int 2244bff34e3Sthurlow mb_put_uint8(struct mbdata *mbp, uint8_t x) 2254bff34e3Sthurlow { 2264bff34e3Sthurlow MB_PUT(uint8_t); 2274bff34e3Sthurlow *p = x; 2284bff34e3Sthurlow return (0); 2294bff34e3Sthurlow } 2304bff34e3Sthurlow 2314bff34e3Sthurlow int 2324bff34e3Sthurlow mb_put_uint16be(struct mbdata *mbp, uint16_t x) 2334bff34e3Sthurlow { 2344bff34e3Sthurlow MB_PUT(uint16_t); 2354bff34e3Sthurlow /* LINTED */ 2364bff34e3Sthurlow setwbe(p, 0, x); 2374bff34e3Sthurlow return (0); 2384bff34e3Sthurlow } 2394bff34e3Sthurlow 2404bff34e3Sthurlow int 2414bff34e3Sthurlow mb_put_uint16le(struct mbdata *mbp, uint16_t x) 2424bff34e3Sthurlow { 2434bff34e3Sthurlow MB_PUT(uint16_t); 2444bff34e3Sthurlow /* LINTED */ 2454bff34e3Sthurlow setwle(p, 0, x); 2464bff34e3Sthurlow return (0); 2474bff34e3Sthurlow } 2484bff34e3Sthurlow 2494bff34e3Sthurlow int 2504bff34e3Sthurlow mb_put_uint32be(struct mbdata *mbp, uint32_t x) 2514bff34e3Sthurlow { 2524bff34e3Sthurlow MB_PUT(uint32_t); 2534bff34e3Sthurlow /* LINTED */ 2544bff34e3Sthurlow setdbe(p, 0, x); 2554bff34e3Sthurlow return (0); 2564bff34e3Sthurlow } 2574bff34e3Sthurlow 2584bff34e3Sthurlow int 2594bff34e3Sthurlow mb_put_uint32le(struct mbdata *mbp, uint32_t x) 2604bff34e3Sthurlow { 2614bff34e3Sthurlow MB_PUT(uint32_t); 2624bff34e3Sthurlow /* LINTED */ 2634bff34e3Sthurlow setdle(p, 0, x); 2644bff34e3Sthurlow return (0); 2654bff34e3Sthurlow } 2664bff34e3Sthurlow 2674bff34e3Sthurlow int 2684bff34e3Sthurlow mb_put_uint64be(struct mbdata *mbp, uint64_t x) 2694bff34e3Sthurlow { 2704bff34e3Sthurlow MB_PUT(uint64_t); 2714bff34e3Sthurlow *p = htobeq(x); 2724bff34e3Sthurlow return (0); 2734bff34e3Sthurlow } 2744bff34e3Sthurlow 2754bff34e3Sthurlow int 2764bff34e3Sthurlow mb_put_uint64le(struct mbdata *mbp, uint64_t x) 2774bff34e3Sthurlow { 2784bff34e3Sthurlow MB_PUT(uint64_t); 2794bff34e3Sthurlow *p = htoleq(x); 2804bff34e3Sthurlow return (0); 2814bff34e3Sthurlow } 2824bff34e3Sthurlow 2834bff34e3Sthurlow int 2844bff34e3Sthurlow mb_put_mem(struct mbdata *mbp, const char *source, size_t size) 2854bff34e3Sthurlow { 2864bff34e3Sthurlow struct mbuf *m; 2874bff34e3Sthurlow char *dst; 2884bff34e3Sthurlow size_t cplen; 2894bff34e3Sthurlow int error; 2904bff34e3Sthurlow 2914bff34e3Sthurlow if (size == 0) 2924bff34e3Sthurlow return (0); 2934bff34e3Sthurlow m = mbp->mb_cur; 2944bff34e3Sthurlow if ((error = m_getm(m, size, &m)) != 0) 2954bff34e3Sthurlow return (error); 2964bff34e3Sthurlow while (size > 0) { 2974bff34e3Sthurlow cplen = M_TRAILINGSPACE(m); 2984bff34e3Sthurlow if (cplen == 0) { 2994bff34e3Sthurlow m = m->m_next; 3004bff34e3Sthurlow continue; 3014bff34e3Sthurlow } 3024bff34e3Sthurlow if (cplen > size) 3034bff34e3Sthurlow cplen = size; 3044bff34e3Sthurlow dst = mtod(m, char *) + m->m_len; 3054bff34e3Sthurlow if (source) { 3064bff34e3Sthurlow bcopy(source, dst, cplen); 3074bff34e3Sthurlow source += cplen; 3084bff34e3Sthurlow } else 3094bff34e3Sthurlow bzero(dst, cplen); 3104bff34e3Sthurlow size -= cplen; 3114bff34e3Sthurlow m->m_len += cplen; 3124bff34e3Sthurlow mbp->mb_count += cplen; 3134bff34e3Sthurlow } 3144bff34e3Sthurlow mbp->mb_pos = mtod(m, char *) + m->m_len; 3154bff34e3Sthurlow mbp->mb_cur = m; 3164bff34e3Sthurlow return (0); 3174bff34e3Sthurlow } 3184bff34e3Sthurlow 3194bff34e3Sthurlow int 3204bff34e3Sthurlow mb_put_mbuf(struct mbdata *mbp, struct mbuf *m) 3214bff34e3Sthurlow { 3224bff34e3Sthurlow mbp->mb_cur->m_next = m; 3234bff34e3Sthurlow while (m) { 3244bff34e3Sthurlow mbp->mb_count += m->m_len; 3254bff34e3Sthurlow if (m->m_next == NULL) 3264bff34e3Sthurlow break; 3274bff34e3Sthurlow m = m->m_next; 3284bff34e3Sthurlow } 3294bff34e3Sthurlow mbp->mb_pos = mtod(m, char *) + m->m_len; 3304bff34e3Sthurlow mbp->mb_cur = m; 3314bff34e3Sthurlow return (0); 3324bff34e3Sthurlow } 3334bff34e3Sthurlow 3344bff34e3Sthurlow int 3354bff34e3Sthurlow mb_put_pstring(struct mbdata *mbp, const char *s) 3364bff34e3Sthurlow { 3374bff34e3Sthurlow int error, len = strlen(s); 3384bff34e3Sthurlow 3394bff34e3Sthurlow if (len > 255) { 3404bff34e3Sthurlow len = 255; 3414bff34e3Sthurlow } 3424bff34e3Sthurlow if ((error = mb_put_uint8(mbp, len)) != 0) 3434bff34e3Sthurlow return (error); 3444bff34e3Sthurlow return (mb_put_mem(mbp, s, len)); 3454bff34e3Sthurlow } 3464bff34e3Sthurlow 3474bff34e3Sthurlow /* 3484bff34e3Sthurlow * Routines for fetching data from an mbuf chain 3494bff34e3Sthurlow */ 3504bff34e3Sthurlow #define mb_left(m, p) (mtod(m, char *) + (m)->m_len - (p)) 3514bff34e3Sthurlow 3524bff34e3Sthurlow int 3534bff34e3Sthurlow mb_get_uint8(struct mbdata *mbp, uint8_t *x) 3544bff34e3Sthurlow { 3554bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 1)); 3564bff34e3Sthurlow } 3574bff34e3Sthurlow 3584bff34e3Sthurlow int 3594bff34e3Sthurlow mb_get_uint16(struct mbdata *mbp, uint16_t *x) 3604bff34e3Sthurlow { 3614bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 2)); 3624bff34e3Sthurlow } 3634bff34e3Sthurlow 3644bff34e3Sthurlow int 3654bff34e3Sthurlow mb_get_uint16le(struct mbdata *mbp, uint16_t *x) 3664bff34e3Sthurlow { 3674bff34e3Sthurlow uint16_t v; 3684bff34e3Sthurlow int error = mb_get_uint16(mbp, &v); 3694bff34e3Sthurlow 3704bff34e3Sthurlow if (x != NULL) 3714bff34e3Sthurlow *x = letohs(v); 3724bff34e3Sthurlow return (error); 3734bff34e3Sthurlow } 3744bff34e3Sthurlow 3754bff34e3Sthurlow int 3764bff34e3Sthurlow mb_get_uint16be(struct mbdata *mbp, uint16_t *x) { 3774bff34e3Sthurlow uint16_t v; 3784bff34e3Sthurlow int error = mb_get_uint16(mbp, &v); 3794bff34e3Sthurlow 3804bff34e3Sthurlow if (x != NULL) 3814bff34e3Sthurlow *x = betohs(v); 3824bff34e3Sthurlow return (error); 3834bff34e3Sthurlow } 3844bff34e3Sthurlow 3854bff34e3Sthurlow int 3864bff34e3Sthurlow mb_get_uint32(struct mbdata *mbp, uint32_t *x) 3874bff34e3Sthurlow { 3884bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 4)); 3894bff34e3Sthurlow } 3904bff34e3Sthurlow 3914bff34e3Sthurlow int 3924bff34e3Sthurlow mb_get_uint32be(struct mbdata *mbp, uint32_t *x) 3934bff34e3Sthurlow { 3944bff34e3Sthurlow uint32_t v; 3954bff34e3Sthurlow int error; 3964bff34e3Sthurlow 3974bff34e3Sthurlow error = mb_get_uint32(mbp, &v); 3984bff34e3Sthurlow if (x != NULL) 3994bff34e3Sthurlow *x = betohl(v); 4004bff34e3Sthurlow return (error); 4014bff34e3Sthurlow } 4024bff34e3Sthurlow 4034bff34e3Sthurlow int 4044bff34e3Sthurlow mb_get_uint32le(struct mbdata *mbp, uint32_t *x) 4054bff34e3Sthurlow { 4064bff34e3Sthurlow uint32_t v; 4074bff34e3Sthurlow int error; 4084bff34e3Sthurlow 4094bff34e3Sthurlow error = mb_get_uint32(mbp, &v); 4104bff34e3Sthurlow if (x != NULL) 4114bff34e3Sthurlow *x = letohl(v); 4124bff34e3Sthurlow return (error); 4134bff34e3Sthurlow } 4144bff34e3Sthurlow 4154bff34e3Sthurlow int 4164bff34e3Sthurlow mb_get_uint64(struct mbdata *mbp, uint64_t *x) 4174bff34e3Sthurlow { 4184bff34e3Sthurlow return (mb_get_mem(mbp, (char *)x, 8)); 4194bff34e3Sthurlow } 4204bff34e3Sthurlow 4214bff34e3Sthurlow int 4224bff34e3Sthurlow mb_get_uint64be(struct mbdata *mbp, uint64_t *x) 4234bff34e3Sthurlow { 4244bff34e3Sthurlow uint64_t v; 4254bff34e3Sthurlow int error; 4264bff34e3Sthurlow 4274bff34e3Sthurlow error = mb_get_uint64(mbp, &v); 4284bff34e3Sthurlow if (x != NULL) 4294bff34e3Sthurlow *x = betohq(v); 4304bff34e3Sthurlow return (error); 4314bff34e3Sthurlow } 4324bff34e3Sthurlow 4334bff34e3Sthurlow int 4344bff34e3Sthurlow mb_get_uint64le(struct mbdata *mbp, uint64_t *x) 4354bff34e3Sthurlow { 4364bff34e3Sthurlow uint64_t v; 4374bff34e3Sthurlow int error; 4384bff34e3Sthurlow 4394bff34e3Sthurlow error = mb_get_uint64(mbp, &v); 4404bff34e3Sthurlow if (x != NULL) 4414bff34e3Sthurlow *x = letohq(v); 4424bff34e3Sthurlow return (error); 4434bff34e3Sthurlow } 4444bff34e3Sthurlow 4454bff34e3Sthurlow int 4464bff34e3Sthurlow mb_get_mem(struct mbdata *mbp, char *target, size_t size) 4474bff34e3Sthurlow { 4484bff34e3Sthurlow struct mbuf *m = mbp->mb_cur; 4494bff34e3Sthurlow uint_t count; 4504bff34e3Sthurlow 4514bff34e3Sthurlow while (size > 0) { 4524bff34e3Sthurlow if (m == NULL) { 4534bff34e3Sthurlow #ifdef DEBUG 4544bff34e3Sthurlow printf( 4554bff34e3Sthurlow dgettext(TEXT_DOMAIN, "incomplete copy\n")); 4564bff34e3Sthurlow #endif 4574bff34e3Sthurlow #ifdef APPLE 4584bff34e3Sthurlow MBERROR("incomplete copy\n"); 4594bff34e3Sthurlow #endif 4604bff34e3Sthurlow return (EBADRPC); 4614bff34e3Sthurlow } 4624bff34e3Sthurlow count = mb_left(m, mbp->mb_pos); 4634bff34e3Sthurlow if (count == 0) { 4644bff34e3Sthurlow mbp->mb_cur = m = m->m_next; 4654bff34e3Sthurlow if (m) 4664bff34e3Sthurlow mbp->mb_pos = mtod(m, char *); 4674bff34e3Sthurlow continue; 4684bff34e3Sthurlow } 4694bff34e3Sthurlow if (count > size) 4704bff34e3Sthurlow count = size; 4714bff34e3Sthurlow size -= count; 4724bff34e3Sthurlow if (target) { 4734bff34e3Sthurlow if (count == 1) { 4744bff34e3Sthurlow *target++ = *mbp->mb_pos; 4754bff34e3Sthurlow } else { 4764bff34e3Sthurlow bcopy(mbp->mb_pos, target, count); 4774bff34e3Sthurlow target += count; 4784bff34e3Sthurlow } 4794bff34e3Sthurlow } 4804bff34e3Sthurlow mbp->mb_pos += count; 4814bff34e3Sthurlow } 4824bff34e3Sthurlow return (0); 4834bff34e3Sthurlow } 484