diff --git a/ChangeLog b/ChangeLog index 61da299e..9d4bca42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2010-09-01 Gary V. Vaughan + Remove announce-gen.m4sh and mailnotify.m4sh. + * libltdl/config/announce-gen.m4sh: Removed. This script has + no apparent connection to libtool functionality, and mostly + duplicates the better maintained gnulib announce-gen script. + * libltdl/config/mailnotify.sh: Removed. This script was used + by only clcommit.m4sh and announce-gen.m4sh, both of which are + now removed too. + * Makefile.maint (announce-gen, libltdl/config/mailnotify): + Targets removed. + * bootstrap: Remove the mailnotify regeneration warning. + * HACKING (Release Procedure): Remove references to + announce-gen. + (Alpha release note template, Full release note template): + Reinstated from before announce-gen was introduced. + Remove clcommit.m4sh. * clcommit.m4sh: Removed. This script was written to help keep ChangeLog and commit messages in sync when committing to CVS, diff --git a/HACKING b/HACKING index e079e4b6..b462c985 100644 --- a/HACKING +++ b/HACKING @@ -687,39 +687,172 @@ or obtained by writing to the Free Software Foundation, Inc., doc/manual using cvs to here: @cvs.savannah.gnu.org:/webcvs/libtool -* In the build directory, run `Make -f[../]Makefile.maint announce-gen'. +* Write a release announcement, and post it to `libtool@gnu.org' and + `autotools-announce@gnu.org' with the Reply-To header set to + `bug-libtool@gnu.org'. Stable releases should also be announced + on `info-gnu@gnu.org'. -* Make sure the source directory has an appropriate .announcerc, along - the lines of: - - --bootstrap-tools='autoconf,automake' - --gpg-key-id={the id of the key you signed the tarballs with} - --header 'From: {your name} <{your email address}> - --header 'To: Libtool List ' - --header 'Cc: Autotools Announce List ' - --header 'Reply-To: Libtool Bugs ' - --message 'GNU Libtool hides the complexity of using shared' - --message 'libraries behind a consistent, portable interface.' - --message 'GNU Libtool ships with GNU libltdl, which hides the' - --message 'complexity of loading dynamic runtime libraries' - --message '(modules) behind a consistent, portable interface.' - --signature - -* Check the release announcement with: - - ./announce-gen -r -o --prev=LASTRELEASE alpha - - or for a stable release: - - ./announce-gen -r -o -h 'Cc: info-gnu@gnu.org' --prev=LASTRELEASE stable - - When you're happy with the announcement text, post it by rerunning the - command with `-p' instead of `-o'. - -* Post a copy of the release announcement to savannah news: +* Post a copy of your release announcement to savannah news: https://savannah.gnu.org/news/submit.php?group=libtool which will automatically propogate to http://planet.gnu.org. + +13. Alpha release note template +=============================== + +To: libtool@gnu.org, autotools-announce@gnu.org +Reply-To: bug-libtool@gnu.org +Subject: GNU Libtool @VERSION@ released (alpha release). + +The Libtool Team is pleased to announce alpha release @VERSION@ of GNU +Libtool. + +GNU Libtool hides the complexity of using shared libraries behind a +consistent, portable interface. GNU Libtool ships with GNU libltdl, +which hides the complexity of loading dynamic runtime libraries +(modules) behind a consistent, portable interface. + +Here are the compressed sources: + + ftp://alpha.gnu.org/gnu/libtool/libtool-@VERSION@.tar.gz + ftp://alpha.gnu.org/gnu/libtool/libtool-@VERSION@.tar.bz2 + +Here are the xdeltas and diffs against libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@: + + ftp://alpha.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz + ftp://alpha.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta + +Here are the gpg detached signatures: + + ftp://alpha.gnu.org/gnu/libtool/libtool-@VERSION@.tar.gz.sig + ftp://alpha.gnu.org/gnu/libtool/libtool-@VERSION@.tar.bz2.sig + ftp://alpha.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz.sig + ftp://alpha.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta.sig + +You should download the signature named after any tarball you download, +and then verify its integrity with, for example: + + gpg --verify libtool-@VERSION@.tar.gz.sig + +Here are the MD5 and SHA1 checksums: + + @MD5SUM@ libtool-@VERSION@.tar.gz + @MD5SUM@ libtool-@VERSION@.tar.bz2 + @MD5SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz + @MD5SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta + @SHA1SUM@ libtool-@VERSION@.tar.gz + @SHA1SUM@ libtool-@VERSION@.tar.bz2 + @SHA1SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz + @SHA1SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta + +This release has @SUMMARY_OF_IMPROVEMENTS_SINCE_LAST_RELEASE_ON_THIS_BRANCH@. + +This release was bootstrapped with @BOOTSTRAP_TOOLS_WITH_VERSIONS@, +but is useable with @COMPATIBLE_AUTOTOOL_VERSIONS@ in your own +projects. + +Alternatively, you can fetch the unbootstrapped source code with +git by using the following command: + + $ git clone git://git.savannah.gnu.org/libtool.git + $ cd libtool + $ git checkout @GIT_RELEASE_TAG@ + +You will then need to have recent (possibly as yet unreleased) versions +of Automake and Autoconf installed to bootstrap the checked out +sources yourself. + +New in @VERSION@: @RELEASE_DATE@ + + @EXCERPT_FROM_NEWS_FILE@ + +Please report bugs to , along with the verbose +output of any failed test groups, and the output from `./libtool --config.' +The README file explains how to capture the verbose test output. + + + +14. Full release note template +============================== + +To: info-gnu@gnu.org +Cc: libtool@gnu.org, autotools-announce@gnu.org +Reply-To: bug-libtool@gnu.org +Subject: GNU Libtool @VERSION@ released. + +The Libtool Team is pleased to announce the release of GNU Libtool +@VERSION@. + +GNU Libtool hides the complexity of using shared libraries behind a +consistent, portable interface. GNU Libtool ships with GNU libltdl, +which hides the complexity of loading dynamic runtime libraries +(modules) behind a consistent, portable interface. + +This release has @SUMMARY_OF_IMPROVEMENTS_SINCE_LAST_RELEASE_ON_THIS_BRANCH@. + +New in @VERSION@: @RELEASE_DATE@ + + @EXCERPT_FROM_NEWS_FILE@ + +libtool-@VERSION@ is available now from ftp.gnu.org, along with +diffs and xdeltas against libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@ +that are also available from ftp.gnu.org. Please +use a mirror to reduce stress on the main gnu machine: + + http://www.gnu.org/order/ftp.html + +Here are the compressed sources: + + ftp://ftp.gnu.org/gnu/libtool/libtool-@VERSION@.tar.gz + ftp://ftp.gnu.org/gnu/libtool/libtool-@VERSION@.tar.bz2 + +Here are the xdeltas and diffs against libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@: + + ftp://ftp.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz + ftp://ftp.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta + +Here are the gpg detached signatures: + + ftp://ftp.gnu.org/gnu/libtool/libtool-@VERSION@.tar.gz.sig + ftp://ftp.gnu.org/gnu/libtool/libtool-@VERSION@.tar.bz2.sig + ftp://ftp.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz.sig + ftp://ftp.gnu.org/gnu/libtool/libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta.sig + +You should download the signature named after any tarball you download, +and then verify its integrity with, for example: + + gpg --verify libtool-@VERSION@.tar.gz.sig + +Here are the MD5 and SHA1 checksums: + + @MD5SUM@ libtool-@VERSION@.tar.gz + @MD5SUM@ libtool-@VERSION@.tar.bz2 + @MD5SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz + @MD5SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta + @SHA1SUM@ libtool-@VERSION@.tar.gz + @SHA1SUM@ libtool-@VERSION@.tar.bz2 + @SHA1SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.diff.gz + @SHA1SUM@ libtool-@PREV_RELEASE_VERSION_ON_THIS_BRANCH@-@VERSION@.xdelta + +This release was bootstrapped with @BOOTSTRAP_TOOLS_WITH_VERSIONS@, +but is useable with @COMPATIBLE_AUTOTOOL_VERSIONS@ in your own +projects. + +Alternatively, you can fetch the unbootstrapped source code with +git by using the following command: + + $ git clone git://git.savannah.gnu.org/libtool.git + $ cd libtool + $ git checkout @GIT_RELEASE_TAG@ + +You will then need to have the latest release versions of Automake +(@AUTOMAKE_VERSION@) and Autoconf (@AUTOCONF_VERSION@) installed to +bootstrap the checked out sources yourself. + +Please report bugs to , along with the verbose +output of any failed test groups, and the output from `./libtool --config.' +The README file explains how to capture the verbose test output. + -- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Free Software Foundation, Inc. diff --git a/Makefile.maint b/Makefile.maint index 15d5a149..64abde69 100644 --- a/Makefile.maint +++ b/Makefile.maint @@ -36,31 +36,6 @@ Makefile: TEXI2HTML = texi2html -announce-gen: $(auxdir)/announce-gen.m4sh $(auxdir)/getopt.m4sh - $(timestamp); \ - rm -f announce-gen announce-gen.in announce-gen.tmp; \ - $(M4SH) -B $(top_srcdir)/$(auxdir) $(top_srcdir)/$(auxdir)/announce-gen.m4sh > announce-gen.in; \ - $(edit) -e "s,@TIMESTAMP\@,$$TIMESTAMP,g" \ - -e "s,@LASTRELEASE\@,$(LASTRELEASE),g" \ - -e "s,@top_srcdir\@,$(top_srcdir),g" \ - announce-gen.in > announce-gen.tmp; \ - chmod a+x announce-gen.tmp; \ - chmod a-w announce-gen.tmp; \ - mv -f announce-gen.tmp announce-gen; \ - rm -f announce-gen.in - -$(srcdir)/$(auxdir)/mailnotify: $(auxdir)/mailnotify.m4sh - $(timestamp); \ - cd $(srcdir)/$(auxdir); \ - rm -f mailnotify mailnotify.in mailnotify.tmp; \ - $(M4SH) -B . mailnotify.m4sh > mailnotify.in; \ - $(edit) -e "s,@TIMESTAMP\@,$$TIMESTAMP,g" \ - mailnotify.in > mailnotify.tmp; \ - chmod a+x mailnotify.tmp; \ - chmod a-w mailnotify.tmp; \ - mv -f mailnotify.tmp mailnotify; \ - rm -f mailnotify.in - .PHONY: git-release git-release: version-check prev-tarball check-news fetch git-dist diffs web-manual @tarname="$(PACKAGE)-$(VERSION).tar.gz"; \ diff --git a/bootstrap b/bootstrap index 82828dbb..78b4d304 100755 --- a/bootstrap +++ b/bootstrap @@ -186,14 +186,4 @@ for macro in LT_INIT AC_PROG_LIBTOOL AM_PROG_LIBTOOL; do else :; fi done -# Commit script caveat: -cat <] -# -v --verbose run in verbose mode -# --version print version information -# -? --help print short or long help message - -# In output mode, selected by `-o', a release note is printed on stdout. - -# In post mode, the release note is displayed in $PAGER, (giving you the -# chance to make changes, and add headers) before posting to any every -# TO-ADDRESS given on the command line, as well as any addresses added -# to `To:', `Cc:' and `Bcc:' headers during editing. - -# The `--rcfile' option points to a file with other option settings, one -# on each line. For example: -# -# --bootstrap-tools='autoconf, automake' -# --gpg-key-id=2983D606 -# --header 'From: "Gary V. Vaughan" ' -# --header 'To: Libtool List ' -# --header 'Cc: Autotools Announce List ' -# --header 'Reply-To: Libtool Bugs ' -# --message 'GNU Libtool hides the complexity of using shared' -# --message 'libraries behind a consistent, portable interface.' -# --message 'GNU Libtool ships with GNU libltdl, which hides the' -# --message 'complexity of loading dynamic runtime libraries' -# --message '(modules) behind a consistent, portable interface.' -# --signature -# -# This is the .announcerc for GNU Libtool. Announce-gen is pretty -# smart about picking defaults for package-name and current-version -# and often guesses previous-version correctly too. So, typically a -# release note can be posted with: -# -# ./$progname -r -p -h 'Cc: info-gnu@gnu.org' --prev= stable -# -# When that's producing a good announcement, it can be posted by using -# the same arguments again, but for `-p' instead of `-o' - -# Report bugs to - -: ${DU="du"} -: ${MAILNOTIFY="mailnotify"} -: ${MD5SUM="md5"} -: ${SHA1SUM="shasum"} - -PROGRAM=announce-gen - -m4_divert_pop -m4_include([getopt.m4sh]) - -M4SH_VERBATIM([[ -top_srcdir=`cd "@top_srcdir@" && pwd` -test -d "$top_srcdir" || top_srcdir='@top_srcdir@' - -# Initialisation: -mailnotify_flags= -package_name="@PACKAGE@" -sendmail_to= -valid_release_types='alpha,beta,release-candidate,stable' - -# try to find out whether read supports -r -if echo bt | tr b '\\' | { read -r line; test "X$line" = 'X\t'; } 2>/dev/null -then - read_r='read -r' -else - read_r=read -fi -]]) - -dnl SHORT LONG DEFAULT INIT -dnl ---------------------------------------------------------------------- -M4SH_GETOPTS( - [b@], [--blurb], [], [], - [h;], [--header], [], [], - [m;], [--message|--msg], [], [], - [o], [--output], [], [], - [p], [--post], [], [], - [r@?],[--rcfile], [$top_srcdir/.announcerc], [ - # The funny quoting allows keeping one option per line in $opt_rcfile: - eval set dummy `echo \`cat $opt_rcfile\` '${1+"[$]@"}'` - shift], - [v], [--verbose], [], [ - mailnotify_flags="${mailnotify_flags+$mailnotify_flags }$opt"], - [!], [--bootstrap-tools|--bootstrap|--boots], [], [ - for tool in `echo "$optarg"|$SED 's|,| |g'`; do - ($tool --version) >/dev/null 2>&1 || { - func_error "$opt \`$optarg' does not respond to --version option." - cmd_exit=exit - } - done], - [!], [--current-version|--current|--curr], [@VERSION@], [], - [!], [--gpg-key-id|--gpg], [], [], - [], [--no-print-checksums], [], [], - [!], [--previous-version|--previous|--prev], [@LASTRELEASE@], [], - [!], [--release-type], [], [], - [@?], [--signature], [$HOME/.signature], [], - [!], [--url-directory], [], [], - [ - # validate $opt_gpg_key_id - test -n "$opt_gpg_key_id" || { - func_error "you must specify a key with --gpg-key-id." - exit_cmd=exit - } - - # validate $opt_bootstrap_tools - test -n "$opt_bootstrap_tools" || { - func_error "you must specify some tools with --bootstrap-tools." - exit_cmd=exit - } - - # validate $opt_blurb and $opt_message - test -n "$opt_blurb" && test -n "$opt_message" && { - func_error "you can specify only one of --blurb and --message." - exit_cmd=exit - } - - # validate $opt_output and $opt_post - $opt_output && $opt_post && { - func_error "you can specify only one of --output and --post." - exit_cmd=exit - } - $opt_output || $opt_post || { - func_error "you must specify either --output or --post." - exit_cmd=exit - } - - # validate $opt_release_type - test -n "$opt_release_type" || { - test [$]# -gt 0 || { func_error "no release type specified."; exit_cmd=exit; } - opt_release_type="[$]1"; shift - } - case ,$valid_release_types, in *,$opt_release_type,*) ;; - *) func_error "\`$opt_release_type': invalid release type."; exit_cmd=exit ;; - esac - - # validate $url_directory - test -n "$url_directory" || { - case $opt_release_type in - stable) url_directory="ftp://ftp.gnu.org/gnu/$package_name" ;; - *) url_directory="ftp://alpha.gnu.org/gnu/$package_name" ;; - esac - } - - # pass trace argument along to mailnotify too - test "$opt_debug" != ":" && - mailnotify_flags="${mailnotify_flags+$mailnotify_flags }--debug" - - # validate remaining command line args as destination addresses - for address - do - func_quote_for_eval "$address" - sendmail_to="${sendmail_to+$sendmail_to }$func_quote_for_eval_result" - done -]) - -M4SH_VERBATIM([[ -# Bail out on command errors! -set -e - -# func_print_changelog_deltas -func_print_changelog_deltas () -{ - $opt_debug - - # FIXME: Jim's announce-gen does something with ChangeLogs - # and cvs diff. We don't use CVS, and perl makes - # my eyes bleed... maybe I'll write this function - # one day. - : -} - - -# func_print_checksums title filename... -func_print_checksums () -{ - $opt_debug - - my_title="$1"; shift - - test -n "$1" && { - echo - echo "Here are the $my_title:" - echo - for my_sum in $MD5SUM $SHA1SUM; do - for my_filename in ${1+"$@"}; do - my_line=`$my_sum $my_filename` - my_hash=`expr "$my_line" : '.*\([0-9a-f]\{40\}\)' || :` - test -n "$my_hash" || my_hash=`expr "$my_line" : '.*\([0-9a-f]\{32\}\)'`" " - echo " $my_hash $my_filename" - done - done - } - - # To stop bash exiting if test fails - : -} - - -# func_print_locations title url files -func_print_locations () -{ - $opt_debug - - test -n "$3" && { - echo - echo "Here are the $1:" - echo - for my_file in $3; do - my_size=`$DU -h $my_file|sed 's,[bB]*[ ].*$,,'` - echo " $2/$my_file (${my_size}B)" - done - } - - # To stop bash exiting if test fails - : -} - - -# func_print_news_deltas -func_print_news_deltas () -{ - $opt_debug - - my_news_file="$top_srcdir/NEWS" - my_skipping=: - - # reset the field separator to prevent whitespace removal by 'read' - save_IFS="$IFS" - IFS= - - echo - cat $my_news_file | - while read line; do - case $line in - "New in $opt_current_version "*:) - my_skipping=false - echo "$line" - ;; - "New in "*:) - my_skipping=: - ;; - *) - $my_skipping || echo "$line" - ;; - esac - done - - IFS="$save_IFS" -} - - -# func_tool_versions toolname... -func_print_tool_versions () -{ - $opt_debug - - test -n "$1" && { - echo - echo "This release was bootstrapped with the following tools:" - echo - for my_tool in ${1+"$@"}; do - my_tool_version=`$my_tool --version|sed 's,^.* ,,g;1q'` - echo " $my_tool-$my_tool_version" - done - } - - # To stop bash exiting if test fails - : -} - - - -## ----- ## -## main. ## -## ----- ## - -{ - # Neutralize the locale, so that, for instance, "du" does not - # issue "1,2" instead of "1.2", which confuses our regexps. - LC_ALL=C - export LC_ALL - - # Secure directory for temporary files - tmp_dir="`func_mktempdir`" - trap '$RM -r "$tmp_dir"; exit $EXIT_FAILURE' 1 2 15 - - # Save any header or post blurb for mailnotify - header_file="$tmp_dir/headers" - blurb_file="$tmp_dir/blurb" - - test -n "$opt_header" && echo "$opt_header" > "$header_file" - test -n "$opt_message" && echo "$opt_message" > "$blurb_file" - test -n "$opt_blurb" && cat "$opt_blurb" > "$blurb_file" - - archive_suffixes='tar.gz tar.bz2 tar.lzma tar.xz' - diff_suffixes='diff.gz diff.bz2 diff.lzma diff.xz xdelta' - - # Ensure there is something to announce! - for suffix in $archive_suffixes; do - candidate="$package_name-$opt_current_version.$suffix" - candidates="${candidates+$candidates, }$candidate" - test -r "$candidate" || continue - tarballs="${tarballs+$tarballs }$candidate" - done - for suffix in $diff_suffixes; do - candidate="$package_name-$opt_previous_version-$opt_current_version.$suffix" - candidates="${candidates+$candidates, }$candidate" - test -r "$candidate" || continue - compressed_diffs="${compressed_diffs+$compressed_diffs }$candidate" - done - test -n "$tarballs$compressed_diffs" || - func_fatal_error "none of $candidates were found." - - # Signature files - signed_files="$tarballs $compressed_diffs" - for signed in $signed_files; do - sig_files="${sig_files+$sig_files }$signed.sig" - done - - # Displaying or posting the announcement? - if $opt_post; then - notify_file="$tmp_dir/post" - exec 3>$notify_file - else - exec 3>&1 - fi - - { - echo "Subject: $package_name $opt_current_version released ($opt_release_type)" - test -f "$header_file" && cat "$header_file" - echo - test -f "$blurb_file" && cat "$blurb_file" - func_print_locations "compressed sources" "$url_directory" "$tarballs" - func_print_locations "diffs against $package_name $opt_previous_version" "$url_directory" "$compressed_diffs" - func_print_locations "GPG detached signatures[1]" "$url_directory" "$sig_files" - - $opt_print_checksums && - func_print_checksums "MD5 and SHA1 checksums[2]" $tarballs $compressed_diffs - - case $url_directory in - *"gnu.org"*) - echo - echo 'To reduce load on the main server, please one of the mirrors listed at:' - echo - echo ' http://www.gnu.org/order/ftp.html' - ;; - esac - - cat <&3 - - $opt_post && { - test -f "$top_srcdir/libltdl/config/$MAILNOTIFY" && - MAILNOTIFY="$top_srcdir/libltdl/config/$MAILNOTIFY" - test -f "$MAILNOTIFY" || - func_fatal_error "$MAILNOTIFY: file not found." - - ${PAGER-more} "$notify_file" || break - - sleep 1 # give the user some time for a ^C - - # Break out the headers - header_file="$tmp_dir/headers" - $SED -n '/[A-Z][a-zA-Z0-9-]*: /p;/^$/q' "$notify_file" > "$header_file" - - my_mail_body="`$SED '1,/^$/d' $notify_file`" - echo "$my_mail_body" > "$notify_file" - - func_verbose "mailing release announcement to \"$sendmail_to\"" - func_show_eval "$MAILNOTIFY $mailnotify_flags \ - --headers='$header_file' \ - -m 'text/plain' -f '$notify_file' -- $sendmail_to" - } -} - -$RM -r "$tmp_dir" - -exit $EXIT_SUCCESS - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -]]) diff --git a/libltdl/config/mailnotify.m4sh b/libltdl/config/mailnotify.m4sh deleted file mode 100644 index bbf3e03a..00000000 --- a/libltdl/config/mailnotify.m4sh +++ /dev/null @@ -1,403 +0,0 @@ -AS_INIT[]m4_divert_push([HEADER-COPYRIGHT]) -# mailnotify (GNU @PACKAGE@) version 1.0 -# Written by Gary V. Vaughan - -# Copyright (C) 2004, 2006, 2010 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. - -# Mailnotify 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. -# -# Mailnotify 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 mailnotify; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Usage: $progname [OPTIONS]... -# -# -x --debug enable verbose shell tracing -# --dry-run don't actually post the mime message -# -f FILE --filename=FILE content of this part -# -h FILE --headers=FILE read additional headers from FILE -# -m TYPE --mime-type=TYPE mime-type of this part -# -o FILE --output-file=FILE output to FILE instead of sending -# -v --verbose run in verbose mode -# --version print version information -# -? --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 'From: me@example.org' > headers -# echo 'To: patch-list@foo.org' >> headers -# echo 'Subject: FYI: PATCHFILE' >> headers -# echo 'Cc: someone@example.org' >> headers -# echo 'Applied this patch to HEAD' > body -# $progname -h headers -f body -m text/plain -f PATCHFILE -m text/x-patch -# -# There is no set order or requirement for mail headers in the headers -# file, though you will obviously need someone's address in 'To:', and -# it's not polite to omit the 'Subject:' header... - -# You will probably find using this script in conjunction with clcommit -# saves you a lot of typing. - -# Report bugs to - -: ${HOST=`hostname`} -: ${SENDMAIL=sendmail} - -PROGRAM=mailnotify - -m4_divert_pop -m4_include([getopt.m4sh]) - -M4SH_VERBATIM([[ -sed_mail_address='s,^.*<\(.*\)>.*$,\1,' -]]) - -dnl SHORT LONG DEFAULT INIT -dnl ---------------------------------------------------------------------- -dnl There are several options supported below for backwards compatibility, -dnl but which are not mentioned in the help. -M4SH_GETOPTS( - [C^!], [--carbon-copy], [], [], - [F^!], [--from], [], [], - [f@+], [--filename], [], [], - [h@!], [--headers], [], [], - [m+!], [--mime-type], [], [ - case [$]1 in - text/*) ;; - */*) func_error "\`[$]1': only text/* mime-types supported" - ;; - *) func_error "invalid mime-type, \`[$]1'" - exit_cmd=exit - ;; - esac], - [n], [], [], [], - [o!], [--output-file], [], [], - [s^!], [--subject], [], [], - [v], [--verbose], [], [], - [], [--dry-run|--dryrun], [], [], - [ - # ensure destination address(es) available - test [$]# -gt 0 || - grep '^\(To\|Cc\|Bcc\): ' "${opt_headers-nosuchfile}" >/dev/null 2>&1 || - func_fatal_help "no destination address" - - # validate headers - test "$opt_headers" && { - test -n "$opt_carbon_copy" && grep "^Cc: *" "$opt_headers" >/dev/null 2>&1 && { - func_error "specify \`Cc:' in either \`$opt_headers' or with \`--carbon-copy'." - exit_cmd=exit - } - test -n "$opt_from" && grep "^From: *" "$opt_headers" >/dev/null 2>&1 && { - func_error "specify \`From:' in either \`$opt_headers' or with \`--from'." - exit_cmd=exit - } - test -n "$opt_subject" && grep "^Subject: *" "$opt_headers" >/dev/null 2>&1 && { - func_error "specify \`Subject:' in either \`$opt_headers' or with \`--subject'." - exit_cmd=exit - } - } - - # validate mime parts - if test "${opt_mime_type_num-0}" -ne "${opt_filename_num-0}"; then - func_fatal_error "One part is incomplete -- each part needs a filename and a mime-type" - fi - if test -z "$opt_output_file"; then - test -f "$opt_headers" || if test -z "$opt_subject" || - eval test -z \"\$opt_mime_type_$opt_mime_type_num\" || - eval test -z \"\$opt_filename_$opt_filename_num\"; then - func_fatal_error "if output is not directed to a file -s, -f, and -m are all required" - fi - else - eval test -n \"\$opt_filename_$opt_filename_num\" || - func_fatal_error "-f is required." - eval test -n \"\$opt_mime_type_$opt_mime_type_num\" || - func_fatal_error "with output directed to a file, -m is required" - fi - - # validate $opt_dry_run - $opt_dry_run && SENDMAIL="echo $SENDMAIL" -]) - -M4SH_VERBATIM([[ -# Bail out on command errors! -set -e - -# func_headers outfile destination -# Generate common headers to OUTFILE, where DESTINATION is a comma -# separated list of fully qualified destination addresses. -func_headers () -{ - $opt_debug - - my_outfile="$1" - my_destination="$2" - my_sed_version_no=' - /^# '$PROGRAM' (GNU / { - s/^# .*version // - p - } - d' - - $opt_dry_run || { - echo "User-Agent: $PROGRAM/`$SED \"$my_sed_version_no\" < $progpath`" - echo "MIME-Version: 1.0" - - # Deprecated command line options take precedence at the moment - my_elide="Bcc" - test -n "$opt_from" && - my_elide="${my_elide+$my_elide\|}From" && eval echo From: $opt_from - test -n "$my_destination" && - my_elide="${my_elide+$my_elide\|}To" && eval echo To: $my_destination - test -n "$opt_carbon_copy" && - my_elide="${my_elide+$my_elide\|}Cc" && eval echo CC: $opt_carbon_copy - test -n "$opt_subject" && - my_elide="${my_elide+$my_elide\|}Subject" && eval echo Subject: $opt_subject - - # Plus any additional headers - test -n "$opt_headers" && $SED "/^\($my_elide\): */d" "$opt_headers" - } > "$my_outfile" - - : -} - - -# func_single_content outfile -# Send the only message part as a single mime mail part. -func_single_content () -{ - $opt_debug - - my_outfile="$1" - - $opt_dry_run || 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 $opt_filename_num - do - i=`expr 1 + $i` - eval file=\"\$opt_filename_$i\" - name=`echo "$file" | $SED $basename` - { - echo "" - echo "--$boundary" - if test $i -gt 1; then - eval echo \"Content-Type: \$opt_mime_type_$i\;\" - echo " name=\"$name\"" - else - eval echo \"Content-Type: \$opt_mime_type_$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 () -{ - $opt_debug - - my_infile="$1" - my_destination="$2" - my_from="$3" - - $opt_dry_run && my_infile=/dev/null - - 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" - - $opt_dry_run || { - 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." - $opt_dry_run || $RM $my_infile - else - func_fatal_error "Mail delivery failed, draft mail is in $my_infile" - fi -} - - -# func_extract_email_from_header re_header headerfile -func_extract_email () -{ - $opt_debug - - my_re_header="$1" - my_headerfile="$2" - $as_unset func_extract_email_result - - save_IFS="$IFS" - IFS=' -' - for to in : `grep "$my_re_header" "$my_headerfile" 2>/dev/null`; do - IFS="$save_IFS" - test "X$to" = X: && continue - - line=`echo "$to" | $SED "s,$my_re_header,,"` - - IFS=, - for addr in $line; do - IFS="$save_IFS" - func_quote_for_eval "$addr" - to_addr=`echo "$func_quote_for_eval_result" | $SED "$sed_mail_address"` - test -n "$to_addr" || to_addr="$func_quote_for_eval_result" - func_extract_email_result="${func_extract_email_result+$func_extract_email_result }$to_addr" - done - done - IFS="$save_IFS" -} - -## ----- ## -## main. ## -## ----- ## - -{ - tmp_dir="`func_mktempdir`" - headers="$tmp_dir/headers" - 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: - $as_unset destination - for to in : ${1+"$@"} - do - test "X$to" = X: && continue - - func_quote_for_eval "$to" - destination="${destination+$destination, }$func_quote_for_eval_result" - done - func_headers "$fname" "$destination" - - if test $opt_filename_num -gt 1; then - func_multipart_content "$fname" - else - func_single_content "$fname" - fi - - # Generate a list of destination addresses for sendmail: - if test -z "$opt_output_file"; then - $as_unset 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+$destination }$to_addr" - done - func_extract_email '^To: *' "$opt_headers" - destination="${destination+$destination }$func_extract_email_result" - func_extract_email '^Cc: *' "$opt_headers" - destination="${destination+$destination }$func_extract_email_result" - func_extract_email '^Bcc: *' "$opt_headers" - destination="${destination+$destination }$func_extract_email_result" - - test -n "$opt_from" || { - func_extract_email '^From: *' "$opt_headers" - opt_from="$func_extract_email_result" - } - - func_sendmail "$fname" "$destination" "$opt_from" - else - mv $fname $opt_output_file || exit $EXIT_FAILURE - fi - - $RM -r "$tmp_dir" -} - -exit $EXIT_SUCCESS - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -]]) -