From 8fee4cbd63b4682e0df8cd78bae906727d044165 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Fri, 10 Apr 2020 11:16:34 -0400 Subject: Use UIDNEXT to avoid asking IMAP to do any work --- archive.c | 67 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 25 deletions(-) (limited to 'archive.c') diff --git a/archive.c b/archive.c index 2e8bf31..97bb99a 100644 --- a/archive.c +++ b/archive.c @@ -29,27 +29,22 @@ #define ENV_PASSWORD "BUBGER_IMAP_PASSWORD" -static void checkValidity(uint32_t validity) { - FILE *file = fopen("UIDVALIDITY", "r"); - if (file) { - uint32_t previous; - int n = fscanf(file, "%" SCNu32, &previous); - if (n < 1) errx(EX_DATAERR, "invalid UIDVALIDITY file"); - - if (validity != previous) { - errx(EX_TEMPFAIL, "UIDVALIDITY changed; fresh export required"); - } - - } else { - FILE *file = fopen("UIDVALIDITY", "w"); - if (!file) err(EX_CANTCREAT, "UIDVALIDITY"); - - int n = fprintf(file, "%" PRIu32 "\n", validity); - if (n < 0) err(EX_IOERR, "UIDVALIDITY"); +static uint32_t uidRead(const char *path) { + FILE *file = fopen(path, "r"); + if (!file) return 0; + uint32_t uid; + int n = fscanf(file, "%" SCNu32, &uid); + if (n < 1) errx(EX_DATAERR, "%s: invalid UID", path); + return uid; +} - int error = fclose(file); - if (error) err(EX_IOERR, "UIDVALIDITY"); - } +static void uidWrite(const char *path, uint32_t uid) { + FILE *file = fopen(path, "w"); + if (!file) err(EX_CANTCREAT, "%s", path); + int n = fprintf(file, "%" PRIu32 "\n", uid); + if (n < 0) err(EX_IOERR, "%s", path); + int error = fclose(file); + if (error) err(EX_IOERR, "%s", path); } int main(int argc, char *argv[]) { @@ -129,13 +124,35 @@ int main(int argc, char *argv[]) { if ( resp.resp == AtomOk && resp.code.len > 1 && - resp.code.ptr[0].type == Atom && - resp.code.ptr[0].atom == AtomUIDValidity + resp.code.ptr[0].type == Atom ) { - if (resp.code.ptr[1].type != Number) { - errx(EX_PROTOCOL, "invalid UIDVALIDITY"); + enum Atom code = resp.code.ptr[0].atom; + if (code == AtomUIDValidity || code == AtomUIDNext) { + if (resp.code.ptr[1].type != Number) { + errx(EX_PROTOCOL, "invalid %s", Atoms[code]); + } + } + if (code == AtomUIDValidity) { + uint32_t validity = resp.code.ptr[1].number; + uint32_t previous = uidRead("UIDVALIDITY"); + if (previous && validity != previous) { + errx( + EX_TEMPFAIL, + "UIDVALIDITY changed; fresh export required" + ); + } + if (!previous) uidWrite("UIDVALIDITY", validity); + } + if (code == AtomUIDNext) { + uint32_t next = resp.code.ptr[1].number; + uint32_t prev = uidRead("UIDNEXT"); + if (next == prev) { + examine = 0; + fprintf(imap, "ayy LOGOUT\r\n"); + } else { + uidWrite("UIDNEXT", next); + } } - checkValidity(resp.code.ptr[1].number); } if (resp.tag == examine) { -- cgit 1.4.1