]> code.citadel.org Git - citadel.git/blob - libcitadel/lib/vnote.c
more vnote work
[citadel.git] / libcitadel / lib / vnote.c
1 /*
2  * $Id$
3  *
4  * vNote implementation for Citadel
5  *
6  * Copyright (C) 1999-2007 by the citadel.org development team.
7  * This code is freely redistributable under the terms of the GNU General
8  * Public License.  All other rights reserved.
9  */
10
11
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <signal.h>
17
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
20 # include <time.h>
21 #else
22 # if HAVE_SYS_TIME_H
23 #  include <sys/time.h>
24 # else
25 #  include <time.h>
26 # endif
27 #endif
28
29 #include <ctype.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include <string.h>
34 #include <libcitadel.h>
35
36
37 /* move this into the header file when we're done */
38 #define CTDL_VNOTE_MAGIC        0xa1fa
39 struct vnote {
40         int magic;
41         char *uid;
42         char *summary;
43         char *body;
44         int pos_left;
45         int pos_top;
46         int pos_width;
47         int pos_height;
48         int color_red;
49         int color_green;
50         int color_blue;
51 };
52
53
54 struct vnote *vnote_new(void) {
55         struct vnote *v;
56
57         v = (struct vnote *) malloc(sizeof(struct vnote));
58         if (v) {
59                 memset(v, 0, sizeof(struct vnote));
60                 v->magic = CTDL_VNOTE_MAGIC;
61                 v->pos_left = rand() % 256;
62                 v->pos_top = rand() % 256;
63                 v->pos_width = 200;
64                 v->pos_height = 150;
65                 v->color_red = 0xFF;
66                 v->color_green = 0xFF;
67                 v->color_blue = 0x00;
68         }
69         return v;
70 }
71
72 struct vnote *vnote_new_from_str(char *s) {
73         struct vnote *v;
74         char *ptr = s;
75         char *nexteol;
76         char *thisline;
77         int thisline_len;
78         char *encoded_value;
79         char *decoded_value;
80         int is_quoted_printable;
81         int is_base64;
82
83         v = vnote_new();
84         if (!v) return NULL;
85
86         while (*ptr) {          // keep going until we hit a null terminator
87                 thisline = NULL;
88                 nexteol = strchr(ptr, '\n');
89                 if (nexteol) {
90                         thisline = malloc((nexteol - ptr) + 2);
91                         strncpy(thisline, ptr, (nexteol-ptr));
92                         thisline_len = (nexteol-ptr);
93                         thisline[thisline_len] = 0;
94                         ptr = nexteol + 1;
95                 }
96                 else {
97                         thisline = strdup(ptr);
98                         thisline_len = strlen(thisline);
99                         ptr += thisline_len;
100                 }
101
102                 if (thisline) {
103                         if (thisline_len > 1) {
104                                 if (thisline[thisline_len - 1] == '\r') {
105                                         thisline[thisline_len - 1] = 0;
106                                         --thisline_len;
107                                 }
108                         }
109
110                         /* locate the colon separator */
111                         encoded_value = strchr(thisline, ':');
112                         if (encoded_value) {
113                                 *encoded_value++ = 0;
114
115                                 /* any qualifiers?  (look for a semicolon) */
116                                 is_base64 = 0;
117                                 is_quoted_printable = 0;
118
119
120                                 decoded_value = malloc(thisline_len);
121                                 if (is_base64) {
122                                 }
123                                 else if (is_quoted_printable) {
124                                 }
125                                 else {
126                                         strcpy(decoded_value, thisline_len);
127                                 }
128
129                                 if (0) {
130                                 }
131                                 else {
132                                         free(decoded_value);    // throw it away
133                                 }
134
135
136                         }
137                         free(thisline);
138                 }
139         }
140
141         return(v);
142 }
143
144 void vnote_free(struct vnote *v) {
145         if (!v) return;
146         if (v->magic != CTDL_VNOTE_MAGIC) return;
147
148         if (v->uid) free(v->uid);
149         if (v->summary) free(v->summary);
150         if (v->body) free(v->body);
151         
152         memset(v, 0, sizeof(struct vnote));
153         free(v);
154 }
155
156
157 /* helper function for vnote_serialize() */
158 void vnote_serialize_output_field(char *append_to, char *field, char *label) {
159
160         char *mydup;
161         int output_len = 0;
162         int is_qp = 0;
163         char *ptr = field;
164         unsigned char ch;
165         int pos = 0;
166
167         if (!append_to) return;
168         if (!field) return;
169         if (!label) return;
170
171         mydup = malloc((strlen(field) * 3) + 1);
172         if (!mydup) return;
173         strcpy(mydup, "");
174
175         while (ptr[pos] != 0) {
176                 ch = (unsigned char)(ptr[pos++]);
177
178                 if (ch == 9) {
179                         mydup[output_len++] = ch;
180                 }
181                 else if ( (ch >= 32) && (ch <= 60) ) {
182                         mydup[output_len++] = ch;
183                 }
184                 else if ( (ch >= 62) && (ch <= 126) ) {
185                         mydup[output_len++] = ch;
186                 }
187                 else {
188                         sprintf((char *)&mydup[output_len], "=%02X", ch);
189                         output_len += 3;
190                         is_qp = 1;
191                 }
192         }
193         mydup[output_len] = 0;
194
195         sprintf(&append_to[strlen(append_to)], "%s%s:%s\r\n",
196                 label,
197                 (is_qp ? ";ENCODING=QUOTED-PRINTABLE" : ""),
198                 mydup);
199         free(mydup);
200 }
201
202
203 char *vnote_serialize(struct vnote *v) {
204         char *s;
205         int bytes_needed = 0;
206
207         if (!v) return NULL;
208         if (v->magic != CTDL_VNOTE_MAGIC) return NULL;
209
210         bytes_needed = 1024;
211         if (v->summary) bytes_needed += strlen(v->summary);
212         if (v->body) bytes_needed += strlen(v->body);
213         s = malloc(bytes_needed);
214         if (!s) return NULL;
215
216         strcpy(s, "");
217         vnote_serialize_output_field(s, "vnote", "BEGIN");
218         vnote_serialize_output_field(s, "//Citadel//vNote handler library//EN", "PRODID");
219         vnote_serialize_output_field(s, "1.1", "VERSION");
220         vnote_serialize_output_field(s, "PUBLIC", "CLASS");
221         vnote_serialize_output_field(s, v->uid, "UID");
222         vnote_serialize_output_field(s, v->body, "BODY");
223         vnote_serialize_output_field(s, v->body, "NOTE");
224         sprintf(&s[strlen(s)], "X-OUTLOOK-COLOR:#%02X%02X%02X\r\n",
225                 v->color_red, v->color_green, v->color_blue);
226         sprintf(&s[strlen(s)], "X-OUTLOOK-LEFT:%d\r\n", v->pos_left);
227         sprintf(&s[strlen(s)], "X-OUTLOOK-TOP:%d\r\n", v->pos_top);
228         sprintf(&s[strlen(s)], "X-OUTLOOK-WIDTH:%d\r\n", v->pos_width);
229         sprintf(&s[strlen(s)], "X-OUTLOOK-HEIGHT:%d\r\n", v->pos_height);
230         vnote_serialize_output_field(s, "vnote", "END");
231         return(s);
232 }
233
234
235 #ifdef VNOTE_TEST_HARNESS
236
237 char *bynari_sample =
238         "BEGIN:vnote\n"
239         "VERSION:1.1\n"
240         "PRODID://Bynari Insight Connector 3.1.3-0605191//Import from Outlook//EN\n"
241         "CLASS:PUBLIC\n"
242         "UID:040000008200E00074C5B7101A82E00800000000000000000000000000820425CE8571864B8D141CB3FB8CAC62\n"
243         "NOTE;ENCODING=QUOTED-PRINTABLE:blah blah blah=0D=0A=0D=0A\n"
244         "SUMMARY:blah blah blah=0D=0A=0D=0A\n"
245         "X-OUTLOOK-COLOR:#FFFF00\n"
246         "X-OUTLOOK-WIDTH:200\n"
247         "X-OUTLOOK-HEIGHT:166\n"
248         "X-OUTLOOK-LEFT:80\n"
249         "X-OUTLOOK-TOP:80\n"
250         "X-OUTLOOK-CREATE-TIME:20070611T204615Z\n"
251         "REV:20070611T204621Z\n"
252         "END:vnote"
253 ;
254
255 char *horde_sample =
256         "BEGIN:VNOTE\n"
257         "VERSION:1.1\n"
258         "UID:20061129111109.7chx73xdok1s at 172.16.45.2\n"
259         "BODY:HORDE_1\n"
260         "DCREATED:20061129T101109Z\n"
261         "END:VNOTE\n"
262 ;
263
264
265 main() {
266         char *s;
267         struct vnote *v;
268
269         printf("Before:\n-------------\n%s-------------\nAfter:\n-----------\n", bynari_sample);
270         v = vnote_new_from_str(bynari_sample);
271         s = vnote_serialize(v);
272         vnote_free(v);
273         if (s) {
274                 printf("%s", s);
275                 free(s);
276         }
277
278         exit(0);
279 }
280 #endif
281
282
283
284
285