dmc

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

commit 03b1147df0e9a5c124a30c9361ef01abcae32921
parent c3b07500a5c3132713e8733b7a11c4c6c980735a
Author: pancake@localhost.localdomain <unknown>
Date:   Sun,  1 Nov 2009 23:19:32 +0100

* Simplify the HAVE_SSL build
  - Remove config.def.h .. we now use config.def.mk
  - make HAVE_SSL=0 to disable ssl
* Initial implementation of dmc-mdir
* pack.c is now in 2 spaces indentation
Diffstat:
Makefile | 10++++++----
README | 15++++++++++-----
config.def.h | 1-
config.mk | 2+-
dmc | 2--
dmc-mdir | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dmc-tag | 2--
pack.c | 252+++++++++++++++++++++++++++++++++++++++----------------------------------------
sock.c | 1-
9 files changed, 208 insertions(+), 144 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,12 +4,14 @@ ifeq ($(HAVE_SSL),1) SSL_LIBS=`pkg-config libssl --libs` CFLAGS+=`pkg-config libssl --cflags` endif +CFLAGS+=-DHAVE_SSL=${HAVE_SSL} +CFLAGS+=-DVERSION=\"${VERSION}\" -all: config.h dmc-smtp dmc-pop3 dmc-imap4 dmc-pack +all: config.mk dmc-smtp dmc-pop3 dmc-imap4 dmc-pack -config.h: - @echo creating $@ from config.def.h - cp config.def.h config.h +config.mk: + @echo creating $@ from config.def.mk + cp config.def.mk config.mk ${MAKE} clean dmc-smtp: smtp.o diff --git a/README b/README @@ -6,13 +6,18 @@ dmc is a minimalist email client solution Requirements ------------ msmtp to send emails (dmc-smtp is not implemented yet) + openssl to build with SSL support Installation ------------ Few binaries will be copied into the bin directory - make all install PREFIX=/usr + make all install PREFIX=/usr + +If you want to build dmc without SSL edit config.mk or type: + + make HAVE_SSL=0 Configuration @@ -20,7 +25,7 @@ Configuration Accounting information is stored in ~/.dmc/acc and can be edited with - dmc -e myaccount + dmc -e myaccount Type your signature in ~/.dmc/signature @@ -28,15 +33,15 @@ Running ------- Start it in daemon mode - dmc -d + dmc -d To send a mail add the contact to your addressbook - echo 'user <foo@bar.com>' > ~/.dmc/addrbook + echo 'user <foo@bar.com>' > ~/.dmc/addrbook or edit the addressbook - dmc -a + dmc -a Then type the mail: diff --git a/config.def.h b/config.def.h @@ -1 +0,0 @@ -#define HAVE_SSL 1 diff --git a/config.mk b/config.mk @@ -2,6 +2,6 @@ VERSION = 0.1 PREFIX ?= /usr CFLAGS ?= -Wall -HAVE_SSL=1 +HAVE_SSL = 1 CC ?= gcc diff --git a/dmc b/dmc @@ -1,8 +1,6 @@ #!/bin/sh -# # dmc - dynamic mail client # Copyleft 2009 -- pancake <at> nopcode <dot> org -# VERSION="0.1" COPYRIGHT="Copyleft -- pancake@nopcode.org" diff --git a/dmc-mdir b/dmc-mdir @@ -0,0 +1,67 @@ +#!/bin/sh +# dmc - dynamic mail client +# Copyleft 2009 -- pancake <at> nopcode <dot> org +# TODO: rewrite in C + +MD=$1 +if [ -z "${MD}" ]; then + echo "Usage: dmc-mdir [Maildir-path]" + exit 1 +fi + +dir="" +while : ; do + read A + arg0=`echo $A | cut -d ' ' -f 1` + arg1=`echo $A | cut -d ' ' -f 2-` + case $arg0 in + "ls") + echo "cur $(ls $MD/$dir/cur | wc -l)" + echo "new $(ls $MD/$dir/new | wc -l)" + echo "tmp $(ls $MD/$dir/tmp | wc -l)" + echo "### 1 ls" > /dev/stderr + ;; + "lsd") + ( cd $MD/$dir ; ls -d .??* | cat ) + echo "### 1 lsd" > /dev/stderr + ;; + "cat") + file=$(ls $MD/$dir | head -n $arg1 | tail -n 1) + if [ -f "$file" ]; then + cat $file + echo "### 1 cat" > /dev/stderr + else + echo "### 0 cat No such file" > /dev/stderr + fi + ;; + "head") + dmc-hdr : < $(ls $MD/$dir/tmp | head -n $arg1 | tail -n 1) + echo "### 1 head" > /dev/stderr + ;; + "rm") + file=$(ls $MD/$dir | head -n $arg1 | tail -n 1) + if [ -f "$file" ]; then + rm -f $file + echo "### 1 rm" > /dev/stderr + else + echo "### 0 rm No such file" > /dev/stderr + fi + ;; + "pwd") + echo $dir + echo "### 1 pwd" > /dev/stderr + ;; + "login") + # ignore + ;; + "exit") + exit 0 + ;; + "cd") + dir=$arg1 + ;; + *) + echo "Usage: ls lsd cat cd" + ;; + esac +done diff --git a/dmc-tag b/dmc-tag @@ -1,9 +1,7 @@ #!/bin/sh -# # dmc - dynamic mail client # Copyleft 2009 -- pancake <at> nopcode <dot> org # TODO: rewrite in C -# [ -z "${DMCTAG_ROOT}" ] && \ DMCTAG_ROOT="${HOME}/.dmctag" diff --git a/pack.c b/pack.c @@ -9,145 +9,141 @@ static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; -void b64_encode(unsigned char in[3], unsigned char out[4], int len) -{ - out[0] = cb64[ in[0] >> 2 ]; - out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; - out[2] = (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); - out[3] = (len > 2 ? cb64[ in[2] & 0x3f ] : '='); +void b64_encode(unsigned char in[3], unsigned char out[4], int len) { + out[0] = cb64[ in[0] >> 2 ]; + out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; + out[2] = (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); + out[3] = (len > 2 ? cb64[ in[2] & 0x3f ] : '='); } -int b64_decode(unsigned char in[4], unsigned char out[3]) -{ - unsigned char len = 3, i, v[4]; - for(i=0;i<4;i++) { - if (in[i]<43||in[i]>122) - return -1; - v[i] = cd64[in[i]-43]; - if (v[i]!='$') v[i]-=62; - else { len = i-1; break; } - } - out[0] = v[0] << 2 | v[1] >> 4; - out[1] = v[1] << 4 | v[2] >> 2; - out[2] = ((v[2] << 6) & 0xc0) | v[3]; - return len; +int b64_decode(unsigned char in[4], unsigned char out[3]) { + unsigned char len = 3, i, v[4]; + for(i=0;i<4;i++) { + if (in[i]<43||in[i]>122) + return -1; + v[i] = cd64[in[i]-43]; + if (v[i]!='$') v[i]-=62; + else { len = i-1; break; } + } + out[0] = v[0] << 2 | v[1] >> 4; + out[1] = v[1] << 4 | v[2] >> 2; + out[2] = ((v[2] << 6) & 0xc0) | v[3]; + return len; } -void mime_pack(char **files, int nfiles) -{ - FILE *fd = NULL; - char b[1024], cmd[1024], *ptr = NULL; - unsigned char bd[1024]; - int header = 1, len, in, out, i; +void mime_pack(char **files, int nfiles) { + FILE *fd = NULL; + char b[1024], cmd[1024], *ptr = NULL; + unsigned char bd[1024]; + int header = 1, len, in, out, i; - memset(b, '\0', 1024); - while(fgets(b, 1023, stdin)) { - if (header && b[0] == '\n') { - printf( "Content-Type: multipart/mixed; boundary=\"dmc-multipart\"\n\n" - "--dmc-multipart\n" - "Content-Type: text/plain\n"); - header = 0; - } - printf("%s", b); - } - for(i = 0; i < nfiles; i++) { - snprintf(cmd, 1023, "file -i \"%s\"", files[i]); - if (!(fd=popen(cmd, "r"))) - continue; - fgets(b, 1023, fd); - pclose(fd); - if (!(ptr = strchr(b, ' '))) - continue; - if (!(fd=fopen(files[i], "r"))) - continue; - printf( "--dmc-multipart\n"); - printf( "Content-Type: %s", ptr+1); - printf( "Content-Disposition: attachment;" - "filename=\"%s\"\n", files[i]); - if (strstr(ptr, "text")) { - printf("Content-Transfer-Encoding: quoted-printable\n\n"); - while(fgets(b, 1023, fd)) - printf("%s", b); - } else { - printf("Content-Transfer-Encoding: base64\n\n"); - while((len=fread(b, 1, 57, fd))) { - memset(bd,'\0',1024); - for(in=out=0;in<len;in+=3,out+=4) - b64_encode((unsigned char*)b+in,bd+out,len-in>3?3:len-in); - printf("%s\n", bd); - } - } - fclose(fd); - } - printf("--dmc-multipart--\n"); + memset(b, '\0', 1024); + while(fgets(b, 1023, stdin)) { + if (header && b[0] == '\n') { + printf( "Content-Type: multipart/mixed; boundary=\"dmc-multipart\"\n\n" + "--dmc-multipart\n" + "Content-Type: text/plain\n"); + header = 0; + } + printf("%s", b); + } + for(i = 0; i < nfiles; i++) { + snprintf(cmd, 1023, "file -i \"%s\"", files[i]); + if (!(fd=popen(cmd, "r"))) + continue; + fgets(b, 1023, fd); + pclose(fd); + if (!(ptr = strchr(b, ' '))) + continue; + if (!(fd=fopen(files[i], "r"))) + continue; + printf( "--dmc-multipart\n"); + printf( "Content-Type: %s", ptr+1); + printf( "Content-Disposition: attachment;" + "filename=\"%s\"\n", files[i]); + if (strstr(ptr, "text")) { + printf("Content-Transfer-Encoding: quoted-printable\n\n"); + while(fgets(b, 1023, fd)) + printf("%s", b); + } else { + printf("Content-Transfer-Encoding: base64\n\n"); + while((len=fread(b, 1, 57, fd))) { + memset(bd,'\0',1024); + for(in=out=0;in<len;in+=3,out+=4) + b64_encode((unsigned char*)b+in,bd+out,len-in>3?3:len-in); + printf("%s\n", bd); + } + } + fclose(fd); + } + printf("--dmc-multipart--\n"); } void mime_unpack() { - FILE *fd = NULL; - char b[1024], boundary[1024], encoding[1024], filename[1024], *ptr = NULL; - unsigned char bd[1024]; - int entity = 0, dump = 0, len, in, out, i; + FILE *fd = NULL; + char b[1024], boundary[1024], encoding[1024], filename[1024], *ptr = NULL; + unsigned char bd[1024]; + int entity = 0, dump = 0, len, in, out, i; - boundary[0] = encoding[0] = filename[0] = '\0'; - memset(b, '\0', 1024); - while(fgets(b, 1023, stdin)) { - if (!memcmp(b, "--", 2)) { - if (boundary[0] && strstr(b, boundary) && - !memcmp(b+strlen(b)-3, "--", 2)) { - entity = 0; - dump = 0; - } else { - strncpy(boundary, b+2, 1023); - if ((len = strlen(boundary)) > 0) - boundary[len-1] = '\0'; - if (fgets(b, 1023, stdin) && strstr(b, "Content-Type:")) { - entity = 1; - dump = 0; - } - } - } - if (entity) { - if ((ptr = strstr(b, "Content-Transfer-Encoding:"))) { - strncpy(encoding, ptr+26, 1023); - } else if ((ptr = strstr(b, "filename="))) { - strncpy(filename, ptr+10, 1023); - if ((len=strlen(filename)) > 1) - filename[len-2] = '\0'; - } else if (b[0] == '\n') { - if (!dump && filename[0] && (fd = fopen(filename, "w"))) { - printf("%s\n", filename); - dump = 1; - continue; - } else if (dump && strstr(encoding, "base64")) - dump = 0; - } - } else boundary[0] = '\0'; - if (dump) { - if (strstr(encoding, "base64")) { - memset(bd,'\0',1024); - if ((len = strlen(b)) > 0) - b[len-1] = '\0'; - for(in=out=0;in<len-1;in+=4) - out+=b64_decode((unsigned char*)b+in,bd+out); - for(i=0;i<out;i++) - fputc(bd[i], fd); - } else fputs(b, fd); - } else if (fd) { - fclose(fd); - fd = NULL; - encoding[0] = filename[0] = '\0'; - } - } + boundary[0] = encoding[0] = filename[0] = '\0'; + memset(b, '\0', 1024); + while(fgets(b, 1023, stdin)) { + if (!memcmp(b, "--", 2)) { + if (boundary[0] && strstr(b, boundary) && + !memcmp(b+strlen(b)-3, "--", 2)) { + entity = 0; + dump = 0; + } else { + strncpy(boundary, b+2, 1023); + if ((len = strlen(boundary)) > 0) + boundary[len-1] = '\0'; + if (fgets(b, 1023, stdin) && strstr(b, "Content-Type:")) { + entity = 1; + dump = 0; + } + } + } + if (entity) { + if ((ptr = strstr(b, "Content-Transfer-Encoding:"))) { + strncpy(encoding, ptr+26, 1023); + } else if ((ptr = strstr(b, "filename="))) { + strncpy(filename, ptr+10, 1023); + if ((len=strlen(filename)) > 1) + filename[len-2] = '\0'; + } else if (b[0] == '\n') { + if (!dump && filename[0] && (fd = fopen(filename, "w"))) { + printf("%s\n", filename); + dump = 1; + continue; + } else if (dump && strstr(encoding, "base64")) + dump = 0; + } + } else boundary[0] = '\0'; + if (dump) { + if (strstr(encoding, "base64")) { + memset(bd,'\0',1024); + if ((len = strlen(b)) > 0) + b[len-1] = '\0'; + for(in=out=0;in<len-1;in+=4) + out+=b64_decode((unsigned char*)b+in,bd+out); + for(i=0;i<out;i++) + fputc(bd[i], fd); + } else fputs(b, fd); + } else if (fd) { + fclose(fd); + fd = NULL; + encoding[0] = filename[0] = '\0'; + } + } } /* TODO: Implement dmc-pack -l to only list filenames attached to the mail */ -int main(int argc, char **argv) -{ - if(argc < 2 || !strcmp(argv[1], "-h")) - printf("usage: %s [-uh | attachment1 attachment2...]\n", argv[0]); - else if(!strcmp(argv[1], "-u")) - mime_unpack(); - else mime_pack(argv+1, argc-1); - return 0; +int main(int argc, char **argv) { + if(argc < 2 || !strcmp(argv[1], "-h")) + printf("usage: %s [-uh | attachment1 attachment2...]\n", argv[0]); + else if(!strcmp(argv[1], "-u")) + mime_unpack(); + else mime_pack(argv+1, argc-1); + return 0; } diff --git a/sock.c b/sock.c @@ -8,7 +8,6 @@ #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> -#include "config.h" #if HAVE_SSL #include <openssl/ssl.h>