1#! /bin/sh
2# Submit a problem report to a GNATS site.
3# Copyright (C) 1993 Free Software Foundation, Inc.
4# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a
5# version written by Heinz G. Seidl (hgs@ide.com).
6#
7# This file is part of GNU GNATS.
8# Modified by Berliner for CVS.
9#
10# GNU GNATS is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2, or (at your option)
13# any later version.
14#
15# GNU GNATS is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19
20# The version of this send-pr.
21VERSION=3.2
22
23# The submitter-id for your site.
24SUBMITTER=net
25
26## # Where the GNATS directory lives, if at all.
27## [ -z "$GNATS_ROOT" ] && 
28## GNATS_ROOT=/usr/local/lib/gnats/gnats-db
29
30# The default mail address for PR submissions. 
31GNATS_ADDR=bug-cvs@gnu.org
32
33## # Where the gnats category tree lives.
34## DATADIR=/usr/local/lib
35
36## # If we've been moved around, try using GCC_EXEC_PREFIX.
37## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}..
38
39# The default release for this host.
40DEFAULT_RELEASE="@VERSION@"
41
42# The default organization.
43DEFAULT_ORGANIZATION="net"
44
45## # The default site to look for.
46## GNATS_SITE=unknown
47
48## # Newer config information?
49## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config
50
51# What mailer to use.  This must come after the config file, since it is
52# host-dependent.
53if [ -f /usr/sbin/sendmail ]; then
54  MAIL_AGENT="/usr/sbin/sendmail -oi -t"
55else
56  MAIL_AGENT="/usr/lib/sendmail -oi -t"
57fi
58MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'`
59if [ ! -f "$MAILER" ] ; then
60	echo "$COMMAND: Cannot file mail program \"$MAILER\"."
61	echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file."
62	exit 1
63fi
64
65if test "`echo -n foo`" = foo ; then
66  ECHON=bsd
67elif test "`echo 'foo\c'`" = foo ; then
68  ECHON=sysv
69else
70  ECHON=none
71fi
72
73if [ $ECHON = bsd ] ; then
74  ECHON1="echo -n"
75  ECHON2=
76elif [ $ECHON = sysv ] ; then
77  ECHON1=echo
78  ECHON2='\c'
79else
80  ECHON1=echo
81  ECHON2=
82fi
83
84#
85
86[ -z "$TMPDIR" ] && TMPDIR=/tmp
87
88TEMP=`mktemp $TMPDIR/p.XXXXXXXXXX` || exit 1
89REF=`mktemp $TMPDIR/pf.XXXXXXXXXX` || {
90  rm -f $TEMP
91  exit 1
92}
93
94if [ -z "$LOGNAME" -a -n "$USER" ]; then
95  LOGNAME=$USER
96fi
97
98FROM="$LOGNAME"
99REPLY_TO="$LOGNAME"
100
101# Find out the name of the originator of this PR.
102if [ -n "$NAME" ]; then
103  ORIGINATOR="$NAME"
104elif [ -f $HOME/.fullname ]; then
105  ORIGINATOR="`sed -e '1q' $HOME/.fullname`"
106elif [ -f /bin/domainname ]; then
107  if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then
108    # Must use temp file due to incompatibilities in quoting behavior
109    # and to protect shell metacharacters in the expansion of $LOGNAME
110    /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" |
111      cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
112    ORIGINATOR="`cat $TEMP`"
113    rm -f $TEMP
114  fi
115fi
116
117if [ "$ORIGINATOR" = "" ]; then
118  grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
119  ORIGINATOR="`cat $TEMP`"
120  rm -f $TEMP
121fi
122
123if [ -n "$ORGANIZATION" ]; then
124  if [ -f "$ORGANIZATION" ]; then
125    ORGANIZATION="`cat $ORGANIZATION`"
126  fi
127else
128  if [ -n "$DEFAULT_ORGANIZATION" ]; then
129    ORGANIZATION="$DEFAULT_ORGANIZATION"
130  elif [ -f $HOME/.organization ]; then
131    ORGANIZATION="`cat $HOME/.organization`"
132  elif [ -f $HOME/.signature ]; then
133    ORGANIZATION="`cat $HOME/.signature`"
134  fi
135fi
136
137# If they don't have a preferred editor set, then use
138if [ -z "$VISUAL" ]; then
139  if [ -z "$EDITOR" ]; then
140    EDIT=vi
141  else
142    EDIT="$EDITOR"
143  fi
144else
145  EDIT="$VISUAL"
146fi
147
148# Find out some information.
149SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \
150        ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""`
151ARCH=`[ -f /bin/arch ] && /bin/arch`
152MACHINE=`[ -f /bin/machine ] && /bin/machine`
153
154COMMAND=`echo $0 | sed -e 's,.*/,,'`
155## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id] 
156USAGE="Usage: $COMMAND [-PVL]
157[--version]"
158REMOVE=
159BATCH=
160
161while [ $# -gt 0 ]; do
162  case "$1" in
163    -r) ;; 		# Ignore for backward compat.
164##     -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
165## 	shift ; GNATS_ADDR="$1"
166## 	EXPLICIT_GNATS_ADDR=true
167##         ;;
168##     -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
169## 	shift ; IN_FILE="$1"
170## 	if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then
171## 	  echo "$COMMAND: cannot read $IN_FILE"
172## 	  exit 1
173## 	fi
174## 	;;
175    -b | --batch) BATCH=true ;;
176    -p | -P | --print) PRINT=true ;;
177    -L | --list) FORMAT=norm ;;
178    -l | -CL | --lisp) FORMAT=lisp ;;
179##     --request-id) REQUEST_ID=true ;;
180    -h | --help) echo "$USAGE"; exit 0 ;;
181    -V | --version) echo "$VERSION"; exit 0 ;;
182    -*) echo "$USAGE" ; exit 1 ;;
183    *) echo "$USAGE" ; exit 1
184##        if [ -z "$USER_GNATS_SITE" ]; then
185## 	 if [ ! -r "$DATADIR/gnats/$1" ]; then
186## 	   echo "$COMMAND: the GNATS site $1 does not have a categories list."
187## 	   exit 1
188## 	 else
189## 	   # The site name is the alias they'll have to have created.
190## 	   USER_GNATS_SITE=$1
191## 	 fi
192##        else
193## 	 echo "$USAGE" ; exit 1
194##        fi
195       ;;
196 esac
197 shift
198done
199
200if [ -n "$USER_GNATS_SITE" ]; then
201  GNATS_SITE=$USER_GNATS_SITE
202  GNATS_ADDR=$USER_GNATS_SITE-gnats
203fi
204
205if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then
206  cat << '__EOF__'
207It seems that send-pr is not installed with your unique submitter-id.
208You need to run
209
210          install-sid YOUR-SID
211
212where YOUR-SID is the identification code you received with `send-pr'.
213`send-pr' will automatically insert this value into the template field
214`>Submitter-Id'.  If you've downloaded `send-pr' from the Net, use `net'
215for this value.  If you do not know your id, run `send-pr --request-id' to 
216get one from your support site.
217__EOF__
218  exit 1
219fi
220
221## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then
222##   CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort`
223## else
224##   echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list."
225##   exit 1
226## fi
227CATEGORIES="contrib cvs doc pcl-cvs portability"
228
229if [ -z "$CATEGORIES" ]; then
230  echo "$COMMAND: the categories list for $GNATS_SITE was empty!"
231  exit 1
232fi
233
234case "$FORMAT" in
235  lisp) echo "$CATEGORIES" | \
236        awk 'BEGIN {printf "( "}
237	     {printf "(\"%s\") ",$0}
238	     END {printf ")\n"}'
239        exit 0
240        ;;
241  norm) l=`echo "$CATEGORIES" | \
242	awk 'BEGIN {max = 0; }
243	     { if (length($0) > max) { max = length($0); } }
244	     END {print max + 1;}'`
245	c=`expr 70 / $l`
246	if [ $c -eq 0 ]; then c=1; fi
247	echo "$CATEGORIES" | \
248        awk 'BEGIN {print "Known categories:"; i = 0 }
249          { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } }
250            END { print ""; }'
251        exit 0
252        ;;
253esac
254
255ORIGINATOR_C='<name of the PR author (one line)>'
256ORGANIZATION_C='<organization of PR author (multiple lines)>'
257CONFIDENTIAL_C='<[ yes | no ] (one line)>'
258SYNOPSIS_C='<synopsis of the problem (one line)>'
259SEVERITY_C='<[ non-critical | serious | critical ] (one line)>'
260PRIORITY_C='<[ low | medium | high ] (one line)>'
261CATEGORY_C='<name of the product (one line)>'
262CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>'
263RELEASE_C='<release number or tag (one line)>'
264ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>'
265DESCRIPTION_C='<precise description of the problem (multiple lines)>'
266HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>'
267FIX_C='<how to correct or work around the problem, if known (multiple lines)>'
268
269# Catch some signals. ($xs kludge needed by Sun /bin/sh)
270xs=0
271trap 'rm -f $REF $TEMP; exit $xs' 0
272trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15
273
274# If they told us to use a specific file, then do so.
275if [ -n "$IN_FILE" ]; then
276  if [ "$IN_FILE" = "-" ]; then
277    # The PR is coming from the standard input.
278    if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
279      sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP
280    else
281      cat > $TEMP
282    fi
283  else
284    # Use the file they named.
285    if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
286      sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP
287    else
288      cat $IN_FILE > $TEMP
289    fi
290  fi
291else
292
293  if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
294    # If their PR_FORM points to a bogus entry, then bail.
295    if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then
296      echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM"
297      sleep 1
298      PRINT_INTERN=bad_prform
299    fi
300  fi
301
302  if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
303    cp $PR_FORM $TEMP || 
304      ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit )
305  else
306    for file in $TEMP $REF ; do
307      cat  > $file << '__EOF__'
308SEND-PR: -*- send-pr -*-
309SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
310SEND-PR: will all comments (text enclosed in `<' and `>').
311SEND-PR: 
312SEND-PR: Choose from the following categories:
313SEND-PR:
314__EOF__
315
316      # Format the categories so they fit onto lines.
317	l=`echo "$CATEGORIES" | \
318	awk 'BEGIN {max = 0; }
319	     { if (length($0) > max) { max = length($0); } }
320	     END {print max + 1;}'`
321	c=`expr 61 / $l`
322	if [ $c -eq 0 ]; then c=1; fi
323	echo "$CATEGORIES" | \
324        awk 'BEGIN {printf "SEND-PR: "; i = 0 }
325          { printf ("%-'$l'.'$l's", $0);
326	    if ((++i % '$c') == 0) { printf "\nSEND-PR: " } }
327            END { printf "\nSEND-PR:\n"; }' >> $file
328
329      cat >> $file << __EOF__
330To: $GNATS_ADDR
331Subject: 
332From: $FROM
333Reply-To: $REPLY_TO
334X-send-pr-version: $VERSION
335
336
337>Submitter-Id:   $SUBMITTER
338>Originator: 	 $ORIGINATOR
339>Organization:
340${ORGANIZATION-$ORGANIZATION_C}
341>Confidential:  $CONFIDENTIAL_C
342>Synopsis:	$SYNOPSIS_C
343>Severity:	$SEVERITY_C
344>Priority:	$PRIORITY_C
345>Category: 	$CATEGORY_C
346>Class:		$CLASS_C
347>Release:	${DEFAULT_RELEASE-$RELEASE_C}
348>Environment:
349    	$ENVIRONMENT_C
350`[ -n "$SYSTEM" ] && echo System: $SYSTEM`
351`[ -n "$ARCH" ] && echo Architecture: $ARCH`
352`[ -n "$MACHINE" ] && echo Machine: $MACHINE`
353>Description:
354	$DESCRIPTION_C
355>How-To-Repeat:
356	$HOW_TO_REPEAT_C
357>Fix:
358	$FIX_C
359__EOF__
360    done
361  fi
362
363  if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then
364    cat $TEMP
365    xs=0; exit
366  fi
367
368  chmod u+w $TEMP
369  if [ -z "$REQUEST_ID" ]; then
370    eval $EDIT $TEMP
371  else
372    ed -s $TEMP << '__EOF__'
373/^Subject/s/^Subject:.*/Subject: request for a customer id/
374/^>Category/s/^>Category:.*/>Category: send-pr/
375w
376q
377__EOF__
378  fi
379
380  if cmp -s $REF $TEMP ; then
381    echo "$COMMAND: problem report not filled out, therefore not sent"
382    xs=1; exit
383  fi
384fi
385
386#
387#	Check the enumeration fields
388
389# This is a "sed-subroutine" with one keyword parameter 
390# (with workaround for Sun sed bug)
391#
392SED_CMD='
393/$PATTERN/{
394s|||
395s|<.*>||
396s|^[ 	]*||
397s|[ 	]*$||
398p
399q
400}'
401
402
403while [ -z "$REQUEST_ID" ]; do
404  CNT=0
405
406  # 1) Confidential
407  #
408  PATTERN=">Confidential:"
409  CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
410  case "$CONFIDENTIAL" in
411    ""|yes|no) CNT=`expr $CNT + 1` ;;
412    *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;;
413  esac
414  #
415  # 2) Severity
416  #
417  PATTERN=">Severity:"
418  SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
419  case "$SEVERITY" in
420    ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;;
421    *)  echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'."
422  esac
423  #
424  # 3) Priority
425  #
426  PATTERN=">Priority:"
427  PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
428  case "$PRIORITY" in
429    ""|low|medium|high) CNT=`expr $CNT + 1` ;;
430    *)  echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'."
431  esac
432  #
433  # 4) Category
434  #
435  PATTERN=">Category:"
436  CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
437  FOUND=
438  for C in $CATEGORIES
439  do
440    if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi
441  done
442  if [ -n "$FOUND" ]; then
443    CNT=`expr $CNT + 1`	
444  else
445    if [ -z "$CATEGORY" ]; then
446      echo "$COMMAND: you must include a Category: field in your report."
447    else
448      echo "$COMMAND: \`$CATEGORY' is not a known category."
449    fi
450  fi
451  #
452  # 5) Class
453  #
454  PATTERN=">Class:"
455  CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
456  case "$CLASS" in
457    ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;;
458    *)  echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'."
459  esac
460
461  [ $CNT -lt 5 -a -z "$BATCH" ] && 
462    echo "Errors were found with the problem report."
463
464  while true; do
465    if [ -z "$BATCH" ]; then
466      $ECHON1 "a)bort, e)dit or s)end? $ECHON2"
467      read input
468    else
469      if [ $CNT -eq 5 ]; then
470        input=s
471      else
472        input=a
473      fi
474    fi
475    case "$input" in
476      a*)
477	if [ -z "$BATCH" ]; then
478	  BAD=`mktemp $TMPDIR/pbad.XXXXXXXXXX` || exit 1
479	  echo "$COMMAND: the problem report remains in $BAD and is not sent."
480	  mv $TEMP $BAD
481        else
482	  echo "$COMMAND: the problem report is not sent."
483	fi
484	xs=1; exit
485	;;
486      e*)
487        eval $EDIT $TEMP
488	continue 2
489	;;
490      s*)
491	break 2
492	;;
493    esac
494  done
495done
496#
497#	Remove comments and send the problem report
498#	(we have to use patterns, where the comment contains regex chars)
499#
500# /^>Originator:/s;$ORIGINATOR;;
501sed  -e "
502/^SEND-PR:/d
503/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;;
504/^>Confidential:/s;<.*>;;
505/^>Synopsis:/s;$SYNOPSIS_C;;
506/^>Severity:/s;<.*>;;
507/^>Priority:/s;<.*>;;
508/^>Category:/s;$CATEGORY_C;;
509/^>Class:/s;<.*>;;
510/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;;
511/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;;
512/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;;
513/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;;
514/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;;
515" $TEMP > $REF
516
517if $MAIL_AGENT < $REF; then
518  echo "$COMMAND: problem report sent"
519  xs=0; exit
520else
521  echo "$COMMAND: mysterious mail failure."
522  if [ -z "$BATCH" ]; then
523    BAD=`mktemp $TMPDIR/pbad.XXXXXXXXXX` || exit 1
524    echo "$COMMAND: the problem report remains in $BAD and is not sent."
525    mv $REF $BAD
526  else
527    echo "$COMMAND: the problem report is not sent."
528  fi
529  xs=1; exit
530fi
531