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