quilt-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Quilt-dev] quilt mail bugs (was [patch 1/8])


From: Gary V. Vaughan
Subject: Re: [Quilt-dev] quilt mail bugs (was [patch 1/8])
Date: Wed, 14 Sep 2005 13:15:53 +0100
User-agent: Mozilla Thunderbird 1.0 (X11/20050305)

Hallo Andreas,

Andreas Gruenbacher wrote:
On Wednesday 14 September 2005 13:31, Gary V. Vaughan wrote:

I was being paranoid about whether quilt mail would be able to pass
'"Gary V. Vaughan" <address@hidden>' through to sendmail
without molesting the quotes.

It really should.

Okay, thanks.

(Incidentally, there are several bugs in mail.in... I might post patches if I try to use it again)


I'd appreciate that. Otherwise, pointing out what broke would be a start...

I haven't really looked at the code too much (walking the path of least
resistance, sorry) but so far:

- 'quilt mail --mbox file' ignores FILE and outputs on stdout.
- `quilt mail --subject ...' is not copied into the template Subject:
   header and is lost (note the missing subject in my series posts --
   I thought --subject would override Subject: so didn't fill it in
   again after specifying it already)
-  `hostname -f' doesn't work except on Linux  (see my patch 6/8)
-  no way to send from a NAT smarthost (see my patch 6/8)

Actually, I'm not sure that the ENVELOPE_SENDER is a good thing to
have.  Much nicer for quilt mail to extract it from my --from argument
to avoid spoofing.

Additionally, it would be nice if there was of not posting the entire
series... say I update one of my patches based on feedback and want to repost it without all the others using:

  $ quilt mail --send --from '"Gary V. Vaughan <address@hidden>"' \
       -p patches/fix-foo.diff

Maybe even to default the subject line to `fix-foo.diff' if --subject
is omitted.

There are a couple of other features I'd like to have from my mailnotify
script (used in libtool, m4, tla-utils and others, attached): gpg
signing and mime attached patches as an alternative to verbatim mail
body inserted patches.

Cheers,
        Gary.
--
Gary V. Vaughan      ())_.  address@hidden,gnu.org}
Research Scientist   ( '/   http://tkd.kicks-ass.net
GNU Hacker           / )=   http://www.gnu.org/software/libtool
Technical Author   `(_~)_   http://sources.redhat.com/autobook
m4_define([_m4_divert(SCRIPT)], 100)
m4_divert_push([SCRIPT])#!/bin/sh
# @configure_input@

# mailnotify (GNU @PACKAGE@) version 0.7
# Written by Gary V. Vaughan <address@hidden>

# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.  There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, a copy can be downloaded from
# http://www.gnu.org/copyleft/gpl.html, or by writing to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.

# Usage: $progname [OPTION]... [--] to-address...
#
#           --debug             enable verbose shell tracing
# -C ADDR   --carbon-copy=ADDR  send a carbon-copy to ADDR
# -F ADDR   --from=ADDR         override default from address with ADDR
# -f FILE   --filename=FILE     content of this part
# -m TYPE   --mime-type=TYPE    mime-type of this part
# -n                            another mime part (-f, -m) to follow
# -o FILE   --output-file=FILE  output to FILE instead of sending
# -s TEXT   --subject=TEXT      set subject header
# -v        --verbose           run in verbose mode
#           --version           print version information
# -h,-?     --help              print short or long help message

# Assemble a (possibly multi-part) mime message and hand it to the local
# sendmail for onward delivery.  MUAs tend to mangle patch attachments in
# various ways: not setting the mime-type correctly, line wrapping the
# patch itself, escaping certain values, etc.  This script is designed to
# make it easier to send a patch as a MIME attachment, though it is general
# enough that it might be useful otherwise.

# For example to send a patch as an attachment, assuming the patch itself
# is in PATCHFILE:
#
#    echo 'Applied to HEAD' > body
#    $progname -f body -m text/plain -n -f PATCHFILE -m text/x-patch \
#        -s 'FYI: PATCHFILE' address@hidden

# You will probably find using this script in conjunction with clcommit
# or cvsapply will save you an awful lot of typing.

# Report bugs to <address@hidden>

: ${HOST=`hostname`}
: ${SENDMAIL=sendmail}

PROGRAM=mailnotify

