4 * Handles functions related to yellow sticky notes.
16 #include <sys/types.h>
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
23 # include <sys/time.h>
32 #include <libcitadel.h>
35 #include "citserver.h"
44 #include "ctdl_module.h"
48 * Callback function for serv_notes_beforesave() hunts for a vNote in the MIME structure
50 void notes_extract_vnote(char *name
, char *filename
, char *partnum
, char *disp
,
51 void *content
, char *cbtype
, char *cbcharset
, size_t length
,
52 char *encoding
, char *cbid
, void *cbuserdata
)
54 struct vnote
**v
= (struct vnote
**) cbuserdata
;
56 if (!strcasecmp(cbtype
, "text/vnote")) {
58 CtdlLogPrintf(CTDL_DEBUG
, "Part %s contains a vNote! Loading...\n", partnum
);
62 *v
= vnote_new_from_str(content
);
68 * Before-save hook searches for two different types of notes (legacy Kolab/Aethera notes
69 * and modern vNote format notes) and does its best to learn the subject (summary)
70 * and EUID (uid) of the note for Citadel's own nefarious purposes.
72 int serv_notes_beforesave(struct CtdlMessage
*msg
)
77 struct vnote
*v
= NULL
;
79 /* First determine if this room has the "notes" view set */
81 if (CC
->room
.QRdefaultview
!= VIEW_NOTES
) {
82 return(0); /* not notes; do nothing */
85 /* It must be an RFC822 message! */
86 if (msg
->cm_format_type
!= 4) {
87 return(0); /* You tried to save a non-RFC822 message! */
91 * If we are in a "notes" view room, and the client has sent an RFC822
92 * message containing an X-KOrg-Note-Id: field (Aethera does this, as
93 * do some Kolab clients) then set both the Subject and the Exclusive ID
94 * of the message to that. It's going to be a UUID so we want to replace
95 * any existing message containing that UUID.
98 p
= msg
->cm_fields
['M'];
101 if (!strncasecmp(p
, "X-KOrg-Note-Id: ", 16)) { /* Found it */
102 safestrncpy(uuid
, p
+ 16, sizeof(uuid
));
103 for (i
= 0; uuid
[i
]; ++i
) {
104 if ( (uuid
[i
] == '\r') || (uuid
[i
] == '\n') ) {
110 CtdlLogPrintf(9, "UUID of note is: %s\n", uuid
);
111 if (!IsEmptyStr(uuid
)) {
113 if (msg
->cm_fields
['E'] != NULL
) {
114 free(msg
->cm_fields
['E']);
116 msg
->cm_fields
['E'] = strdup(uuid
);
118 if (msg
->cm_fields
['U'] != NULL
) {
119 free(msg
->cm_fields
['U']);
121 msg
->cm_fields
['U'] = strdup(uuid
);
127 /* Modern clients are using vNote format. Check for one... */
129 mime_parser(msg
->cm_fields
['M'],
131 *notes_extract_vnote
,
133 &v
, /* user data ptr - put the vnote here */
137 if (v
== NULL
) return(0); /* no vNotes were found in this message */
139 /* Set the message EUID to the vNote UID */
141 if (v
->uid
) if (!IsEmptyStr(v
->uid
)) {
142 CtdlLogPrintf(9, "UID of vNote is: %s\n", v
->uid
);
143 if (msg
->cm_fields
['E'] != NULL
) {
144 free(msg
->cm_fields
['E']);
146 msg
->cm_fields
['E'] = strdup(v
->uid
);
149 /* Set the message Subject to the vNote Summary */
151 if (v
->summary
) if (!IsEmptyStr(v
->summary
)) {
152 if (msg
->cm_fields
['U'] != NULL
) {
153 free(msg
->cm_fields
['U']);
155 msg
->cm_fields
['U'] = strdup(v
->summary
);
156 if (strlen(msg
->cm_fields
['U']) > 72) {
157 strcpy(&msg
->cm_fields
['U'][68], "...");
167 CTDL_MODULE_INIT(notes
)
171 CtdlRegisterMessageHook(serv_notes_beforesave
, EVT_BEFORESAVE
);
174 /* return our Subversion id for the Log */