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 a5632f95183662cea1b1b99d346c4ddcbf2961ac
parent 6d0a0f95e2b73cdaff8efc6749aa4092b16837dd
Author: Jaromil <jaromil@dyne.org>
Date:   Fri, 26 Dec 2014 15:09:03 +0100

addressbook export to abook format, with some improvements

Diffstat:
Msrc/jaro | 9++++++++-
Msrc/zlibs/addressbook | 417+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/zlibs/email | 133++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/zlibs/helpers | 5+++++
4 files changed, 283 insertions(+), 281 deletions(-)

diff --git a/src/jaro b/src/jaro @@ -696,7 +696,14 @@ main() list) CLEANEXIT=0; list_addresses ${PARAM} ;; import) import_addressbook ${PARAM} ;; - "export") export_vcard ${PARAM} ;; + "export") + case "$PARAM" in + abook) export_abook ;; + vcard) export_vcard ;; + *) export_vcard ;; + esac + ;; + abook) edit_abook ${PARAM} ;; edit) CLEANEXIT=0; edit_file ${PARAM} ;; diff --git a/src/zlibs/addressbook b/src/zlibs/addressbook @@ -28,8 +28,8 @@ ADDRESSBOOK="$MAILDIRS/Addressbook" create_addressbook() { func "create addressbook" { test -r "$1" } && { - error "Addressbook already exists: $1" - return 1 + error "Addressbook already exists: $1" + return 1 } cat <<EOF | ${SQL} -batch "$1" CREATE TABLE whitelist @@ -44,8 +44,8 @@ CREATE TABLE blacklist ); EOF { test $? != 0 } && { - error "Error creating addressbook database." - return 1 } + error "Error creating addressbook database." + return 1 } # make sure is private chmod 600 "$1" chown $_uid:$_gid "$1" @@ -61,8 +61,8 @@ INSERT INTO $list (email, name) VALUES ("${_email}", "${_name}"); EOF [[ $? = 0 ]] || { - func "address already present in $list" - return 1 + func "address already present in $list" + return 1 } return 0 } @@ -73,7 +73,7 @@ EOF # UPDATE $list SET name="${2}" WHERE email LIKE "${1}"; # EOF # { test $? != 0 } && { -# func "address not found or error occurred" } +# func "address not found or error occurred" } # } remove_address() { @@ -83,12 +83,12 @@ DELETE FROM $list WHERE email IS "${1}"; EOF { test $? != 0 } && { - func "address not found or error occurred" } + func "address not found or error occurred" } } search_name() { func "search_name from $list like $1" - cat <<EOF | ${SQL} -column -batch $ADDRESSBOOK + cat <<EOF | ${SQL} -column -batch $ADDRESSBOOK .width 64 128 SELECT * FROM $list WHERE name LIKE "%${1}%"; @@ -117,29 +117,29 @@ complete() { # completion on configured groups { test -r "$MAILDIRS/Groups" } && { - if [[ "$1" =~ "group/" ]]; then - func "completion will look into groups" - needle="${1[(ws:/:)2]}" - if [ "$needle" = "" ]; then - act "Listing all mailout groups" - matches=`${=find} "$MAILDIRS/Groups" -type f` - else - act "Searching for \"$needle\" in mailout groups" - matches=`${=find} "$MAILDIRS/Groups" -type f -name \"*$needle*\"` - fi - print "Groups: `print $matches | wc -l` matches" - print - for i in ${(f)matches}; do - gr=`basename $i` - print "$gr@jaromail.group\t`wc -l < $i` recipients" - done - return 0 - fi + if [[ "$1" =~ "group/" ]]; then + func "completion will look into groups" + needle="${1[(ws:/:)2]}" + if [ "$needle" = "" ]; then + act "Listing all mailout groups" + matches=`${=find} "$MAILDIRS/Groups" -type f` + else + act "Searching for \"$needle\" in mailout groups" + matches=`${=find} "$MAILDIRS/Groups" -type f -name \"*$needle*\"` + fi + print "Groups: `print $matches | wc -l` matches" + print + for i in ${(f)matches}; do + gr=`basename $i` + print "$gr@jaromail.group\t`wc -l < $i` recipients" + done + return 0 + fi } act "Searching for \"$1\" in addressbook $list" matches="${matches}\n`search_name $1`" - + # mutt query requires something like this print "jaro: $((`print $matches | wc -l` -1)) matches" print "$matches" | awk ' @@ -166,8 +166,8 @@ sender_isknown() { lookup="`lookup_email ${email}`" [[ "$lookup" = "" ]] || { - func "sender_isknown() found <$email> in $list (id $lookup)" - return 0 } + func "sender_isknown() found <$email> in $list (id $lookup)" + return 0 } return 1 } @@ -185,71 +185,71 @@ learn() { buffer=`awk '{ print $0 } /^$/ { exit }'` case ${what} in - - sender) # simple: one address only on From: - head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x From -a`" - # (Q) eliminates quotes, then word split - email="${(Q)head[(ws:,:)1]}" - name="${(Q)head[(ws:,:)2]}" + + sender) # simple: one address only on From: + head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x From -a`" + # (Q) eliminates quotes, then word split + email="${(Q)head[(ws:,:)1]}" + name="${(Q)head[(ws:,:)2]}" print "$head" [[ $DRYRUN == 1 ]] || { - insert_address "$email" "$name" - { test $? = 0 } && { act "new: $_name <${_email}>" } + insert_address "$email" "$name" + { test $? = 0 } && { act "new: $_name <${_email}>" } } - return 0 - ;; - - all) - head="`print $buffer | ${WORKDIR}/bin/fetchaddr -a`" - for h in ${(f)head}; do - # (Q) eliminates quotes, then word split - email="${(Q)h[(ws:,:)1]}" - name="${(Q)h[(ws:,:)2]}" - + return 0 + ;; + + all) + head="`print $buffer | ${WORKDIR}/bin/fetchaddr -a`" + for h in ${(f)head}; do + # (Q) eliminates quotes, then word split + email="${(Q)h[(ws:,:)1]}" + name="${(Q)h[(ws:,:)2]}" + print "$h" - + [[ $DRYRUN == 1 ]] || { - insert_address "$email" "$name" - { test $? = 0 } && { act "new: $_name <${_email}>" } + insert_address "$email" "$name" + { test $? = 0 } && { act "new: $_name <${_email}>" } } - done - return 0 - ;; - - recipient) # complex: more addresses in To: and Cc: - head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x To -a`" - for h in ${(f)head}; do - # (Q) eliminates quotes, then word split - email="${(Q)h[(ws:,:)1]}" - name="${(Q)h[(ws:,:)2]}" + done + return 0 + ;; + + recipient) # complex: more addresses in To: and Cc: + head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x To -a`" + for h in ${(f)head}; do + # (Q) eliminates quotes, then word split + email="${(Q)h[(ws:,:)1]}" + name="${(Q)h[(ws:,:)2]}" print "$h" - + [[ $DRYRUN == 1 ]] || { - insert_address "$email" "$name" - { test $? = 0 } && { act "new: $_name <${_email}>" } + insert_address "$email" "$name" + { test $? = 0 } && { act "new: $_name <${_email}>" } } - done - - head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x Cc -a`" - for h in ${(f)head}; do - # (Q) eliminates quotes, then word split - email="${(Q)h[(ws:,:)1]}" - name="${(Q)h[(ws:,:)2]}" + done + + head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x Cc -a`" + for h in ${(f)head}; do + # (Q) eliminates quotes, then word split + email="${(Q)h[(ws:,:)1]}" + name="${(Q)h[(ws:,:)2]}" print "$h" - + [[ $DRYRUN == 1 ]] || { - insert_address "$email" "$name" - { test $? = 0 } && { act "new: $_name <${_email}>" } + insert_address "$email" "$name" + { test $? = 0 } && { act "new: $_name <${_email}>" } } - done - return 0 - ;; - - *) - error "Unknown learning function: $what" ;; + done + return 0 + ;; + + *) + error "Unknown learning function: $what" ;; esac return 1 - + } forget() { @@ -260,13 +260,11 @@ forget() { remove_address "${head[(ws:,:)1]}" } list_addresses() { - func "list addresses in ${PARAM[1]}" - - { test ${PARAM[1]} } && { list=${PARAM[1]} } + [[ "$1" = "" ]] || list="$1" act "Listing all contents for $list" cat <<EOF | ${SQL} -column -header -batch $ADDRESSBOOK -.width 32 40 +.width 32 72 SELECT * FROM $list; EOF } @@ -275,12 +273,12 @@ EOF import_addressbook() { notice "Importing addressbook" if [ "${PARAM[1]}" != "" ]; then - func "file specified: ${PARAM[1]}" - # a file was given as argument - import_vcard ${PARAM[2]} + func "file specified: ${PARAM[1]}" + # a file was given as argument + import_vcard ${PARAM[2]} else - # no file as parameter - { test "$OS" = "MAC" } && { import_macosx } + # no file as parameter + { test "$OS" = "MAC" } && { import_macosx } fi } @@ -290,7 +288,7 @@ import_macosx() { act "system addressbook from Mac/OSX" { test "$OS" = "MAC" } || { error "Not running on Mac/OSX, operation aborted." } { command -v ABQuery > /dev/null } || { - error "ABQuery not found, operation aborted." } + error "ABQuery not found, operation aborted." } tmp=$TMPDIR/abook.import_osx.$datestamp.$RANDOM newlock $tmp @@ -305,13 +303,13 @@ import_macosx() { lock $ADDRESSBOOK new=0; dupes=0; for a in ${(f)addresses}; do - _email="${a[(ws:|:)1]}" - # remove from name all what is an email between brackets - # crop (trim) all beginning and ending whitespaces from name - _name=`print ${a[(ws:|:)2]} | sed 's/<.*>//;s/^[ \t]*//;s/[ \t]*$//'` - insert_address ${_email} ${_name} - if [ $? = 0 ]; then new=$(( $new + 1 )) - else dupes=$(( $dupes + 1 )); fi + _email="${a[(ws:|:)1]}" + # remove from name all what is an email between brackets + # crop (trim) all beginning and ending whitespaces from name + _name=`print ${a[(ws:|:)2]} | sed 's/<.*>//;s/^[ \t]*//;s/[ \t]*$//'` + insert_address ${_email} ${_name} + if [ $? = 0 ]; then new=$(( $new + 1 )) + else dupes=$(( $dupes + 1 )); fi done unlock $ADDRESSBOOK @@ -326,16 +324,16 @@ import_vcard() { act "import VCard from file: ${PARAM[1]}" { test -r "${PARAM[1]}" } || { - error "File not found: ${PARAM[1]}" - return 1 + error "File not found: ${PARAM[1]}" + return 1 } vcard=${PARAM[1]} head -n1 $vcard | grep '^BEGIN:VCARD' > /dev/null { test $? = 0 } || { - error "File to import is not a VCard: $vcard" - return 1 + error "File to import is not a VCard: $vcard" + return 1 } notice "Import in addressbook VCard ${vcard}" @@ -373,29 +371,29 @@ BEGIN { newcard=0; c=0; name=""; email=""; } newa=1; _name=""; _email="" for a in ${(f)addresses}; do - { test "${a[1]}" = "#" } && { - newa=1; # its the end of the entry - - # handle lines with multiple emails in vcard - # TODO: generate Groups/${_name} from this - for ee in ${=_email}; do - # check if we have this email already - _e=`print ${ee} | extract_emails` - func "lookup_email: ${_e}" - foundemail=`lookup_email "${_e}"` + { test "${a[1]}" = "#" } && { + newa=1; # its the end of the entry + + # handle lines with multiple emails in vcard + # TODO: generate Groups/${_name} from this + for ee in ${=_email}; do + # check if we have this email already + _e=`print ${ee} | extract_emails` + func "lookup_email: ${_e}" + foundemail=`lookup_email "${_e}"` # func "lookup_email: ${_email}" - - { test "$foundemail" = "" } && { - insert_address "${_e}" "${_name}" - act "${a} ${_name} <${_e}>" - } - done - - continue } - { test $newa -eq 1 } && { - # (V) makes special chars visible, we need to remove them.. - _name=`echo ${(V)a} | cut -d^ -f1`; newa=0; continue } - { test $newa -eq 0 } && { _email=`echo ${(V)a} | cut -d^ -f1` } + + { test "$foundemail" = "" } && { + insert_address "${_e}" "${_name}" + act "${a} ${_name} <${_e}>" + } + done + + continue } + { test $newa -eq 1 } && { + # (V) makes special chars visible, we need to remove them.. + _name=`echo ${(V)a} | cut -d^ -f1`; newa=0; continue } + { test $newa -eq 0 } && { _email=`echo ${(V)a} | cut -d^ -f1` } done unlock $ADDRESSBOOK @@ -403,6 +401,52 @@ BEGIN { newcard=0; c=0; name=""; email=""; } notice "Done importing addresses" } +export_abook() { + + lock $ADDRESSBOOK + + out=$MAILDIRS/$list.abook + act "Exporting $list to abook format: $out" + rm -f $out + + func "launching SELECT email,name sqlite3 query" + addresses=`cat <<EOF | ${SQL} -column -header -batch $ADDRESSBOOK \ + | grep -v '^email' +.width 40 100 +.mode list +.separator '|' +SELECT email, name FROM $list; +EOF` + + unlock $ADDRESSBOOK + func "converting database into abook format" + cat <<EOF > $out +# abook addressbook file + +[format] +program=JaroMail +version=$VERSION + +EOF + c=0 + for a in ${(f)addresses}; do + _email="${(Q)a[(ws:|:)1]}" + # remove from name all what is an email between brackets + # crop (trim) all beginning and ending whitespaces from name + _name=`print ${(Q)a[(ws:|:)2]} | trim` + { test "${_email}" != "" } && { + cat <<EOF >> $out +[${c}] +name=${_name} +email=${_email} + +EOF + c=$(( $c + 1 )) + } + done + +} + # export addressbook to vcard export_vcard() { @@ -412,7 +456,7 @@ export_vcard() { lock $ADDRESSBOOK cat <<EOF | ${SQL} -column -header -batch $ADDRESSBOOK \ - | grep -v '^email' > $tmp + | grep -v '^email' > $tmp .width 40 100 .mode list .separator '|' @@ -427,12 +471,12 @@ EOF rm -f $ADDRESSBOOK.vcf touch $ADDRESSBOOK.vcf for a in ${(f)addresses}; do - _email="${a[(ws:|:)1]}" - # remove from name all what is an email between brackets - # crop (trim) all beginning and ending whitespaces from name - _name=`print ${a[(ws:|:)2]} | sed 's/<.*>//;s/^[ \t]*//;s/[ \t]*$//'` - { test "${_email}" != "" } && { - cat <<EOF >> $ADDRESSBOOK.vcf + _email="${a[(ws:|:)1]}" + # remove from name all what is an email between brackets + # crop (trim) all beginning and ending whitespaces from name + _name=`print ${a[(ws:|:)2]} | sed 's/<.*>//;s/^[ \t]*//;s/[ \t]*$//'` + { test "${_email}" != "" } && { + cat <<EOF >> $ADDRESSBOOK.vcf BEGIN:VCARD VERSION:3.0 FN:${_name} @@ -440,113 +484,63 @@ N:;${_name};;; EMAIL;TYPE=HOME:${_email// /} END:VCARD EOF - } + } done } edit_abook() { # take argument even without option -l - { test -z ${PARAM[1]} } || { list=${PARAM[1]} } + [[ "$1" = "" ]] || list="$1" # check if abook binary is found { command -v abook > /dev/null } || { - error "ABook not found, operation aborted." - return 1 + error "ABook not found, operation aborted." + return 1 } - lock $ADDRESSBOOK - - act "Editing addressbook $list" - tmp=$TMPDIR/abook.$datestamp.$RANDOM - newlock $tmp - - func "launching SELECT email,name sqlite3 query" - cat <<EOF | ${SQL} -column -header -batch $addressbook \ - | grep -v '^email' > $tmp -.width 40 100 -.mode list -.separator '|' -SELECT email, name FROM $list; -EOF - func "query returned" - - addresses="$(<$tmp)" - # no need to wipe, will be rewritten - rm -f $tmp + notice "Preparing to edit addressbook $list" - func "converting database into abook format" - cat <<EOF > $tmp -# abook addressbook file - -[format] -program=jaromail -version=1.0 - -EOF - c=0 - for a in ${(f)addresses}; do - _email="${a[(ws:|:)1]}" - # remove from name all what is an email between brackets - # crop (trim) all beginning and ending whitespaces from name - _name=`print ${a[(ws:|:)2]} | sed 's/<.*>//'` - { test "${_email}" != "" } && { - cat <<EOF >> $tmp -[${c}] -name=${_name} -email=${_email} - -EOF - c=$(( $c + 1 )) - } - done + export_abook "$list" func "abook format ready, generating configuration" # generate abook configuration - abookrc=$TMPDIR/abookrc.$datestamp.$RANDOM - cat <<EOF > $abookrc -set autosave=true -set mutt_command=jaro -set sort_field=name -EOF # new abook supports also: # set emailpos=35 # set extra_column=-1 func "ready to launch abook." - abook --config $abookrc --datafile $tmp - # remove config and backup turd - ${=rm} ${tmp}~ - ${=rm} ${abookrc} + abook --config <(cat <<EOF > $abookrc +set autosave=true +set mutt_command=jaro +set sort_field=name +EOF +) --datafile $MAILDIRS/$list.abook + act "Saving changes to native addressbook..." func "exporting abook to spruce format" - tmpspruce=$TMPDIR/abook.spruce.$datestamp.$RANDOM - newlock $tmpspruce - - abook --convert --infile $tmp \ - --outformat spruce | awk ' + addresses=`abook --convert --infile $MAILDIRS/$list.abook \ + --outformat spruce | awk ' BEGIN { c=0; name=""; email=""; } /^#/ { if(email != "") { - c+=1 - print name - print email - print "# " c + c+=1 + print name + print email + print "# " c } email="" next } /^Name:/ { name=$0 } /^Email:/ { email=$0 } -' > $tmpspruce - addresses=`cat $tmpspruce` - unlink $tmpspruce +'` func "done, ready to reimport the database" - rm -f $tmp + tmp=$TMPDIR/abook_edit.$datestamp.$RANDOM # move addressbook to old act "Updating the addressbook database" @@ -563,19 +557,20 @@ EOF newa=1; _name=""; _email="" for a in ${(f)addresses}; do - { test "${a[1]}" = "#" } && { - newa=1; #its the end of the entry - print "INSERT INTO $list (email, name) VALUES (\"${_email}\", \"${_name}\");" >> $tmp - continue } + [[ "${a[1]}" = "#" ]] && { + newa=1; #its the end of the entry + print "INSERT INTO $list (email, name) VALUES (\"${_email}\", \"${_name}\");" >> $tmp + continue } - { test $newa -eq 1 } && { - _name="${a[(ws/:/)2]}"; newa=0; continue } - { test $newa -eq 0 } && { a=${a// /}; _email="${a[(ws/:/)2]}" } + [[ $newa -eq 1 ]] && { + _name="${a[(ws/:/)2]}"; newa=0; continue } + [[ $newa -eq 0 ]] && { a=${a// /}; _email="${a[(ws/:/)2]}" } done func "Inserting the updated addressbook" - cat $tmp | ${SQL} -batch $addressbook 2> /dev/null - unlink $tmp + lock $ADDRESSBOOK + cat $tmp | ${SQL} -batch $addressbook + rm $tmp unlock $ADDRESSBOOK notice "Addressbook updated" } diff --git a/src/zlibs/email b/src/zlibs/email @@ -157,14 +157,13 @@ fetchall() { } fetch() { - { test "$account" = "" } && { + [[ "$account" = "" ]] && { fetchall; return $? } # setup global account variables read_account ${account} # name login host protocol port auth folders accountopt - - { test $? != 0 } && { + [[ $? = 0 ]] || { error "Invalid account: $account" return 1 } @@ -172,13 +171,13 @@ fetch() { notice "Fetching email for account ${account}" is_online ${imap} ${imap_port} - { test $? = 0 } || { return 1 } + [[ $? = 0 ]] || { return 1 } type=imap host=$imap port=$imap_port ask_password - { test $? = 0 } || { + [[ $? = 0 ]] || { error "Impossible to fetch email for account ${account}"; return 1 } @@ -195,8 +194,8 @@ fetch() { fmconf=("poll $imap with proto IMAP user \"$login\" there with password \"$password\"") - if ! [ -z $accountopt ]; then # add option configuration - fmconf+=(" ${accountopt} "); fi + [[ -z $accountopt ]] || { # add option configuration + fmconf+=(" ${accountopt} ") } # check if folders on commandline if [[ "$PARAM[@]" = "" ]]; then @@ -242,14 +241,14 @@ fetch() { fmconf+=(" antispam 571 550 501 554 ") print $accountopt | grep 'keep' > /dev/null - { test $? = 0 } || { + [[ $? = 0 ]] || { error "planning to delete mails from server, account option: $accountopt" } # try login without doing anything print "$fmconf" | fetchmail -c -f - res=$? # examine result - case $ret in + case $res in 1) notice "No mails for $name" unset $fmconf @@ -296,27 +295,27 @@ send() { queue_outbox=`${=find} "${MAILDIRS}/outbox" -type f` queue_outbox_num=`${=find} "${MAILDIRS}/outbox" -type f|wc -l` { test "$queue_outbox_num" = "0" } && { - act "Outbox is empty, no mails to send." - return 0 } + act "Outbox is empty, no mails to send." + return 0 } read_account ${account} { test $? != 0 } && { - error "Invalid account: $account" - return 1 + error "Invalid account: $account" + return 1 } # defaults - { test -z $auth } && { auth=plain } - { test -z $smtp_port } && { smtp_port=25 } + [[ -z $auth ]] && { auth=plain } + [[ -z $smtp_port ]] && { smtp_port=25 } is_online ${smtp} ${smtp_port} - { test $? = 0 } || { - error "Smtp host not reachable: $smtp_host:$smtp_port" - return 1 } + [[ $? = 0 ]] || { + error "Smtp host not reachable: $smtp_host:$smtp_port" + return 1 } notice "Sending out $queue_outbox_num mails via account ${account}" - { test $DRYRUN = 1 } && { return 0 } + [[ $DRYRUN = 1 ]] && { return 0 } # from here on we must unlock on error lock "${MAILDIRS}/outbox" @@ -325,19 +324,19 @@ send() { host=$smtp port=$smtp_port ask_password - { test $? = 0 } || { - error "Error retrieving password for $login on $smtp" - unset password - unlock "${MAILDIRS}/outbox" - return 1 } + [[ $? = 0 ]] || { + error "Error retrieving password for $login on $smtp" + unset password + unlock "${MAILDIRS}/outbox" + return 1 } for qbody in ${(f)queue_outbox}; do - # check if this is an anonymous mail - hdr "$qbody" | grep -i '^from: anon' > /dev/null - if [ $? = 0 ]; then - anoncfg="${TMPDIR}/${smtp}.anon.$RANDOM" - cat <<EOF > "$anoncfg" + # check if this is an anonymous mail + hdr "$qbody" | grep -i '^from: anon' > /dev/null + if [[ $? = 0 ]]; then + anoncfg="${TMPDIR}/${smtp}.anon.$RANDOM" + cat <<EOF > "$anoncfg" REMAIL n POOLSIZE 0 SENDPOOLTIME 0m @@ -355,19 +354,19 @@ VERBOSE=2 EOF - act "Sending out anonymous email via mixmaster" - recipients=(`cat $qbody | fetchaddr -a -x to | cut -d, -f1`) - recipients+=(`cat $qbody | fetchaddr -a -x cc | cut -d, -f1`) - for r in ${recipients}; do - act "Sending to: ${r}" + 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`) + for r in ${recipients}; do + act "Sending to: ${r}" - # parse subject line - anonsubj=`hdr "$qbody" | awk ' + # parse subject line + anonsubj=`hdr "$qbody" | awk ' /^Subject: / { for(i=2;i<=NF;i++) printf "%s ", $i }'` - act "Subject: $anonsubj" + act "Subject: $anonsubj" - # strip headers and send via mixmaster - cat "$qbody" | awk ' + # strip headers and send via mixmaster + cat "$qbody" | awk ' BEGIN { head=1 } /^To: / { print $0; next } /^Cc: / { print $0; next } @@ -382,26 +381,26 @@ BEGIN { head=1 } /^$/ { head=0 } { if(head==0) print $0 } ' | tee -a "$qbody.anon" | mixmaster --config=$anoncfg -m --to="$r" --subject="$anonsubj" - res=$? - mv "$qbody.anon" "$qbody" - func "mixmaster returns $res" - done + res=$? + mv "$qbody.anon" "$qbody" + func "mixmaster returns $res" + done - ${=rm} $anoncfg + ${=rm} $anoncfg - else # normal send with msmtp + else # normal send with msmtp - act "Sending out email" - hdr "$qbody" | awk ' + act "Sending out email" + hdr "$qbody" | awk ' /^From:/ { print " . " $0 } /^To:/ { print " . " $0 } /^Cc:/ { print " . " $0 } /^Subject:/ { print " . " $0 } ' - tmp="$TMPDIR/msmtp.$host.$datestamp.$RANDOM" - newlock "$tmp" - cat <<EOF > "$tmp" + tsize=`stat -c '%s' "$qbody"` + act "sending `human_size $tsize` over the network ..." + msmtp -C <(cat <<EOF account default from ${email} user ${login} @@ -414,25 +413,21 @@ logfile "${MAILDIRS}/logs/msmtp.log" auth ${auth} password ${password} EOF - tsize=`stat -c '%s' "$qbody"` - act "sending $tsize bytes over the network ..." - msmtp -C "$tmp" -t < "${qbody}" - res=$? - # unlink "$tmp" - unlock "$tmp" - rm -f "$tmp" - fi - - # evaluate results - if [ "$res" != "0" ]; then - error "Error sending mail, skipped" - else - notice "Mail sent succesfully" - # whitelist those to whom we send mails - cat "$qbody" | "$WORKDIR/bin/jaro" -q learn recipient - cat "$qbody" | deliver sent - { test $? = 0 } && { rm "$qbody" } - fi + ) -t < "${qbody}" + res=$? + fi + + # evaluate results + if [[ "$res" != "0" ]]; then + error "Error sending mail, skipped" + else + notice "Mail sent succesfully" + # whitelist those to whom we send mails + cat "$qbody" | \ + "$WORKDIR/bin/jaro" -q learn recipient > /dev/null + cat "$qbody" | deliver sent + [[ $? = 0 ]] && { rm "$qbody" } + fi done diff --git a/src/zlibs/helpers b/src/zlibs/helpers @@ -27,6 +27,11 @@ # which mutt binary to use mutt="mutt" +# remote leading and trailing spaces in a string taken from stdin +trim() { + sed -e 's/^[[:space:]]*//g ; s/[[:space:]]*\$//g' +} + # extract all emails found in a text from stdin # outputs them one per line extract_emails() {