Commit 445a4766 authored by Howard Chu's avatar Howard Chu
Browse files

Added ber_get_stringbv

parent ac39aa50
......@@ -132,8 +132,8 @@ typedef struct lber_memory_fns {
#define LBER_SB_OPT_DRAIN 10
#define LBER_SB_OPT_NEEDS_READ 11
#define LBER_SB_OPT_NEEDS_WRITE 12
#define LBER_SB_OPT_GET_MAX_INCOMING 13
#define LBER_SB_OPT_SET_MAX_INCOMING 14
#define LBER_SB_OPT_GET_MAX_INCOMING 13
#define LBER_SB_OPT_SET_MAX_INCOMING 14
/* Largest option used by the library */
#define LBER_SB_OPT_OPT_MAX 14
......@@ -201,6 +201,8 @@ typedef struct berval {
char *bv_val;
} BerValue;
typedef BerValue *BVarray; /* To distinguish from a single bv */
/* this should be moved to lber-int.h */
/*
......@@ -260,6 +262,11 @@ ber_get_stringb LDAP_P((
char *buf,
ber_len_t *len ));
LBER_F( ber_tag_t )
ber_get_stringbv LDAP_P((
BerElement *ber,
struct berval *bv ));
LBER_F( ber_tag_t )
ber_get_stringa LDAP_P((
BerElement *ber,
......
......@@ -279,31 +279,45 @@ ber_get_stringb(
}
ber_tag_t
ber_get_stringa( BerElement *ber, char **buf )
ber_get_stringbv( BerElement *ber, struct berval *bv )
{
ber_len_t datalen;
ber_tag_t tag;
assert( ber != NULL );
assert( buf != NULL );
assert( bv != NULL );
assert( LBER_VALID( ber ) );
if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
*buf = NULL;
if ( (tag = ber_skip_tag( ber, &bv->bv_len )) == LBER_DEFAULT ) {
bv->bv_val = NULL;
return LBER_DEFAULT;
}
if ( (*buf = (char *) LBER_MALLOC( datalen + 1 )) == NULL ) {
if ( (bv->bv_val = (char *) LBER_MALLOC( bv->bv_len + 1 )) == NULL ) {
return LBER_DEFAULT;
}
if ( datalen > 0 && (ber_len_t) ber_read( ber, *buf, datalen ) != datalen ) {
LBER_FREE( *buf );
*buf = NULL;
if ( bv->bv_len > 0 && (ber_len_t) ber_read( ber, bv->bv_val,
bv->bv_len ) != bv->bv_len ) {
LBER_FREE( bv->bv_val );
bv->bv_val = NULL;
return LBER_DEFAULT;
}
(*buf)[datalen] = '\0';
bv->bv_val[bv->bv_len] = '\0';
return tag;
}
ber_tag_t
ber_get_stringa( BerElement *ber, char **buf )
{
BerValue bv;
ber_tag_t tag;
assert( buf != NULL );
tag = ber_get_stringbv( ber, &bv );
*buf = bv.bv_val;
return tag;
}
......@@ -311,46 +325,21 @@ ber_get_stringa( BerElement *ber, char **buf )
ber_tag_t
ber_get_stringal( BerElement *ber, struct berval **bv )
{
ber_len_t len;
ber_tag_t tag;
assert( ber != NULL );
assert( bv != NULL );
assert( LBER_VALID( ber ) );
if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
*bv = NULL;
return LBER_DEFAULT;
}
*bv = (struct berval *) LBER_MALLOC( sizeof(struct berval) );
if ( *bv == NULL ) {
return LBER_DEFAULT;
}
if( len == 0 ) {
(*bv)->bv_val = NULL;
(*bv)->bv_len = 0;
return tag;
}
(*bv)->bv_val = (char *) LBER_MALLOC( len + 1 );
if ( (*bv)->bv_val == NULL ) {
tag = ber_get_stringbv( ber, *bv );
if ( tag == LBER_DEFAULT ) {
LBER_FREE( *bv );
*bv = NULL;
return LBER_DEFAULT;
}
if ( (ber_len_t) ber_read( ber, (*bv)->bv_val, len ) != len ) {
ber_bvfree( *bv );
*bv = NULL;
return LBER_DEFAULT;
}
((*bv)->bv_val)[len] = '\0';
(*bv)->bv_len = len;
return tag;
}
......@@ -479,6 +468,9 @@ ber_next_element(
return ber_peek_tag( ber, len );
}
/* Hopefully no one sends vectors with more elements than this */
#define TMP_SLOTS 1024
/* VARARGS */
ber_tag_t
ber_scanf ( BerElement *ber,
......@@ -562,8 +554,7 @@ ber_scanf ( BerElement *ber,
case 'o': /* octet string in a supplied berval */
bval = va_arg( ap, struct berval * );
ber_peek_tag( ber, &bval->bv_len );
rc = ber_get_stringa( ber, &bval->bv_val );
rc = ber_get_stringbv( ber, bval );
break;
case 'O': /* octet string - allocate & include length */
......@@ -588,6 +579,8 @@ ber_scanf ( BerElement *ber,
break;
case 'v': /* sequence of strings */
{
char *tmp[TMP_SLOTS];
sss = va_arg( ap, char *** );
*sss = NULL;
j = 0;
......@@ -595,25 +588,30 @@ ber_scanf ( BerElement *ber,
tag != LBER_DEFAULT && rc != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) )
{
char **save = *sss;
*sss = (char **) LBER_REALLOC( *sss,
(j + 2) * sizeof(char *) );
if( *sss == NULL ) {
save[j] = NULL;
ber_memvfree( (void **) save );
rc = ber_get_stringa( ber, &tmp[j] );
j++;
assert(j < TMP_SLOTS);
}
if (j > 0 && rc != LBER_DEFAULT ) {
*sss = (char **)LBER_MALLOC( (j+1) * sizeof(char *));
if (*sss == NULL) {
rc = LBER_DEFAULT;
goto breakout;
} else {
(*sss)[j] = NULL;
for (j--; j>=0; j--)
(*sss)[j] = tmp[j];
}
rc = ber_get_stringa( ber, &((*sss)[j]) );
j++;
}
if ( j > 0 ) (*sss)[j] = NULL;
if ( rc == LBER_DEFAULT ) {
for (j--; j>=0; j--)
LBER_FREE(tmp[j]);
}
break;
}
case 'V': /* sequence of strings + lengths */
{
struct berval *tmp[TMP_SLOTS];
bv = va_arg( ap, struct berval *** );
*bv = NULL;
j = 0;
......@@ -621,23 +619,58 @@ ber_scanf ( BerElement *ber,
tag != LBER_DEFAULT && rc != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) )
{
struct berval **save = *bv;
*bv = (struct berval **) LBER_REALLOC( *bv,
(j + 2) * sizeof(struct berval *) );
if( *bv == NULL ) {
save[j] = NULL;
ber_bvecfree( save );
rc = ber_get_stringal( ber, &tmp[j] );
j++;
assert( j < TMP_SLOTS);
}
if (j > 0 && rc != LBER_DEFAULT ) {
*bv = (struct berval **)LBER_MALLOC( (j+1) * sizeof(struct berval *));
if (*bv == NULL) {
rc = LBER_DEFAULT;
goto breakout;
} else {
(*bv)[j] = NULL;
for (j--; j>=0; j--)
(*bv)[j] = tmp[j];
}
}
if ( rc == LBER_DEFAULT ) {
for (j--; j>=0; j--)
ber_bvfree(tmp[j]);
}
break;
}
rc = ber_get_stringal( ber, &((*bv)[j]) );
case 'W': /* bvarray */
{
struct berval tmp[TMP_SLOTS];
bvp = va_arg( ap, struct berval ** );
*bvp = NULL;
j = 0;
for ( tag = ber_first_element( ber, &len, &last );
tag != LBER_DEFAULT && rc != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) )
{
rc = ber_get_stringbv( ber, &tmp[j] );
j++;
assert( j < TMP_SLOTS);
}
if (j > 0 && rc != LBER_DEFAULT ) {
*bvp = (struct berval *)LBER_MALLOC( (j+1) * sizeof(struct berval));
if (*bvp == NULL) {
rc = LBER_DEFAULT;
} else {
(*bvp)[j].bv_val = NULL;
(*bvp)[j].bv_len = 0;
for (j--; j>=0; j--)
(*bvp)[j] = tmp[j];
}
}
if ( rc == LBER_DEFAULT ) {
for (j--; j>=0; j--)
LBER_FREE(tmp[j].bv_val);
}
if ( j > 0 ) (*bv)[j] = NULL;
break;
}
case 'x': /* skip the next element - whatever it is */
if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
......@@ -747,21 +780,8 @@ breakout:
break;
case 'v': /* sequence of strings */
sss = va_arg( ap, char *** );
if ( *sss ) {
ber_memvfree( (void **) *sss );
*sss = NULL;
}
break;
case 'V': /* sequence of strings + lengths */
bv = va_arg( ap, struct berval *** );
if ( *bv ) {
ber_bvecfree( *bv );
*bv = NULL;
}
break;
case 'W': /* BVarray */
case 'n': /* null */
case 'x': /* skip the next element - whatever it is */
case '{': /* begin sequence */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment