2 * vNote implementation for Citadel
4 * Copyright (C) 1999-2007 by the citadel.org development team.
6 * This program is open source software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #if TIME_WITH_SYS_TIME
29 # include <sys/time.h>
33 # include <sys/time.h>
44 #include <libcitadel.h>
47 struct vnote *vnote_new(void) {
50 v = (struct vnote *) malloc(sizeof(struct vnote));
52 memset(v, 0, sizeof(struct vnote));
53 v->magic = CTDL_VNOTE_MAGIC;
54 v->pos_left = rand() % 256;
55 v->pos_top = rand() % 256;
59 v->color_green = 0xFF;
65 struct vnote *vnote_new_from_str(char *s) {
73 int is_quoted_printable;
79 while (*ptr) { // keep going until we hit a null terminator
81 nexteol = strchr(ptr, '\n');
83 thisline_len = (nexteol-ptr);
84 thisline = malloc(thisline_len + 2);
85 memcpy(thisline, ptr, thisline_len);
86 thisline[thisline_len] = '\0';
90 thisline = strdup(ptr);
91 thisline_len = strlen(thisline);
96 if (thisline_len > 1) {
97 if (thisline[thisline_len - 1] == '\r') {
98 thisline[thisline_len - 1] = 0;
103 /* locate the colon separator */
104 encoded_value = strchr(thisline, ':');
106 *encoded_value++ = 0;
108 /* any qualifiers? (look for a semicolon) */
109 is_base64 = bmstrcasestr(thisline, "encoding=base64") ? 1 : 0;
110 is_quoted_printable = bmstrcasestr(thisline, "encoding=quoted-printable") ? 1 : 0;
112 char *semicolon_pos = strchr(thisline, ';');
117 decoded_value = malloc(thisline_len);
119 CtdlDecodeBase64(decoded_value,
121 strlen(encoded_value));
123 else if (is_quoted_printable) {
124 CtdlDecodeQuotedPrintable(decoded_value,
126 strlen(encoded_value));
129 strcpy(decoded_value, encoded_value);
132 if (!strcasecmp(thisline, "UID")) {
133 if (v->uid) free(v->uid);
134 v->uid = decoded_value;
136 else if (!strcasecmp(thisline, "SUMMARY")) {
137 if (v->summary) free(v->summary);
138 v->summary = decoded_value;
140 else if ( (!strcasecmp(thisline, "NOTE"))
141 || (!strcasecmp(thisline, "BODY")) ) {
142 if (v->body) free(v->body);
143 v->body = decoded_value;
145 else if (!strcasecmp(thisline, "X-OUTLOOK-WIDTH")) {
146 v->pos_width = atoi(decoded_value);
149 else if (!strcasecmp(thisline, "X-OUTLOOK-HEIGHT")) {
150 v->pos_height = atoi(decoded_value);
153 else if (!strcasecmp(thisline, "X-OUTLOOK-LEFT")) {
154 v->pos_left = atoi(decoded_value);
157 else if (!strcasecmp(thisline, "X-OUTLOOK-TOP")) {
158 v->pos_top = atoi(decoded_value);
161 else if ( (!strcasecmp(thisline, "X-OUTLOOK-COLOR"))
162 && (strlen(decoded_value) == 7)
163 && (decoded_value[0] == '#') ) {
164 sscanf(&decoded_value[1], "%2x%2x%2x",
171 free(decoded_value); // throw it away
174 /* FIXME still need to handle these:
175 * X-OUTLOOK-CREATE-TIME:20070611T204615Z
176 * REV:20070611T204621Z
186 void vnote_free(struct vnote *v) {
188 if (v->magic != CTDL_VNOTE_MAGIC) return;
190 if (v->uid) free(v->uid);
191 if (v->summary) free(v->summary);
192 if (v->body) free(v->body);
194 memset(v, 0, sizeof(struct vnote));
199 /* helper function for vnote_serialize() */
200 void vnote_serialize_output_field(char *append_to, char *field, char *label) {
209 if (!append_to) return;
213 mydup = malloc((strlen(field) * 3) + 1);
217 while (ptr[pos] != 0) {
218 ch = (unsigned char)(ptr[pos++]);
221 mydup[output_len++] = ch;
223 else if ( (ch >= 32) && (ch <= 60) ) {
224 mydup[output_len++] = ch;
226 else if ( (ch >= 62) && (ch <= 126) ) {
227 mydup[output_len++] = ch;
230 sprintf((char *)&mydup[output_len], "=%02X", ch);
235 mydup[output_len] = 0;
237 sprintf(&append_to[strlen(append_to)], "%s%s:%s\r\n",
239 (is_qp ? ";ENCODING=QUOTED-PRINTABLE" : ""),
245 char *vnote_serialize(struct vnote *v) {
247 int bytes_needed = 0;
250 if (v->magic != CTDL_VNOTE_MAGIC) return NULL;
253 if (v->summary) bytes_needed += strlen(v->summary);
254 if (v->body) bytes_needed += strlen(v->body);
255 s = malloc(bytes_needed);
259 vnote_serialize_output_field(s, "vnote", "BEGIN");
260 vnote_serialize_output_field(s, "//Citadel//vNote handler library//EN", "PRODID");
261 vnote_serialize_output_field(s, "1.1", "VERSION");
262 vnote_serialize_output_field(s, "PUBLIC", "CLASS");
263 vnote_serialize_output_field(s, v->uid, "UID");
264 vnote_serialize_output_field(s, v->summary, "SUMMARY");
265 vnote_serialize_output_field(s, v->body, "BODY");
266 vnote_serialize_output_field(s, v->body, "NOTE");
267 sprintf(&s[strlen(s)], "X-OUTLOOK-COLOR:#%02X%02X%02X\r\n",
268 v->color_red, v->color_green, v->color_blue);
269 sprintf(&s[strlen(s)], "X-OUTLOOK-LEFT:%d\r\n", v->pos_left);
270 sprintf(&s[strlen(s)], "X-OUTLOOK-TOP:%d\r\n", v->pos_top);
271 sprintf(&s[strlen(s)], "X-OUTLOOK-WIDTH:%d\r\n", v->pos_width);
272 sprintf(&s[strlen(s)], "X-OUTLOOK-HEIGHT:%d\r\n", v->pos_height);
273 vnote_serialize_output_field(s, "vnote", "END");