_new_extension( char *exec_name, int exec_flags, extend_registration_block *ereg )
{
    netsnmp_extend     *extension;
    netsnmp_table_row  *row;
    netsnmp_extend     *eptr1, *eptr2; 
    netsnmp_table_data *dinfo = ereg->dinfo;

    if (!exec_name)
        return NULL;
    extension = SNMP_MALLOC_TYPEDEF( netsnmp_extend );
    if (!extension)
        return NULL;
    extension->token    = strdup( exec_name );
    extension->flags    = exec_flags;
    extension->cache    = netsnmp_cache_create( 0, extend_load_cache,
                                                   extend_free_cache, NULL, 0 );
    if (extension->cache)
        extension->cache->magic = extension;

    row = netsnmp_create_table_data_row();
    if (!row || !extension->cache) {
        _free_extension( extension, ereg );
        SNMP_FREE( row );
        return NULL;
    }
    row->data = (void *)extension;
    extension->row = row;
    netsnmp_table_row_add_index( row, ASN_OCTET_STR,
                                 exec_name, strlen(exec_name));
    if ( netsnmp_table_data_add_row( dinfo, row) != SNMPERR_SUCCESS ) {
        /* _free_extension( extension, ereg ); */
        SNMP_FREE( extension );  /* Probably not sufficient */
        SNMP_FREE( row );
        return NULL;
    }

    ereg->num_entries++;
        /*
         *  Now add this structure to a private linked list.
         *  We don't need this for the main tables - the
         *   'table_data' helper will take care of those.
         *  But it's probably easier to handle the multi-line
         *  output table ourselves, for which we need access
         *  to the underlying data.
         *   So we'll keep a list internally as well.
         */
    for ( eptr1 = ereg->ehead, eptr2 = NULL;
          eptr1;
          eptr2 = eptr1, eptr1 = eptr1->next ) {

        if (strlen( eptr1->token )  > strlen( exec_name ))
            break;
        if (strlen( eptr1->token ) == strlen( exec_name ) &&
            strcmp( eptr1->token, exec_name ) > 0 )
            break;
    }
    if ( eptr2 )
        eptr2->next = extension;
    else
        ereg->ehead = extension;
    extension->next = eptr1;
    return extension;
}
_new_extension( char *exec_name, int exec_flags, extend_registration_block *ereg )
{
    netsnmp_extend     *extension;
    netsnmp_table_row  *row;
    netsnmp_extend     *eptr1, *eptr2; 
    netsnmp_table_data *dinfo = ereg->dinfo;

    if (!exec_name)
        return NULL;
    extension = SNMP_MALLOC_TYPEDEF( netsnmp_extend );
    if (!extension)
        return NULL;
    extension->token    = strdup( exec_name );
    extension->flags    = exec_flags;
    extension->cache    = netsnmp_cache_create( 0, extend_load_cache,
                                                   extend_free_cache, NULL, 0 );
    if (extension->cache)
        extension->cache->magic = extension;

    row = netsnmp_create_table_data_row();
    if (!row || !extension->cache) {
        _free_extension( extension, ereg );
        SNMP_FREE( row );
        return NULL;
    }
    row->data = (void *)extension;
    extension->row = row;
    netsnmp_table_row_add_index( row, ASN_OCTET_STR,
                                 exec_name, strlen(exec_name));
    if ( netsnmp_table_data_add_row( dinfo, row) != SNMPERR_SUCCESS ) {
         
        SNMP_FREE( extension );   
        SNMP_FREE( row );
        return NULL;
    }

    ereg->num_entries++;
         
    for ( eptr1 = ereg->ehead, eptr2 = NULL;
          eptr1;
          eptr2 = eptr1, eptr1 = eptr1->next ) {

        if (strlen( eptr1->token )  > strlen( exec_name ))
            break;
        if (strlen( eptr1->token ) == strlen( exec_name ) &&
            strcmp( eptr1->token, exec_name ) > 0 )
            break;
    }
    if ( eptr2 )
        eptr2->next = extension;
    else
        ereg->ehead = extension;
    extension->next = eptr1;
    return extension;
}