X-Git-Url: https://git.deb.at/?a=blobdiff_plain;f=filter.c;h=3aa3708a78acd5c2c23b1c8d0450a74821a4b4cb;hb=1f1bc68c78000f3269bb4bb1f15db6fefac03901;hp=ff3e511872f0e2bd3619680fa67c70de7699eff4;hpb=9ccd2453b5a55c7bccae5de1e1022947c7ff889a;p=pkg%2Fabook.git diff --git a/filter.c b/filter.c index ff3e511..3aa3708 100644 --- a/filter.c +++ b/filter.c @@ -547,35 +547,42 @@ static int ldif_conv_table[LDIF_ITEM_FIELDS] = { -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. + */ static char * -ldif_read_line(FILE *in) +ldif_read_line(FILE *in, char **next_line) { char *buf = NULL; char *ptr, *tmp; - long pos; - int i; + char *line; - 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); + } - pos = ftell(in); + while(!feof(in)) { + // if no line already read-ahead. line = getaline(in); + if(!line) break; - 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 if(*line != ' ') { - fseek(in, pos, SEEK_SET); /* fixme ! */ - free(line); + *next_line = line; break; } + // starts with ' ': this is the continuation of buf ptr = line; while( *ptr == ' ') ptr++; @@ -630,15 +637,8 @@ ldif_convert(ldif_item item, char *type, char *value) return; } - for(i=0; i < LDIF_ITEM_FIELDS; i++) { + for(i=0; i < LDIF_ITEM_FIELDS - 1; i++) { if(!strcasecmp(ldif_field_names[i], type) && *value) { - if(i == LDIF_ITEM_FIELDS - 1) /* this is a dirty hack */ - if(safe_strcmp("person", value)) - break; - - if(item_fget(item, i)) - free(item_fget(item, i)); - item_fput(item, i, xstrdup(value)); break; } @@ -649,6 +649,7 @@ static int ldif_parse_file(FILE *handle) { char *line = NULL; + char *next_line = NULL; char *type, *value; int vlen; ldif_item item; @@ -656,8 +657,10 @@ ldif_parse_file(FILE *handle) 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); @@ -880,16 +883,22 @@ ldif_export_database(FILE *out, struct db_enumerator e) int j; get_first_email(email, e.item); - tmp = strdup_printf("cn=%s,mail=%s",db_name_get(e.item),email); + if(*email) + tmp = strdup_printf("cn=%s,mail=%s",db_name_get(e.item),email); + else + tmp = strdup_printf("cn=%s",db_name_get(e.item)); ldif_fput_type_and_value(out, "dn", tmp); free(tmp); for(j = 0; j < LDIF_ITEM_FIELDS; j++) { if(ldif_conv_table[j] >= 0) { - if(ldif_conv_table[j] == EMAIL) - ldif_fput_type_and_value(out, - ldif_field_names[j], email); + if(ldif_conv_table[j] == EMAIL) { + if(*email) // don't dump en empty email field + ldif_fput_type_and_value(out, + ldif_field_names[j], + email); + } else if(db_fget(e.item,ldif_conv_table[j])) ldif_fput_type_and_value(out, ldif_field_names[j],