jaromail

a commandline tool to easily and privately handle your e-mail
git clone git://parazyd.org/jaromail.git
Log | Files | Refs | Submodules | README

commit d5d150c5a06e898f0aa91b8fdc0d337abc7bf775
parent f2329a0c84b4942bcee4fca3188aa9f146070946
Author: Jaromil <jaromil@dyne.org>
Date:   Sun, 19 Aug 2012 22:09:56 -0700

temporary commit from a half-way backed rewrite of the addressbook and whitelist system in California

Diffstat:
Mbuild/build-osx.sh | 8++++++++
Msrc/fetchaddr.c | 7+++++--
Msrc/fetchdate.c | 19++++++++++++++-----
Msrc/jaro | 18++++++++++--------
Msrc/zlibs/addressbook | 112+++++++++++++++++++++++++++++++++++++++++++------------------------------------
5 files changed, 98 insertions(+), 66 deletions(-)

diff --git a/build/build-osx.sh b/build/build-osx.sh @@ -134,6 +134,14 @@ CC="$cc" LD=/usr/bin/ld CPP=/usr/bin/cpp \ > /dev/null ; make 2>&1 > /dev/null popd +# build our own mutt +# port deps: db48 tokyocabinet +pushd src/mutt-src +print "MUA Mail user agent" +CC="$cc" LD=/usr/bin/ld CPP=/usr/bin/cpp CFLAGS="$CFLAGS -I/opt/local/include -L/opt/local/lib" \ + ./configure --with-ssl --enable-imap --enable-hcache --with-regex --with-tokyocabinet +popd + # CFLAGS="${=cflags}" \ diff --git a/src/fetchaddr.c b/src/fetchaddr.c @@ -97,8 +97,11 @@ int writeout(struct header *h, const char *datefmt, *c=tolower(*c); strftime(timebuf, sizeof(timebuf), datefmt, localtime(&timep)); - printf("%s\t%s\t%s\n", p->mailbox, p->personal && *p->personal ? - p->personal : "no realname given", timebuf); + /* printf("%s\t%s\t%s\n", p->mailbox, p->personal && *p->personal ? */ + /* p->personal : "no realname given", timebuf); */ + + printf("%s,%s\n", p->mailbox, + p->personal && *p->personal ? p->personal : " "); rv = 1; } diff --git a/src/fetchdate.c b/src/fetchdate.c @@ -23,8 +23,12 @@ #include <stdio.h> #include <mairix.h> +#define TEST 1 + int verbose = 0; int do_hardlinks = 0; +char dateformat[256]; + void out_of_mem(char *file, int line, size_t size); void report_error(const char *str, const char *filename); void emit_int(int x); @@ -32,14 +36,19 @@ void emit_int(int x); static struct rfc822 *parsed; int main (int argc, char **argv) { - if( argc < 3 ) { - printf("usage: fetchdate strftime_format filename\n"); + if( argc < 2 ) { + printf("usage: fetchdate filename strftime_format\n"); printf("see man strftime(5) for format options"); exit(1); } + if(argc>2) + snprintf(dateformat, 255, "%s", argv[2]); + else // default date format + strcpy(dateformat, "%a, %d %b %Y"); + // printf("Parsing email: %s\n",argv[1]); - parsed = make_rfc822(argv[2]); + parsed = make_rfc822(argv[1]); if (parsed) { char datebuf[64]; @@ -52,11 +61,11 @@ int main (int argc, char **argv) { if (parsed->hdrs.message_id) printf(" Message-ID: %s\n", parsed->hdrs.message_id); thetm = gmtime(&parsed->hdrs.date); - strftime(datebuf, sizeof(datebuf), "%a, %d %b %Y", thetm); + strftime(datebuf, sizeof(datebuf), dateformat, thetm); printf(" Date: %s\n", datebuf); #else thetm = gmtime(&parsed->hdrs.date); - strftime(datebuf, sizeof(datebuf), argv[1], thetm); + strftime(datebuf, sizeof(datebuf), dateformat, thetm); /* needed by timecloud: diff --git a/src/jaro b/src/jaro @@ -124,7 +124,7 @@ WORKDIR=$MAILDIRS/jaro ${=mkdir} $MAILDIRS ${=mkdir} $WORKDIR -# make sure the directory is private +# make sure the permissions are private chmod 700 $WORKDIR PATH=$WORKDIR/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/opt/local/bin @@ -281,7 +281,7 @@ Main commands: Options: -a use a particular account instead of default (keyword) - -l whitelist or blacklist to use with learn/query/forget + -l whitelist or blacklist for learn/forget etc. -h print this help -v version information for this tool @@ -296,11 +296,11 @@ Maintenance commands: update refresh configurations queue add a mail into outbox - addr look for a matching address in list - query read mail from stdin, return 0 if known to list learn learn addresses from mails piped in stdin forget remove addresses found in mails piped in stdin list prints out the list of known addresses + complete look for a glob matching address in whitelist + isknown read e-mail from stdin, return 0 if sender is known backup move mails from a maildir to a new one with search expr rmdupes remove all duplicated e-mails into a maildir @@ -341,11 +341,13 @@ main() subcommands_opts[stat]="" subcommands_opts[search]="" - subcommands_opts[addr]="" - subcommands_opts[query]="" + subcommands_opts[learn]="" subcommands_opts[forget]="" subcommands_opts[list]="" + subcommands_opts[complete]="" + subcommands_opts[isknown]="" + subcommands_opts[import]="" subcommands_opts[export]="" subcommands_opts[abook]="" @@ -461,8 +463,8 @@ main() stat) CLEANEXIT=0; stats ${PARAM} ;; - addr) CLEANEXIT=0; address ${PARAM} ;; - query) CLEANEXIT=0; query ${PARAM} ;; + complete) CLEANEXIT=0; complete ${PARAM} ;; + isknown) CLEANEXIT=0; isknown ${PARAM} ;; learn) CLEANEXIT=0; learn ${PARAM} ;; forget) CLEANEXIT=0; forget ${PARAM} ;; list) CLEANEXIT=0; list_addresses ${PARAM} ;; diff --git a/src/zlibs/addressbook b/src/zlibs/addressbook @@ -32,15 +32,13 @@ create_addressbook() { cat <<EOF | ${SQL} -batch $WORKDIR/addressbook CREATE TABLE whitelist ( - email text collate nocase, - name text collate nocase unique, - hits int + email text collate nocase unique, + name text collate nocase, ); CREATE TABLE blacklist ( - email text collate nocase, - name text collate nocase unique, - hits int + email text collate nocase unique, + name text collate nocase, ); EOF { test $? != 0 } && { @@ -62,19 +60,21 @@ EOF } return $0 } -update_name() { - func "update address: $1, $2" - cat <<EOF | ${SQL} -batch $WORKDIR/addressbook 2> /dev/null -UPDATE $list SET name="${2}" WHERE email LIKE "${1}"; -EOF - { test $? != 0 } && { - func "address not found or error occurred" } -} + +# update_name() { +# func "update address: $1, $2" +# cat <<EOF | ${SQL} -batch $WORKDIR/addressbook 2> /dev/null +# UPDATE $list SET name="${2}" WHERE email LIKE "${1}"; +# EOF +# { test $? != 0 } && { +# func "address not found or error occurred" } +# } + remove_address() { func "remove address <$1> from $list" cat <<EOF | ${SQL} -batch $WORKDIR/addressbook DELETE FROM $list -WHERE email LIKE "${1}"; +WHERE email IS "${1}"; EOF { test $? != 0 } && { func "address not found or error occurred" } @@ -93,9 +93,8 @@ WHERE email IS "${1}"; EOF return $? } -address() { +complete() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private act "Searching for \"${PARAM[1]}\" in $list" { test "$OS" = "MAC" } && { @@ -114,52 +113,68 @@ address() { } printf "\n" }' } -query() { +isknown() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private - if [ -z ${PARAM[1]} ]; then - email="`${WORKDIR}/bin/fetchaddr -a| awk '{print $1}'`" - else - email="`${WORKDIR}/bin/fetchaddr -x ${PARAM[1]} -a| awk '{print $1}'`" - fi + head="`${WORKDIR}/bin/fetchaddr -x From: -a`" + + + email="${head[(ws:,:)1]}" + exitcode=1 + lookup="`search_email ${email}`" + { test "$lookup" != "" } && { exitcode=0 } + act "Email <$email> found in $list with id $lookup" } learn() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private - - tmp=$TMPDIR/learn.$datestamp.$RANDOM - from="`tee -i $tmp | formail -xFrom: | sed -e 's/\"//g;s/<.*>//;s/^[ \t]*//;s/[ \t]*$//'`" - - if [ -z ${PARAM[1]} ]; then - email="`cat $tmp | ${WORKDIR}/bin/fetchaddr| awk '{print $1}'`" - else - email="`cat $tmp | ${WORKDIR}/bin/fetchaddr -x ${PARAM[1]}| awk '{print $1}'`" - fi - ${=rm} $tmp & - insert_address "$email" "$from" + + what=sender + { test -z ${PARAM[1]} } || { what=${PARAM[1]} } + case ${PARAM[1]} in + sender) # simple: one address only on From: + head="`cat | ${WORKDIR}/bin/fetchaddr -x From: -a`" + email="${head[(ws:,:)1]}" + name="${head[(ws:,:)2]}" + insert_address "$email" "$name" + return 0 + ;; + receiver) # complex: more addresses in To: and Cc: + head="`cat | ${WORKDIR}/bin/fetchaddr -x To: -a`" + for h in ${head}; do + email="${h[(ws:,:)1]} )" + name="${h[(ws:,:)2]} )" + insert_address "$email" "$name" + done + head="`cat | ${WORKDIR}/bin/fetchaddr -x Cc: -a`" + for h in ${head}; do + email="${h[(ws:,:)1]} )" + name="${h[(ws:,:)2]} )" + insert_address "$email" "$name" + done + return 0 + ;; + *) + error "Unknown learning function: $what" ;; + esac + return 1 } forget() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private act "Expecting mail from stdin pipe" - if [ -z ${PARAM[1]} ]; then - email="`${WORKDIR}/bin/fetchaddr| awk '{print $1}'`" - else - email="`${WORKDIR}/bin/fetchaddr -x ${PARAM[1]}| awk '{print $1}'`" - fi - remove_address "${email}" + head="`${WORKDIR}/bin/fetchaddr -x From:`" + + # forget the email part of the parsed head + remove_address "${head[(ws:,:)1]}" } list_addresses() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private { test ${PARAM[1]} } && { list=${PARAM[1]} } @@ -174,8 +189,6 @@ EOF # import addresbook email from VCard import_vcard() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private - { test -r ${PARAM[1]} } || { error "File not found: import ${PARAM[1]}" @@ -244,7 +257,6 @@ BEGIN { newcard=0; c=0; name=""; email=""; } # export addressbook to vcard export_vcard() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private act "Export addressbook into vCard $WORKDIR/addressbook.vcf" tmp=$TMPDIR/export.$datestamp.$RANDOM @@ -282,7 +294,6 @@ EOF export_abook() { { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - chmod 600 $WORKDIR/addressbook # make sure is private if [ -z ${PARAM[1]} ]; then list=whitelist else list=${PARAM[1]}; fi @@ -360,9 +371,8 @@ BEGIN { c=0; name=""; email=""; } DROP TABLE $list; CREATE TABLE $list ( - email text collate nocase, - name text collate nocase unique, - hits int + email text collate nocase unique, + name text collate nocase, ); EOF