commit 3e5d8243ddc78134ab5d8dbc18fdf8a660157130
parent 8d2823f10f7caf07b8e7545e52d06ae10ffe6b42
Author: Jaromil <jaromil@dyne.org>
Date: Fri, 26 Dec 2014 19:18:09 +0100
list addresses in gpg key signatures, more fixes
Diffstat:
5 files changed, 148 insertions(+), 28 deletions(-)
diff --git a/src/jaro b/src/jaro
@@ -443,20 +443,19 @@ a pipe | in front indicate they take an email body from stdin
import import entries from a VCard file in the $list
- export export the $list to VCard file (addressbook.vcf)
+ export export the $list to a VCard file
- abook edit the $list using abook terminal curses editor
+ abook edit the $list using abook terminal console editor
|learn learn addresses from mails piped in stdin
-|forget remove addresses found in mails piped in stdin
-
- list prints to console all the entries in a $list
+ list prints to console all the entries in $list
search search into $list using a string parameter
|isknown read e-mail from stdin, return 0 if sender is known
+ extract list all recipients or senders found in a maildir
== Operational commands (use -a to indicate which $account)
account names correspond to the filenames, i.e. imap.default
@@ -466,8 +465,8 @@ account names correspond to the filenames, i.e. imap.default
send send all emails queued in outbox/ to an smtp.$account
- peek connect to an imap.$account with ncurses terminal mutt
- remote folders supported. use to delete without download
+ peek connect to an imap folder with ncurses terminal mutt
+ use for server-side operations on emails without download
passwd set account passwords in the OS native keyring
or into a simple, file based, gpg encrypted database.
@@ -492,15 +491,14 @@ maildirs are directories of mails downloaded in Mail/
update updates Filters.txt generating rules (sieve format)
- ramdisk [open|close] activates fast cache in RAM on Mac/OSX (root)
-
Experimental commands:
stat prints a statistical overview on stored maildirs
cert import most common SSL certificates from the Internet
-For a complete introductory documentation, see the User Manual in LaTeX
-Website on <http://jaromail.dyne.org> Report bugs to <https://bugs.dyne.org>
+For a complete introductory documentation, see the User Manual (PDF)
+Website on <http://dyne.org/software/jaro-mail>
+Report bugs to <https://github.com/dyne/JaroMail/issues>
EOF
}
@@ -696,9 +694,9 @@ main()
isknown) CLEANEXIT=0; sender_isknown ${PARAM} ;;
learn) CLEANEXIT=0; learn ${PARAM} ;;
forget) CLEANEXIT=0; forget ${PARAM} ;;
- list) CLEANEXIT=0; edit_abook ${PARAM} ;;
+ list) CLEANEXIT=0; list_addresses ${PARAM} ;;
- import) import_addressbook ${PARAM} ;;
+ import) import_addressbook "${PARAM}" ;;
"export")
case "$PARAM" in
abook)
diff --git a/src/zlibs/addressbook b/src/zlibs/addressbook
@@ -68,15 +68,6 @@ insert_address() {
return 0
}
-# update_name() {
-# func "update address: $1, $2"
-# cat <<EOF | ${SQL} -batch $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() {
warning "remove_address() TODO in abook branch"
return 0
@@ -230,9 +221,129 @@ forget() {
# remove_address "${head[(ws:,:)1]}"
}
+# list all entries in addressbook or a file
+list_addresses() {
+ [[ "$1" = "" ]] && {
+ # TODO: list the default addressbook
+ edit_abook
+ }
+
+ # a map to eliminate duplicates
+ typeset -AU result
+
+ ######### GPG
+ [[ `file "$1"` =~ "GPG key public ring" ]] && {
+
+ notice "Listing addresses found in GPG keyring: $1"
+ _addrs=`gpg --list-keys --with-colons | awk -F: '{print $10}'`
+ for i in ${(f)_addrs}; do
+ _parsed=`print "From: $i" | ${WORKDIR}/bin/fetchaddr -a -x from`
+ _e="${_parsed[(ws:,:)1]}"
+ isemail "$_e"
+ [[ $? = 0 ]] || continue
+ # check if the email is not already parsed
+ [[ "${result[$_e]}" = "" ]] && {
+ _n="${_parsed[(ws:,:)2]}"
+ result+=("$_e" "$_n")
+ print - "$_n <$_e>"
+ }
+ done
+
+ notice "Unique addresses found: ${#result}"
+ # counts which addresses are known to us
+ _known=0
+ for i in ${(k)result}; do
+ lookup_email ${i}
+ [[ $? = 0 ]] || {
+ _known=$(( $_known + 1 )) }
+ done
+ act "new addresses: $_known"
+ }
+
+ [[ `file "$1"` =~ "PGP public key" ]] && {
+ _gpg="gpg --no-default-keyring --keyring $MAILDIRS/cache/pubkey.gpg --batch --with-colons"
+ rm -f $MAILDIRS/cache/pubkey.gpg
+ ${=_gpg} --import "$1"
+ # first make sure all unknown keys are imported
+ _addrs=`${=_gpg} --list-sigs | awk -F: '{print $5 " " $10}'`
+ for i in ${(f)_addrs}; do
+ [[ "$i" =~ "[User ID not found]" ]] && {
+ act "looking up: $i"
+ ${=_gpg} --recv-key ${i[(w)1]}
+ }
+ done
+
+ _addrs=`${=_gpg} --list-sigs | awk -F: '{print $10}'`
+ for i in ${(f)_addrs}; do
+ _parsed=`print "From: $i" | ${WORKDIR}/bin/fetchaddr -a -x from`
+ _e="${_parsed[(ws:,:)1]}"
+ isemail "$_e"
+ [[ $? = 0 ]] || continue
+ # check if the email is not already parsed
+ [[ "${result[$_e]}" = "" ]] && {
+ _n="${_parsed[(ws:,:)2]}"
+ result+=("$_e" "$_n")
+ print - "$_n <$_e>"
+ }
+ done
+
+ notice "Unique addresses found: ${#result}"
+ # counts which addresses are known to us
+ _known=0
+ for i in ${(k)result}; do
+ lookup_email ${i}
+ [[ $? = 0 ]] || {
+ _known=$(( $_known + 1 )) }
+ done
+ act "new addresses: $_known"
+ }
+
+}
+
+
# import an addressbook, autodetect its type
import_addressbook() {
notice "Importing addressbook"
+ func "$1"
+ # a map to eliminate duplicates
+ typeset -AU result
+
+ # stdin
+ [[ "$1" = "stdin" ]] && {
+ act "reading entries from stdin"
+ _stdin=`cat`
+ _new=0
+ for i in ${(f)_stdin}; do
+
+ # skip comments starting with #
+ [[ "$i[1]" = "#" ]] && continue
+
+ _parsed=`print - "From: $i" | ${WORKDIR}/bin/fetchaddr -a -x from`
+ _e="${_parsed[(ws:,:)1]}"
+
+ # check if is really an email
+ isemail "$_e"
+ [[ $? = 0 ]] || continue
+
+ # check if the email is not a duplicate
+ [[ "${result[$_e]}" = "" ]] || continue
+
+ _n="${_parsed[(ws:,:)2]}"
+ result+=("$_e" "$_n")
+
+ # check if the email is not already known
+ lookup_email "$_e"
+ [[ $? = 0 ]] && continue
+
+ [[ $DRYRUN = 0 ]] && insert_address "$_e" "$_n"
+ act "new entry imported: $_n <$_e>"
+ _new=$(( $_new + 1 ))
+ done
+ notice "Valid unique entries parsed: ${#result}"
+ act "new addresses found: ${_new}"
+ return 0
+ }
+
if [[ "$1" != "" ]]; then
func "file specified: $1"
# a file was given as argument
@@ -428,7 +539,7 @@ edit_abook() {
abook --config <(cat <<EOF
set autosave=true
-set mutt_command=jaro
+set mutt_command=jaro compose
set sort_field=name
EOF
) --datafile "$ADDRESSBOOK"
diff --git a/src/zlibs/email b/src/zlibs/email
@@ -355,8 +355,8 @@ VERBOSE=2
EOF
act "Sending out anonymous email via mixmaster"
- recipients=(`hdr $qbody | fetchaddr -a -x to | cut -d, -f1`)
- recipients+=(`hdr $qbody | fetchaddr -a -x cc | cut -d, -f1`)
+ recipients=(`hdr $qbody | ${WORKDIR}/bin/fetchaddr -a -x to | cut -d, -f1`)
+ recipients+=(`hdr $qbody | ${WORKDIR}/bin/fetchaddr -a -x cc | cut -d, -f1`)
for r in ${recipients}; do
act "Sending to: ${r}"
diff --git a/src/zlibs/helpers b/src/zlibs/helpers
@@ -40,6 +40,17 @@ awk '{ for (i=1;i<=NF;i++)
gsub(/<|>|,/ , "" , $i); print $i } }'
}
+isemail() {
+ [[ "$1" = "" ]] && {
+ func "isemail() called on an empty string"
+ return 1
+ }
+ print "$1" | \
+ grep -E "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" \
+ > /dev/null
+ return $?
+}
+
# parses stdin and converts some characters to html
escape_html() {
sed -e '
diff --git a/src/zlibs/maildirs b/src/zlibs/maildirs
@@ -321,7 +321,7 @@ md_extract() {
[[ "${result[$_e]}" = "" ]] && {
_n=${i[(ws:,:)2]}
result+=("$_e" "$_n")
- print "$_n <$_e>"
+ print - "$_n <$_e>"
}
done
notice "Unique $_action found: ${#result}"
@@ -329,8 +329,8 @@ md_extract() {
# counts which addresses are known to us
_known=0
for i in ${(k)result}; do
- lookup="`lookup_email ${i}`"
- [[ "$lookup" = "" ]] || {
+ lookup_email ${i}
+ [[ $? = 0 ]] && {
_known=$(( $_known + 1 )) }
done
act "addresses known: $_known"