AS_SHELL_SANITIZE
$as_unset CDPATH

m4_include([getopt.m4sh])

# Global variables:
multipart=1
outputfile=""

sed_mail_address='s,^.*<\(.*\)>.*$,\1,'

# Parse options once, thoroughly.  This comes as soon as possible in
# the script to make things like `mailnotify --version' happen quickly.
{
  options=`func_fastopt -o '?C:F:f:hm:no:qs:v' \
        --long=debug,carbon-copy:,from:,filename:,help,mime-type: \
        --long=output-file:,subject:,verbose,version \
    -- ${1+"$@"}`
  test $? -eq 0 || exit_cmd=exit

  eval set dummy "$options"; shift

  while test $# -gt 0; do
    opt=$1
    shift
    test $# -gt 0 && func_quote_arg "$1"

    case $opt in
      --debug)          func_echo "enabling shell trace mode"
                        set -x
                        ;;

      -C|--carbon-copy) cc=$func_quote_arg_result;   shift              ;;
      -F|--from)        from=$func_quote_arg_result; shift              ;;

      -f|--filename)    if test -f "$1"; then :; else
                          func_error "\`$1' does not exist"
                          exit_cmd=exit
                          break
                        fi
                        eval datafile$multipart=\"$1\"
                        shift
                        ;;

      -m|--mime-type)   case $1 in
                          text/*) ;;
                          */*) func_error "only text/* mime-types supported"
                               ;;
                          *)   func_error "invalid mime-type, \`$1'"
                               exit_cmd=exit
                               ;;
                        esac
                        eval ctype$multipart=\"$1\"
                        shift
                        ;;

      -n)               if eval test -z \"\$ctype$multipart\" ||
                           eval test -z \"\$datafile$multipart\"; then
                          func_fatal_error "One part is incomplete -- each part 
needs a filename and a mime-type"
                        fi
                        multipart=`expr 1 + $multipart`
                        ;;

      -o|--output-file) outputfile=$1; shift                            ;;
      -s|--subject)     subject=$func_quote_arg_result; shift           ;;
      -v|--verbose)     opt_verbose=:                                   ;;
      -\?|-h)           func_usage                                      ;;
      --help)           func_help                                       ;;
      --version)        func_version                                    ;;
      --)               break                                           ;;
    esac
  done

  test $# -gt 0 ||
    func_fatal_help "no destination address"

  if test -z "$outputfile"; then
    if test -z "$subject" ||
       eval test -z \"\$ctype$multipart\" ||
       eval test -z \"\$datafile$multipart\"; then
      func_fatal_error "if output is not directed to a file -s, -f, and -m are 
all required"
    fi
  else
    eval test -n \"\$datafile$multipart\" ||
        func_fatal_error "-f is required."
    eval test -n \"\$ctype$multipart\" ||
        func_fatal_error "with output directed to a file, -m is required"
  fi
  eval test -f \"\$datafile$multipart\" ||
    eval func_fatal_error \"\$datafile$multipart: file not found\"

  $exit_cmd $EXIT_FAILURE
}


# func_headers outfile destination
# Generate common headers to OUTFILE, where DESTINATION is a comma
# separated list of fully qualified destination addresses.
func_headers ()
{
    my_outfile="$1"
    my_destination="$2"
    my_sed_version_no='/^# '$PROGRAM' (GNU / { s/^# .*version //; p; }; d'

    {
        echo "User-Agent: $PROGRAM/`$SED \"$my_sed_version_no\" < $progpath`"
        echo "MIME-Version: 1.0"
        test -n "$from" && eval echo From: $from
        eval echo To: $my_destination
        test -n "$cc" && eval echo CC: $cc
        test -n "$subject" && eval echo Subject: $subject
    } > "$my_outfile"
}


# func_single_content outfile
# Send the only message part as a single mime mail part.
func_single_content ()
{
    my_outfile="$1"

    cat >> "$my_outfile" <<EOF
Content-Type: $ctype1;
Content-Transfer-Encoding: 7bit

`cat $datafile1`
EOF
}


