From: Gary V. Vaughan Date: Wed, 11 Feb 2004 12:24:59 +0000 (+0000) Subject: * config/mailnotify: New file for mailing commit notifications, X-Git-Tag: release-1-5-4~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa348cde950afd089e62f31aa8bfca39815f6da1;p=thirdparty%2Flibtool.git * config/mailnotify: New file for mailing commit notifications, imported from cvs-utils. * commit: Updated from cvs-utils and tweaked for libtool. --- diff --git a/ChangeLog b/ChangeLog index 8d39ca842..61ac15e50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-02-11 Gary V. Vaughan + + * config/mailnotify: New file for mailing commit notifications, + imported from cvs-utils. + * commit: Updated from cvs-utils and tweaked for libtool. + 2004-02-09 Albert Chin-A-Young * m4/libtool.m4: Fix typo: testring -> teststring. @@ -9,13 +15,13 @@ distribute these. 2004-02-05 Peter O'Gorman - + * ltmain.in (infer_tag, win32_libid): Style changes. Rename infer_tag to func_infer_tag and win32_libid to func_win32_libid. * libtool.m4 (cygwin): rename win32_libid to func_win32_libid. - + 2004-02-04 Peter O'Gorman - + * ltmain.in (infer_tag): Move tag inferrence to a shell function. Also test $base_compile against $CC with escaped arguments. Bug reported by Geoff Keating . @@ -116,7 +122,7 @@ * ltmain.in: Move eval to after command separation to allow ~ in paths. - * ltmain.in (linkalldeplibs,darwin): Fix a bug reported by Idar + * ltmain.in (linkalldeplibs,darwin): Fix a bug reported by Idar Tollefsen where a dir could be added to the link line with no '-L' on darwin. @@ -148,7 +154,7 @@ for platforms that have been using pass_all for some time now. 2004-01-23 Gary V. Vaughan - + * ltmain.in: Don't suppress output of PIC mode compile if -no-suppress option is given. * doc/libtool.texi (Invoking libtool): Document it. @@ -162,7 +168,7 @@ 2004-01-23 Kevin P. Fleming Charles Wilson - + * ltmain.in: include --tag options, if specified, in the relink_command in uninstalled .la files. Also, preserve --silent, --debug options when libtool re-execs itself. @@ -175,13 +181,13 @@ -export-symbols and -export-symbols-regex options. 2004-01-23 Owen Taylor - + * m4/libtool.m4 (AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE): Recognise the 'R' symbol type so read-only symbols can be exported when combining GCC and Solaris LD. 2004-01-23 Scott James Remnant - + * ltmain.in: When relinking, place the -L parameter containing the installation prefix directory after the intended destination, so we don't accidentally link against an older installed library. diff --git a/commit b/commit index e52b40a9f..f51fde93a 100755 --- a/commit +++ b/commit @@ -1,17 +1,51 @@ #! /bin/sh -# commit version 0.9.2 +# commit (GNU cvs-utils) version 0.10 +# Originally by Gary V. Vaughan +# Pretty much rewritten by Alexandre Oliva -# Copyright (C) 1999, Free Software Foundation +# Copyright (C) 1999, 2000, 2004 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 script is Free Software, and it can be copied, distributed and -# modified as defined in the GNU General Public License. A copy of -# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html +# 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., 59 Temple Place - Suite 330, Boston, +# MA 02111-1307, USA. -# Originally by Gary V. Vaughan -# Heavily modified by Alexandre Oliva +# Usage: commit [-v] [-h] [-f] [-l] [-n] [-q] [-z N] [-C ChangeLog_file] +# [-m msg|-F msg_file|-1] [-s addr [--from addr]] [--] [file|dir ...] -# This scripts eases checking in changes to CVS-maintained projects +# -C file --changelog=file extract commit message from specified ChangeLog +# -zN --compress=N set compression level (0-9, 0=none, 9=max) +# -n --dry-run don't commit anything +# --fast same as --force --first +# -F file --file=file read commit message from file +# -1 --first extract first entry from ChangeLog, no cvs diff +# -f --force don't check (unless *followed* by -n), and just +# display commit message instead of running $PAGER +# --from=addr override default from address in commit email +# -l --local don't descend into subdirectories +# -m msg --message=msg set commit message +# --msg=msg same as -m +# -q --quiet run cvs in quiet mode +# -s addr --sendmail=addr send a commit email of the differences to ADDR +# --signature[=file] add FILE to the end of the email (~/.signature) +# -v --version print version information +# -h,-? --help print short or long help message + +# This script eases checking in changes to CVS-maintained projects # with ChangeLog files. It will check that there have been no # conflicting commits in the CVS repository and print which files it # is going to commit to stderr. A list of files to compare and to @@ -19,32 +53,23 @@ # files in the current directory (and below, unless `-l' is given) are # considered for check in. -# The commit message will be extracted from the differences between -# the local ChangeLog and the one in the repository (unless a message -# was specified with `-m' or `-F'). An empty message is not accepted -# (but a blank line is). If the message is acceptable, it will be -# presented for verification (and possible edition) using the $PAGER -# environment variable (or `more', if it is not set, or `cat', if the -# `-f' switch is given). If $PAGER exits successfully, the modified -# files (at that moment) are checked in, unless `-n' was specified, in -# which case nothing is checked in. - -# usage: commit [-v] [-h] [-f] [-l] [-n] [-q] [-z N] -# [-m msg|-F msg_file] [--] [file|dir ...] - -# -f --fast don't check (unless *followed* by -n), and just -# --force display commit message instead of running $PAGER -# -l --local don't descend into subdirectories -# -m msg --message=msg set commit message -# --msg=msg same as -m -# -F file --file=file read commit message from file -# -n --dry-run don't commit anything -# -q --quiet run cvs in quiet mode -# -zN --compress=N set compression level (0-9, 0=none, 9=max) -# -v --version print version information -# -h,-? --help print short or long help message +# The commit message will be extracted from the differences between a +# file named ChangeLog* in the commit list, or named after -C, and the +# one in the repository (unless a message was specified with `-m' or +# `-F'). An empty message is not accepted (but a blank line is). If +# the message is acceptable, it will be presented for verification +# (and possible edition) using the $PAGER environment variable (or +# `more', if it is not set, or `cat', if the `-f' switch is given). +# If $PAGER exits successfully, the modified files (at that moment) +# are checked in, unless `-n' was specified, in which case nothing is +# checked in. + +# Report bugs to name=commit +: ${CVS=cvs} +: ${SHELL=/bin/sh} +: ${MAILNOTIFY=./mailnotify} cvsopt= updateopt= commitopt= @@ -52,9 +77,26 @@ dry_run=false commit=: update=: log_file="${TMPDIR-/tmp}/commitlog.$$" +signature_file= +first=false +sendmail_to='Libtool Commit ' +sendmail_from= + +my_sed_help='/^# Usage:/,/# Report bugs to/ { + s/^# //; s/^# *$//; + s/\$progname/'$progname'/; + p; + }; d' +my_sed_version='/^# '$name' (GNU /,/# warranty; / { + s/^# //; s/^# *$//; + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/; + p; + }; d' + +rm -f "${log_file}*" +trap 'rm -f "${log_file}*"; exit 1' 1 2 15 -rm -f "$log_file" -trap 'rm -f "$log_file"; exit 1' 1 2 15 +set -e # this just eases exit handling main_repeat=":" @@ -63,11 +105,25 @@ while $main_repeat; do repeat="test $# -gt 0" while $repeat; do case "$1" in - -f|--force|--fast) + --fast) + shift + set fnord --force --first ${1+"$@"} + shift + ;; + -f|--force) update=false PAGER=cat shift ;; + --from) + if test $# = 1; then + echo "$name: missing argument for $1" >&2 + break + fi + shift + sendmail_from="$1" + shift + ;; -l|--local) updateopt="$updateopt -l" commitopt="$commitopt -l" @@ -78,8 +134,8 @@ while $repeat; do echo "$name: missing argument for $1" >&2 break fi - if test -f "$log_file"; then - echo "$name: you can have at most one of -m and -F" >&2 + if $first || test -f "$log_file"; then + echo "$name: you can have at most one of -m, -F and -1" >&2 break fi shift @@ -87,8 +143,8 @@ while $repeat; do shift ;; -F|--file) - if test -f "$log_file"; then - echo "$name: you can have at most one of -m and -F" >&2 + if $first || test -f "$log_file"; then + echo "$name: you can have at most one of -m, -F and -1" >&2 break fi if test $# = 1; then @@ -101,6 +157,27 @@ while $repeat; do fi shift ;; + -1|--first) + if test -f "$log_File"; then + echo "$name: you can have at most one of -m, -F and -1" >&2 + break + fi + first=: + shift + ;; + -C|--[cC]hange[lL]og) + if test $# = 1; then + echo "$name: missing argument for $1" >&2 + break + fi + shift + if test ! -f "$1"; then + echo "$name: ChangeLog file \`$1' does not exist" >&2 + break + fi + ChangeLog="$1" + shift + ;; -n|--dry-run) commit=false update=true @@ -110,6 +187,32 @@ while $repeat; do cvsopt="$cvsopt -q" shift ;; + -s|--sendmail) + if test $# = 1; then + echo "$name: missing argument for $1" >&2 + break + fi + shift + sendmail_to="$1" + shift + ;; + --signature) + if test $# = 1; then + echo "$name: missing argument for $1" >&2 + break + fi + shift + signature_file="$HOME/.signature" + case $1 in + -*) ;; + *) signature_file="$1"; shift ;; + esac + if test -f "$signature_file"; then : + else + echo "$name: \`$signature_file': file not found" + break + fi + ;; -z|--compress) if test $# = 1; then echo "$name: missing argument for $1" >&2 @@ -126,13 +229,13 @@ while $repeat; do shift ;; - -m*|-F*|-z*) + -m*|-F*|-C*|-s*|-z*) opt=`echo "$1" | sed '1s/^\(..\).*$/\1/;q'` arg=`echo "$1" | sed '1s/^-[a-zA-Z0-9]//'` shift set -- "$opt" "$arg" ${1+"$@"} ;; - --message=*|--msg=*|--file=*|--compress=*) + --message=*|--msg=*|--from=*|--file=*|--[Cc]hange[Ll]og=*|--compress=*|--sendmail=*|--signature=*) opt=`echo "$1" | sed '1s/^\(--[^=]*\)=.*/\1/;q'` arg=`echo "$1" | sed '1s/^--[^=]*=//'` shift @@ -140,7 +243,7 @@ while $repeat; do ;; -v|--version) - sed '/^# '$name' version /,/^# Heavily modified by/ { s/^# //; p; }; d' < $0 + sed "$my_sed_version" < $0 exit 0 ;; -\?|-h) @@ -150,7 +253,7 @@ while $repeat; do exit 0 ;; --help) - sed '/^# '$name' version /,/^[^#]/ { /^[^#]/ d; s/^# //; p; }; d' < $0 + sed "$my_sed_help" < $0 exit 0 ;; --) @@ -166,12 +269,22 @@ while $repeat; do ;; esac done + +if test -z "$sendmail_to"; then + # can't have a from address without a destination address + test -n "$sendmail_from" && + echo "$name: can't use --from without --sendmail." >&2 && exit 1 + # can't use a signature file without a destination address + test -n "$signature_file" && + echo "$name: can't use --signature without --sendmail," >&2 && exit 1 +fi + # might have used break 2 within the previous loop, but so what $repeat && break $update && \ if echo "$name: checking for conflicts..." >&2 - (cvs $cvsopt -q -n update $updateopt ${1+"$@"} 2>/dev/null \ + ($CVS $cvsopt -q -n update $updateopt ${1+"$@"} \ | while read line; do echo "$line" echo "$line" >&3 @@ -181,11 +294,41 @@ if echo "$name: checking for conflicts..." >&2 fi if test ! -f "$log_file"; then + if test -z "$ChangeLog"; then + for f in ${1+"$@"}; do + case "$f" in + ChangeLog* | */ChangeLog*) + if test -z "$ChangeLog"; then + ChangeLog="$f" + else + echo "$name: multiple ChangeLog files: $ChangeLog and $f" >&2 + break + fi + ;; + esac + done + fi + echo "$name: checking commit message..." >&2 - cvs $cvsopt diff -u ChangeLog \ - | while read line; do + if $first; then + skipping=: + sed 's,^,+,' < ${ChangeLog-ChangeLog} | + while read line; do case "$line" in - "--- ChangeLog"*) :;; + "+") if $skipping; then skipping=false; else break; fi;; + "+ "*) + echo "$name: *** Warning: lines should start with tabs, not spaces; ignoring line:" >&2 + echo "$line" | sed 's/^.//' >&2;; + "+ "*) + $skipping || echo "$line" ;; + esac + done | + sed 's,^\+ ,,' > "$log_file" || break + else + $CVS $cvsopt diff -u ${ChangeLog-ChangeLog} | + while read line; do + case $line in + "--- "*) :;; "-"*) echo "$name: *** Warning: the following line in ChangeLog diff is suspicious:" >&2 echo "$line" | sed 's/^.//' >&2;; @@ -195,9 +338,10 @@ if test ! -f "$log_file"; then "+") echo;; "+ "*) echo "$line";; esac - done \ - | sed -e 's,\+ ,,' -e '/./p' -e '/./d' -e '1d' -e '$d' > "$log_file" \ - || break + done | + sed -e 's,\+ ,,' -e '/./p' -e '/./d' -e '1d' -e '$d' > "$log_file" \ + || break + fi # The sed script above removes "+TAB" from the beginning of a line, then # deletes the first and/or the last line, when they happen to be empty fi @@ -208,7 +352,7 @@ if grep '[^ ]' < "$log_file" > /dev/null; then :; else fi if grep '^$' < "$log_file" > /dev/null; then - echo "$name: *** Warning: blank lines should not appear within a commit messages." >&2 + echo "$name: *** Warning: blank lines should not appear within commit messages." >&2 echo "$name: *** They should be used to separate distinct commits." >&2 fi @@ -216,17 +360,49 @@ ${PAGER-more} "$log_file" || break sleep 1 # give the user some time for a ^C +filelist=`cvs -nq up 2>/dev/null | grep '^[MAD] ' | sed 's/^. //'` + # Do not check for empty $log_file again, even though the user might have # zeroed it out. If s/he did, it was probably intentional. if $commit; then - cvs $cvsopt commit $commitopt -F $log_file ${1+"$@"} || break + $CVS $cvsopt commit $commitopt -F $log_file ${1+"$@"} || break fi main_repeat=false done -rm -f "$log_file" +# Send a copy of the log_file if sendmail_to was set: +if test -n "$sendmail_to"; then + notify_file="${log_file}.2" + echo "$name: Mailing commit notification to $sendmail_to" >&2 + test $# -gt 0 && filelist="$@" + + { + test -f CVS/Root && + echo "CVSROOT: `sed -e 's,.*:,,g' CVS/Root`" + test -f ./mkstamp && + echo "TIMESTAMP: `$SHELL ./mkstamp < ./ChangeLog`" + test -f CVS/Repository && + echo "Module name: `cat CVS/Repository`" + test -f CVS/Tag && + echo "Branch: `sed -e 's,^T,,;1q' CVS/Tag`" + test -f CVS/Root && + echo "Changes by: `sed -e 's,^.*:\(.*\):.*$,\1,' CVS/Root`" + echo "" + echo "Log Message:" + sed -e 's,^, ,' "$log_file" + test -f "$signature_file" && cat "$signature_file" + } >> "$notify_file" + + if test -n "$sendmail_from"; then + $SHELL $MAILNOTIFY -F "$sendmail_from" -s "`echo $filelist`" -f "$notify_file" -m "text/plain" "$sendmail_to" + else + $SHELL $MAILNOTIFY -s "`echo $filelist`" -f "$notify_file" -m "text/plain" "$sendmail_to" + fi +fi + +rm -f "${log_file}*" # if main_repeat was not set to `false', we failed $main_repeat && exit 1 diff --git a/mailnotify b/mailnotify new file mode 100755 index 000000000..b071860bb --- /dev/null +++ b/mailnotify @@ -0,0 +1,389 @@ +#!/bin/sh +# +# mailnotify (GNU cvs-utils) version 0.1 +# Written by Gary V. Vaughan + +# Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, +# MA 02111-1307, USA. + +# Usage: $progname [OPTION]... [--] to-address... +# +# -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' patch-list@foo.org + +# You will probably find using this script in conjunction with clcommit +# or cvsapply will save you an awful lot of typing. + +# Report bugs to + +: ${TMPDIR=/tmp} +: ${HOST=`hostname`} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="sed"} + +# The name of this program: +progname=`echo "$0" | $SED 's%^.*/%%'` +PROGRAM=mailnotify + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +multipart=1 +outputfile="" + +exit_cmd=: + +sed_dirname='s,/[^/]*$,,' +sed_basename='s,^.*/,,' +sed_mail_address='s,^.*<\(.*\)>.*$,\1,' + +# func_echo arg... +# Echo program name prefixed message. +func_echo () +{ + echo $progname: ${1+"$@"} +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + echo $progname: ${1+"$@"} 1>&2 +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_error ${1+"$@"} +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "Try \`$progname --help' for more information." +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1" + exit_cmd=exit +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `mailnotify --version' happen quickly. +{ + # sed scripts: + my_sed_single_opt='1s/^\(..\).*$/\1/;q' + my_sed_single_rest='1s/^..\(.*\)$/\1/;q' + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + my_sed_help='/^# Usage:/,/# Report bugs to/ { + s/^# //; s/^# *$//; + s/\$progname/'$progname'/; + p; + }; d' + my_sed_version='/^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# //; s/^# *$//; + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/; + p; + }; d' + + while test $# -gt 0; do + opt="$1" + shift + case $opt in + -C|--carbon-copy) test $# -eq 0 && func_missing_arg "$opt" && break + cc="$1" + shift + ;; + + -F|--from) test $# -eq 0 && func_missing_arg "$opt" && break + from="$1" + shift + ;; + + -f|--filename) test $# -eq 0 && func_missing_arg "$opt" && break + 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) test $# -eq 0 && func_missing_arg "$opt" && break + 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) test $# -eq 0 && func_missing_arg "$opt" && break + outputfile="$1" + shift + ;; + + -s|--subject) test $# -eq 0 && func_missing_arg "$opt" && break + subject="$1" + shift + ;; + + -v|--verbose) opt_verbose=: ;; + + --carbon-copy=*|--from=*|--filename=*|--mime-type=*|--output-file=*|--subject=*) + arg=`echo "$opt" | $SED "$my_sed_long_arg"` + opt=`echo "$opt" | $SED "$my_sed_long_opt"` + set -- "$opt" "$arg" ${1+"$@"} + ;; + + -C*|-F*|-f*|-m*|-o*|-s*) + arg=`echo "$opt" |$SED "$my_sed_single_rest"` + opt=`echo "$opt" |$SED "$my_sed_single_opt"` + set -- "$opt" "$arg" ${1+"$@"} + ;; + + -n*|-v*) + rest=`echo "$opt" |$SED "$my_sed_single_rest"` + opt=`echo "$opt" |$SED "$my_sed_single_opt"` + set -- "$opt" "-$rest" ${1+"$@"} + ;; + + --version) $SED "$my_sed_version" < $0; exit $EXIT_SUCCESS ;; + --help) $SED "$my_sed_help" < $0; exit $EXIT_SUCCESS ;; + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set -- "$opt" ${1+"$@"}; 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\" +} + + +# 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\" < $0`" + echo "MIME-Version: 1.0" + test -n "$from" && echo "From: $from" + echo "To: $my_destination" + test -n "$cc" && echo "CC: $cc" + test -n "$subject" && 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" <> "$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` + { + echo "" + echo "--$boundary" + eval echo \"Content-Type: \$ctype$i\" + echo "Content-Transfer-Encoding: 7bit" + echo "" + eval cat \"\$datafile$i\" + } >> "$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=`echo "$my_from" | sed 's, *<.*> *$,,;s,",,g'` + from_addr=`echo "$my_from" | sed "$sed_mail_address"` + + 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. ## +## ----- ## + +{ + fname="${TMPDIR}/$PROGRAM$RANDOM-$RANDOM.$$" + trap 'rm -f "$fname"; exit 1' 1 2 15 + + destination="" + for to; + do + case $destination in + "") destination="$to" ;; + *) destination="$destination, $to" ;; + esac + done + + func_headers "$fname" "$destination" + if test $multipart -gt 1; then + func_multipart_content "$fname" + else + func_single_content "$fname" + fi + + if test -z "$outputfile"; then + destination="" + for to; do + to_addr=`echo "$to" | sed "$sed_mail_address"` + test -n "$to_addr" || to_addr="$to" + destination="$destination $to_addr" + done + func_sendmail "$fname" "$destination" "$from" + else + mv $fname $outputfile || exit $EXIT_FAILURE + fi +} + +exit $EXIT_SUCCESS