Annotation of embedaddon/dhcp/omapip/buffer.c, revision 1.1.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>