tAdding the rppath utility and allowing the creation of all paths. - rohrpost - A commandline mail client to change the world as we see it.
 (HTM) git clone git://r-36.net/rohrpost
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 24b5d99fda7e3603ae9136e13e241f3f76d48692
 (DIR) parent 119cc0c7df1604df82651fdc9ea6afa9b884452f
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Mon, 24 Dec 2012 17:36:54 +0100
       
       Adding the rppath utility and allowing the creation of all paths.
       
       Diffstat:
         Makefile                            |       2 +-
         bin/rpcat                           |       2 +-
         bin/rpcomp                          |       2 +-
         bin/rpflag                          |       2 +-
         bin/rpfwd                           |       2 +-
         bin/rpinc                           |       2 +-
         bin/rpnews                          |      18 +++++++++++-------
         bin/rpprint                         |       9 ++++++++-
         bin/rprepl                          |       2 +-
         bin/rpscan                          |       2 +-
         bin/rpview                          |       2 +-
         cfg.c                               |      80 ++++++++++---------------------
         cfg.h                               |       2 --
         flag.c                              |       2 +-
         inc.c                               |      17 +++--------------
         inc.h                               |       1 -
         ind.h                               |       6 ------
         mark.c                              |      17 +++--------------
         mark.h                              |       1 -
         path.c                              |     196 +++++++++++++++++++++++++++++++
         path.h                              |      25 +++++++++++++++++++++++++
         rohrpost.c                          |       2 ++
       
       22 files changed, 284 insertions(+), 110 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -7,7 +7,7 @@ SRC = ${NAME}.c ind.c llist.c cfg.c txtdb.c mark.c cur.c \
                select.c sieve.c net.c base64.c strio.c parser.c pager.c \
                mime.c folder.c imap.c inc.c stats.c capability.c pick.c \
                flag.c copy.c remove.c scan.c quote.c view.c \
       -        param.c part.c add.c ids.c util.c
       +        param.c part.c add.c ids.c util.c path.c
        
        OBJ = ${SRC:.c=.o}
        
 (DIR) diff --git a/bin/rpcat b/bin/rpcat
       t@@ -1,4 +1,4 @@
        #!/bin/sh
        
       -rpview -r $*
       +rpview -r $* | cat
        
 (DIR) diff --git a/bin/rpcomp b/bin/rpcomp
       t@@ -1,6 +1,6 @@
        #!/bin/sh
        
       -BASE="$(rpcfg -b)"
       +BASE="$(rppath -b)"
        
        if [ ! -x $BASE/tmpl/compose.sh ];
        then
 (DIR) diff --git a/bin/rpflag b/bin/rpflag
       t@@ -1,6 +1,6 @@
        #!/bin/sh
        
       -TMPL="$(rpcfg -b)/tmpl/flag.sh"
       +TMPL="$(rppath -b)/tmpl/flag.sh"
        
        if [ -t 1 -a -x "$TMPL" ];
        then
 (DIR) diff --git a/bin/rpfwd b/bin/rpfwd
       t@@ -1,6 +1,6 @@
        #!/bin/sh
        
       -BASE="$(rpcfg -b)"
       +BASE="$(rppath -b)"
        
        usage() {
                printf "usage. %s [-h] msgids\n" "$(basename $1)" 2>&1
 (DIR) diff --git a/bin/rpinc b/bin/rpinc
       t@@ -1,6 +1,6 @@
        #!/bin/sh
        
       -TMPL="$(rpcfg -b)/tmpl/inc.sh"
       +TMPL="$(rppath -b)/tmpl/inc.sh"
        
        if [ -t 1 -a -x "$TMPL" ];
        then
 (DIR) diff --git a/bin/rpnews b/bin/rpnews
       t@@ -1,12 +1,16 @@
        #!/bin/sh
        
       -args="$*"
       -echo $args
       -if [ -z "$args" ];
       +TMPL="$(rppath -b)/tmpl/news.sh"
       +
       +if [ -t 1 -a -x "$TMPL" ];
        then
       -        args="u"
       +        if [ -n "$PAGER" ];
       +        then
       +                rohrpost rpscan "$@" | $TMPL | eval $PAGER
       +        else
       +                rohrpost rpscan "$@" | $TMPL
       +        fi
       +else
       +        rohrpost rpscan "$@"
        fi
        
       -rpscan $args | $(rpcfg -b)/tmpl/news.sh \
       -        | eval $PAGER
       -
 (DIR) diff --git a/bin/rpprint b/bin/rpprint
       t@@ -1,4 +1,11 @@
        #!/bin/sh
        
       -rpview "$@" | $(rpcfg -b)/tmpl/print.sh
       +TMPL="$(rppath -b)/tmpl/print.sh"
       +
       +if [ -t 1 -a -x "$TMPL" ];
       +then
       +        rohrpost rpview "$@" | $TMPL
       +else
       +        rohrpost rpview "$@"
       +fi
        
 (DIR) diff --git a/bin/rprepl b/bin/rprepl
       t@@ -1,6 +1,6 @@
        #!/bin/sh
        
       -BASE="$(rpcfg -b)"
       +BASE="$(rppath -b)"
        
        if [ ! -x $BASE/tmpl/repl.sh ];
        then
 (DIR) diff --git a/bin/rpscan b/bin/rpscan
       t@@ -1,6 +1,6 @@
        #!/bin/sh
        
       -TMPL="$(rpcfg -b)/tmpl/scan.sh"
       +TMPL="$(rppath -b)/tmpl/scan.sh"
        
        if [ -t 1 -a -x "$TMPL" ];
        then
 (DIR) diff --git a/bin/rpview b/bin/rpview
       t@@ -1,6 +1,6 @@
        #!/bin/sh
        
       -TMPL="$(rpcfg -b)/tmpl/view.sh"
       +TMPL="$(rppath -b)/tmpl/view.sh"
        
        if [ -t 1 -a -x "$TMPL" ];
        then
 (DIR) diff --git a/cfg.c b/cfg.c
       t@@ -15,41 +15,11 @@
        #include "ind.h"
        #include "arg.h"
        #include "llist.h"
       +#include "path.h"
        #include "cfg.h"
        
       -
        char *argv0;
        
       -char *
       -config_mkcfgpath(char *cfgn)
       -{
       -        char *prefix, *path;
       -
       -        if (cfgn == NULL)
       -                cfgn = "default";
       -
       -        prefix = expandhome(CONFIGFILE);
       -        path = smprintf(prefix, cfgn);
       -        free(prefix);
       -
       -        return path;
       -}
       -
       -char *
       -config_mkbasepath(char *cfgn)
       -{
       -        char *prefix, *path;
       -
       -        if (cfgn == NULL)
       -                cfgn = "default";
       -
       -        prefix = expandhome(BASEPREFIX);
       -        path = smprintf(prefix, cfgn);
       -        free(prefix);
       -
       -        return path;
       -}
       -
        config_t *
        config_init(char *cfgn)
        {
       t@@ -59,7 +29,7 @@ config_init(char *cfgn)
                if (cfgn == NULL)
                        cfgn = "default";
        
       -        path = config_mkcfgpath(cfgn);
       +        path = path_mkcfgfile(cfgn);
                cfg = config_read(path);
                if (cfg == NULL)
                        cfg = config_new();
       t@@ -74,16 +44,25 @@ config_init(char *cfgn)
        void
        config_default(char *cfgn)
        {
       -        char *defaultpath, *cfgpath;
       -
       -        cfgpath = config_mkbasepath(cfgn);
       -        defaultpath = config_mkbasepath("default");
       -
       -        if (symlink(cfgpath, defaultpath) < 0)
       +        char *path, *cwd;
       +
       +        cwd = getcwd(NULL, 0);
       +        if (cwd == NULL)
       +                edie("getcwd");
       +
       +        path = path_mkbasepath(cfgn);
       +        if (chdir(path) < 0)
       +                edie("chdir");
       +        if (remove("default") < 0)
       +                edie("remove");
       +        if (symlink(cfgn, "default") < 0)
                        edie("symlink");
        
       -        free(cfgpath);
       -        free(defaultpath);
       +        if (chdir(cwd) < 0)
       +                edie("chdir");
       +
       +        free(cwd);
       +        free(path);
        }
        
        void
       t@@ -92,7 +71,7 @@ config_stop(config_t *cfg)
                char *path;
        
                if (cfg->changed) {
       -                path = config_mkcfgpath(cfg->name);
       +                path = path_mkcfgfile(cfg->name);
                        if (config_write(cfg, NULL) == NULL)
                                edie("config_write");
                        free(path);
       t@@ -160,7 +139,7 @@ configprintelem(llistelem_t *elem, int onlydata)
        void
        configusage(void)
        {
       -        die("usage: %s [-bhqv] [-c cfg] [-e cfg|-l|key"
       +        die("usage: %s [-hiqv] [-c cfg] [-e cfg|-l|key"
                                " [value]]|-d key|-s regex]\n", argv0);
        }
        
       t@@ -168,7 +147,7 @@ int
        configmain(int argc, char *argv[])
        {
                int status;
       -        char *key, *value, *cfgn, *def, *path;
       +        char *key, *value, *cfgn, *def;
                config_t *cfg;
                llist_t *results;
                llistelem_t *result, *elem;
       t@@ -179,7 +158,7 @@ configmain(int argc, char *argv[])
                        DOLIST = 0x04,
                        DODELETE = 0x08,
                        DOSEARCH = 0x10,
       -                DOBASE = 0x20
       +                DOINIT = 0x20
                };
        
                status = 0;
       t@@ -192,15 +171,15 @@ configmain(int argc, char *argv[])
                case 'c':
                        cfgn = EARGF(configusage());
                        break;
       -        case 'b':
       -                status |= DOBASE;
       -                break;
                case 'd':
                        status |= DODELETE;
                        break;
                case 'e':
                        def = EARGF(configusage());
                        break;
       +        case 'i':
       +                status |= DOINIT;
       +                break;
                case 'q':
                        status |= BEQUIET;
                        break;
       t@@ -226,13 +205,6 @@ configmain(int argc, char *argv[])
                        return 0;
                }
        
       -        if (status & DOBASE) {
       -                path = config_mkbasepath(cfgn);
       -                printf("%s\n", path);
       -                free(path);
       -                return 0;
       -        }
       -
                cfg = config_init(cfgn);
        
                if (status & DOLIST) {
 (DIR) diff --git a/cfg.h b/cfg.h
       t@@ -28,8 +28,6 @@ llistelem_t *config_checkget(config_t *cfg, char *key);
        char *config_getstr(config_t *cfg, char *key);
        char *config_checkgetstr(config_t *cfg, char *key);
        
       -char *config_mkcfgpath(char *cfgn);
       -char *config_mkbasepath(char *cfgn);
        config_t *config_init(char *cfgn);
        void config_stop(config_t *cfg);
        void config_default(char *cfgn);
 (DIR) diff --git a/flag.c b/flag.c
       t@@ -157,7 +157,7 @@ flagmain(int argc, char *argv[])
                if (status & SETSEEN) {
                        if (argc == 0) {
                                argc = 1;
       -                        argv = (char *[]){ "unseen", NULL };
       +                        argv = (char *[]){ "u", NULL };
                        }
        
                        flagl = flag_sanitize("seen");
 (DIR) diff --git a/inc.c b/inc.c
       t@@ -18,21 +18,10 @@
        #include "imap.h"
        #include "mark.h"
        #include "inc.h"
       +#include "path.h"
        
        char *argv0;
        
       -char *
       -inc_mkincfile(char *cfgn)
       -{
       -        char *prefix, *path;
       -
       -        prefix = expandhome(INCFILE);
       -        path = smprintf(prefix, cfgn);
       -        free(prefix);
       -
       -        return path;
       -}
       -
        inc_t *
        inc_init(char *cfgn)
        {
       t@@ -42,7 +31,7 @@ inc_init(char *cfgn)
                if (cfgn == NULL)
                        cfgn = "default";
        
       -        path = inc_mkincfile(cfgn);
       +        path = path_mkincfile(cfgn);
                incs = inc_read(path);
                if (incs == NULL)
                        incs = inc_new();
       t@@ -60,7 +49,7 @@ inc_stop(inc_t *incs)
                char *path;
        
                if (incs->changed) {
       -                path = inc_mkincfile(incs->name);
       +                path = path_mkincfile(incs->name);
                        if (inc_write(incs, path) == NULL)
                                edie("inc_write");
                        free(path);
 (DIR) diff --git a/inc.h b/inc.h
       t@@ -24,7 +24,6 @@
        #define inc_read txtdb_read
        #define inc_write txtdb_write
        
       -char *inc_mkincfile(char *cfgn);
        inc_t *inc_init(char *cfgn);
        void inc_stop(inc_t *incs);
        llist_t *inc_getstatus(inc_t *incs, char *mailbox);
 (DIR) diff --git a/ind.h b/ind.h
       t@@ -14,12 +14,6 @@
        
        #define MAXLINESIZE 1048576
        
       -#define RPPREFIX "~/.rohrpost/"
       -#define BASEPREFIX RPPREFIX "%s"
       -#define CONFIGFILE BASEPREFIX "/config"
       -#define MARKPREFIX BASEPREFIX "/marks/%s"
       -#define INCFILE BASEPREFIX "/status"
       -
        void die(char *fmt, ...);
        void edie(char *fmt, ...);
        void *reallocz(void *p, int l, int z);
 (DIR) diff --git a/mark.c b/mark.c
       t@@ -18,21 +18,10 @@
        #include "llist.h"
        #include "txtdb.h"
        #include "imap.h"
       +#include "path.h"
        
        char *argv0;
        
       -char *
       -mark_mkmarkfile(char *cfgn, char *mailbox)
       -{
       -        char *prefix, *path;
       -
       -        prefix = expandhome(MARKPREFIX);
       -        path = smprintf(prefix, cfgn, mailbox);
       -        free(prefix);
       -
       -        return path;
       -}
       -
        mark_t *
        mark_init(char *cfgn, char *mailbox)
        {
       t@@ -42,7 +31,7 @@ mark_init(char *cfgn, char *mailbox)
                if (cfgn == NULL)
                        cfgn = "default";
        
       -        path = mark_mkmarkfile(cfgn, mailbox);
       +        path = path_mkmarkfile(cfgn, mailbox);
                marks = mark_read(path);
                if (marks == NULL)
                        marks = mark_new();
       t@@ -84,7 +73,7 @@ mark_stop(mark_t *marks)
                char *path;
        
                if (marks->changed) {
       -                path = mark_mkmarkfile(marks->name, (char *)marks->data);
       +                path = path_mkmarkfile(marks->name, (char *)marks->data);
                        if (mark_write(marks, path) == NULL)
                                edie("mark_write");
                        free(path);
 (DIR) diff --git a/mark.h b/mark.h
       t@@ -20,7 +20,6 @@
        #define mark_read txtdb_read
        #define mark_write txtdb_write
        
       -char *mark_mkmarkfile(char *cfgn, char *mailbox);
        mark_t *mark_init(char *cfgn, char *mailbox);
        void mark_free(mark_t *marks);
        mark_t *mark_cfg(config_t *cfg);
 (DIR) diff --git a/path.c b/path.c
       t@@ -0,0 +1,196 @@
       +/*
       + * Copy me if you can.
       + * by 20h
       + */
       +
       +#include <unistd.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <sys/stat.h>
       +#include <sys/types.h>
       +#include <stdarg.h>
       +#include <fcntl.h>
       +#include <string.h>
       +
       +#include "arg.h"
       +#include "ind.h"
       +#include "path.h"
       +
       +char *argv0;
       +
       +enum {
       +        PATH_MKFILE = 0x00,
       +        PATH_MKDIR
       +};
       +
       +char *
       +path_chkmk(char *base, char *spath, int mode, int cmode)
       +{
       +        struct stat sbuf;
       +        char *path, *home;
       +        int fd;
       +
       +        if (base != NULL) {
       +                home = expandhome(base);
       +                path = smprintf("%s/%s", home, spath);
       +                free(home);
       +        } else {
       +                path = memdup(spath, strlen(spath)+1);
       +        }
       +
       +        if (stat(path, &sbuf) < 0) {
       +                switch(mode) {
       +                case PATH_MKFILE:
       +                        fd = open(path, O_WRONLY|O_CREAT|O_TRUNC,
       +                                        (cmode >= 0)? \
       +                                        cmode : (S_IRUSR|S_IWUSR));
       +                        if (fd < 0)
       +                                edie("open");
       +                        close(fd);
       +                        break;
       +                case PATH_MKDIR:
       +                        if (mkdir(path, (cmode >= 0)? \
       +                                        cmode : S_IRWXU) < 0) {
       +                                edie("mkdir");
       +                        }
       +                        break;
       +                default:
       +                        die("path_chkmkdir: Unknown mode.\n");
       +                }
       +        }
       +
       +        return path;
       +}
       +
       +char *
       +path_chkmkfile(char *base, char *path, int mode)
       +{
       +        return path_chkmk(base, path, PATH_MKFILE, mode);
       +}
       +
       +char *
       +path_chkmkdir(char *base, char *path, int mode)
       +{
       +        return path_chkmk(base, path, PATH_MKDIR, mode);
       +}
       +
       +char *
       +path_mkrppath(char *rppath)
       +{
       +        return path_chkmkdir("~", (rppath)? rppath : RPPATH, -1);
       +}
       +
       +char *
       +path_mkbasepath(char *cfgn)
       +{
       +        char *path, *rpath;
       +
       +        path = path_mkrppath(NULL);
       +        rpath = path_chkmkdir(path, (cfgn)? cfgn : "default", -1);
       +        free(path);
       +
       +        return rpath;
       +}
       +
       +char *
       +path_mkcfgfile(char *cfgn)
       +{
       +        char *path, *rpath;
       +
       +        path = path_mkbasepath(cfgn);
       +        rpath = path_chkmkfile(path, "config", -1);
       +        free(path);
       +
       +        return rpath;
       +}
       +
       +char *
       +path_mkmarkfile(char *cfgn, char *markn)
       +{
       +        char *path, *mpath;
       +
       +        if (markn == NULL)
       +                return NULL;
       +
       +        path = path_mkbasepath(cfgn);
       +        mpath = path_chkmkdir(path, "marks", -1);
       +        free(path);
       +
       +        path = path_chkmkfile(mpath, markn, -1);
       +        free(mpath);
       +
       +        return path;
       +}
       +
       +char *
       +path_mkincfile(char *cfgn)
       +{
       +        char *path, *rpath;
       +
       +        path = path_mkbasepath(cfgn);
       +        rpath = path_chkmkfile(path, "status", -1);
       +        free(path);
       +
       +        return rpath;
       +}
       +
       +void
       +pathusage(void)
       +{
       +        die("usage: %s [-bhi] [-c cfg]\n", argv0);
       +}
       +
       +int
       +pathmain(int argc, char *argv[])
       +{
       +        int status;
       +        char *cfgn, *path;
       +
       +        enum {
       +                PRINTBASE = 0x01,
       +                INITBASE = 0x02,
       +        };
       +
       +        status = 0;
       +        cfgn = NULL;
       +
       +        ARGBEGIN {
       +        case 'b':
       +                status |= PRINTBASE;
       +                break;
       +        case 'c':
       +                cfgn = EARGF(pathusage());
       +                break;
       +        case 'i':
       +                status |= INITBASE;
       +                break;
       +        default:
       +                pathusage();
       +        } ARGEND;
       +
       +        if (status & PRINTBASE) {
       +                path = path_mkbasepath(cfgn);
       +                printf("%s\n", path);
       +                free(path);
       +                return 0;
       +        }
       +
       +        if (status & INITBASE) {
       +                /* Will initialize all subpathnames. */
       +                path = path_mkbasepath(cfgn);
       +                free(path_chkmkfile(path, "config", -1));
       +                free(path_chkmkfile(path, "status", -1));
       +                free(path_chkmkdir(path, "drafts", -1));
       +                free(path_chkmkdir(path, "marks", -1));
       +                free(path_chkmkdir(path, "tmpl", -1));
       +
       +                printf("The directory '%s' has been initialized.\n", path);
       +                free(path);
       +                return 0;
       +        }
       +
       +        pathusage();
       +
       +        return 0;
       +}
       +
 (DIR) diff --git a/path.h b/path.h
       t@@ -0,0 +1,25 @@
       +/*
       + * Copy me if you can.
       + * by 20h
       + */
       +
       +#ifndef __PATH_H__
       +#define __PATH_H__
       +
       +#define RPPATH ".rohrpost"
       +
       +char *path_chkmk(char *base, char *spath, int mode, int cmode);
       +char *path_chkmkdir(char *base, char *path, int mode);
       +char *path_chkmkfile(char *base, char *path, int mode);
       +
       +char *path_mkrppath(char *rppath);
       +char *path_mkbasepath(char *cfgn);
       +char *path_mkcfgfile(char *cfgn);
       +char *path_mkmarkbasepath(char *cfgn);
       +char *path_mkmarkfile(char *cfgn, char *markn);
       +char *path_mkincfile(char *cfgn);
       +
       +int pathmain(int argc, char *argv[]);
       +
       +#endif
       +
 (DIR) diff --git a/rohrpost.c b/rohrpost.c
       t@@ -31,6 +31,7 @@
        #include "ids.h"
        #include "mime.h"
        #include "util.h"
       +#include "path.h"
        
        char *argv0;
        
       t@@ -73,6 +74,7 @@ struct command cmds[] = {
                {"rprm", DOINSTALL, removemain},
                {"rpsel", DOINSTALL, selectmain},
                {"rpview", DONTINSTALL, viewmain},
       +        {"rppath", DOINSTALL, pathmain},
        };
        
        int