rohrpost

A commandline mail client to change the world as we see it.
git clone git://r-36.net/rohrpost
Log | Files | Refs | LICENSE

commit 24b5d99fda7e3603ae9136e13e241f3f76d48692
parent 119cc0c7df1604df82651fdc9ea6afa9b884452f
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(-)

diff --git a/Makefile b/Makefile @@ -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} diff --git a/bin/rpcat b/bin/rpcat @@ -1,4 +1,4 @@ #!/bin/sh -rpview -r $* +rpview -r $* | cat diff --git a/bin/rpcomp b/bin/rpcomp @@ -1,6 +1,6 @@ #!/bin/sh -BASE="$(rpcfg -b)" +BASE="$(rppath -b)" if [ ! -x $BASE/tmpl/compose.sh ]; then diff --git a/bin/rpflag b/bin/rpflag @@ -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 diff --git a/bin/rpfwd b/bin/rpfwd @@ -1,6 +1,6 @@ #!/bin/sh -BASE="$(rpcfg -b)" +BASE="$(rppath -b)" usage() { printf "usage. %s [-h] msgids\n" "$(basename $1)" 2>&1 diff --git a/bin/rpinc b/bin/rpinc @@ -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 diff --git a/bin/rpnews b/bin/rpnews @@ -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 - diff --git a/bin/rpprint b/bin/rpprint @@ -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 diff --git a/bin/rprepl b/bin/rprepl @@ -1,6 +1,6 @@ #!/bin/sh -BASE="$(rpcfg -b)" +BASE="$(rppath -b)" if [ ! -x $BASE/tmpl/repl.sh ]; then diff --git a/bin/rpscan b/bin/rpscan @@ -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 diff --git a/bin/rpview b/bin/rpview @@ -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 diff --git a/cfg.c b/cfg.c @@ -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) { @@ -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(); @@ -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 @@ -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); @@ -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); } @@ -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; @@ -179,7 +158,7 @@ configmain(int argc, char *argv[]) DOLIST = 0x04, DODELETE = 0x08, DOSEARCH = 0x10, - DOBASE = 0x20 + DOINIT = 0x20 }; status = 0; @@ -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; @@ -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) { diff --git a/cfg.h b/cfg.h @@ -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); diff --git a/flag.c b/flag.c @@ -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"); diff --git a/inc.c b/inc.c @@ -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) { @@ -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(); @@ -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); diff --git a/inc.h b/inc.h @@ -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); diff --git a/ind.h b/ind.h @@ -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); diff --git a/mark.c b/mark.c @@ -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) { @@ -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(); @@ -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); diff --git a/mark.h b/mark.h @@ -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); diff --git a/path.c b/path.c @@ -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; +} + diff --git a/path.h b/path.h @@ -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 + diff --git a/rohrpost.c b/rohrpost.c @@ -31,6 +31,7 @@ #include "ids.h" #include "mime.h" #include "util.h" +#include "path.h" char *argv0; @@ -73,6 +74,7 @@ struct command cmds[] = { {"rprm", DOINSTALL, removemain}, {"rpsel", DOINSTALL, selectmain}, {"rpview", DONTINSTALL, viewmain}, + {"rppath", DOINSTALL, pathmain}, }; int