commit 23994ab79d4c9e22873526f9c928f934160f8d97
parent 28ae5038608041eaee262165ac7a1576d64238be
Author: pancake <nopcode.org>
Date: Tue, 11 May 2010 00:10:38 +0200
* Fix many errors appeared in previous commit
- Some paths was not correctly handled
- Simplify and refactorize a bit more
* Implemented local 'ls' and 'cat' commands
- Split into dmccat() and dmcls()
Diffstat:
dmc.c | | | 160 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
1 file changed, 98 insertions(+), 62 deletions(-)
diff --git a/dmc.c b/dmc.c
@@ -61,6 +61,18 @@ static const char* wd(const char *fmt, ...) {
return ret;
}
+static const char *abspath(const char *file) {
+ static char filepath[512];
+ char cwd[128];
+ if (*file=='/')
+ return file;
+ getcwd (cwd, sizeof (cwd));
+ snprintf (filepath, sizeof (filepath)-strlen (file)-3, "%s", cwd);
+ strcat (filepath, "/");
+ strcat (filepath, file);
+ return filepath;
+}
+
static const char *dmcalias(const char *filter) {
static char line[64];
FILE *fd = fopen (wd ("addrbook"), "r");
@@ -105,6 +117,62 @@ static const char *dmcmailpath(const char *name) {
return NULL;
}
+static int dmccat(const char *file) {
+ char line[128];
+ const char *f = dmcmailpath (file); // XXX dup?
+ if (f && fexist (f)) {
+ snprintf (line, sizeof (line), "cat '%s'", f);
+ system (line); // implement native cat
+ return 1;
+ } else fprintf (stderr, "Cannot find '%s'\n", file);
+ return 0;
+}
+
+static char *gethdr(const char *path, const char *file, const char *hdr) {
+ char line[1024], *ret = NULL;
+ FILE *fd;
+ int i;
+ snprintf (line, sizeof (line), "%s/%s", path, file);
+ fd = fopen (line, "r");
+ if (fd) {
+ int len = strlen (hdr);
+ while (!feof (fd)) {
+ fgets (line, sizeof (line), fd);
+ if (!memcmp (line, hdr, len)) {
+ i = strlen (line)-1;
+ if (i>len) {
+ line[i--] = '\0';
+ if (line[i]=='\r'||line[i]=='\n')
+ line[i] = '\0';
+ ret = strdup (line+len);
+ } else ret = strdup ("");
+ break;
+ }
+ }
+ fclose (fd);
+ }
+ return ret;
+}
+
+static int dmcls(const char *path) {
+ struct dirent *de;
+ DIR *dir;
+ if ((dir = opendir (path))) {
+ while ((de = readdir (dir))) {
+ if (*de->d_name!='.') {
+ char *subj = gethdr (path, de->d_name, "Subject: ");
+ char *from = gethdr (path, de->d_name, "From: ");
+ printf ("%s:\t%s\n\t%s\n", de->d_name, subj, from);
+ free (from);
+ free (subj);
+ }
+ }
+ closedir (dir);
+ return 1;
+ }
+ return 0;
+}
+
static void dmcinit() {
char *tmp = getenv ("EDITOR");
editor = tmp? tmp: EDITOR;
@@ -112,7 +180,6 @@ static void dmcinit() {
fprintf (stderr, "Cannot find HOME\n");
exit (1);
}
- // NOTE: force home to be absolute path
snprintf (dmcdir, sizeof (dmcdir), "/%s/"DMCDIR"/", tmp);
if (!fexist (dmcdir))
if (mkdir (dmcdir, DIRPERM) == -1) {
@@ -124,7 +191,6 @@ static void dmcinit() {
mkdir (wd ("acc"), DIRPERM);
acc = dmcaccounts ();
defacc = acc[0];
- //
signal (SIGINT, dmcstop);
atexit (dmcstop);
reply.out = reply.err = NULL;
@@ -152,32 +218,6 @@ static char *cfgget(const char *key) {
return ret;
}
-static char *gethdr(const char *path, const char *file, const char *hdr) {
- char line[1024], *ret = NULL;
- FILE *fd;
- int i;
- snprintf (line, sizeof (line), "%s/%s", path, file);
- fd = fopen (line, "r");
- if (fd) {
- int len = strlen (hdr);
- while (!feof (fd)) {
- fgets (line, sizeof (line), fd);
- if (!memcmp (line, hdr, len)) {
- i = strlen (line)-1;
- if (i>len) {
- line[i--] = '\0';
- if (line[i]=='\r'||line[i]=='\n')
- line[i] = '\0';
- ret = strdup (line+len);
- } else ret = strdup ("");
- break;
- }
- }
- fclose (fd);
- }
- return ret;
-}
-
/* server */
static int dmcstart(const char *name) {
char a0[512], a1[32];
@@ -315,7 +355,8 @@ static void dmcpush(const char *name) {
int i;
for (i=0; acc[i]; i++) {
- dir = opendir (wd ("box/%s/out", acc[i]));
+ snprintf (path, sizeof (path), "%s/box/%s/out", dmcdir, acc[i]);
+ dir = opendir (path);
while ((de = readdir (dir))) {
char *n = de->d_name;
if (*n != '.' && !strstr (n, ".d")) {
@@ -333,10 +374,9 @@ static void dmcpush(const char *name) {
}
}
-/* utils */
static int fexist(const char *path) {
struct stat st;
- int ret = stat (path, &st);
+ int ret = path? stat (path, &st): -1;
return (ret != -1);
}
@@ -392,7 +432,6 @@ static int dmcsend(const char *file) {
"dmc-pack `ls %s.d/* 2>/dev/null` < %s "
"| msmtp --user=\"%s\" --from=\"%s\" \"%s\"",
file, file, user, mail, to);
- //printf ("LINE: %s\n", line);
if (system (line) != 0) {
fprintf (stderr, "Error ocurred while sending %s\n", file);
return 0;
@@ -403,7 +442,7 @@ static int dmcsend(const char *file) {
static int dmcline(const char *line) {
char cmd[128];
if (!strcmp (line, "?")) {
- printf ("Usage: on off push pull exit ls cat ..\n");
+ printf ("Usage: on off push pull exit ls lsd cat ..\n");
} else
if (!strcmp (line, "login")) {
char *user = cfgget ("USER=");
@@ -422,8 +461,18 @@ static int dmcline(const char *line) {
if (!strcmp (line, "off")) {
dmcstop ();
} else
+ if (!strcmp (line, "ls")) {
+ if (dmc_pid != -1)
+ dmccmd ("ls\n");
+ else dmcls (wd ("box/%s/in", defacc));
+ } else
+ if (!memcmp (line, "cat ", 4)) {
+ if (dmc_pid != -1)
+ dmccmd (line); // bypass
+ else dmccat (line+4);
+ } else
if (!strcmp (line, "push")) {
- dmcpush (acc[0]);
+ dmcpush (defacc);
} else
if (!strcmp (line, "pull")) {
if (dmcstart (acc[0])) {
@@ -445,7 +494,7 @@ static int dmcline(const char *line) {
static int usage(const char *argv0, int lon) {
fprintf (stderr, "Usage: %s [-hv] [-c [cmd] [-s file] [-e acc] [-A file ..]\n"
- "\t [-a addr] [-m [a [s [..]] [-f m a] [-r m a] [-l [box]]\n", argv0);
+ "\t[-a addr] [-m [a [s [..]] [-f m a] [-r m a] [-l [box]]\n", argv0);
if (lon) fprintf (stderr,
" -m [a [s]..] create mail [addr [subj [file1 file2 ..]]]\n"
" -c [cmd] command shell\n"
@@ -464,10 +513,11 @@ static int usage(const char *argv0, int lon) {
static int dmcmail(const char *addr, const char *subj, const char *slurp, const char *slurptitle) {
const char *from = cfgget("MAIL=");
char file[128], line[128];
- int fd;
+ int fd, ret = 0;
snprintf (file, sizeof (file), "%s/box/%s/out/mail.XXXXXX", dmcdir, acc[0]);
fd = mkstemp (file);
if (fd != -1) {
+ // TODO: fchmod or mkostemp
snprintf (line, sizeof (line),
"X-Mailer: dmc v"VERSION"\n"
"From: %s\n"
@@ -492,17 +542,19 @@ static int dmcmail(const char *addr, const char *subj, const char *slurp, const
}
}
close (fd);
- snprintf (line, sizeof (line), EDITOR" %s", file);
+ snprintf (line, sizeof (line), EDITOR" '%s'", file);
system (line);
if (fsize (file)<32) {
fprintf (stderr, "Aborted\n");
unlink (file);
} else {
snprintf (line, sizeof (line), "%s/mail.last", dmcdir);
+ unlink (line);
symlink (file, line);
+ ret = 1;
}
} else fprintf (stderr, "Cannot create '%s'\n", file);
- return 0;
+ return ret;
}
static void dmcattach(const char *file) {
@@ -511,11 +563,13 @@ static void dmcattach(const char *file) {
while (*name!='/' && name>file)
name--;
name++;
- if (readlink (wd ("mail.last"), path, sizeof (path)-10)!=-1) {
+ path[0] = 0;
+ memset (path, 0, sizeof(path));
+ if (readlink (wd ("mail.last"), path, sizeof (path)-strlen (name)-2)!=-1) {
strcat (path, ".d/");
mkdir (path, 0750);
strcat (path, name);
- symlink (file, path);
+ symlink (abspath (file), path);
} else fprintf (stderr, "Cannot attach '%s'\n", file);
}
@@ -573,8 +627,6 @@ static void dmcfwd(const char *file, const char *addr, const char *msg, const ch
int main(int argc, char **argv) {
char file[128], line[128];
- struct dirent *de;
- DIR *dir;
int i;
if (argc < 2)
@@ -592,27 +644,11 @@ int main(int argc, char **argv) {
switch (argv[1][1]) {
case 'l':
if (argc>2) {
- snprintf (line, sizeof (line), "%s/box/%s/in/%s.eml", dmcdir, acc[0], argv[2]);
- if (fexist (line)) {
- snprintf (line, sizeof (line), "cat '%s/box/%s/in/%s.eml'",
- dmcdir, acc[0], argv[2]);
- system (line); // implement native cat
+ if (dmccat (argv[2]))
break;
- }
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!='.') {
- char *subj = gethdr (line, de->d_name, "Subject: ");
- char *from = gethdr (line, de->d_name, "From: ");
- printf ("%s:\t%s\n\t%s\n", de->d_name, subj, from);
- free (from);
- free (subj);
- }
- }
- closedir (dir);
- }
+ dmcls (line);
break;
case 'A':
for (i=2; i<argc; i++)
@@ -711,10 +747,10 @@ int main(int argc, char **argv) {
}
dmcstop ();
break;
- case 'r': // reply
+ case 'r':
dmcfwd (dmcmailpath (argv[2]), argc>3?argv[3]:"", REPMSG, REPSUB);
break;
- case 'f': // forward
+ case 'f':
dmcfwd (dmcmailpath (argv[2]), argc>3?argv[3]:"", FWDMSG, FWDSUB);
break;
default: