/* Resize the ber buffer */ int ber_realloc( BerElement *ber, ber_len_t len ) { ber_len_t total, offset, sos_offset; char *buf; assert( ber != NULL ); assert( LBER_VALID( ber ) ); /* leave room for ber_flatten() to \0-terminate ber_buf */ if ( ++len == 0 ) { return( -1 ); } total = ber_pvt_ber_total( ber ); #define LBER_EXBUFSIZ 4060 /* a few words less than 2^N for binary buddy */ #if defined( LBER_EXBUFSIZ ) && LBER_EXBUFSIZ > 0 # ifndef notdef /* don't realloc by small amounts */ total += len < LBER_EXBUFSIZ ? LBER_EXBUFSIZ : len; # else { /* not sure what value this adds. reduce fragmentation? */ ber_len_t have = (total + (LBER_EXBUFSIZE - 1)) / LBER_EXBUFSIZ; ber_len_t need = (len + (LBER_EXBUFSIZ - 1)) / LBER_EXBUFSIZ; total = ( have + need ) * LBER_EXBUFSIZ; } # endif #else total += len; /* realloc just what's needed */ #endif if ( total < len || total > (ber_len_t)-1 / 2 /* max ber_slen_t */ ) { return( -1 ); } buf = ber->ber_buf; offset = ber->ber_ptr - buf; sos_offset = ber->ber_sos_ptr ? ber->ber_sos_ptr - buf : 0; /* if ber_sos_ptr != NULL, it is > ber_buf so that sos_offset > 0 */ buf = (char *) ber_memrealloc_x( buf, total, ber->ber_memctx ); if ( buf == NULL ) { return( -1 ); } ber->ber_buf = buf; ber->ber_end = buf + total; ber->ber_ptr = buf + offset; if ( sos_offset ) ber->ber_sos_ptr = buf + sos_offset; return( 0 ); }
int ber_get_option( void *item, int option, void *outvalue) { const BerElement *ber; const Sockbuf *sb; if(outvalue == NULL) { /* no place to get to */ ber_errno = LBER_ERROR_PARAM; return LBER_OPT_ERROR; } if(item == NULL) { switch ( option ) { case LBER_OPT_BER_DEBUG: * (int *) outvalue = ber_int_debug; return LBER_OPT_SUCCESS; case LBER_OPT_MEMORY_INUSE: /* The memory inuse is a global variable on kernal implementations. * This means that memory debug is shared by all LDAP processes * so for this variable to have much meaning, only one LDAP process * should be running and memory inuse should be initialized to zero * using the lber_set_option() function during startup. * The counter is not accurate for multithreaded ldap applications. */ #ifdef LDAP_MEMORY_DEBUG * (int *) outvalue = ber_int_meminuse; return LBER_OPT_SUCCESS; #else return LBER_OPT_ERROR; #endif case LBER_OPT_LOG_PRINT_FILE: *((FILE**)outvalue) = (FILE*)ber_pvt_err_file; return LBER_OPT_SUCCESS; } ber_errno = LBER_ERROR_PARAM; return LBER_OPT_ERROR; } ber = item; sb = item; switch(option) { case LBER_OPT_BER_OPTIONS: assert( LBER_VALID( ber ) ); * (int *) outvalue = ber->ber_options; return LBER_OPT_SUCCESS; case LBER_OPT_BER_DEBUG: assert( LBER_VALID( ber ) ); * (int *) outvalue = ber->ber_debug; return LBER_OPT_SUCCESS; case LBER_OPT_BER_REMAINING_BYTES: assert( LBER_VALID( ber ) ); *((ber_len_t *) outvalue) = ber_pvt_ber_remaining(ber); return LBER_OPT_SUCCESS; case LBER_OPT_BER_TOTAL_BYTES: assert( LBER_VALID( ber ) ); *((ber_len_t *) outvalue) = ber_pvt_ber_total(ber); return LBER_OPT_SUCCESS; case LBER_OPT_BER_BYTES_TO_WRITE: assert( LBER_VALID( ber ) ); *((ber_len_t *) outvalue) = ber_pvt_ber_write(ber); return LBER_OPT_SUCCESS; case LBER_OPT_BER_MEMCTX: assert( LBER_VALID( ber ) ); *((void **) outvalue) = ber->ber_memctx; return LBER_OPT_SUCCESS; default: /* bad param */ ber_errno = LBER_ERROR_PARAM; break; } return LBER_OPT_ERROR; }
int ber_realloc( BerElement *ber, ber_len_t len ) { ber_len_t total; Seqorset *s; long off; char *oldbuf; assert( ber != NULL ); assert( len > 0 ); assert( LBER_VALID( ber ) ); total = ber_pvt_ber_total( ber ); #define LBER_EXBUFSIZ 4060 /* a few words less than 2^N for binary buddy */ #if defined( LBER_EXBUFSIZ ) && LBER_EXBUFSIZ > 0 # ifndef notdef /* don't realloc by small amounts */ total += len < LBER_EXBUFSIZ ? LBER_EXBUFSIZ : len; # else { /* not sure what value this adds */ ber_len_t have = (total + (LBER_EXBUFSIZE - 1)) / LBER_EXBUFSIZ; ber_len_t need = (len + (LBER_EXBUFSIZ - 1)) / LBER_EXBUFSIZ; total = ( have + need ) * LBER_EXBUFSIZ; } # endif #else total += len; /* realloc just what's needed */ #endif oldbuf = ber->ber_buf; ber->ber_buf = (char *) ber_memrealloc_x( oldbuf, total, ber->ber_memctx ); if ( ber->ber_buf == NULL ) { ber->ber_buf = oldbuf; return( -1 ); } ber->ber_end = ber->ber_buf + total; /* * If the stinking thing was moved, we need to go through and * reset all the sos and ber pointers. Offsets would've been * a better idea... oh well. */ if ( ber->ber_buf != oldbuf ) { ber->ber_ptr = ber->ber_buf + (ber->ber_ptr - oldbuf); for ( s = ber->ber_sos; s != NULL; s = s->sos_next ) { off = s->sos_first - oldbuf; s->sos_first = ber->ber_buf + off; off = s->sos_ptr - oldbuf; s->sos_ptr = ber->ber_buf + off; } } return( 0 ); }