dmc

dynamic mail client
git clone git://git.suckless.org/dmc
Log | Files | Refs | README | LICENSE

commit 28ae5038608041eaee262165ac7a1576d64238be
parent 43eaf431363a563976bc93d3b69df5f80cbac5ba
Author: pancake <nopcode.org>
Date:   Mon, 10 May 2010 22:19:41 +0200

* Honor HOME and EDITOR environment variables
Diffstat:
TODO | 1+
config.def.h | 2+-
dmc.c | 104++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
3 files changed, 65 insertions(+), 42 deletions(-)

diff --git a/TODO b/TODO @@ -1,5 +1,6 @@ TODO ---- +* use dmc-tag to 'replied' 'new' 'forwarded' 'partial' mails * PULL METHOD: * lsd ! cd - ; ls ! get 1 --- diff --git a/config.def.h b/config.def.h @@ -1,5 +1,5 @@ #define VERSION "0.1" -#define DMCDIR "/home/pancake/.dmc" +#define DMCDIR ".dmc" #define DIRPERM 0750 #define EDITOR "vim" #define MAXACC 16 /* maximum number of accounts */ diff --git a/dmc.c b/dmc.c @@ -6,11 +6,14 @@ #include <dirent.h> #include <unistd.h> #include <stdlib.h> +#include <stdarg.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include "config.h" +static char *editor; +static char dmcdir[128]; static char **dmcaccounts(); static char prompt[64]; static char **acc, *defacc = NULL; @@ -46,9 +49,21 @@ static int dmcstore() { } #endif +static const char* wd(const char *fmt, ...) { + va_list ap; + int len; + static char ret[512]; + va_start (ap, fmt); + len = strlen (dmcdir); + memcpy (ret, dmcdir, len); + vsnprintf (ret+len, sizeof (ret)-len, fmt, ap); + va_end (ap); + return ret; +} + static const char *dmcalias(const char *filter) { static char line[64]; - FILE *fd = fopen (DMCDIR"/addrbook", "r"); + FILE *fd = fopen (wd ("addrbook"), "r"); if (fd) { for (;;) { fgets (line, sizeof (line), fd); @@ -69,20 +84,21 @@ static const char *dmcmailpath(const char *name) { /* check ./%s */ if (fexist (name)) return name; + // TODO: simplify in loop and use wd() /* check DMCDIR/box/$acc/in/%s.eml */ - snprintf (path, sizeof (path), DMCDIR"/box/%s/in/%s.eml", defacc, name); + snprintf (path, sizeof (path), "%s/box/%s/in/%s.eml", dmcdir, defacc, name); if (fexist (path)) return path; /* check DMCDIR/box/$acc/in/%s */ - snprintf (path, sizeof (path), DMCDIR"/box/%s/in/%s", defacc, name); + snprintf (path, sizeof (path), "%s/box/%s/in/%s", dmcdir, defacc, name); if (fexist (path)) return path; /* check DMCDIR/box/$acc/%s */ - snprintf (path, sizeof (path), DMCDIR"/box/%s/%s", defacc, name); + snprintf (path, sizeof (path), "%s/box/%s/%s", dmcdir, defacc, name); if (fexist (path)) return path; /* check DMCDIR/box/%s */ - snprintf (path, sizeof (path), DMCDIR"/box/%s", name); + snprintf (path, sizeof (path), "%s/box/%s", dmcdir, name); if (fexist (path)) return path; /* not found */ @@ -90,16 +106,25 @@ static const char *dmcmailpath(const char *name) { } static void dmcinit() { - if (!fexist (DMCDIR)) - if (mkdir (DMCDIR, DIRPERM) == -1) { - fprintf (stderr, "Cannot create "DMCDIR"\n"); + char *tmp = getenv ("EDITOR"); + editor = tmp? tmp: EDITOR; + if (!(tmp = getenv ("HOME"))) { + fprintf (stderr, "Cannot find HOME\n"); exit (1); } - mkdir (DMCDIR"/tmp", DIRPERM); - mkdir (DMCDIR"/box", DIRPERM); - mkdir (DMCDIR"/acc", DIRPERM); + // NOTE: force home to be absolute path + snprintf (dmcdir, sizeof (dmcdir), "/%s/"DMCDIR"/", tmp); + if (!fexist (dmcdir)) + if (mkdir (dmcdir, DIRPERM) == -1) { + fprintf (stderr, "Cannot create \"%s\"\n", dmcdir); + exit (1); + } + mkdir (wd ("tmp"), DIRPERM); + mkdir (wd ("box"), DIRPERM); + mkdir (wd ("acc"), DIRPERM); acc = dmcaccounts (); defacc = acc[0]; + // signal (SIGINT, dmcstop); atexit (dmcstop); reply.out = reply.err = NULL; @@ -107,9 +132,8 @@ static void dmcinit() { static char *cfgget(const char *key) { FILE *fd; - char file[128], line[128], *ptr, *ret = NULL; - snprintf (file, sizeof (file), DMCDIR"/acc/%s", defacc); - if ((fd = fopen (file, "r"))) { + char line[128], *ptr, *ret = NULL; + if ((fd = fopen (wd ("acc/%s", defacc), "r"))) { int len = strlen (key); while (!feof (fd)) { fgets (line, sizeof (line), fd); @@ -291,8 +315,7 @@ static void dmcpush(const char *name) { int i; for (i=0; acc[i]; i++) { - snprintf (path, sizeof (path), DMCDIR"/box/%s/out", acc[i]); - dir = opendir (path); + dir = opendir (wd ("box/%s/out", acc[i])); while ((de = readdir (dir))) { char *n = de->d_name; if (*n != '.' && !strstr (n, ".d")) { @@ -300,9 +323,8 @@ static void dmcpush(const char *name) { printf ("%s: ", file); fflush (stdout); if (dmcsend (file)) { - snprintf (path, sizeof (path), - "mv %s* "DMCDIR"/box/%s/sent", - file, defacc); + snprintf (path, sizeof (path), "mv %s* '%s'", + file, wd ("box/%s/sent", defacc)); system (path); // do not use system() } } @@ -336,16 +358,17 @@ static char **dmcaccounts() { DIR *dir; int acc = 0; memset (buf, 0, sizeof (buf)); - if (readlink (DMCDIR"/acc.default", buf, sizeof (buf))!=-1) { + if (readlink (wd ("acc.default"), buf, sizeof (buf))!=-1) { defacc = buf + strlen (buf)-1; while (*defacc != '/') defacc--; accounts[acc++] = strdup (++defacc); } else fprintf (stderr, "No default account defined.\n"); - dir = opendir (DMCDIR"/acc"); + dir = opendir (wd ("acc")); while ((de = readdir (dir)) && acc<MAXACC-2) if (*de->d_name != '.' && (!defacc || strcmp (de->d_name, defacc))) accounts[acc++] = strdup (de->d_name); + closedir (dir); accounts[acc] = NULL; return accounts; } @@ -442,7 +465,7 @@ static int dmcmail(const char *addr, const char *subj, const char *slurp, const const char *from = cfgget("MAIL="); char file[128], line[128]; int fd; - snprintf (file, sizeof (file), DMCDIR"/box/%s/out/mail.XXXXXX", acc[0]); + snprintf (file, sizeof (file), "%s/box/%s/out/mail.XXXXXX", dmcdir, acc[0]); fd = mkstemp (file); if (fd != -1) { snprintf (line, sizeof (line), @@ -474,7 +497,10 @@ static int dmcmail(const char *addr, const char *subj, const char *slurp, const if (fsize (file)<32) { fprintf (stderr, "Aborted\n"); unlink (file); - } else symlink (file, DMCDIR"/mail.last"); + } else { + snprintf (line, sizeof (line), "%s/mail.last", dmcdir); + symlink (file, line); + } } else fprintf (stderr, "Cannot create '%s'\n", file); return 0; } @@ -485,7 +511,7 @@ static void dmcattach(const char *file) { while (*name!='/' && name>file) name--; name++; - if (readlink (DMCDIR"/mail.last", path, sizeof (path)-10)!=-1) { + if (readlink (wd ("mail.last"), path, sizeof (path)-10)!=-1) { strcat (path, ".d/"); mkdir (path, 0750); strcat (path, name); @@ -566,15 +592,15 @@ int main(int argc, char **argv) { switch (argv[1][1]) { case 'l': if (argc>2) { - snprintf (line, sizeof (line), DMCDIR"/box/%s/in/%s.eml", acc[0], argv[2]); + snprintf (line, sizeof (line), "%s/box/%s/in/%s.eml", dmcdir, acc[0], argv[2]); if (fexist (line)) { - snprintf (line, sizeof (line), "cat '"DMCDIR"/box/%s/in/%s.eml'", - acc[0], argv[2]); + snprintf (line, sizeof (line), "cat '%s/box/%s/in/%s.eml'", + dmcdir, acc[0], argv[2]); system (line); // implement native cat break; } - snprintf (line, sizeof (line), DMCDIR"/box/%s", argv[2]); - } else snprintf (line, sizeof (line), DMCDIR"/box/%s/in", acc[0]); + snprintf (line, sizeof (line), "%s/box/%s", dmcdir, argv[2]); + } else snprintf (line, sizeof (line), "%s/box/%s/in", dmcdir, acc[0]); if ((dir = opendir (line))) { while ((de = readdir (dir))) { if (*de->d_name!='.') { @@ -620,7 +646,7 @@ int main(int argc, char **argv) { for (i=0; acc[i]; i++) printf ("%s\n", acc[i]); } else { - snprintf (file, sizeof (file), DMCDIR"/acc/%s", argv[2]); + snprintf (file, sizeof (file), "%s/acc/%s", dmcdir, argv[2]); if (!fexist (file)) { /* create template */ FILE *fd = fopen (file, "w"); @@ -649,22 +675,18 @@ int main(int argc, char **argv) { unlink (file); } else { printf ("Default account has changed.\n"); - unlink (DMCDIR"/acc.default"); - symlink (file, DMCDIR"/acc.default"); - snprintf (line, sizeof (line), DMCDIR"/box/%s", argv[2]); - mkdir (line, DIRPERM); - snprintf (line, sizeof (line), DMCDIR"/box/%s/out", argv[2]); - mkdir (line, DIRPERM); - snprintf (line, sizeof (line), DMCDIR"/box/%s/in", argv[2]); - mkdir (line, DIRPERM); - snprintf (line, sizeof (line), DMCDIR"/box/%s/sent", argv[2]); - mkdir (line, DIRPERM); + unlink (wd ("acc.default")); + symlink (file, wd ("acc.default")); + mkdir (wd ("box/%s", argv[2]), DIRPERM); + mkdir (wd ("box/%s/out", argv[2]), DIRPERM); + mkdir (wd ("box/%s/in", argv[2]), DIRPERM); + mkdir (wd ("box/%s/sent", argv[2]), DIRPERM); } } break; case 'a': if (argc<3) { - snprintf (line, sizeof (line), EDITOR" '"DMCDIR"/addrbook'"); + snprintf (line, sizeof (line), "%s '%s'", editor, wd ("addrbook")); system (line); } else { const char *mail = dmcalias (argv[2]);