From c225c4af34700c6a5be880ae8eeaf67fede803fb Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 12 May 2005 00:46:39 +0000 Subject: [PATCH] Updated ldif_read_record to support LDIF include: directive --- include/ldif.h | 19 ++++++- libraries/liblutil/fetch.c | 40 +++++++++------ libraries/liblutil/ldif.c | 89 +++++++++++++++++++++++++++++++-- servers/slapd/back-sql/config.c | 8 +-- servers/slapd/root_dse.c | 8 +-- servers/slapd/slapcat.c | 5 +- servers/slapd/slapcommon.c | 8 ++- servers/slapd/slapcommon.h | 2 +- 8 files changed, 147 insertions(+), 32 deletions(-) diff --git a/include/ldif.h b/include/ldif.h index a51e1cf4d3..0b2eaed130 100644 --- a/include/ldif.h +++ b/include/ldif.h @@ -66,6 +66,9 @@ ldif_parse_line2 LDAP_P(( struct berval *value, int *freeval )); +LDAP_LDIF_F( FILE * ) +ldif_open_url LDAP_P(( LDAP_CONST char *urlstr )); + LDAP_LDIF_F( int ) ldif_fetch_url LDAP_P(( LDAP_CONST char *line, @@ -78,9 +81,23 @@ ldif_getline LDAP_P(( char **next )); LDAP_LDIF_F( int ) ldif_countlines LDAP_P(( LDAP_CONST char *line )); +/* ldif_ropen, rclose, read_record - just for reading LDIF files, + * no special open/close needed to write LDIF files. + */ +typedef struct LDIFFP { + FILE *fp; + struct LDIFFP *prev; +} LDIFFP; + +LDAP_LDIF_F( LDIFFP * ) +ldif_open LDAP_P(( char *file, char *mode )); + +LDAP_LDIF_F( void ) +ldif_close LDAP_P(( LDIFFP * )); + LDAP_LDIF_F( int ) ldif_read_record LDAP_P(( - FILE *fp, + LDIFFP *fp, int *lineno, char **bufp, int *buflen )); diff --git a/libraries/liblutil/fetch.c b/libraries/liblutil/fetch.c index 49a72c6e4c..5ed0ad9cb0 100644 --- a/libraries/liblutil/fetch.c +++ b/libraries/liblutil/fetch.c @@ -38,22 +38,13 @@ #include "ldap_config.h" #include "ldif.h" -int -ldif_fetch_url( - LDAP_CONST char *urlstr, - char **valuep, - ber_len_t *vlenp +FILE * +ldif_open_url( + LDAP_CONST char *urlstr ) { FILE *url; - char buffer[1024]; char *p = NULL; - size_t total; - size_t bytes; - - *valuep = NULL; - *vlenp = 0; - #ifdef HAVE_FETCH url = fetchGetURL( (char*) urlstr, "" ); @@ -61,7 +52,7 @@ ldif_fetch_url( if( strncasecmp( "file://", urlstr, sizeof("file://")-1 ) == 0 ) { p = strchr( &urlstr[sizeof("file://")-1], '/' ); if( p == NULL ) { - return -1; + return NULL; } /* we don't check for LDAP_DIRSEP since URLs should contain '/' */ @@ -75,10 +66,31 @@ ldif_fetch_url( url = fopen( p, "rb" ); + ber_memfree( p ); } else { - return -1; + return NULL; } #endif + return url; +} + +int +ldif_fetch_url( + LDAP_CONST char *urlstr, + char **valuep, + ber_len_t *vlenp +) +{ + FILE *url; + char buffer[1024]; + char *p = NULL; + size_t total; + size_t bytes; + + *valuep = NULL; + *vlenp = 0; + + url = ldif_open_url( urlstr ); if( url == NULL ) { return -1; diff --git a/libraries/liblutil/ldif.c b/libraries/liblutil/ldif.c index cc0225c090..c4f2618441 100644 --- a/libraries/liblutil/ldif.c +++ b/libraries/liblutil/ldif.c @@ -745,12 +745,44 @@ int ldif_is_not_printable( return 1; } +LDIFFP * +ldif_open( + char *file, + char *mode +) +{ + FILE *fp = fopen( file, mode ); + LDIFFP *lfp = NULL; + + if ( fp ) { + lfp = ber_memalloc( sizeof( LDIFFP )); + lfp->fp = fp; + lfp->prev = NULL; + } + return lfp; +} + +void +ldif_close( + LDIFFP *lfp +) +{ + LDIFFP *prev; + + while ( lfp ) { + fclose( lfp->fp ); + prev = lfp->prev; + ber_memfree( lfp ); + lfp = prev; + } +} + /* - * slap_read_ldif - read an ldif record. Return 1 for success, 0 for EOF. + * ldif_read_record - read an ldif record. Return 1 for success, 0 for EOF. */ int ldif_read_record( - FILE *fp, + LDIFFP *lfp, int *lno, /* ptr to line number counter */ char **bufp, /* ptr to malloced output buffer */ int *buflenp ) /* ptr to length of *bufp */ @@ -762,8 +794,25 @@ ldif_read_record( line = linebuf; linesize = sizeof( linebuf ); - for ( stop = feof( fp ); !stop; last_ch = line[len-1] ) { - if ( fgets( line, linesize, fp ) == NULL ) { + for ( stop = 0; !stop; last_ch = line[len-1] ) { + /* If we're at the end of this file, see if we should pop + * back to a previous file. (return from an include) + */ + while ( feof( lfp->fp )) { + if ( lfp->prev ) { + LDIFFP *tmp = lfp->prev; + fclose( lfp->fp ); + *lfp = *tmp; + ber_memfree( tmp ); + } else { + stop = 1; + break; + } + } + if ( stop ) + break; + + if ( fgets( line, linesize, lfp->fp ) == NULL ) { stop = 1; /* Add \n in case the file does not end with newline */ line = "\n"; @@ -793,6 +842,38 @@ ldif_read_record( /* skip index */ continue; } + if ( !strncasecmp( line, "include:", + STRLENOF("include:"))) { + FILE *fp2; + char *ptr; + found_entry = 0; + + if ( line[len-1] == '\n' ) { + len--; + line[len] = '\0'; + } + if ( line[len-1] == '\r' ) { + len--; + line[len] = '\0'; + } + + ptr = line + STRLENOF("include:"); + while (isspace(*ptr)) ptr++; + fp2 = ldif_open_url( ptr ); + if ( fp2 ) { + LDIFFP *lnew = ber_memalloc( sizeof( LDIFFP )); + lnew->prev = lfp->prev; + lnew->fp = lfp->fp; + lfp->prev = lnew; + lfp->fp = fp2; + continue; + } else { + /* We failed to open the file, this should + * be reported as an error somehow. + */ + break; + } + } } } } diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index 1a89a0da84..a333ae0419 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -610,13 +610,13 @@ read_baseObject( const char *fname ) { backsql_info *bi = (backsql_info *)be->be_private; - FILE *fp; + LDIFFP *fp; int rc = 0, lineno = 0, lmax = 0; char *buf = NULL; assert( fname ); - fp = fopen( fname, "r" ); + fp = ldif_open( fname, "r" ); if ( fp == NULL ) { Debug( LDAP_DEBUG_ANY, "could not open back-sql baseObject " @@ -630,7 +630,7 @@ read_baseObject( if ( bi->sql_baseObject == NULL ) { Debug( LDAP_DEBUG_ANY, "read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 ); - fclose( fp ); + ldif_close( fp ); return LDAP_NO_MEMORY; } bi->sql_baseObject->e_name = be->be_suffix[0]; @@ -688,7 +688,7 @@ read_baseObject( ch_free( buf ); - fclose( fp ); + ldif_close( fp ); Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", fname, 0, 0 ); diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c index 907affc302..3b3cb12f0c 100644 --- a/servers/slapd/root_dse.c +++ b/servers/slapd/root_dse.c @@ -234,11 +234,11 @@ root_dse_info( */ int read_root_dse_file( const char *fname ) { - FILE *fp; + struct LDIFFP *fp; int rc = 0, lineno = 0, lmax = 0; char *buf = NULL; - if ( (fp = fopen( fname, "r" )) == NULL ) { + if ( (fp = ldif_open( fname, "r" )) == NULL ) { Debug( LDAP_DEBUG_ANY, "could not open rootdse attr file \"%s\" - absolute path?\n", fname, 0, 0 ); @@ -250,7 +250,7 @@ int read_root_dse_file( const char *fname ) if( usr_attr == NULL ) { Debug( LDAP_DEBUG_ANY, "read_root_dse_file: SLAP_CALLOC failed", 0, 0, 0 ); - fclose( fp ); + ldif_close( fp ); return LDAP_OTHER; } usr_attr->e_attrs = NULL; @@ -302,7 +302,7 @@ int read_root_dse_file( const char *fname ) ch_free( buf ); - fclose( fp ); + ldif_close( fp ); Debug(LDAP_DEBUG_CONFIG, "rootDSE file %s read.\n", fname, 0, 0); return rc; diff --git a/servers/slapd/slapcat.c b/servers/slapd/slapcat.c index e8a4beda5a..3e4d7ae12b 100644 --- a/servers/slapd/slapcat.c +++ b/servers/slapd/slapcat.c @@ -30,6 +30,7 @@ #include #include "slapcommon.h" +#include "ldif.h" int slapcat( int argc, char **argv ) @@ -101,8 +102,8 @@ slapcat( int argc, char **argv ) break; } - fputs( data, ldiffp ); - fputs( "\n", ldiffp ); + fputs( data, ldiffp->fp ); + fputs( "\n", ldiffp->fp ); } be->be_entry_close( be ); diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index 48122b53d1..1d72c5cf74 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -36,6 +36,7 @@ #include "slapcommon.h" #include "lutil.h" +#include "ldif.h" tool_vars tool_globals; @@ -44,6 +45,8 @@ static char *leakfilename; static FILE *leakfile; #endif +static LDIFFP dummy; + static void usage( int tool, const char *progname ) { @@ -376,9 +379,10 @@ slap_tool_init( ldap_syslog = 0; if ( ldiffile == NULL ) { - ldiffp = tool == SLAPCAT ? stdout : stdin; + dummy.fp = tool == SLAPCAT ? stdout : stdin; + ldiffp = &dummy; - } else if ((ldiffp = fopen( ldiffile, tool == SLAPCAT ? "w" : "r" )) + } else if ((ldiffp = ldif_open( ldiffile, tool == SLAPCAT ? "w" : "r" )) == NULL ) { perror( ldiffile ); diff --git a/servers/slapd/slapcommon.h b/servers/slapd/slapcommon.h index 4dcf7a8cbb..30ae1567c5 100644 --- a/servers/slapd/slapcommon.h +++ b/servers/slapd/slapcommon.h @@ -41,7 +41,7 @@ typedef struct tool_vars { int tv_dryrun; Filter *tv_filter; struct berval tv_sub_ndn; - FILE *tv_ldiffp; + struct LDIFFP *tv_ldiffp; struct berval tv_baseDN; struct berval tv_authcDN; struct berval tv_authzDN; -- 2.39.5