/* Copyright (C) 2020 C. McEnroe * * 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 . */ #include #include #include #include #include #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 . const char *template = TEMPLATE( [name] [mailbox]@[host] ); 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[] = { { "name", pathSafe(envelope->messageID) }, {0}, }; return templateURL("/message/[name].mbox", vars); } int atomEntryOpen(FILE *file, const struct Envelope *envelope) { const char *template = TEMPLATE( [id] [title] [updated] ); 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] ); struct Variable vars[] = { { "content", content }, {0}, }; return templateRender(file, template, vars, escapeXML); } int atomEntryClose(FILE *file) { return templateRender(file, TEMPLATE(), NULL, NULL); } static char *atomFeedURL(const struct Envelope *envelope, const char *type) { struct Variable vars[] = { { "name", pathSafe(envelope->messageID) }, { "type", type }, {0}, }; return templateURL("/thread/[name].[type]", vars); } int atomFeedOpen(FILE *file, const struct Envelope *envelope) { const char *template = TEMPLATE( <[q]xml version="1.0" encoding="utf-8"[q]> [id] [title] [updated] ); 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(), NULL, NULL); }