dmc

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

commit 7109edc0fd732ae1155bb6720f334ba8cee743f0
parent 6067e94de0a509f59c34f47ffacd12e3f3441175
Author: pancake@localhost.localdomain <unknown>
Date:   Mon,  2 Nov 2009 01:47:19 +0100

* dmc-mbox does not needs SSL_LIBS
* Many enhacements related to dmc-pop3 and dmc -c
  - dmc -c shell exits if command is 'exit'
  - Fix sync of login and -c user commands
* Fixes in dmc start and dmc stop
* Some little enhacements in the imap4 reply parser
* Fix pop3 output of messages
Diffstat:
Makefile | 9+++++----
dmc | 26++++++++++++++++++--------
imap4.c | 23++++++++++++++++-------
pop3.c | 35++++++++++++++++++++---------------
4 files changed, 59 insertions(+), 34 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,6 +4,7 @@ ifeq ($(HAVE_SSL),1) SSL_LIBS=`pkg-config libssl --libs` CFLAGS+=`pkg-config libssl --cflags` endif + CFLAGS+=-DHAVE_SSL=${HAVE_SSL} CFLAGS+=-DVERSION=\"${VERSION}\" @@ -20,7 +21,10 @@ dmc-smtp: smtp.o ${CC} ${LDFLAGS} smtp.o -o dmc-smtp -lresolv dmc-mbox: mbox.o - ${CC} ${LDFLAGS} ${SSL_LIBS} mbox.o -o dmc-mbox + ${CC} ${LDFLAGS} mbox.o -o dmc-mbox + +dmc-pack: pack.o + ${CC} ${LDFLAGS} pack.o -o dmc-pack dmc-pop3: pop3.o ${CC} ${LDFLAGS} ${SSL_LIBS} pop3.o -o dmc-pop3 @@ -28,9 +32,6 @@ dmc-pop3: pop3.o dmc-imap4: imap4.o ${CC} ${LDFLAGS} ${SSL_LIBS} imap4.o -o dmc-imap4 -dmc-pack: pack.o - ${CC} ${LDFLAGS} pack.o -o dmc-pack - install: chmod +x dmc dmc-tag dmc-mdir cp -f dmc.1 ${PREFIX}/share/man/man1 diff --git a/dmc b/dmc @@ -17,11 +17,12 @@ function acc_daemon { INPUT=~/.dmc/tmp/${NAME}.input OUTPUT=~/.dmc/tmp/${NAME}.output - echo "Starting $NAME account daemon..." + echo "Starting $NAME account $PROTOCOL daemon..." rm -f "${LOCK}" "${INPUT}" "${OUTPUT}" mkfifo "${LOCK}" "${INPUT}" - (sleep 2 ; echo login ${USER} ${PASS} > ${INPUT} ) & + + ( head -n 1 ${LOCK} ; dmc_cmd "login ${USER} ${PASS}" ) & (while : ; do cat ${INPUT} 2> /dev/null ; done) | \ dmc-${PROTOCOL} ${HOST} ${PORT} ${SSL} 2> ${OUTPUT} > ${LOCK} rm -f "${LOCK}" "${INPUT}" "${OUTPUT}" @@ -143,21 +144,27 @@ function pull_mails { done } +function ign { : ; } + case "$1" in "start") start_account_daemons sleep 1 ;; "stop") - for a in ~/.dmc/tmp/*.input ; do - echo $a - echo exit > $a + cd ~/.dmc/tmp + for a in *.input ; do + [ "$a" = "*.input" ] && break # XXX ugly hack + file=`echo $a|cut -d '.' -f 1` + echo Stopping $file daemon + echo exit > $a & + sleep 1 rm -f ~/.dmc/tmp/$a done - sleep 1 - rm -f ~/.dmc/tmp/* - pkill dmc + rm -f ~/.dmc/tmp/* 2> /dev/null pkill cat + trap ign TERM + pkill -TERM dmc ;; "push") for a in ~/.dmc/acc/* ; do @@ -213,6 +220,9 @@ case "$1" in printf "> " read A dmc_cmd "$A" + if [ "$A" = "exit" ]; then + exit 0 + fi done else shift diff --git a/imap4.c b/imap4.c @@ -72,19 +72,28 @@ static int waitreply() { if (!memcmp (ptr+1, "OK", 2)) reply = 1; else + if (!memcmp (ptr+1, "FETCH", 5)) + reply = 1; + else if (!memcmp (ptr+1, "NO", 2)) reply = 0; else // TODO: Do 'BAD' should be -1 ? if (!memcmp (ptr+1, "BAD", 3)) reply = 0; - strcpy (word, ptr); + else + reply = -1; + } else reply = -1; + + ptr = strchr (word, '\r'); + if (!ptr) + ptr = strchr (word, '\n'); + if (ptr) { + *ptr = '\0'; + snprintf (result, 254, "### %s %d \"%s\"\n", cmd, reply, word); + *ptr = '\n'; + if (reply != -1) + strcpy (word, ptr+1); } - ptr = strchr(word, '\n'); - if (ptr) - *ptr=0; - snprintf (result, 254, "### %s %d \"%s\"\n", cmd, reply, word); - if (ptr) - *ptr='\n'; } write (2, word, strlen (word)); } diff --git a/pop3.c b/pop3.c @@ -21,14 +21,15 @@ static char *getword () { return word; } -static int waitreply() { +static int waitreply (int res) { char result[256]; char *ch, *str = word; int lock = 1; int reply = -1; + result[0] = 0; ftruncate (2, 0); - while (lock || sock_ready()) { + while (lock || sock_ready ()) { lock = 0; if (sock_read (word, 512) <1) break; @@ -52,9 +53,13 @@ static int waitreply() { *ch = '\0'; write (2, str, strlen (str)); } - write (1, result, strlen (result)); - /* stderr lseek works on pipes :D */ - lseek (2, 0, 0); + write (2, "\n", 1); + if (res) { + if (result[0] == 0) + snprintf (result, 1023, "### %s %d \"\"\n", cmd, reply); + write (1, result, strlen (result)); + } + lseek(1, 0, SEEK_SET); return reply; } @@ -68,33 +73,33 @@ static int doword (char *word) { } else if (!strcmp (word, "exit")) { sock_printf ("QUIT\n"); - waitreply (); + waitreply (1); ret = 0; } else if (!strcmp (word, "help") || !strcmp (word, "?")) { - fprintf(stderr, "Use: ls cat head rm login exit\n"); + printf ("Use: ls cat head rm login exit\n"); } else if (!strcmp(word, "ls")) { - sock_printf("LIST\n"); - waitreply(); + sock_printf ("LIST\n"); + waitreply (1); } else if (!strcmp(word, "cat")) { sock_printf ("RETR %d\n", atoi(getword())); - waitreply (); + waitreply (1); } else if (!strcmp(word, "head")) { sock_printf ("TOP %d 50\n", atoi(getword())); - waitreply (); + waitreply (1); } else if (!strcmp(word, "rm")) { sock_printf ("DELE %d\n", atoi(getword())); - waitreply (); + waitreply (1); } else if (!strcmp(word, "login")) { sock_printf ("USER %s\n", getword()); - waitreply (); // TODO: if user fail, do not send pass + waitreply (0); // TODO: if user fail, do not send pass sock_printf ("PASS %s\n", getword()); - waitreply (); + waitreply (1); } else sock_printf ("NOOP\n"); return ret; } @@ -107,7 +112,7 @@ int main(int argc, char **argv) { if (sock_connect (argv[1], atoi (argv[2]), ssl) >= 0) { ret = 0; atexit (sock_close); - waitreply (); + waitreply (1); while (doword (getword ())); } else fprintf (stderr, "Cannot connect to %s %d\n", argv[1], atoi(argv[2])); } else fprintf (stderr, "Usage: dmc-pop3 host port [ssl] 2> body > fifo < input\n");