/**
 * add new entry
 */
static void
_add_connection(netsnmp_tcpconn_entry *entry, netsnmp_container *container)
{
    tcpListenerTable_rowreq_ctx *rowreq_ctx;

    DEBUGMSGTL(("tcpListenerTable:access", "creating new entry\n"));

    /*
     * allocate an row context and set the index(es), then add it to
     * the container
     */
    rowreq_ctx = tcpListenerTable_allocate_rowreq_ctx(entry, NULL);
    if ((NULL != rowreq_ctx) &&
        (MFD_SUCCESS == tcpListenerTable_indexes_set(rowreq_ctx,
                                                     entry->loc_addr_len,
                                                     (char*)entry->loc_addr,
                                                     entry->loc_addr_len,
                                                     entry->loc_port))) {
        CONTAINER_INSERT(container, rowreq_ctx);
    } else {
        if (rowreq_ctx) {
            snmp_log(LOG_ERR, "error setting index while loading "
                     "tcpListenerTable cache.\n");
            tcpListenerTable_release_rowreq_ctx(rowreq_ctx);
        } else {
            snmp_log(LOG_ERR, "memory allocation failed while loading "
                     "tcpListenerTable cache.\n");
            netsnmp_access_tcpconn_entry_free(entry);
        }
    }
}
/**
 * @internal
 */
static void
_container_item_free(tcpListenerTable_rowreq_ctx * rowreq_ctx,
                     void *context)
{
    DEBUGMSGTL(("internal:tcpListenerTable:_container_item_free",
                "called\n"));

    if (NULL == rowreq_ctx)
        return;

    tcpListenerTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */
/*
 *********************************************************************
 * @internal
 * allocate resources for a tcpListenerTable_rowreq_ctx
 */
tcpListenerTable_rowreq_ctx *
tcpListenerTable_allocate_rowreq_ctx(tcpListenerTable_data * data,
                                     void *user_init_ctx)
{
    tcpListenerTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(tcpListenerTable_rowreq_ctx);

    DEBUGMSGTL(("internal:tcpListenerTable:tcpListenerTable_allocate_rowreq_ctx", "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "tcpListenerTable_rowreq_ctx.\n");
        return NULL;
    } else {
        if (NULL != data) {
            /*
             * track if we got data from user
             */
            rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
            rowreq_ctx->data = data;
        } else if (NULL ==
                   (rowreq_ctx->data = tcpListenerTable_allocate_data())) {
            SNMP_FREE(rowreq_ctx);
            return NULL;
        }
    }

    /*
     * undo context will be allocated when needed (in *_undo_setup)
     */

    rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;

    rowreq_ctx->tcpListenerTable_data_list = NULL;

    /*
     * if we allocated data, call init routine
     */
    if (!(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) {
        if (SNMPERR_SUCCESS !=
            tcpListenerTable_rowreq_ctx_init(rowreq_ctx, user_init_ctx)) {
            tcpListenerTable_release_rowreq_ctx(rowreq_ctx);
            rowreq_ctx = NULL;
        }
    }

    return rowreq_ctx;
}                               /* tcpListenerTable_allocate_rowreq_ctx */
/**
 * @internal
 * wrapper
 */
static int
_mfd_tcpListenerTable_post_request(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    tcpListenerTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    int             rc, packet_rc;

    DEBUGMSGTL(("internal:tcpListenerTable:_mfd_tcpListenerTable_post_request", "called\n"));

    /*
     * release row context, if deleted
     */
    if (rowreq_ctx && (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED))
        tcpListenerTable_release_rowreq_ctx(rowreq_ctx);

    /*
     * wait for last call before calling user
     */
    if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:tcpListenerTable",
                    "waiting for last post_request\n"));
        return SNMP_ERR_NOERROR;
    }

    packet_rc = netsnmp_check_all_requests_error(agtreq_info->asp, 0);
    rc = tcpListenerTable_post_request(tcpListenerTable_if_ctx.user_ctx,
                                       packet_rc);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("tcpListenerTable", "error %d from "
                    "tcpListenerTable_post_request\n", rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpListenerTable_post_request */