-/*
- * JSON data type and serializer for Citadel
- *
- * Copyright (c) 1987-2018 by the citadel.org team
- *
+//
+// JSON data type and serializer for Citadel
+//
+// Copyright (c) 1987-2018 by the citadel.org team
+//
// This program is open source software. Use, duplication, or disclosure
// is subject to the terms of the GNU General Public License, version 3.
- */
#include "sysdep.h"
#include <sys/types.h>
#define JSON_ARRAY 4
#define JSON_OBJECT 7
-struct JsonValue
-{
+struct JsonValue {
int Type;
StrBuf *Name;
StrBuf *Value;
};
-void DeleteJSONValue(void *vJsonValue)
-{
+void DeleteJSONValue(void *vJsonValue) {
JsonValue *Val = (JsonValue*) vJsonValue;
FreeStrBuf(&Val->Name);
FreeStrBuf(&Val->Value);
}
-JsonValue *NewJsonObject(const char *Key, long keylen)
-{
+JsonValue *NewJsonObject(const char *Key, long keylen) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
memset(Ret, 0, sizeof(JsonValue));
Ret->Type = JSON_OBJECT;
- if (Key != NULL)
- {
+ if (Key != NULL) {
Ret->Name = NewStrBufPlain(Key, keylen);
}
Ret->SubValues = NewHash(1, NULL);
}
-JsonValue *NewJsonArray(const char *Key, long keylen)
-{
+JsonValue *NewJsonArray(const char *Key, long keylen) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
memset(Ret, 0, sizeof(JsonValue));
Ret->Type = JSON_ARRAY;
- if (Key != NULL)
- {
+ if (Key != NULL) {
Ret->Name = NewStrBufPlain(Key, keylen);
}
Ret->SubValues = NewHash(1, lFlathash);
}
-JsonValue *NewJsonNumber(const char *Key, long keylen, long Number)
-{
+JsonValue *NewJsonNumber(const char *Key, long keylen, long Number) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
memset(Ret, 0, sizeof(JsonValue));
Ret->Type = JSON_NUM;
- if (Key != NULL)
- {
+ if (Key != NULL) {
Ret->Name = NewStrBufPlain(Key, keylen);
}
Ret->Value = NewStrBufPlain(NULL, 64);
}
-JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number)
-{
+JsonValue *NewJsonBigNumber(const char *Key, long keylen, double Number) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
memset(Ret, 0, sizeof(JsonValue));
Ret->Type = JSON_NUM;
- if (Key != NULL)
- {
+ if (Key != NULL) {
Ret->Name = NewStrBufPlain(Key, keylen);
}
Ret->Value = NewStrBufPlain(NULL, 128);
}
-JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe, int copy_or_smash)
-{
+JsonValue *NewJsonString(const char *Key, long keylen, StrBuf *CopyMe, int copy_or_smash) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
memset(Ret, 0, sizeof(JsonValue));
Ret->Type = JSON_STRING;
- if (Key != NULL)
- {
+ if (Key != NULL) {
Ret->Name = NewStrBufPlain(Key, keylen);
}
- if (copy_or_smash == NEWJSONSTRING_COPYBUF)
- {
+ if (copy_or_smash == NEWJSONSTRING_COPYBUF) {
Ret->Value = NewStrBufDup(CopyMe);
}
- else if (copy_or_smash == NEWJSONSTRING_SMASHBUF)
- {
+ else if (copy_or_smash == NEWJSONSTRING_SMASHBUF) {
Ret->Value = CopyMe;
}
- else
- {
+ else {
Ret->Value = NULL; // error condition
}
return Ret;
}
-JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len)
-{
+JsonValue *NewJsonPlainString(const char *Key, long keylen, const char *CopyMe, long len) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
memset(Ret, 0, sizeof(JsonValue));
Ret->Type = JSON_STRING;
- if (Key != NULL)
- {
+ if (Key != NULL) {
Ret->Name = NewStrBufPlain(Key, keylen);
}
Ret->Value = NewStrBufPlain(CopyMe, len);
}
-JsonValue *NewJsonNull(const char *Key, long keylen)
-{
+JsonValue *NewJsonNull(const char *Key, long keylen) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
}
-JsonValue *NewJsonBool(const char *Key, long keylen, int value)
-{
+JsonValue *NewJsonBool(const char *Key, long keylen, int value) {
JsonValue *Ret;
Ret = (JsonValue*) malloc(sizeof(JsonValue));
memset(Ret, 0, sizeof(JsonValue));
Ret->Type = JSON_BOOL;
- if (Key != NULL)
- {
+ if (Key != NULL) {
Ret->Name = NewStrBufPlain(Key, keylen);
}
if (value) {
Ret->Value = NewStrBufPlain(HKEY("true"));
}
- else
- {
+ else {
Ret->Value = NewStrBufPlain(HKEY("false"));
}
return Ret;
}
-void JsonArrayAppend(JsonValue *Array, JsonValue *Val)
-{
+void JsonArrayAppend(JsonValue *Array, JsonValue *Val) {
long n;
- if (Array->Type != JSON_ARRAY)
- {
+ if (Array->Type != JSON_ARRAY) {
return;
}
}
-void JsonObjectAppend(JsonValue *Array, JsonValue *Val)
-{
- if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL))
- {
+void JsonObjectAppend(JsonValue *Array, JsonValue *Val) {
+ if ((Array->Type != JSON_OBJECT) || (Val->Name == NULL)) {
return;
}
Put(Array->SubValues, SKEY(Val->Name), Val, DeleteJSONValue);
}
-void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal)
-{
+void SerializeJson(StrBuf *Target, JsonValue *Val, int FreeVal) {
void *vValue, *vPrevious;
JsonValue *SubVal;
HashPos *It;
vPrevious = NULL;
StrBufAppendBufPlain(Target, HKEY("["), 0);
It = GetNewHashPos(Val->SubValues, 0);
- while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue))
- {
- if (vPrevious != NULL)
- {
+ while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue)) {
+ if (vPrevious != NULL) {
StrBufAppendBufPlain(Target, HKEY(","), 0);
}
SubVal = (JsonValue*) vValue;
vPrevious = NULL;
StrBufAppendBufPlain(Target, HKEY("{"), 0);
It = GetNewHashPos(Val->SubValues, 0);
- while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue))
- {
+ while (GetNextHashPos(Val->SubValues, It, &keylen, &Key, &vValue)) {
SubVal = (JsonValue*) vValue;
- if (vPrevious != NULL)
- {
+ if (vPrevious != NULL) {
StrBufAppendBufPlain(Target, HKEY(","), 0);
}
StrBufAppendBufPlain(Target, HKEY("\""), 0);
DeleteHashPos(&It);
break;
}
- if (FreeVal)
- {
+ if (FreeVal) {
DeleteJSONValue(Val);
}
}
}
+// 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));
+ striplt(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;
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]));
+ }
}
-
JsonObjectAppend(j, NewJsonNumber(HKEY("locl"), message_originated_locally));
if (!strcmp(buf, "text")) {