ldif parser used to seek in the file handler to grab multi-line
strings, thus creating buggy records when input was stdin.
It now reads-ahead the next line in order to work consistently with
unseekable streams like stdin.
-1, /* "objectclass" */ /* this must be the last entry */
};
-1, /* "objectclass" */ /* this must be the last entry */
};
+/*
+ Handles multi-line strings.
+ If a string starts with a space, it's the continuation
+ of the previous line. Thus we need to always read ahead.
+ But for this to work with stdin, we need to stores the next
+ line for later use in case it's not a continuation of the
+ first line.
+ */
-ldif_read_line(FILE *in)
+ldif_read_line(FILE *in, char **next_line)
{
char *buf = NULL;
char *ptr, *tmp;
{
char *buf = NULL;
char *ptr, *tmp;
- for(i = 1;;i++) {
- char *line;
+ // buf filled with the first line
+ if(!*next_line)
+ buf = getaline(in);
+ else {
+ buf = xstrdup(*next_line);
+ xfree(*next_line);
+ }
+ while(!feof(in)) {
+ // if no line already read-ahead.
- if(feof(in) || !line)
- break;
-
- if(i == 1) {
- buf = line;
- continue;
- }
-
+ // this is not a continuation of what is already in buf
+ // store it for the next round
- fseek(in, pos, SEEK_SET); /* fixme ! */
- free(line);
+ // starts with ' ': this is the continuation of buf
ptr = line;
while( *ptr == ' ')
ptr++;
ptr = line;
while( *ptr == ' ')
ptr++;
ldif_parse_file(FILE *handle)
{
char *line = NULL;
ldif_parse_file(FILE *handle)
{
char *line = NULL;
+ char *next_line = NULL;
char *type, *value;
int vlen;
ldif_item item;
char *type, *value;
int vlen;
ldif_item item;
memset(item, 0, sizeof(item));
do {
memset(item, 0, sizeof(item));
do {
- if( !(line = ldif_read_line(handle)) )
- continue;
+ line = ldif_read_line(handle, &next_line);
+
+ // EOF or empty lines: continue;
+ if(!line || *line == '\0') continue;
if(-1 == (str_parse_line(line, &type, &value, &vlen))) {
xfree(line);
if(-1 == (str_parse_line(line, &type, &value, &vlen))) {
xfree(line);