]> git.sur5r.net Git - openldap/commitdiff
Added ldif_parse_line2 to parse in-place
authorHoward Chu <hyc@openldap.org>
Wed, 19 Jan 2005 05:05:53 +0000 (05:05 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 19 Jan 2005 05:05:53 +0000 (05:05 +0000)
include/ldif.h
libraries/liblutil/ldif.c
servers/slapd/entry.c

index 4743f1de96362b77339e56a4064c85298341aab3..b484da6ae126f3980a206c512a0da17316d10e89 100644 (file)
@@ -59,6 +59,14 @@ ldif_parse_line LDAP_P((
        char **value,
        ber_len_t *vlen ));
 
+LDAP_LDIF_F( int )
+ldif_parse_line2 LDAP_P((
+       LDAP_CONST char *line,
+       char **name,
+       char **value,
+       ber_len_t *vlen,
+       int *alloc ));
+
 LDAP_LDIF_F( int )
 ldif_fetch_url LDAP_P((
        LDAP_CONST char *line,
index 05220b09472bbc1c12fe02e114cd4cf576e73883..9d67b3cf75056ff54eb004c5b9b332a4d2de3136 100644 (file)
@@ -81,7 +81,12 @@ static const unsigned char b642nib[0x80] = {
  * ldif_parse_line - takes a line of the form "type:[:] value" and splits it
  * into components "type" and "value".  if a double colon separates type from
  * value, then value is encoded in base 64, and parse_line un-decodes it
- * (in place) before returning.
+ * (in place) before returning. The type and value are stored in malloc'd
+ * memory which must be freed by the caller.
+ *
+ * ldif_parse_line2 - operates in-place on input buffer, returning type
+ * in-place. Will return value in-place if possible, (must malloc for
+ * fetched URLs).
  */
 
 int
@@ -91,11 +96,23 @@ ldif_parse_line(
     char       **valuep,
     ber_len_t *vlenp
 )
+{
+       return ldif_parse_line2( line, typep, valuep, vlenp, NULL );
+}
+
+int
+ldif_parse_line2(
+    LDAP_CONST char    *line,
+    char       **typep,
+    char       **valuep,
+    ber_len_t *vlenp,
+       int             *alloc
+)
 {
        char    *s, *p, *d; 
        char    nib;
        int     b64, url;
-       char    *freeme, *type, *value;
+       char    *type, *value;
        ber_len_t vlen;
 
        *typep = NULL;
@@ -107,15 +124,19 @@ ldif_parse_line(
                line++;
        }
 
-       freeme = ber_strdup( line );
+       if ( alloc ) {
+               *alloc = 0;
+       } else {
+               line = ber_strdup( line );
 
-       if( freeme == NULL ) {
-               ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
-                       _("ldif_parse_line: line malloc failed\n"));
-               return( -1 );
+               if( line == NULL ) {
+                       ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
+                               _("ldif_parse_line: line malloc failed\n"));
+                       return( -1 );
+               }
        }
 
-       type = freeme;
+       type = line;
 
        s = strchr( type, ':' );
 
@@ -123,7 +144,7 @@ ldif_parse_line(
                ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
                        _("ldif_parse_line: missing ':' after %s\n"),
                        type );
-               ber_memfree( freeme );
+               if ( !alloc ) ber_memfree( line );
                return( -1 );
        }
 
@@ -165,7 +186,7 @@ ldif_parse_line(
                        /* no value is present, error out */
                        ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
                                _("ldif_parse_line: %s missing base64 value\n"), type );
-                       ber_memfree( freeme );
+                       if ( !alloc ) ber_memfree( line );
                        return( -1 );
                }
 
@@ -180,7 +201,7 @@ ldif_parse_line(
                                                _("ldif_parse_line: %s: invalid base64 encoding"
                                                " char (%c) 0x%x\n"),
                                            type, p[i], p[i] );
-                                       ber_memfree( freeme );
+                                       if ( !alloc ) ber_memfree( line );
                                        return( -1 );
                                }
                        }
@@ -217,7 +238,7 @@ ldif_parse_line(
                        /* no value is present, error out */
                        ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
                                _("ldif_parse_line: %s missing URL value\n"), type );
-                       ber_memfree( freeme );
+                       if ( !alloc ) ber_memfree( line );
                        return( -1 );
                }
 
@@ -225,40 +246,43 @@ ldif_parse_line(
                        ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
                                _("ldif_parse_line: %s: URL \"%s\" fetch failed\n"),
                                type, s );
-                       ber_memfree( freeme );
+                       if ( !alloc ) ber_memfree( line );
                        return( -1 );
                }
+               if ( alloc ) *alloc = 1;
 
        } else {
                value = s;
                vlen = (int) (d - s);
        }
 
-       type = ber_strdup( type );
-
-       if( type == NULL ) {
-               ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
-                       _("ldif_parse_line: type malloc failed\n"));
-               if( url ) ber_memfree( value );
-               ber_memfree( freeme );
-               return( -1 );
-       }
+       if ( !alloc ) {
+               type = ber_strdup( type );
 
-       if( !url ) {
-               p = ber_memalloc( vlen + 1 );
-               if( p == NULL ) {
+               if( type == NULL ) {
                        ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
-                               _("ldif_parse_line: value malloc failed\n"));
-                       ber_memfree( type );
-                       ber_memfree( freeme );
+                               _("ldif_parse_line: type malloc failed\n"));
+                       if( url ) ber_memfree( value );
+                       ber_memfree( line );
                        return( -1 );
                }
-               AC_MEMCPY( p, value, vlen );
-               p[vlen] = '\0';
-               value = p;
-       }
 