# func_multipart_content outfile
# Send the various message parts to OUTFILE as a multipart mime mail.
func_multipart_content ()
{
    my_outfile="$1"
    boundary="boundary-${HOST}-$$-`date | tr ' :' -`"
    cat <<EOF >> "$my_outfile"
Content-Type: multipart/mixed;
        boundary="$boundary"

This is a multimedia message in MIME format.  If you are reading
this prefix, your mail reader does not understand MIME.  You may
wish to look into upgrading to a mime-aware mail reader.
EOF
    i=0
    while test $i -lt $multipart
    do
      i=`expr 1 + $i`
      eval file=\"\$datafile$i\"
      name=`echo "$file" | $SED $basename`
      {
        echo ""
        echo "--$boundary"
        if test $i -gt 1; then
            eval echo \"Content-Type: \$ctype$i\;\"
            echo "        name=\"$name\""
        else
            eval echo \"Content-Type: \$ctype$i\"
        fi
        echo "Content-Transfer-Encoding: 7bit"
        echo ""
        cat "$file"
      } >> "$my_outfile"
    done
    {
      echo ""
      echo "--${boundary}--"
      echo ""
    } >> "$my_outfile"
}


# func_sendmail infile destination [from]
# Send the message in INFILE to the space delimited list of destination
# addresses in DESTINATION.  If FROM is given, it is the address the
# mail purports to be from.
# BEWARE: Many MTAs will refuse mail where FROM does not match the actual
#         sending domain.
func_sendmail ()
{
    my_infile="$1"
    my_destination="$2"
    my_from="$3"

    from_name=`eval echo "X$my_from" | $Xsed -e 's, *<.*> *$,,'`
    from_addr=`eval echo "X$my_from" | $Xsed -e "$sed_mail_address"`

    save_PATH="$PATH"
    PATH="/usr/lib:/usr/sbin:$PATH"

    save_IFS="$IFS"
    IFS=':'
    for try_sendmail_dir in $PATH; do
        IFS="$save_IFS"
        PATH="$save_PATH"
        if test -x "$try_sendmail_dir/$SENDMAIL"; then
            SENDMAIL="$try_sendmail_dir/$SENDMAIL"
            break
        fi
    done
    IFS="$save_IFS"
    PATH="$save_PATH"
    test -x "$SENDMAIL" || func_fatal_error "sendmail executable not found"

    func_verbose "Delivering mail, please wait..."
    if test -n "$from_name"; then
        $SENDMAIL -F "$from_name" -f "$from_addr" $my_destination < "$my_infile"
    elif test -n "$from_addr"; then
        $SENDMAIL -f "$from_addr" $my_destination < "$my_infile"
    else
        $SENDMAIL $my_destination < "$my_infile"
    fi
    if test $? -eq 0; then
        func_verbose "...succeeded."
        $RM $my_infile
    else
        func_fatal_error "Mail delivery failed, draft mail is in $my_infile"
    fi
}



## ----------- ##
##    Main.    ##
## ----------- ##

set -e

{
  tmp_dir="`func_mktempdir`"
  fname="$tmp_dir/mail"
  trap '$RM -r "$tmp_dir"; exit $EXIT_FAILURE' 1 2 15

  # Generate a comma separated list of destination addresses for the
  # mail headers:
  destination=""
  for to in : ${1+"$@"}
  do
      test "X$to" = X: && continue

      func_quote_for_eval "$to"

      case $destination in
          "") destination="$func_quote_for_eval_result" ;;
          *)  destination="$destination, $func_quote_for_eval_result" ;;
      esac
  done

  func_headers "$fname" "$destination"
  if test $multipart -gt 1; then
      func_multipart_content "$fname"
  else
      func_single_content "$fname"
  fi

  # Generate a space delimited list of destination addresses for sendmail:
  if test -z "$outputfile"; then
      destination=""
      for to in : ${1+"$@"}
      do
          test "X$to" = X: && continue

          func_quote_for_eval "$to"

          to_addr=`echo "$func_quote_for_eval_result" | sed "$sed_mail_address"`
          test -n "$to_addr" || to_addr="$func_quote_for_eval_result"
          destination="$destination $to_addr"
      done
      func_sendmail "$fname" "$destination" "$from"
  else
      mv $fname $outputfile || exit $EXIT_FAILURE
  fi

  $RM -r "$tmp_dir"
}

exit $EXIT_SUCCESS

# Local Variables:
# mode:shell-script
# sh-indentation:2
# End:

reply via email to

[Prev in Thread] Current Thread [Next in Thread]