X-Git-Url: https://git.deb.at/w?a=blobdiff_plain;f=filter.c;h=4d1abd893f018cdacc9e6e2e8c41852eb76889a1;hb=2b6493a629d94386ed6e07b5c71482c66d3be4fe;hp=31b6f2d259fab66e7a4c58fe4705b87541409310;hpb=2f827e0ef00d2c90e00adf976147faaa448b1651;p=pkg%2Fabook.git diff --git a/filter.c b/filter.c index 31b6f2d..4d1abd8 100644 --- a/filter.c +++ b/filter.c @@ -503,8 +503,6 @@ export_file(char filtname[FILTNAME_LEN], char *filename) #include "ldif.h" -static void ldif_fix_string(char *str); - /* During LDIF import we need more fields than the ITEM_FIELDS of a *list_item. Eg: "objectclass" to test valid records, ... @@ -789,8 +787,6 @@ ldif_parse_file(FILE *handle) continue; /* just skip the errors */ } - ldif_fix_string(value); - ldif_convert(item, type, value); xfree(line); @@ -802,19 +798,6 @@ ldif_parse_file(FILE *handle) return 0; } -static void -ldif_fix_string(char *str) -{ - int i, j; - - for(i = 0, j = 0; j < (int)strlen(str); i++, j++) - str[i] = ( str[j] == (char)0xc3 ? - (char) str[++j] + (char) 0x40 : - str[j] ); - - str[i] = 0; -} - /* * end of ldif import */ @@ -998,6 +981,7 @@ static int ldif_export_database(FILE *out, struct db_enumerator e) { char email[MAX_EMAILSTR_LEN]; + abook_list *emails, *em; fprintf(out, "version: 1\n"); @@ -1018,10 +1002,15 @@ ldif_export_database(FILE *out, struct db_enumerator e) for(j = 0; j < ITEM_FIELDS; j++) { if(j == EMAIL) { - if(*email) // don't dump an empty email field - ldif_fput_type_and_value(out, - ldif_field_names[j], - email); + if(*email) { + tmp = db_email_get(e.item); + emails = csv_to_abook_list(tmp); + free(tmp); + for(em = emails; em; em = em->next) + ldif_fput_type_and_value(out, + ldif_field_names[EMAIL], + em->data); + } } else if(db_fget(e.item,j)) { ldif_fput_type_and_value(out, @@ -2038,15 +2027,18 @@ vcard_export_item(FILE *out, int item) free(name); - if(db_fget(item, ADDRESS)) - fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\r\n", - safe_str(db_fget(item, ADDRESS)), - safe_str(db_fget(item, ADDRESS2)), - safe_str(db_fget(item, CITY)), - safe_str(db_fget(item, STATE)), - safe_str(db_fget(item, ZIP)), - safe_str(db_fget(item, COUNTRY)) - ); + // see rfc6350 section 6.3.1 + if(db_fget(item, ADDRESS)) { + fprintf(out, "ADR:;%s;%s;%s;%s;%s;%s\r\n", + // pobox (unsupported) + safe_str(db_fget(item, ADDRESS2)), // ext (n°, ...) + safe_str(db_fget(item, ADDRESS)), // street + safe_str(db_fget(item, CITY)), // locality + safe_str(db_fget(item, STATE)), // region + safe_str(db_fget(item, ZIP)), // code (postal) + safe_str(db_fget(item, COUNTRY)) // country + ); + } if(db_fget(item, PHONE)) fprintf(out, "TEL;HOME:%s\r\n", @@ -2496,37 +2488,15 @@ bsdcal_export_database(FILE *out, struct db_enumerator e) return 0; } -// see enum field_types @database.h -static char *conv_table[] = { - "name", - "email", - "address", - "address2", - "city", - "state", - "zip", - "country", - "phone", - "workphone", - "fax", - "mobile", - "nick", - "url", - "notes", - "anniversary", - 0 /* ITEM_FIELDS */ -}; - +// see also enum field_types @database.h +extern abook_field standard_fields[]; static int find_field_enum(char *s) { - int i = 0; - while (conv_table[i]) { - if(!safe_strcmp(conv_table[i], s)) - return i; - i++; - } - // failed - return -1; + int i = -1; + while(standard_fields[++i].key) + if(!strcmp(standard_fields[i].key, s)) + return i; + return -1; } /* Convert a string with named placeholders to @@ -2540,17 +2510,17 @@ parse_custom_format(char *s, char *fmt_string, enum field_types *ft) exit(EXIT_FAILURE); } + char tmp[1] = { 0 }; char *p, *start, *field_name = NULL; p = start = s; while(*p) { if(*p == '{') { start = ++p; + + if(! *start) goto cannotparse; p = strchr(start, '}'); - if(! *p) { - fprintf(stderr, _("parse_custom_format: invalid format\n")); - exit(EXIT_FAILURE); - } + if(! p) goto cannotparse; strcat(fmt_string, "%s"); field_name = strndup(start, (size_t)(p-start)); *ft = find_field_enum(field_name); @@ -2560,23 +2530,53 @@ parse_custom_format(char *s, char *fmt_string, enum field_types *ft) } ft++; - p++; - start = p; - } else { + start = ++p; + } + + else if(*p == '\\') { + ++p; + if(! *p) tmp[0] = '\\'; // last char is a '\' ? + else if(*p == 'n') *tmp = '\n'; + else if(*p == 't') *tmp = '\t'; + else if(*p == 'r') *tmp = '\r'; + else if(*p == 'v') *tmp = '\v'; + else if(*p == 'b') *tmp = '\b'; + else if(*p == 'a') *tmp = '\a'; + else *tmp = *p; + strncat(fmt_string, tmp, 1); + start = ++p; + } + + // if no '\' following: quick mode using strchr/strncat + else if(! strchr(start, '\\')) { p = strchr(start, '{'); - if(p && *p) { + if(p) { // copy until the next placeholder strncat(fmt_string, start, (size_t)(p-start)); start = p; } - else { + else { // copy till the end strncat( fmt_string, start, FORMAT_STRING_LEN - strlen(fmt_string) - 1 ); break; } } + + // otherwise character by character + else { + strncat(fmt_string, p, 1); + start = ++p; + } } - *ft = 66; + + *ft = ITEM_FIELDS; + return; + + cannotparse: + fprintf(stderr, _("%s: invalid format, index %ld\n"), __FUNCTION__, (start - s)); + free(fmt_string); + while(*ft) free(ft--); + exit(EXIT_FAILURE); } static int @@ -2609,7 +2609,7 @@ custom_export_item(FILE *out, int item, char *fmt, enum field_types *ft) // we first check that all fields exist before continuing if(*fmt == '!') { enum field_types *ftp = ft; - while(*ft != 66) { + while(*ft != ITEM_FIELDS) { if(! db_fget(item, *ft) ) return 1; ft++; @@ -2623,7 +2623,7 @@ custom_export_item(FILE *out, int item, char *fmt, enum field_types *ft) fprintf(out, "%s", safe_str(db_fget(item, *ft))); ft++; fmt+=2; - } else if (*ft == 66) { + } else if (*ft == ITEM_FIELDS) { fprintf(out, "%s", fmt); return 0; } else {