Commit message: don't mix up int and size_t (first pass to fix that)
CVE: CVE-2020-12135
CWE: CWE-190
Vulnerability description: bson before 0.8 incorrectly uses int rather than size_t for many variables, parameters, and return values. In particular, the bson_ensure_space() parameter bytesNeeded could have an integer overflow via properly constructed bson input.

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_get_socket(mongo* conn) {
    mongo* conn_ = (mongo*)conn;
    return conn_->sock;
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_check_last_error( mongo *conn, const char *ns,
                                   mongo_write_concern *write_concern ) {
    int ret = MONGO_OK;
    bson response = {NULL, 0};
    bson fields;
    bson_iterator it;
    int res = 0;
    char *cmd_ns = mongo_ns_to_cmd_db( ns );

    res = mongo_find_one( conn, cmd_ns, write_concern->cmd, bson_empty( &fields ), &response );
    bson_free( cmd_ns );

    if( res != MONGO_OK )
        ret = MONGO_ERROR;
    else {
        if( ( bson_find( &it, &response, "$err" ) == BSON_STRING ) ||
                ( bson_find( &it, &response, "err" ) == BSON_STRING ) ) {

            __mongo_set_error( conn, MONGO_WRITE_ERROR,
                               "See conn->lasterrstr for details.", 0 );
            mongo_set_last_error( conn, &it, &response );
            ret = MONGO_ERROR;
        }
        bson_destroy( &response );
    }
    return ret;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_clear_errors( mongo *conn ) {
    conn->err = 0;
    conn->errcode = 0;
    conn->lasterrcode = 0;
    memset( conn->errstr, 0, MONGO_ERR_LEN );
    memset( conn->lasterrstr, 0, MONGO_ERR_LEN );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str ) {
    int i;
    for ( i=0; i<12; i++ ) {
        oid->bytes[i] = ( hexbyte( str[2*i] ) << 4 ) | hexbyte( str[2*i + 1] );
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i ) {
    if ( bson_append_estart( b, BSON_INT, name, 4 ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append32( b , &i );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_get_host_count(mongo* conn) {
    mongo_replica_set* r = conn->replica_set;
    mongo_host_port* hp;
    int count = 0;
    if (!r) return 0;
    for (hp = r->hosts; hp; hp = hp->next)
        ++count;
    return count;
}

Project: mongo-c-driver-legacy
File: bcon.c

static void bcon_json_print(bcon *bc, int n) {
    int t = 0;
    int key_value_count = 0;
    char *s;
    int end_of_data;
    bcon *bcp;
    putchar('{');
    for (end_of_data = 0, bcp = bc; !end_of_data; bcp++) {
        bcon bci = *bcp;
        switch (t) {
        case 'l':
            if (key_value_count & 0x1) putchar(':');
            printf("%ld", bci.l);
            t = 0;
            key_value_count++;
            break;
        case 's': /* fall through */
        default:
            s = bci.s;
            switch (*s) {
            case ':':
                ++s;
                t = *++s;
                break;
            case '{':
                if (key_value_count & 0x1) putchar(':');
                putchar(*s);
                key_value_count = 0;
                break;
            case '}':
                putchar(*s);
                key_value_count = 2;
                break;
            default:
                if (key_value_count & 0x1) putchar(':');
                else if (key_value_count > 1) putchar(',');
                printf("\"%s\"", s);
                t = 0;
                key_value_count++;
                break;
            }
            break;
        }
    }
    putchar('}');
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
    char *cbuf = buf;
    while ( len ) {
        size_t sent = recv( conn->sock, cbuf, len, 0 );
        if ( sent == 0 || sent == -1 ) {
            conn->err = MONGO_IO_ERROR;
            return MONGO_ERROR;
        }
        cbuf += sent;
        len -= sent;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT const char *gridfile_get_contenttype( gridfile *gfile ) {
    bson_iterator it;

    if ( bson_find( &it, gfile->meta, "contentType" ) )
        return bson_iterator_string( &it );
    else return NULL;
}

Project: mongo-c-driver-legacy
File: mongo.c

static const char* _get_host_port(mongo_host_port* hp) {
    static char _hp[sizeof(hp->host)+12];
    bson_sprintf(_hp, "%s:%d", hp->host, hp->port);
    return _hp;
}

Project: mongo-c-driver-legacy
File: bcon.c

static bcon_error_t bson_append_bcon_with_state(bson *b, const bcon *bc, bcon_state_t start_state) {
    bcon_error_t ret = BCON_OK;
    bcon_state_t state = start_state;
    char *key = 0;
    char *typespec = 0;
    unsigned char doc_stack[DOC_STACK_SIZE];
    size_t doc_stack_pointer = 0;
    size_t array_index = 0;
    size_t array_index_stack[ARRAY_INDEX_STACK_SIZE];
    size_t array_index_stack_pointer = 0;
    char array_index_buffer[ARRAY_INDEX_BUFFER_SIZE]; /* max BSON size */
    int end_of_data;
    const bcon *bcp;
    for (end_of_data = 0, bcp = bc; ret == BCON_OK && !end_of_data; bcp++) {
        bcon bci = *bcp;
        char *s = bci.s;
        switch (state) {
        case State_Element:
            switch (bcon_token(s)) {
            case Token_CloseBrace:
                bson_append_finish_object( b );
                DOC_POP_STATE; /* state = ...; */
                break;
            case Token_End:
                end_of_data = 1;
                break;
            default:
                key = s;
                state = State_DocSpecValue;
                break;
            }
            break;
        case State_DocSpecValue:
            switch (bcon_token(s)) {
            case Token_Typespec:
                typespec = s;
                state = State_DocValue;
                break;
            case Token_OpenBrace:
                bson_append_start_object( b, key );
                DOC_PUSH_STATE(State_Element);
                state = State_Element;
                break;
            case Token_OpenBracket:
                bson_append_start_array( b, key );
                ARRAY_PUSH_RESET_INDEX_STATE(State_Element);
                state = State_ArraySpecValue;
                break;
            case Token_End:
                end_of_data = 1;
                break;
            default:
                ret = bson_bcon_key_value(b, key, typespec, bci);
                state = State_Element;
                break;
            }
            break;
        case State_DocValue:
            ret = bson_bcon_key_value(b, key, typespec, bci);
            state = State_Element;
            typespec = 0;
            break;
        case State_ArraySpecValue:
            switch (bcon_token(s)) {
            case Token_Typespec:
                typespec = s;
                state = State_ArrayValue;
                break;
            case Token_OpenBrace:
                key = ARRAY_KEY_STRING(array_index++);
                bson_append_start_object( b, key );
                DOC_PUSH_STATE(State_ArraySpecValue);
                state = State_Element;
                break;
            case Token_OpenBracket:
                key = ARRAY_KEY_STRING(array_index++);
                bson_append_start_array( b, key );
                ARRAY_PUSH_RESET_INDEX_STATE(State_ArraySpecValue);
                /* state = State_ArraySpecValue; */
                break;
            case Token_CloseBracket:
                bson_append_finish_array( b );
                ARRAY_POP_INDEX_STATE; /* state = ...; */
                break;
            case Token_End:
                end_of_data = 1;
                break;
            default:
                key = ARRAY_KEY_STRING(array_index++);
                ret = bson_bcon_key_value(b, key, typespec, bci);
                /* state = State_ArraySpecValue; */
                break;
            }
            break;
        case State_ArrayValue:
            key = ARRAY_KEY_STRING(array_index++);
            ret = bson_bcon_key_value(b, key, typespec, bci);
            state = State_ArraySpecValue;
            typespec = 0;
            break;
        default: assert(NOT_REACHED); break;
        }
    }
    return state == start_state ? BCON_OK : BCON_DOCUMENT_INCOMPLETE;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_remove( mongo *conn, const char *ns, const bson *cond,
                               mongo_write_concern *custom_write_concern ) {

    char *data;
    mongo_message *mm;
    mongo_write_concern *write_concern = NULL;

    /* Make sure that the BSON is valid UTF-8.
     * TODO: decide whether to check cond as well.
     * */
    if( mongo_bson_valid( conn, ( bson * )cond, 0 ) != MONGO_OK ) {
        return MONGO_ERROR;
    }

    if( mongo_choose_write_concern( conn, custom_write_concern,
                                    &write_concern ) == MONGO_ERROR ) {
        return MONGO_ERROR;
    }

    mm = mongo_message_create( 16  /* header */
                               + 4  /* ZERO */
                               + strlen( ns ) + 1
                               + 4  /* ZERO */
                               + bson_size( cond )
                               , 0 , 0 , MONGO_OP_DELETE );

    data = &mm->data;
    data = mongo_data_append32( data, &ZERO );
    data = mongo_data_append( data, ns, strlen( ns ) + 1 );
    data = mongo_data_append32( data, &ZERO );
    mongo_data_append( data, cond->data, bson_size( cond ) );

    /* TODO: refactor so that we can send the insert message
     * and the getlasterror messages together. */
    if( write_concern ) {
        if( mongo_message_send( conn, mm ) == MONGO_ERROR ) {
            return MONGO_ERROR;
        }

        return mongo_check_last_error( conn, ns, write_concern );
    }
    else {
        return mongo_message_send( conn, mm );
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ) {
    bson_timestamp_t ts;
    bson_little_endian32( &( ts.i ), bson_iterator_value( i ) );
    bson_little_endian32( &( ts.t ), bson_iterator_value( i ) + 4 );
    return ts;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT double bson_int64_to_double( int64_t i64 ) {
    return (double)i64;
}

Project: mongo-c-driver-legacy
File: bson.c

int _bson_errprintf( const char *format, ... ) {
    va_list ap;
    int ret = 0;
    va_start( ap, format );
#ifndef R_SAFETY_NET
    ret = vfprintf( stderr, format, ap );
#endif
    va_end( ap );

    return ret;
}

Project: mongo-c-driver-legacy
File: bson.c

static int bson_append_string_base( bson *b, const char *name,
                                    const char *value, size_t len, bson_type type ) {

    size_t sl = len + 1;
    if ( bson_check_string( b, ( const char * )value, sl - 1 ) == BSON_ERROR )
        return BSON_ERROR;
    if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) {
        return BSON_ERROR;
    }
    bson_append32_as_int( b , ( int )sl );
    bson_append( b , value , sl - 1 );
    bson_append( b , "\0" , 1 );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ) {
    memset( cursor, 0, sizeof( mongo_cursor ) );
    cursor->conn = conn;
    cursor->ns = ( const char * )bson_malloc( strlen( ns ) + 1 );
    strncpy( ( char * )cursor->ns, ns, strlen( ns ) + 1 );
    cursor->current.data = NULL;
}

Project: mongo-c-driver-legacy
File: bson.c

int bson_init_data( bson *b, char *data ) {
    b->data = data;
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_data( const bson *b ) {
    return (const char *)b->data;
}

Project: mongo-c-driver-legacy
File: bson.c

double bson_iterator_double_raw( const bson_iterator *i ) {
    double out;
    bson_little_endian64( &out, bson_iterator_value( i ) );
    return out;
}

Project: mongo-c-driver-legacy
File: bson.c

bson_bool_t bson_iterator_bool_raw( const bson_iterator *i ) {
    return bson_iterator_value( i )[0];
}

Project: mongo-c-driver-legacy
File: bson.c

void bson_fatal_msg( int ok , const char *msg ) {
    if ( ok )
        return;

    if ( err_handler ) {
        err_handler( msg );
    }
#ifndef R_SAFETY_NET
    bson_errprintf( "error: %s\n" , msg );
    exit( -5 );
#endif
}

Project: mongo-c-driver-legacy
File: gridfs.c

int gridfs_store_file( gridfs *gfs, const char *filename,
                       const char *remotename, const char *contenttype ) {

    char buffer[DEFAULT_CHUNK_SIZE];
    FILE *fd;
    bson_oid_t id;
    int chunkNumber = 0;
    gridfs_offset length = 0;
    gridfs_offset chunkLen = 0;
    bson *oChunk;

    /* Open the file and the correct stream */
    if ( strcmp( filename, "-" ) == 0 ) fd = stdin;
    else {
        fd = fopen( filename, "rb" );
        if (fd == NULL)
            return MONGO_ERROR;
    }

    /* Generate and append an oid*/
    bson_oid_gen( &id );

    /* Insert the file chunk by chunk */
    chunkLen = fread( buffer, 1, DEFAULT_CHUNK_SIZE, fd );
    do {
        oChunk = chunk_new( id, chunkNumber, buffer, chunkLen );
        mongo_insert( gfs->client, gfs->chunks_ns, oChunk, NULL );
        chunk_free( oChunk );
        length += chunkLen;
        chunkNumber++;
        chunkLen = fread( buffer, 1, DEFAULT_CHUNK_SIZE, fd );
    }
    while ( chunkLen != 0 );

    /* Close the file stream */
    if ( fd != stdin ) fclose( fd );

    /* Large files Assertion */
    /* assert(length <= 0xffffffff); */

    /* Optional Remote Name */
    if ( remotename == NULL || *remotename == '\0' ) {
        remotename = filename;
    }

    /* Inserts file's metadata */
    return gridfs_insert_file( gfs, remotename, id, length, contenttype );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_get_op_timeout(mongo* conn) {
    return conn->op_timeout_ms;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cursor_set_options( mongo_cursor *cursor, int options ) {
    cursor->options = options;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *value ) {
    return bson_append_string_base( b, name, value, strlen ( value ), BSON_STRING );
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT gridfs* gridfs_create( void ) {
    return (gridfs*)bson_malloc(sizeof(gridfs));
}

Project: mongo-c-driver-legacy
File: bson.c

static void bson_append_byte( bson *b, char c ) {
    b->cur[0] = c;
    b->cur++;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfile_get_metadata( gridfile *gfile, bson* out ) {
    bson_iterator it;

    if ( bson_find( &it, gfile->meta, "metadata" ) )
        bson_iterator_subobject( &it, out );
    else
        bson_empty( out );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) {
    return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_init( bson *b ) {
    _bson_init_size( b, initialBufferSize );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_simple_int_command( mongo *conn, const char *db,
        const char *cmdstr, int arg, bson *realout ) {

    bson out = {NULL, 0};
    bson cmd;
    int result;

    bson_init( &cmd );
    bson_append_int( &cmd, cmdstr, arg );
    bson_finish( &cmd );

    result = mongo_run_command( conn, db, &cmd, &out );

    bson_destroy( &cmd );

    if ( realout )
        *realout = out;
    else
        bson_destroy( &out );

    return result;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str ) {
    static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
    int i;
    for ( i=0; i<12; i++ ) {
        str[2*i]     = hex[( oid->bytes[i] & 0xf0 ) >> 4];
        str[2*i + 1] = hex[ oid->bytes[i] & 0x0f      ];
    }
    str[24] = '\0';
}

Project: mongo-c-driver-legacy
File: mongo.c

static void mongo_replica_set_free_list( mongo_host_port **list ) {
    mongo_host_port *node = *list;
    mongo_host_port *prev;

    while( node != NULL ) {
        prev = node;
        node = node->next;
        bson_free( prev );
    }

    *list = NULL;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT const char *gridfile_get_md5( gridfile *gfile ) {
    bson_iterator it;

    bson_find( &it, gfile->meta, "md5" );
    return bson_iterator_string( &it );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_print_raw( const char *data , int depth ) {
    bson_iterator i;
    const char *key;
    int temp;
    bson_timestamp_t ts;
    char oidhex[25];
    bson scope;
    bson_iterator_from_buffer( &i, data );

    while ( bson_iterator_next( &i ) ) {
        bson_type t = bson_iterator_type( &i );
        if ( t == 0 )
            break;
        key = bson_iterator_key( &i );

        for ( temp=0; temp<=depth; temp++ )
            bson_printf( "\t" );
        bson_printf( "%s : %d \t " , key , t );
        switch ( t ) {
        case BSON_DOUBLE:
            bson_printf( "%f" , bson_iterator_double( &i ) );
            break;
        case BSON_STRING:
            bson_printf( "%s" , bson_iterator_string( &i ) );
            break;
        case BSON_SYMBOL:
            bson_printf( "SYMBOL: %s" , bson_iterator_string( &i ) );
            break;
        case BSON_OID:
            bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
            bson_printf( "%s" , oidhex );
            break;
        case BSON_BOOL:
            bson_printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" );
            break;
        case BSON_DATE:
            bson_printf( "%ld" , ( long int )bson_iterator_date( &i ) );
            break;
        case BSON_BINDATA:
            bson_printf( "BSON_BINDATA" );
            break;
        case BSON_UNDEFINED:
            bson_printf( "BSON_UNDEFINED" );
            break;
        case BSON_NULL:
            bson_printf( "BSON_NULL" );
            break;
        case BSON_REGEX:
            bson_printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) );
            break;
        case BSON_CODE:
            bson_printf( "BSON_CODE: %s", bson_iterator_code( &i ) );
            break;
        case BSON_CODEWSCOPE:
            bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
            /* bson_init( &scope ); */ /* review - stepped on by bson_iterator_code_scope? */
            bson_iterator_code_scope( &i, &scope );
            bson_printf( "\n\t SCOPE: " );
            bson_print( &scope );
            /* bson_destroy( &scope ); */ /* review - causes free error */
            break;
        case BSON_INT:
            bson_printf( "%d" , bson_iterator_int( &i ) );
            break;
        case BSON_LONG:
            bson_printf( "%lld" , ( uint64_t )bson_iterator_long( &i ) );
            break;
        case BSON_TIMESTAMP:
            ts = bson_iterator_timestamp( &i );
            bson_printf( "i: %d, t: %d", ts.i, ts.t );
            break;
        case BSON_OBJECT:
        case BSON_ARRAY:
            bson_printf( "\n" );
            bson_print_raw( bson_iterator_value( &i ) , depth + 1 );
            break;
        default:
            bson_errprintf( "can't print type : %d\n" , t );
        }
        bson_printf( "\n" );
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT mongo_cursor *mongo_find( mongo *conn, const char *ns, const bson *query,
                                       const bson *fields, int limit, int skip, int options ) {

    mongo_cursor *cursor = ( mongo_cursor * )bson_malloc( sizeof( mongo_cursor ) );
    mongo_cursor_init( cursor, conn, ns );
    cursor->flags |= MONGO_CURSOR_MUST_FREE;

    mongo_cursor_set_query( cursor, query );
    mongo_cursor_set_fields( cursor, fields );
    mongo_cursor_set_limit( cursor, limit );
    mongo_cursor_set_skip( cursor, skip );
    mongo_cursor_set_options( cursor, options );

    if( mongo_cursor_op_query( cursor ) == MONGO_OK )
        return cursor;
    else {
        mongo_cursor_destroy( cursor );
        return NULL;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

int bson_init_finished_data( bson *b, char *data ) {
    bson_init_data( b, data );
    b->finished = 1;
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out ) {
    bson query;

    bson_iterator it;
    bson_oid_t id;
    int result;

    bson_init( &query );
    bson_find( &it, gfile->meta, "_id" );
    id = *bson_iterator_oid( &it );
    bson_append_oid( &query, "files_id", &id );
    bson_append_int( &query, "n", n );
    bson_finish( &query );

    result = (mongo_find_one(gfile->gfs->client,
                             gfile->gfs->chunks_ns,
                             &query, NULL, out ) == MONGO_OK );
    bson_destroy( &query );
    if (!result) {
        bson empty;
        bson_empty(&empty);
        bson_copy(out, &empty);
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_insert_batch( mongo *conn, const char *ns,
                                     const bson **bsons, int count, mongo_write_concern *custom_write_concern,
                                     int flags ) {

    mongo_message *mm;
    mongo_write_concern *write_concern = NULL;
    int i;
    char *data;
    size_t overhead =  16 + 4 + strlen( ns ) + 1;
    size_t size = overhead;

    if( mongo_validate_ns( conn, ns ) != MONGO_OK )
        return MONGO_ERROR;

    for( i=0; i<count; i++ ) {
        size += bson_size( bsons[i] );
        if( mongo_bson_valid( conn, bsons[i], 1 ) != MONGO_OK )
            return MONGO_ERROR;
    }

    if( ( size - overhead ) > conn->max_bson_size ) {
        conn->err = MONGO_BSON_TOO_LARGE;
        return MONGO_ERROR;
    }

    if( mongo_choose_write_concern( conn, custom_write_concern,
                                    &write_concern ) == MONGO_ERROR ) {
        return MONGO_ERROR;
    }

    mm = mongo_message_create( size , 0 , 0 , MONGO_OP_INSERT );

    data = &mm->data;
    if( flags & MONGO_CONTINUE_ON_ERROR )
        data = mongo_data_append32( data, &ONE );
    else
        data = mongo_data_append32( data, &ZERO );
    data = mongo_data_append( data, ns, strlen( ns ) + 1 );

    for( i=0; i<count; i++ ) {
        data = mongo_data_append( data, bsons[i]->data, bson_size( bsons[i] ) );
    }

    /* TODO: refactor so that we can send the insert message
     * and the getlasterror messages together. */
    if( write_concern ) {
        if( mongo_message_send( conn, mm ) == MONGO_ERROR ) {
            return MONGO_ERROR;
        }

        return mongo_check_last_error( conn, ns, write_concern );
    }
    else {
        return mongo_message_send( conn, mm );
    }
}

Project: mongo-c-driver-legacy
File: bcon.c

static bcon_token_t bcon_token(char *s) {
    if (s == 0) return Token_EOD;
    switch (s[0]) {
    case ':': if (s[1] != '\0' && s[2] != '\0' && s[3] != '\0' && s[4] == '\0' &&
                      s[3] == ':' && (s[1] == '_' || s[1] == 'P' || s[1] == 'R'))
            return Token_Typespec; break;
    case '{': if (s[1] == '\0') return Token_OpenBrace; break;
    case '}': if (s[1] == '\0') return Token_CloseBrace; break;
    case '[': if (s[1] == '\0') return Token_OpenBracket; break;
    case ']': if (s[1] == '\0') return Token_CloseBracket; break;
    case '.': if (s[1] == '\0') return Token_End; break;
    }
    return Token_Default;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out ) {
    return mongo_simple_str_command( conn, db, "drop", collection, out );
}

Project: mongo-c-driver-legacy
File: bcon.c

bcon_error_t bson_append_bcon_array(bson *b, const bcon *bc) {
    return bson_append_bcon_with_state(b, bc, State_ArraySpecValue);
}

Project: mongo-c-driver-legacy
File: bson.c

void bson_numstr( char *str, int i ) {
    if( i < 1000 )
        memcpy( str, bson_numstrs[i], 4 );
    else
        bson_sprintf( str,"%d", i );
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfile_destroy( gridfile *gfile )

{
    bson_destroy( gfile->meta );
    bson_free( gfile->meta );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_replica_set_client( mongo *conn ) {

    int res = 0;
    mongo_host_port *node;

    conn->sock = 0;
    conn->connected = 0;

    /* First iterate over the seed nodes to get the canonical list of hosts
     * from the replica set. Break out once we have a host list.
     */
    node = conn->replica_set->seeds;
    while( node != NULL ) {
        res = mongo_env_socket_connect( conn, ( const char * )&node->host, node->port );
        if( res == MONGO_OK ) {
            mongo_replica_set_check_seed( conn );
            if( conn->replica_set->hosts )
                break;
        }
        node = node->next;
    }

    /* Iterate over the host list, checking for the primary node. */
    if( !conn->replica_set->hosts ) {
        conn->err = MONGO_CONN_NO_PRIMARY;
        return MONGO_ERROR;
    }
    else {
        node = conn->replica_set->hosts;

        while( node != NULL ) {
            res = mongo_env_socket_connect( conn, ( const char * )&node->host, node->port );

            if( res == MONGO_OK ) {
                if( mongo_replica_set_check_host( conn ) != MONGO_OK )
                    return MONGO_ERROR;

                /* Primary found, so return. */
                else if( conn->replica_set->primary_connected ) {
                    conn->primary = bson_malloc( sizeof( mongo_host_port ) );
                    strncpy( conn->primary->host, node->host, strlen( node->host ) + 1 );
                    conn->primary->port = node->port;
                    return MONGO_OK;
                }

                /* No primary, so close the connection. */
                else {
                    mongo_env_close_socket( conn->sock );
                    conn->sock = 0;
                    conn->connected = 0;
                }
            }

            node = node->next;
        }
    }


    conn->err = MONGO_CONN_NO_PRIMARY;
    return MONGO_ERROR;
}

Project: mongo-c-driver-legacy
File: bson.c

static char hexbyte( char hex ) {
    if (hex >= '0' && hex <= '9')
        return (hex - '0');
    else if (hex >= 'A' && hex <= 'F')
        return (hex - 'A' + 10);
    else if (hex >= 'a' && hex <= 'f')
        return (hex - 'a' + 10);
    else
        return 0x0;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_null( bson *b, const char *name ) {
    if ( bson_append_estart( b , BSON_NULL, name, 0 ) == BSON_ERROR )
        return BSON_ERROR;
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

void *bson_realloc( void *ptr, size_t size ) {
    void *p;
    p = bson_realloc_func( ptr, size );
    bson_fatal_msg( !!p, "realloc() failed" );
    return p;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_write_concern_init( mongo_write_concern *write_concern ) {
    memset( write_concern, 0, sizeof( mongo_write_concern ) );
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT gridfs_offset gridfile_get_contentlength( gridfile *gfile ) {
    bson_iterator it;

    bson_find( &it, gfile->meta, "length" );

    if( bson_iterator_type( &it ) == BSON_INT )
        return ( gridfs_offset )bson_iterator_int( &it );
    else
        return ( gridfs_offset )bson_iterator_long( &it );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i ) {
    return bson_iterator_value( i )[4];
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ) {
    bson user_obj;
    bson pass_obj;
    char hex_digest[33];
    char *ns = bson_malloc( strlen( db ) + strlen( ".system.users" ) + 1 );
    int res;

    strcpy( ns, db );
    strcpy( ns+strlen( db ), ".system.users" );

    mongo_pass_digest( user, pass, hex_digest );

    bson_init( &user_obj );
    bson_append_string( &user_obj, "user", user );
    bson_finish( &user_obj );

    bson_init( &pass_obj );
    bson_append_start_object( &pass_obj, "$set" );
    bson_append_string( &pass_obj, "pwd", hex_digest );
    bson_append_finish_object( &pass_obj );
    bson_finish( &pass_obj );

    res = mongo_update( conn, ns, &user_obj, &pass_obj, MONGO_UPDATE_UPSERT, NULL );

    bson_free( ns );
    bson_destroy( &user_obj );
    bson_destroy( &pass_obj );

    return res;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT bson_date_t gridfile_get_uploaddate( gridfile *gfile ) {
    bson_iterator it;

    bson_find( &it, gfile->meta, "uploadDate" );
    return bson_iterator_date( &it );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_iterator_value( const bson_iterator *i ) {
    const char *t = i->cur + 1;
    t += strlen( t ) + 1;
    return t;
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_cursor_get_more( mongo_cursor *cursor ) {
    int res;

    if( cursor->limit > 0 && cursor->seen >= cursor->limit ) {
        cursor->err = MONGO_CURSOR_EXHAUSTED;
        return MONGO_ERROR;
    }
    else if( ! cursor->reply ) {
        cursor->err = MONGO_CURSOR_INVALID;
        return MONGO_ERROR;
    }
    else if( ! cursor->reply->fields.cursorID ) {
        cursor->err = MONGO_CURSOR_EXHAUSTED;
        return MONGO_ERROR;
    }
    else {
        char *data;
        size_t sl = strlen( cursor->ns )+1;
        int limit = 0;
        mongo_message *mm;

        if( cursor->limit > 0 )
            limit = cursor->limit - cursor->seen;

        mm = mongo_message_create( 16 /*header*/
                                   +4 /*ZERO*/
                                   +sl
                                   +4 /*numToReturn*/
                                   +8 /*cursorID*/
                                   , 0, 0, MONGO_OP_GET_MORE );
        data = &mm->data;
        data = mongo_data_append32( data, &ZERO );
        data = mongo_data_append( data, cursor->ns, sl );
        data = mongo_data_append32( data, &limit );
        mongo_data_append64( data, &cursor->reply->fields.cursorID );

        bson_free( cursor->reply );
        res = mongo_message_send( cursor->conn, mm );
        if( res != MONGO_OK ) {
            mongo_cursor_destroy( cursor );
            return MONGO_ERROR;
        }

        res = mongo_read_response( cursor->conn, &( cursor->reply ) );
        if( res != MONGO_OK ) {
            mongo_cursor_destroy( cursor );
            return MONGO_ERROR;
        }
        cursor->current.data = NULL;
        cursor->seen += cursor->reply->fields.num;

        return MONGO_OK;
    }
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, size_t size ) {
    bson_iterator it;
    bson_oid_t id;
    bson gte;
    bson query;
    bson orderby;
    bson command;
    mongo_cursor *cursor;

    bson_find( &it, gfile->meta, "_id" );
    id = *bson_iterator_oid( &it );

    bson_init( &query );
    bson_append_oid( &query, "files_id", &id );
    if ( size == 1 ) {
        bson_append_int( &query, "n", (int)start );
    }
    else {
        bson_init( &gte );
        bson_append_int( &gte, "$gte", (int)start );
        bson_finish( &gte );
        bson_append_bson( &query, "n", &gte );
        bson_destroy( &gte );
    }
    bson_finish( &query );

    bson_init( &orderby );
    bson_append_int( &orderby, "n", 1 );
    bson_finish( &orderby );

    bson_init( &command );
    bson_append_bson( &command, "query", &query );
    bson_append_bson( &command, "orderby", &orderby );
    bson_finish( &command );

    cursor = mongo_find( gfile->gfs->client, gfile->gfs->chunks_ns,
                         &command, NULL, (int)size, 0, 0 );

    bson_destroy( &command );
    bson_destroy( &query );
    bson_destroy( &orderby );

    return cursor;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT int gridfs_store_buffer( gridfs *gfs, const char *data,
                                      gridfs_offset length, const char *remotename,
                                      const char *contenttype ) {

    char const *end = data + length;
    const char *data_ptr = data;
    bson_oid_t id;
    int chunkNumber = 0;
    int chunkLen;
    bson *oChunk;

    /* Large files Assertion */
    /* assert( length <= 0xffffffff ); */

    /* Generate and append an oid*/
    bson_oid_gen( &id );

    /* Insert the file's data chunk by chunk */
    while ( data_ptr < end ) {
        chunkLen = DEFAULT_CHUNK_SIZE < ( unsigned int )( end - data_ptr ) ?
                   DEFAULT_CHUNK_SIZE : ( unsigned int )( end - data_ptr );
        oChunk = chunk_new( id, chunkNumber, data_ptr, chunkLen );
        mongo_insert( gfs->client, gfs->chunks_ns, oChunk, NULL );
        chunk_free( oChunk );
        chunkNumber++;
        data_ptr += chunkLen;
    }

    /* Inserts file's metadata */
    return gridfs_insert_file( gfs, remotename, id, length, contenttype );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_connect( mongo *conn , const char *host, int port ) {
    int ret;
    bson_errprintf("WARNING: mongo_connect() is deprecated, please use mongo_client()\n");
    ret = mongo_client( conn, host, port );
    mongo_set_write_concern( conn, 0 );
    return ret;
}

Project: mongo-c-driver-legacy
File: encoding.c

static int isLegalUTF8( const unsigned char *source, int length ) {
    unsigned char a;
    const unsigned char *srcptr = source + length;
    switch ( length ) {
    default:
        return 0;
        /* Everything else falls through when "true"... */
    case 4:
        if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0;
    case 3:
        if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0;
    case 2:
        if ( ( a = ( *--srcptr ) ) > 0xBF ) return 0;
        switch ( *source ) {
            /* no fall-through in this inner switch */
        case 0xE0:
            if ( a < 0xA0 ) return 0;
            break;
        case 0xF0:
            if ( a < 0x90 ) return 0;
            break;
        case 0xF4:
            if ( a > 0x8F ) return 0;
            break;
        default:
            if ( a < 0x80 ) return 0;
        }
    case 1:
        if ( *source >= 0x80 && *source < 0xC2 ) return 0;
        if ( *source > 0xF4 ) return 0;
    }
    return 1;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void *bson_malloc( size_t size ) {
    void *p;
    p = bson_malloc_func( size );
    bson_fatal_msg( !!p, "malloc() failed" );
    return p;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ) {
    return mongo_cmd_get_error_helper( conn, db, out, "getlasterror" );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_finish( bson *b ) {
    int i;

    if( b->err & BSON_NOT_UTF8 )
        return BSON_ERROR;

    if ( ! b->finished ) {
        if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
        bson_append_byte( b, 0 );
        i = ( int )( b->cur - b->data );
        bson_little_endian32( b->data, &i );
        b->finished = 1;
    }

    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name,
        const char *code, size_t len, const bson *scope ) {

    size_t sl, size;
    if ( !scope ) return BSON_ERROR;
    sl = len + 1;
    size = 4 + 4 + sl + bson_size( scope );
    if ( bson_append_estart( b, BSON_CODEWSCOPE, name, size ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append32_as_int( b, ( int )size );
    bson_append32( b, &sl );
    bson_append( b, code, sl );
    bson_append( b, scope->data, bson_size( scope ) );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_write_concern_finish( mongo_write_concern *write_concern ) {
    bson *command;

    /* Destory any existing serialized write concern object and reuse it. */
    if( write_concern->cmd ) {
        bson_destroy( write_concern->cmd );
        command = write_concern->cmd;
    }
    else
        command = (bson *)bson_malloc( sizeof( bson ) );

    if( !command ) {
        return MONGO_ERROR;
    }

    bson_init( command );

    bson_append_int( command, "getlasterror", 1 );

    if( write_concern->mode ) {
        bson_append_string( command, "w", write_concern->mode );
    }

    else if( write_concern->w && write_concern->w > 1 ) {
        bson_append_int( command, "w", write_concern->w );
    }

    if( write_concern->wtimeout ) {
        bson_append_int( command, "wtimeout", write_concern->wtimeout );
    }

    if( write_concern->j ) {
        bson_append_int( command, "j", write_concern->j );
    }

    if( write_concern->fsync ) {
        bson_append_int( command, "fsync", write_concern->fsync );
    }

    bson_finish( command );

    /* write_concern now owns the BSON command object.
     * This is freed in mongo_write_concern_destroy(). */
    write_concern->cmd = command;

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid ) {
    static int incr = 0;
    static int fuzz = 0;
    int i;
    time_t t = time( NULL );

    if( oid_inc_func )
        i = oid_inc_func();
    else
        i = incr++;

    if ( !fuzz ) {
        if ( oid_fuzz_func )
            fuzz = oid_fuzz_func();
        else {
            srand( ( int )t );
            fuzz = rand();
        }
    }

    bson_big_endian32( &oid->ints[0], &t );
    oid->ints[1] = fuzz;
    bson_big_endian32( &oid->ints[2], &i );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_iterator_dispose(bson_iterator* i) {
    free(i);
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_cursor_destroy( mongo_cursor *cursor ) {
    int result = MONGO_OK;

    if ( !cursor ) return result;

    /* Kill cursor if live. */
    if ( cursor->reply && cursor->reply->fields.cursorID ) {
        mongo *conn = cursor->conn;
        mongo_message *mm = mongo_message_create( 16 /*header*/
                            +4 /*ZERO*/
                            +4 /*numCursors*/
                            +8 /*cursorID*/
                            , 0, 0, MONGO_OP_KILL_CURSORS );
        char *data = &mm->data;
        data = mongo_data_append32( data, &ZERO );
        data = mongo_data_append32( data, &ONE );
        mongo_data_append64( data, &cursor->reply->fields.cursorID );

        result = mongo_message_send( conn, mm );
    }

    bson_free( cursor->reply );
    bson_free( ( void * )cursor->ns );

    if( cursor->flags & MONGO_CURSOR_MUST_FREE )
        bson_free( cursor );

    return result;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name ) {
    bson_oid_t oid;
    bson_oid_gen( &oid );
    return bson_append_oid( b, name, &oid );
}

Project: mongo-c-driver-legacy
File: gridfs.c

gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ) {
    int i;
    size_t len;
    bson chunk;
    bson_iterator it;
    const char *data;
    const int num = gridfile_get_numchunks( gfile );

    for ( i=0; i<num; i++ ) {
        gridfile_get_chunk( gfile, i, &chunk );
        bson_find( &it, &chunk, "data" );
        len = bson_iterator_bin_len( &it );
        data = bson_iterator_bin_data( &it );
        fwrite( data, sizeof( char ), len, stream );
        bson_destroy( &chunk );
    }

    return gridfile_get_contentlength( gfile );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cursor_dispose(mongo_cursor* cursor) {
    bson_free(cursor);
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ) {
    gridfs_offset length;

    length = gridfile_get_contentlength( gfile );
    gfile->pos = length < offset ? length : offset;
    return gfile->pos;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cmd_reset_error( mongo *conn, const char *db ) {
    mongo_simple_int_command( conn, db, "reseterror", 1, NULL );
}

Project: mongo-c-driver-legacy
File: gridfs.c

int gridfs_find_filename( gridfs *gfs, const char *filename,
                          gridfile *gfile )

{
    bson query;
    int i;

    bson_init( &query );
    bson_append_string( &query, "filename", filename );
    bson_finish( &query );
    i = gridfs_find_query( gfs, &query, gfile );
    bson_destroy( &query );
    return i;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_update( mongo *conn, const char *ns, const bson *cond,
                               const bson *op, int flags, mongo_write_concern *custom_write_concern ) {

    char *data;
    mongo_message *mm;
    mongo_write_concern *write_concern = NULL;

    /* Make sure that the op BSON is valid UTF-8.
     * TODO: decide whether to check cond as well.
     * */
    if( mongo_bson_valid( conn, ( bson * )op, 0 ) != MONGO_OK ) {
        return MONGO_ERROR;
    }

    if( mongo_choose_write_concern( conn, custom_write_concern,
                                    &write_concern ) == MONGO_ERROR ) {
        return MONGO_ERROR;
    }

    mm = mongo_message_create( 16 /* header */
                               + 4  /* ZERO */
                               + strlen( ns ) + 1
                               + 4  /* flags */
                               + bson_size( cond )
                               + bson_size( op )
                               , 0 , 0 , MONGO_OP_UPDATE );

    data = &mm->data;
    data = mongo_data_append32( data, &ZERO );
    data = mongo_data_append( data, ns, strlen( ns ) + 1 );
    data = mongo_data_append32( data, &flags );
    data = mongo_data_append( data, cond->data, bson_size( cond ) );
    mongo_data_append( data, op->data, bson_size( op ) );

    /* TODO: refactor so that we can send the insert message
     * and the getlasterror messages together. */
    if( write_concern ) {
        if( mongo_message_send( conn, mm ) == MONGO_ERROR ) {
            return MONGO_ERROR;
        }

        return mongo_check_last_error( conn, ns, write_concern );
    }
    else {
        return mongo_message_send( conn, mm );
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_check_connection( mongo *conn ) {
    if( ! conn->connected )
        return MONGO_ERROR;

    if( mongo_simple_int_command( conn, "admin", "ping", 1, NULL ) == MONGO_OK )
        return MONGO_OK;
    else
        return MONGO_ERROR;
}

Project: mongo-c-driver-legacy
File: bson.c

int64_t bson_iterator_long_raw( const bson_iterator *i ) {
    int64_t out;
    bson_little_endian64( &out, bson_iterator_value( i ) );
    return out;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_iterator_int( const bson_iterator *i ) {
    switch ( bson_iterator_type( i ) ) {
    case BSON_INT:
        return bson_iterator_int_raw( i );
    case BSON_LONG:
        return ( int )bson_iterator_long_raw( i );
    case BSON_DOUBLE:
        return bson_iterator_double_raw( i );
    default:
        return 0;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i ) {
    return bson_iterator_value( i );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment ) {
    if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;

    bson_append32( b , &increment );
    bson_append32( b , &time );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfile_dispose(gridfile* gf) {
    free(gf);
}

Project: mongo-c-driver-legacy
File: bcon.c

static int bcon_error(bson *b, const bcon *bc, size_t i, bcon_error_t err) {
    b->err = err;
    b->errstr = bcon_errstr[err];
    return BCON_ERROR;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_validate_ns( mongo *conn, const char *ns ) {
    char *last = NULL;
    char *current = NULL;
    const char *db_name = ns;
    char *collection_name = NULL;
    char errmsg[64];
    int ns_len = 0;

    /* If the first character is a '.', fail. */
    if( *ns == '.' ) {
        __mongo_set_error( conn, MONGO_NS_INVALID, "ns cannot start with a '.'.", 0 );
        return MONGO_ERROR;
    }

    /* Find the division between database and collection names. */
    for( current = (char *)ns; *current != '\0'; current++ ) {
        if( *current == '.' ) {
            current++;
            break;
        }
    }

    /* Fail if the collection part starts with a dot. */
    if( *current == '.' ) {
        __mongo_set_error( conn, MONGO_NS_INVALID, "ns cannot start with a '.'.", 0 );
        return MONGO_ERROR;
    }

    /* Fail if collection length is 0.
     * or the ns doesn't contain a '.'. */
    if( *current == '\0' ) {
        __mongo_set_error( conn, MONGO_NS_INVALID, "Collection name missing.", 0 );
        return MONGO_ERROR;
    }


    /* Point to the beginning of the collection name. */
    collection_name = current;

    /* Ensure that the database name is greater than one char.*/
    if( collection_name - 1 == db_name ) {
        __mongo_set_error( conn, MONGO_NS_INVALID, "Database name missing.", 0 );
        return MONGO_ERROR;
    }

    /* Go back and validate the database name. */
    for( current = (char *)db_name; *current != '.'; current++ ) {
        switch( *current ) {
        case ' ':
        case '$':
        case '/':
        case '\\':
            __mongo_set_error( conn, MONGO_NS_INVALID,
                               "Database name may not contain ' ', '$', '/', or '\\'", 0 );
            return MONGO_ERROR;
        default:
            break;
        }

        ns_len++;
    }

    /* Add one to the length for the '.' character. */
    ns_len++;

    /* Now validate the collection name. */
    for( current = collection_name; *current != '\0'; current++ ) {

        /* Cannot have two consecutive dots. */
        if( last && *last == '.' && *current == '.' ) {
            __mongo_set_error( conn, MONGO_NS_INVALID,
                               "Collection may not contain two consecutive '.'", 0 );
            return MONGO_ERROR;
        }

        /* Cannot contain a '$' */
        if( *current == '$' ) {
            __mongo_set_error( conn, MONGO_NS_INVALID,
                               "Collection may not contain '$'", 0 );
            return MONGO_ERROR;
        }

        last = current;
        ns_len++;
    }

    if( ns_len > 128 ) {
        bson_sprintf( errmsg, "Namespace too long; has %d but must <= 128.",
                      ns_len );
        __mongo_set_error( conn, MONGO_NS_INVALID, errmsg, 0 );
        return MONGO_ERROR;
    }

    /* Cannot end with a '.' */
    if( *(current - 1) == '.' ) {
        __mongo_set_error( conn, MONGO_NS_INVALID,
                           "Collection may not end with '.'", 0 );
        return MONGO_ERROR;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
    const char *cbuf = buf;
#ifdef _WIN32
    int flags = 0;
#else
#ifdef __APPLE__
    int flags = 0;
#else
    int flags = MSG_NOSIGNAL;
#endif
#endif

    while ( len ) {
        size_t sent = send( conn->sock, cbuf, len, flags );
        if ( sent == -1 ) {
            if (errno == EPIPE)
                conn->connected = 0;
            conn->err = MONGO_IO_ERROR;
            return MONGO_ERROR;
        }
        cbuf += sent;
        len -= sent;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) {
    if ( bson_iterator_type( i ) == BSON_CODEWSCOPE ) {
        int code_len;
        bson_little_endian32( &code_len, bson_iterator_value( i )+4 );
        bson_init_data( scope, ( void * )( bson_iterator_value( i )+8+code_len ) );
        _bson_reset( scope );
        scope->finished = 1;
    }
    else {
        bson_empty( scope );
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_is_connected(mongo* conn) {
    return conn->connected != 0;
}

Project: mongo-c-driver-legacy
File: mongo.c

static char *mongo_ns_to_cmd_db( const char *ns ) {
    char *current = NULL;
    char *cmd_db_name = NULL;
    int len = 0;

    for( current = (char *)ns; *current != '.'; current++ ) {
        len++;
    }

    cmd_db_name = (char *)bson_malloc( len + 6 );
    strncpy( cmd_db_name, ns, len );
    strncpy( cmd_db_name + len, ".$cmd", 6 );

    return cmd_db_name;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_finish_object( bson *b ) {
    char *start;
    int i;
    if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
    bson_append_byte( b , 0 );

    start = b->data + b->stack[ --b->stackPos ];
    i = ( int )( b->cur - start );
    bson_little_endian32( start, &i );

    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i ) {
    int time;
    bson_little_endian32( &time, bson_iterator_value( i ) + 4 );
    return time;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_time_t( bson *b, const char *name, time_t secs ) {
    return bson_append_date( b, name, ( bson_date_t )secs * 1000 );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT const char*  mongo_get_server_err_string(mongo* conn) {
    return conn->lasterrstr;
}

Project: mongo-c-driver-legacy
File: env.c

static int mongo_env_unix_socket_connect( mongo *conn, const char *sock_path ) {
    struct sockaddr_un addr;
    int status, len;

    conn->connected = 0;

    conn->sock = socket( AF_UNIX, SOCK_STREAM, 0 );

    if ( conn->sock < 0 ) {
        conn->sock = 0;
        return MONGO_ERROR;
    }

    addr.sun_family = AF_UNIX;
    strncpy( addr.sun_path, sock_path, sizeof(addr.sun_path) - 1 );
    len = sizeof( addr );

    status = connect( conn->sock, (struct sockaddr *) &addr, len );
    if( status < 0 ) {
        mongo_env_close_socket( conn->sock );
        conn->sock = 0;
        conn->err = MONGO_CONN_FAIL;
        return MONGO_ERROR;
    }

    conn->connected = 1;

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

void bson_init_size( bson *b, int size ) {
    _bson_init_size( b, size );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT double mongo_count( mongo *conn, const char *db, const char *ns, const bson *query ) {
    bson cmd;
    bson out = {NULL, 0};
    double count = -1;

    bson_init( &cmd );
    bson_append_string( &cmd, "count", ns );
    if ( query && bson_size( query ) > 5 ) /* not empty */
        bson_append_bson( &cmd, "query", query );
    bson_finish( &cmd );

    if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) {
        bson_iterator it;
        if( bson_find( &it, &out, "n" ) )
            count = bson_iterator_double( &it );
        bson_destroy( &cmd );
        bson_destroy( &out );
        return count;
    }
    else {
        bson_destroy( &out );
        bson_destroy( &cmd );
        return MONGO_ERROR;
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

static void mongo_pass_digest( const char *user, const char *pass, char hex_digest[33] ) {
    mongo_md5_state_t st;
    mongo_md5_byte_t digest[16];

    mongo_md5_init( &st );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, ( int )strlen( user ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )":mongo:", 7 );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )pass, ( int )strlen( pass ) );
    mongo_md5_finish( &st, digest );
    digest2hex( digest, hex_digest );
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
    char port_str[NI_MAXSERV];
    char errstr[MONGO_ERR_LEN];
    int status;

    struct addrinfo ai_hints;
    struct addrinfo *ai_list = NULL;
    struct addrinfo *ai_ptr = NULL;

    conn->sock = 0;
    conn->connected = 0;

    bson_sprintf( port_str, "%d", port );

    memset( &ai_hints, 0, sizeof( ai_hints ) );
    ai_hints.ai_family = AF_UNSPEC;
    ai_hints.ai_socktype = SOCK_STREAM;
    ai_hints.ai_protocol = IPPROTO_TCP;

    status = getaddrinfo( host, port_str, &ai_hints, &ai_list );
    if ( status != 0 ) {
        bson_sprintf( errstr, "getaddrinfo failed with error %d", status );
        __mongo_set_error( conn, MONGO_CONN_ADDR_FAIL, errstr, WSAGetLastError() );
        return MONGO_ERROR;
    }

    for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) {
        conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype,
                             ai_ptr->ai_protocol );

        if ( conn->sock < 0 ) {
            __mongo_set_error( conn, MONGO_SOCKET_ERROR, "socket() failed",
                               WSAGetLastError() );
            conn->sock = 0;
            continue;
        }

        status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen );
        if ( status != 0 ) {
            __mongo_set_error( conn, MONGO_SOCKET_ERROR, "connect() failed",
                               WSAGetLastError() );
            mongo_env_close_socket( conn->sock );
            conn->sock = 0;
            continue;
        }

        if ( ai_ptr->ai_protocol == IPPROTO_TCP ) {
            int flag = 1;

            setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY,
                        ( void * ) &flag, sizeof( flag ) );

            if ( conn->op_timeout_ms > 0 )
                mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
        }

        conn->connected = 1;
        break;
    }

    freeaddrinfo( ai_list );

    if ( ! conn->connected ) {
        conn->err = MONGO_CONN_FAIL;
        return MONGO_ERROR;
    }
    else {
        mongo_clear_errors( conn );
        return MONGO_OK;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_swap_endian64( void *outp, const void *inp ) {
    const char *in = ( const char * )inp;
    char *out = ( char * )outp;

    out[0] = in[7];
    out[1] = in[6];
    out[2] = in[5];
    out[3] = in[4];
    out[4] = in[3];
    out[5] = in[2];
    out[6] = in[1];
    out[7] = in[0];

}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_destroy( mongo *conn ) {
    mongo_disconnect( conn );

    if( conn->replica_set ) {
        mongo_replica_set_free_list( &conn->replica_set->seeds );
        mongo_replica_set_free_list( &conn->replica_set->hosts );
        bson_free( conn->replica_set->name );
        bson_free( conn->replica_set );
        conn->replica_set = NULL;
    }

    bson_free( conn->primary );

    mongo_clear_errors( conn );
}

Project: mongo-c-driver-legacy
File: mongo.c

static char *mongo_data_append32( char *start , const void *data ) {
    bson_little_endian32( start , data );
    return start + 4;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT gridfile* gridfile_create( void ) {
    return (gridfile*)bson_malloc(sizeof(gridfile));
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
    if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&millis,
                     sizeof( millis ) ) == -1 ) {
        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.",
                           WSAGetLastError() );
        return MONGO_ERROR;
    }

    if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&millis,
                     sizeof( millis ) ) == -1 ) {
        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.",
                           WSAGetLastError() );
        return MONGO_ERROR;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

static void mongo_replica_set_check_seed( mongo *conn ) {
    bson out;
    bson hosts;
    const char *data;
    bson_iterator it;
    bson_iterator it_sub;
    const char *host_string;
    mongo_host_port *host_port = NULL;

    out.data = NULL;

    hosts.data = NULL;

    if( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) {

        if( bson_find( &it, &out, "hosts" ) ) {
            data = bson_iterator_value( &it );
            bson_iterator_from_buffer( &it_sub, data );

            /* Iterate over host list, adding each host to the
             * connection's host list. */
            while( bson_iterator_next( &it_sub ) ) {
                host_string = bson_iterator_string( &it_sub );

                host_port = bson_malloc( sizeof( mongo_host_port ) );

                if( host_port ) {
                    mongo_parse_host( host_string, host_port );
                    mongo_replica_set_add_node( &conn->replica_set->hosts,
                                                host_port->host, host_port->port );

                    bson_free( host_port );
                    host_port = NULL;
                }
            }
        }
    }

    bson_destroy( &out );
    bson_destroy( &hosts );
    mongo_env_close_socket( conn->sock );
    conn->sock = 0;
    conn->connected = 0;

}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_choose_write_concern( mongo *conn,
                                       mongo_write_concern *custom_write_concern,
                                       mongo_write_concern **write_concern ) {

    if( custom_write_concern ) {
        *write_concern = custom_write_concern;
    }
    else if( conn->write_concern ) {
        *write_concern = conn->write_concern;
    }
    if ( *write_concern && (*write_concern)->w < 1 ) {
        *write_concern = 0; /* do not generate getLastError request */
    }
    if( *write_concern && !((*write_concern)->cmd) ) {
        __mongo_set_error( conn, MONGO_WRITE_CONCERN_INVALID,
                           "Must call mongo_write_concern_finish() before using *write_concern.", 0 );
        return MONGO_ERROR;
    }
    else
        return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_create_capped_collection( mongo *conn, const char *db,
        const char *collection, int size, int max, bson *out ) {

    bson b;
    int result;

    bson_init( &b );
    bson_append_string( &b, "create", collection );
    bson_append_bool( &b, "capped", 1 );
    bson_append_int( &b, "size", size );
    if( max > 0 )
        bson_append_int( &b, "max", size );
    bson_finish( &b );

    result = mongo_run_command( conn, db, &b, out );

    bson_destroy( &b );

    return result;
}

Project: mongo-c-driver-legacy
File: bson.c

static void _bson_init_size( bson *b, int size ) {
    if( size == 0 )
        b->data = NULL;
    else
        b->data = ( char * )bson_malloc( size );
    b->dataSize = size;
    b->cur = b->data + 4;
    _bson_reset( b );
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfs_remove_filename( gridfs *gfs, const char *filename ) {
    bson query;
    mongo_cursor *files;
    bson file;
    bson_iterator it;
    bson_oid_t id;
    bson b;

    bson_init( &query );
    bson_append_string( &query, "filename", filename );
    bson_finish( &query );
    files = mongo_find( gfs->client, gfs->files_ns, &query, NULL, 0, 0, 0 );
    bson_destroy( &query );

    /* Remove each file and it's chunks from files named filename */
    while ( mongo_cursor_next( files ) == MONGO_OK ) {
        file = files->current;
        bson_find( &it, &file, "_id" );
        id = *bson_iterator_oid( &it );

        /* Remove the file with the specified id */
        bson_init( &b );
        bson_append_oid( &b, "_id", &id );
        bson_finish( &b );
        mongo_remove( gfs->client, gfs->files_ns, &b, NULL );
        bson_destroy( &b );

        /* Remove all chunks from the file with the specified id */
        bson_init( &b );
        bson_append_oid( &b, "files_id", &id );
        bson_finish( &b );
        mongo_remove( gfs->client, gfs->chunks_ns, &b, NULL );
        bson_destroy( &b );
    }

    mongo_cursor_destroy( files );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ) {
    if ( bson_append_estart( b, BSON_OID, name, 12 ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append( b , oid , 12 );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_get_err(mongo* conn) {
    return conn->err;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis ) {
    if ( bson_append_estart( b, BSON_DATE, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
    bson_append64( b , &millis );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_init( mongo *conn ) {
    memset( conn, 0, sizeof( mongo ) );
    conn->max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE;
    mongo_set_write_concern( conn, &WC1 );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i ) {
    return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
           ? bson_iterator_int_raw( i ) - 4
           : bson_iterator_int_raw( i );
}

Project: mongo-c-driver-legacy
File: bcon.c

bcon_error_t bson_append_bcon(bson *b, const bcon *bc) {
    return bson_append_bcon_with_state(b, bc, State_Element);
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
    char *cbuf = buf;

    while ( len ) {
        size_t sent = recv( conn->sock, cbuf, len, 0 );
        if ( sent == 0 || sent == -1 ) {
            __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
            return MONGO_ERROR;
        }
        cbuf += sent;
        len -= sent;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ) {
    return mongo_cmd_get_error_helper( conn, db, out, "getpreverror" );
}

Project: mongo-c-driver-legacy
File: encoding.c

int bson_check_string( bson *b, const char *string,
                       const size_t length ) {

    return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_set_oid_inc( int ( *func )( void ) ) {
    oid_inc_func = func;
}

Project: mongo-c-driver-legacy
File: bson.c

static void bson_append32( bson *b, const void *data ) {
    bson_little_endian32( b->cur, data );
    b->cur += 4;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_print( const bson *b ) {
    bson_print_raw( b->data , 0 );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cursor_set_fields( mongo_cursor *cursor, const bson *fields ) {
    cursor->fields = fields;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_swap_endian32( void *outp, const void *inp ) {
    const char *in = ( const char * )inp;
    char *out = ( char * )outp;

    out[0] = in[3];
    out[1] = in[2];
    out[2] = in[1];
    out[3] = in[0];
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_replica_set_add_seed( mongo *conn, const char *host, int port ) {
    mongo_replica_set_add_node( &conn->replica_set->seeds, host, port );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_free( void *ptr ) {
    bson_free_func( ptr );
}

Project: mongo-c-driver-legacy
File: mongo.c

void mongo_parse_host( const char *host_string, mongo_host_port *host_port ) {
    int len, idx, split;
    len = split = idx = 0;

    /* Split the host_port string at the ':' */
    while( 1 ) {
        if( *( host_string + len ) == '\0' )
            break;
        if( *( host_string + len ) == ':' )
            split = len;

        len++;
    }

    /* If 'split' is set, we know the that port exists;
     * Otherwise, we set the default port. */
    idx = split ? split : len;
    memcpy( host_port->host, host_string, idx );
    memcpy( host_port->host + idx, "\0", 1 );
    if( split )
        host_port->port = atoi( host_string + idx + 1 );
    else
        host_port->port = MONGO_DEFAULT_PORT;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfile_get_descriptor(gridfile* gf, bson* out) {
    *out = *gf->meta;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, size_t len ) {
    return bson_append_string_base( b, name, value, len, BSON_SYMBOL );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_client( mongo *conn , const char *host, int port ) {
    mongo_init( conn );

    conn->primary = bson_malloc( sizeof( mongo_host_port ) );
    strncpy( conn->primary->host, host, strlen( host ) + 1 );
    conn->primary->port = port;
    conn->primary->next = NULL;

    if( mongo_env_socket_connect( conn, host, port ) != MONGO_OK )
        return MONGO_ERROR;

    if( mongo_check_is_master( conn ) != MONGO_OK )
        return MONGO_ERROR;
    else
        return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

static void mongo_replica_set_add_node( mongo_host_port **list, const char *host, int port ) {
    mongo_host_port *host_port = bson_malloc( sizeof( mongo_host_port ) );
    host_port->port = port;
    host_port->next = NULL;
    strncpy( host_port->host, host, strlen( host ) + 1 );

    if( *list == NULL )
        *list = host_port;
    else {
        mongo_host_port *p = *list;
        while( p->next != NULL )
            p = p->next;
        p->next = host_port;
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ) {
    cursor->limit = limit;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_simple_str_command( mongo *conn, const char *db,
        const char *cmdstr, const char *arg, bson *realout ) {

    bson out = {NULL, 0};
    int result;

    bson cmd;
    bson_init( &cmd );
    bson_append_string( &cmd, cmdstr, arg );
    bson_finish( &cmd );

    result = mongo_run_command( conn, db, &cmd, &out );

    bson_destroy( &cmd );

    if ( realout )
        *realout = out;
    else
        bson_destroy( &out );

    return result;
}

Project: mongo-c-driver-legacy
File: bson.c

static void bson_append( bson *b, const void *data, size_t len ) {
    memcpy( b->cur , data , len );
    b->cur += len;
}

Project: mongo-c-driver-legacy
File: env.c

MONGO_EXPORT int mongo_env_sock_init( void ) {

#if defined(_WIN32)
    WSADATA wsaData;
    WORD wVers;
#elif defined(SIGPIPE)
    struct sigaction act;
#endif

    static int called_once;
    static int retval;
    if (called_once) return retval;
    called_once = 1;

#if defined(_WIN32)
    wVers = MAKEWORD(1, 1);
    retval = (WSAStartup(wVers, &wsaData) == 0);
#elif defined(MACINTOSH)
    GUSISetup(GUSIwithInternetSockets);
    retval = 1;
#elif defined(SIGPIPE)
    retval = 1;
    if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) < 0)
        retval = 0;
    else if (act.sa_handler == SIG_DFL) {
        act.sa_handler = SIG_IGN;
        if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) < 0)
            retval = 0;
    }
#endif
    return retval;
}

Project: mongo-c-driver-legacy
File: bson.c

int bson_ensure_space( bson *b, const size_t bytesNeeded ) {
    int pos = b->cur - b->data;
    char *orig = b->data;
    int new_size;

    if ( pos + bytesNeeded <= b->dataSize )
        return BSON_OK;

    new_size = 1.5 * ( b->dataSize + bytesNeeded );

    if( new_size < b->dataSize ) {
        if( ( b->dataSize + bytesNeeded ) < INT_MAX )
            new_size = INT_MAX;
        else {
            b->err = BSON_SIZE_OVERFLOW;
            return BSON_ERROR;
        }
    }

    b->data = bson_realloc( b->data, new_size );
    if ( !b->data )
        bson_fatal_msg( !!b->data, "realloc() failed" );

    b->dataSize = new_size;
    b->cur += b->data - orig;

    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i ) {
    int increment;
    bson_little_endian32( &increment, bson_iterator_value( i ) );
    return increment;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT int gridfile_get_numchunks( gridfile *gfile ) {
    bson_iterator it;
    gridfs_offset length;
    gridfs_offset chunkSize;
    double numchunks;

    bson_find( &it, gfile->meta, "length" );

    if( bson_iterator_type( &it ) == BSON_INT )
        length = ( gridfs_offset )bson_iterator_int( &it );
    else
        length = ( gridfs_offset )bson_iterator_long( &it );

    bson_find( &it, gfile->meta, "chunkSize" );
    chunkSize = bson_iterator_int( &it );
    numchunks = ( ( double )length/( double )chunkSize );
    return ( numchunks - ( int )numchunks > 0 )
           ? ( int )( numchunks+1 )
           : ( int )( numchunks );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) {
    bson_iterator next = *elem;
    size_t size;

    bson_iterator_next( &next );
    size = next.cur - elem->cur;

    if ( name_or_null == NULL ) {
        if( bson_ensure_space( b, size ) == BSON_ERROR )
            return BSON_ERROR;
        bson_append( b, elem->cur, size );
    }
    else {
        size_t data_size = size - 2 - strlen( bson_iterator_key( elem ) );
        bson_append_estart( b, elem->cur[0], name_or_null, data_size );
        bson_append( b, bson_iterator_value( elem ), data_size );
    }

    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_close_socket( int socket ) {
    return closesocket( socket );
}

Project: mongo-c-driver-legacy
File: gridfs.c

const char *gridfile_get_field( gridfile *gfile, const char *name ) {
    bson_iterator it;

    bson_find( &it, gfile->meta, name );
    return bson_iterator_value( &it );
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfile_writer_init( gridfile *gfile, gridfs *gfs,
                                        const char *remote_name, const char *content_type ) {
    gfile->gfs = gfs;

    bson_oid_gen( &( gfile->id ) );
    gfile->chunk_num = 0;
    gfile->length = 0;
    gfile->pending_len = 0;
    gfile->pending_data = NULL;

    gfile->remote_name = ( char * )bson_malloc( strlen( remote_name ) + 1 );
    strcpy( ( char * )gfile->remote_name, remote_name );

    gfile->content_type = ( char * )bson_malloc( strlen( content_type ) + 1 );
    strcpy( ( char * )gfile->content_type, content_type );
}

Project: mongo-c-driver-legacy
File: gridfs.c

bson_bool_t gridfile_get_boolean( gridfile *gfile, const char *name ) {
    bson_iterator it;

    bson_find( &it, gfile->meta, name );
    return bson_iterator_bool( &it );
}

Project: mongo-c-driver-legacy
File: bson.c

void bson_builder_error( bson *b ) {
    if( err_handler )
        err_handler( "BSON error." );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void __mongo_set_error( mongo *conn, mongo_error_t err, const char *str,
                                     int errcode ) {
    size_t errstr_size, str_size;

    conn->err = err;
    conn->errcode = errcode;

    if( str ) {
        str_size = strlen( str ) + 1;
        errstr_size = str_size > MONGO_ERR_LEN ? MONGO_ERR_LEN : str_size;
        memcpy( conn->errstr, str, errstr_size );
        conn->errstr[errstr_size-1] = '\0';
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_finish_array( bson *b ) {
    return bson_append_finish_object( b );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_replica_set_init( mongo *conn, const char *name ) {
    mongo_init( conn );

    conn->replica_set = bson_malloc( sizeof( mongo_replica_set ) );
    conn->replica_set->primary_connected = 0;
    conn->replica_set->seeds = NULL;
    conn->replica_set->hosts = NULL;
    conn->replica_set->name = ( char * )bson_malloc( strlen( name ) + 1 );
    memcpy( conn->replica_set->name, name, strlen( name ) + 1  );

    conn->primary = bson_malloc( sizeof( mongo_host_port ) );
    conn->primary->host[0] = '\0';
    conn->primary->next = NULL;
}

Project: mongo-c-driver-legacy
File: bson.c

void bson_fatal( int ok ) {
    bson_fatal_msg( ok, "" );
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_bson_valid( mongo *conn, const bson *bson, int write ) {
    int size;

    if( ! bson->finished ) {
        conn->err = MONGO_BSON_NOT_FINISHED;
        return MONGO_ERROR;
    }

    size = bson_size( bson );
    if( size > conn->max_bson_size ) {
        conn->err = MONGO_BSON_TOO_LARGE;
        return MONGO_ERROR;
    }

    if( bson->err & BSON_NOT_UTF8 ) {
        conn->err = MONGO_BSON_INVALID;
        return MONGO_ERROR;
    }

    if( write ) {
        if( ( bson->err & BSON_FIELD_HAS_DOT ) ||
                ( bson->err & BSON_FIELD_INIT_DOLLAR ) ) {

            conn->err = MONGO_BSON_INVALID;
            return MONGO_ERROR;

        }
    }

    conn->err = 0;

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT const char *mongo_cursor_data( mongo_cursor *cursor ) {
    return cursor->current.data;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_read_socket( mongo *conn, void *buf, size_t len ) {
    char *cbuf = buf;
    while ( len ) {
        size_t sent = recv( conn->sock, cbuf, len, 0 );
        if ( sent == 0 || sent == -1 ) {
            __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
            return MONGO_ERROR;
        }
        cbuf += sent;
        len -= sent;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_start_array( bson *b, const char *name ) {
    if ( bson_append_estart( b, BSON_ARRAY, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
    b->stack[ b->stackPos++ ] = b->cur - b->data;
    bson_append32( b , &zero );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *realout ) {
    bson out = {NULL,0};
    bson_bool_t ismaster = 0;

    if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) {
        bson_iterator it;
        bson_find( &it, &out, "ismaster" );
        ismaster = bson_iterator_bool( &it );
    }

    if( realout )
        *realout = out; /* transfer of ownership */
    else
        bson_destroy( &out );

    return ismaster;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT size_t bson_buffer_size( const bson *b ) {
    return (b->cur - b->data + 1);
}

Project: mongo-c-driver-legacy
File: mongo.c

static char *mongo_data_append( char *start , const void *data , size_t len ) {
    memcpy( start , data , len );
    return start + len;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson ) {
    if ( !bson ) return BSON_ERROR;
    if ( bson_append_estart( b, BSON_OBJECT, name, bson_size( bson ) ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append( b , bson->data , bson_size( bson ) );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) {
    i->cur = buffer + 4;
    i->first = 1;
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_message_send( mongo *conn, mongo_message *mm ) {
    mongo_header head; /* little endian */
    int res;
    bson_little_endian32( &head.len, &mm->head.len );
    bson_little_endian32( &head.id, &mm->head.id );
    bson_little_endian32( &head.responseTo, &mm->head.responseTo );
    bson_little_endian32( &head.op, &mm->head.op );

    res = mongo_env_write_socket( conn, &head, sizeof( head ) );
    if( res != MONGO_OK ) {
        bson_free( mm );
        return res;
    }

    res = mongo_env_write_socket( conn, &mm->data, mm->head.len - sizeof( head ) );
    if( res != MONGO_OK ) {
        bson_free( mm );
        return res;
    }

    bson_free( mm );
    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT int gridfile_writer_done( gridfile *gfile ) {

    /* write any remaining pending chunk data.
     * pending data will always take up less than one chunk */
    bson *oChunk;
    int response;
    if( gfile->pending_data ) {
        oChunk = chunk_new( gfile->id, gfile->chunk_num, gfile->pending_data, gfile->pending_len );
        mongo_insert( gfile->gfs->client, gfile->gfs->chunks_ns, oChunk, NULL );
        chunk_free( oChunk );
        bson_free( gfile->pending_data );
        gfile->length += gfile->pending_len;
    }

    /* insert into files collection */
    response = gridfs_insert_file( gfile->gfs, gfile->remote_name, gfile->id,
                                   gfile->length, gfile->content_type );

    bson_free( gfile->remote_name );
    bson_free( gfile->content_type );

    return response;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i ) {
    switch ( bson_iterator_type( i ) ) {
    case BSON_STRING:
    case BSON_SYMBOL:
        return bson_iterator_value( i ) + 4;
    default:
        return "";
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_cursor_next( mongo_cursor *cursor ) {
    char *next_object;
    char *message_end;

    if( ! ( cursor->flags & MONGO_CURSOR_QUERY_SENT ) )
        if( mongo_cursor_op_query( cursor ) != MONGO_OK )
            return MONGO_ERROR;

    if( !cursor->reply )
        return MONGO_ERROR;

    /* no data */
    if ( cursor->reply->fields.num == 0 ) {

        /* Special case for tailable cursors. */
        if( cursor->reply->fields.cursorID ) {
            if( ( mongo_cursor_get_more( cursor ) != MONGO_OK ) ||
                    cursor->reply->fields.num == 0 ) {
                return MONGO_ERROR;
            }
        }

        else
            return MONGO_ERROR;
    }

    /* first */
    if ( cursor->current.data == NULL ) {
        bson_init_finished_data( &cursor->current, &cursor->reply->objs );
        return MONGO_OK;
    }

    next_object = cursor->current.data + bson_size( &cursor->current );
    message_end = ( char * )cursor->reply + cursor->reply->head.len;

    if ( next_object >= message_end ) {
        if( mongo_cursor_get_more( cursor ) != MONGO_OK )
            return MONGO_ERROR;

        if ( cursor->reply->fields.num == 0 ) {
            /* Special case for tailable cursors. */
            if ( cursor->reply->fields.cursorID ) {
                cursor->err = MONGO_CURSOR_PENDING;
                return MONGO_ERROR;
            }
            else
                return MONGO_ERROR;
        }

        bson_init_finished_data( &cursor->current, &cursor->reply->objs );
    }
    else {
        bson_init_finished_data( &cursor->current, next_object );
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i ) {
    return ( bson_oid_t * )bson_iterator_value( i );
}

Project: mongo-c-driver-legacy
File: mongo.c

static void digest2hex( mongo_md5_byte_t digest[16], char hex_digest[33] ) {
    static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
    int i;
    for ( i=0; i<16; i++ ) {
        hex_digest[2*i]     = hex[( digest[i] & 0xf0 ) >> 4];
        hex_digest[2*i + 1] = hex[ digest[i] & 0x0f      ];
    }
    hex_digest[32] = '\0';
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT const char* mongo_get_primary(mongo* conn) {
    mongo* conn_ = (mongo*)conn;
    if( !(conn_->connected) || (conn_->primary->host[0] == '\0') )
        return NULL;
    return _get_host_port(conn_->primary);
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT time_t bson_oid_generated_time( bson_oid_t *oid ) {
    time_t out;
    bson_big_endian32( &out, &oid->ints[0] );

    return out;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_close_socket( int socket ) {
    return close( socket );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ) {
    cursor->skip = skip;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i ) {
    return i->cur + 1;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i ) {
    switch ( bson_iterator_type( i ) ) {
    case BSON_STRING:
    case BSON_CODE:
        return bson_iterator_value( i ) + 4;
    case BSON_CODEWSCOPE:
        return bson_iterator_value( i ) + 8;
    default:
        return NULL;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_undefined( bson *b, const char *name ) {
    if ( bson_append_estart( b, BSON_UNDEFINED, name, 0 ) == BSON_ERROR )
        return BSON_ERROR;
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

static int gridfs_insert_file( gridfs *gfs, const char *name,
                               const bson_oid_t id, gridfs_offset length,
                               const char *contenttype ) {
    bson command;
    bson ret;
    bson res;
    bson_iterator it;
    int result;
    int64_t d;

    /* Check run md5 */
    bson_init( &command );
    bson_append_oid( &command, "filemd5", &id );
    bson_append_string( &command, "root", gfs->prefix );
    bson_finish( &command );
    result = mongo_run_command( gfs->client, gfs->dbname, &command, &res );
    bson_destroy( &command );
    if (result != MONGO_OK)
        return result;

    /* Create and insert BSON for file metadata */
    bson_init( &ret );
    bson_append_oid( &ret, "_id", &id );
    if ( name != NULL && *name != '\0' ) {
        bson_append_string( &ret, "filename", name );
    }
    bson_append_long( &ret, "length", length );
    bson_append_int( &ret, "chunkSize", DEFAULT_CHUNK_SIZE );
    d = ( bson_date_t )1000*time( NULL );
    bson_append_date( &ret, "uploadDate", d);
    bson_find( &it, &res, "md5" );
    bson_append_string( &ret, "md5", bson_iterator_string( &it ) );
    bson_destroy( &res );
    if ( contenttype != NULL && *contenttype != '\0' ) {
        bson_append_string( &ret, "contentType", contenttype );
    }
    bson_finish( &ret );
    result = mongo_insert( gfs->client, gfs->files_ns, &ret, NULL );
    bson_destroy( &ret );

    return result;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_insert( mongo *conn, const char *ns,
                               const bson *bson, mongo_write_concern *custom_write_concern ) {

    char *data;
    mongo_message *mm;
    mongo_write_concern *write_concern = NULL;

    if( mongo_validate_ns( conn, ns ) != MONGO_OK )
        return MONGO_ERROR;

    if( mongo_bson_valid( conn, bson, 1 ) != MONGO_OK ) {
        return MONGO_ERROR;
    }

    if( mongo_choose_write_concern( conn, custom_write_concern,
                                    &write_concern ) == MONGO_ERROR ) {
        return MONGO_ERROR;
    }

    mm = mongo_message_create( 16 /* header */
                               + 4 /* ZERO */
                               + strlen( ns )
                               + 1 + bson_size( bson )
                               , 0, 0, MONGO_OP_INSERT );

    data = &mm->data;
    data = mongo_data_append32( data, &ZERO );
    data = mongo_data_append( data, ns, strlen( ns ) + 1 );
    mongo_data_append( data, bson->data, bson_size( bson ) );


    /* TODO: refactor so that we can send the insert message
       and the getlasterror messages together. */
    if( write_concern ) {
        if( mongo_message_send( conn, mm ) == MONGO_ERROR ) {
            return MONGO_ERROR;
        }

        return mongo_check_last_error( conn, ns, write_concern );
    }
    else {
        return mongo_message_send( conn, mm );
    }
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
    struct sockaddr_in sa;
    socklen_t addressSize;
    int flag = 1;

    if ( ( conn->sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
        conn->sock = 0;
        conn->err = MONGO_CONN_NO_SOCKET;
        return MONGO_ERROR;
    }

    memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) );
    sa.sin_family = AF_INET;
    sa.sin_port = htons( port );
    sa.sin_addr.s_addr = inet_addr( host );
    addressSize = sizeof( sa );

    if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) {
        mongo_env_close_socket( conn->sock );
        conn->connected = 0;
        conn->sock = 0;
        conn->err = MONGO_CONN_FAIL;
        return MONGO_ERROR;
    }

    setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) );

    if( conn->op_timeout_ms > 0 )
        mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );

    conn->connected = 1;

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bcon.c

void bcon_print(const bcon *bc) { /* prints internal representation, not JSON */
    char *typespec = 0;
    char *delim = "";
    int end_of_data;
    bcon *bcp;
    putchar('{');
    for (end_of_data = 0, bcp = (bcon*)bc; !end_of_data; bcp++) {
        bcon bci = *bcp;
        char *typespec_next = 0;
        if (typespec) {
            switch (typespec[1]) {
            case '_':
                switch (typespec[2]) {
                case 'f': printf("%s%f", delim, bci.f); break;
                case 's': printf("%s\"%s\"", delim, bci.s); break;
                case 'D': printf("%sPD(0x%lx,..)", delim, (unsigned long)bci.D); break;
                case 'A': printf("%sPA(0x%lx,....)", delim, (unsigned long)bci.A); break;
                case 'o': printf("%s\"%s\"", delim, bci.o); break;
                case 'b': printf("%s%d", delim, bci.b); break;
                case 't': printf("%s%ld", delim, (long)bci.t); break;
                case 'v': printf("%s\"%s\"", delim, bci.v); break;
                case 'x': printf("%s\"%s\"", delim, bci.x); break;
                case 'i': printf("%s%d", delim, bci.i); break;
                case 'l': printf("%s%ld", delim, bci.l); break;
                default: printf("\ntypespec:\"%s\"\n", typespec); assert(NOT_REACHED); break;
                }
                break;
            case 'R':
                switch (typespec[2]) {
                case 'f': printf("%sRf(0x%lx,%f)", delim, (unsigned long)bci.Rf, *bci.Rf); break;
                case 's': printf("%sRs(0x%lx,\"%s\")", delim, (unsigned long)bci.Rs, bci.Rs); break;
                case 'D': printf("%sRD(0x%lx,..)", delim, (unsigned long)bci.RD); break;
                case 'A': printf("%sRA(0x%lx,....)", delim, (unsigned long)bci.RA); break;
                case 'o': printf("%sRo(0x%lx,\"%s\")", delim, (unsigned long)bci.Ro, bci.Ro); break;
                case 'b': printf("%sRb(0x%lx,%d)", delim, (unsigned long)bci.Rb, *bci.Rb); break;
                case 't': printf("%sRt(0x%lx,%ld)", delim, (unsigned long)bci.Rt, (long)*bci.Rt); break;
                case 'x': printf("%sRx(0x%lx,\"%s\")", delim, (unsigned long)bci.Rx, bci.Rx); break;
                case 'i': printf("%sRi(0x%lx,%d)", delim, (unsigned long)bci.Ri, *bci.Ri); break;
                case 'l': printf("%sRl(0x%lx,%ld)", delim, (unsigned long)bci.Rl, *bci.Rl); break;
                default: printf("\ntypespec:\"%s\"\n", typespec); assert(NOT_REACHED); break;
                }
                break;
            case 'P':
                switch (typespec[2]) {
                case 'f': printf("%sPf(0x%lx,0x%lx,%f)", delim, (unsigned long)bci.Pf, (unsigned long)(bci.Pf ? *bci.Pf : 0), bci.Pf && *bci.Pf ? **bci.Pf : 0.0); break;
                case 's': printf("%sPs(0x%lx,0x%lx,\"%s\")", delim, (unsigned long)bci.Ps, (unsigned long)(bci.Ps ? *bci.Ps : 0), bci.Ps && *bci.Ps ? *bci.Ps : ""); break;
                case 'D': printf("%sPD(0x%lx,0x%lx,..)", delim, (unsigned long)bci.PD, (unsigned long)(bci.PD ? *bci.PD : 0)); break;
                case 'A': printf("%sPA(0x%lx,0x%lx,....)", delim, (unsigned long)bci.PA, (unsigned long)(bci.PA ? *bci.PA : 0)); break;
                case 'o': printf("%sPo(0x%lx,0x%lx,\"%s\")", delim, (unsigned long)bci.Po, (unsigned long)(bci.Po ? *bci.Po : 0), bci.Po && *bci.Po ? *bci.Po : ""); break;
                case 'b': printf("%sPb(0x%lx,0x%lx,%d)", delim, (unsigned long)bci.Pb, (unsigned long)(bci.Pb ? *bci.Pb : 0), bci.Pb && *bci.Pb ? **bci.Pb : 0); break;
                case 't': printf("%sPt(0x%lx,0x%lx,%ld)", delim, (unsigned long)bci.Pt, (unsigned long)(bci.Pt ? *bci.Pt : 0), bci.Pt && *bci.Pt ? (long)**bci.Pt : 0); break;
                case 'x': printf("%sPx(0x%lx,0x%lx,\"%s\")", delim, (unsigned long)bci.Px, (unsigned long)(bci.Px ? *bci.Px : 0), bci.Px && *bci.Px ? *bci.Px : ""); break;
                case 'i': printf("%sPi(0x%lx,0x%lx,%d)", delim, (unsigned long)bci.Pi, (unsigned long)(bci.Pi ? *bci.Pi : 0), bci.Pi && *bci.Pi ? **bci.Pi : 0); break;
                case 'l': printf("%sPl(0x%lx,0x%lx,%ld)", delim, (unsigned long)bci.Pl, (unsigned long)(bci.Pl ? *bci.Pl : 0), bci.Pl && *bci.Pl ? **bci.Pl : 0); break;

                default: printf("\ntypespec:\"%s\"\n", typespec); assert(NOT_REACHED); break;
                }
                break;
            default:
                printf("\ntypespec:\"%s\"\n", typespec); assert(NOT_REACHED);
                break;
            }
        }
        else {
            char *s = bci.s;
            switch (s[0]) {
            case '.':
                end_of_data = (s[1] == '\0');
                break;
            case ':':
                typespec_next = bcon_token(s) == Token_Typespec ? s : 0;
                break;
            }
            printf("%s\"%s\"", delim, s);
        }
        typespec = typespec_next;
        delim = ",";
    }
    putchar('}');
}

Project: mongo-c-driver-legacy
File: encoding.c

static int bson_string_is_db_ref( const unsigned char *string, const size_t length ) {
    int result = 0;

    if( length >= 4 ) {
        if( string[1] == 'r' && string[2] == 'e' && string[3] == 'f' )
            result = 1;
    }
    else if( length >= 3 ) {
        if( string[1] == 'i' && string[2] == 'd' )
            result = 1;
        else if( string[1] == 'd' && string[2] == 'b' )
            result = 1;
    }

    return result;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i ) {
    if ( bson_append_estart( b , BSON_LONG, name, 8 ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append64( b , &i );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *value ) {
    return bson_append_string_base( b, name, value, strlen ( value ), BSON_SYMBOL );
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
    const char *cbuf = buf;
    int flags = 0;

    while ( len ) {
        size_t sent = send( conn->sock, cbuf, len, flags );
        if ( sent == -1 ) {
            __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
            conn->connected = 0;
            return MONGO_ERROR;
        }
        cbuf += sent;
        len -= sent;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

static char *mongo_data_append64( char *start , const void *data ) {
    bson_little_endian64( start , data );
    return start + 8;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, size_t len ) {
    return bson_append_string_base( b, name, value, len, BSON_STRING );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_set_oid_fuzz( int ( *func )( void ) ) {
    oid_fuzz_func = func;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i ) {
    const char *p = bson_iterator_value( i );
    return p + strlen( p ) + 1;

}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_copy( bson *out, const bson *in ) {
    if ( !out || !in ) return BSON_ERROR;
    if ( !in->finished ) return BSON_ERROR;
    bson_init_size( out, bson_size( in ) );
    memcpy( out->data, in->data, bson_size( in ) );
    out->finished = 1;

    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i ) {
    return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
           ? bson_iterator_value( i ) + 9
           : bson_iterator_value( i ) + 5;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t i ) {
    if ( bson_append_estart( b, BSON_BOOL, name, 1 ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append_byte( b , i != 0 );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile )

{
    gfile->gfs = gfs;
    gfile->pos = 0;
    gfile->meta = ( bson * )bson_malloc( sizeof( bson ) );
    if ( gfile->meta == NULL ) return MONGO_ERROR;
    bson_copy( gfile->meta, meta );
    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson *bson_empty( bson *obj ) {
    static char *data = "\005\0\0\0\0";
    bson_init_data( obj, data );
    obj->finished = 1;
    obj->err = 0;
    obj->errstr = NULL;
    obj->stackPos = 0;
    return obj;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_cursor_set_query( mongo_cursor *cursor, const bson *query ) {
    cursor->query = query;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT bson_bool_t mongo_create_simple_index( mongo *conn, const char *ns, const char *field, int options, bson *out ) {
    bson b;
    bson_bool_t success;

    bson_init( &b );
    bson_append_int( &b, field, 1 );
    bson_finish( &b );

    success = mongo_create_index( conn, ns, &b, options, out );
    bson_destroy( &b );
    return success;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *command,
                                    bson *out ) {
    int ret = MONGO_OK;
    bson response = {NULL, 0};
    bson fields;
    size_t sl = strlen( db );
    char *ns = bson_malloc( sl + 5 + 1 ); /* ".$cmd" + nul */
    int res, success = 0;

    strcpy( ns, db );
    strcpy( ns+sl, ".$cmd" );

    res = mongo_find_one( conn, ns, command, bson_empty( &fields ), &response );
    bson_free( ns );

    if( res != MONGO_OK )
        ret = MONGO_ERROR;
    else {
        bson_iterator it;
        if( bson_find( &it, &response, "ok" ) )
            success = bson_iterator_bool( &it );

        if( !success ) {
            conn->err = MONGO_COMMAND_FAILED;
            bson_destroy( &response );
            ret = MONGO_ERROR;
        }
        else {
            if( out )
                *out = response;
            else
                bson_destroy( &response );
        }
    }
    return ret;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *value ) {
    return bson_append_string_base( b, name, value, strlen ( value ), BSON_CODE );
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_replica_set_check_host( mongo *conn ) {

    bson out;
    bson_iterator it;
    bson_bool_t ismaster = 0;
    const char *set_name;
    int max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE;

    out.data = NULL;

    if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) {
        if( bson_find( &it, &out, "ismaster" ) )
            ismaster = bson_iterator_bool( &it );

        if( bson_find( &it, &out, "maxBsonObjectSize" ) )
            max_bson_size = bson_iterator_int( &it );
        conn->max_bson_size = max_bson_size;

        if( bson_find( &it, &out, "setName" ) ) {
            set_name = bson_iterator_string( &it );
            if( strcmp( set_name, conn->replica_set->name ) != 0 ) {
                bson_destroy( &out );
                conn->err = MONGO_CONN_BAD_SET_NAME;
                return MONGO_ERROR;
            }
        }
    }

    bson_destroy( &out );

    if( ismaster ) {
        conn->replica_set->primary_connected = 1;
    }
    else {
        mongo_env_close_socket( conn->sock );
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

static void chunk_free( bson *oChunk ) {
    bson_destroy( oChunk );
    bson_free( oChunk );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) {
    const size_t plen = strlen( pattern )+1;
    const size_t olen = strlen( opts )+1;
    if ( bson_append_estart( b, BSON_REGEX, name, plen + olen ) == BSON_ERROR )
        return BSON_ERROR;
    if ( bson_check_string( b, pattern, plen - 1 ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append( b , pattern , plen );
    bson_append( b , opts , olen );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_set_op_timeout( mongo *conn, int millis ) {
    conn->op_timeout_ms = millis;
    if( conn->sock && conn->connected )
        mongo_env_set_socket_op_timeout( conn, millis );

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

bson_bool_t gridfile_exists( gridfile *gfile ) {
    return ( bson_bool_t )( gfile != NULL && gfile->meta != NULL );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT const bson *mongo_cursor_bson( mongo_cursor *cursor ) {
    return (const bson *)&(cursor->current);
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func ) {
    bson_err_handler old = err_handler;
    err_handler = func;
    return old;
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_read_response( mongo *conn, mongo_reply **reply ) {
    mongo_header head; /* header from network */
    mongo_reply_fields fields; /* header from network */
    mongo_reply *out;  /* native endian */
    unsigned int len;
    int res;

    mongo_env_read_socket( conn, &head, sizeof( head ) );
    mongo_env_read_socket( conn, &fields, sizeof( fields ) );

    bson_little_endian32( &len, &head.len );

    if ( len < sizeof( head )+sizeof( fields ) || len > 64*1024*1024 )
        return MONGO_READ_SIZE_ERROR;  /* most likely corruption */

    out = ( mongo_reply * )bson_malloc( len );

    out->head.len = len;
    bson_little_endian32( &out->head.id, &head.id );
    bson_little_endian32( &out->head.responseTo, &head.responseTo );
    bson_little_endian32( &out->head.op, &head.op );

    bson_little_endian32( &out->fields.flag, &fields.flag );
    bson_little_endian64( &out->fields.cursorID, &fields.cursorID );
    bson_little_endian32( &out->fields.start, &fields.start );
    bson_little_endian32( &out->fields.num, &fields.num );

    res = mongo_env_read_socket( conn, &out->objs, len-sizeof( head )-sizeof( fields ) );
    if( res != MONGO_OK ) {
        bson_free( out );
        return res;
    }

    *reply = out;

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_iterator_init( bson_iterator *i, const bson *b ) {
    i->cur = b->data + 4;
    i->first = 1;
}

Project: mongo-c-driver-legacy
File: bcon.c

static bcon_error_t bson_bcon_key_value(bson *b, const char *key, const char *typespec, const bcon bci) {
    bcon_error_t ret = BCON_OK;
    bson_oid_t oid;
    char ptype = typespec ? typespec[1] : '_';
    char utype = typespec ? typespec[2] : '_';
    switch (ptype) {
    case '_': /* kv(b, key, utype, bci) */
        switch (utype) {
        case '_': /* fall through */
        case 's': bson_append_string( b, key, bci.s ); break; /* common case */
        case 'f': bson_append_double( b, key, bci.f ); break;
        case 'D':
            bson_append_start_object( b, key );
            ret = bson_append_bcon( b, bci.D );
            bson_append_finish_object( b );
            break;
        case 'A':
            bson_append_start_array( b, key );
            ret = bson_append_bcon_array( b, bci.A );
            bson_append_finish_array( b );
            break;
        case 'o': if (*bci.o == '\0') bson_oid_gen( &oid ); else bson_oid_from_string( &oid, bci.o ); bson_append_oid( b, key, &oid ); break;
        case 'b': bson_append_bool( b, key, bci.b ); break;
        case 't': bson_append_time_t( b, key, bci.t ); break;
        case 'v': bson_append_null( b, key ); break; /* void */
        case 'x': bson_append_symbol( b, key, bci.x ); break;
        case 'i': bson_append_int( b, key, bci.i ); break;
        case 'l': bson_append_long( b, key, bci.l ); break;
        default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break;
        }
        break;
    case 'R': /* krv(b, key, utype, bci) */
        switch (utype) {
        case 'f': bson_append_double( b, key, *bci.Rf ); break;
        case 's': bson_append_string( b, key, bci.Rs ); break;
        case 'D':
            bson_append_start_object( b, key );
            ret = bson_append_bcon( b, bci.RD );
            bson_append_finish_object( b );
            break;
        case 'A':
            bson_append_start_array( b, key );
            ret = bson_append_bcon_array( b, bci.RA );
            bson_append_finish_array( b );
            break;
        case 'o': if (*bci.o == '\0') bson_oid_gen( &oid ); else bson_oid_from_string( &oid, bci.o ); bson_append_oid( b, key, &oid ); break;
        case 'b': bson_append_bool( b, key, *bci.Rb ); break;
        case 't': bson_append_time_t( b, key, *bci.Rt ); break;
        case 'x': bson_append_symbol( b, key, bci.Rx ); break;
        case 'i': bson_append_int( b, key, *bci.Ri ); break;
        case 'l': bson_append_long( b, key, *bci.Rl ); break;
        default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break;
        }
        break;
    case 'P': /* kpv(b, key, utype, bci) */
        if (*bci.Pv != 0) {
            switch (utype) {
            case 'f': bson_append_double( b, key, **bci.Pf ); break;
            case 's': bson_append_string( b, key, *bci.Ps ); break;
            case 'D':
                bson_append_start_object( b, key );
                ret = bson_append_bcon( b, *bci.PD );
                bson_append_finish_object( b );
                break;
            case 'A':
                bson_append_start_array( b, key );
                ret = bson_append_bcon_array( b, *bci.PA );
                bson_append_finish_array( b );
                break;
            case 'o': if (**bci.Po == '\0') bson_oid_gen( &oid );
                else bson_oid_from_string( &oid, *bci.Po );
                bson_append_oid( b, key, &oid );
                break;
            case 'b': bson_append_bool( b, key, **bci.Pb ); break;
            case 't': bson_append_time_t( b, key, **bci.Pt ); break;
            case 'x': if (*bci.Px != 0) bson_append_symbol( b, key, *bci.Px ); break;
            case 'i': bson_append_int( b, key, **bci.Pi ); break;
            case 'l': bson_append_long( b, key, **bci.Pl ); break;
            default: printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED); break;
            }
        }
        break;
    default:
        printf("\nptype:'%c' utype:'%c'\n", ptype, utype); assert(NOT_REACHED);
        break;
    }
    return ret;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_start_object( bson *b, const char *name ) {
    if ( bson_append_estart( b, BSON_OBJECT, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
    b->stack[ b->stackPos++ ] = b->cur - b->data;
    bson_append32( b , &zero );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_write_socket( mongo *conn, const void *buf, size_t len ) {
    const char *cbuf = buf;
#ifdef __APPLE__
    int flags = 0;
#else
    int flags = MSG_NOSIGNAL;
#endif

    while ( len ) {
        size_t sent = send( conn->sock, cbuf, len, flags );
        if ( sent == -1 ) {
            if (errno == EPIPE)
                conn->connected = 0;
            __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
            return MONGO_ERROR;
        }
        cbuf += sent;
        len -= sent;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT time_t bson_iterator_time_t( const bson_iterator *i ) {
    return bson_iterator_date( i ) / 1000;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_sock_init( void ) {
    return 0;
}

Project: mongo-c-driver-legacy
File: bson.c

static int bson_append_estart( bson *b, int type, const char *name, const size_t dataSize ) {
    const int len = strlen( name ) + 1;

    if ( b->finished ) {
        b->err |= BSON_ALREADY_FINISHED;
        return BSON_ERROR;
    }

    if ( bson_ensure_space( b, 1 + len + dataSize ) == BSON_ERROR ) {
        return BSON_ERROR;
    }

    if( bson_check_field_name( b, ( const char * )name, len - 1 ) == BSON_ERROR ) {
        bson_builder_error( b );
        return BSON_ERROR;
    }

    bson_append_byte( b, ( char )type );
    bson_append( b, name, len );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT const char *gridfile_get_filename( gridfile *gfile ) {
    bson_iterator it;

    bson_find( &it, gfile->meta, "filename" );
    return bson_iterator_string( &it );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_dispose(mongo* conn) {
    bson_free(conn);
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, size_t len ) {
    if ( type == BSON_BIN_BINARY_OLD ) {
        int subtwolen = len + 4;
        if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+4+len ) == BSON_ERROR )
            return BSON_ERROR;
        bson_append32_as_int( b, ( int )subtwolen );
        bson_append_byte( b, type );
        bson_append32_as_int( b, ( int )len );
        bson_append( b, str, len );
    }
    else {
        if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+len ) == BSON_ERROR )
            return BSON_ERROR;
        bson_append32_as_int( b, ( int )len );
        bson_append_byte( b, type );
        bson_append( b, str, len );
    }
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_replset_init( mongo *conn, const char *name ) {
    bson_errprintf("WARNING: mongo_replset_init() is deprecated, please use mongo_replica_set_init()\n");
    mongo_replica_set_init( conn, name );
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfs_dispose(gridfs* gfs) {
    free(gfs);
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_destroy( bson *b ) {
    if (b) {
        bson_free( b->data );
        b->err = 0;
        b->data = 0;
        b->cur = 0;
        b->finished = 1;
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_write_concern_destroy( mongo_write_concern *write_concern ) {
    if( !write_concern )
        return;

    if( write_concern->cmd )
        bson_destroy( write_concern->cmd );

    bson_free( write_concern->cmd );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i ) {
    size_t ds;

    if ( i->first ) {
        i->first = 0;
        return ( bson_type )( *i->cur );
    }

    switch ( bson_iterator_type( i ) ) {
    case BSON_EOO:
        return BSON_EOO; /* don't advance */
    case BSON_UNDEFINED:
    case BSON_NULL:
        ds = 0;
        break;
    case BSON_BOOL:
        ds = 1;
        break;
    case BSON_INT:
        ds = 4;
        break;
    case BSON_LONG:
    case BSON_DOUBLE:
    case BSON_TIMESTAMP:
    case BSON_DATE:
        ds = 8;
        break;
    case BSON_OID:
        ds = 12;
        break;
    case BSON_STRING:
    case BSON_SYMBOL:
    case BSON_CODE:
        ds = 4 + bson_iterator_int_raw( i );
        break;
    case BSON_BINDATA:
        ds = 5 + bson_iterator_int_raw( i );
        break;
    case BSON_OBJECT:
    case BSON_ARRAY:
    case BSON_CODEWSCOPE:
        ds = bson_iterator_int_raw( i );
        break;
    case BSON_DBREF:
        ds = 4+12 + bson_iterator_int_raw( i );
        break;
    case BSON_REGEX: {
        const char *s = bson_iterator_value( i );
        const char *p = s;
        p += strlen( p )+1;
        p += strlen( p )+1;
        ds = p-s;
        break;
    }

    default: {
        char msg[] = "unknown type: 000000000000";
        bson_numstr( msg+14, ( unsigned )( i->cur[0] ) );
        bson_fatal_msg( 0, msg );
        return 0;
    }
    }

    i->cur += 1 + strlen( i->cur + 1 ) + 1 + ds;

    return ( bson_type )( *i->cur );
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_check_is_master( mongo *conn ) {
    bson out;
    bson_iterator it;
    bson_bool_t ismaster = 0;
    int max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE;

    out.data = NULL;

    if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) {
        if( bson_find( &it, &out, "ismaster" ) )
            ismaster = bson_iterator_bool( &it );
        if( bson_find( &it, &out, "maxBsonObjectSize" ) ) {
            max_bson_size = bson_iterator_int( &it );
        }
        conn->max_bson_size = max_bson_size;
    }
    else {
        return MONGO_ERROR;
    }

    bson_destroy( &out );

    if( ismaster )
        return MONGO_OK;
    else {
        conn->err = MONGO_CONN_NOT_MASTER;
        return MONGO_ERROR;
    }
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_set_write_concern( mongo *conn,
        mongo_write_concern *write_concern ) {

    conn->write_concern = write_concern;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_iterator* bson_iterator_create( void ) {
    return ( bson_iterator* )malloc( sizeof( bson_iterator ) );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ) {
    bson from_db;
    bson cmd;
    const char *nonce;
    int result;

    mongo_md5_state_t st;
    mongo_md5_byte_t digest[16];
    char hex_digest[33];

    if( mongo_simple_int_command( conn, db, "getnonce", 1, &from_db ) == MONGO_OK ) {
        bson_iterator it;
        bson_find( &it, &from_db, "nonce" );
        nonce = bson_iterator_string( &it );
    }
    else {
        return MONGO_ERROR;
    }

    mongo_pass_digest( user, pass, hex_digest );

    mongo_md5_init( &st );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )nonce, ( int )strlen( nonce ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )user, ( int )strlen( user ) );
    mongo_md5_append( &st, ( const mongo_md5_byte_t * )hex_digest, 32 );
    mongo_md5_finish( &st, digest );
    digest2hex( digest, hex_digest );

    bson_init( &cmd );
    bson_append_int( &cmd, "authenticate", 1 );
    bson_append_string( &cmd, "user", user );
    bson_append_string( &cmd, "nonce", nonce );
    bson_append_string( &cmd, "key", hex_digest );
    bson_finish( &cmd );

    bson_destroy( &from_db );

    result = mongo_run_command( conn, db, &cmd, NULL );

    bson_destroy( &cmd );

    return result;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson* bson_create( void ) {
    return (bson*)bson_malloc(sizeof(bson));
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) {
    bson_iterator_init( it, (bson *)obj );
    while( bson_iterator_next( it ) ) {
        if ( strcmp( name, bson_iterator_key( it ) ) == 0 )
            break;
    }
    return bson_iterator_type( it );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_replset_add_seed( mongo *conn, const char *host, int port ) {
    bson_errprintf("WARNING: mongo_replset_add_seed() is deprecated, please use mongo_replica_set_add_seed()\n");
    mongo_replica_set_add_node( &conn->replica_set->seeds, host, port );
}

Project: mongo-c-driver-legacy
File: mongo.c

static void mongo_set_last_error( mongo *conn, bson_iterator *it, bson *obj ) {
    int result_len = bson_iterator_string_len( it );
    const char *result_string = bson_iterator_string( it );
    int len = result_len < MONGO_ERR_LEN ? result_len : MONGO_ERR_LEN;
    memcpy( conn->lasterrstr, result_string, len );

    if( bson_find( it, obj, "code" ) != BSON_NULL )
        conn->lasterrcode = bson_iterator_int( it );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_create_index( mongo *conn, const char *ns, const bson *key, int options, bson *out ) {
    bson b;
    bson_iterator it;
    char name[255] = {'_'};
    int i = 1;
    char idxns[1024];

    bson_iterator_init( &it, key );
    while( i < 255 && bson_iterator_next( &it ) ) {
        strncpy( name + i, bson_iterator_key( &it ), 255 - i );
        i += strlen( bson_iterator_key( &it ) );
    }
    name[254] = '\0';

    bson_init( &b );
    bson_append_bson( &b, "key", key );
    bson_append_string( &b, "ns", ns );
    bson_append_string( &b, "name", name );
    if ( options & MONGO_INDEX_UNIQUE )
        bson_append_bool( &b, "unique", 1 );
    if ( options & MONGO_INDEX_DROP_DUPS )
        bson_append_bool( &b, "dropDups", 1 );
    if ( options & MONGO_INDEX_BACKGROUND )
        bson_append_bool( &b, "background", 1 );
    if ( options & MONGO_INDEX_SPARSE )
        bson_append_bool( &b, "sparse", 1 );
    bson_finish( &b );

    strncpy( idxns, ns, 1024-16 );
    strcpy( strchr( idxns, '.' ), ".system.indexes" );
    mongo_insert( conn, idxns, &b, NULL );
    bson_destroy( &b );

    *strchr( idxns, '.' ) = '\0'; /* just db not ns */
    return mongo_cmd_get_last_error( conn, idxns, out );
}

Project: mongo-c-driver-legacy
File: mongo.c

static mongo_message *mongo_message_create( size_t len , int id , int responseTo , int op ) {
    mongo_message *mm = ( mongo_message * )bson_malloc( len );

    if ( !id )
        id = rand();

    /* native endian (converted on send) */
    mm->head.len = ( int )len;
    mm->head.id = id;
    mm->head.responseTo = responseTo;
    mm->head.op = op;

    return mm;
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_cmd_get_error_helper( mongo *conn, const char *db,
                                       bson *realout, const char *cmdtype ) {

    bson out = {NULL,0};
    bson_bool_t haserror = 0;

    /* Reset last error codes. */
    mongo_clear_errors( conn );

    /* If there's an error, store its code and string in the connection object. */
    if( mongo_simple_int_command( conn, db, cmdtype, 1, &out ) == MONGO_OK ) {
        bson_iterator it;
        haserror = ( bson_find( &it, &out, "err" ) != BSON_NULL );
        if( haserror ) mongo_set_last_error( conn, &it, &out );
    }

    if( realout )
        *realout = out; /* transfer of ownership */
    else
        bson_destroy( &out );

    if( haserror )
        return MONGO_ERROR;
    else
        return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: encoding.c

int bson_check_field_name( bson *b, const char *string,
                           const size_t length ) {

    return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_iterator_subobject( const bson_iterator *i, bson *sub ) {
    bson_init_data( sub, ( char * )bson_iterator_value( i ) );
    _bson_reset( sub );
    sub->finished = 1;
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_cursor_bson_valid( mongo_cursor *cursor, const bson *bson ) {
    if( ! bson->finished ) {
        cursor->err = MONGO_CURSOR_BSON_ERROR;
        cursor->conn->err = MONGO_BSON_NOT_FINISHED;
        return MONGO_ERROR;
    }

    if( bson->err & BSON_NOT_UTF8 ) {
        cursor->err = MONGO_CURSOR_BSON_ERROR;
        cursor->conn->err = MONGO_BSON_INVALID;
        return MONGO_ERROR;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d ) {
    if ( bson_append_estart( b, BSON_DOUBLE, name, 8 ) == BSON_ERROR )
        return BSON_ERROR;
    bson_append64( b , &d );
    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT const char* mongo_get_host(mongo* conn, int i) {
    mongo_replica_set* r = conn->replica_set;
    mongo_host_port* hp;
    int count = 0;
    if (!r) return 0;
    for (hp = r->hosts; hp; hp = hp->next) {
        if (count == i)
            return _get_host_port(hp);
        ++count;
    }
    return 0;
}

Project: mongo-c-driver-legacy
File: bson.c

static void bson_append64( bson *b, const void *data ) {
    bson_little_endian64( b->cur, data );
    b->cur += 8;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT double bson_iterator_double( const bson_iterator *i ) {
    switch ( bson_iterator_type( i ) ) {
    case BSON_INT:
        return bson_iterator_int_raw( i );
    case BSON_LONG:
        return bson_iterator_long_raw( i );
    case BSON_DOUBLE:
        return bson_iterator_double_raw( i );
    default:
        return 0;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i ) {
    switch ( bson_iterator_type( i ) ) {
    case BSON_INT:
        return bson_iterator_int_raw( i );
    case BSON_LONG:
        return bson_iterator_long_raw( i );
    case BSON_DOUBLE:
        return bson_iterator_double_raw( i );
    default:
        return 0;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

int bson_iterator_int_raw( const bson_iterator *i ) {
    int out;
    bson_little_endian32( &out, bson_iterator_value( i ) );
    return out;
}

Project: mongo-c-driver-legacy
File: gridfs.c

int gridfs_init( mongo *client, const char *dbname, const char *prefix,
                 gridfs *gfs ) {

    int options;
    bson b;
    bson_bool_t success;

    gfs->client = client;

    /* Allocate space to own the dbname */
    gfs->dbname = ( const char * )bson_malloc( strlen( dbname )+1 );
    strcpy( ( char * )gfs->dbname, dbname );

    /* Allocate space to own the prefix */
    if ( prefix == NULL ) prefix = "fs";
    gfs->prefix = ( const char * )bson_malloc( strlen( prefix )+1 );
    strcpy( ( char * )gfs->prefix, prefix );

    /* Allocate space to own files_ns */
    gfs->files_ns =
        ( const char * ) bson_malloc ( strlen( prefix )+strlen( dbname )+strlen( ".files" )+2 );
    strcpy( ( char * )gfs->files_ns, dbname );
    strcat( ( char * )gfs->files_ns, "." );
    strcat( ( char * )gfs->files_ns, prefix );
    strcat( ( char * )gfs->files_ns, ".files" );

    /* Allocate space to own chunks_ns */
    gfs->chunks_ns = ( const char * ) bson_malloc( strlen( prefix ) + strlen( dbname )
                     + strlen( ".chunks" ) + 2 );
    strcpy( ( char * )gfs->chunks_ns, dbname );
    strcat( ( char * )gfs->chunks_ns, "." );
    strcat( ( char * )gfs->chunks_ns, prefix );
    strcat( ( char * )gfs->chunks_ns, ".chunks" );

    bson_init( &b );
    bson_append_int( &b, "filename", 1 );
    bson_finish( &b );
    options = 0;
    success = ( mongo_create_index( gfs->client, gfs->files_ns, &b, options, NULL ) == MONGO_OK );
    bson_destroy( &b );
    if ( !success ) {
        bson_free( ( char * )gfs->dbname );
        bson_free( ( char * )gfs->prefix );
        bson_free( ( char * )gfs->files_ns );
        bson_free( ( char * )gfs->chunks_ns );
        return MONGO_ERROR;
    }

    bson_init( &b );
    bson_append_int( &b, "files_id", 1 );
    bson_append_int( &b, "n", 1 );
    bson_finish( &b );
    options = MONGO_INDEX_UNIQUE;
    success = ( mongo_create_index( gfs->client, gfs->chunks_ns, &b, options, NULL ) == MONGO_OK );
    bson_destroy( &b );
    if ( !success ) {
        bson_free( ( char * )gfs->dbname );
        bson_free( ( char * )gfs->prefix );
        bson_free( ( char * )gfs->files_ns );
        bson_free( ( char * )gfs->chunks_ns );
        return MONGO_ERROR;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT int gridfile_get_chunksize( gridfile *gfile ) {
    bson_iterator it;

    bson_find( &it, gfile->meta, "chunkSize" );
    return bson_iterator_int( &it );
}

Project: mongo-c-driver-legacy
File: gridfs.c

static bson *chunk_new( bson_oid_t id, int chunkNumber,
                        const char *data, int len ) {
    bson *b = bson_malloc( sizeof( bson ) );

    bson_init( b );
    bson_append_oid( b, "files_id", &id );
    bson_append_int( b, "n", chunkNumber );
    bson_append_binary( b, "data", BSON_BIN_BINARY, data, len );
    bson_finish( b );
    return  b;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) {
    if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;

    bson_append32( b , &( ts->i ) );
    bson_append32( b , &( ts->t ) );

    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, size_t len ) {
    return bson_append_string_base( b, name, value, len, BSON_CODE );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_find_one( mongo *conn, const char *ns, const bson *query,
                                 const bson *fields, bson *out ) {

    mongo_cursor cursor[1];
    mongo_cursor_init( cursor, conn, ns );
    mongo_cursor_set_query( cursor, query );
    mongo_cursor_set_fields( cursor, fields );
    mongo_cursor_set_limit( cursor, 1 );

    if ( mongo_cursor_next( cursor ) == MONGO_OK ) {
        if( out ) {
            bson_init_size( out, bson_size( (bson *)&cursor->current ) );
            memcpy( out->data, cursor->current.data,
                    bson_size( (bson *)&cursor->current ) );
            out->finished = 1;
        }
        mongo_cursor_destroy( cursor );
        return MONGO_OK;
    }
    else {
        mongo_cursor_destroy( cursor );
        return MONGO_ERROR;
    }
}

Project: mongo-c-driver-legacy
File: encoding.c

static int bson_validate_string( bson *b, const unsigned char *string,
                                 const size_t length, const char check_utf8, const char check_dot,
                                 const char check_dollar ) {

    size_t position = 0;
    int sequence_length = 1;

    if( check_dollar && string[0] == '$' ) {
        if( !bson_string_is_db_ref( string, length ) )
            b->err |= BSON_FIELD_INIT_DOLLAR;
    }

    while ( position < length ) {
        if ( check_dot && *( string + position ) == '.' ) {
            b->err |= BSON_FIELD_HAS_DOT;
        }

        if ( check_utf8 ) {
            sequence_length = trailingBytesForUTF8[*( string + position )] + 1;
            if ( ( position + sequence_length ) > length ) {
                b->err |= BSON_NOT_UTF8;
                return BSON_ERROR;
            }
            if ( !isLegalUTF8( string + position, sequence_length ) ) {
                b->err |= BSON_NOT_UTF8;
                return BSON_ERROR;
            }
        }
        position += sequence_length;
    }

    return BSON_OK;
}

Project: mongo-c-driver-legacy
File: env.c

MONGO_EXPORT int mongo_env_sock_init( void ) {

    WSADATA wsaData;
    WORD wVers;
    static int called_once;
    static int retval;

    if (called_once) return retval;

    called_once = 1;
    wVers = MAKEWORD(1, 1);
    retval = (WSAStartup(wVers, &wsaData) == 0);

    return retval;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
    struct timeval tv;
    tv.tv_sec = millis / 1000;
    tv.tv_usec = ( millis % 1000 ) * 1000;

    if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) {
        conn->err = MONGO_IO_ERROR;
        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.", errno );
        return MONGO_ERROR;
    }

    if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) {
        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.", errno );
        return MONGO_ERROR;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_reconnect( mongo *conn ) {
    int res;
    mongo_disconnect( conn );

    if( conn->replica_set ) {
        conn->replica_set->primary_connected = 0;
        mongo_replica_set_free_list( &conn->replica_set->hosts );
        conn->replica_set->hosts = NULL;
        res = mongo_replica_set_client( conn );
        return res;
    }
    else
        return mongo_env_socket_connect( conn, conn->primary->host, conn->primary->port );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT mongo* mongo_create( void ) {
    return (mongo*)bson_malloc(sizeof(mongo));
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_disconnect( mongo *conn ) {
    if( ! conn->connected )
        return;

    if( conn->replica_set ) {
        conn->replica_set->primary_connected = 0;
        mongo_replica_set_free_list( &conn->replica_set->hosts );
        conn->replica_set->hosts = NULL;
    }

    mongo_env_close_socket( conn->sock );

    conn->sock = 0;
    conn->connected = 0;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_dispose(bson* b) {
    bson_free(b);
}

Project: mongo-c-driver-legacy
File: gridfs.c

int gridfs_find_query( gridfs *gfs, bson *query,
                       gridfile *gfile ) {

    bson uploadDate;
    bson finalQuery;
    bson out;
    int i;

    bson_init( &uploadDate );
    bson_append_int( &uploadDate, "uploadDate", -1 );
    bson_finish( &uploadDate );

    bson_init( &finalQuery );
    bson_append_bson( &finalQuery, "query", query );
    bson_append_bson( &finalQuery, "orderby", &uploadDate );
    bson_finish( &finalQuery );

    i = ( mongo_find_one( gfs->client, gfs->files_ns,
                          &finalQuery, NULL, &out ) == MONGO_OK );
    bson_destroy( &uploadDate );
    bson_destroy( &finalQuery );
    if ( !i )
        return MONGO_ERROR;
    else {
        gridfile_init( gfs, &out, gfile );
        bson_destroy( &out );
        return MONGO_OK;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i ) {
    return *( i->cur );
}

Project: mongo-c-driver-legacy
File: bson.c

static void _bson_reset( bson *b ) {
    b->finished = 0;
    b->stackPos = 0;
    b->err = 0;
    b->errstr = NULL;
}

Project: mongo-c-driver-legacy
File: bson.c

int bson_iterator_string_len( const bson_iterator *i ) {
    return bson_iterator_int_raw( i );
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfile_write_buffer( gridfile *gfile, const char *data,
        gridfs_offset length ) {

    size_t bytes_left = 0;
    size_t data_partial_len = 0;
    size_t chunks_to_write = 0;
    char *buffer;
    bson *oChunk;
    gridfs_offset to_write = length + gfile->pending_len;

    if ( to_write < DEFAULT_CHUNK_SIZE ) { /* Less than one chunk to write */
        if( gfile->pending_data ) {
            gfile->pending_data = ( char * )bson_realloc( ( void * )gfile->pending_data, gfile->pending_len + to_write );
            memcpy( gfile->pending_data + gfile->pending_len, data, length );
        }
        else if ( to_write > 0 ) {
            gfile->pending_data = ( char * )bson_malloc( to_write );
            memcpy( gfile->pending_data, data, length );
        }
        gfile->pending_len += length;

    }
    else {   /* At least one chunk of data to write */
        chunks_to_write = to_write / DEFAULT_CHUNK_SIZE;
        bytes_left = to_write % DEFAULT_CHUNK_SIZE;

        /* If there's a pending chunk to be written, we need to combine
         * the buffer provided up to DEFAULT_CHUNK_SIZE.
         */
        if ( gfile->pending_len > 0 ) {
            data_partial_len = DEFAULT_CHUNK_SIZE - gfile->pending_len;
            buffer = ( char * )bson_malloc( DEFAULT_CHUNK_SIZE );
            memcpy( buffer, gfile->pending_data, gfile->pending_len );
            memcpy( buffer + gfile->pending_len, data, data_partial_len );

            oChunk = chunk_new( gfile->id, gfile->chunk_num, buffer, DEFAULT_CHUNK_SIZE );
            mongo_insert( gfile->gfs->client, gfile->gfs->chunks_ns, oChunk, NULL );
            chunk_free( oChunk );
            gfile->chunk_num++;
            gfile->length += DEFAULT_CHUNK_SIZE;
            data += data_partial_len;

            chunks_to_write--;

            bson_free( buffer );
        }

        while( chunks_to_write > 0 ) {
            oChunk = chunk_new( gfile->id, gfile->chunk_num, data, DEFAULT_CHUNK_SIZE );
            mongo_insert( gfile->gfs->client, gfile->gfs->chunks_ns, oChunk, NULL );
            chunk_free( oChunk );
            gfile->chunk_num++;
            chunks_to_write--;
            gfile->length += DEFAULT_CHUNK_SIZE;
            data += DEFAULT_CHUNK_SIZE;
        }

        bson_free( gfile->pending_data );

        /* If there are any leftover bytes, store them as pending data. */
        if( bytes_left == 0 )
            gfile->pending_data = NULL;
        else {
            gfile->pending_data = ( char * )bson_malloc( bytes_left );
            memcpy( gfile->pending_data, data, bytes_left );
        }

        gfile->pending_len = bytes_left;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

static void bson_append32_as_int( bson *b, int data ) {
    bson_little_endian32( b->cur, &data );
    b->cur += 4;
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT mongo_cursor* mongo_cursor_create( void ) {
    return (mongo_cursor*)bson_malloc(sizeof(mongo_cursor));
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT void mongo_init_sockets( void ) {
    mongo_env_sock_init();
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_close_socket( int socket ) {
#ifdef _WIN32
    return closesocket( socket );
#else
    return close( socket );
#endif
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_replset_connect( mongo *conn ) {
    int ret;
    bson_errprintf("WARNING: mongo_replset_connect() is deprecated, please use mongo_replica_set_client()\n");
    ret = mongo_replica_set_client( conn );
    mongo_set_write_concern( conn, 0 );
    return ret;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i ) {
    return bson_iterator_long_raw( i );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int mongo_cmd_drop_db( mongo *conn, const char *db ) {
    return mongo_simple_int_command( conn, db, "dropDatabase", 1, NULL );
}

Project: mongo-c-driver-legacy
File: mongo.c

MONGO_EXPORT int  mongo_get_server_err(mongo* conn) {
    return conn->lasterrcode;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) {
    mongo_cursor *chunks;
    bson chunk;

    size_t first_chunk;
    size_t last_chunk;
    size_t total_chunks;
    gridfs_offset chunksize;
    gridfs_offset contentlength;
    gridfs_offset bytes_left;
    int i;
    bson_iterator it;
    gridfs_offset chunk_len;
    const char *chunk_data;

    contentlength = gridfile_get_contentlength( gfile );
    chunksize = gridfile_get_chunksize( gfile );
    size = ( contentlength - gfile->pos < size )
           ? contentlength - gfile->pos
           : size;
    bytes_left = size;

    first_chunk = ( gfile->pos )/chunksize;
    last_chunk = ( gfile->pos+size-1 )/chunksize;
    total_chunks = last_chunk - first_chunk + 1;
    chunks = gridfile_get_chunks( gfile, first_chunk, total_chunks );

    for ( i = 0; i < total_chunks; i++ ) {
        mongo_cursor_next( chunks );
        chunk = chunks->current;
        bson_find( &it, &chunk, "data" );
        chunk_len = bson_iterator_bin_len( &it );
        chunk_data = bson_iterator_bin_data( &it );
        if ( i == 0 ) {
            chunk_data += ( gfile->pos )%chunksize;
            chunk_len -= ( gfile->pos )%chunksize;
        }
        if ( bytes_left > chunk_len ) {
            memcpy( buf, chunk_data, chunk_len );
            bytes_left -= chunk_len;
            buf += chunk_len;
        }
        else {
            memcpy( buf, chunk_data, bytes_left );
        }
    }

    mongo_cursor_destroy( chunks );
    gfile->pos = gfile->pos + size;

    return size;
}

Project: mongo-c-driver-legacy
File: gridfs.c

MONGO_EXPORT void gridfs_destroy( gridfs *gfs ) {
    if ( gfs == NULL ) return;
    if ( gfs->dbname ) bson_free( ( char * )gfs->dbname );
    if ( gfs->prefix ) bson_free( ( char * )gfs->prefix );
    if ( gfs->files_ns ) bson_free( ( char * )gfs->files_ns );
    if ( gfs->chunks_ns ) bson_free( ( char * )gfs->chunks_ns );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i ) {
    return ( bson_type )i->cur[0];
}

Project: mongo-c-driver-legacy
File: mongo.c

static int mongo_cursor_op_query( mongo_cursor *cursor ) {
    int res;
    bson empty;
    char *data;
    mongo_message *mm;
    bson temp;
    bson_iterator it;

    /* Clear any errors. */
    mongo_clear_errors( cursor->conn );

    /* Set up default values for query and fields, if necessary. */
    if( ! cursor->query )
        cursor->query = bson_empty( &empty );
    else if( mongo_cursor_bson_valid( cursor, cursor->query ) != MONGO_OK )
        return MONGO_ERROR;

    if( ! cursor->fields )
        cursor->fields = bson_empty( &empty );
    else if( mongo_cursor_bson_valid( cursor, cursor->fields ) != MONGO_OK )
        return MONGO_ERROR;

    mm = mongo_message_create( 16 + /* header */
                               4 + /*  options */
                               strlen( cursor->ns ) + 1 + /* ns */
                               4 + 4 + /* skip,return */
                               bson_size( cursor->query ) +
                               bson_size( cursor->fields ) ,
                               0 , 0 , MONGO_OP_QUERY );

    data = &mm->data;
    data = mongo_data_append32( data , &cursor->options );
    data = mongo_data_append( data , cursor->ns , strlen( cursor->ns ) + 1 );
    data = mongo_data_append32( data , &cursor->skip );
    data = mongo_data_append32( data , &cursor->limit );
    data = mongo_data_append( data , cursor->query->data , bson_size( cursor->query ) );
    if ( cursor->fields )
        data = mongo_data_append( data , cursor->fields->data , bson_size( cursor->fields ) );

    bson_fatal_msg( ( data == ( ( char * )mm ) + mm->head.len ), "query building fail!" );

    res = mongo_message_send( cursor->conn , mm );
    if( res != MONGO_OK ) {
        return MONGO_ERROR;
    }

    res = mongo_read_response( cursor->conn, ( mongo_reply ** )&( cursor->reply ) );
    if( res != MONGO_OK ) {
        return MONGO_ERROR;
    }

    if( cursor->reply->fields.num == 1 ) {
        bson_init_data( &temp, &cursor->reply->objs );
        if( bson_find( &it, &temp, "$err" ) ) {
            mongo_set_last_error( cursor->conn, &it, &temp );
            cursor->err = MONGO_CURSOR_QUERY_FAIL;
            return MONGO_ERROR;
        }
    }

    cursor->seen += cursor->reply->fields.num;
    cursor->flags |= MONGO_CURSOR_QUERY_SENT;
    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: env.c

int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
    char port_str[NI_MAXSERV];
    int status;

    struct addrinfo ai_hints;
    struct addrinfo *ai_list = NULL;
    struct addrinfo *ai_ptr = NULL;

    if ( port < 0 ) {
        return mongo_env_unix_socket_connect( conn, host );
    }

    conn->sock = 0;
    conn->connected = 0;
    sprintf(port_str,"%d",port);

    bson_sprintf( port_str, "%d", port );

    memset( &ai_hints, 0, sizeof( ai_hints ) );
#ifdef AI_ADDRCONFIG
    ai_hints.ai_flags = AI_ADDRCONFIG;
#endif
    ai_hints.ai_family = AF_UNSPEC;
    ai_hints.ai_socktype = SOCK_STREAM;

    status = getaddrinfo( host, port_str, &ai_hints, &ai_list );
    if ( status != 0 ) {
        bson_errprintf( "getaddrinfo failed: %s", gai_strerror( status ) );
        conn->err = MONGO_CONN_ADDR_FAIL;
        return MONGO_ERROR;
    }

    for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) {
        conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol );
        if ( conn->sock < 0 ) {
            conn->sock = 0;
            continue;
        }

        status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen );
        if ( status != 0 ) {
            mongo_env_close_socket( conn->sock );
            conn->sock = 0;
            continue;
        }
#if __APPLE__
        {
            int flag = 1;
            setsockopt( conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
                       ( void * ) &flag, sizeof( flag ) );
        }
#endif

        if ( ai_ptr->ai_protocol == IPPROTO_TCP ) {
            int flag = 1;

            setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY,
                        ( void * ) &flag, sizeof( flag ) );
            if ( conn->op_timeout_ms > 0 )
                mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
        }

        conn->connected = 1;
        break;
    }

    freeaddrinfo( ai_list );

    if ( ! conn->connected ) {
        conn->err = MONGO_CONN_FAIL;
        return MONGO_ERROR;
    }

    return MONGO_OK;
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ) {
    bson_iterator_from_buffer( sub, bson_iterator_value( i ) );
}

Project: mongo-c-driver-legacy
File: bcon.c

bcon_error_t bson_from_bcon(bson *b, const bcon *bc) {
    bcon_error_t ret = BSON_OK;
    bson_init( b );
    ret = bson_append_bcon_with_state( b, bc, State_Element );
    if (ret != BCON_OK) return ret;
    ret = bson_finish( b );
    return ( ret == BSON_OK ? BCON_OK : BCON_BSON_ERROR );
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i ) {
    switch ( bson_iterator_type( i ) ) {
    case BSON_BOOL:
        return bson_iterator_bool_raw( i );
    case BSON_INT:
        return bson_iterator_int_raw( i ) != 0;
    case BSON_LONG:
        return bson_iterator_long_raw( i ) != 0;
    case BSON_DOUBLE:
        return bson_iterator_double_raw( i ) != 0;
    case BSON_EOO:
    case BSON_NULL:
        return 0;
    default:
        return 1;
    }
}

Project: mongo-c-driver-legacy
File: bson.c

MONGO_EXPORT int bson_size( const bson *b ) {
    int i;
    if ( ! b || ! b->data )
        return 0;
    bson_little_endian32( &i, b->data );
    return i;
}