From d9e8a44f6f56393e4b08b4570115de77cf0d2a2f Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sat, 28 Nov 2020 21:10:25 -0500 Subject: Replace templateBuffer with templateString --- archive.h | 5 ++--- atom.c | 6 +++--- concat.c | 40 ++++++++++++++++++++++++---------------- export.c | 42 ++++++++++++++++++++++++------------------ html.c | 12 ++++++------ template.c | 27 +++++++-------------------- 6 files changed, 66 insertions(+), 66 deletions(-) diff --git a/archive.h b/archive.h index a4278ff..3328340 100644 --- a/archive.h +++ b/archive.h @@ -187,11 +187,10 @@ int templateRender( FILE *file, const char *template, const struct Variable vars[], EscapeFn *escape ); -char *templateBuffer( - char *buf, size_t cap, const char *template, +char *templateString( + const char *template, const struct Variable vars[], EscapeFn *escape ); -char *templateURL(const char *template, const struct Variable vars[]); extern const char *baseURL; extern const char *baseTitle; diff --git a/atom.c b/atom.c index 3ecebbc..ddfb3f6 100644 --- a/atom.c +++ b/atom.c @@ -38,7 +38,7 @@ static char *atomID(const struct Envelope *envelope) { { "messageID", envelope->messageID }, {0}, }; - return templateURL("mid:[messageID]", vars); + return templateString("mid:[messageID]", vars, escapeURL); } static int atomAuthor(FILE *file, struct Address addr) { @@ -63,7 +63,7 @@ static char *atomEntryURL(const struct Envelope *envelope) { { "type", "mbox" }, {0}, }; - return templateURL("/" PATH_MESSAGE, vars); + return templateString("/" PATH_MESSAGE, vars, escapeURL); } static const char *atomUpdated(time_t time) { @@ -123,7 +123,7 @@ static char *atomThreadURL(const struct Envelope *envelope, const char *type) { { "type", type }, {0}, }; - return templateURL("/" PATH_THREAD, vars); + return templateString("/" PATH_THREAD, vars, escapeURL); } int atomThreadOpen(FILE *file, const struct Envelope *envelope) { diff --git a/concat.c b/concat.c index 3e0dec6..c59a828 100644 --- a/concat.c +++ b/concat.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -82,8 +81,7 @@ void concatData( errx(EX_TEMPFAIL, "no thread with root UID %" PRIu32, uid); } -static const char *uidPath(uint32_t uid, const char *type) { - static char buf[PATH_MAX]; +static char *uidPath(uint32_t uid, const char *type) { char str[32]; snprintf(str, sizeof(str), "%" PRIu32, uid); struct Variable vars[] = { @@ -91,18 +89,18 @@ static const char *uidPath(uint32_t uid, const char *type) { { "type", type }, {0}, }; - templateBuffer(buf, sizeof(buf), PATH_UID, vars, escapePath); - return buf; + return templateString(PATH_UID, vars, escapePath); } static time_t uidNewest(struct List uids, const char *type) { time_t newest = 0; for (size_t i = 0; i < uids.len; ++i) { - const char *path = uidPath(dataCheck(uids.ptr[i], Number).number, type); + char *path = uidPath(dataCheck(uids.ptr[i], Number).number, type); struct stat status; int error = stat(path, &status); if (error) err(EX_DATAERR, "%s", path); if (status.st_mtime > newest) newest = status.st_mtime; + free(path); } return newest; } @@ -129,22 +127,22 @@ static int concatHTML(FILE *file, struct List thread) { || htmlSubthreadClose(file); } else { uint32_t uid = dataCheck(thread.ptr[i], Number).number; - error = concatFile(file, uidPath(uid, "html")); + char *path = uidPath(uid, "html"); + error = concatFile(file, path); + free(path); } if (error) return error; } return 0; } -static const char *threadPath(const char *messageID, const char *type) { - static char buf[PATH_MAX]; +static char *threadPath(const char *messageID, const char *type) { struct Variable vars[] = { { "messageID", messageID }, { "type", type }, {0}, }; - templateBuffer(buf, sizeof(buf), PATH_THREAD, vars, escapePath); - return buf; + return templateString(PATH_THREAD, vars, escapePath); } const char *concatHead; @@ -155,7 +153,7 @@ static void concatThread(struct List thread, const struct Envelope *envelope) { int error; FILE *file; - const char *path; + char *path; struct stat status; path = threadPath(envelope->messageID, "mbox"); @@ -166,13 +164,16 @@ static void concatThread(struct List thread, const struct Envelope *envelope) { for (size_t i = 0; i < flat.len; ++i) { uint32_t uid = dataCheck(flat.ptr[i], Number).number; - error = concatFile(file, uidPath(uid, "mbox")); + char *src = uidPath(uid, "mbox"); + error = concatFile(file, src); if (error) err(EX_IOERR, "%s", path); + free(src); } error = fclose(file); if (error) err(EX_IOERR, "%s", path); } + free(path); path = threadPath(envelope->messageID, "atom"); error = stat(path, &status); @@ -185,13 +186,16 @@ static void concatThread(struct List thread, const struct Envelope *envelope) { for (size_t i = 0; i < flat.len; ++i) { uint32_t uid = dataCheck(flat.ptr[i], Number).number; - error = concatFile(file, uidPath(uid, "atom")); + char *src = uidPath(uid, "atom"); + error = concatFile(file, src); if (error) err(EX_IOERR, "%s", path); + free(src); } error = atomThreadClose(file) || fclose(file); if (error) err(EX_IOERR, "%s", path); } + free(path); path = threadPath(envelope->messageID, "html"); error = stat(path, &status); @@ -214,6 +218,7 @@ static void concatThread(struct List thread, const struct Envelope *envelope) { || fclose(file); if (error) err(EX_IOERR, "%s", path); } + free(path); listFree(flat); } @@ -252,8 +257,10 @@ void concatIndex(struct List threads, const struct Envelope *envelopes) { listFlatten(&flat, threads); for (size_t i = flat.len - 1; i < flat.len; --i) { uint32_t uid = dataCheck(flat.ptr[i], Number).number; - error = concatFile(file, uidPath(uid, "atom")); + char *src = uidPath(uid, "atom"); + error = concatFile(file, src); if (error) err(EX_IOERR, "%s", path); + free(src); } listFree(flat); @@ -265,9 +272,10 @@ void concatIndex(struct List threads, const struct Envelope *envelopes) { for (size_t i = 0; i < threads.len; ++i) { struct stat status; - const char *path = threadPath(envelopes[i].messageID, "html"); + char *path = threadPath(envelopes[i].messageID, "html"); int error = stat(path, &status); if (error) err(EX_DATAERR, "%s", path); + free(path); order[i].index = i; order[i].created = envelopes[i].time; diff --git a/export.c b/export.c index f9f533e..2b579c3 100644 --- a/export.c +++ b/export.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -40,8 +39,7 @@ #include "archive.h" #include "imap.h" -static const char *exportPath(uint32_t uid, const char *type) { - static char buf[PATH_MAX]; +static char *exportPath(uint32_t uid, const char *type) { char str[32]; snprintf(str, sizeof(str), "%" PRIu32, uid); struct Variable vars[] = { @@ -49,8 +47,7 @@ static const char *exportPath(uint32_t uid, const char *type) { { "type", type }, {0}, }; - templateBuffer(buf, sizeof(buf), PATH_UID, vars, escapePath); - return buf; + return templateString(PATH_UID, vars, escapePath); } bool exportFetch(FILE *imap, enum Atom tag, struct List threads) { @@ -58,11 +55,17 @@ bool exportFetch(FILE *imap, enum Atom tag, struct List threads) { listFlatten(&uids, threads); for (size_t i = uids.len - 1; i < uids.len; --i) { uint32_t uid = dataCheck(uids.ptr[i], Number).number; + char *atom = exportPath(uid, "atom"); + char *html = exportPath(uid, "html"); + char *mbox = exportPath(uid, "mbox"); int error = 0 - || access(exportPath(uid, "atom"), F_OK) - || access(exportPath(uid, "html"), F_OK) - || access(exportPath(uid, "mbox"), F_OK); + || access(atom, F_OK) + || access(html, F_OK) + || access(mbox, F_OK); if (!error) uids.ptr[i] = uids.ptr[--uids.len]; + free(atom); + free(html); + free(mbox); } if (!uids.len) { listFree(uids); @@ -86,7 +89,7 @@ static void exportMbox( uint32_t uid, const struct Envelope *envelope, const char *header, const char *body ) { - const char *path = exportPath(uid, "mbox"); + char *path = exportPath(uid, "mbox"); FILE *file = fopen(path, "w"); if (!file) err(EX_CANTCREAT, "%s", path); int error = 0 @@ -96,17 +99,18 @@ static void exportMbox( || fclose(file); if (error) err(EX_IOERR, "%s", path); - char buf[PATH_MAX]; struct Variable vars[] = { { "messageID", envelope->messageID }, { "type", "mbox" }, {0}, }; - templateBuffer(buf, sizeof(buf), PATH_MESSAGE, vars, escapePath); + char *dest = templateString(PATH_MESSAGE, vars, escapePath); + unlink(dest); + error = link(path, dest); + if (error) err(EX_CANTCREAT, "%s", dest); - unlink(buf); - error = link(path, buf); - if (error) err(EX_CANTCREAT, "%s", buf); + free(dest); + free(path); } static bool isInline(const struct BodyPart *part) { @@ -124,7 +128,7 @@ static void exportAtom( uint32_t uid, const struct Envelope *envelope, const struct BodyPart *structure, struct Data body ) { - const char *path = exportPath(uid, "atom"); + char *path = exportPath(uid, "atom"); FILE *file = fopen(path, "w"); if (!file) err(EX_CANTCREAT, "%s", path); @@ -155,6 +159,7 @@ static void exportAtom( error = atomEntryClose(file) || fclose(file); if (error) err(EX_IOERR, "%s", path); + free(path); } static const char *sectionName(struct List section) { @@ -181,7 +186,6 @@ static int exportHTMLAttachment( const char *disposition = part->disposition.type; if (!disposition) disposition = "INLINE"; - char path[PATH_MAX]; struct Variable vars[] = { { "messageID", envelope->messageID }, { "section", sectionName(section) }, @@ -191,7 +195,7 @@ static int exportHTMLAttachment( { "subtype", (name ? "" : part->subtype) }, {0}, }; - templateBuffer(path, sizeof(path), PATH_ATTACHMENT, vars, escapePath); + char *path = templateString(PATH_ATTACHMENT, vars, escapePath); for (char *ch = path; (ch = strchr(ch, '/')); ++ch) { *ch = '\0'; @@ -207,6 +211,7 @@ static int exportHTMLAttachment( || decodeToFile(attachment, part, dataCheck(body, String).string) || fclose(attachment); if (error) err(EX_IOERR, "%s", path); + free(path); return htmlAttachment(file, part, vars); } @@ -274,7 +279,7 @@ static void exportHTML( uint32_t uid, const struct Envelope *envelope, const struct BodyPart *structure, struct Data body ) { - const char *path = exportPath(uid, "html"); + char *path = exportPath(uid, "html"); FILE *file = fopen(path, "w"); if (!file) err(EX_CANTCREAT, "%s", path); @@ -288,6 +293,7 @@ static void exportHTML( error = htmlMessageClose(file) || fclose(file); if (error) err(EX_IOERR, "%s", path); + free(path); } static void fetchParts( diff --git a/html.c b/html.c index 6d9b6b2..d55e5bf 100644 --- a/html.c +++ b/html.c @@ -96,7 +96,7 @@ static char *htmlReply(const struct Envelope *envelope) { { ">", ">" }, {0}, }; - return templateURL(template, vars); + return templateString(template, vars, escapeURL); } static char *htmlFragment(const char *messageID) { @@ -104,7 +104,7 @@ static char *htmlFragment(const char *messageID) { { "messageID", messageID }, {0}, }; - return templateURL("#[messageID]", vars); + return templateString("#[messageID]", vars, escapeURL); } static char *htmlMbox(const char *messageID) { @@ -113,7 +113,7 @@ static char *htmlMbox(const char *messageID) { { "type", "mbox" }, {0}, }; - return templateURL("../" PATH_MESSAGE, vars); + return templateString("../" PATH_MESSAGE, vars, escapeURL); } static int @@ -353,7 +353,7 @@ int htmlAttachment( const char *template = { Q(
  • [name][type][/][subtype]
  • ) }; - char *url = templateURL("../" PATH_ATTACHMENT, path); + char *url = templateString("../" PATH_ATTACHMENT, path, escapeURL); const char *name = paramGet(part->disposition.params, "filename"); if (!name) name = paramGet(part->params, "name"); struct Variable vars[] = { @@ -383,7 +383,7 @@ static char *htmlThreadURL(const struct Envelope *envelope, const char *type) { { "type", type }, {0}, }; - return templateURL("../" PATH_THREAD, vars); + return templateString("../" PATH_THREAD, vars, escapeURL); } int htmlThreadHead(FILE *file, const struct Envelope *envelope) { @@ -553,7 +553,7 @@ static char *htmlIndexURL(const struct Envelope *envelope) { { "type", "html" }, {0}, }; - return templateURL(PATH_THREAD, vars); + return templateString(PATH_THREAD, vars, escapeURL); } int htmlIndexThread( diff --git a/template.c b/template.c index b3ab00f..a47d9f5 100644 --- a/template.c +++ b/template.c @@ -135,30 +135,17 @@ int templateRender( return 0; } -char *templateBuffer( - char *buf, size_t cap, const char *template, - const struct Variable vars[], EscapeFn *escape +char *templateString( + const char *template, const struct Variable vars[], EscapeFn *escape ) { - FILE *file = fmemopen(buf, cap, "w"); - if (!file) err(EX_OSERR, "fmemopen"); + char *buf; + size_t len; + FILE *file = open_memstream(&buf, &len); + if (!file) err(EX_OSERR, "open_memstream"); int error = templateRender(file, template, vars, escape) || fclose(file); - assert(!error); + if (error) err(EX_OSERR, "open_memstream"); - // XXX: fmemopen only null-terminates if there is room. - buf[cap - 1] = '\0'; return buf; } - -char *templateURL(const char *template, const struct Variable vars[]) { - size_t cap = strlen(template) + 1; - for (const struct Variable *var = vars; var->name; ++var) { - cap += 3 * strlen(var->value); - } - - char *buf = malloc(cap); - if (!buf) err(EX_OSERR, "malloc"); - - return templateBuffer(buf, cap, template, vars, escapeURL); -} -- cgit 1.4.1