-       ber_memfree( freeme );
+               if( !url ) {
+                       p = ber_memalloc( vlen + 1 );
+                       if( p == NULL ) {
+                               ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
+                                       _("ldif_parse_line: value malloc failed\n"));
+                               ber_memfree( type );
+                               ber_memfree( line );
+                               return( -1 );
+                       }
+                       AC_MEMCPY( p, value, vlen );
+                       p[vlen] = '\0';
+                       value = p;
+               }
+
+               ber_memfree( line );
+       }
 
        *typep = type;
        *valuep = value;
index 40dcdb638b28ad47b1e0cafbe201c9d9ded4ac8f..c1a1116360188c9c7f34e59d185d7a8f5583e29a 100644 (file)
@@ -69,6 +69,7 @@ str2entry( char *s )
        const char *text;
        char    *next;
        int             attr_cnt;
+       int             freeval;
 
        /*
         * LDIF is used as the string format.
@@ -114,34 +115,33 @@ str2entry( char *s )
                        break;
                }
 
-               if ( ldif_parse_line( s, &type, &vals[0].bv_val, &vals[0].bv_len ) != 0 ) {
+               if ( ldif_parse_line2( s, &type, &vals[0].bv_val, &vals[0].bv_len,
+                       &freeval ) != 0 ) {
                        Debug( LDAP_DEBUG_TRACE,
                                "<= str2entry NULL (parse_line)\n", 0, 0, 0 );
                        continue;
                }
 
                if ( strcasecmp( type, "dn" ) == 0 ) {
-                       free( type );
 
                        if ( e->e_dn != NULL ) {
                                Debug( LDAP_DEBUG_ANY, "str2entry: "
                                        "entry %ld has multiple DNs \"%s\" and \"%s\"\n",
                                        (long) e->e_id, e->e_dn, vals[0].bv_val );
-                               free( vals[0].bv_val );
+                               if ( freeval ) free( vals[0].bv_val );
                                entry_free( e );
                                return NULL;
                        }
 
                        rc = dnPrettyNormal( NULL, &vals[0], &e->e_name, &e->e_nname, NULL );
+                       if ( freeval ) free( vals[0].bv_val );
                        if( rc != LDAP_SUCCESS ) {
                                Debug( LDAP_DEBUG_ANY, "str2entry: "
                                        "entry %ld has invalid DN \"%s\"\n",
                                        (long) e->e_id, vals[0].bv_val, 0 );
                                entry_free( e );
-                               free( vals[0].bv_val );
                                return NULL;
                        }
-                       free( vals[0].bv_val );
                        continue;
                }
 
@@ -155,8 +155,7 @@ str2entry( char *s )
                                "<= str2entry: str2ad(%s): %s\n", type, text, 0 );
                        if( slapMode & SLAP_TOOL_MODE ) {
                                entry_free( e );
-                               free( vals[0].bv_val );
-                               free( type );
+                               if ( freeval ) free( vals[0].bv_val );
                                return NULL;
                        }
 
@@ -166,8 +165,7 @@ str2entry( char *s )
                                        "<= str2entry: str2undef_ad(%s): %s\n",
                                                type, text, 0 );
                                entry_free( e );
-                               free( vals[0].bv_val );
-                               free( type );
+                               if ( freeval ) free( vals[0].bv_val );
                                return NULL;
                        }
                }
@@ -200,8 +198,7 @@ str2entry( char *s )
                                        ad->ad_cname.bv_val, attr_cnt,
                                        ad->ad_type->sat_syntax->ssyn_oid );
                                entry_free( e );
-                               free( vals[0].bv_val );
-                               free( type );
+                               if ( freeval ) free( vals[0].bv_val );
                                return NULL;
                        }
 
@@ -212,14 +209,14 @@ str2entry( char *s )
                                        ad->ad_cname.bv_val, attr_cnt,
                                        ad->ad_type->sat_syntax->ssyn_oid );
                                entry_free( e );
-                               free( vals[0].bv_val );
-                               free( type );
+                               if ( freeval ) free( vals[0].bv_val );
                                return NULL;
                        }
 
                        if( pretty ) {
-                               free( vals[0].bv_val );
+                               if ( freeval ) free( vals[0].bv_val );
                                vals[0] = pval;
+                               freeval = 1;
                        }
                }
 
@@ -240,8 +237,7 @@ str2entry( char *s )
                                        "<= str2entry NULL (smr_normalize %d)\n", rc, 0, 0 );
 
                                entry_free( e );
-                               free( vals[0].bv_val );
-                               free( type );
+                               if ( freeval ) free( vals[0].bv_val );
                                return NULL;
                        }
 
@@ -256,13 +252,11 @@ str2entry( char *s )
                        Debug( LDAP_DEBUG_ANY,
                                "<= str2entry NULL (attr_merge)\n", 0, 0, 0 );
                        entry_free( e );
-                       free( vals[0].bv_val );
-                       free( type );
+                       if ( freeval ) free( vals[0].bv_val );
                        return( NULL );
                }
 
-               free( type );
-               free( vals[0].bv_val );
+               if ( freeval ) free( vals[0].bv_val );
                free( nvals[0].bv_val );
 
                attr_cnt++;