]> git.deb.at Git - pkg/abook.git/blob - vcard.c
f86d610e0e8df762b5ab65e26c31a3cb391dab0f
[pkg/abook.git] / vcard.c
1
2 /*
3  * Copyright 2012, RaphaĆ«l Droz <raphael.droz+floss@gmail.com>
4  *
5  * abook's wrapper for libvformat:
6  * fits a vcard parsed by libvformat into a usable abook item list
7  *
8  * see:
9  * libvformat's vf_iface.h
10  * http://www.imc.org/pdi/vcard-21.txt
11  * rfc 2426
12  * rfc 2739
13  */
14
15 #include <stdio.h>
16 #include <string.h>
17
18 #include "database.h"
19 #include "xmalloc.h"
20
21 #include "vcard.h"
22
23 int vcard_parse_file_libvformat(char *filename) {
24   VF_OBJECT_T*  vfobj;
25   if (!vf_read_file(&vfobj, filename)) {
26     fprintf(stderr, "Could not read VCF file %s\n", filename);
27     return 1;
28   }
29
30   // a libvformat property
31   VF_PROP_T* prop;
32   // property number (used for multivalued properties)
33   int props = 0;
34   // temporary values
35   char *propval;
36   char multival[MAX_FIELD_LEN] = { 0 };
37   size_t available = MAX_FIELD_LEN;
38
39   do {
40     list_item item = item_create();
41
42     // fullname [ or struct-name [ or name ] ]
43     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "FN", NULL))
44       if ((propval = vf_get_prop_value_string(prop, 0)))
45         item_fput(item, NAME, xstrdup(propval));
46
47     if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "N", "*", NULL)) {
48       // TODO: GIVENNAME , FAMILYNAME
49       propval = vf_get_prop_value_string(prop, 0);
50       if(propval)
51         item_fput(item, NAME, xstrdup(propval));
52     }
53
54     if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NAME", NULL)) {
55       propval = vf_get_prop_value_string(prop, 0);
56       if(propval)
57         item_fput(item, NAME, xstrdup(propval));
58     }
59
60     // email(s)
61     // TODO: use our strconcat() ?
62     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "EMAIL", NULL)) {
63       props = 0;
64       available = MAX_FIELD_LEN;
65       while (available > 0 && props < 5) {
66         propval = vf_get_prop_value_string(prop, props++);
67         if(!propval) continue;
68         if (available > 0 && *multival != 0)
69           strncat(multival, ",", available--);
70         strncat(multival, propval, available);
71         available -= strlen(propval);
72       }
73       if (available < MAX_FIELD_LEN)
74         item_fput(item, EMAIL, xstrdup(multival));
75     }
76
77     // format for ADR:
78     // PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country
79     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", NULL)) {
80       props = 0;
81       // US address ?
82       propval = vf_get_prop_value_string(prop, props++);
83       if(propval)
84         item_fput(item, ADDRESS, xstrdup(propval));
85       // address
86       propval = vf_get_prop_value_string(prop, props++);
87       // TODO: concat ?
88
89       // street: TODO: address1 instead ?
90       propval = vf_get_prop_value_string(prop, props++);
91       if(propval)
92         item_fput(item, ADDRESS2, xstrdup(propval));
93       // city
94       propval = vf_get_prop_value_string(prop, props++);
95       if(propval)
96         item_fput(item, CITY, xstrdup(propval));
97       // state
98       propval = vf_get_prop_value_string(prop, props++);
99       if(propval)
100         item_fput(item, STATE, xstrdup(propval));
101       propval = vf_get_prop_value_string(prop, props++);
102       if(propval)
103         item_fput(item, ZIP, xstrdup(propval));
104       propval = vf_get_prop_value_string(prop, props++);
105       if(propval)
106         item_fput(item, COUNTRY, xstrdup(propval));
107     }
108
109
110     /*
111     // city: not in libvformat
112     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", "CITY", NULL)) {
113       propval = vf_get_prop_value_string(prop, 0);
114       item_fput(item, CITY, xstrdup(propval));
115     }
116     // state
117     // zip
118     // country
119     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "C", NULL)) {
120       propval = vf_get_prop_value_string(prop, 0);
121       item_fput(item, COUNTRY, xstrdup(propval));
122     }
123     */
124
125     // phone
126     // check for HOME
127     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "HOME")) {
128       propval = vf_get_prop_value_string(prop, 0);
129       item_fput(item, PHONE, xstrdup(propval));
130     }
131     // or grab a more generic one otherwise
132     else if(vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", NULL)) {
133       propval = vf_get_prop_value_string(prop, 0);
134       item_fput(item, PHONE, xstrdup(propval));
135     }
136
137     // workphone
138     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "WORK", NULL)) {
139       propval = vf_get_prop_value_string(prop, 0);
140       item_fput(item, WORKPHONE, xstrdup(propval));
141     }
142
143     // fax
144     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "FAX", NULL)) {
145       propval = vf_get_prop_value_string(prop, 0);
146       item_fput(item, FAX, xstrdup(propval));
147     }
148
149     // cellphone
150     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "CELL", NULL)) {
151       propval = vf_get_prop_value_string(prop, 0);
152       item_fput(item, MOBILEPHONE, xstrdup(propval));
153     }
154
155     // nick
156     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NICKNAME", NULL)) {
157       propval = vf_get_prop_value_string(prop, 0);
158       item_fput(item, NICK, xstrdup(propval));
159     }
160
161     // url
162     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "URL", NULL)) {
163       propval = vf_get_prop_value_string(prop, 0);
164       item_fput(item, URL, xstrdup(propval));
165     }
166
167     // notes
168     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NOTE", NULL)) {
169       propval = vf_get_prop_value_string(prop, 0);
170       item_fput(item, NOTES, xstrdup(propval));
171     }
172
173     // anniversary
174     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "BDAY", NULL)) {
175       propval = vf_get_prop_value_string(prop, 0);
176       item_fput(item, ANNIVERSARY, xstrdup(propval));
177     }
178
179     // (mutt) groups
180     if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "CATEGORIES", NULL)) {
181         props = 0;
182         available = MAX_FIELD_LEN;
183         *multival = 0;
184         while (available > 0 && props < 5) {
185           propval = vf_get_prop_value_string(prop, props++);
186           if(!propval) continue;
187           if (available > 0 && *multival != 0)
188             strncat(multival, ",", available--);
189           strncat(multival, propval, available);
190           available -= strlen(propval);
191         }
192         if (available < MAX_FIELD_LEN)
193           item_fput(item, GROUPS, xstrdup(multival));
194     }
195
196     add_item2database(item);
197     item_free(&item);
198   } while (vf_get_next_object(&vfobj));
199
200   return 0;
201 }