tUse filter program upon writing, so we can first decode the message - scribo - Email-based phlog generator
 (HTM) git clone git://git.z3bra.org/scribo.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 32d45f430b241c943ea593a9125211e9842013dc
 (DIR) parent 866b5fcbd5aa5bdd3ea2fecdf3b568be1631ecf0
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Wed,  9 Sep 2020 12:37:09 +0200
       
       Use filter program upon writing, so we can first decode the message
       
       Diffstat:
         M scribo.c                            |      48 ++++++++++++++++++++++++++------
       
       1 file changed, 40 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/scribo.c b/scribo.c
       t@@ -34,13 +34,14 @@ size_t strlcat(char *dst, const char *src, size_t siz);
        
        void usage(char *);
        char * sanitize(const char *);
       +FILE *pipeout(const char *, FILE *);
        char * header(struct headers *, char *);
        struct hdr * saveheader(struct headers *, char *);
        int parseheaders(FILE *, struct headers *);
        int verifyheaders(struct headers *);
        int write_8bit(FILE *, FILE *);
        int write_base64(FILE *, FILE *);
       -int writeentry(FILE *, char *, struct headers *);
       +int writeentry(FILE *, const char *, char *, struct headers *);
        int writeindex(FILE *, char *);
        
        
       t@@ -75,6 +76,32 @@ sanitize(const char *s)
                return tmp;
        }
        
       +FILE *
       +pipeout(const char *cmd, FILE *out)
       +{
       +        int fd[2];
       +        char *sh;
       +
       +        if (pipe(fd) < 0)
       +                return NULL;
       +
       +        if (!(sh = getenv("SHELL")))
       +                sh = "/bin/sh";
       +
       +        if (!fork()) {
       +                close(fd[1]);
       +                dup2(fd[0], STDIN_FILENO);
       +                dup2(fileno(out), STDOUT_FILENO);
       +
       +                execlp(sh, sh, "-c", cmd, NULL);
       +                return NULL; /* NOTREACHED */
       +        }
       +
       +        fclose(out);
       +        close(fd[0]);
       +        return fdopen(fd[1], "w");
       +}
       +
        char *
        header(struct headers *head, char *key)
        {
       t@@ -210,7 +237,7 @@ write_base64(FILE *in, FILE *out)
        }
        
        int
       -writeentry(FILE *in, char *dir, struct headers *head)
       +writeentry(FILE *in, const char *cmd, char *dir, struct headers *head)
        {
                FILE *out;
                struct tm tm = {.tm_isdst = -1};
       t@@ -235,12 +262,20 @@ writeentry(FILE *in, char *dir, struct headers *head)
        
                fprintf(out, titlefmt, subject);
        
       +        if (cmd) {
       +                if (!(out = pipeout(cmd, out))) {
       +                        perror(cmd);
       +                        return -1;
       +                }
       +        }
       +
                if (transfer && !strncmp(transfer, "base64", 6))
                        write_base64(in, out);
                else
                        write_8bit(in, out);
        
                fprintf(out, "\n%s\n", stamp);
       +        fclose(out);
        
                return 0;
        }
       t@@ -273,9 +308,10 @@ int
        main(int argc, char *argv[])
        {
                FILE *in = stdin, *out = stdout;
       -        char *argv0, *cmd, *infile, *outfile;
       +        char *argv0, *infile, *outfile, *cmd;
                struct headers headers;
        
       +        cmd = NULL;
                infile = NULL;
                outfile = NULL;
        
       t@@ -305,8 +341,6 @@ main(int argc, char *argv[])
        
                if (infile && strcmp(infile, "-"))
                        in = fopen(infile, "r");
       -        else if (cmd)
       -                in = popen(cmd, "r");
        
                if (!in) {
                        perror(infile);
       t@@ -326,10 +360,8 @@ main(int argc, char *argv[])
                if (verifyheaders(&headers) < 0)
                        return -1;
        
       -        if (writeentry(in, basedir, &headers) < 0) {
       -                perror("header section");
       +        if (writeentry(in, cmd, basedir, &headers) < 0)
                        return -1;
       -        }
        
                fclose(in);