From dc156d7f6e7b3e51d1d50c551310db35a5371b84 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 7 Dec 2010 10:14:51 +0000 Subject: [PATCH] allow to set LDIF max line width (ITS#6645) --- doc/man/man8/slapcat.8 | 7 ++++++- include/ldif.h | 26 +++++++++++++++++++++++++- libraries/liblutil/ldif.c | 38 +++++++++++++++++++++++++++++++++----- servers/slapd/entry.c | 16 +++++++++++++--- servers/slapd/proto-slap.h | 1 + servers/slapd/slapcat.c | 2 +- servers/slapd/slapcommon.c | 19 +++++++++++++++++++ servers/slapd/slapcommon.h | 3 +++ 8 files changed, 101 insertions(+), 11 deletions(-) diff --git a/doc/man/man8/slapcat.8 b/doc/man/man8/slapcat.8 index 02e64c8988..96950514b4 100644 --- a/doc/man/man8/slapcat.8 +++ b/doc/man/man8/slapcat.8 @@ -149,7 +149,12 @@ Possible generic options/values are: syslog\-level= (see `\-S' in slapd(8)) syslog\-user= (see `\-l' in slapd(8)) -.fi + ldif-wrap={no|} + +.in +\fIn\fP is the number of columns allowed for the LDIF output +(\fIn\fP equal to \fI0\fP uses the default, corresponding to 76). +Use \fIno\fP for no wrap. .TP .BI \-s \ subtree-dn Only dump entries in the subtree specified by this DN. diff --git a/include/ldif.h b/include/ldif.h index 09c70b956f..87fe9ab159 100644 --- a/include/ldif.h +++ b/include/ldif.h @@ -33,7 +33,9 @@ LDAP_BEGIN_DECL /* This is NOT a bogus extern declaration (unlike ldap_debug) */ LDAP_LDIF_V (int) ldif_debug; -#define LDIF_LINE_WIDTH 76 /* maximum length of LDIF lines */ +#define LDIF_LINE_WIDTH 76 /* default maximum length of LDIF lines */ +#define LDIF_LINE_WIDTH_MAX ((ber_len_t)-1) /* maximum length of LDIF lines */ +#define LDIF_LINE_WIDTH_WRAP(wrap) ((wrap) == 0 ? LDIF_LINE_WIDTH : (wrap)) /* * Macro to calculate maximum number of bytes that the base64 equivalent @@ -52,6 +54,11 @@ LDAP_LDIF_V (int) ldif_debug; ((nlen) + 4 + LDIF_BASE64_LEN(vlen) \ + ((LDIF_BASE64_LEN(vlen) + (nlen) + 3) / LDIF_LINE_WIDTH * 2 )) +#define LDIF_SIZE_NEEDED_WRAP(nlen,vlen,wrap) \ + ((nlen) + 4 + LDIF_BASE64_LEN(vlen) \ + + ((wrap) == 0 ? ((LDIF_BASE64_LEN(vlen) + (nlen) + 3) / ( LDIF_LINE_WIDTH ) * 2 ) : \ + ((wrap) == LDIF_LINE_WIDTH_MAX ? 0 : ((LDIF_BASE64_LEN(vlen) + (nlen) + 3) / (wrap) * 2 )))) + LDAP_LDIF_F( int ) ldif_parse_line LDAP_P(( LDAP_CONST char *line, @@ -128,6 +135,15 @@ ldif_sput LDAP_P(( LDAP_CONST char *val, ber_len_t vlen )); +LDAP_LDIF_F( void ) +ldif_sput_wrap LDAP_P(( + char **out, + int type, + LDAP_CONST char *name, + LDAP_CONST char *val, + ber_len_t vlen, + ber_len_t wrap )); + LDAP_LDIF_F( char * ) ldif_put LDAP_P(( int type, @@ -135,6 +151,14 @@ ldif_put LDAP_P(( LDAP_CONST char *val, ber_len_t vlen )); +LDAP_LDIF_F( char * ) +ldif_put_wrap LDAP_P(( + int type, + LDAP_CONST char *name, + LDAP_CONST char *val, + ber_len_t vlen, + ber_len_t wrap )); + LDAP_LDIF_F( int ) ldif_is_not_printable LDAP_P(( LDAP_CONST char *val, diff --git a/libraries/liblutil/ldif.c b/libraries/liblutil/ldif.c index 6994a060ca..c080199151 100644 --- a/libraries/liblutil/ldif.c +++ b/libraries/liblutil/ldif.c @@ -489,6 +489,7 @@ ldif_must_b64_encode( LDAP_CONST char *s ) /* compatibility with U-Mich off by one bug */ #define LDIF_KLUDGE 1 +/* NOTE: only preserved for binary compatibility */ void ldif_sput( char **out, @@ -496,6 +497,18 @@ ldif_sput( LDAP_CONST char *name, LDAP_CONST char *val, ber_len_t vlen ) +{ + ldif_sput_wrap( out, type, name, val, vlen, LDIF_LINE_WIDTH ); +} + +void +ldif_sput_wrap( + char **out, + int type, + LDAP_CONST char *name, + LDAP_CONST char *val, + ber_len_t vlen, + ber_len_t wrap ) { const unsigned char *byte, *stop; unsigned char buf[3]; @@ -508,6 +521,8 @@ ldif_sput( ber_len_t len=0; ber_len_t i; + wrap = LDIF_LINE_WIDTH_WRAP( wrap ); + /* prefix */ switch( type ) { case LDIF_PUT_COMMENT: @@ -578,7 +593,7 @@ ldif_sput( case LDIF_PUT_COMMENT: /* pre-encoded names */ for ( i=0; i < vlen; i++ ) { - if ( len > LDIF_LINE_WIDTH ) { + if ( len > wrap ) { *(*out)++ = '\n'; *(*out)++ = ' '; len = 1; @@ -618,7 +633,7 @@ ldif_sput( b64 = 1; break; } - if ( len > LDIF_LINE_WIDTH+LDIF_KLUDGE ) { + if ( len - LDIF_KLUDGE > wrap ) { *(*out)++ = '\n'; *(*out)++ = ' '; len = 1; @@ -647,7 +662,7 @@ ldif_sput( bits |= (byte[2] & 0xff); for ( i = 0; i < 4; i++, len++, bits <<= 6 ) { - if ( len > LDIF_LINE_WIDTH+LDIF_KLUDGE ) { + if ( len - LDIF_KLUDGE > wrap ) { *(*out)++ = '\n'; *(*out)++ = ' '; len = 1; @@ -672,7 +687,7 @@ ldif_sput( bits |= (byte[2] & 0xff); for ( i = 0; i < 4; i++, len++, bits <<= 6 ) { - if ( len > LDIF_LINE_WIDTH+LDIF_KLUDGE ) { + if ( len - LDIF_KLUDGE > wrap ) { *(*out)++ = '\n'; *(*out)++ = ' '; len = 1; @@ -693,19 +708,32 @@ ldif_sput( /* * ldif_type_and_value return BER malloc'd, zero-terminated LDIF line */ + +/* NOTE: only preserved for binary compatibility */ char * ldif_put( int type, LDAP_CONST char *name, LDAP_CONST char *val, ber_len_t vlen ) +{ + return ldif_put_wrap( type, name, val, vlen, LDIF_LINE_WIDTH ); +} + +char * +ldif_put_wrap( + int type, + LDAP_CONST char *name, + LDAP_CONST char *val, + ber_len_t vlen, + ber_len_t wrap ) { char *buf, *p; ber_len_t nlen; nlen = ( name != NULL ) ? strlen( name ) : 0; - buf = (char *) ber_memalloc( LDIF_SIZE_NEEDED( nlen, vlen ) + 1 ); + buf = (char *) ber_memalloc( LDIF_SIZE_NEEDED_WRAP( nlen, vlen, wrap ) + 1 ); if ( buf == NULL ) { ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 07ee458113..542db90165 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -426,10 +426,20 @@ fail: } \ } +/* NOTE: only preserved for binary compatibility */ char * entry2str( Entry *e, int *len ) +{ + return entry2str_wrap( e, len, LDIF_LINE_WIDTH ); +} + +char * +entry2str_wrap( + Entry *e, + int *len, + ber_len_t wrap ) { Attribute *a; struct berval *bv; @@ -451,7 +461,7 @@ entry2str( /* put "dn: " */ tmplen = e->e_name.bv_len; MAKE_SPACE( LDIF_SIZE_NEEDED( 2, tmplen )); - ldif_sput( &ecur, LDIF_PUT_VALUE, "dn", e->e_dn, tmplen ); + ldif_sput_wrap( &ecur, LDIF_PUT_VALUE, "dn", e->e_dn, tmplen, wrap ); } /* put the attributes */ @@ -461,9 +471,9 @@ entry2str( bv = &a->a_vals[i]; tmplen = a->a_desc->ad_cname.bv_len; MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len )); - ldif_sput( &ecur, LDIF_PUT_VALUE, + ldif_sput_wrap( &ecur, LDIF_PUT_VALUE, a->a_desc->ad_cname.bv_val, - bv->bv_val, bv->bv_len ); + bv->bv_val, bv->bv_len, wrap ); } } MAKE_SPACE( 1 ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index f16eaa6175..138739aef7 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -986,6 +986,7 @@ LDAP_SLAPD_F (int) entry_destroy LDAP_P((void)); LDAP_SLAPD_F (Entry *) str2entry LDAP_P(( char *s )); LDAP_SLAPD_F (Entry *) str2entry2 LDAP_P(( char *s, int checkvals )); LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len )); +LDAP_SLAPD_F (char *) entry2str_wrap LDAP_P(( Entry *e, int *len, ber_len_t wrap )); LDAP_SLAPD_F (ber_len_t) entry_flatsize LDAP_P(( Entry *e, int norm )); LDAP_SLAPD_F (void) entry_partsize LDAP_P(( Entry *e, ber_len_t *len, diff --git a/servers/slapd/slapcat.c b/servers/slapd/slapcat.c index c4e7a7d658..56cfd60426 100644 --- a/servers/slapd/slapcat.c +++ b/servers/slapd/slapcat.c @@ -148,7 +148,7 @@ slapcat( int argc, char **argv ) printf( "# id=%08lx\n", (long) id ); } - data = entry2str( e, &len ); + data = entry2str_wrap( e, &len, ldif_wrap ); be_entry_release_r( &op, e ); if ( data == NULL ) { diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index 5805232176..ccdeddb0c2 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -228,6 +228,23 @@ parse_slapopt( int tool, int *mode ) break; } + } else if ( strncasecmp( optarg, "ldif-wrap", len ) == 0 ) { + switch ( tool ) { + case SLAPCAT: + if ( strcasecmp( p, "no" ) == 0 ) { + ldif_wrap = LDIF_LINE_WIDTH_MAX; + + } else if ( lutil_atou( &ldif_wrap, p ) ) { + Debug( LDAP_DEBUG_ANY, "unable to parse ldif-wrap=\"%s\".\n", p, 0, 0 ); + return -1; + } + break; + + default: + Debug( LDAP_DEBUG_ANY, "value-check meaningless for tool.\n", 0, 0, 0 ); + break; + } + } else { return -1; } @@ -283,6 +300,8 @@ slap_tool_init( leakfilename = NULL; #endif + ldif_wrap = LDIF_LINE_WIDTH; + scope = LDAP_SCOPE_DEFAULT; switch( tool ) { diff --git a/servers/slapd/slapcommon.h b/servers/slapd/slapcommon.h index 5041f374d7..a3ddffada6 100644 --- a/servers/slapd/slapcommon.h +++ b/servers/slapd/slapcommon.h @@ -65,6 +65,7 @@ typedef struct tool_vars { slap_ssf_t tv_sasl_ssf; unsigned tv_dn_mode; unsigned int tv_csnsid; + ber_len_t tv_ldif_wrap; } tool_vars; extern tool_vars tool_globals; @@ -99,6 +100,8 @@ extern tool_vars tool_globals; #define sasl_ssf tool_globals.tv_sasl_ssf #define dn_mode tool_globals.tv_dn_mode #define csnsid tool_globals.tv_csnsid +#define ldif_wrap tool_globals.tv_ldif_wrap + #define SLAP_TOOL_LDAPDN_PRETTY SLAP_LDAPDN_PRETTY #define SLAP_TOOL_LDAPDN_NORMAL (SLAP_LDAPDN_PRETTY << 1) -- 2.39.5