/* 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/>.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this Program, or any covered work, by linking or
* combining it with OpenSSL (or a modified version of that library),
* containing parts covered by the terms of the OpenSSL License and the
* original SSLeay license, the licensors of this Program grant you
* additional permission to convey the resulting work. Corresponding
* Source for a non-source form of such a combination shall include the
* source code for the parts of OpenSSL used as well as that of the
* covered work.
*/
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <time.h>
#include "archive.h"
static char *atomID(const struct Envelope *envelope) {
struct Variable vars[] = {
{ "messageID", envelope->messageID },
{0},
};
return templateString("mid:[messageID]", vars, escapeURL);
}
static char *atomEntryURL(const struct Envelope *envelope) {
struct Variable vars[] = {
{ "messageID", envelope->messageID },
{ "type", "mbox" },
{0},
};
return templateString("/" PATH_MESSAGE, vars, escapeURL);
}
static int atomAuthor(FILE *file, struct Address addr) {
const char *template = Q(
<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);
}
int atomEntryOpen(FILE *file, const struct Envelope *envelope) {
char *id = atomID(envelope);
char *url = atomEntryURL(envelope);
const char *template = Q(
<entry>
<id>[id]</id>
<title>[title]</title>
<updated>[updated]</updated>
<link rel="alternate" type="application/mbox" href="[base][url]"/>
);
struct Variable vars[] = {
{ "id", id },
{ "title", envelope->subject },
{ "updated", iso8601(envelope->time).s },
{ "base", baseURL },
{ "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 = Q(
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<pre>[content]</pre>
</div>
</content>
);
struct Variable vars[] = {
{ "content", content },
{0},
};
return templateRender(file, template, vars, escapeXML);
}
int atomEntryClose(FILE *file) {
return templateRender(file, Q(</entry>), NULL, NULL);
}
static char *atomThreadURL(const struct Envelope *envelope, const char *type) {
struct Variable vars[] = {
{ "messageID", envelope->messageID },
{ "type", type },
{0},
};
return templateString("/" PATH_THREAD, vars, escapeURL);
}
#define XML_DECL "<?" Q(xml version="1.0" encoding="utf-8") "?>"
int atomThreadOpen(FILE *file, const struct Envelope *envelope) {
char *id = atomID(envelope);
char *atom = atomThreadURL(envelope, "atom");
char *html = atomThreadURL(envelope, "html");
char *mbox = atomThreadURL(envelope, "mbox");
const char *template = XML_DECL Q(
<feed xmlns="http://www.w3.org/2005/Atom">
<generator uri="[generator]">bubger</generator>
<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]"/>
);
struct Variable vars[] = {
{ "generator", GENERATOR_URL },
{ "id", id },
{ "title", envelope->subject },
{ "updated", iso8601(time(NULL)).s },
{ "base", baseURL },
{ "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 atomThreadClose(FILE *file) {
return templateRender(file, Q(</feed>), NULL, NULL);
}
int atomIndexOpen(FILE *file) {
const char *template = XML_DECL Q(
<feed xmlns="http://www.w3.org/2005/Atom">
<generator uri="[generator]">bubger</generator>
<id>[base]/</id>
<title>[title]</title>
<updated>[updated]</updated>
<link rel="self" href="[base]/index.atom"/>
<link rel="alternate" type="text/html" href="[base]/index.html"/>
);
struct Variable vars[] = {
{ "generator", GENERATOR_URL },
{ "title", baseTitle },
{ "updated", iso8601(time(NULL)).s },
{ "base", baseURL },
{0},
};
return templateRender(file, template, vars, escapeXML);
}
int atomIndexClose(FILE *file) {
return templateRender(file, Q(</feed>), NULL, NULL);
}