Annotation of embedaddon/dhcp/omapip/buffer.c, revision 1.1.1.1.2.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 (!h || h -> type != omapi_type_connection)
                    285:                return ISC_R_INVALIDARG;
                    286:        c = (omapi_connection_object_t *)h;
                    287: 
                    288:        /* If the connection is closed, return an error if the caller
                    289:           tries to copy in. */
                    290:        if (c -> state == omapi_connection_disconnecting ||
                    291:            c -> state == omapi_connection_closed)
                    292:                return ISC_R_NOTCONNECTED;
                    293: 
                    294:        if (c -> outbufs) {
                    295:                for (buffer = c -> outbufs;
                    296:                     buffer -> next; buffer = buffer -> next)
                    297:                        ;
                    298:        } else {
                    299:                status = omapi_buffer_new (&c -> outbufs, MDL);
                    300:                if (status != ISC_R_SUCCESS)
                    301:                        return status;
                    302:                buffer = c -> outbufs;
                    303:        }
                    304: 
                    305:        while (bytes_copied < len) {
                    306:                /* If there is no space available in this buffer,
                    307:                    allocate a new one. */
                    308:                if (!BUFFER_BYTES_FREE (buffer)) {
                    309:                        status = (omapi_buffer_new (&buffer -> next, MDL));
                    310:                        if (status != ISC_R_SUCCESS)
                    311:                                return status;
                    312:                        buffer = buffer -> next;
                    313:                }
                    314: 
                    315:                if (buffer -> tail > buffer -> head)
                    316:                        copy_len = sizeof (buffer -> buf) - buffer -> tail;
                    317:                else
                    318:                        copy_len = buffer -> head - buffer -> tail;
                    319: 
                    320:                if (copy_len > (len - bytes_copied))
                    321:                        copy_len = len - bytes_copied;
                    322: 
                    323:                if (c -> out_key) {
                    324:                        if (!c -> out_context)
                    325:                                sig_flags |= SIG_MODE_INIT;
                    326:                        status = omapi_connection_sign_data
                    327:                                (sig_flags, c -> out_key, &c -> out_context,
                    328:                                 &bufp [bytes_copied], copy_len,
                    329:                                 (omapi_typed_data_t **)0);
                    330:                        if (status != ISC_R_SUCCESS)
                    331:                                return status;
                    332:                }
                    333: 
                    334:                memcpy (&buffer -> buf [buffer -> tail],
                    335:                        &bufp [bytes_copied], copy_len);
                    336:                buffer -> tail += copy_len;
                    337:                c -> out_bytes += copy_len;
                    338:                bytes_copied += copy_len;
                    339:                if (buffer -> tail == sizeof buffer -> buf)
                    340:                        buffer -> tail = 0;
                    341:        }
                    342:        return ISC_R_SUCCESS;
                    343: }
                    344: 
                    345: /* Copy some bytes from the input buffer, and advance the input buffer
                    346:    pointer beyond the bytes copied out. */
                    347: 
                    348: isc_result_t omapi_connection_copyout (unsigned char *buf,
                    349:                                       omapi_object_t *h,
                    350:                                       unsigned size)
                    351: {
                    352:        unsigned bytes_remaining;
                    353:        unsigned bytes_this_copy;
                    354:        unsigned first_byte;
                    355:        omapi_buffer_t *buffer;
                    356:        unsigned char *bufp;
                    357:        int sig_flags = SIG_MODE_UPDATE;
                    358:        omapi_connection_object_t *c;
                    359:        isc_result_t status;
                    360: 
                    361:        if (!h || h -> type != omapi_type_connection)
                    362:                return ISC_R_INVALIDARG;
                    363:        c = (omapi_connection_object_t *)h;
                    364: 
                    365:        if (size > c -> in_bytes)
                    366:                return ISC_R_NOMORE;
                    367:        bufp = buf;
                    368:        bytes_remaining = size;
                    369:        buffer = c -> inbufs;
                    370: 
                    371:        while (bytes_remaining) {
                    372:                if (!buffer)
                    373:                        return ISC_R_UNEXPECTED;
                    374:                if (BYTES_IN_BUFFER (buffer)) {
                    375:                        if (buffer -> head == (sizeof buffer -> buf) - 1)
                    376:                                first_byte = 0;
                    377:                        else
                    378:                                first_byte = buffer -> head + 1;
                    379: 
                    380:                        if (first_byte > buffer -> tail) {
                    381:                                bytes_this_copy = (sizeof buffer -> buf -
                    382:                                                   first_byte);
                    383:                        } else {
                    384:                                bytes_this_copy =
                    385:                                        buffer -> tail - first_byte;
                    386:                        }
                    387:                        if (bytes_this_copy > bytes_remaining)
                    388:                                bytes_this_copy = bytes_remaining;
                    389:                        if (bufp) {
                    390:                                if (c -> in_key) {
                    391:                                        if (!c -> in_context)
                    392:                                                sig_flags |= SIG_MODE_INIT;
                    393:                                        status = omapi_connection_sign_data
                    394:                                                (sig_flags,
                    395:                                                 c -> in_key,
                    396:                                                 &c -> in_context,
                    397:                                                 (unsigned char *)
                    398:                                                 &buffer -> buf [first_byte],
                    399:                                                 bytes_this_copy,
                    400:                                                 (omapi_typed_data_t **)0);
                    401:                                        if (status != ISC_R_SUCCESS)
                    402:                                                return status;
                    403:                                }
                    404: 
                    405:                                memcpy (bufp, &buffer -> buf [first_byte],
                    406:                                        bytes_this_copy);
                    407:                                bufp += bytes_this_copy;
                    408:                        }
                    409:                        bytes_remaining -= bytes_this_copy;
                    410:                        buffer -> head = first_byte + bytes_this_copy - 1;
                    411:                        c -> in_bytes -= bytes_this_copy;
                    412:                }
                    413:                        
                    414:                if (!BYTES_IN_BUFFER (buffer))
                    415:                        buffer = buffer -> next;
                    416:        }
                    417: 
                    418:        /* Get rid of any input buffers that we emptied. */
                    419:        buffer = (omapi_buffer_t *)0;
                    420:        while (c -> inbufs &&
                    421:               !BYTES_IN_BUFFER (c -> inbufs)) {
                    422:                if (c -> inbufs -> next) {
                    423:                        omapi_buffer_reference (&buffer,
                    424:                                                c -> inbufs -> next, MDL);
                    425:                        omapi_buffer_dereference (&c -> inbufs -> next, MDL);
                    426:                }
                    427:                omapi_buffer_dereference (&c -> inbufs, MDL);
                    428:                if (buffer) {
                    429:                        omapi_buffer_reference
                    430:                                (&c -> inbufs, buffer, MDL);
                    431:                        omapi_buffer_dereference (&buffer, MDL);
                    432:                }
                    433:        }
                    434:        return ISC_R_SUCCESS;
                    435: }
                    436: 
                    437: isc_result_t omapi_connection_writer (omapi_object_t *h)
                    438: {
                    439:        unsigned bytes_this_write;
                    440:        int bytes_written;
                    441:        unsigned first_byte;
                    442:        omapi_buffer_t *buffer;
                    443:        omapi_connection_object_t *c;
                    444: 
                    445:        if (!h || h -> type != omapi_type_connection)
                    446:                return ISC_R_INVALIDARG;
                    447:        c = (omapi_connection_object_t *)h;
                    448: 
                    449:        /* Already flushed... */
                    450:        if (!c -> out_bytes)
                    451:                return ISC_R_SUCCESS;
                    452: 
                    453:        buffer = c -> outbufs;
                    454: 
                    455:        while (c -> out_bytes) {
                    456:                if (!buffer)
                    457:                        return ISC_R_UNEXPECTED;
                    458:                if (BYTES_IN_BUFFER (buffer)) {
                    459:                        if (buffer -> head == (sizeof buffer -> buf) - 1)
                    460:                                first_byte = 0;
                    461:                        else
                    462:                                first_byte = buffer -> head + 1;
                    463: 
                    464:                        if (first_byte > buffer -> tail) {
                    465:                                bytes_this_write = (sizeof buffer -> buf -
                    466:                                                   first_byte);
                    467:                        } else {
                    468:                                bytes_this_write =
                    469:                                        buffer -> tail - first_byte;
                    470:                        }
                    471:                        bytes_written = write (c -> socket,
                    472:                                               &buffer -> buf [first_byte],
                    473:                                               bytes_this_write);
                    474:                        /* If the write failed with EWOULDBLOCK or we wrote
                    475:                           zero bytes, a further write would block, so we have
                    476:                           flushed as much as we can for now.   Other errors
                    477:                           are really errors. */
                    478:                        if (bytes_written < 0) {
                    479:                                if (errno == EWOULDBLOCK || errno == EAGAIN)
                    480:                                        return ISC_R_SUCCESS;
                    481:                                else if (errno == EPIPE)
                    482:                                        return ISC_R_NOCONN;
                    483: #ifdef EDQUOT
                    484:                                else if (errno == EFBIG || errno == EDQUOT)
                    485: #else
                    486:                                else if (errno == EFBIG)
                    487: #endif
                    488:                                        return ISC_R_NORESOURCES;
                    489:                                else if (errno == ENOSPC)
                    490:                                        return ISC_R_NOSPACE;
                    491:                                else if (errno == EIO)
                    492:                                        return ISC_R_IOERROR;
                    493:                                else if (errno == EINVAL)
                    494:                                        return ISC_R_INVALIDARG;
                    495:                                else if (errno == ECONNRESET)
                    496:                                        return ISC_R_SHUTTINGDOWN;
                    497:                                else
                    498:                                        return ISC_R_UNEXPECTED;
                    499:                        }
                    500:                        if (bytes_written == 0)
                    501:                                return ISC_R_SUCCESS;
                    502: 
                    503: #if defined (TRACING)
                    504:                        if (trace_record ()) {
                    505:                                isc_result_t status;
                    506:                                trace_iov_t iov [2];
                    507:                                int32_t connect_index;
                    508:                                
                    509:                                connect_index = htonl (c -> index);
                    510:                                
                    511:                                iov [0].buf = (char *)&connect_index;
                    512:                                iov [0].len = sizeof connect_index;
                    513:                                iov [1].buf = &buffer -> buf [buffer -> tail];
                    514:                                iov [1].len = bytes_written;
                    515:                                
                    516:                                status = (trace_write_packet_iov
                    517:                                          (trace_connection_input, 2, iov,
                    518:                                           MDL));
                    519:                                if (status != ISC_R_SUCCESS) {
                    520:                                        trace_stop ();
                    521:                                        log_error ("trace %s output: %s",
                    522:                                                   "connection",
                    523:                                                   isc_result_totext (status));
                    524:                                }
                    525:                        }
                    526: #endif
                    527: 
                    528:                        buffer -> head = first_byte + bytes_written - 1;
                    529:                        c -> out_bytes -= bytes_written;
                    530: 
                    531:                        /* If we didn't finish out the write, we filled the
                    532:                           O.S. output buffer and a further write would block,
                    533:                           so stop trying to flush now. */
                    534:                        if (bytes_written != bytes_this_write)
                    535:                                return ISC_R_SUCCESS;
                    536:                }
                    537:                        
                    538:                if (!BYTES_IN_BUFFER (buffer))
                    539:                        buffer = buffer -> next;
                    540:        }
                    541:                
                    542:        /* Get rid of any output buffers we emptied. */
                    543:        buffer = (omapi_buffer_t *)0;
                    544:        while (c -> outbufs &&
                    545:               !BYTES_IN_BUFFER (c -> outbufs)) {
                    546:                if (c -> outbufs -> next) {
                    547:                        omapi_buffer_reference (&buffer,
                    548:                                                c -> outbufs -> next, MDL);
                    549:                        omapi_buffer_dereference (&c -> outbufs -> next, MDL);
                    550:                }
                    551:                omapi_buffer_dereference (&c -> outbufs, MDL);
                    552:                if (buffer) {
                    553:                        omapi_buffer_reference (&c -> outbufs, buffer, MDL);
                    554:                        omapi_buffer_dereference (&buffer, MDL);
                    555:                }
                    556:        }
                    557:        return ISC_R_SUCCESS;
                    558: }
                    559: 
                    560: isc_result_t omapi_connection_get_uint32 (omapi_object_t *c,
                    561:                                          u_int32_t *result)
                    562: {
                    563:        u_int32_t inbuf;
                    564:        isc_result_t status;
                    565: 
                    566:        status = omapi_connection_copyout ((unsigned char *)&inbuf,
                    567:                                           c, sizeof inbuf);
                    568:        if (status != ISC_R_SUCCESS)
                    569:                return status;
                    570: 
                    571:        *result = ntohl (inbuf);
                    572:        return ISC_R_SUCCESS;
                    573: }
                    574: 
                    575: isc_result_t omapi_connection_put_uint32 (omapi_object_t *c,
                    576:                                          u_int32_t value)
                    577: {
                    578:        u_int32_t inbuf;
                    579: 
                    580:        inbuf = htonl (value);
                    581:        
                    582:        return omapi_connection_copyin (c, (unsigned char *)&inbuf,
                    583:                                        sizeof inbuf);
                    584: }
                    585: 
                    586: isc_result_t omapi_connection_get_uint16 (omapi_object_t *c,
                    587:                                          u_int16_t *result)
                    588: {
                    589:        u_int16_t inbuf;
                    590:        isc_result_t status;
                    591: 
                    592:        status = omapi_connection_copyout ((unsigned char *)&inbuf,
                    593:                                           c, sizeof inbuf);
                    594:        if (status != ISC_R_SUCCESS)
                    595:                return status;
                    596: 
                    597:        *result = ntohs (inbuf);
                    598:        return ISC_R_SUCCESS;
                    599: }
                    600: 
                    601: isc_result_t omapi_connection_put_uint16 (omapi_object_t *c,
                    602:                                          u_int32_t value)
                    603: {
                    604:        u_int16_t inbuf;
                    605: 
                    606:        inbuf = htons (value);
                    607:        
                    608:        return omapi_connection_copyin (c, (unsigned char *)&inbuf,
                    609:                                        sizeof inbuf);
                    610: }
                    611: 
                    612: isc_result_t omapi_connection_write_typed_data (omapi_object_t *c,
                    613:                                                omapi_typed_data_t *data)
                    614: {
                    615:        isc_result_t status;
                    616:        omapi_handle_t handle;
                    617: 
                    618:        /* Null data is valid. */
                    619:        if (!data)
                    620:                return omapi_connection_put_uint32 (c, 0);
                    621: 
                    622:        switch (data -> type) {
                    623:              case omapi_datatype_int:
                    624:                status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
                    625:                if (status != ISC_R_SUCCESS)
                    626:                        return status;
                    627:                return omapi_connection_put_uint32 (c, ((u_int32_t)
                    628:                                                        (data -> u.integer)));
                    629: 
                    630:              case omapi_datatype_string:
                    631:              case omapi_datatype_data:
                    632:                status = omapi_connection_put_uint32 (c, data -> u.buffer.len);
                    633:                if (status != ISC_R_SUCCESS)
                    634:                        return status;
                    635:                if (data -> u.buffer.len)
                    636:                        return omapi_connection_copyin
                    637:                                (c, data -> u.buffer.value,
                    638:                                 data -> u.buffer.len);
                    639:                return ISC_R_SUCCESS;
                    640: 
                    641:              case omapi_datatype_object:
                    642:                if (data -> u.object) {
                    643:                        status = omapi_object_handle (&handle,
                    644:                                                      data -> u.object);
                    645:                        if (status != ISC_R_SUCCESS)
                    646:                                return status;
                    647:                } else
                    648:                        handle = 0;
                    649:                status = omapi_connection_put_uint32 (c, sizeof handle);
                    650:                if (status != ISC_R_SUCCESS)
                    651:                        return status;
                    652:                return omapi_connection_put_uint32 (c, handle);
                    653: 
                    654:        }
                    655:        return ISC_R_INVALIDARG;
                    656: }
                    657: 
                    658: isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name)
                    659: {
                    660:        isc_result_t status;
                    661:        unsigned len = strlen (name);
                    662: 
                    663:        status = omapi_connection_put_uint16 (c, len);
                    664:        if (status != ISC_R_SUCCESS)
                    665:                return status;
                    666:        return omapi_connection_copyin (c, (const unsigned char *)name, len);
                    667: }
                    668: 
                    669: isc_result_t omapi_connection_put_string (omapi_object_t *c,
                    670:                                          const char *string)
                    671: {
                    672:        isc_result_t status;
                    673:        unsigned len;
                    674: 
                    675:        if (string)
                    676:                len = strlen (string);
                    677:        else
                    678:                len = 0;
                    679: 
                    680:        status = omapi_connection_put_uint32 (c, len);
                    681:        if (status != ISC_R_SUCCESS)
                    682:                return status;
                    683:        if (len)
                    684:                return omapi_connection_copyin
                    685:                        (c, (const unsigned char *)string, len);
                    686:        return ISC_R_SUCCESS;
                    687: }
                    688: 
                    689: isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h)
                    690: {
                    691:        isc_result_t status;
                    692:        omapi_handle_t handle;
                    693: 
                    694:        if (h) {
                    695:                status = omapi_object_handle (&handle, h);
                    696:                if (status != ISC_R_SUCCESS)
                    697:                        return status;
                    698:        } else
                    699:                handle = 0;     /* The null handle. */
                    700:        status = omapi_connection_put_uint32 (c, sizeof handle);
                    701:        if (status != ISC_R_SUCCESS)
                    702:                return status;
                    703:        return omapi_connection_put_uint32 (c, handle);
                    704: }

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