// The code in here feeds messages out as JSON to the client browser. It is currently being used
// for the forum view, but as we implement other views we'll probably reuse a lot of what's here.
//
-// Copyright (c) 1996-2022 by the citadel.org team
+// Copyright (c) 1996-2023 by the citadel.org team
//
-// This program is open source software. Use, duplication, or
-// disclosure are subject to the GNU General Public License v3.
+// This program is open source software. Use, duplication, or disclosure is subject to the GNU General Public License v3.
#include "webcit.h"
}
+// Convenience function for json_render_one_message()
+// Converts a string of comma-separated recipients into a JSON Array
+JsonValue *json_tokenize_recipients(const char *Key, long keylen, char *recp) {
+ char tokbuf[1024];
+
+ JsonValue *j = NewJsonArray(Key, keylen);
+ int num_recp = num_tokens(recp, ',');
+ for (int i=0; i<num_recp; ++i) {
+ extract_token(tokbuf, recp, i, ',', sizeof(tokbuf));
+ string_trim(tokbuf);
+ JsonArrayAppend(j, NewJsonPlainString(HKEY("r"), tokbuf, strlen(tokbuf)));
+ }
+ return(j);
+}
+
+
// Fetch a single message and return it in JSON format for client-side rendering
void json_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum) {
StrBuf *raw_msg = NULL;
char content_transfer_encoding[1024] = { 0 };
char content_type[1024] = { 0 };
char datetime[128] = { 0 };
- char author[1024] = { 0 };
- char emailaddr[1024] = { 0 };
int message_originated_locally = 0;
setup_for_forum_view(c);
return;
}
- JsonValue *j = NewJsonObject(HKEY("message"));
+ JsonValue *attachments = NULL;
+
+ JsonValue *j = NewJsonObject(HKEY(""));
JsonObjectAppend(j, NewJsonNumber(HKEY("msgnum"), msgnum));
while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "text")) && (strcmp(buf, "000"))) {
// citadel header parsing here
if (!strncasecmp(buf, "from=", 5)) {
- safestrncpy(author, &buf[5], sizeof author);
+ JsonObjectAppend(j, NewJsonPlainString(HKEY("from"), &buf[5], -1));
}
else if (!strncasecmp(buf, "rfca=", 5)) {
- safestrncpy(emailaddr, &buf[5], sizeof emailaddr);
+ JsonObjectAppend(j, NewJsonPlainString(HKEY("rfca"), &buf[5], -1));
}
else if (!strncasecmp(buf, "time=", 5)) {
JsonObjectAppend(j, NewJsonNumber(HKEY("time"), atol(&buf[5])));
else if (!strncasecmp(buf, "wefw=", 5)) {
JsonObjectAppend(j, NewJsonPlainString(HKEY("wefw"), &buf[5], -1));
}
+ else if (!strncasecmp(buf, "rcpt=", 5)) {
+ JsonObjectAppend(j, json_tokenize_recipients(HKEY("rcpt"), &buf[5]));
+ }
+ else if (!strncasecmp(buf, "cccc=", 5)) {
+ JsonObjectAppend(j, json_tokenize_recipients(HKEY("cccc"), &buf[5]));
+ }
+ else if (!strncasecmp(buf, "part=", 5)) {
+ if (attachments == NULL) {
+ attachments = NewJsonArray(HKEY("part"));
+ }
+ JsonValue *part = NewJsonObject(HKEY(""));
+ char tokbuf[1024];
+ extract_token(tokbuf, &buf[5], 0, '|', sizeof tokbuf);
+ JsonObjectAppend(part, NewJsonPlainString(HKEY("name"), tokbuf, -1));
+ extract_token(tokbuf, &buf[5], 1, '|', sizeof tokbuf);
+ JsonObjectAppend(part, NewJsonPlainString(HKEY("filename"), tokbuf, -1));
+ extract_token(tokbuf, &buf[5], 2, '|', sizeof tokbuf);
+ JsonObjectAppend(part, NewJsonPlainString(HKEY("partnum"), tokbuf, -1));
+ extract_token(tokbuf, &buf[5], 3, '|', sizeof tokbuf);
+ JsonObjectAppend(part, NewJsonPlainString(HKEY("disp"), tokbuf, -1));
+ extract_token(tokbuf, &buf[5], 4, '|', sizeof tokbuf);
+ JsonObjectAppend(part, NewJsonPlainString(HKEY("type"), tokbuf, -1));
+ JsonObjectAppend(part, NewJsonNumber(HKEY("len"), extract_long(&buf[5], 5)));
+ extract_token(tokbuf, &buf[5], 6, '|', sizeof tokbuf);
+ JsonObjectAppend(part, NewJsonPlainString(HKEY("id"), tokbuf, -1));
+ extract_token(tokbuf, &buf[5], 7, '|', sizeof tokbuf);
+ JsonObjectAppend(part, NewJsonPlainString(HKEY("charset"), tokbuf, -1));
+ JsonArrayAppend(attachments, part);
+ }
+ else {
+ // unhandled header
+ }
}
-
- if (message_originated_locally) {
- JsonObjectAppend(j, NewJsonPlainString(HKEY("from"), author, -1));
- }
- else {
- JsonObjectAppend(j, NewJsonPlainString(HKEY("from"), emailaddr, -1)); // FIXME do compound address string
+ JsonObjectAppend(j, NewJsonNumber(HKEY("locl"), message_originated_locally));
+ if (attachments != NULL) {
+ JsonObjectAppend(j, attachments);
}
if (!strcmp(buf, "text")) {
while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "")) && (strcmp(buf, "000"))) {
- // rfc822 header parsing here
+ // RFC822 header parsing here
if (!strncasecmp(buf, "Content-transfer-encoding:", 26)) {
strcpy(content_transfer_encoding, &buf[26]);
- striplt(content_transfer_encoding);
+ string_trim(content_transfer_encoding);
}
if (!strncasecmp(buf, "Content-type:", 13)) {
strcpy(content_type, &buf[13]);
- striplt(content_type);
+ string_trim(content_type);
}
}
if (!strcmp(buf, "000")) { // if we have an empty message, don't try to read further