1 diff -ru a/filter.c b/filter.c
2 --- a/filter.c 2006-09-06 07:26:10.000000000 +0200
3 +++ b/filter.c 2008-05-18 20:55:12.000000000 +0200
5 static int csv_parse_file(FILE *in);
6 static int allcsv_parse_file(FILE *in);
7 static int palmcsv_parse_file(FILE *in);
8 +static int vcard_parse_file(FILE *in);
11 * export filter prototypes
13 { "csv", N_("comma separated values"), csv_parse_file },
14 { "allcsv", N_("comma separated values (all fields)"), allcsv_parse_file },
15 { "palmcsv", N_("Palm comma separated values"), palmcsv_parse_file },
16 + { "vcard", N_("vCard file"), vcard_parse_file },
20 @@ -1331,6 +1333,262 @@
24 + * vCard import filter
27 +static char *vcard_fields[] = {
29 + "EMAIL", /* EMAIL */
30 + "ADR", /* ADDRESS */
31 + "ADR", /* ADDRESS2 - not used */
35 + "ADR", /* COUNTRY */
37 + "TEL", /* WORKPHONE */
39 + "TEL", /* MOBILEPHONE */
40 + "NICKNAME", /* NICK */
43 + NULL /* not implemented: ANNIVERSARY, ITEM_FIELDS */
47 + * mappings between vCard ADR field and abook's ADDRESS
48 + * see rfc2426 section 3.2.1
50 +static int vcard_address_fields[] = {
51 + -1, /* vCard(post office box) - not used */
52 + -1, /* vCard(the extended address) - not used */
53 + 2, /* vCard(the street address) - ADDRESS */
54 + 4, /* vCard(the locality) - CITY */
55 + 5, /* vCard(the region) - STATE */
56 + 6, /* vCard(the postal code) - ZIP */
57 + 7 /* vCard(the country name) - COUNTRY */
62 + VCARD_KEY_ATTRIBUTE,
67 +vcard_get_line_element(char *line, int element)
70 + char *line_copy = 0;
76 + line_copy = xstrdup(line);
78 + /* make newline characters if exist end of string */
79 + for(i=0; line_copy[i]; i++) {
80 + if(line_copy[i] == '\r' || line_copy[i] == '\n') {
81 + line_copy[i] = '\0';
86 + /* separate key from value */
87 + for(i=0; line_copy[i]; i++) {
88 + if(line_copy[i] == ':') {
89 + line_copy[i] = '\0';
91 + value = &line_copy[i+1];
96 + /* separate key from key attributes */
98 + for(i=0; key[i]; i++) {
101 + key_attr = &key[i+1];
110 + result = xstrdup(key);
112 + case VCARD_KEY_ATTRIBUTE:
114 + result = xstrdup(key_attr);
118 + result = xstrdup(value);
127 +vcard_parse_email(list_item item, char *line)
131 + email = vcard_get_line_element(line, VCARD_VALUE);
134 + item[1] = strconcat(item[1], ",", email, 0);
143 +vcard_parse_address(list_item item, char *line)
148 + char *address_field;
150 + value = vcard_get_line_element(line, VCARD_VALUE);
154 + address_field = value;
155 + for(i=k=0; value[i]; i++) {
156 + if(value[i] == ';') {
158 + if(vcard_address_fields[k] >= 0) {
159 + item[vcard_address_fields[k]] = xstrdup(address_field);
161 + address_field = &value[i+1];
163 + if((k+1)==(sizeof(vcard_address_fields)/sizeof(*vcard_address_fields)))
167 + item[vcard_address_fields[k]] = xstrdup(address_field);
172 +vcard_parse_phone(list_item item, char *line)
175 + char *type = vcard_get_line_element(line, VCARD_KEY_ATTRIBUTE);
176 + char *value = vcard_get_line_element(line, VCARD_VALUE);
178 + /* set the standard number */
180 + item[index] = value;
184 + * see rfc2426 section 3.3.1
186 + else if (strstr(type, "TYPE=") == type){
187 + if (strcasestr(type, "home")) {
188 + item[index] = xstrdup(value);
190 + if (strcasestr(type, "work")) {
191 + item[index+1] = xstrdup(value);
193 + if (strcasestr(type, "fax")) {
194 + item[index+2] = xstrdup(value);
196 + if (strcasestr(type, "cell")) {
197 + item[index+3] = xstrdup(value);
206 +vcard_parse_line(list_item item, char *line)
211 + for(i=0; vcard_fields[i]; i++) {
212 + key = vcard_fields[i];
214 + if(!strncmp(key, line, strlen(key))) {
216 + vcard_parse_email(item, line);
219 + vcard_parse_address(item, line);
222 + vcard_parse_phone(item, line);
225 + item[i] = vcard_get_line_element(line, VCARD_VALUE);
233 +vcard_parse_item(FILE *in)
236 + list_item item = item_create();
239 + line = getaline(in);
241 + if(line && !strncmp("END:VCARD", line, 9)) {
246 + vcard_parse_line(item, line);
251 + add_item2database(item);
256 +vcard_parse_file(FILE *in)
261 + line = getaline(in);
263 + if(line && !strncmp("BEGIN:VCARD", line, 11)) {
265 + vcard_parse_item(in);
276 + * end of vCard import filter
280 * csv addressbook export filters
283 diff -ru a/misc.c b/misc.c
284 --- a/misc.c 2006-09-04 21:24:18.000000000 +0200
285 +++ b/misc.c 2008-05-18 18:00:33.000000000 +0200
291 +strcasestr(char *haystack, char *needle)
296 + assert(haystack != NULL);
297 + assert(needle != NULL);
299 + for(i=0; i<strlen(haystack)-strlen(needle)+1; i++) {
300 + for(k=0; k<strlen(needle); k++, i++) {
301 + if (tolower(haystack[i]) != tolower(needle[k]))
303 + else if ((k+1) == strlen(needle))
304 + return &haystack[i];
314 diff -ru a/misc.h b/misc.h
315 --- a/misc.h 2006-09-04 21:24:18.000000000 +0200
316 +++ b/misc.h 2008-05-18 17:55:59.000000000 +0200
319 int is_number(char *s);
321 +char *strcasestr(char *haystack, char *needle);
323 char *strdup_printf(const char *format, ... );
324 char *strconcat(const char *str, ...);