dmc

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

commit 80b2c4152281151f6e8103b258e929bcd624b0c4
parent b984c091502272e99581e830d365c3e982d3d451
Author: pancake@localhost.localdomain <unknown>
Date:   Sun, 11 Oct 2009 20:36:23 +0200

* Initial design of the ~/.dmc/acc and ~/.dmc/tmp
  - Allows to easily configure accounts for pop3 and imap4
  - No support for smtp, and imap4 is incomplete atm
* Properly parse input from fifo files
* Daemon launch is now implemented, a client can now
  be implemented by using echo, :> and cat
* Fix output of the dmc-pop3.c parsing
  - Single line containing command, return value and status string
  - After \n there's the body of the command result
  - \x00 is found at the end (EOF character)
Diffstat:
TODO | 1+
src/dmc | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
src/pop3.c | 55++++++++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 115 insertions(+), 15 deletions(-)

diff --git a/TODO b/TODO @@ -0,0 +1 @@ +* --stop and pid registration is broken diff --git a/src/dmc b/src/dmc @@ -3,11 +3,73 @@ # Dynamic Mail Client # -FIFO=fifo-session -./dmc-pop3 $FIFO | nc radare.org 110 > $FIFO -exit 0 - -./dmc-pop3 | nc localhost 110 | ./dmc-pop3-post -./dmc-imap4 | openssl s_client -host radare.org -port 993 | ./dmc-imap4 +VERSION="0.1" +COPYRIGHT="Copyleft -- pancake@nopcode.org" mkdir -p ~/.dmc/mail +mkdir -p ~/.dmc/tmp +mkdir -p ~/.dmc/acc + +function acc_daemon { + FIFO=~/.dmc/tmp/${NAME}.fifo + INPUT=~/.dmc/tmp/${NAME}.input + OUTPUT=~/.dmc/tmp/${NAME}.output + + if [ ${SSL} = 1 ]; then + NETCMD="openssl s_client -host $HOST -port $POST" + else + NETCMD="nc $HOST $PORT" + fi + + echo "Starting $NAME account daemon..." + + rm -f ${INPUT} + mkfifo ${INPUT} + (while : ; do cat ${INPUT} ; done) | \ + ./dmc-${PROTOCOL} $FIFO 2> ${OUTPUT} | $NETCMD > $FIFO + rm -f ${INPUT} +} + +function start_account_daemons { + i=0 + for a in ~/.dmc/accounts/* ; do + ( source $a ; acc_daemon ) & + i=$(($i+1)) + done + if [ "$i" = 0 ]; then + echo "No accounts defined in ~/.dmc/acc" + exit 1 + fi +} + +function start_test_daemon { + NAME="test" + SSL=0 + PROTOCOL="pop3" + HOST=radare.org + PORT=110 + acc_daemon +} + +case "$1" in +"--test") + start_test_daemon + ;; +"--start") + start_account_daemons + ;; +"--stop") + for a in ~/.dmc/tmp/*.pid ; do + echo $a + kill -INT `cat $a` + done + ;; +"-v"|"--version") + echo "dmc v${VERSION} ${COPYRIGHT}" + ;; +"--help"|"-h"|*) + echo "Usage: dmc [--start|--stop|--test|--version|--help]" + ;; +esac + +exit 0 diff --git a/src/pop3.c b/src/pop3.c @@ -11,10 +11,12 @@ #include <poll.h> +static char *cmd = NULL; static char word[1024]; static char *fifo; static int ff; +/* XXX : Use of stdin FILE* fails when using fifo files */ static char *getword() { fscanf(stdin, "%255s", word); if (feof(stdin)) @@ -31,6 +33,7 @@ static int ready() { } static int waitreply(int lock) { + char *ch, *str = word; int ret, reply = -1; fflush(stdout); while(lock || ready()) { @@ -38,22 +41,41 @@ static int waitreply(int lock) { ret = read(ff, word, 512); if (ret<1) break; + word[ret] = 0; if (reply==-1) { - if (!memcmp(word, "+OK", 3)) - reply = 1; - else - if (!memcmp(word, "-ERR", 4)) - reply = 0; + ch = strchr(str, '\r'); + if (!ch) ch = strchr(str, '\n'); + if (ch) { + if (!memcmp(word, "+OK", 3)) + reply = 1; + else + if (!memcmp(word, "-ERR", 4)) + reply = 0; + *ch = 0; + fprintf(stderr, "%s %d \"%s\"\n", cmd, ret, str); + str = ch+((ch[1]=='\n')?2:1); + } } - fprintf(stderr, "\n\n-->(%d)(%s)<--\n\n", ret, word); + // TODO: \r \n issues + ch = strstr(str, "\r\n."); + if (ch) + *ch = '\0'; + fprintf(stderr, "%s\n", str); } - fprintf(stderr, "REPLY BOOL IS %d\n", reply); + fflush(stderr); + write(2, "\x00", 1); // end of output return reply; } static int doword(char *word) { int ret = 1; - if (*word == '\0' || !strcmp(word, "exit")) { + free (cmd); + cmd = strdup(word); + //if (*word == '\0' || !strcmp(word, "exit")) { + if (*word == '\0') { + /* Do nothing */ + } else + if (!strcmp(word, "exit")) { printf("QUIT\n"); waitreply(1); ret = 0; @@ -99,12 +121,27 @@ static void cleanup(int foo) { exit(0); } +/* XXX: do not use system here */ +static int storepid(const char *fifo) { + int ret; + char *cmd = malloc(strlen(fifo)+32); + sprintf(cmd, "echo %d > %s.pid", getpid(), fifo); + ret = system(cmd); + free(cmd); + return ret; +} + int main(int argc, char **argv) { if (argc>1) { signal(SIGINT, cleanup); fifo = argv[1]; mkfifo(fifo, 0600); - ff = open(fifo, O_RDONLY); //O_NONBLOCK|O_RDWR); + ff = open(fifo, O_RDONLY); + if (ff == -1) { + fprintf(stderr, "Cannot open fifo file.\n"); + return 1; + } + storepid(fifo); waitreply(1); while(doword(getword())); cleanup(0);