Annotation of embedaddon/dhcp/omapip/buffer.c, revision 1.1

1.1     ! misho       1: /* buffer.c
        !             2: 
        !             3:    Buffer access functions for the object management protocol... */
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 2004,2005,2007,2009
        !             7:  * by Internet Systems Consortium, Inc. ("ISC")
        !             8:  * Copyright (c) 1999-2003 by Internet Software Consortium
        !             9:  *
        !            10:  * Permission to use, copy, modify, and distribute this software for any
        !            11:  * purpose with or without fee is hereby granted, provided that the above
        !            12:  * copyright notice and this permission notice appear in all copies.
        !            13:  *
        !            14:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
        !            15:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            16:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
        !            17:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            18:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            19:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
        !            20:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            21:  *
        !            22:  *   Internet Systems Consortium, Inc.
        !            23:  *   950 Charter Street
        !            24:  *   Redwood City, CA 94063
        !            25:  *   <info@isc.org>
        !            26:  *   https://www.isc.org/
        !            27:  *
        !            28:  * This software has been written for Internet Systems Consortium
        !            29:  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
        !            30:  * To learn more about Internet Systems Consortium, see
        !            31:  * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
        !            32:  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
        !            33:  * ``http://www.nominum.com''.
        !            34:  */
        !            35: 
        !            36: #include "dhcpd.h"
        !            37: 
        !            38: #include <omapip/omapip_p.h>
        !            39: #include <errno.h>
        !            40: 
        !            41: #if defined (TRACING)
        !            42: static void trace_connection_input_input (trace_type_t *, unsigned, char *);
        !            43: static void trace_connection_input_stop (trace_type_t *);
        !            44: static void trace_connection_output_input (trace_type_t *, unsigned, char *);
        !            45: static void trace_connection_output_stop (trace_type_t *);
        !            46: static trace_type_t *trace_connection_input;
        !            47: static trace_type_t *trace_connection_output;
        !            48: static isc_result_t omapi_connection_reader_trace (omapi_object_t *,
        !            49:                                                   unsigned, char *,
        !            50:                                                   unsigned *);
        !            51: extern omapi_array_t *omapi_connections;
        !            52: 
        !            53: void omapi_buffer_trace_setup ()
        !            54: {
        !            55:        trace_connection_input =
        !            56:                trace_type_register ("connection-input",
        !            57:                                     (void *)0,
        !            58:                                     trace_connection_input_input,
        !            59:                                     trace_connection_input_stop, MDL);
        !            60:        trace_connection_output =
        !            61:                trace_type_register ("connection-output",
        !            62:                                     (void *)0,
        !            63:                                     trace_connection_output_input,
        !            64:                                     trace_connection_output_stop, MDL);
        !            65: }
        !            66: 
        !            67: static void trace_connection_input_input (trace_type_t *ttype,
        !            68:                                          unsigned length, char *buf)
        !            69: {
        !            70:        unsigned left, taken, cc = 0;
        !            71:        char *s;
        !            72:        int32_t connect_index;
        !            73:        isc_result_t status;
        !            74:        omapi_connection_object_t *c = (omapi_connection_object_t *)0;
        !            75: 
        !            76:        memcpy (&connect_index, buf, sizeof connect_index);
        !            77:        connect_index = ntohl (connect_index);
        !            78: 
        !            79:        omapi_array_foreach_begin (omapi_connections,
        !            80:                                   omapi_connection_object_t, lp) {
        !            81:                if (lp -> index == ntohl (connect_index)) {
        !            82:                        omapi_connection_reference (&c, lp, MDL);
        !            83:                        omapi_connection_dereference (&lp, MDL);
        !            84:                        break;
        !            85:                }
        !            86:        } omapi_array_foreach_end (omapi_connections,
        !            87:                                   omapi_connection_object_t, lp);
        !            88: 
        !            89:        if (!c) {
        !            90:                log_error ("trace connection input: no connection index %ld",
        !            91:                           (long int)connect_index);
        !            92:                return;
        !            93:        }
        !            94: 
        !            95:        s = buf + sizeof connect_index;
        !            96:        left = length - sizeof connect_index;
        !            97: 
        !            98:        while (left) {
        !            99:                taken = 0;
        !           100:                status = omapi_connection_reader_trace ((omapi_object_t *)c,
        !           101:                                                        left, s, &taken);
        !           102:                if (status != ISC_R_SUCCESS) {
        !           103:                        log_error ("trace connection input: %s",
        !           104:                                   isc_result_totext (status));
        !           105:                        break;
        !           106:                }
        !           107:                if (!taken) {
        !           108:                        if (cc > 0) {
        !           109:                                log_error ("trace connection_input: %s",
        !           110:                                           "input is not being consumed.");
        !           111:                                break;
        !           112:                        }
        !           113:                        cc++;
        !           114:                } else {
        !           115:                        cc = 0;
        !           116:                        left -= taken;
        !           117:                }
        !           118:        }
        !           119:        omapi_connection_dereference (&c, MDL);
        !           120: }
        !           121: 
        !           122: static void trace_connection_input_stop (trace_type_t *ttype) { }
        !           123: 
        !           124: static void trace_connection_output_input (trace_type_t *ttype,
        !           125:                                          unsigned length, char *buf)
        !           126: {
        !           127:        /* We *could* check to see if the output is correct, but for now
        !           128:           we aren't going to do that. */
        !           129: }
        !           130: 
        !           131: static void trace_connection_output_stop (trace_type_t *ttype) { }
        !           132: 
        !           133: #endif
        !           134: 
        !           135: /* Make sure that at least len bytes are in the input buffer, and if not,
        !           136:    read enough bytes to make up the difference. */
        !           137: 
        !           138: isc_result_t omapi_connection_reader (omapi_object_t *h)
        !           139: {
        !           140: #if defined (TRACING)
        !           141:        return omapi_connection_reader_trace (h, 0, (char *)0, (unsigned *)0);
        !           142: }
        !           143: 
        !           144: static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
        !           145:                                                   unsigned stuff_len,
        !           146:                                                   char *stuff_buf,
        !           147:                                                   unsigned *stuff_taken)
        !           148: {
        !           149: #endif
        !           150:        omapi_buffer_t *buffer;
        !           151:        isc_result_t status;
        !           152:        unsigned read_len;
        !           153:        int read_status;
        !           154:        omapi_connection_object_t *c;
        !           155:        unsigned bytes_to_read;
        !           156:        
        !           157:        if (!h || h -> type != omapi_type_connection)
        !           158:                return ISC_R_INVALIDARG;
        !           159:        c = (omapi_connection_object_t *)h;
        !           160: 
        !           161:        /* See if there are enough bytes. */
        !           162:        if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
        !           163:            c -> in_bytes > c -> bytes_needed)
        !           164:                return ISC_R_SUCCESS;
        !           165: 
        !           166: 
        !           167:        if (c -> inbufs) {
        !           168:                for (buffer = c -> inbufs; buffer -> next;
        !           169:                     buffer = buffer -> next)
        !           170:                        ;
        !           171:                if (!BUFFER_BYTES_FREE (buffer)) {
        !           172:                        status = omapi_buffer_new (&buffer -> next, MDL);
        !           173:                        if (status != ISC_R_SUCCESS)
        !           174:                                return status;
        !           175:                        buffer = buffer -> next;
        !           176:                }
        !           177:        } else {
        !           178:                status = omapi_buffer_new (&c -> inbufs, MDL);
        !           179:                if (status != ISC_R_SUCCESS)
        !           180:                        return status;
        !           181:                buffer = c -> inbufs;
        !           182:        }
        !           183: 
        !           184:        bytes_to_read = BUFFER_BYTES_FREE (buffer);
        !           185: 
        !           186:        while (bytes_to_read) {
        !           187:                if (buffer -> tail > buffer -> head)
        !           188:                        read_len = sizeof (buffer -> buf) - buffer -> tail;
        !           189:                else
        !           190:                        read_len = buffer -> head - buffer -> tail;
        !           191: 
        !           192: #if defined (TRACING)
        !           193:                if (trace_playback()) {
        !           194:                        if (stuff_len) {
        !           195:                                if (read_len > stuff_len)
        !           196:                                        read_len = stuff_len;
        !           197:                                if (stuff_taken)
        !           198:                                        *stuff_taken += read_len;
        !           199:                                memcpy (&buffer -> buf [buffer -> tail],
        !           200:                                        stuff_buf, read_len);
        !           201:                                stuff_len -= read_len;
        !           202:                                stuff_buf += read_len;
        !           203:                                read_status = read_len;
        !           204:                        } else {
        !           205:                                break;
        !           206:                        }
        !           207:                } else
        !           208: #endif
        !           209:                {
        !           210:                        read_status = read (c -> socket,
        !           211:                                            &buffer -> buf [buffer -> tail],
        !           212:                                            read_len);
        !           213:                }
        !           214:                if (read_status < 0) {
        !           215:                        if (errno == EWOULDBLOCK)
        !           216:                                break;
        !           217:                        else if (errno == EIO)
        !           218:                                return ISC_R_IOERROR;
        !           219:                        else if (errno == EINVAL)
        !           220:                                return ISC_R_INVALIDARG;
        !           221:                        else if (errno == ECONNRESET) {
        !           222:                                omapi_disconnect (h, 1);
        !           223:                                return ISC_R_SHUTTINGDOWN;
        !           224:                        } else
        !           225:                                return ISC_R_UNEXPECTED;
        !           226:                }
        !           227: 
        !           228:                /* If we got a zero-length read, as opposed to EWOULDBLOCK,
        !           229:                   the remote end closed the connection. */
        !           230:                if (read_status == 0) {
        !           231:                        omapi_disconnect (h, 0);
        !           232:                        return ISC_R_SHUTTINGDOWN;
        !           233:                }
        !           234: #if defined (TRACING)
        !           235:                if (trace_record ()) {
        !           236:                        trace_iov_t iov [2];
        !           237:                        int32_t connect_index;
        !           238: 
        !           239:                        connect_index = htonl (c -> index);
        !           240: 
        !           241:                        iov [0].buf = (char *)&connect_index;
        !           242:                        iov [0].len = sizeof connect_index;
        !           243:                        iov [1].buf = &buffer -> buf [buffer -> tail];
        !           244:                        iov [1].len = read_status;
        !           245: 
        !           246:                        status = (trace_write_packet_iov
        !           247:                                  (trace_connection_input, 2, iov, MDL));
        !           248:                        if (status != ISC_R_SUCCESS) {
        !           249:                                trace_stop ();
        !           250:                                log_error ("trace connection input: %s",
        !           251:                                           isc_result_totext (status));
        !           252:                        }
        !           253:                }
        !           254: #endif
        !           255:                buffer -> tail += read_status;
        !           256:                c -> in_bytes += read_status;
        !           257:                if (buffer -> tail == sizeof buffer -> buf)
        !           258:                        buffer -> tail = 0;
        !           259:                if (read_status < read_len)
        !           260:                        break;
        !           261:                bytes_to_read -= read_status;
        !           262:        }
        !           263: 
        !           264:        if (c -> bytes_needed <= c -> in_bytes) {
        !           265:                omapi_signal (h, "ready", c);
        !           266:        }
        !           267:        return ISC_R_SUCCESS;
        !           268: }
        !           269: 
        !           270: /* Put some bytes into the output buffer for a connection. */
        !           271: 
        !           272: isc_result_t omapi_connection_copyin (omapi_object_t *h,
        !           273:                                      const unsigned char *bufp,
        !           274:                                      unsigned len)
        !           275: {
        !           276:        omapi_buffer_t *buffer;
        !           277:        isc_result_t status;
        !           278:        int bytes_copied = 0;
        !           279:        unsigned copy_len;
        !           280:        int sig_flags = SIG_MODE_UPDATE;
        !           281:        omapi_connection_object_t *c;
        !           282: 
        !           283:        /* Make sure len is valid. */
        !           284:        if (len < 0)
        !           285:                return ISC_R_INVALIDARG;
        !           286:        if (!h || h -> type != omapi_type_connection)
        !           287:                return ISC_R_INVALIDARG;
        !           288:        c = (omapi_connection_object_t *)h;
        !           289: 
        !           290:        /* If the connection is closed, return an error if the caller
        !           291:           tries to copy in. */
        !           292:        if (c -> state == omapi_connection_disconnecting ||
        !           293:            c -> state == omapi_connection_closed)
        !           294:                return ISC_R_NOTCONNECTED;
        !           295: 
        !           296:        if (c -> outbufs) {
        !           297:                for (buffer = c -> outbufs;
        !           298:                     buffer -> next; buffer = buffer -> next)
        !           299:                        ;
        !           300:        } else {
        !           301:                status = omapi_buffer_new (&c -> outbufs, MDL);
        !           302:                if (status != ISC_R_SUCCESS)
        !           303:                        return status;
        !           304:                buffer = c -> outbufs;
        !           305:        }
        !           306: 
        !           307:        while (bytes_copied < len) {
        !           308:                /* If there is no space available in this buffer,
        !           309:                    allocate a new one. */
        !           310:                if (!BUFFER_BYTES_FREE (buffer)) {
        !           311:                        status = (omapi_buffer_new (&buffer -> next, MDL));
        !           312:                        if (status != ISC_R_SUCCESS)
        !           313:                                return status;
        !           314:                        buffer = buffer -> next;
        !           315:                }
        !           316: 
        !           317:                if (buffer -> tail > buffer -> head)
        !           318:                        copy_len = sizeof (buffer -> buf) - buffer -> tail;
        !           319:                else
        !           320:                        copy_len = buffer -> head - buffer -> tail;
        !           321: 
        !           322:                if (copy_len > (len - bytes_copied))
        !           323:                        copy_len = len - bytes_copied;
        !           324: 
        !           325:                if (c -> out_key) {
        !           326:                        if (!c -> out_context)
        !           327:                                sig_flags |= SIG_MODE_INIT;
        !           328:                        status = omapi_connection_sign_data
        !           329:                                (sig_flags, c -> out_key, &c -> out_context,
        !           330:                                 &bufp [bytes_copied], copy_len,
        !           331:                                 (omapi_typed_data_t **)0);
        !           332:                        if (status != ISC_R_SUCCESS)
        !           333:                                return status;
        !           334:                }
        !           335: 
        !           336:                memcpy (&buffer -> buf [buffer -> tail],
        !           337:                        &bufp [bytes_copied], copy_len);
        !           338:                buffer -> tail += copy_len;
        !           339:                c -> out_bytes += copy_len;
        !           340:                bytes_copied += copy_len;
        !           341:                if (buffer -> tail == sizeof buffer -> buf)
        !           342:                        buffer -> tail = 0;
        !           343:        }
        !           344:        return ISC_R_SUCCESS;
        !           345: }
        !           346: 
        !           347: /* Copy some bytes from the input buffer, and advance the input buffer
        !           348:    pointer beyond the bytes copied out. */
        !           349: 
        !           350: isc_result_t omapi_connection_copyout (unsigned char *buf,
        !           351:                                       omapi_object_t *h,
        !           352:                                       unsigned size)
        !           353: {
        !           354:        unsigned bytes_remaining;
        !           355:        unsigned bytes_this_copy;
        !           356:        unsigned first_byte;
        !           357:        omapi_buffer_t *buffer;
        !           358:        unsigned char *bufp;
        !           359:        int sig_flags = SIG_MODE_UPDATE;
        !           360:        omapi_connection_object_t *c;
        !           361:        isc_result_t status;
        !           362: 
        !           363:        if (!h || h -> type != omapi_type_connection)
        !           364:                return ISC_R_INVALIDARG;
        !           365:        c = (omapi_connection_object_t *)h;
        !           366: 
        !           367:        if (size > c -> in_bytes)
        !           368:                return ISC_R_NOMORE;
        !           369:        bufp = buf;
        !           370:        bytes_remaining = size;
        !           371:        buffer = c -> inbufs;
        !           372: 
        !           373:        while (bytes_remaining) {
        !           374:                if (!buffer)
        !           375:                        return ISC_R_UNEXPECTED;
        !           376:                if (BYTES_IN_BUFFER (buffer)) {
        !           377:                        if (buffer -> head == (sizeof buffer -> buf) - 1)
        !           378:                                first_byte = 0;
        !           379:                        else
        !           380:                                first_byte = buffer -> head + 1;
        !           381: 
        !           382:                        if (first_byte > buffer -> tail) {
        !           383:                                bytes_this_copy = (sizeof buffer -> buf -
        !           384:                                                   first_byte);
        !           385:                        } else {
        !           386:                                bytes_this_copy =
        !           387:                                        buffer -> tail - first_byte;
        !           388:                        }
        !           389:                        if (bytes_this_copy > bytes_remaining)
        !           390:                                bytes_this_copy = bytes_remaining;
        !           391:                        if (bufp) {
        !           392:                                if (c -> in_key) {
        !           393:                                        if (!c -> in_context)
        !           394:                                                sig_flags |= SIG_MODE_INIT;
        !           395:                                        status = omapi_connection_sign_data
        !           396:                                                (sig_flags,
        !           397:                                                 c -> in_key,
        !           398:                                                 &c -> in_context,
        !           399:                                                 (unsigned char *)
        !           400:                                                 &buffer -> buf [first_byte],
        !           401:                                                 bytes_this_copy,
        !           402:                                                 (omapi_typed_data_t **)0);
        !           403:                                        if (status != ISC_R_SUCCESS)
        !           404:                                                return status;
        !           405:                                }
        !           406: 
        !           407:                                memcpy (bufp, &buffer -> buf [first_byte],
        !           408:                                        bytes_this_copy);
        !           409:                                bufp += bytes_this_copy;
        !           410:                        }
        !           411:                        bytes_remaining -= bytes_this_copy;
        !           412:                        buffer -> head = first_byte + bytes_this_copy - 1;
        !           413:                        c -> in_bytes -= bytes_this_copy;
        !           414:                }
        !           415:                        
        !           416:                if (!BYTES_IN_BUFFER (buffer))
        !           417:                        buffer = buffer -> next;
        !           418:        }
        !           419: 
        !           420:        /* Get rid of any input buffers that we emptied. */
        !           421:        buffer = (omapi_buffer_t *)0;
        !           422:        while (c -> inbufs &&
        !           423:               !BYTES_IN_BUFFER (c -> inbufs)) {
        !           424:                if (c -> inbufs -> next) {
        !           425:                        omapi_buffer_reference (&buffer,
        !           426:                                                c -> inbufs -> next, MDL);
        !           427:                        omapi_buffer_dereference (&c -> inbufs -> next, MDL);
        !           428:                }
        !           429:                omapi_buffer_dereference (&c -> inbufs, MDL);
        !           430:                if (buffer) {
        !           431:                        omapi_buffer_reference
        !           432:                                (&c -> inbufs, buffer, MDL);
        !           433:                        omapi_buffer_dereference (&buffer, MDL);
        !           434:                }
        !           435:        }
        !           436:        return ISC_R_SUCCESS;
        !           437: }
        !           438: 
        !           439: isc_result_t omapi_connection_writer (omapi_object_t *h)
        !           440: {
        !           441:        unsigned bytes_this_write;
        !           442:        int bytes_written;
        !           443:        unsigned first_byte;
        !           444:        omapi_buffer_t *buffer;
        !           445:        omapi_connection_object_t *c;
        !           446: 
        !           447:        if (!h || h -> type != omapi_type_connection)
        !           448:                return ISC_R_INVALIDARG;
        !           449:        c = (omapi_connection_object_t *)h;
        !           450: 
        !           451:        /* Already flushed... */
        !           452:        if (!c -> out_bytes)
        !           453:                return ISC_R_SUCCESS;
        !           454: 
        !           455:        buffer = c -> outbufs;
        !           456: 
        !           457:        while (c -> out_bytes) {
        !           458:                if (!buffer)
        !           459:                        return ISC_R_UNEXPECTED;
        !           460:                if (BYTES_IN_BUFFER (buffer)) {
        !           461:                        if (buffer -> head == (sizeof buffer -> buf) - 1)
        !           462:                                first_byte = 0;
        !           463:                        else
        !           464:                                first_byte = buffer -> head + 1;
        !           465: 
        !           466:                        if (first_byte > buffer -> tail) {
        !           467:                                bytes_this_write = (sizeof buffer -> buf -
        !           468:                                                   first_byte);
        !           469:                        } else {
        !           470:                                bytes_this_write =
        !           471:                                        buffer -> tail - first_byte;
        !           472:                        }
        !           473:                        bytes_written = write (c -> socket,
        !           474:                                               &buffer -> buf [first_byte],
        !           475:                                               bytes_this_write);
        !           476:                        /* If the write failed with EWOULDBLOCK or we wrote
        !           477:                           zero bytes, a further write would block, so we have
        !           478:                           flushed as much as we can for now.   Other errors
        !           479:                           are really errors. */
        !           480:                        if (bytes_written < 0) {
        !           481:                                if (errno == EWOULDBLOCK || errno == EAGAIN)
        !           482:                                        return ISC_R_SUCCESS;
        !           483:                                else if (errno == EPIPE)
        !           484:                                        return ISC_R_NOCONN;
        !           485: #ifdef EDQUOT
        !           486:                                else if (errno == EFBIG || errno == EDQUOT)
        !           487: #else
        !           488:                                else if (errno == EFBIG)
        !           489: #endif
        !           490:                                        return ISC_R_NORESOURCES;
        !           491:                                else if (errno == ENOSPC)
        !           492:                                        return ISC_R_NOSPACE;
        !           493:                                else if (errno == EIO)
        !           494:                                        return ISC_R_IOERROR;
        !           495:                                else if (errno == EINVAL)
        !           496:                                        return ISC_R_INVALIDARG;
        !           497:                                else if (errno == ECONNRESET)
        !           498:                                        return ISC_R_SHUTTINGDOWN;
        !           499:                                else
        !           500:                                        return ISC_R_UNEXPECTED;
        !           501:                        }
        !           502:                        if (bytes_written == 0)
        !           503:                                return ISC_R_SUCCESS;
        !           504: 
        !           505: #if defined (TRACING)
        !           506:                        if (trace_record ()) {
        !           507:                                isc_result_t status;
        !           508:                                trace_iov_t iov [2];
        !           509:                                int32_t connect_index;
        !           510:                                
        !           511:                                connect_index = htonl (c -> index);
        !           512:                                
        !           513:                                iov [0].buf = (char *)&connect_index;
        !           514:                                iov [0].len = sizeof connect_index;
        !           515:                                iov [1].buf = &buffer -> buf [buffer -> tail];
        !           516:                                iov [1].len = bytes_written;
        !           517:                                
        !           518:                                status = (trace_write_packet_iov
        !           519:                                          (trace_connection_input, 2, iov,
        !           520:                                           MDL));
        !           521:                                if (status != ISC_R_SUCCESS) {
        !           522:                                        trace_stop ();
        !           523:                                        log_error ("trace %s output: %s",
        !           524:                                                   "connection",
        !           525:                                                   isc_result_totext (status));
        !           526:                                }
        !           527:                        }
        !           528: #endif
        !           529: 
        !           530:                        buffer -> head = first_byte + bytes_written - 1;
        !           531:                        c -> out_bytes -= bytes_written;
        !           532: 
        !           533:                        /* If we didn't finish out the write, we filled the
        !           534:                           O.S. output buffer and a further write would block,
        !           535:                           so stop trying to flush now. */
        !           536:                        if (bytes_written != bytes_this_write)
        !           537:                                return ISC_R_SUCCESS;
        !           538:                }
        !           539:                        
        !           540:                if (!BYTES_IN_BUFFER (buffer))
        !           541:                        buffer = buffer -> next;
        !           542:        }
        !           543:                
        !           544:        /* Get rid of any output buffers we emptied. */
        !           545:        buffer = (omapi_buffer_t *)0;
        !           546:        while (c -> outbufs &&
        !           547:               !BYTES_IN_BUFFER (c -> outbufs)) {
        !           548:                if (c -> outbufs -> next) {
        !           549:                        omapi_buffer_reference (&buffer,
        !           550:                                                c -> outbufs -> next, MDL);
        !           551:                        omapi_buffer_dereference (&c -> outbufs -> next, MDL);
        !           552:                }
        !           553:                omapi_buffer_dereference (&c -> outbufs, MDL);
        !           554:                if (buffer) {
        !           555:                        omapi_buffer_reference (&c -> outbufs, buffer, MDL);
        !           556:                        omapi_buffer_dereference (&buffer, MDL);
        !           557:                }
        !           558:        }
        !           559:        return ISC_R_SUCCESS;
        !           560: }
        !           561: 
        !           562: isc_result_t omapi_connection_get_uint32 (omapi_object_t *c,
        !           563:                                          u_int32_t *result)
        !           564: {
        !           565:        u_int32_t inbuf;
        !           566:        isc_result_t status;
        !           567: 
        !           568:        status = omapi_connection_copyout ((unsigned char *)&inbuf,
        !           569:                                           c, sizeof inbuf);
        !           570:        if (status != ISC_R_SUCCESS)
        !           571:                return status;
        !           572: 
        !           573:        *result = ntohl (inbuf);
        !           574:        return ISC_R_SUCCESS;
        !           575: }
        !           576: 
        !           577: isc_result_t omapi_connection_put_uint32 (omapi_object_t *c,
        !           578:                                          u_int32_t value)
        !           579: {
        !           580:        u_int32_t inbuf;
        !           581: 
        !           582:        inbuf = htonl (value);
        !           583:        
        !           584:        return omapi_connection_copyin (c, (unsigned char *)&inbuf,
        !           585:                                        sizeof inbuf);
        !           586: }
        !           587: 
        !           588: isc_result_t omapi_connection_get_uint16 (omapi_object_t *c,
        !           589:                                          u_int16_t *result)
        !           590: {
        !           591:        u_int16_t inbuf;
        !           592:        isc_result_t status;
        !           593: 
        !           594:        status = omapi_connection_copyout ((unsigned char *)&inbuf,
        !           595:                                           c, sizeof inbuf);
        !           596:        if (status != ISC_R_SUCCESS)
        !           597:                return status;
        !           598: 
        !           599:        *result = ntohs (inbuf);
        !           600:        return ISC_R_SUCCESS;
        !           601: }
        !           602: 
        !           603: isc_result_t omapi_connection_put_uint16 (omapi_object_t *c,
        !           604:                                          u_int32_t value)
        !           605: {
        !           606:        u_int16_t inbuf;
        !           607: 
        !           608:        inbuf = htons (value);
        !           609:        
        !           610:        return omapi_connection_copyin (c, (unsigned char *)&inbuf,
        !           611:                                        sizeof inbuf);
        !           612: }
        !           613: 
        !           614: isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
        !           615:                                                omapi_typed_data_t *data)
        !           616: {
        !           617:        isc_result_t status;
        !           618:        omapi_handle_t handle;
        !           619: 
        !           620:        /* Null data is valid. */
        !           621:        if (!data)
        !           622:                return omapi_connection_put_uint32 (c, 0);
        !           623: 
        !           624:        switch (data -> type) {
        !           625:              case omapi_datatype_int:
        !           626:                status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
        !           627:                if (status != ISC_R_SUCCESS)
        !           628:                        return status;
        !           629:                return omapi_connection_put_uint32 (c, ((u_int32_t)
        !           630:                                                        (data -> u.integer)));
        !           631: 
        !           632:              case omapi_datatype_string:
        !           633:              case omapi_datatype_data:
        !           634:                status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
        !           635:                if (status != ISC_R_SUCCESS)
        !           636:                        return status;
        !           637:                if (data -> u.buffer.len)
        !           638:                        return omapi_connection_copyin
        !           639:                                (c, data -> u.buffer.value,
        !           640:                                 data -> u.buffer.len);
        !           641:                return ISC_R_SUCCESS;
        !           642: 
        !           643:              case omapi_datatype_object:
        !           644:                if (data -> u.object) {
        !           645:                        status = omapi_object_handle (&handle,
        !           646:                                                      data -> u.object);
        !           647:                        if (status != ISC_R_SUCCESS)
        !           648:                                return status;
        !           649:                } else
        !           650:                        handle = 0;
        !           651:                status = omapi_connection_put_uint32 (c, sizeof handle);
        !           652:                if (status != ISC_R_SUCCESS)
        !           653:                        return status;
        !           654:                return omapi_connection_put_uint32 (c, handle);
        !           655: 
        !           656:        }
        !           657:        return ISC_R_INVALIDARG;
        !           658: }
        !           659: 
        !           660: isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name)
        !           661: {
        !           662:        isc_result_t status;
        !           663:        unsigned len = strlen (name);
        !           664: 
        !           665:        status = omapi_connection_put_uint16 (c, len);
        !           666:        if (status != ISC_R_SUCCESS)
        !           667:                return status;
        !           668:        return omapi_connection_copyin (c, (const unsigned char *)name, len);
        !           669: }
        !           670: 
        !           671: isc_result_t omapi_connection_put_string (omapi_object_t *c,
        !           672:                                          const char *string)
        !           673: {
        !           674:        isc_result_t status;
        !           675:        unsigned len;
        !           676: 
        !           677:        if (string)
        !           678:                len = strlen (string);
        !           679:        else
        !           680:                len = 0;
        !           681: 
        !           682:        status = omapi_connection_put_uint32 (c, len);
        !           683:        if (status != ISC_R_SUCCESS)
        !           684:                return status;
        !           685:        if (len)
        !           686:                return omapi_connection_copyin
        !           687:                        (c, (const unsigned char *)string, len);
        !           688:        return ISC_R_SUCCESS;
        !           689: }
        !           690: 
        !           691: isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
        !           692: {
        !           693:        isc_result_t status;
        !           694:        omapi_handle_t handle;
        !           695: 
        !           696:        if (h) {
        !           697:                status = omapi_object_handle (&handle, h);
        !           698:                if (status != ISC_R_SUCCESS)
        !           699:                        return status;
        !           700:        } else
        !           701:                handle = 0;     /* The null handle. */
        !           702:        status = omapi_connection_put_uint32 (c, sizeof handle);
        !           703:        if (status != ISC_R_SUCCESS)
        !           704:                return status;
        !           705:        return omapi_connection_put_uint32 (c, handle);
        !           706: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>