xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/utils/perlbug.PL (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!/usr/local/bin/perl
2*0Sstevel@tonic-gate
3*0Sstevel@tonic-gateuse Config;
4*0Sstevel@tonic-gateuse File::Basename qw(&basename &dirname);
5*0Sstevel@tonic-gateuse Cwd;
6*0Sstevel@tonic-gateuse File::Spec::Functions;
7*0Sstevel@tonic-gate
8*0Sstevel@tonic-gate# List explicitly here the variables you want Configure to
9*0Sstevel@tonic-gate# generate.  Metaconfig only looks for shell variables, so you
10*0Sstevel@tonic-gate# have to mention them as if they were shell variables, not
11*0Sstevel@tonic-gate# %Config entries.  Thus you write
12*0Sstevel@tonic-gate#  $startperl
13*0Sstevel@tonic-gate# to ensure Configure will look for $Config{startperl}.
14*0Sstevel@tonic-gate#  $perlpath
15*0Sstevel@tonic-gate
16*0Sstevel@tonic-gate# This forces PL files to create target in same directory as PL file.
17*0Sstevel@tonic-gate# This is so that make depend always knows where to find PL derivatives.
18*0Sstevel@tonic-gate$origdir = cwd;
19*0Sstevel@tonic-gatechdir dirname($0);
20*0Sstevel@tonic-gate$file = basename($0, '.PL');
21*0Sstevel@tonic-gate$file .= '.com' if $^O eq 'VMS';
22*0Sstevel@tonic-gate
23*0Sstevel@tonic-gateopen OUT, ">$file" or die "Can't create $file: $!";
24*0Sstevel@tonic-gate
25*0Sstevel@tonic-gate# extract patchlevel.h information
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gateopen PATCH_LEVEL, "<" . catfile(updir, "patchlevel.h")
28*0Sstevel@tonic-gate    or die "Can't open patchlevel.h: $!";
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gatemy $patchlevel_date = (stat PATCH_LEVEL)[9];
31*0Sstevel@tonic-gate
32*0Sstevel@tonic-gatewhile (<PATCH_LEVEL>) {
33*0Sstevel@tonic-gate    last if $_ =~ /^\s*static\s+char.*?local_patches\[\]\s*=\s*{\s*$/;
34*0Sstevel@tonic-gate}
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gatemy @patches;
37*0Sstevel@tonic-gatewhile (<PATCH_LEVEL>) {
38*0Sstevel@tonic-gate    last if /^\s*}/;
39*0Sstevel@tonic-gate    chomp;
40*0Sstevel@tonic-gate    s/^\s+,?\s*"?//;
41*0Sstevel@tonic-gate    s/"?\s*,?$//;
42*0Sstevel@tonic-gate    s/(['\\])/\\$1/g;
43*0Sstevel@tonic-gate    push @patches, $_ unless $_ eq 'NULL';
44*0Sstevel@tonic-gate}
45*0Sstevel@tonic-gatemy $patch_desc = "'" . join("',\n    '", @patches) . "'";
46*0Sstevel@tonic-gatemy $patch_tags = join "", map /(\S+)/ ? "+$1 " : (), @patches;
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gateclose(PATCH_LEVEL) or die "Error closing patchlevel.h: $!";
49*0Sstevel@tonic-gate
50*0Sstevel@tonic-gate# TO DO (prehaps): store/embed $Config::config_sh into perlbug. When perlbug is
51*0Sstevel@tonic-gate# used, compare $Config::config_sh with the stored version. If they differ then
52*0Sstevel@tonic-gate# append a list of individual differences to the bug report.
53*0Sstevel@tonic-gate
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gateprint "Extracting $file (with variable substitutions)\n";
56*0Sstevel@tonic-gate
57*0Sstevel@tonic-gate# In this section, perl variables will be expanded during extraction.
58*0Sstevel@tonic-gate# You can use $Config{...} to use Configure variables.
59*0Sstevel@tonic-gate
60*0Sstevel@tonic-gatemy $extract_version = sprintf("v%vd", $^V);
61*0Sstevel@tonic-gate
62*0Sstevel@tonic-gateprint OUT <<"!GROK!THIS!";
63*0Sstevel@tonic-gate$Config{startperl}
64*0Sstevel@tonic-gate    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
65*0Sstevel@tonic-gate	if \$running_under_some_shell;
66*0Sstevel@tonic-gate
67*0Sstevel@tonic-gatemy \$config_tag1 = '$extract_version - $Config{cf_time}';
68*0Sstevel@tonic-gate
69*0Sstevel@tonic-gatemy \$patchlevel_date = $patchlevel_date;
70*0Sstevel@tonic-gatemy \$patch_tags = '$patch_tags';
71*0Sstevel@tonic-gatemy \@patches = (
72*0Sstevel@tonic-gate    $patch_desc
73*0Sstevel@tonic-gate);
74*0Sstevel@tonic-gate!GROK!THIS!
75*0Sstevel@tonic-gate
76*0Sstevel@tonic-gate# In the following, perl variables are not expanded during extraction.
77*0Sstevel@tonic-gate
78*0Sstevel@tonic-gateprint OUT <<'!NO!SUBS!';
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gateuse Config;
81*0Sstevel@tonic-gateuse File::Spec;		# keep perlbug Perl 5.005 compatible
82*0Sstevel@tonic-gateuse Getopt::Std;
83*0Sstevel@tonic-gateuse strict;
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gatesub paraprint;
86*0Sstevel@tonic-gate
87*0Sstevel@tonic-gateBEGIN {
88*0Sstevel@tonic-gate    eval "use Mail::Send;";
89*0Sstevel@tonic-gate    $::HaveSend = ($@ eq "");
90*0Sstevel@tonic-gate    eval "use Mail::Util;";
91*0Sstevel@tonic-gate    $::HaveUtil = ($@ eq "");
92*0Sstevel@tonic-gate    # use secure tempfiles wherever possible
93*0Sstevel@tonic-gate    eval "require File::Temp;";
94*0Sstevel@tonic-gate    $::HaveTemp = ($@ eq "");
95*0Sstevel@tonic-gate};
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gatemy $Version = "1.35";
98*0Sstevel@tonic-gate
99*0Sstevel@tonic-gate# Changed in 1.06 to skip Mail::Send and Mail::Util if not available.
100*0Sstevel@tonic-gate# Changed in 1.07 to see more sendmail execs, and added pipe output.
101*0Sstevel@tonic-gate# Changed in 1.08 to use correct address for sendmail.
102*0Sstevel@tonic-gate# Changed in 1.09 to close the REP file before calling it up in the editor.
103*0Sstevel@tonic-gate#                 Also removed some old comments duplicated elsewhere.
104*0Sstevel@tonic-gate# Changed in 1.10 to run under VMS without Mail::Send; also fixed
105*0Sstevel@tonic-gate#                 temp filename generation.
106*0Sstevel@tonic-gate# Changed in 1.11 to clean up some text and removed Mail::Send deactivator.
107*0Sstevel@tonic-gate# Changed in 1.12 to check for editor errors, make save/send distinction
108*0Sstevel@tonic-gate#                 clearer and add $ENV{REPLYTO}.
109*0Sstevel@tonic-gate# Changed in 1.13 to hopefully make it more difficult to accidentally
110*0Sstevel@tonic-gate#                 send mail
111*0Sstevel@tonic-gate# Changed in 1.14 to make the prompts a little more clear on providing
112*0Sstevel@tonic-gate#                 helpful information. Also let file read fail gracefully.
113*0Sstevel@tonic-gate# Changed in 1.15 to add warnings to stop people using perlbug for non-bugs.
114*0Sstevel@tonic-gate#                 Also report selected environment variables.
115*0Sstevel@tonic-gate# Changed in 1.16 to include @INC, and allow user to re-edit if no changes.
116*0Sstevel@tonic-gate# Changed in 1.17 Win32 support added.  GSAR 97-04-12
117*0Sstevel@tonic-gate# Changed in 1.18 add '-ok' option for reporting build success. CFR 97-06-18
118*0Sstevel@tonic-gate# Changed in 1.19 '-ok' default not '-v'
119*0Sstevel@tonic-gate#                 add local patch information
120*0Sstevel@tonic-gate#                 warn on '-ok' if this is an old system; add '-okay'
121*0Sstevel@tonic-gate# Changed in 1.20 Added patchlevel.h reading and version/config checks
122*0Sstevel@tonic-gate# Changed in 1.21 Added '-nok' for reporting build failure DFD 98-05-05
123*0Sstevel@tonic-gate# Changed in 1.22 Heavy reformatting & minor bugfixes HVDS 98-05-10
124*0Sstevel@tonic-gate# Changed in 1.23 Restore -ok(ay): say 'success'; don't prompt
125*0Sstevel@tonic-gate# Changed in 1.24 Added '-F<file>' to save report HVDS 98-07-01
126*0Sstevel@tonic-gate# Changed in 1.25 Warn on failure to open save file. HVDS 98-07-12
127*0Sstevel@tonic-gate# Changed in 1.26 Don't require -t STDIN for -ok. HVDS 98-07-15
128*0Sstevel@tonic-gate# Changed in 1.27 Added Mac OS and File::Spec support CNANDOR 99-07-27
129*0Sstevel@tonic-gate# Changed in 1.28 Additional questions for Perlbugtron RFOLEY 20.03.2000
130*0Sstevel@tonic-gate# Changed in 1.29 Perlbug(tron): auto(-ok), short prompts RFOLEY 05-05-2000
131*0Sstevel@tonic-gate# Changed in 1.30 Added warnings on failure to open files MSTEVENS 13-07-2000
132*0Sstevel@tonic-gate# Changed in 1.31 Add checks on close().Fix my $var unless. TJENNESS 26-07-2000
133*0Sstevel@tonic-gate# Changed in 1.32 Use File::Spec->tmpdir TJENNESS 20-08-2000
134*0Sstevel@tonic-gate# Changed in 1.33 Don't require -t STDOUT for -ok.
135*0Sstevel@tonic-gate# Changed in 1.34 Added Message-Id RFOLEY 18-06-2002
136*0Sstevel@tonic-gate# Changed in 1.35 Use File::Temp (patch from Solar Designer) NWCLARK 28-02-2004
137*0Sstevel@tonic-gate
138*0Sstevel@tonic-gate# TODO: - Allow the user to re-name the file on mail failure, and
139*0Sstevel@tonic-gate#       make sure failure (transmission-wise) of Mail::Send is
140*0Sstevel@tonic-gate#       accounted for.
141*0Sstevel@tonic-gate#       - Test -b option
142*0Sstevel@tonic-gate
143*0Sstevel@tonic-gatemy( $file, $usefile, $cc, $address, $perlbug, $testaddress, $filename, $messageid, $domain,
144*0Sstevel@tonic-gate    $subject, $from, $verbose, $ed, $outfile, $Is_MacOS, $category, $severity,
145*0Sstevel@tonic-gate    $fh, $me, $Is_MSWin32, $Is_Linux, $Is_VMS, $msg, $body, $andcc, %REP, $ok,
146*0Sstevel@tonic-gate    $Is_OpenBSD);
147*0Sstevel@tonic-gate
148*0Sstevel@tonic-gatemy $perl_version = $^V ? sprintf("v%vd", $^V) : $];
149*0Sstevel@tonic-gate
150*0Sstevel@tonic-gatemy $config_tag2 = "$perl_version - $Config{cf_time}";
151*0Sstevel@tonic-gate
152*0Sstevel@tonic-gateInit();
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gateif ($::opt_h) { Help(); exit; }
155*0Sstevel@tonic-gateif ($::opt_d) { Dump(*STDOUT); exit; }
156*0Sstevel@tonic-gateif (!-t STDIN && !($ok and not $::opt_n)) {
157*0Sstevel@tonic-gate    paraprint <<EOF;
158*0Sstevel@tonic-gatePlease use perlbug interactively. If you want to
159*0Sstevel@tonic-gateinclude a file, you can use the -f switch.
160*0Sstevel@tonic-gateEOF
161*0Sstevel@tonic-gate    die "\n";
162*0Sstevel@tonic-gate}
163*0Sstevel@tonic-gate
164*0Sstevel@tonic-gateQuery();
165*0Sstevel@tonic-gateEdit() unless $usefile || ($ok and not $::opt_n);
166*0Sstevel@tonic-gateNowWhat();
167*0Sstevel@tonic-gateSend();
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gateexit;
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gatesub ask_for_alternatives { # (category|severity)
172*0Sstevel@tonic-gate    my $name = shift;
173*0Sstevel@tonic-gate    my %alts = (
174*0Sstevel@tonic-gate	'category' => {
175*0Sstevel@tonic-gate	    'default' => 'core',
176*0Sstevel@tonic-gate	    'ok'      => 'install',
177*0Sstevel@tonic-gate	    'opts'    => [qw(core docs install library utilities)], # patch, notabug
178*0Sstevel@tonic-gate	},
179*0Sstevel@tonic-gate	'severity' => {
180*0Sstevel@tonic-gate	    'default' => 'low',
181*0Sstevel@tonic-gate	    'ok'      => 'none',
182*0Sstevel@tonic-gate	    'opts'    => [qw(critical high medium low wishlist none)], # zero
183*0Sstevel@tonic-gate	},
184*0Sstevel@tonic-gate    );
185*0Sstevel@tonic-gate    die "Invalid alternative($name) requested\n" unless grep(/^$name$/, keys %alts);
186*0Sstevel@tonic-gate    my $alt = "";
187*0Sstevel@tonic-gate    if ($ok) {
188*0Sstevel@tonic-gate	$alt = $alts{$name}{'ok'};
189*0Sstevel@tonic-gate    } else {
190*0Sstevel@tonic-gate 	my @alts = @{$alts{$name}{'opts'}};
191*0Sstevel@tonic-gate	paraprint <<EOF;
192*0Sstevel@tonic-gatePlease pick a \u$name from the following:
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate    @alts
195*0Sstevel@tonic-gate
196*0Sstevel@tonic-gateEOF
197*0Sstevel@tonic-gate	my $err = 0;
198*0Sstevel@tonic-gate	do {
199*0Sstevel@tonic-gate	    if ($err++ > 5) {
200*0Sstevel@tonic-gate		die "Invalid $name: aborting.\n";
201*0Sstevel@tonic-gate	    }
202*0Sstevel@tonic-gate	    print "Please enter a \u$name [$alts{$name}{'default'}]: ";
203*0Sstevel@tonic-gate	    $alt = <>;
204*0Sstevel@tonic-gate	    chomp $alt;
205*0Sstevel@tonic-gate	    if ($alt =~ /^\s*$/) {
206*0Sstevel@tonic-gate		$alt = $alts{$name}{'default'};
207*0Sstevel@tonic-gate	    }
208*0Sstevel@tonic-gate	} while !((($alt) = grep(/^$alt/i, @alts)));
209*0Sstevel@tonic-gate    }
210*0Sstevel@tonic-gate    lc $alt;
211*0Sstevel@tonic-gate}
212*0Sstevel@tonic-gate
213*0Sstevel@tonic-gatesub Init {
214*0Sstevel@tonic-gate    # -------- Setup --------
215*0Sstevel@tonic-gate
216*0Sstevel@tonic-gate    $Is_MSWin32 = $^O eq 'MSWin32';
217*0Sstevel@tonic-gate    $Is_VMS = $^O eq 'VMS';
218*0Sstevel@tonic-gate    $Is_Linux = lc($^O) eq 'linux';
219*0Sstevel@tonic-gate    $Is_OpenBSD = lc($^O) eq 'openbsd';
220*0Sstevel@tonic-gate    $Is_MacOS = $^O eq 'MacOS';
221*0Sstevel@tonic-gate
222*0Sstevel@tonic-gate    @ARGV = split m/\s+/,
223*0Sstevel@tonic-gate        MacPerl::Ask('Provide command-line args here (-h for help):')
224*0Sstevel@tonic-gate        if $Is_MacOS && $MacPerl::Version =~ /App/;
225*0Sstevel@tonic-gate
226*0Sstevel@tonic-gate    if (!getopts("Adhva:s:b:f:F:r:e:SCc:to:n:")) { Help(); exit; };
227*0Sstevel@tonic-gate
228*0Sstevel@tonic-gate    # This comment is needed to notify metaconfig that we are
229*0Sstevel@tonic-gate    # using the $perladmin, $cf_by, and $cf_time definitions.
230*0Sstevel@tonic-gate
231*0Sstevel@tonic-gate    # -------- Configuration ---------
232*0Sstevel@tonic-gate
233*0Sstevel@tonic-gate    # perlbug address
234*0Sstevel@tonic-gate    $perlbug = 'perlbug@perl.org';
235*0Sstevel@tonic-gate
236*0Sstevel@tonic-gate    # Test address
237*0Sstevel@tonic-gate    $testaddress = 'perlbug-test@perl.org';
238*0Sstevel@tonic-gate
239*0Sstevel@tonic-gate    # Target address
240*0Sstevel@tonic-gate    $address = $::opt_a || ($::opt_t ? $testaddress : $perlbug);
241*0Sstevel@tonic-gate
242*0Sstevel@tonic-gate    # Users address, used in message and in Reply-To header
243*0Sstevel@tonic-gate    $from = $::opt_r || "";
244*0Sstevel@tonic-gate
245*0Sstevel@tonic-gate    # Include verbose configuration information
246*0Sstevel@tonic-gate    $verbose = $::opt_v || 0;
247*0Sstevel@tonic-gate
248*0Sstevel@tonic-gate    # Subject of bug-report message
249*0Sstevel@tonic-gate    $subject = $::opt_s || "";
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate    # Send a file
252*0Sstevel@tonic-gate    $usefile = ($::opt_f || 0);
253*0Sstevel@tonic-gate
254*0Sstevel@tonic-gate    # File to send as report
255*0Sstevel@tonic-gate    $file = $::opt_f || "";
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gate    # File to output to
258*0Sstevel@tonic-gate    $outfile = $::opt_F || "";
259*0Sstevel@tonic-gate
260*0Sstevel@tonic-gate    # Body of report
261*0Sstevel@tonic-gate    $body = $::opt_b || "";
262*0Sstevel@tonic-gate
263*0Sstevel@tonic-gate    # Editor
264*0Sstevel@tonic-gate    $ed = $::opt_e || $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT}
265*0Sstevel@tonic-gate	|| ($Is_VMS && "edit/tpu")
266*0Sstevel@tonic-gate	|| ($Is_MSWin32 && "notepad")
267*0Sstevel@tonic-gate	|| ($Is_MacOS && '')
268*0Sstevel@tonic-gate	|| "vi";
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate    # Not OK - provide build failure template by finessing OK report
271*0Sstevel@tonic-gate    if ($::opt_n) {
272*0Sstevel@tonic-gate	if (substr($::opt_n, 0, 2) eq 'ok' )	{
273*0Sstevel@tonic-gate	    $::opt_o = substr($::opt_n, 1);
274*0Sstevel@tonic-gate	} else {
275*0Sstevel@tonic-gate	    Help();
276*0Sstevel@tonic-gate	    exit();
277*0Sstevel@tonic-gate	}
278*0Sstevel@tonic-gate    }
279*0Sstevel@tonic-gate
280*0Sstevel@tonic-gate    # OK - send "OK" report for build on this system
281*0Sstevel@tonic-gate    $ok = 0;
282*0Sstevel@tonic-gate    if ($::opt_o) {
283*0Sstevel@tonic-gate	if ($::opt_o eq 'k' or $::opt_o eq 'kay') {
284*0Sstevel@tonic-gate	    my $age = time - $patchlevel_date;
285*0Sstevel@tonic-gate	    if ($::opt_o eq 'k' and $age > 60 * 24 * 60 * 60 ) {
286*0Sstevel@tonic-gate		my $date = localtime $patchlevel_date;
287*0Sstevel@tonic-gate		print <<"EOF";
288*0Sstevel@tonic-gate"perlbug -ok" and "perlbug -nok" do not report on Perl versions which
289*0Sstevel@tonic-gateare more than 60 days old.  This Perl version was constructed on
290*0Sstevel@tonic-gate$date.  If you really want to report this, use
291*0Sstevel@tonic-gate"perlbug -okay" or "perlbug -nokay".
292*0Sstevel@tonic-gateEOF
293*0Sstevel@tonic-gate		exit();
294*0Sstevel@tonic-gate	    }
295*0Sstevel@tonic-gate	    # force these options
296*0Sstevel@tonic-gate	    unless ($::opt_n) {
297*0Sstevel@tonic-gate		$::opt_S = 1; # don't prompt for send
298*0Sstevel@tonic-gate		$::opt_b = 1; # we have a body
299*0Sstevel@tonic-gate		$body = "Perl reported to build OK on this system.\n";
300*0Sstevel@tonic-gate	    }
301*0Sstevel@tonic-gate	    $::opt_C = 1; # don't send a copy to the local admin
302*0Sstevel@tonic-gate	    $::opt_s = 1; # we have a subject line
303*0Sstevel@tonic-gate	    $subject = ($::opt_n ? 'Not ' : '')
304*0Sstevel@tonic-gate		    . "OK: perl $perl_version ${patch_tags}on"
305*0Sstevel@tonic-gate		    ." $::Config{'archname'} $::Config{'osvers'} $subject";
306*0Sstevel@tonic-gate	    $ok = 1;
307*0Sstevel@tonic-gate	} else {
308*0Sstevel@tonic-gate	    Help();
309*0Sstevel@tonic-gate	    exit();
310*0Sstevel@tonic-gate	}
311*0Sstevel@tonic-gate    }
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate    # Possible administrator addresses, in order of confidence
314*0Sstevel@tonic-gate    # (Note that cf_email is not mentioned to metaconfig, since
315*0Sstevel@tonic-gate    # we don't really want it. We'll just take it if we have to.)
316*0Sstevel@tonic-gate    #
317*0Sstevel@tonic-gate    # This has to be after the $ok stuff above because of the way
318*0Sstevel@tonic-gate    # that $::opt_C is forced.
319*0Sstevel@tonic-gate    $cc = $::opt_C ? "" : (
320*0Sstevel@tonic-gate	$::opt_c || $::Config{'perladmin'}
321*0Sstevel@tonic-gate	|| $::Config{'cf_email'} || $::Config{'cf_by'}
322*0Sstevel@tonic-gate    );
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gate    if ($::HaveUtil) {
325*0Sstevel@tonic-gate		$domain = Mail::Util::maildomain();
326*0Sstevel@tonic-gate    } elsif ($Is_MSWin32) {
327*0Sstevel@tonic-gate		$domain = $ENV{'USERDOMAIN'};
328*0Sstevel@tonic-gate    } else {
329*0Sstevel@tonic-gate		require Sys::Hostname;
330*0Sstevel@tonic-gate		$domain = Sys::Hostname::hostname();
331*0Sstevel@tonic-gate    }
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gate    # Message-Id - rjsf
334*0Sstevel@tonic-gate    $messageid = "<$::Config{'version'}_${$}_".time."\@$domain>";
335*0Sstevel@tonic-gate
336*0Sstevel@tonic-gate    # My username
337*0Sstevel@tonic-gate    $me = $Is_MSWin32 ? $ENV{'USERNAME'}
338*0Sstevel@tonic-gate	    : $^O eq 'os2' ? $ENV{'USER'} || $ENV{'LOGNAME'}
339*0Sstevel@tonic-gate	    : $Is_MacOS ? $ENV{'USER'}
340*0Sstevel@tonic-gate	    : eval { getpwuid($<) };	# May be missing
341*0Sstevel@tonic-gate
342*0Sstevel@tonic-gate    $from = $::Config{'cf_email'}
343*0Sstevel@tonic-gate       if !$from && $::Config{'cf_email'} && $::Config{'cf_by'} && $me &&
344*0Sstevel@tonic-gate               ($me eq $::Config{'cf_by'});
345*0Sstevel@tonic-gate} # sub Init
346*0Sstevel@tonic-gate
347*0Sstevel@tonic-gatesub Query {
348*0Sstevel@tonic-gate    # Explain what perlbug is
349*0Sstevel@tonic-gate    unless ($ok) {
350*0Sstevel@tonic-gate	paraprint <<EOF;
351*0Sstevel@tonic-gateThis program provides an easy way to create a message reporting a bug
352*0Sstevel@tonic-gatein perl, and e-mail it to $address.  It is *NOT* intended for
353*0Sstevel@tonic-gatesending test messages or simply verifying that perl works, *NOR* is it
354*0Sstevel@tonic-gateintended for reporting bugs in third-party perl modules.  It is *ONLY*
355*0Sstevel@tonic-gatea means of reporting verifiable problems with the core perl distribution,
356*0Sstevel@tonic-gateand any solutions to such problems, to the people who maintain perl.
357*0Sstevel@tonic-gate
358*0Sstevel@tonic-gateIf you're just looking for help with perl, try posting to the Usenet
359*0Sstevel@tonic-gatenewsgroup comp.lang.perl.misc.  If you're looking for help with using
360*0Sstevel@tonic-gateperl with CGI, try posting to comp.infosystems.www.programming.cgi.
361*0Sstevel@tonic-gateEOF
362*0Sstevel@tonic-gate    }
363*0Sstevel@tonic-gate
364*0Sstevel@tonic-gate    # Prompt for subject of message, if needed
365*0Sstevel@tonic-gate
366*0Sstevel@tonic-gate    if (TrivialSubject($subject)) {
367*0Sstevel@tonic-gate	$subject = '';
368*0Sstevel@tonic-gate    }
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate    unless ($subject) {
371*0Sstevel@tonic-gate	paraprint <<EOF;
372*0Sstevel@tonic-gateFirst of all, please provide a subject for the
373*0Sstevel@tonic-gatemessage. It should be a concise description of
374*0Sstevel@tonic-gatethe bug or problem. "perl bug" or "perl problem"
375*0Sstevel@tonic-gateis not a concise description.
376*0Sstevel@tonic-gateEOF
377*0Sstevel@tonic-gate
378*0Sstevel@tonic-gate	my $err = 0;
379*0Sstevel@tonic-gate	do {
380*0Sstevel@tonic-gate	    print "Subject: ";
381*0Sstevel@tonic-gate	    $subject = <>;
382*0Sstevel@tonic-gate	    chomp $subject;
383*0Sstevel@tonic-gate	    if ($err++ == 5) {
384*0Sstevel@tonic-gate		die "Aborting.\n";
385*0Sstevel@tonic-gate	    }
386*0Sstevel@tonic-gate	} while (TrivialSubject($subject));
387*0Sstevel@tonic-gate    }
388*0Sstevel@tonic-gate
389*0Sstevel@tonic-gate    # Prompt for return address, if needed
390*0Sstevel@tonic-gate    unless ($from) {
391*0Sstevel@tonic-gate	# Try and guess return address
392*0Sstevel@tonic-gate	my $guess;
393*0Sstevel@tonic-gate
394*0Sstevel@tonic-gate	$guess = $ENV{'REPLY-TO'} || $ENV{'REPLYTO'} || '';
395*0Sstevel@tonic-gate        if ($Is_MacOS) {
396*0Sstevel@tonic-gate            require Mac::InternetConfig;
397*0Sstevel@tonic-gate            $guess = $Mac::InternetConfig::InternetConfig{
398*0Sstevel@tonic-gate                Mac::InternetConfig::kICEmail()
399*0Sstevel@tonic-gate            };
400*0Sstevel@tonic-gate        }
401*0Sstevel@tonic-gate
402*0Sstevel@tonic-gate	unless ($guess) {
403*0Sstevel@tonic-gate		# move $domain to where we can use it elsewhere
404*0Sstevel@tonic-gate        if ($domain) {
405*0Sstevel@tonic-gate		if ($Is_VMS && !$::Config{'d_socket'}) {
406*0Sstevel@tonic-gate		    $guess = "$domain\:\:$me";
407*0Sstevel@tonic-gate		} else {
408*0Sstevel@tonic-gate		    $guess = "$me\@$domain" if $domain;
409*0Sstevel@tonic-gate		}
410*0Sstevel@tonic-gate	    }
411*0Sstevel@tonic-gate	}
412*0Sstevel@tonic-gate
413*0Sstevel@tonic-gate	if ($guess) {
414*0Sstevel@tonic-gate	    unless ($ok) {
415*0Sstevel@tonic-gate		paraprint <<EOF;
416*0Sstevel@tonic-gateYour e-mail address will be useful if you need to be contacted. If the
417*0Sstevel@tonic-gatedefault shown is not your full internet e-mail address, please correct it.
418*0Sstevel@tonic-gateEOF
419*0Sstevel@tonic-gate	    }
420*0Sstevel@tonic-gate	} else {
421*0Sstevel@tonic-gate	    paraprint <<EOF;
422*0Sstevel@tonic-gateSo that you may be contacted if necessary, please enter
423*0Sstevel@tonic-gateyour full internet e-mail address here.
424*0Sstevel@tonic-gateEOF
425*0Sstevel@tonic-gate	}
426*0Sstevel@tonic-gate
427*0Sstevel@tonic-gate	if ($ok && $guess) {
428*0Sstevel@tonic-gate	    # use it
429*0Sstevel@tonic-gate	    $from = $guess;
430*0Sstevel@tonic-gate	} else {
431*0Sstevel@tonic-gate	    # verify it
432*0Sstevel@tonic-gate	    print "Your address [$guess]: ";
433*0Sstevel@tonic-gate	    $from = <>;
434*0Sstevel@tonic-gate	    chomp $from;
435*0Sstevel@tonic-gate	    $from = $guess if $from eq '';
436*0Sstevel@tonic-gate	}
437*0Sstevel@tonic-gate    }
438*0Sstevel@tonic-gate
439*0Sstevel@tonic-gate    if ($from eq $cc or $me eq $cc) {
440*0Sstevel@tonic-gate	# Try not to copy ourselves
441*0Sstevel@tonic-gate	$cc = "yourself";
442*0Sstevel@tonic-gate    }
443*0Sstevel@tonic-gate
444*0Sstevel@tonic-gate    # Prompt for administrator address, unless an override was given
445*0Sstevel@tonic-gate    if( !$::opt_C and !$::opt_c ) {
446*0Sstevel@tonic-gate	paraprint <<EOF;
447*0Sstevel@tonic-gateA copy of this report can be sent to your local
448*0Sstevel@tonic-gateperl administrator. If the address is wrong, please
449*0Sstevel@tonic-gatecorrect it, or enter 'none' or 'yourself' to not send
450*0Sstevel@tonic-gatea copy.
451*0Sstevel@tonic-gateEOF
452*0Sstevel@tonic-gate	print "Local perl administrator [$cc]: ";
453*0Sstevel@tonic-gate	my $entry = scalar <>;
454*0Sstevel@tonic-gate	chomp $entry;
455*0Sstevel@tonic-gate
456*0Sstevel@tonic-gate	if ($entry ne "") {
457*0Sstevel@tonic-gate	    $cc = $entry;
458*0Sstevel@tonic-gate	    $cc = '' if $me eq $cc;
459*0Sstevel@tonic-gate	}
460*0Sstevel@tonic-gate    }
461*0Sstevel@tonic-gate
462*0Sstevel@tonic-gate    $cc = '' if $cc =~ /^(none|yourself|me|myself|ourselves)$/i;
463*0Sstevel@tonic-gate    $andcc = " and $cc" if $cc;
464*0Sstevel@tonic-gate
465*0Sstevel@tonic-gate    # Prompt for editor, if no override is given
466*0Sstevel@tonic-gateeditor:
467*0Sstevel@tonic-gate    unless ($::opt_e || $::opt_f || $::opt_b) {
468*0Sstevel@tonic-gate	paraprint <<EOF;
469*0Sstevel@tonic-gateNow you need to supply the bug report. Try to make
470*0Sstevel@tonic-gatethe report concise but descriptive. Include any
471*0Sstevel@tonic-gaterelevant detail. If you are reporting something
472*0Sstevel@tonic-gatethat does not work as you think it should, please
473*0Sstevel@tonic-gatetry to include example of both the actual
474*0Sstevel@tonic-gateresult, and what you expected.
475*0Sstevel@tonic-gate
476*0Sstevel@tonic-gateSome information about your local
477*0Sstevel@tonic-gateperl configuration will automatically be included
478*0Sstevel@tonic-gateat the end of the report. If you are using any
479*0Sstevel@tonic-gateunusual version of perl, please try and confirm
480*0Sstevel@tonic-gateexactly which versions are relevant.
481*0Sstevel@tonic-gate
482*0Sstevel@tonic-gateYou will probably want to use an editor to enter
483*0Sstevel@tonic-gatethe report. If "$ed" is the editor you want
484*0Sstevel@tonic-gateto use, then just press Enter, otherwise type in
485*0Sstevel@tonic-gatethe name of the editor you would like to use.
486*0Sstevel@tonic-gate
487*0Sstevel@tonic-gateIf you would like to use a prepared file, type
488*0Sstevel@tonic-gate"file", and you will be asked for the filename.
489*0Sstevel@tonic-gateEOF
490*0Sstevel@tonic-gate	print "Editor [$ed]: ";
491*0Sstevel@tonic-gate	my $entry =scalar <>;
492*0Sstevel@tonic-gate	chomp $entry;
493*0Sstevel@tonic-gate
494*0Sstevel@tonic-gate	$usefile = 0;
495*0Sstevel@tonic-gate	if ($entry eq "file") {
496*0Sstevel@tonic-gate	    $usefile = 1;
497*0Sstevel@tonic-gate	} elsif ($entry ne "") {
498*0Sstevel@tonic-gate	    $ed = $entry;
499*0Sstevel@tonic-gate	}
500*0Sstevel@tonic-gate    }
501*0Sstevel@tonic-gate
502*0Sstevel@tonic-gate    # Prompt for category of bug
503*0Sstevel@tonic-gate    $category ||= ask_for_alternatives('category');
504*0Sstevel@tonic-gate
505*0Sstevel@tonic-gate    # Prompt for severity of bug
506*0Sstevel@tonic-gate    $severity ||= ask_for_alternatives('severity');
507*0Sstevel@tonic-gate
508*0Sstevel@tonic-gate    # Generate scratch file to edit report in
509*0Sstevel@tonic-gate    $filename = filename();
510*0Sstevel@tonic-gate
511*0Sstevel@tonic-gate    # Prompt for file to read report from, if needed
512*0Sstevel@tonic-gate    if ($usefile and !$file) {
513*0Sstevel@tonic-gatefilename:
514*0Sstevel@tonic-gate	paraprint <<EOF;
515*0Sstevel@tonic-gateWhat is the name of the file that contains your report?
516*0Sstevel@tonic-gateEOF
517*0Sstevel@tonic-gate	print "Filename: ";
518*0Sstevel@tonic-gate	my $entry = scalar <>;
519*0Sstevel@tonic-gate	chomp $entry;
520*0Sstevel@tonic-gate
521*0Sstevel@tonic-gate	if ($entry eq "") {
522*0Sstevel@tonic-gate	    paraprint <<EOF;
523*0Sstevel@tonic-gateNo filename? I'll let you go back and choose an editor again.
524*0Sstevel@tonic-gateEOF
525*0Sstevel@tonic-gate	    goto editor;
526*0Sstevel@tonic-gate	}
527*0Sstevel@tonic-gate
528*0Sstevel@tonic-gate	unless (-f $entry and -r $entry) {
529*0Sstevel@tonic-gate	    paraprint <<EOF;
530*0Sstevel@tonic-gateI'm sorry, but I can't read from `$entry'. Maybe you mistyped the name of
531*0Sstevel@tonic-gatethe file? If you don't want to send a file, just enter a blank line and you
532*0Sstevel@tonic-gatecan get back to the editor selection.
533*0Sstevel@tonic-gateEOF
534*0Sstevel@tonic-gate	    goto filename;
535*0Sstevel@tonic-gate	}
536*0Sstevel@tonic-gate	$file = $entry;
537*0Sstevel@tonic-gate    }
538*0Sstevel@tonic-gate
539*0Sstevel@tonic-gate    # Generate report
540*0Sstevel@tonic-gate    open(REP,">$filename") or die "Unable to create report file `$filename': $!\n";
541*0Sstevel@tonic-gate    my $reptype = !$ok ? "bug" : $::opt_n ? "build failure" : "success";
542*0Sstevel@tonic-gate
543*0Sstevel@tonic-gate    print REP <<EOF;
544*0Sstevel@tonic-gateThis is a $reptype report for perl from $from,
545*0Sstevel@tonic-gategenerated with the help of perlbug $Version running under perl $perl_version.
546*0Sstevel@tonic-gate
547*0Sstevel@tonic-gateEOF
548*0Sstevel@tonic-gate
549*0Sstevel@tonic-gate    if ($body) {
550*0Sstevel@tonic-gate	print REP $body;
551*0Sstevel@tonic-gate    } elsif ($usefile) {
552*0Sstevel@tonic-gate	open(F, "<$file")
553*0Sstevel@tonic-gate		or die "Unable to read report file from `$file': $!\n";
554*0Sstevel@tonic-gate	while (<F>) {
555*0Sstevel@tonic-gate	    print REP $_
556*0Sstevel@tonic-gate	}
557*0Sstevel@tonic-gate	close(F) or die "Error closing `$file': $!";
558*0Sstevel@tonic-gate    } else {
559*0Sstevel@tonic-gate	print REP <<EOF;
560*0Sstevel@tonic-gate
561*0Sstevel@tonic-gate-----------------------------------------------------------------
562*0Sstevel@tonic-gate[Please enter your report here]
563*0Sstevel@tonic-gate
564*0Sstevel@tonic-gate
565*0Sstevel@tonic-gate
566*0Sstevel@tonic-gate[Please do not change anything below this line]
567*0Sstevel@tonic-gate-----------------------------------------------------------------
568*0Sstevel@tonic-gateEOF
569*0Sstevel@tonic-gate    }
570*0Sstevel@tonic-gate    Dump(*REP);
571*0Sstevel@tonic-gate    close(REP) or die "Error closing report file: $!";
572*0Sstevel@tonic-gate
573*0Sstevel@tonic-gate    # read in the report template once so that
574*0Sstevel@tonic-gate    # we can track whether the user does any editing.
575*0Sstevel@tonic-gate    # yes, *all* whitespace is ignored.
576*0Sstevel@tonic-gate    open(REP, "<$filename") or die "Unable to open report file `$filename': $!\n";
577*0Sstevel@tonic-gate    while (<REP>) {
578*0Sstevel@tonic-gate	s/\s+//g;
579*0Sstevel@tonic-gate	$REP{$_}++;
580*0Sstevel@tonic-gate    }
581*0Sstevel@tonic-gate    close(REP) or die "Error closing report file `$filename': $!";
582*0Sstevel@tonic-gate} # sub Query
583*0Sstevel@tonic-gate
584*0Sstevel@tonic-gatesub Dump {
585*0Sstevel@tonic-gate    local(*OUT) = @_;
586*0Sstevel@tonic-gate
587*0Sstevel@tonic-gate    print OUT <<EFF;
588*0Sstevel@tonic-gate---
589*0Sstevel@tonic-gateFlags:
590*0Sstevel@tonic-gate    category=$category
591*0Sstevel@tonic-gate    severity=$severity
592*0Sstevel@tonic-gateEFF
593*0Sstevel@tonic-gate    if ($::opt_A) {
594*0Sstevel@tonic-gate	print OUT <<EFF;
595*0Sstevel@tonic-gate    ack=no
596*0Sstevel@tonic-gateEFF
597*0Sstevel@tonic-gate    }
598*0Sstevel@tonic-gate    print OUT <<EFF;
599*0Sstevel@tonic-gate---
600*0Sstevel@tonic-gateEFF
601*0Sstevel@tonic-gate    print OUT "This perlbug was built using Perl $config_tag1\n",
602*0Sstevel@tonic-gate	    "It is being executed now by  Perl $config_tag2.\n\n"
603*0Sstevel@tonic-gate	if $config_tag2 ne $config_tag1;
604*0Sstevel@tonic-gate
605*0Sstevel@tonic-gate    print OUT <<EOF;
606*0Sstevel@tonic-gateSite configuration information for perl $perl_version:
607*0Sstevel@tonic-gate
608*0Sstevel@tonic-gateEOF
609*0Sstevel@tonic-gate    if ($::Config{cf_by} and $::Config{cf_time}) {
610*0Sstevel@tonic-gate	print OUT "Configured by $::Config{cf_by} at $::Config{cf_time}.\n\n";
611*0Sstevel@tonic-gate    }
612*0Sstevel@tonic-gate    print OUT Config::myconfig;
613*0Sstevel@tonic-gate
614*0Sstevel@tonic-gate    if (@patches) {
615*0Sstevel@tonic-gate	print OUT join "\n    ", "Locally applied patches:", @patches;
616*0Sstevel@tonic-gate	print OUT "\n";
617*0Sstevel@tonic-gate    };
618*0Sstevel@tonic-gate
619*0Sstevel@tonic-gate    print OUT <<EOF;
620*0Sstevel@tonic-gate
621*0Sstevel@tonic-gate---
622*0Sstevel@tonic-gate\@INC for perl $perl_version:
623*0Sstevel@tonic-gateEOF
624*0Sstevel@tonic-gate    for my $i (@INC) {
625*0Sstevel@tonic-gate	print OUT "    $i\n";
626*0Sstevel@tonic-gate    }
627*0Sstevel@tonic-gate
628*0Sstevel@tonic-gate    print OUT <<EOF;
629*0Sstevel@tonic-gate
630*0Sstevel@tonic-gate---
631*0Sstevel@tonic-gateEnvironment for perl $perl_version:
632*0Sstevel@tonic-gateEOF
633*0Sstevel@tonic-gate    my @env =
634*0Sstevel@tonic-gate        qw(PATH LD_LIBRARY_PATH LANG PERL_BADLANG SHELL HOME LOGDIR LANGUAGE);
635*0Sstevel@tonic-gate    push @env, $Config{ldlibpthname} if $Config{ldlibpthname} ne '';
636*0Sstevel@tonic-gate    push @env, grep /^(?:PERL|LC_|LANG|CYGWIN)/, keys %ENV;
637*0Sstevel@tonic-gate    my %env;
638*0Sstevel@tonic-gate    @env{@env} = @env;
639*0Sstevel@tonic-gate    for my $env (sort keys %env) {
640*0Sstevel@tonic-gate	print OUT "    $env",
641*0Sstevel@tonic-gate		exists $ENV{$env} ? "=$ENV{$env}" : ' (unset)',
642*0Sstevel@tonic-gate		"\n";
643*0Sstevel@tonic-gate    }
644*0Sstevel@tonic-gate    if ($verbose) {
645*0Sstevel@tonic-gate	print OUT "\nComplete configuration data for perl $perl_version:\n\n";
646*0Sstevel@tonic-gate	my $value;
647*0Sstevel@tonic-gate	foreach (sort keys %::Config) {
648*0Sstevel@tonic-gate	    $value = $::Config{$_};
649*0Sstevel@tonic-gate	    $value =~ s/'/\\'/g;
650*0Sstevel@tonic-gate	    print OUT "$_='$value'\n";
651*0Sstevel@tonic-gate	}
652*0Sstevel@tonic-gate    }
653*0Sstevel@tonic-gate} # sub Dump
654*0Sstevel@tonic-gate
655*0Sstevel@tonic-gatesub Edit {
656*0Sstevel@tonic-gate    # Edit the report
657*0Sstevel@tonic-gate    if ($usefile || $body) {
658*0Sstevel@tonic-gate	paraprint <<EOF;
659*0Sstevel@tonic-gatePlease make sure that the name of the editor you want to use is correct.
660*0Sstevel@tonic-gateEOF
661*0Sstevel@tonic-gate	print "Editor [$ed]: ";
662*0Sstevel@tonic-gate	my $entry =scalar <>;
663*0Sstevel@tonic-gate	chomp $entry;
664*0Sstevel@tonic-gate	$ed = $entry unless $entry eq '';
665*0Sstevel@tonic-gate    }
666*0Sstevel@tonic-gate
667*0Sstevel@tonic-gatetryagain:
668*0Sstevel@tonic-gate    my $sts;
669*0Sstevel@tonic-gate    $sts = system("$ed $filename") unless $Is_MacOS;
670*0Sstevel@tonic-gate    if ($Is_MacOS) {
671*0Sstevel@tonic-gate        require ExtUtils::MakeMaker;
672*0Sstevel@tonic-gate        ExtUtils::MM_MacOS::launch_file($filename);
673*0Sstevel@tonic-gate        paraprint <<EOF;
674*0Sstevel@tonic-gatePress Enter when done.
675*0Sstevel@tonic-gateEOF
676*0Sstevel@tonic-gate        scalar <>;
677*0Sstevel@tonic-gate    }
678*0Sstevel@tonic-gate    if ($sts) {
679*0Sstevel@tonic-gate	paraprint <<EOF;
680*0Sstevel@tonic-gateThe editor you chose (`$ed') could apparently not be run!
681*0Sstevel@tonic-gateDid you mistype the name of your editor? If so, please
682*0Sstevel@tonic-gatecorrect it here, otherwise just press Enter.
683*0Sstevel@tonic-gateEOF
684*0Sstevel@tonic-gate	print "Editor [$ed]: ";
685*0Sstevel@tonic-gate	my $entry =scalar <>;
686*0Sstevel@tonic-gate	chomp $entry;
687*0Sstevel@tonic-gate
688*0Sstevel@tonic-gate	if ($entry ne "") {
689*0Sstevel@tonic-gate	    $ed = $entry;
690*0Sstevel@tonic-gate	    goto tryagain;
691*0Sstevel@tonic-gate	} else {
692*0Sstevel@tonic-gate	    paraprint <<EOF;
693*0Sstevel@tonic-gateYou may want to save your report to a file, so you can edit and mail it
694*0Sstevel@tonic-gateyourself.
695*0Sstevel@tonic-gateEOF
696*0Sstevel@tonic-gate	}
697*0Sstevel@tonic-gate    }
698*0Sstevel@tonic-gate
699*0Sstevel@tonic-gate    return if ($ok and not $::opt_n) || $body;
700*0Sstevel@tonic-gate    # Check that we have a report that has some, eh, report in it.
701*0Sstevel@tonic-gate    my $unseen = 0;
702*0Sstevel@tonic-gate
703*0Sstevel@tonic-gate    open(REP, "<$filename") or die "Couldn't open `$filename': $!\n";
704*0Sstevel@tonic-gate    # a strange way to check whether any significant editing
705*0Sstevel@tonic-gate    # have been done: check whether any new non-empty lines
706*0Sstevel@tonic-gate    # have been added. Yes, the below code ignores *any* space
707*0Sstevel@tonic-gate    # in *any* line.
708*0Sstevel@tonic-gate    while (<REP>) {
709*0Sstevel@tonic-gate	s/\s+//g;
710*0Sstevel@tonic-gate	$unseen++ if $_ ne '' and not exists $REP{$_};
711*0Sstevel@tonic-gate    }
712*0Sstevel@tonic-gate
713*0Sstevel@tonic-gate    while ($unseen == 0) {
714*0Sstevel@tonic-gate	paraprint <<EOF;
715*0Sstevel@tonic-gateI am sorry but it looks like you did not report anything.
716*0Sstevel@tonic-gateEOF
717*0Sstevel@tonic-gate	print "Action (Retry Edit/Cancel) ";
718*0Sstevel@tonic-gate	my ($action) = scalar(<>);
719*0Sstevel@tonic-gate	if ($action =~ /^[re]/i) { # <R>etry <E>dit
720*0Sstevel@tonic-gate	    goto tryagain;
721*0Sstevel@tonic-gate	} elsif ($action =~ /^[cq]/i) { # <C>ancel, <Q>uit
722*0Sstevel@tonic-gate	    Cancel();
723*0Sstevel@tonic-gate	}
724*0Sstevel@tonic-gate    }
725*0Sstevel@tonic-gate} # sub Edit
726*0Sstevel@tonic-gate
727*0Sstevel@tonic-gatesub Cancel {
728*0Sstevel@tonic-gate    1 while unlink($filename);  # remove all versions under VMS
729*0Sstevel@tonic-gate    print "\nCancelling.\n";
730*0Sstevel@tonic-gate    exit(0);
731*0Sstevel@tonic-gate}
732*0Sstevel@tonic-gate
733*0Sstevel@tonic-gatesub NowWhat {
734*0Sstevel@tonic-gate    # Report is done, prompt for further action
735*0Sstevel@tonic-gate    if( !$::opt_S ) {
736*0Sstevel@tonic-gate	while(1) {
737*0Sstevel@tonic-gate	    paraprint <<EOF;
738*0Sstevel@tonic-gateNow that you have completed your report, would you like to send
739*0Sstevel@tonic-gatethe message to $address$andcc, display the message on
740*0Sstevel@tonic-gatethe screen, re-edit it, display/change the subject,
741*0Sstevel@tonic-gateor cancel without sending anything?
742*0Sstevel@tonic-gateYou may also save the message as a file to mail at another time.
743*0Sstevel@tonic-gateEOF
744*0Sstevel@tonic-gate      retry:
745*0Sstevel@tonic-gate	    print "Action (Send/Display/Edit/Subject/Save to File): ";
746*0Sstevel@tonic-gate	    my $action = scalar <>;
747*0Sstevel@tonic-gate	    chomp $action;
748*0Sstevel@tonic-gate
749*0Sstevel@tonic-gate	    if ($action =~ /^(f|sa)/i) { # <F>ile/<Sa>ve
750*0Sstevel@tonic-gate		my $file_save = $outfile || "perlbug.rep";
751*0Sstevel@tonic-gate		print "\n\nName of file to save message in [$file_save]: ";
752*0Sstevel@tonic-gate		my $file = scalar <>;
753*0Sstevel@tonic-gate		chomp $file;
754*0Sstevel@tonic-gate		$file = $file_save if $file eq "";
755*0Sstevel@tonic-gate
756*0Sstevel@tonic-gate		unless (open(FILE, ">$file")) {
757*0Sstevel@tonic-gate		    print "\nError opening $file: $!\n\n";
758*0Sstevel@tonic-gate		    goto retry;
759*0Sstevel@tonic-gate		}
760*0Sstevel@tonic-gate		open(REP, "<$filename") or die "Couldn't open file `$filename': $!\n";
761*0Sstevel@tonic-gate		print FILE "To: $address\nSubject: $subject\n";
762*0Sstevel@tonic-gate		print FILE "Cc: $cc\n" if $cc;
763*0Sstevel@tonic-gate		print FILE "Reply-To: $from\n" if $from;
764*0Sstevel@tonic-gate		print FILE "Message-Id: $messageid\n" if $messageid;
765*0Sstevel@tonic-gate		print FILE "\n";
766*0Sstevel@tonic-gate		while (<REP>) { print FILE }
767*0Sstevel@tonic-gate		close(REP) or die "Error closing report file `$filename': $!";
768*0Sstevel@tonic-gate		close(FILE) or die "Error closing $file: $!";
769*0Sstevel@tonic-gate
770*0Sstevel@tonic-gate		print "\nMessage saved in `$file'.\n";
771*0Sstevel@tonic-gate		exit;
772*0Sstevel@tonic-gate	    } elsif ($action =~ /^(d|l|sh)/i ) { # <D>isplay, <L>ist, <Sh>ow
773*0Sstevel@tonic-gate		# Display the message
774*0Sstevel@tonic-gate		open(REP, "<$filename") or die "Couldn't open file `$filename': $!\n";
775*0Sstevel@tonic-gate		while (<REP>) { print $_ }
776*0Sstevel@tonic-gate		close(REP) or die "Error closing report file `$filename': $!";
777*0Sstevel@tonic-gate	    } elsif ($action =~ /^su/i) { # <Su>bject
778*0Sstevel@tonic-gate		print "Subject: $subject\n";
779*0Sstevel@tonic-gate		print "If the above subject is fine, just press Enter.\n";
780*0Sstevel@tonic-gate		print "If not, type in the new subject.\n";
781*0Sstevel@tonic-gate		print "Subject: ";
782*0Sstevel@tonic-gate		my $reply = scalar <STDIN>;
783*0Sstevel@tonic-gate		chomp $reply;
784*0Sstevel@tonic-gate		if ($reply ne '') {
785*0Sstevel@tonic-gate		    unless (TrivialSubject($reply)) {
786*0Sstevel@tonic-gate			$subject = $reply;
787*0Sstevel@tonic-gate			print "Subject: $subject\n";
788*0Sstevel@tonic-gate		    }
789*0Sstevel@tonic-gate		}
790*0Sstevel@tonic-gate	    } elsif ($action =~ /^se/i) { # <S>end
791*0Sstevel@tonic-gate		# Send the message
792*0Sstevel@tonic-gate		print "Are you certain you want to send this message?\n"
793*0Sstevel@tonic-gate		    . 'Please type "yes" if you are: ';
794*0Sstevel@tonic-gate		my $reply = scalar <STDIN>;
795*0Sstevel@tonic-gate		chomp $reply;
796*0Sstevel@tonic-gate		if ($reply eq "yes") {
797*0Sstevel@tonic-gate		    last;
798*0Sstevel@tonic-gate		} else {
799*0Sstevel@tonic-gate		    paraprint <<EOF;
800*0Sstevel@tonic-gateThat wasn't a clear "yes", so I won't send your message. If you are sure
801*0Sstevel@tonic-gateyour message should be sent, type in "yes" (without the quotes) at the
802*0Sstevel@tonic-gateconfirmation prompt.
803*0Sstevel@tonic-gateEOF
804*0Sstevel@tonic-gate		}
805*0Sstevel@tonic-gate	    } elsif ($action =~ /^[er]/i) { # <E>dit, <R>e-edit
806*0Sstevel@tonic-gate		# edit the message
807*0Sstevel@tonic-gate		Edit();
808*0Sstevel@tonic-gate	    } elsif ($action =~ /^[qc]/i) { # <C>ancel, <Q>uit
809*0Sstevel@tonic-gate		Cancel();
810*0Sstevel@tonic-gate	    } elsif ($action =~ /^s/i) {
811*0Sstevel@tonic-gate		paraprint <<EOF;
812*0Sstevel@tonic-gateI'm sorry, but I didn't understand that. Please type "send" or "save".
813*0Sstevel@tonic-gateEOF
814*0Sstevel@tonic-gate	    }
815*0Sstevel@tonic-gate	}
816*0Sstevel@tonic-gate    }
817*0Sstevel@tonic-gate} # sub NowWhat
818*0Sstevel@tonic-gate
819*0Sstevel@tonic-gatesub TrivialSubject {
820*0Sstevel@tonic-gate    my $subject = shift;
821*0Sstevel@tonic-gate    if ($subject =~
822*0Sstevel@tonic-gate	/^(y(es)?|no?|help|perl( (bug|problem))?|bug|problem)$/i ||
823*0Sstevel@tonic-gate	length($subject) < 4 ||
824*0Sstevel@tonic-gate	$subject !~ /\s/) {
825*0Sstevel@tonic-gate	print "\nThat doesn't look like a good subject.  Please be more verbose.\n\n";
826*0Sstevel@tonic-gate        return 1;
827*0Sstevel@tonic-gate    } else {
828*0Sstevel@tonic-gate	return 0;
829*0Sstevel@tonic-gate    }
830*0Sstevel@tonic-gate}
831*0Sstevel@tonic-gate
832*0Sstevel@tonic-gatesub Send {
833*0Sstevel@tonic-gate    # Message has been accepted for transmission -- Send the message
834*0Sstevel@tonic-gate    if ($outfile) {
835*0Sstevel@tonic-gate	open SENDMAIL, ">$outfile" or die "Couldn't open '$outfile': $!\n";
836*0Sstevel@tonic-gate	goto sendout;
837*0Sstevel@tonic-gate    }
838*0Sstevel@tonic-gate
839*0Sstevel@tonic-gate    # on linux certain mail implementations won't accept the subject
840*0Sstevel@tonic-gate    # as "~s subject" and thus the Subject header will be corrupted
841*0Sstevel@tonic-gate    # so don't use Mail::Send to be safe
842*0Sstevel@tonic-gate    if ($::HaveSend && !$Is_Linux && !$Is_OpenBSD) {
843*0Sstevel@tonic-gate	$msg = new Mail::Send Subject => $subject, To => $address;
844*0Sstevel@tonic-gate	$msg->cc($cc) if $cc;
845*0Sstevel@tonic-gate	$msg->add("Reply-To",$from) if $from;
846*0Sstevel@tonic-gate
847*0Sstevel@tonic-gate	$fh = $msg->open;
848*0Sstevel@tonic-gate	open(REP, "<$filename") or die "Couldn't open `$filename': $!\n";
849*0Sstevel@tonic-gate	while (<REP>) { print $fh $_ }
850*0Sstevel@tonic-gate	close(REP) or die "Error closing $filename: $!";
851*0Sstevel@tonic-gate	$fh->close;
852*0Sstevel@tonic-gate
853*0Sstevel@tonic-gate	print "\nMessage sent.\n";
854*0Sstevel@tonic-gate    } elsif ($Is_VMS) {
855*0Sstevel@tonic-gate	if ( ($address =~ /@/ and $address !~ /^\w+%"/) or
856*0Sstevel@tonic-gate	     ($cc      =~ /@/ and $cc      !~ /^\w+%"/) ) {
857*0Sstevel@tonic-gate	    my $prefix;
858*0Sstevel@tonic-gate	    foreach (qw[ IN MX SMTP UCX PONY WINS ], '') {
859*0Sstevel@tonic-gate		$prefix = "$_%", last if $ENV{"MAIL\$PROTOCOL_$_"};
860*0Sstevel@tonic-gate	    }
861*0Sstevel@tonic-gate	    $address = qq[${prefix}"$address"] unless $address =~ /^\w+%"/;
862*0Sstevel@tonic-gate	    $cc = qq[${prefix}"$cc"] unless !$cc || $cc =~ /^\w+%"/;
863*0Sstevel@tonic-gate	}
864*0Sstevel@tonic-gate	$subject =~ s/"/""/g; $address =~ s/"/""/g; $cc =~ s/"/""/g;
865*0Sstevel@tonic-gate	my $sts = system(qq[mail/Subject="$subject" $filename. "$address","$cc"]);
866*0Sstevel@tonic-gate	if ($sts) {
867*0Sstevel@tonic-gate	    die <<EOF;
868*0Sstevel@tonic-gateCan't spawn off mail
869*0Sstevel@tonic-gate	(leaving bug report in $filename): $sts
870*0Sstevel@tonic-gateEOF
871*0Sstevel@tonic-gate	}
872*0Sstevel@tonic-gate    } else {
873*0Sstevel@tonic-gate	my $sendmail = "";
874*0Sstevel@tonic-gate	for (qw(/usr/lib/sendmail /usr/sbin/sendmail /usr/ucblib/sendmail)) {
875*0Sstevel@tonic-gate	    $sendmail = $_, last if -e $_;
876*0Sstevel@tonic-gate	}
877*0Sstevel@tonic-gate	if ($^O eq 'os2' and $sendmail eq "") {
878*0Sstevel@tonic-gate	    my $path = $ENV{PATH};
879*0Sstevel@tonic-gate	    $path =~ s:\\:/: ;
880*0Sstevel@tonic-gate	    my @path = split /$Config{'path_sep'}/, $path;
881*0Sstevel@tonic-gate	    for (@path) {
882*0Sstevel@tonic-gate		$sendmail = "$_/sendmail", last if -e "$_/sendmail";
883*0Sstevel@tonic-gate		$sendmail = "$_/sendmail.exe", last if -e "$_/sendmail.exe";
884*0Sstevel@tonic-gate	    }
885*0Sstevel@tonic-gate	}
886*0Sstevel@tonic-gate
887*0Sstevel@tonic-gate	paraprint(<<"EOF"), die "\n" if $sendmail eq "";
888*0Sstevel@tonic-gateI am terribly sorry, but I cannot find sendmail, or a close equivalent, and
889*0Sstevel@tonic-gatethe perl package Mail::Send has not been installed, so I can't send your bug
890*0Sstevel@tonic-gatereport. We apologize for the inconvenience.
891*0Sstevel@tonic-gate
892*0Sstevel@tonic-gateSo you may attempt to find some way of sending your message, it has
893*0Sstevel@tonic-gatebeen left in the file `$filename'.
894*0Sstevel@tonic-gateEOF
895*0Sstevel@tonic-gate	open(SENDMAIL, "|$sendmail -t -oi") || die "'|$sendmail -t -oi' failed: $!";
896*0Sstevel@tonic-gatesendout:
897*0Sstevel@tonic-gate	print SENDMAIL "To: $address\n";
898*0Sstevel@tonic-gate	print SENDMAIL "Subject: $subject\n";
899*0Sstevel@tonic-gate	print SENDMAIL "Cc: $cc\n" if $cc;
900*0Sstevel@tonic-gate	print SENDMAIL "Reply-To: $from\n" if $from;
901*0Sstevel@tonic-gate	print SENDMAIL "Message-Id: $messageid\n" if $messageid;
902*0Sstevel@tonic-gate	print SENDMAIL "\n\n";
903*0Sstevel@tonic-gate	open(REP, "<$filename") or die "Couldn't open `$filename': $!\n";
904*0Sstevel@tonic-gate	while (<REP>) { print SENDMAIL $_ }
905*0Sstevel@tonic-gate	close(REP) or die "Error closing $filename: $!";
906*0Sstevel@tonic-gate
907*0Sstevel@tonic-gate	if (close(SENDMAIL)) {
908*0Sstevel@tonic-gate	    printf "\nMessage %s.\n", $outfile ? "saved" : "sent";
909*0Sstevel@tonic-gate	} else {
910*0Sstevel@tonic-gate	    warn "\nSendmail returned status '", $? >> 8, "'\n";
911*0Sstevel@tonic-gate	}
912*0Sstevel@tonic-gate    }
913*0Sstevel@tonic-gate    1 while unlink($filename);  # remove all versions under VMS
914*0Sstevel@tonic-gate} # sub Send
915*0Sstevel@tonic-gate
916*0Sstevel@tonic-gatesub Help {
917*0Sstevel@tonic-gate    print <<EOF;
918*0Sstevel@tonic-gate
919*0Sstevel@tonic-gateA program to help generate bug reports about perl5, and mail them.
920*0Sstevel@tonic-gateIt is designed to be used interactively. Normally no arguments will
921*0Sstevel@tonic-gatebe needed.
922*0Sstevel@tonic-gate
923*0Sstevel@tonic-gateUsage:
924*0Sstevel@tonic-gate$0  [-v] [-a address] [-s subject] [-b body | -f inpufile ] [ -F outputfile ]
925*0Sstevel@tonic-gate    [-r returnaddress] [-e editor] [-c adminaddress | -C] [-S] [-t] [-h]
926*0Sstevel@tonic-gate$0  [-v] [-r returnaddress] [-A] [-ok | -okay | -nok | -nokay]
927*0Sstevel@tonic-gate
928*0Sstevel@tonic-gateSimplest usage:  run "$0", and follow the prompts.
929*0Sstevel@tonic-gate
930*0Sstevel@tonic-gateOptions:
931*0Sstevel@tonic-gate
932*0Sstevel@tonic-gate  -v    Include Verbose configuration data in the report
933*0Sstevel@tonic-gate  -f    File containing the body of the report. Use this to
934*0Sstevel@tonic-gate        quickly send a prepared message.
935*0Sstevel@tonic-gate  -F    File to output the resulting mail message to, instead of mailing.
936*0Sstevel@tonic-gate  -S    Send without asking for confirmation.
937*0Sstevel@tonic-gate  -a    Address to send the report to. Defaults to `$address'.
938*0Sstevel@tonic-gate  -c    Address to send copy of report to. Defaults to `$cc'.
939*0Sstevel@tonic-gate  -C    Don't send copy to administrator.
940*0Sstevel@tonic-gate  -s    Subject to include with the message. You will be prompted
941*0Sstevel@tonic-gate        if you don't supply one on the command line.
942*0Sstevel@tonic-gate  -b    Body of the report. If not included on the command line, or
943*0Sstevel@tonic-gate        in a file with -f, you will get a chance to edit the message.
944*0Sstevel@tonic-gate  -r    Your return address. The program will ask you to confirm
945*0Sstevel@tonic-gate        this if you don't give it here.
946*0Sstevel@tonic-gate  -e    Editor to use.
947*0Sstevel@tonic-gate  -t    Test mode. The target address defaults to `$testaddress'.
948*0Sstevel@tonic-gate  -d    Data mode.  This prints out your configuration data, without mailing
949*0Sstevel@tonic-gate        anything. You can use this with -v to get more complete data.
950*0Sstevel@tonic-gate  -A    Don't send a bug received acknowledgement to the return address.
951*0Sstevel@tonic-gate  -ok   Report successful build on this system to perl porters
952*0Sstevel@tonic-gate        (use alone or with -v). Only use -ok if *everything* was ok:
953*0Sstevel@tonic-gate        if there were *any* problems at all, use -nok.
954*0Sstevel@tonic-gate  -okay As -ok but allow report from old builds.
955*0Sstevel@tonic-gate  -nok  Report unsuccessful build on this system to perl porters
956*0Sstevel@tonic-gate        (use alone or with -v). You must describe what went wrong
957*0Sstevel@tonic-gate        in the body of the report which you will be asked to edit.
958*0Sstevel@tonic-gate  -nokay As -nok but allow report from old builds.
959*0Sstevel@tonic-gate  -h    Print this help message.
960*0Sstevel@tonic-gate
961*0Sstevel@tonic-gateEOF
962*0Sstevel@tonic-gate}
963*0Sstevel@tonic-gate
964*0Sstevel@tonic-gatesub filename {
965*0Sstevel@tonic-gate    if ($::HaveTemp) {
966*0Sstevel@tonic-gate	# Good. Use a secure temp file
967*0Sstevel@tonic-gate	my ($fh, $filename) = File::Temp::tempfile(UNLINK => 1);
968*0Sstevel@tonic-gate	close($fh);
969*0Sstevel@tonic-gate	return $filename;
970*0Sstevel@tonic-gate    } else {
971*0Sstevel@tonic-gate	# Bah. Fall back to doing things less securely.
972*0Sstevel@tonic-gate	my $dir = File::Spec->tmpdir();
973*0Sstevel@tonic-gate	$filename = "bugrep0$$";
974*0Sstevel@tonic-gate	$filename++ while -e File::Spec->catfile($dir, $filename);
975*0Sstevel@tonic-gate	$filename = File::Spec->catfile($dir, $filename);
976*0Sstevel@tonic-gate    }
977*0Sstevel@tonic-gate}
978*0Sstevel@tonic-gate
979*0Sstevel@tonic-gatesub paraprint {
980*0Sstevel@tonic-gate    my @paragraphs = split /\n{2,}/, "@_";
981*0Sstevel@tonic-gate    print "\n\n";
982*0Sstevel@tonic-gate    for (@paragraphs) {   # implicit local $_
983*0Sstevel@tonic-gate	s/(\S)\s*\n/$1 /g;
984*0Sstevel@tonic-gate	write;
985*0Sstevel@tonic-gate	print "\n";
986*0Sstevel@tonic-gate    }
987*0Sstevel@tonic-gate}
988*0Sstevel@tonic-gate
989*0Sstevel@tonic-gateformat STDOUT =
990*0Sstevel@tonic-gate^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
991*0Sstevel@tonic-gate$_
992*0Sstevel@tonic-gate.
993*0Sstevel@tonic-gate
994*0Sstevel@tonic-gate__END__
995*0Sstevel@tonic-gate
996*0Sstevel@tonic-gate=head1 NAME
997*0Sstevel@tonic-gate
998*0Sstevel@tonic-gateperlbug - how to submit bug reports on Perl
999*0Sstevel@tonic-gate
1000*0Sstevel@tonic-gate=head1 SYNOPSIS
1001*0Sstevel@tonic-gate
1002*0Sstevel@tonic-gateB<perlbug> S<[ B<-v> ]> S<[ B<-a> I<address> ]> S<[ B<-s> I<subject> ]>
1003*0Sstevel@tonic-gateS<[ B<-b> I<body> | B<-f> I<inputfile> ]> S<[ B<-F> I<outputfile> ]>
1004*0Sstevel@tonic-gateS<[ B<-r> I<returnaddress> ]>
1005*0Sstevel@tonic-gateS<[ B<-e> I<editor> ]> S<[ B<-c> I<adminaddress> | B<-C> ]>
1006*0Sstevel@tonic-gateS<[ B<-S> ]> S<[ B<-t> ]>  S<[ B<-d> ]>  S<[ B<-A> ]>  S<[ B<-h> ]>
1007*0Sstevel@tonic-gate
1008*0Sstevel@tonic-gateB<perlbug> S<[ B<-v> ]> S<[ B<-r> I<returnaddress> ]>
1009*0Sstevel@tonic-gate S<[ B<-A> ]> S<[ B<-ok> | B<-okay> | B<-nok> | B<-nokay> ]>
1010*0Sstevel@tonic-gate
1011*0Sstevel@tonic-gate=head1 DESCRIPTION
1012*0Sstevel@tonic-gate
1013*0Sstevel@tonic-gateA program to help generate bug reports about perl or the modules that
1014*0Sstevel@tonic-gatecome with it, and mail them.
1015*0Sstevel@tonic-gate
1016*0Sstevel@tonic-gateIf you have found a bug with a non-standard port (one that was not part
1017*0Sstevel@tonic-gateof the I<standard distribution>), a binary distribution, or a
1018*0Sstevel@tonic-gatenon-standard module (such as Tk, CGI, etc), then please see the
1019*0Sstevel@tonic-gatedocumentation that came with that distribution to determine the correct
1020*0Sstevel@tonic-gateplace to report bugs.
1021*0Sstevel@tonic-gate
1022*0Sstevel@tonic-gateC<perlbug> is designed to be used interactively. Normally no arguments
1023*0Sstevel@tonic-gatewill be needed.  Simply run it, and follow the prompts.
1024*0Sstevel@tonic-gate
1025*0Sstevel@tonic-gateIf you are unable to run B<perlbug> (most likely because you don't have
1026*0Sstevel@tonic-gatea working setup to send mail that perlbug recognizes), you may have to
1027*0Sstevel@tonic-gatecompose your own report, and email it to B<perlbug@perl.org>.  You might
1028*0Sstevel@tonic-gatefind the B<-d> option useful to get summary information in that case.
1029*0Sstevel@tonic-gate
1030*0Sstevel@tonic-gateIn any case, when reporting a bug, please make sure you have run through
1031*0Sstevel@tonic-gatethis checklist:
1032*0Sstevel@tonic-gate
1033*0Sstevel@tonic-gate=over 4
1034*0Sstevel@tonic-gate
1035*0Sstevel@tonic-gate=item What version of Perl you are running?
1036*0Sstevel@tonic-gate
1037*0Sstevel@tonic-gateType C<perl -v> at the command line to find out.
1038*0Sstevel@tonic-gate
1039*0Sstevel@tonic-gate=item Are you running the latest released version of perl?
1040*0Sstevel@tonic-gate
1041*0Sstevel@tonic-gateLook at http://www.perl.com/ to find out.  If it is not the latest
1042*0Sstevel@tonic-gatereleased version, get that one and see whether your bug has been
1043*0Sstevel@tonic-gatefixed.  Note that bug reports about old versions of Perl, especially
1044*0Sstevel@tonic-gatethose prior to the 5.0 release, are likely to fall upon deaf ears.
1045*0Sstevel@tonic-gateYou are on your own if you continue to use perl1 .. perl4.
1046*0Sstevel@tonic-gate
1047*0Sstevel@tonic-gate=item Are you sure what you have is a bug?
1048*0Sstevel@tonic-gate
1049*0Sstevel@tonic-gateA significant number of the bug reports we get turn out to be documented
1050*0Sstevel@tonic-gatefeatures in Perl.  Make sure the behavior you are witnessing doesn't fall
1051*0Sstevel@tonic-gateunder that category, by glancing through the documentation that comes
1052*0Sstevel@tonic-gatewith Perl (we'll admit this is no mean task, given the sheer volume of
1053*0Sstevel@tonic-gateit all, but at least have a look at the sections that I<seem> relevant).
1054*0Sstevel@tonic-gate
1055*0Sstevel@tonic-gateBe aware of the familiar traps that perl programmers of various hues
1056*0Sstevel@tonic-gatefall into.  See L<perltrap>.
1057*0Sstevel@tonic-gate
1058*0Sstevel@tonic-gateCheck in L<perldiag> to see what any Perl error message(s) mean.
1059*0Sstevel@tonic-gateIf message isn't in perldiag, it probably isn't generated by Perl.
1060*0Sstevel@tonic-gateConsult your operating system documentation instead.
1061*0Sstevel@tonic-gate
1062*0Sstevel@tonic-gateIf you are on a non-UNIX platform check also L<perlport>, as some
1063*0Sstevel@tonic-gatefeatures may be unimplemented or work differently.
1064*0Sstevel@tonic-gate
1065*0Sstevel@tonic-gateTry to study the problem under the Perl debugger, if necessary.
1066*0Sstevel@tonic-gateSee L<perldebug>.
1067*0Sstevel@tonic-gate
1068*0Sstevel@tonic-gate=item Do you have a proper test case?
1069*0Sstevel@tonic-gate
1070*0Sstevel@tonic-gateThe easier it is to reproduce your bug, the more likely it will be
1071*0Sstevel@tonic-gatefixed, because if no one can duplicate the problem, no one can fix it.
1072*0Sstevel@tonic-gateA good test case has most of these attributes: fewest possible number
1073*0Sstevel@tonic-gateof lines; few dependencies on external commands, modules, or
1074*0Sstevel@tonic-gatelibraries; runs on most platforms unimpeded; and is self-documenting.
1075*0Sstevel@tonic-gate
1076*0Sstevel@tonic-gateA good test case is almost always a good candidate to be on the perl
1077*0Sstevel@tonic-gatetest suite.  If you have the time, consider making your test case so
1078*0Sstevel@tonic-gatethat it will readily fit into the standard test suite.
1079*0Sstevel@tonic-gate
1080*0Sstevel@tonic-gateRemember also to include the B<exact> error messages, if any.
1081*0Sstevel@tonic-gate"Perl complained something" is not an exact error message.
1082*0Sstevel@tonic-gate
1083*0Sstevel@tonic-gateIf you get a core dump (or equivalent), you may use a debugger
1084*0Sstevel@tonic-gate(B<dbx>, B<gdb>, etc) to produce a stack trace to include in the bug
1085*0Sstevel@tonic-gatereport.  NOTE: unless your Perl has been compiled with debug info
1086*0Sstevel@tonic-gate(often B<-g>), the stack trace is likely to be somewhat hard to use
1087*0Sstevel@tonic-gatebecause it will most probably contain only the function names and not
1088*0Sstevel@tonic-gatetheir arguments.  If possible, recompile your Perl with debug info and
1089*0Sstevel@tonic-gatereproduce the dump and the stack trace.
1090*0Sstevel@tonic-gate
1091*0Sstevel@tonic-gate=item Can you describe the bug in plain English?
1092*0Sstevel@tonic-gate
1093*0Sstevel@tonic-gateThe easier it is to understand a reproducible bug, the more likely it
1094*0Sstevel@tonic-gatewill be fixed.  Anything you can provide by way of insight into the
1095*0Sstevel@tonic-gateproblem helps a great deal.  In other words, try to analyze the
1096*0Sstevel@tonic-gateproblem (to the extent you can) and report your discoveries.
1097*0Sstevel@tonic-gate
1098*0Sstevel@tonic-gate=item Can you fix the bug yourself?
1099*0Sstevel@tonic-gate
1100*0Sstevel@tonic-gateA bug report which I<includes a patch to fix it> will almost
1101*0Sstevel@tonic-gatedefinitely be fixed.  Use the C<diff> program to generate your patches
1102*0Sstevel@tonic-gate(C<diff> is being maintained by the GNU folks as part of the B<diffutils>
1103*0Sstevel@tonic-gatepackage, so you should be able to get it from any of the GNU software
1104*0Sstevel@tonic-gaterepositories).  If you do submit a patch, the cool-dude counter at
1105*0Sstevel@tonic-gateperlbug@perl.org will register you as a savior of the world.  Your
1106*0Sstevel@tonic-gatepatch may be returned with requests for changes, or requests for more
1107*0Sstevel@tonic-gatedetailed explanations about your fix.
1108*0Sstevel@tonic-gate
1109*0Sstevel@tonic-gateHere are some clues for creating quality patches: Use the B<-c> or
1110*0Sstevel@tonic-gateB<-u> switches to the diff program (to create a so-called context or
1111*0Sstevel@tonic-gateunified diff).  Make sure the patch is not reversed (the first
1112*0Sstevel@tonic-gateargument to diff is typically the original file, the second argument
1113*0Sstevel@tonic-gateyour changed file).  Make sure you test your patch by applying it with
1114*0Sstevel@tonic-gatethe C<patch> program before you send it on its way.  Try to follow the
1115*0Sstevel@tonic-gatesame style as the code you are trying to patch.  Make sure your patch
1116*0Sstevel@tonic-gatereally does work (C<make test>, if the thing you're patching supports
1117*0Sstevel@tonic-gateit).
1118*0Sstevel@tonic-gate
1119*0Sstevel@tonic-gate=item Can you use C<perlbug> to submit the report?
1120*0Sstevel@tonic-gate
1121*0Sstevel@tonic-gateB<perlbug> will, amongst other things, ensure your report includes
1122*0Sstevel@tonic-gatecrucial information about your version of perl.  If C<perlbug> is unable
1123*0Sstevel@tonic-gateto mail your report after you have typed it in, you may have to compose
1124*0Sstevel@tonic-gatethe message yourself, add the output produced by C<perlbug -d> and email
1125*0Sstevel@tonic-gateit to B<perlbug@perl.org>.  If, for some reason, you cannot run
1126*0Sstevel@tonic-gateC<perlbug> at all on your system, be sure to include the entire output
1127*0Sstevel@tonic-gateproduced by running C<perl -V> (note the uppercase V).
1128*0Sstevel@tonic-gate
1129*0Sstevel@tonic-gateWhether you use C<perlbug> or send the email manually, please make
1130*0Sstevel@tonic-gateyour Subject line informative.  "a bug" not informative.  Neither is
1131*0Sstevel@tonic-gate"perl crashes" nor "HELP!!!".  These don't help.
1132*0Sstevel@tonic-gateA compact description of what's wrong is fine.
1133*0Sstevel@tonic-gate
1134*0Sstevel@tonic-gate=back
1135*0Sstevel@tonic-gate
1136*0Sstevel@tonic-gateHaving done your bit, please be prepared to wait, to be told the bug
1137*0Sstevel@tonic-gateis in your code, or even to get no reply at all.  The Perl maintainers
1138*0Sstevel@tonic-gateare busy folks, so if your problem is a small one or if it is difficult
1139*0Sstevel@tonic-gateto understand or already known, they may not respond with a personal reply.
1140*0Sstevel@tonic-gateIf it is important to you that your bug be fixed, do monitor the
1141*0Sstevel@tonic-gateC<Changes> file in any development releases since the time you submitted
1142*0Sstevel@tonic-gatethe bug, and encourage the maintainers with kind words (but never any
1143*0Sstevel@tonic-gateflames!).  Feel free to resend your bug report if the next released
1144*0Sstevel@tonic-gateversion of perl comes out and your bug is still present.
1145*0Sstevel@tonic-gate
1146*0Sstevel@tonic-gate=head1 OPTIONS
1147*0Sstevel@tonic-gate
1148*0Sstevel@tonic-gate=over 8
1149*0Sstevel@tonic-gate
1150*0Sstevel@tonic-gate=item B<-a>
1151*0Sstevel@tonic-gate
1152*0Sstevel@tonic-gateAddress to send the report to.  Defaults to B<perlbug@perl.org>.
1153*0Sstevel@tonic-gate
1154*0Sstevel@tonic-gate=item B<-A>
1155*0Sstevel@tonic-gate
1156*0Sstevel@tonic-gateDon't send a bug received acknowledgement to the reply address.
1157*0Sstevel@tonic-gateGenerally it is only a sensible to use this option if you are a
1158*0Sstevel@tonic-gateperl maintainer actively watching perl porters for your message to
1159*0Sstevel@tonic-gatearrive.
1160*0Sstevel@tonic-gate
1161*0Sstevel@tonic-gate=item B<-b>
1162*0Sstevel@tonic-gate
1163*0Sstevel@tonic-gateBody of the report.  If not included on the command line, or
1164*0Sstevel@tonic-gatein a file with B<-f>, you will get a chance to edit the message.
1165*0Sstevel@tonic-gate
1166*0Sstevel@tonic-gate=item B<-C>
1167*0Sstevel@tonic-gate
1168*0Sstevel@tonic-gateDon't send copy to administrator.
1169*0Sstevel@tonic-gate
1170*0Sstevel@tonic-gate=item B<-c>
1171*0Sstevel@tonic-gate
1172*0Sstevel@tonic-gateAddress to send copy of report to.  Defaults to the address of the
1173*0Sstevel@tonic-gatelocal perl administrator (recorded when perl was built).
1174*0Sstevel@tonic-gate
1175*0Sstevel@tonic-gate=item B<-d>
1176*0Sstevel@tonic-gate
1177*0Sstevel@tonic-gateData mode (the default if you redirect or pipe output).  This prints out
1178*0Sstevel@tonic-gateyour configuration data, without mailing anything.  You can use this
1179*0Sstevel@tonic-gatewith B<-v> to get more complete data.
1180*0Sstevel@tonic-gate
1181*0Sstevel@tonic-gate=item B<-e>
1182*0Sstevel@tonic-gate
1183*0Sstevel@tonic-gateEditor to use.
1184*0Sstevel@tonic-gate
1185*0Sstevel@tonic-gate=item B<-f>
1186*0Sstevel@tonic-gate
1187*0Sstevel@tonic-gateFile containing the body of the report.  Use this to quickly send a
1188*0Sstevel@tonic-gateprepared message.
1189*0Sstevel@tonic-gate
1190*0Sstevel@tonic-gate=item B<-F>
1191*0Sstevel@tonic-gate
1192*0Sstevel@tonic-gateFile to output the results to instead of sending as an email. Useful
1193*0Sstevel@tonic-gateparticularly when running perlbug on a machine with no direct internet
1194*0Sstevel@tonic-gateconnection.
1195*0Sstevel@tonic-gate
1196*0Sstevel@tonic-gate=item B<-h>
1197*0Sstevel@tonic-gate
1198*0Sstevel@tonic-gatePrints a brief summary of the options.
1199*0Sstevel@tonic-gate
1200*0Sstevel@tonic-gate=item B<-ok>
1201*0Sstevel@tonic-gate
1202*0Sstevel@tonic-gateReport successful build on this system to perl porters. Forces B<-S>
1203*0Sstevel@tonic-gateand B<-C>. Forces and supplies values for B<-s> and B<-b>. Only
1204*0Sstevel@tonic-gateprompts for a return address if it cannot guess it (for use with
1205*0Sstevel@tonic-gateB<make>). Honors return address specified with B<-r>.  You can use this
1206*0Sstevel@tonic-gatewith B<-v> to get more complete data.   Only makes a report if this
1207*0Sstevel@tonic-gatesystem is less than 60 days old.
1208*0Sstevel@tonic-gate
1209*0Sstevel@tonic-gate=item B<-okay>
1210*0Sstevel@tonic-gate
1211*0Sstevel@tonic-gateAs B<-ok> except it will report on older systems.
1212*0Sstevel@tonic-gate
1213*0Sstevel@tonic-gate=item B<-nok>
1214*0Sstevel@tonic-gate
1215*0Sstevel@tonic-gateReport unsuccessful build on this system.  Forces B<-C>.  Forces and
1216*0Sstevel@tonic-gatesupplies a value for B<-s>, then requires you to edit the report
1217*0Sstevel@tonic-gateand say what went wrong.  Alternatively, a prepared report may be
1218*0Sstevel@tonic-gatesupplied using B<-f>.  Only prompts for a return address if it
1219*0Sstevel@tonic-gatecannot guess it (for use with B<make>). Honors return address
1220*0Sstevel@tonic-gatespecified with B<-r>.  You can use this with B<-v> to get more
1221*0Sstevel@tonic-gatecomplete data.  Only makes a report if this system is less than 60
1222*0Sstevel@tonic-gatedays old.
1223*0Sstevel@tonic-gate
1224*0Sstevel@tonic-gate=item B<-nokay>
1225*0Sstevel@tonic-gate
1226*0Sstevel@tonic-gateAs B<-nok> except it will report on older systems.
1227*0Sstevel@tonic-gate
1228*0Sstevel@tonic-gate=item B<-r>
1229*0Sstevel@tonic-gate
1230*0Sstevel@tonic-gateYour return address.  The program will ask you to confirm its default
1231*0Sstevel@tonic-gateif you don't use this option.
1232*0Sstevel@tonic-gate
1233*0Sstevel@tonic-gate=item B<-S>
1234*0Sstevel@tonic-gate
1235*0Sstevel@tonic-gateSend without asking for confirmation.
1236*0Sstevel@tonic-gate
1237*0Sstevel@tonic-gate=item B<-s>
1238*0Sstevel@tonic-gate
1239*0Sstevel@tonic-gateSubject to include with the message.  You will be prompted if you don't
1240*0Sstevel@tonic-gatesupply one on the command line.
1241*0Sstevel@tonic-gate
1242*0Sstevel@tonic-gate=item B<-t>
1243*0Sstevel@tonic-gate
1244*0Sstevel@tonic-gateTest mode.  The target address defaults to B<perlbug-test@perl.org>.
1245*0Sstevel@tonic-gate
1246*0Sstevel@tonic-gate=item B<-v>
1247*0Sstevel@tonic-gate
1248*0Sstevel@tonic-gateInclude verbose configuration data in the report.
1249*0Sstevel@tonic-gate
1250*0Sstevel@tonic-gate=back
1251*0Sstevel@tonic-gate
1252*0Sstevel@tonic-gate=head1 AUTHORS
1253*0Sstevel@tonic-gate
1254*0Sstevel@tonic-gateKenneth Albanowski (E<lt>kjahds@kjahds.comE<gt>), subsequently I<doc>tored
1255*0Sstevel@tonic-gateby Gurusamy Sarathy (E<lt>gsar@activestate.comE<gt>), Tom Christiansen
1256*0Sstevel@tonic-gate(E<lt>tchrist@perl.comE<gt>), Nathan Torkington (E<lt>gnat@frii.comE<gt>),
1257*0Sstevel@tonic-gateCharles F. Randall (E<lt>cfr@pobox.comE<gt>), Mike Guy
1258*0Sstevel@tonic-gate(E<lt>mjtg@cam.a.ukE<gt>), Dominic Dunlop (E<lt>domo@computer.orgE<gt>),
1259*0Sstevel@tonic-gateHugo van der Sanden (E<lt>hv@crypt.org<gt>),
1260*0Sstevel@tonic-gateJarkko Hietaniemi (E<lt>jhi@iki.fiE<gt>), Chris Nandor
1261*0Sstevel@tonic-gate(E<lt>pudge@pobox.comE<gt>), Jon Orwant (E<lt>orwant@media.mit.eduE<gt>,
1262*0Sstevel@tonic-gateand Richard Foley (E<lt>richard@rfi.netE<gt>).
1263*0Sstevel@tonic-gate
1264*0Sstevel@tonic-gate=head1 SEE ALSO
1265*0Sstevel@tonic-gate
1266*0Sstevel@tonic-gateperl(1), perldebug(1), perldiag(1), perlport(1), perltrap(1),
1267*0Sstevel@tonic-gatediff(1), patch(1), dbx(1), gdb(1)
1268*0Sstevel@tonic-gate
1269*0Sstevel@tonic-gate=head1 BUGS
1270*0Sstevel@tonic-gate
1271*0Sstevel@tonic-gateNone known (guess what must have been used to report them?)
1272*0Sstevel@tonic-gate
1273*0Sstevel@tonic-gate=cut
1274*0Sstevel@tonic-gate
1275*0Sstevel@tonic-gate!NO!SUBS!
1276*0Sstevel@tonic-gate
1277*0Sstevel@tonic-gateclose OUT or die "Can't close $file: $!";
1278*0Sstevel@tonic-gatechmod 0755, $file or die "Can't reset permissions for $file: $!\n";
1279*0Sstevel@tonic-gateexec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
1280*0Sstevel@tonic-gatechdir $origdir;
1281