/* Copyright (C) 2020 C. McEnroe <june@causal.agency>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <time.h>
#include "archive.h"
const char *atomBaseURL;
static char *atomID(const struct Envelope *envelope) {
struct Variable vars[] = {
{ "messageID", envelope->messageID },
{0},
};
return templateURL("mid:[messageID]", vars);
}
static int atomAuthor(FILE *file, struct Address addr) {
// TODO: Conditionally include <email>.
const char *template = TEMPLATE(
<author>
<name>[name]</name>
<email>[mailbox]@[host]</email>
</author>
);
struct Variable vars[] = {
{ "name", addressName(addr) },
{ "mailbox", addr.mailbox },
{ "host", addr.host },
{0},
};
return templateRender(file, template, vars, escapeXML);
}
static char *atomEntryURL(const struct Envelope *envelope) {
struct Variable vars[] = {
{ "messageID", envelope->messageID },
{ "type", "mbox" },
{0},
};
return templateURL("/" PATH_MESSAGE, vars);
}
int atomEntryOpen(FILE *file, const struct Envelope *envelope) {
const char *template = TEMPLATE(
<entry>
<id>[id]</id>
<title>[title]</title>
<updated>[updated]</updated>
<link rel="alternate" type="application/mbox" href="[base][url]"/>
);
char *id = atomID(envelope);
char updated[sizeof("0000-00-00T00:00:00Z")];
strftime(updated, sizeof(updated), "%FT%TZ", gmtime(&envelope->time));
char *url = atomEntryURL(envelope);
struct Variable vars[] = {
{ "id", id },
{ "title", envelope->subject },
{ "updated", updated },
{ "base", (atomBaseURL ? atomBaseURL : "") },
{ "url", url },
{0},
};
int error = 0
|| templateRender(file, template, vars, escapeXML)
|| atomAuthor(file, envelope->from);
free(id);
free(url);
return error;
}
int atomContent(FILE *file, const char *content) {
const char *template = TEMPLATE(
<content type="text">[content]</content>
);
struct Variable vars[] = {
{ "content", content },
{0},
};
return templateRender(file, template, vars, escapeXML);
}
int atomEntryClose(FILE *file) {
return templateRender(file, TEMPLATE(</entry>), NULL, NULL);
}
static char *atomFeedURL(const struct Envelope *envelope, const char *type) {
struct Variable vars[] = {
{ "messageID", envelope->messageID },
{ "type", type },
{0},
};
return templateURL("/" PATH_THREAD, vars);
}
int atomFeedOpen(FILE *file, const struct Envelope *envelope) {
const char *template = TEMPLATE(
<[q]xml version="1.0" encoding="utf-8"[q]>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>[id]</id>
<title>[title]</title>
<updated>[updated]</updated>
<link rel="self" href="[base][atom]"/>
<link rel="alternate" type="text/html" href="[base][html]"/>
<link rel="alternate" type="application/mbox" href="[base][mbox]"/>
);
char *id = atomID(envelope);
time_t now = time(NULL);
char updated[sizeof("0000-00-00T00:00:00Z")];
strftime(updated, sizeof(updated), "%FT%TZ", gmtime(&now));
char *atom = atomFeedURL(envelope, "atom");
char *html = atomFeedURL(envelope, "html");
char *mbox = atomFeedURL(envelope, "mbox");
struct Variable vars[] = {
{ "q", "?" },
{ "id", id },
{ "title", envelope->subject },
{ "updated", updated },
{ "base", (atomBaseURL ? atomBaseURL : "") },
{ "atom", atom },
{ "html", html },
{ "mbox", mbox },
{0},
};
int error = 0
|| templateRender(file, template, vars, escapeXML)
|| atomAuthor(file, envelope->from);
free(id);
free(atom);
free(html);
free(mbox);
return error;
}
int atomFeedClose(FILE *file) {
return templateRender(file, TEMPLATE(</feed>), NULL, NULL);
}