4 * vNote implementation for Citadel
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.
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
23 # include <sys/time.h>
34 #include <libcitadel.h>
37 struct vnote *vnote_new(void) {
40 v = (struct vnote *) malloc(sizeof(struct vnote));
42 memset(v, 0, sizeof(struct vnote));
43 v->magic = CTDL_VNOTE_MAGIC;
44 v->pos_left = rand() % 256;
45 v->pos_top = rand() % 256;
49 v->color_green = 0xFF;
55 struct vnote *vnote_new_from_str(char *s) {
63 int is_quoted_printable;
69 while (*ptr) { // keep going until we hit a null terminator
71 nexteol = strchr(ptr, '\n');
73 thisline = malloc((nexteol - ptr) + 2);
74 strncpy(thisline, ptr, (nexteol-ptr));
75 thisline_len = (nexteol-ptr);
76 thisline[thisline_len] = 0;
80 thisline = strdup(ptr);
81 thisline_len = strlen(thisline);
86 if (thisline_len > 1) {
87 if (thisline[thisline_len - 1] == '\r') {
88 thisline[thisline_len - 1] = 0;
93 /* locate the colon separator */
94 encoded_value = strchr(thisline, ':');
98 /* any qualifiers? (look for a semicolon) */
99 is_base64 = bmstrcasestr(thisline, "encoding=base64") ? 1 : 0;
100 is_quoted_printable = bmstrcasestr(thisline, "encoding=quoted-printable") ? 1 : 0;
102 char *semicolon_pos = strchr(thisline, ';');
107 decoded_value = malloc(thisline_len);
109 CtdlDecodeBase64(decoded_value,
111 strlen(encoded_value));
113 else if (is_quoted_printable) {
114 CtdlDecodeQuotedPrintable(decoded_value,
116 strlen(encoded_value));
119 strcpy(decoded_value, encoded_value);
122 if (!strcasecmp(thisline, "UID")) {
123 if (v->uid) free(v->uid);
124 v->uid = decoded_value;
126 else if (!strcasecmp(thisline, "SUMMARY")) {
127 if (v->summary) free(v->summary);
128 v->summary = decoded_value;
130 else if ( (!strcasecmp(thisline, "NOTE"))
131 || (!strcasecmp(thisline, "BODY")) ) {
132 if (v->body) free(v->body);
133 v->body = decoded_value;
135 else if (!strcasecmp(thisline, "X-OUTLOOK-WIDTH")) {
136 v->pos_width = atoi(decoded_value);
139 else if (!strcasecmp(thisline, "X-OUTLOOK-HEIGHT")) {
140 v->pos_height = atoi(decoded_value);
143 else if (!strcasecmp(thisline, "X-OUTLOOK-LEFT")) {
144 v->pos_left = atoi(decoded_value);
147 else if (!strcasecmp(thisline, "X-OUTLOOK-TOP")) {
148 v->pos_top = atoi(decoded_value);
151 else if ( (!strcasecmp(thisline, "X-OUTLOOK-COLOR"))
152 && (strlen(decoded_value) == 7)
153 && (decoded_value[0] == '#') ) {
154 sscanf(&decoded_value[1], "%2x%2x%2x",
161 free(decoded_value); // throw it away
164 /* FIXME still need to handle these:
165 * X-OUTLOOK-CREATE-TIME:20070611T204615Z
166 * REV:20070611T204621Z
176 void vnote_free(struct vnote *v) {
178 if (v->magic != CTDL_VNOTE_MAGIC) return;
180 if (v->uid) free(v->uid);
181 if (v->summary) free(v->summary);
182 if (v->body) free(v->body);
184 memset(v, 0, sizeof(struct vnote));
189 /* helper function for vnote_serialize() */
190 void vnote_serialize_output_field(char *append_to, char *field, char *label) {
199 if (!append_to) return;
203 mydup = malloc((strlen(field) * 3) + 1);
207 while (ptr[pos] != 0) {
208 ch = (unsigned char)(ptr[pos++]);
211 mydup[output_len++] = ch;
213 else if ( (ch >= 32) && (ch <= 60) ) {
214 mydup[output_len++] = ch;
216 else if ( (ch >= 62) && (ch <= 126) ) {
217 mydup[output_len++] = ch;
220 sprintf((char *)&mydup[output_len], "=%02X", ch);
225 mydup[output_len] = 0;
227 sprintf(&append_to[strlen(append_to)], "%s%s:%s\r\n",
229 (is_qp ? ";ENCODING=QUOTED-PRINTABLE" : ""),
235 char *vnote_serialize(struct vnote *v) {
237 int bytes_needed = 0;
240 if (v->magic != CTDL_VNOTE_MAGIC) return NULL;
243 if (v->summary) bytes_needed += strlen(v->summary);
244 if (v->body) bytes_needed += strlen(v->body);
245 s = malloc(bytes_needed);
249 vnote_serialize_output_field(s, "vnote", "BEGIN");
250 vnote_serialize_output_field(s, "//Citadel//vNote handler library//EN", "PRODID");
251 vnote_serialize_output_field(s, "1.1", "VERSION");
252 vnote_serialize_output_field(s, "PUBLIC", "CLASS");
253 vnote_serialize_output_field(s, v->uid, "UID");
254 vnote_serialize_output_field(s, v->summary, "SUMMARY");
255 vnote_serialize_output_field(s, v->body, "BODY");
256 vnote_serialize_output_field(s, v->body, "NOTE");
257 sprintf(&s[strlen(s)], "X-OUTLOOK-COLOR:#%02X%02X%02X\r\n",
258 v->color_red, v->color_green, v->color_blue);
259 sprintf(&s[strlen(s)], "X-OUTLOOK-LEFT:%d\r\n", v->pos_left);
260 sprintf(&s[strlen(s)], "X-OUTLOOK-TOP:%d\r\n", v->pos_top);
261 sprintf(&s[strlen(s)], "X-OUTLOOK-WIDTH:%d\r\n", v->pos_width);
262 sprintf(&s[strlen(s)], "X-OUTLOOK-HEIGHT:%d\r\n", v->pos_height);
263 vnote_serialize_output_field(s, "vnote", "END");