commit fdeff1b6e7b09bedb1f87326fc70a90716503980
parent 0288b48f2b47ad004b6b17020a238c1c371d868e
Author: pancake <nopcode.org>
Date: Mon, 3 May 2010 01:38:06 +0200
* Explain how to configure msmtp in README
* dmc-cmd is now mostly implementing all the
commands of the 'dmc' shellscript
Diffstat:
README | | | 17 | +++++++++++++++++ |
dmc-cmd.c | | | 234 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
2 files changed, 240 insertions(+), 11 deletions(-)
diff --git a/README b/README
@@ -34,6 +34,23 @@ edited with
Type your signature in ~/.dmc/signature
+Configuring msmtp:
+------------------
+To be able to send emails you have to properly configure msmtp.
+
+$ cat <<EOF > ~/.msmtprc
+defaults
+
+account <account-name>
+user <user-name>
+auth login
+from <email-address>
+password <smtp-password>
+host <smtp-host-name>
+
+account default : <account-name>
+EOF
+
Running
-------
Start one dmc mail daemon for each account
diff --git a/dmc-cmd.c b/dmc-cmd.c
@@ -1,32 +1,244 @@
#include <stdio.h>
#include <string.h>
+#include <dirent.h>
#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define DMCDIR "/home/pancake/.dmc"
+#define EDITOR "vim"
+#define VERSION "0.1"
static char prompt[64];
+static char **acc;
+
+static int dmcstart(const char *name) {
+ return 0;
+}
+
+static int dmcstop(const char *name) {
+ return 0;
+}
+
+static char *dmccmd(const char *cmd, char *err, int errlen) {
+ return 0;
+}
+
+static int dmcpull(const char *name) {
+ return 0;
+}
+
+static int dmcpush(const char *name) {
+ return 0;
+}
+
+#define MAXACC 4
+static char **dmcaccounts() {
+ struct dirent *de;
+ static char *accounts[MAXACC];
+ char buf[256], *defacc = NULL;
+ DIR *dir;
+ int acc = 0;
+ memset (buf, 0, sizeof (buf));
+ if (readlink (DMCDIR"/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");
+ while ((de = readdir (dir)))
+ if (*de->d_name != '.' && (!defacc || strcmp (de->d_name, defacc)))
+ accounts[acc++] = strdup (de->d_name);
+ accounts[acc] = NULL;
+ return accounts;
+}
+static void charrfree(char **ptr) {
+ char **p = ptr;
+ while (*p) {
+ free(*p);
+ p++;
+ }
+ *ptr = NULL;
+}
static int dmcline(const char *line) {
+ char err[128];
char *ptr = strchr (line, ' ');
if (ptr)
*ptr = '\0';
- printf ("--> (%s)\n", ptr);
- if (!strcmp (line, "")) {
-
+ if (!strcmp (line, "?")) {
+ printf ("Usage: push pull exit\n");
+ } else
+ if (!strcmp (line, "push")) {
+ dmcpush (acc[0]);
+ } else
+ if (!strcmp (line, "pull")) {
+ dmcstart (acc[0]);
+ dmcpull (acc[0]);
+ dmcstop (acc[0]);
+ } else
+ if (!strcmp (line, "exit")) {
+ return 0;
} else {
/* bypass to child */
+ ptr = dmccmd (line, err, sizeof (err));
+ if (ptr) {
+ printf ("%s\n", ptr);
+ fprintf (stderr, "%s\n", err);
+ free (ptr);
+ } else fprintf (stderr, "## No reply\n");
}
return 1;
}
+static int usage(const char *argv0, int lon) {
+ fprintf (stderr, "Usage: %s [-hv] [-s file] [-e acc] [-a addr] [-m [A|S A]] [-l [box]]\n", argv0);
+ if (lon) {
+ fprintf (stderr,
+ " -m [A|S A .. ] ; create mail (Subject, Address, ..)\n"
+ " -c [cmd] ; command shell\n"
+ " -e [acc] ; list/edit/set default accounts\n"
+ " -a [addr] ; grep in addressbook\n"
+ " -l [box] ; list mails in specified box of def account\n"
+ " -s [file] ; send mail\n"
+ " -v ; show version\n"
+ "");
+ }
+ return 0;
+}
+
+static int fexist(const char *path) {
+ struct stat st;
+ int ret = stat (path, &st);
+ return (ret != -1);
+}
+
+static int fsize(const char *path) {
+ FILE *fd = fopen (path, "r");
+ int len = 0;
+ if (fd) {
+ len = fseek (fd, 0, SEEK_END);
+ fclose (fd);
+ }
+ return len;
+}
+
int main(int argc, char **argv) {
- char line[128];
- strcpy (prompt, "dmc> ");
- do {
- write (1, prompt, strlen (prompt));
- read (0, line, sizeof (line));
- if (feof (stdin))
- strcpy (line, "exit\n");
- } while (dmcline (line));
+ char file[128], line[128];
+ struct dirent *de;
+ DIR *dir;
+ int i;
+
+ if (argc < 2)
+ return usage (argv[0], 0);
+
+ acc = dmcaccounts ();
+
+ if (argv[1][0] == '-')
+ switch (argv[1][1]) {
+ case 'l':
+ if (argc>2) {
+ snprintf (line, sizeof (line), DMCDIR"/box/%s/in/%s.eml", acc[0], argv[2]);
+ if (fexist (line)) {
+ snprintf (line, sizeof (line), "cat '"DMCDIR"/box/%s/in/%s.eml'",
+ 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]);
+ charrfree (acc);
+ if ((dir = opendir (line))) {
+ while ((de = readdir (dir))) {
+ if (*de->d_name!='.')
+ printf ("%s:\n", de->d_name);
+ }
+ closedir (dir);
+ }
+ break;
+ case 'v':
+ printf ("dmc v"VERSION"\n");
+ break;
+ case 's':
+ case 'm':
+ fprintf (stderr, "TODO\n");
+ break;
+ case 'e':
+ if (argc<3) {
+ for (i=0; acc[i]; i++)
+ printf ("%s\n", acc[i]);
+ } else {
+ snprintf (file, sizeof (file), DMCDIR"/acc/%s", argv[2]);
+ if (!fexist (file)) {
+ /* create template */
+ FILE *fd = fopen (file, "w");
+ if (fd) {
+ fprintf (fd,
+ "NAME=test\n"
+ "SSL=0\n"
+ "LIMIT=50 # get only 50 mails for each folder\n"
+ "PROTOCOL=pop3 # imap4\n"
+ "HOST=serverhost.com\n"
+ "PORT=110\n"
+ "#SEND=acc-name\n"
+ "SEND=!msmtp\n"
+ "MAIL=username@domain.com\n"
+ "USER=username\n"
+ "PASS=password\n");
+ fclose (fd);
+ } else {
+ fprintf (stderr, "Cannot write in %s\n", file);
+ return 1;
+ }
+ }
+ snprintf (line, sizeof (line), EDITOR" %s", file);
+ system (line);
+ if (fsize(file)<32) {
+ printf ("Abort\n");
+ unlink (file);
+ } else {
+ printf ("Default account has changed.\n");
+ unlink (DMCDIR"/acc.default");
+ symlink (file, DMCDIR"/acc.default");
+ }
+ }
+ charrfree (acc);
+ return 0;
+ case 'a':
+ if (argc<3) {
+ snprintf (line, sizeof (line), EDITOR" '"DMCDIR"/addrbook'");
+ system (line);
+ } else {
+ FILE *fd = fopen (DMCDIR"/addrbook", "r");
+ if (fd) {
+ while (!feof (fd)) {
+ fgets (line, sizeof (line), fd);
+ for (i=2; i<argc; i++) {
+ if (strstr (line, argv[i]))
+ printf ("%s", line);
+ }
+ }
+ fclose (fd);
+ }
+ }
+ break;
+ case 'c':
+ strcpy (prompt, "dmc> ");
+ do {
+ write (1, prompt, strlen (prompt));
+ fgets(line, sizeof (line), stdin);
+ if (feof (stdin))
+ strcpy (line, "exit");
+ else line[strlen (line)-1] = '\0';
+ } while (dmcline (line));
+ break;
+ default:
+ return usage (argv[0], 1);
+ }
+
+ charrfree (acc);
return 0;
}