60eaeb9b9732f8912f783381cf51d0a14d4ed577
[platform/upstream/bash.git] / support / bashbug.sh
1 #!/bin/sh -
2 #
3 # bashbug - create a bug report and mail it to the bug address
4 #
5 # The bug address depends on the release status of the shell.  Versions
6 # with status `devel', `alpha', `beta', or `rc' mail bug reports to
7 # chet@po.cwru.edu and, optionally, to bash-testers@po.cwru.edu.
8 # Other versions send mail to bug-bash@gnu.org.
9 #
10 # configuration section:
11 #       these variables are filled in by the make target in Makefile
12 #
13 MACHINE="!MACHINE!"
14 OS="!OS!"
15 CC="!CC!"
16 CFLAGS="!CFLAGS!"
17 RELEASE="!RELEASE!"
18 PATCHLEVEL="!PATCHLEVEL!"
19 RELSTATUS="!RELSTATUS!"
20 MACHTYPE="!MACHTYPE!"
21
22 PATH=/bin:/usr/bin:/usr/local/bin:$PATH
23 export PATH
24
25 # If the OS supplies a program to make temp files with semi-random names,
26 # use it.
27 : ${TMPDIR:=/tmp}
28 rm_tmp1=false
29 rm_tmp2=false
30
31 # if we don't have mktemp or tempfile, we don't want to see error messages
32 # like `mktemp: not found', so temporarily redirect stderr using {...} while
33 # trying to run them.  this may fail using old versions of the bourne shell
34 # that run {...} blocks with redirections in subshells; in that case we're
35 # no worse off than previous versions
36
37 { TEMPFILE1=`mktemp "$TMPDIR/bbug.XXXXXX" 2>/dev/null` ; } 2>/dev/null
38 if [ -z "$TEMPFILE1" ]; then
39         { TEMPFILE1=`tempfile --prefix bbug --mode 600 2>/dev/null`; } 2>/dev/null
40 fi
41 if [ -z "$TEMPFILE1" ]; then
42         TEMPFILE1=$TMPDIR/bbug.$$
43         rm_tmp1=true
44 fi
45 { TEMPFILE2=`mktemp "$TMPDIR/bbug.XXXXXX" 2>/dev/null`; } 2>/dev/null
46 if [ -z "$TEMPFILE2" ]; then
47         { TEMPFILE2=`tempfile --prefix bbug --mode 600 2>/dev/null`; } 2>/dev/null
48 fi
49 if [ -z "$TEMPFILE2" ]; then
50         TEMPFILE2="$TMPDIR/bbug.$$.x"
51         rm_tmp2=true
52 fi
53
54 USAGE="Usage: $0 [--help] [--version] [bug-report-email-address]"
55 VERSTR="GNU bashbug, version ${RELEASE}.${PATCHLEVEL}-${RELSTATUS}"
56
57 do_help= do_version=
58
59 while [ $# -gt 0 ]; do
60         case "$1" in
61         --help)         shift ; do_help=y ;;
62         --version)      shift ; do_version=y ;;
63         --)             shift ; break ;;
64         -*)             echo "bashbug: ${1}: invalid option" >&2
65                         echo "$USAGE" >& 2
66                         exit 2 ;;
67         *)              break ;;
68         esac
69 done
70
71 if [ -n "$do_version" ]; then
72         echo "${VERSTR}"
73         exit 0
74 fi
75
76 if [ -n "$do_help" ]; then
77         echo "${VERSTR}"
78         echo "${USAGE}"
79         echo
80         cat << HERE_EOF
81 Bashbug is used to send mail to the Bash maintainers
82 for when Bash doesn't behave like you'd like, or expect.
83
84 Bashbug will start up your editor (as defined by the shell's
85 EDITOR environment variable) with a preformatted bug report
86 template for you to fill in. The report will be mailed to the
87 bash maintainers by default. See the manual for details.
88
89 If you invoke bashbug by accident, just quit your editor without
90 saving any changes to the template, and no bug report will be sent.
91 HERE_EOF
92         exit 0
93 fi
94
95 # Figure out how to echo a string without a trailing newline
96 N=`echo 'hi there\c'`
97 case "$N" in
98 *c)     n=-n c= ;;
99 *)      n= c='\c' ;;
100 esac
101
102 BASHTESTERS="bash-testers@po.cwru.edu"
103
104 case "$RELSTATUS" in
105 alpha*|beta*|devel*|rc*)        BUGBASH=chet@po.cwru.edu ;;
106 *)                              BUGBASH=bug-bash@gnu.org ;;
107 esac
108
109 case "$RELSTATUS" in
110 alpha*|beta*|devel*|rc*)
111                 echo "$0: This is a testing release.  Would you like your bug report"
112                 echo "$0: to be sent to the bash-testers mailing list?"
113                 echo $n "$0: Send to bash-testers? $c"
114                 read ans
115                 case "$ans" in
116                 y*|Y*)  BUGBASH="${BUGBASH},${BASHTESTERS}" ;;
117                 esac ;;
118 esac
119
120 BUGADDR="${1-$BUGBASH}"
121
122 if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then
123         if [ -x /usr/bin/editor ]; then
124                 DEFEDITOR=editor
125         elif [ -x /usr/local/bin/ce ]; then
126                 DEFEDITOR=ce
127         elif [ -x /usr/local/bin/emacs ]; then
128                 DEFEDITOR=emacs
129         elif [ -x /usr/contrib/bin/emacs ]; then
130                 DEFEDITOR=emacs
131         elif [ -x /usr/bin/emacs ]; then
132                 DEFEDITOR=emacs
133         elif [ -x /usr/bin/xemacs ]; then
134                 DEFEDITOR=xemacs
135         elif [ -x /usr/contrib/bin/jove ]; then
136                 DEFEDITOR=jove
137         elif [ -x /usr/local/bin/jove ]; then
138                 DEFEDITOR=jove
139         elif [ -x /usr/bin/vi ]; then
140                 DEFEDITOR=vi
141         else
142                 echo "$0: No default editor found: attempting to use vi" >&2
143                 DEFEDITOR=vi
144         fi
145 fi
146
147
148 : ${EDITOR=$DEFEDITOR}
149
150 : ${USER=${LOGNAME-`whoami`}}
151
152 trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"; exit 1' 1 2 3 13 15
153 trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"' 0
154
155 UN=
156 if (uname) >/dev/null 2>&1; then
157         UN=`uname -a`
158 fi
159
160 if [ -f /usr/lib/sendmail ] ; then
161         RMAIL="/usr/lib/sendmail"
162         SMARGS="-i -t"
163 elif [ -f /usr/sbin/sendmail ] ; then
164         RMAIL="/usr/sbin/sendmail"
165         SMARGS="-i -t"
166 else
167         RMAIL=rmail
168         SMARGS="$BUGADDR"
169 fi
170
171 INITIAL_SUBJECT='[50 character or so descriptive subject here (for reference)]'
172
173 # this is raceable unless (hopefully) we used mktemp(1) or tempfile(1)
174 $rm_tmp1 && rm -f "$TEMPFILE1"
175
176 cat > "$TEMPFILE1" <<EOF
177 From: ${USER}
178 To: ${BUGADDR}
179 Subject: ${INITIAL_SUBJECT}
180
181 Configuration Information [Automatically generated, do not change]:
182 Machine: $MACHINE
183 OS: $OS
184 Compiler: $CC
185 Compilation CFLAGS: $CFLAGS
186 uname output: $UN
187 Machine Type: $MACHTYPE
188
189 Bash Version: $RELEASE
190 Patch Level: $PATCHLEVEL
191 Release Status: $RELSTATUS
192
193 Description:
194         [Detailed description of the problem, suggestion, or complaint.]
195
196 Repeat-By:
197         [Describe the sequence of events that causes the problem
198         to occur.]
199
200 Fix:
201         [Description of how to fix the problem.  If you don't know a
202         fix for the problem, don't include this section.]
203 EOF
204
205 # this is still raceable unless (hopefully) we used mktemp(1) or tempfile(1)
206 $rm_tmp2 && rm -f "$TEMPFILE2"
207
208 cp "$TEMPFILE1" "$TEMPFILE2"
209 chmod u+w "$TEMPFILE1"
210
211 trap '' 2               # ignore interrupts while in editor
212
213 edstat=1
214 while [ $edstat -ne 0 ]; do
215         $EDITOR "$TEMPFILE1"
216         edstat=$?
217
218         if [ $edstat -ne 0 ]; then
219                 echo "$0: editor \`$EDITOR' exited with nonzero status."
220                 echo "$0: Perhaps it was interrupted."
221                 echo "$0: Type \`y' to give up, and lose your bug report;"
222                 echo "$0: type \`n' to re-enter the editor."
223                 echo $n "$0: Do you want to give up? $c"
224
225                 read ans
226                 case "$ans" in
227                 [Yy]*) exit 1 ;;
228                 esac
229
230                 continue
231         fi
232
233         # find the subject from the temp file and see if it's been changed
234         CURR_SUB=`grep '^Subject: ' "$TEMPFILE1" | sed 's|^Subject:[    ]*||' | sed 1q`
235
236         case "$CURR_SUB" in
237         "${INITIAL_SUBJECT}")
238                 echo
239                 echo "$0: You have not changed the subject from the default."
240                 echo "$0: Please use a more descriptive subject header."
241                 echo "$0: Type \`y' to give up, and lose your bug report;"
242                 echo "$0: type \`n' to re-enter the editor."
243                 echo $n "$0: Do you want to give up? $c"
244
245                 read ans
246                 case "$ans" in
247                 [Yy]*) exit 1 ;;
248                 esac
249
250                 echo "$0:  The editor will be restarted in five seconds."
251                 sleep 5
252                 edstat=1
253                 ;;
254         esac
255
256 done
257
258 trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"; exit 1' 2        # restore trap on SIGINT
259
260 if cmp -s "$TEMPFILE1" "$TEMPFILE2"
261 then
262         echo "File not changed, no bug report submitted."
263         exit
264 fi
265
266 echo $n "Send bug report? [y/n] $c"
267 read ans
268 case "$ans" in
269 [Nn]*)  exit 0 ;;
270 esac
271
272 ${RMAIL} $SMARGS < "$TEMPFILE1" || {
273         cat "$TEMPFILE1" >> $HOME/dead.bashbug
274         echo "$0: mail failed: report saved in $HOME/dead.bashbug" >&2
275 }
276
277 exit 0