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]);