dmc

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

commit 99651cc5e47e904d9ce8f1d7d99bbaeb74507fb4
parent 6fe9d1430bad2be16b9f17438cd447cf792a3822
Author: pancake@localhost.localdomain <unknown>
Date:   Wed, 28 Oct 2009 01:44:10 +0100

* Import dmc-tag
* Add doc/design documentation
* Minor syntax fixes in pack.c
Diffstat:
Makefile | 1+
dmc | 0
dmc-tag | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
doc/design | 44++++++++++++++++++++++++++++++++++++++++++++
pack.c | 8+++-----
5 files changed, 172 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile @@ -19,6 +19,7 @@ dmc-pack: pack.o install: cp -f dmc.1 ${PREFIX}/share/man/man1 cp -f dmc ${PREFIX}/bin + cp -f dmc-tag ${PREFIX}/bin cp -f dmc-smtp ${PREFIX}/bin cp -f dmc-pop3 ${PREFIX}/bin cp -f dmc-imap4 ${PREFIX}/bin diff --git a/dmc b/dmc diff --git a/dmc-tag b/dmc-tag @@ -0,0 +1,124 @@ +#!/bin/sh +# +# dmc - dynamic mail client +# Copyleft 2009 -- pancake <at> nopcode <dot> org +# TODO: rewrite in C +# + +[ -z "${DMCTAG_ROOT}" ] && \ + DMCTAG_ROOT="${HOME}/.dmctag" +if [ ! -d "${DMCTAG_ROOT}" ]; then + mkdir -p "${DMCTAG_ROOT}" + if [ ! $? = 0 ]; then + echo "Cannot create \${DMCTAG_ROOT}" + exit 1 + fi +fi +cd ${DMCTAG_ROOT} + +function set_file { + FILE=$1 + if [ -e "${OLDPWD}/${FILE}" ]; then + if [ ! "`echo $FILE|cut -c 1`" = / ]; then + # autocomplete relative paths + FILE="$OLDPWD/$FILE" + fi + else + echo "Cannot find $FILE" + exit 1 + fi + export FILE +} + +# untag this file . this is highly suboptimal. in C will be much faster +function untag { + FILE=$1 + for TAG in * ; do + grep -v ${FILE} $TAG > $TAG.tmp + mv $TAG.tmp $TAG + done +} + +case "$1" in +"-f") + cat * | sort | uniq + ;; +"-m") + # move cached files in from to + for a in * ; do + sed -e "s,^$1,$2," $a > $a.tmp + mv $a.tmp $a + done + ;; +"-c") + # check/cleanup for missing files + if [ -n "$2" ] ; then + set_file "$2" + if [ -z "`cat * | grep $FILE`" ]; then + rm -f "${FILE}" + fi + else + for a in `$0 -f` ; do + if [ ! -e $a ]; then + echo Untag missing file $a + untag ${FILE} + fi + done + fi + ;; +"-l") + # show all available tags + if [ -z "$2" ]; then + ls | cat + else + shift + while [ -n "$1" ] ; do + if [ -e "${DMCTAG_ROOT}/$1" ]; then + cat ${DMCTAG_ROOT}/$1 + else + echo "Cannot find tag $1" + fi + shift + done + fi + ;; +"-u") + untag $2 + ;; +"-v") + echo "dmc-tag-0.1 (c) 2009 pancake(at)nopcode(dot)org" + ;; +"") + echo "Usage: dmc-tag [-uhv] [-c [file ..]][-m dir dir] [[,-u] [file] [[tag ..]]]" + ;; +"-h") + $0 + echo " dmc-tag file # get tags of file" + echo " dmc-tag file tag1 tag2 # set tags of file" + echo " dmc-tag -u file # untag file" + echo " dmc-tag -m dir1 dir2 # move files from dir1 to dir2 in tags" + echo " dmc-tag -f # list all tagged files" + echo " dmc-tag -l # list tags" + echo " dmc-tag -l tag1 tag2 # list files matching tag1+tag2" + echo " dmc-tag -c # check tag consistency. untag all nonexistent files" + echo " dmc-tag -c file # remove file if not tagged" + echo " dmc-tag -v # show version" + echo " dmc-tag -h # show this help" + ;; +*) + if [ -z "$2" ]; then + # get tags of given file + set_file "$1" + grep "$1" * | cut -d : -f 1 + else + # set tags for a file + set_file "$1" + untag "${FILE}" + shift + while [ -n "$1" ] ; do + echo "${FILE}" >> ${DMCTAG_ROOT}/$1 + shift + done + fi + ;; +esac diff --git a/doc/design b/doc/design @@ -0,0 +1,44 @@ +dmc design +========== + ++--------+ +| source | Maildir, mbox, pop3, imap4, mbox ++--------+ (login, ls, exit, cat, head, ...) + | + +-------+ + | cache | Local storage cache + +-------+ (pull, push) + | + +------+ + | tags | Tagging system pointing to cache contents + +------+ (set, get, list) + | ++----------------+ +| mail processor | mail client, user interface ++----------------+ (process mail headers, create mails, filter tags..) + +For some accounts we will probably be interested in not caching anything. +This is the case of local maildir and mbox spools. + + +attachments +=========== + +Attachments can be extracted from any mail by using the dmc-pack utility. +This tool parses a mail from stdin and extracts the attachments on +separated files in the current directory. + + +tags +==== + +local mailbox is a filesystem cache + +filename = unixtimestamp + 2 random letters + +Tags are used to mark the mails or files + + $ dmc-tag -s file [tag ...] # set tags for specific file + $ dmc-tag -g [tag ...] # get/grep files matching those AND'd tags + $ dmc-tag -l # list all available tags + $ dmc-tag - < mail # wtf? diff --git a/pack.c b/pack.c @@ -71,9 +71,9 @@ int mime_unpack() } else boundary[0] = '\0'; } } else if (entity) { - if ((ptr = strstr(b, "Content-Transfer-Encoding:"))) + if ((ptr = strstr(b, "Content-Transfer-Encoding:"))) { strncpy(encoding, ptr+26, 1023); - else if ((ptr = strstr(b, "filename="))) { + } else if ((ptr = strstr(b, "filename="))) { strncpy(filename, ptr+10, 1023); filename[strlen(filename)-2] = '\0'; printf("%s\n", filename); @@ -88,8 +88,7 @@ int mime_unpack() b64_decode(b+i,bd+o); for(i=0;i<o;i++) fputc(bd[i], fd); - } else - fputs(b, fd); + } else fputs(b, fd); } } } @@ -103,6 +102,5 @@ int main(int argc, char **argv) else if(!strcmp(argv[1], "-u")) mime_unpack(); else mime_pack(argv+1, argc-1); - return 0; }