xref: /openbsd-src/gnu/usr.bin/perl/utils/perlbug.PL (revision fac98b93b71777a71b1e912ccaf68ce33d7b87c4)
1#!/usr/local/bin/perl
2
3use strict;
4use warnings;
5
6use Config;
7use File::Basename qw(&basename &dirname);
8use Cwd;
9use File::Spec::Functions;
10
11# List explicitly here the variables you want Configure to
12# generate.  Metaconfig only looks for shell variables, so you
13# have to mention them as if they were shell variables, not
14# %Config entries.  Thus you write
15#  $startperl
16# to ensure Configure will look for $Config{startperl}.
17#  $perlpath
18
19# This forces PL files to create target in same directory as PL file.
20# This is so that make depend always knows where to find PL derivatives.
21my $origdir = cwd;
22chdir dirname($0);
23my $file = basename($0, '.PL');
24$file .= '.com' if $^O eq 'VMS';
25
26open OUT, ">", $file or die "Can't create $file: $!";
27
28# get patchlevel.h timestamp
29
30-e catfile(updir, "patchlevel.h")
31    or die "Can't find patchlevel.h: $!";
32
33my $patchlevel_date = (stat _)[9];
34
35# TO DO (perhaps): store/embed $Config::config_sh into perlbug. When perlbug is
36# used, compare $Config::config_sh with the stored version. If they differ then
37# append a list of individual differences to the bug report.
38
39
40print "Extracting $file (with variable substitutions)\n";
41
42# In this section, perl variables will be expanded during extraction.
43# You can use $Config{...} to use Configure variables.
44
45my $extract_version = sprintf("%vd", $^V);
46
47print OUT <<"!GROK!THIS!";
48$Config{startperl}
49    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
50	if 0; # ^ Run only under a shell
51
52my \$config_tag1 = '$extract_version - $Config{cf_time}';
53
54my \$patchlevel_date = $patchlevel_date;
55!GROK!THIS!
56
57# In the following, perl variables are not expanded during extraction.
58
59print OUT <<'!NO!SUBS!';
60my @patches = Config::local_patches();
61my $patch_tags = join "", map /(\S+)/ ? "+$1 " : (), @patches;
62
63BEGIN { pop @INC if $INC[-1] eq '.' }
64use warnings;
65use strict;
66use Config;
67use File::Spec;		# keep perlbug Perl 5.005 compatible
68use Getopt::Std;
69use File::Basename 'basename';
70
71$Getopt::Std::STANDARD_HELP_VERSION = 1;
72
73sub paraprint;
74
75BEGIN {
76    eval { require Mail::Send;};
77    $::HaveSend = ($@ eq "");
78    eval { require Mail::Util; } ;
79    $::HaveUtil = ($@ eq "");
80    # use secure tempfiles wherever possible
81    eval { require File::Temp; };
82    $::HaveTemp = ($@ eq "");
83    eval { require Module::CoreList; };
84    $::HaveCoreList = ($@ eq "");
85    eval { require Text::Wrap; };
86    $::HaveWrap = ($@ eq "");
87};
88
89our $VERSION = "1.43";
90
91#TODO:
92#       make sure failure (transmission-wise) of Mail::Send is accounted for.
93#       (This may work now. Unsure of the original author's issue -JESSE 2008-06-08)
94#       - Test -b option
95
96my( $file, $usefile, $cc, $address, $thanksaddress,
97    $filename, $messageid, $domain, $subject, $from, $verbose, $ed, $outfile,
98    $fh, $me, $body, $andcc, %REP, $ok, $thanks, $progname,
99    $Is_MSWin32, $Is_Linux, $Is_VMS, $Is_OpenBSD,
100    $report_about_module, $category, $severity,
101    %opt, $have_attachment, $attachments, $has_patch, $mime_boundary
102);
103
104my $running_noninteractively = !-t STDIN;
105
106my $perl_version = $^V ? sprintf("%vd", $^V) : $];
107
108my $config_tag2 = "$perl_version - $Config{cf_time}";
109
110Init();
111
112if ($opt{h}) { Help(); exit; }
113if ($opt{d}) { Dump(*STDOUT); exit; }
114if ($running_noninteractively && !$opt{t} && !($ok and not $opt{n})) {
115    paraprint <<"EOF";
116Please use $progname interactively. If you want to
117include a file, you can use the -f switch.
118EOF
119    die "\n";
120}
121
122Query();
123Edit() unless $usefile || ($ok and not $opt{n});
124NowWhat();
125if ($address) {
126    Send();
127    if ($thanks) {
128	print "\nThank you for taking the time to send a thank-you message!\n\n";
129
130	paraprint <<EOF
131Please note that mailing lists are moderated, your message may take a while to
132show up.
133EOF
134    } else {
135	print "\nThank you for taking the time to file a bug report!\n\n";
136
137	paraprint <<EOF
138Please note that mailing lists are moderated, your message may take a while to
139show up. Please consider submitting your report directly to the issue tracker
140at https://github.com/Perl/perl5/issues
141EOF
142    }
143
144} else {
145    save_message_to_disk($outfile);
146}
147
148exit;
149
150sub ask_for_alternatives { # (category|severity)
151    my $name = shift;
152    my %alts = (
153	'category' => {
154	    'default' => 'core',
155	    'ok'      => 'install',
156	    # Inevitably some of these will end up in RT whatever we do:
157	    'thanks'  => 'thanks',
158	    'opts'    => [qw(core docs install library utilities)], # patch, notabug
159	},
160	'severity' => {
161	    'default' => 'low',
162	    'ok'      => 'none',
163	    'thanks'  => 'none',
164	    'opts'    => [qw(critical high medium low wishlist none)], # zero
165	},
166    );
167    die "Invalid alternative ($name) requested\n" unless grep(/^$name$/, keys %alts);
168    my $alt = "";
169    my $what = $ok || $thanks;
170    if ($what) {
171	$alt = $alts{$name}{$what};
172    } else {
173 	my @alts = @{$alts{$name}{'opts'}};
174    print "\n\n";
175	paraprint <<EOF;
176Please pick a $name from the following list:
177
178    @alts
179EOF
180	my $err = 0;
181	do {
182	    if ($err++ > 5) {
183		die "Invalid $name: aborting.\n";
184	    }
185        $alt = _prompt('', "\u$name", $alts{$name}{'default'});
186		$alt ||= $alts{$name}{'default'};
187	} while !((($alt) = grep(/^$alt/i, @alts)));
188    }
189    lc $alt;
190}
191
192sub HELP_MESSAGE { Help(); exit; }
193sub VERSION_MESSAGE { print "perlbug version $VERSION\n"; }
194
195sub Init {
196    # -------- Setup --------
197
198    $Is_MSWin32 = $^O eq 'MSWin32';
199    $Is_VMS = $^O eq 'VMS';
200    $Is_Linux = lc($^O) eq 'linux';
201    $Is_OpenBSD = lc($^O) eq 'openbsd';
202
203    # Thanks address
204    $thanksaddress = 'perl-thanks@perl.org';
205
206    # Defaults if getopts fails.
207    $outfile = (basename($0) =~ /^perlthanks/i) ? "perlthanks.rep" : "perlbug.rep";
208    $cc = $::Config{'perladmin'} || $::Config{'cf_email'} || $::Config{'cf_by'} || '';
209
210    HELP_MESSAGE() unless getopts("Adhva:s:b:f:F:r:e:SCc:to:n:T:p:", \%opt);
211
212    # This comment is needed to notify metaconfig that we are
213    # using the $perladmin, $cf_by, and $cf_time definitions.
214    # -------- Configuration ---------
215
216    if (basename ($0) =~ /^perlthanks/i) {
217	# invoked as perlthanks
218	$opt{T} = 1;
219	$opt{C} = 1; # don't send a copy to the local admin
220    }
221
222    if ($opt{T}) {
223	$thanks = 'thanks';
224    }
225
226    $progname = $thanks ? 'perlthanks' : 'perlbug';
227    # Target address
228    $address = $opt{a} || ($thanks ? $thanksaddress : "");
229
230    # Users address, used in message and in From and Reply-To headers
231    $from = $opt{r} || "";
232
233    # Include verbose configuration information
234    $verbose = $opt{v} || 0;
235
236    # Subject of bug-report message
237    $subject = $opt{s} || "";
238
239    # Send a file
240    $usefile = ($opt{f} || 0);
241
242    # File to send as report
243    $file = $opt{f} || "";
244
245    # We have one or more attachments
246    $have_attachment = ($opt{p} || 0);
247    $mime_boundary = ('-' x 12) . "$VERSION.perlbug" if $have_attachment;
248
249    # Comma-separated list of attachments
250    $attachments = $opt{p} || "";
251    $has_patch = 0; # TBD based on file type
252
253    for my $attachment (split /\s*,\s*/, $attachments) {
254        unless (-f $attachment && -r $attachment) {
255            die "The attachment $attachment is not a readable file: $!\n";
256        }
257        $has_patch = 1 if $attachment =~ m/\.(patch|diff)$/;
258    }
259
260    # File to output to
261    $outfile = $opt{F} || "$progname.rep";
262
263    # Body of report
264    $body = $opt{b} || "";
265
266    # Editor
267    $ed = $opt{e} || $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT}
268	|| ($Is_VMS && "edit/tpu")
269	|| ($Is_MSWin32 && "notepad")
270	|| "vi";
271
272    # Not OK - provide build failure template by finessing OK report
273    if ($opt{n}) {
274	if (substr($opt{n}, 0, 2) eq 'ok' )	{
275	    $opt{o} = substr($opt{n}, 1);
276	} else {
277	    Help();
278	    exit();
279	}
280    }
281
282    # OK - send "OK" report for build on this system
283    $ok = '';
284    if ($opt{o}) {
285	if ($opt{o} eq 'k' or $opt{o} eq 'kay') {
286	    my $age = time - $patchlevel_date;
287	    if ($opt{o} eq 'k' and $age > 60 * 24 * 60 * 60 ) {
288		my $date = localtime $patchlevel_date;
289		print <<"EOF";
290"perlbug -ok" and "perlbug -nok" do not report on Perl versions which
291are more than 60 days old.  This Perl version was constructed on
292$date.  If you really want to report this, use
293"perlbug -okay" or "perlbug -nokay".
294EOF
295		exit();
296	    }
297	    # force these options
298	    unless ($opt{n}) {
299		$opt{S} = 1; # don't prompt for send
300		$opt{b} = 1; # we have a body
301		$body = "Perl reported to build OK on this system.\n";
302	    }
303	    $opt{C} = 1; # don't send a copy to the local admin
304	    $opt{s} = 1; # we have a subject line
305	    $subject = ($opt{n} ? 'Not ' : '')
306		    . "OK: perl $perl_version ${patch_tags}on"
307		    ." $::Config{'archname'} $::Config{'osvers'} $subject";
308	    $ok = 'ok';
309	} else {
310	    Help();
311	    exit();
312	}
313    }
314
315    # Possible administrator addresses, in order of confidence
316    # (Note that cf_email is not mentioned to metaconfig, since
317    # we don't really want it. We'll just take it if we have to.)
318    #
319    # This has to be after the $ok stuff above because of the way
320    # that $opt{C} is forced.
321    $cc = $opt{C} ? "" : (
322	$opt{c} || $::Config{'perladmin'}
323	|| $::Config{'cf_email'} || $::Config{'cf_by'}
324    );
325
326    if ($::HaveUtil) {
327		$domain = Mail::Util::maildomain();
328    } elsif ($Is_MSWin32) {
329		$domain = $ENV{'USERDOMAIN'};
330    } else {
331		require Sys::Hostname;
332		$domain = Sys::Hostname::hostname();
333    }
334
335    # Message-Id - rjsf
336    $messageid = "<$::Config{'version'}_${$}_".time."\@$domain>";
337
338    # My username
339    $me = $Is_MSWin32 ? $ENV{'USERNAME'}
340	    : $^O eq 'os2' ? $ENV{'USER'} || $ENV{'LOGNAME'}
341	    : eval { getpwuid($<) };	# May be missing
342
343    $from = $::Config{'cf_email'}
344       if !$from && $::Config{'cf_email'} && $::Config{'cf_by'} && $me &&
345               ($me eq $::Config{'cf_by'});
346} # sub Init
347
348sub Query {
349    # Explain what perlbug is
350    unless ($ok) {
351	if ($thanks) {
352	    paraprint <<'EOF';
353This program provides an easy way to send a thank-you message back to the
354authors and maintainers of perl.
355
356If you wish to generate a bug report, please run it without the -T flag
357EOF
358	} else {
359	    paraprint <<"EOF";
360This program provides an easy way to generate a bug report for the core
361perl distribution (along with tests or patches).  To send a thank-you
362note to $thanksaddress instead of a bug report, please use the -T flag.
363
364The GitHub issue tracker at https://github.com/Perl/perl5/issues is the
365best place to submit your report so it can be tracked and resolved.
366
367Please do not use $0 to report bugs in perl modules from CPAN.
368
369Suggestions for how to find help using Perl can be found at
370https://perldoc.perl.org/perlcommunity.html
371EOF
372	}
373    }
374
375    # Prompt for subject of message, if needed
376
377    if ($subject && TrivialSubject($subject)) {
378	$subject = '';
379    }
380
381    unless ($subject) {
382	    print
383"First of all, please provide a subject for the report.\n";
384	if ( not $thanks)  {
385	    paraprint <<EOF;
386This should be a concise description of your bug or problem
387which will help the volunteers working to improve perl to categorize
388and resolve the issue.  Be as specific and descriptive as
389you can. A subject like "perl bug" or "perl problem" will make it
390much less likely that your issue gets the attention it deserves.
391EOF
392	}
393
394	my $err = 0;
395	do {
396        $subject = _prompt('','Subject');
397	    if ($err++ == 5) {
398		if ($thanks) {
399		    $subject = 'Thanks for Perl';
400		} else {
401		    die "Aborting.\n";
402		}
403	    }
404	} while (TrivialSubject($subject));
405    }
406    $subject = '[PATCH] ' . $subject
407        if $has_patch && ($subject !~ m/^\[PATCH/i);
408
409    # Prompt for return address, if needed
410    unless ($opt{r}) {
411	# Try and guess return address
412	my $guess;
413
414	$guess = $ENV{'REPLY-TO'} || $ENV{'REPLYTO'} || $ENV{'EMAIL'}
415	    || $from || '';
416
417	unless ($guess) {
418		# move $domain to where we can use it elsewhere
419        if ($domain) {
420		if ($Is_VMS && !$::Config{'d_socket'}) {
421		    $guess = "$domain\:\:$me";
422		} else {
423		    $guess = "$me\@$domain" if $domain;
424		}
425	    }
426	}
427
428	if ($guess) {
429	    unless ($ok) {
430		paraprint <<EOF;
431Perl's developers may need your email address to contact you for
432further information about your issue or to inform you when it is
433resolved.  If the default shown is not your email address, please
434correct it.
435EOF
436	    }
437	} else {
438	    paraprint <<EOF;
439Please enter your full internet email address so that Perl's
440developers can contact you with questions about your issue or to
441inform you that it has been resolved.
442EOF
443	}
444
445	if ($ok && $guess) {
446	    # use it
447	    $from = $guess;
448	} else {
449	    # verify it
450        $from = _prompt('','Your address',$guess);
451	    $from = $guess if $from eq '';
452	}
453    }
454
455    if ($from eq $cc or $me eq $cc) {
456	# Try not to copy ourselves
457	$cc = "yourself";
458    }
459
460    # Prompt for administrator address, unless an override was given
461    if( $address and !$opt{C} and !$opt{c} ) {
462	my $description =  <<EOF;
463$0 can send a copy of this report to your local perl
464administrator.  If the address below is wrong, please correct it,
465or enter 'none' or 'yourself' to not send a copy.
466EOF
467	my $entry = _prompt($description, "Local perl administrator", $cc);
468
469	if ($entry ne "") {
470	    $cc = $entry;
471	    $cc = '' if $me eq $cc;
472	}
473    }
474
475    $cc = '' if $cc =~ /^(none|yourself|me|myself|ourselves)$/i;
476    if ($cc) {
477        $andcc = " and $cc"
478    } else {
479        $andcc = ''
480    }
481
482    # Prompt for editor, if no override is given
483editor:
484    unless ($opt{e} || $opt{f} || $opt{b}) {
485
486    my $description;
487
488	chomp (my $common_end = <<"EOF");
489You will probably want to use a text editor to enter the body of
490your report. If "$ed" is the editor you want to use, then just press
491Enter, otherwise type in the name of the editor you would like to
492use.
493
494If you have already composed the body of your report, you may enter
495"file", and $0 will prompt you to enter the name of the file
496containing your report.
497EOF
498
499	if ($thanks) {
500	    $description = <<"EOF";
501It's now time to compose your thank-you message.
502
503Some information about your local perl configuration will automatically
504be included at the end of your message, because we're curious about
505the different ways that people build and use perl. If you'd rather
506not share this information, you're welcome to delete it.
507
508$common_end
509EOF
510	} else {
511	    $description =  <<"EOF";
512It's now time to compose your bug report. Try to make the report
513concise but descriptive. Please include any detail which you think
514might be relevant or might help the volunteers working to improve
515perl. If you are reporting something that does not work as you think
516it should, please try to include examples of the actual result and of
517what you expected.
518
519Some information about your local perl configuration will automatically
520be included at the end of your report. If you are using an unusual
521version of perl, it would be useful if you could confirm that you
522can replicate the problem on a standard build of perl as well.
523
524$common_end
525EOF
526	}
527
528    my $entry = _prompt($description, "Editor", $ed);
529	$usefile = 0;
530	if ($entry eq "file") {
531	    $usefile = 1;
532	} elsif ($entry ne "") {
533	    $ed = $entry;
534	}
535    }
536    if ($::HaveCoreList && !$ok && !$thanks) {
537	my $description =  <<EOF;
538If your bug is about a Perl module rather than a core language
539feature, please enter its name here. If it's not, just hit Enter
540to skip this question.
541EOF
542
543    my $entry = '';
544	while ($entry eq '') {
545        $entry = _prompt($description, 'Module');
546	    my $first_release = Module::CoreList->first_release($entry);
547	    if ($entry and not $first_release) {
548		paraprint <<EOF;
549$entry is not a "core" Perl module. Please check that you entered
550its name correctly. If it is correct, quit this program, try searching
551for $entry on https://rt.cpan.org, and report your issue there.
552EOF
553
554            $entry = '';
555	} elsif (my $bug_tracker = $Module::CoreList::bug_tracker{$entry}) {
556		paraprint <<"EOF";
557$entry included with core Perl is copied directly from the CPAN distribution.
558Please report bugs in $entry directly to its maintainers using $bug_tracker
559EOF
560            $entry = '';
561        } elsif ($entry) {
562	        $category ||= 'library';
563	        $report_about_module = $entry;
564            last;
565        } else {
566            last;
567        }
568	}
569    }
570
571    # Prompt for category of bug
572    $category ||= ask_for_alternatives('category');
573
574    # Prompt for severity of bug
575    $severity ||= ask_for_alternatives('severity');
576
577    # Generate scratch file to edit report in
578    $filename = filename();
579
580    # Prompt for file to read report from, if needed
581    if ($usefile and !$file) {
582filename:
583	my $description = <<EOF;
584What is the name of the file that contains your report?
585EOF
586	my $entry = _prompt($description, "Filename");
587
588	if ($entry eq "") {
589	    paraprint <<EOF;
590It seems you didn't enter a filename. Please choose to use a text
591editor or enter a filename.
592EOF
593	    goto editor;
594	}
595
596	unless (-f $entry and -r $entry) {
597	    paraprint <<EOF;
598'$entry' doesn't seem to be a readable file.  You may have mistyped
599its name or may not have permission to read it.
600
601If you don't want to use a file as the content of your report, just
602hit Enter and you'll be able to select a text editor instead.
603EOF
604	    goto filename;
605	}
606	$file = $entry;
607    }
608
609    # Generate report
610    open(REP, '>:raw', $filename) or die "Unable to create report file '$filename': $!\n";
611    binmode(REP, ':raw :crlf') if $Is_MSWin32;
612
613    my $reptype = !$ok ? ($thanks ? 'thank-you' : 'bug')
614	: $opt{n} ? "build failure" : "success";
615
616    print REP <<EOF;
617This is a $reptype report for perl from $from,
618generated with the help of perlbug $VERSION running under perl $perl_version.
619
620EOF
621
622    if ($report_about_module) {
623	print REP "Module: $report_about_module\n\n";
624    }
625
626    if ($body) {
627	print REP $body;
628    } elsif ($usefile) {
629	open(F, '<:raw', $file)
630		or die "Unable to read report file from '$file': $!\n";
631	binmode(F, ':raw :crlf') if $Is_MSWin32;
632	while (<F>) {
633	    print REP $_
634	}
635	close(F) or die "Error closing '$file': $!";
636    } else {
637	if ($thanks) {
638	    print REP <<'EOF';
639
640-----------------------------------------------------------------
641[Please enter your thank-you message here]
642
643
644
645[You're welcome to delete anything below this line]
646-----------------------------------------------------------------
647EOF
648	} else {
649	    print REP <<'EOF';
650
651-----------------------------------------------------------------
652<!--[Please describe your issue here]-->
653
654**Description**
655<!-- A clear and concise description of what the bug is. -->
656
657
658
659**Steps to Reproduce**
660<!-- A one-liner or script to reproduce the issue. -->
661
662
663
664**Expected behavior**
665<!-- A clear and concise description of what you expected to happen. -->
666
667
668
669<!--[Please do not change anything below this line]-->
670<!------------------------------------------------------------------- -->
671EOF
672	}
673    }
674    Dump(*REP);
675    close(REP) or die "Error closing report file: $!";
676
677    # Set up an initial report fingerprint so we can compare it later
678    _fingerprint_lines_in_report();
679
680} # sub Query
681
682sub Dump {
683    local(*OUT) = @_;
684
685    # these won't have been set if run with -d
686    $category ||= 'core';
687    $severity ||= 'low';
688
689    print OUT <<EFF;
690
691
692---
693**Flags**
694- category=$category
695- severity=$severity
696EFF
697
698    if ($has_patch) {
699        print OUT <<EFF;
700- Type=Patch
701- PatchStatus=HasPatch
702EFF
703    }
704
705    if ($report_about_module ) {
706        print OUT <<EFF;
707- module=$report_about_module
708EFF
709    }
710    print OUT <<EFF;
711---
712**Perl configuration**
713```
714EFF
715    print OUT "This perlbug was built using Perl $config_tag1\n",
716	    "It is being executed now by  Perl $config_tag2.\n\n"
717	if $config_tag2 ne $config_tag1;
718
719    print OUT <<EOF;
720Site configuration information for perl $perl_version:
721
722EOF
723    if ($::Config{cf_by} and $::Config{cf_time}) {
724	print OUT "Configured by $::Config{cf_by} at $::Config{cf_time}.\n\n";
725    }
726    print OUT Config::myconfig;
727
728    if (@patches) {
729	print OUT join "\n    ", "Locally applied patches:", @patches;
730	print OUT "\n";
731    };
732
733    print OUT <<EOF;
734
735---
736\@INC for perl $perl_version:
737EOF
738    for my $i (@INC) {
739	print OUT "    $i\n";
740    }
741
742    print OUT <<EOF;
743
744---
745Environment for perl $perl_version:
746EOF
747    my @env =
748        qw(PATH LD_LIBRARY_PATH LANG PERL_BADLANG SHELL HOME LOGDIR LANGUAGE);
749    push @env, $Config{ldlibpthname} if $Config{ldlibpthname} ne '';
750    push @env, grep /^(?:PERL|LC_|LANG|CYGWIN)/, keys %ENV;
751    my %env;
752    @env{@env} = @env;
753    for my $env (sort keys %env) {
754	print OUT "    $env",
755		exists $ENV{$env} ? "=$ENV{$env}" : ' (unset)',
756		"\n";
757    }
758    if ($verbose) {
759	print OUT "\nComplete configuration data for perl $perl_version:\n\n";
760	my $value;
761	foreach (sort keys %::Config) {
762	    $value = $::Config{$_};
763	    $value = '' unless defined $value;
764	    $value =~ s/'/\\'/g;
765	    print OUT "$_='$value'\n";
766	}
767    }
768    print OUT "```\n";
769} # sub Dump
770
771sub Edit {
772    # Edit the report
773    if ($usefile || $body) {
774	my $description = "Please make sure that the name of the editor you want to use is correct.";
775	my $entry = _prompt($description, 'Editor', $ed);
776	$ed = $entry unless $entry eq '';
777    }
778
779    _edit_file($ed) unless $running_noninteractively;
780}
781
782sub _edit_file {
783    my $editor = shift;
784
785    my $report_written = 0;
786
787    while ( !$report_written ) {
788        my $exit_status = system("$editor $filename");
789        if ($exit_status) {
790            my $desc = <<EOF;
791The editor you chose ('$editor') could not be run!
792
793If you mistyped its name, please enter it now, otherwise just press Enter.
794EOF
795            my $entry = _prompt( $desc, 'Editor', $editor );
796            if ( $entry ne "" ) {
797                $editor = $entry;
798                next;
799            } else {
800                paraprint <<EOF;
801You can edit your report after saving it to a file.
802EOF
803                return;
804            }
805        }
806        return if ( $ok and not $opt{n} ) || $body;
807
808        # Check that we have a report that has some, eh, report in it.
809
810        unless ( _fingerprint_lines_in_report() ) {
811            my $description = <<EOF;
812It looks like you didn't enter a report. You may [r]etry your edit
813or [c]ancel this report.
814EOF
815            my $action = _prompt( $description, "Action (Retry/Cancel) " );
816            if ( $action =~ /^[re]/i ) {    # <R>etry <E>dit
817                next;
818            } elsif ( $action =~ /^[cq]/i ) {    # <C>ancel, <Q>uit
819                Cancel();                        # cancel exits
820            }
821        }
822        # Ok. the user did what they needed to;
823        return;
824
825    }
826}
827
828
829sub Cancel {
830    1 while unlink($filename);  # remove all versions under VMS
831    print "\nQuitting without generating a report.\n";
832    exit(0);
833}
834
835sub NowWhat {
836    # Report is done, prompt for further action
837    if( !$opt{S} ) {
838	while(1) {
839	    my $send_to = $address || 'the Perl developers';
840	    my $menu = <<EOF;
841
842
843You have finished composing your report. At this point, you have
844a few options. You can:
845
846    * Save the report to a [f]ile
847    * [Se]nd the report to $send_to$andcc
848    * [D]isplay the report on the screen
849    * [R]e-edit the report
850    * Display or change the report's [su]bject
851    * [Q]uit without generating the report
852
853EOF
854      retry:
855        print $menu;
856	    my $action =  _prompt('', "Action (Save/Send/Display/Edit/Subject/Quit)",
857	        $opt{t} ? 'q' : '');
858        print "\n";
859	    if ($action =~ /^(f|sa)/i) { # <F>ile/<Sa>ve
860            if ( SaveMessage() ) { exit }
861	    } elsif ($action =~ /^(d|l|sh)/i ) { # <D>isplay, <L>ist, <Sh>ow
862		# Display the message
863		print _read_report($filename);
864		if ($have_attachment) {
865		    print "\n\n---\nAttachment(s):\n";
866		    for my $att (split /\s*,\s*/, $attachments) { print "    $att\n"; }
867		}
868	    } elsif ($action =~ /^su/i) { # <Su>bject
869		my $reply = _prompt( "Subject: $subject", "If the above subject is fine, press Enter. Otherwise, type a replacement now\nSubject");
870		if ($reply ne '') {
871		    unless (TrivialSubject($reply)) {
872			$subject = $reply;
873			print "Subject: $subject\n";
874		    }
875		}
876	    } elsif ($action =~ /^se/i) { # <S>end
877		# Send the message
878		if (not $thanks) {
879		    print <<EOF
880To ensure your issue can be best tracked and resolved,
881you should submit it to the GitHub issue tracker at
882https://github.com/Perl/perl5/issues
883EOF
884		}
885		my $reply =  _prompt( "Are you certain you want to send this report to $send_to$andcc?", 'Please type "yes" if you are','no');
886		if ($reply =~ /^yes$/) {
887		    $address ||= 'perl5-porters@perl.org';
888		    last;
889		} else {
890		    paraprint <<EOF;
891You didn't type "yes", so your report has not been sent.
892EOF
893		}
894	    } elsif ($action =~ /^[er]/i) { # <E>dit, <R>e-edit
895		# edit the message
896		Edit();
897	    } elsif ($action =~ /^[qc]/i) { # <C>ancel, <Q>uit
898		Cancel();
899	    } elsif ($action =~ /^s/i) {
900		paraprint <<EOF;
901The command you entered was ambiguous. Please type "send", "save" or "subject".
902EOF
903	    }
904	}
905    }
906} # sub NowWhat
907
908sub TrivialSubject {
909    my $subject = shift;
910    if ($subject =~
911	/^(y(es)?|no?|help|perl( (bug|problem))?|bug|problem)$/i ||
912	length($subject) < 4 ||
913	($subject !~ /\s/ && ! $opt{t})) { # non-whitespace is accepted in test mode
914	print "\nThe subject you entered wasn't very descriptive. Please try again.\n\n";
915        return 1;
916    } else {
917	return 0;
918    }
919}
920
921sub SaveMessage {
922    my $file = _prompt( '', "Name of file to save report in", $outfile );
923    save_message_to_disk($file) || return undef;
924    return 1;
925}
926
927sub Send {
928
929    # Message has been accepted for transmission -- Send the message
930
931    # on linux certain "mail" implementations won't accept the subject
932    # as "~s subject" and thus the Subject header will be corrupted
933    # so don't use Mail::Send to be safe
934    eval {
935        if ( $::HaveSend && !$Is_Linux && !$Is_OpenBSD ) {
936            _send_message_mailsend();
937        } elsif ($Is_VMS) {
938            _send_message_vms();
939        } else {
940            _send_message_sendmail();
941        }
942    };
943
944    if ( my $error = $@ ) {
945        paraprint <<EOF;
946$0 has detected an error while trying to send your message: $error.
947
948Your message may not have been sent. You will now have a chance to save a copy to disk.
949EOF
950        SaveMessage();
951        return;
952    }
953
954    1 while unlink($filename);    # remove all versions under VMS
955}    # sub Send
956
957sub Help {
958    print <<EOF;
959
960This program is designed to help you generate bug reports
961(and thank-you notes) about perl5 and the modules which ship with it.
962
963In most cases, you can just run "$0" interactively from a command
964line without any special arguments and follow the prompts.
965
966Advanced usage:
967
968$0  [-v] [-a address] [-s subject] [-b body | -f inpufile ] [ -F outputfile ]
969    [-r returnaddress] [-e editor] [-c adminaddress | -C] [-S] [-t] [-h]
970    [-p patchfile ]
971$0  [-v] [-r returnaddress] [-ok | -okay | -nok | -nokay]
972
973
974Options:
975
976  -v    Include Verbose configuration data in the report
977  -f    File containing the body of the report. Use this to
978        quickly send a prepared report.
979  -p    File containing a patch or other text attachment. Separate
980        multiple files with commas.
981  -F    File to output the resulting report to. Defaults to
982        '$outfile'.
983  -S    Save or send the report without asking for confirmation.
984  -a    Send the report to this address, instead of saving to a file.
985  -c    Address to send copy of report to. Defaults to '$cc'.
986  -C    Don't send copy to administrator.
987  -s    Subject to include with the report. You will be prompted
988        if you don't supply one on the command line.
989  -b    Body of the report. If not included on the command line, or
990        in a file with -f, you will get a chance to edit the report.
991  -r    Your return address. The program will ask you to confirm
992        this if you don't give it here.
993  -e    Editor to use.
994  -t    Test mode.
995  -T    Thank-you mode. The target address defaults to '$thanksaddress'.
996  -d    Data mode.  This prints out your configuration data, without mailing
997        anything. You can use this with -v to get more complete data.
998  -ok   Report successful build on this system to perl porters
999        (use alone or with -v). Only use -ok if *everything* was ok:
1000        if there were *any* problems at all, use -nok.
1001  -okay As -ok but allow report from old builds.
1002  -nok  Report unsuccessful build on this system to perl porters
1003        (use alone or with -v). You must describe what went wrong
1004        in the body of the report which you will be asked to edit.
1005  -nokay As -nok but allow report from old builds.
1006  -h    Print this help message.
1007
1008EOF
1009}
1010
1011sub filename {
1012    if ($::HaveTemp) {
1013	# Good. Use a secure temp file
1014	my ($fh, $filename) = File::Temp::tempfile(UNLINK => 1);
1015	close($fh);
1016	return $filename;
1017    } else {
1018	# Bah. Fall back to doing things less securely.
1019	my $dir = File::Spec->tmpdir();
1020	$filename = "bugrep0$$";
1021	$filename++ while -e File::Spec->catfile($dir, $filename);
1022	$filename = File::Spec->catfile($dir, $filename);
1023    }
1024}
1025
1026sub paraprint {
1027    my @paragraphs = split /\n{2,}/, "@_";
1028    for (@paragraphs) {   # implicit local $_
1029	s/(\S)\s*\n/$1 /g;
1030	write;
1031	print "\n";
1032    }
1033}
1034
1035sub _prompt {
1036    my ($explanation, $prompt, $default) = (@_);
1037    if ($explanation) {
1038        print "\n\n";
1039        paraprint $explanation;
1040    }
1041    print $prompt. ($default ? " [$default]" :''). ": ";
1042	my $result = scalar(<>);
1043    return $default if !defined $result; # got eof
1044    chomp($result);
1045	$result =~ s/^\s*(.*?)\s*$/$1/s;
1046    if ($default && $result eq '') {
1047        return $default;
1048    } else {
1049        return $result;
1050    }
1051}
1052
1053sub _build_header {
1054    my %attr = (@_);
1055
1056    my $head = '';
1057    for my $header (keys %attr) {
1058        $head .= "$header: ".$attr{$header}."\n";
1059    }
1060    return $head;
1061}
1062
1063sub _message_headers {
1064    my %headers = ( To => $address || 'perl5-porters@perl.org', Subject => $subject );
1065    $headers{'Cc'}         = $cc        if ($cc);
1066    $headers{'Message-Id'} = $messageid if ($messageid);
1067    $headers{'Reply-To'}   = $from      if ($from);
1068    $headers{'From'}       = $from      if ($from);
1069    if ($have_attachment) {
1070        $headers{'MIME-Version'} = '1.0';
1071        $headers{'Content-Type'} = qq{multipart/mixed; boundary=\"$mime_boundary\"};
1072    }
1073    return \%headers;
1074}
1075
1076sub _add_body_start {
1077    my $body_start = <<"BODY_START";
1078This is a multi-part message in MIME format.
1079--$mime_boundary
1080Content-Type: text/plain; format=fixed
1081Content-Transfer-Encoding: 8bit
1082
1083BODY_START
1084    return $body_start;
1085}
1086
1087sub _add_attachments {
1088    my $attach = '';
1089    for my $attachment (split /\s*,\s*/, $attachments) {
1090        my $attach_file = basename($attachment);
1091        $attach .= <<"ATTACHMENT";
1092
1093--$mime_boundary
1094Content-Type: text/x-patch; name="$attach_file"
1095Content-Transfer-Encoding: 8bit
1096Content-Disposition: attachment; filename="$attach_file"
1097
1098ATTACHMENT
1099
1100        open my $attach_fh, '<:raw', $attachment
1101            or die "Couldn't open attachment '$attachment': $!\n";
1102        while (<$attach_fh>) { $attach .= $_; }
1103        close($attach_fh) or die "Error closing attachment '$attachment': $!";
1104    }
1105
1106    $attach .= "\n--$mime_boundary--\n";
1107    return $attach;
1108}
1109
1110sub _read_report {
1111    my $fname = shift;
1112    my $content;
1113    open( REP, "<:raw", $fname ) or die "Couldn't open file '$fname': $!\n";
1114    binmode(REP, ':raw :crlf') if $Is_MSWin32;
1115    # wrap long lines to make sure the report gets delivered
1116    local $Text::Wrap::columns = 900;
1117    local $Text::Wrap::huge = 'overflow';
1118    while (<REP>) {
1119        if ($::HaveWrap && /\S/) { # wrap() would remove empty lines
1120            $content .= Text::Wrap::wrap(undef, undef, $_);
1121        } else {
1122            $content .= $_;
1123        }
1124    }
1125    close(REP) or die "Error closing report file '$fname': $!";
1126    return $content;
1127}
1128
1129sub build_complete_message {
1130    my $content = _build_header(%{_message_headers()}) . "\n\n";
1131    $content .= _add_body_start() if $have_attachment;
1132    $content .= _read_report($filename);
1133    $content .= _add_attachments() if $have_attachment;
1134    return $content;
1135}
1136
1137sub save_message_to_disk {
1138    my $file = shift;
1139
1140        if (-e $file) {
1141            my $response = _prompt( '', "Overwrite existing '$file'", 'n' );
1142            return undef unless $response =~ / yes | y /xi;
1143        }
1144        open OUTFILE, '>:raw', $file or do { warn  "Couldn't open '$file': $!\n"; return undef};
1145        binmode(OUTFILE, ':raw :crlf') if $Is_MSWin32;
1146
1147        print OUTFILE build_complete_message();
1148        close(OUTFILE) or do { warn  "Error closing $file: $!"; return undef };
1149	    print "\nReport saved to '$file'. Please submit it to https://github.com/Perl/perl5/issues\n";
1150        return 1;
1151}
1152
1153sub _send_message_vms {
1154
1155    my $mail_from  = $from;
1156    my $rcpt_to_to = $address;
1157    my $rcpt_to_cc = $cc;
1158
1159    map { $_ =~ s/^[^<]*<//;
1160          $_ =~ s/>[^>]*//; } ($mail_from, $rcpt_to_to, $rcpt_to_cc);
1161
1162    if ( open my $sff_fh, '|-:raw', 'MCR TCPIP$SYSTEM:TCPIP$SMTP_SFF.EXE SYS$INPUT:' ) {
1163        print $sff_fh "MAIL FROM:<$mail_from>\n";
1164        print $sff_fh "RCPT TO:<$rcpt_to_to>\n";
1165        print $sff_fh "RCPT TO:<$rcpt_to_cc>\n" if $rcpt_to_cc;
1166        print $sff_fh "DATA\n";
1167        print $sff_fh build_complete_message();
1168        my $success = close $sff_fh;
1169        if ($success ) {
1170            print "\nMessage sent\n";
1171            return;
1172        }
1173    }
1174    die "Mail transport failed (leaving bug report in $filename): $^E\n";
1175}
1176
1177sub _send_message_mailsend {
1178    my $msg = Mail::Send->new();
1179    my %headers = %{_message_headers()};
1180    for my $key ( keys %headers) {
1181        $msg->add($key => $headers{$key});
1182    }
1183
1184    $fh = $msg->open;
1185    binmode($fh, ':raw');
1186    print $fh _add_body_start() if $have_attachment;
1187    print $fh _read_report($filename);
1188    print $fh _add_attachments() if $have_attachment;
1189    $fh->close or die "Error sending mail: $!";
1190
1191    print "\nMessage sent.\n";
1192}
1193
1194sub _probe_for_sendmail {
1195    my $sendmail = "";
1196    for (qw(/usr/lib/sendmail /usr/sbin/sendmail /usr/ucblib/sendmail)) {
1197        $sendmail = $_, last if -e $_;
1198    }
1199    if ( $^O eq 'os2' and $sendmail eq "" ) {
1200        my $path = $ENV{PATH};
1201        $path =~ s:\\:/:;
1202        my @path = split /$Config{'path_sep'}/, $path;
1203        for (@path) {
1204            $sendmail = "$_/sendmail",     last if -e "$_/sendmail";
1205            $sendmail = "$_/sendmail.exe", last if -e "$_/sendmail.exe";
1206        }
1207    }
1208    return $sendmail;
1209}
1210
1211sub _send_message_sendmail {
1212    my $sendmail = _probe_for_sendmail();
1213    unless ($sendmail) {
1214        my $message_start = !$Is_Linux && !$Is_OpenBSD ? <<'EOT' : <<'EOT';
1215It appears that there is no program which looks like "sendmail" on
1216your system and that the Mail::Send library from CPAN isn't available.
1217EOT
1218It appears that there is no program which looks like "sendmail" on
1219your system.
1220EOT
1221        paraprint(<<"EOF"), die "\n";
1222$message_start
1223Because of this, there's no easy way to automatically send your
1224report.
1225
1226A copy of your report has been saved in '$filename' for you to
1227send to '$address' with your normal mail client.
1228EOF
1229    }
1230
1231    open( SENDMAIL, "|-:raw", $sendmail, "-t", "-oi", "-f", $from )
1232        || die "'|$sendmail -t -oi -f $from' failed: $!";
1233    print SENDMAIL build_complete_message();
1234    if ( close(SENDMAIL) ) {
1235        print "\nMessage sent\n";
1236    } else {
1237        warn "\nSendmail returned status '", $? >> 8, "'\n";
1238    }
1239}
1240
1241
1242
1243# a strange way to check whether any significant editing
1244# has been done: check whether any new non-empty lines
1245# have been added.
1246
1247sub _fingerprint_lines_in_report {
1248    my $new_lines = 0;
1249    # read in the report template once so that
1250    # we can track whether the user does any editing.
1251    # yes, *all* whitespace is ignored.
1252
1253    open(REP, '<:raw', $filename) or die "Unable to open report file '$filename': $!\n";
1254    binmode(REP, ':raw :crlf') if $Is_MSWin32;
1255    while (my $line = <REP>) {
1256        $line =~ s/\s+//g;
1257        $new_lines++ if (!$REP{$line});
1258
1259    }
1260    close(REP) or die "Error closing report file '$filename': $!";
1261    # returns the number of lines with content that wasn't there when last we looked
1262    return $new_lines;
1263}
1264
1265
1266
1267format STDOUT =
1268^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
1269$_
1270.
1271
1272__END__
1273
1274=head1 NAME
1275
1276perlbug - how to submit bug reports on Perl
1277
1278=head1 SYNOPSIS
1279
1280B<perlbug>
1281
1282B<perlbug> S<[ B<-v> ]> S<[ B<-a> I<address> ]> S<[ B<-s> I<subject> ]>
1283S<[ B<-b> I<body> | B<-f> I<inputfile> ]> S<[ B<-F> I<outputfile> ]>
1284S<[ B<-r> I<returnaddress> ]>
1285S<[ B<-e> I<editor> ]> S<[ B<-c> I<adminaddress> | B<-C> ]>
1286S<[ B<-S> ]> S<[ B<-t> ]>  S<[ B<-d> ]>  S<[ B<-h> ]> S<[ B<-T> ]>
1287
1288B<perlbug> S<[ B<-v> ]> S<[ B<-r> I<returnaddress> ]>
1289 S<[ B<-ok> | B<-okay> | B<-nok> | B<-nokay> ]>
1290
1291=head1 DESCRIPTION
1292
1293
1294This program is designed to help you generate bug reports
1295(and thank-you notes) about perl5 and the modules which ship with it.
1296
1297In most cases, you can just run it interactively from a command
1298line without any special arguments and follow the prompts.
1299
1300If you have found a bug with a non-standard port (one that was not
1301part of the I<standard distribution>), a binary distribution, or a
1302non-core module (such as Tk, DBI, etc), then please see the
1303documentation that came with that distribution to determine the
1304correct place to report bugs.
1305
1306Bug reports should be submitted to the GitHub issue tracker at
1307L<https://github.com/Perl/perl5/issues>. The B<perlbug@perl.org>
1308address no longer automatically opens tickets. You can use this tool
1309to compose your report and save it to a file which you can then submit
1310to the issue tracker.
1311
1312In extreme cases, B<perlbug> may not work well enough on your system
1313to guide you through composing a bug report. In those cases, you
1314may be able to use B<perlbug -d> or B<perl -V> to get system
1315configuration information to include in your issue report.
1316
1317
1318When reporting a bug, please run through this checklist:
1319
1320=over 4
1321
1322=item What version of Perl you are running?
1323
1324Type C<perl -v> at the command line to find out.
1325
1326=item Are you running the latest released version of perl?
1327
1328Look at L<http://www.perl.org/> to find out.  If you are not using the
1329latest released version, please try to replicate your bug on the
1330latest stable release.
1331
1332Note that reports about bugs in old versions of Perl, especially
1333those which indicate you haven't also tested the current stable
1334release of Perl, are likely to receive less attention from the
1335volunteers who build and maintain Perl than reports about bugs in
1336the current release.
1337
1338=item Are you sure what you have is a bug?
1339
1340A significant number of the bug reports we get turn out to be
1341documented features in Perl.  Make sure the issue you've run into
1342isn't intentional by glancing through the documentation that comes
1343with the Perl distribution.
1344
1345Given the sheer volume of Perl documentation, this isn't a trivial
1346undertaking, but if you can point to documentation that suggests
1347the behaviour you're seeing is I<wrong>, your issue is likely to
1348receive more attention. You may want to start with B<perldoc>
1349L<perltrap> for pointers to common traps that new (and experienced)
1350Perl programmers run into.
1351
1352If you're unsure of the meaning of an error message you've run
1353across, B<perldoc> L<perldiag> for an explanation.  If the message
1354isn't in perldiag, it probably isn't generated by Perl.  You may
1355have luck consulting your operating system documentation instead.
1356
1357If you are on a non-UNIX platform B<perldoc> L<perlport>, as some
1358features may be unimplemented or work differently.
1359
1360You may be able to figure out what's going wrong using the Perl
1361debugger.  For information about how to use the debugger B<perldoc>
1362L<perldebug>.
1363
1364=item Do you have a proper test case?
1365
1366The easier it is to reproduce your bug, the more likely it will be
1367fixed -- if nobody can duplicate your problem, it probably won't be
1368addressed.
1369
1370A good test case has most of these attributes: short, simple code;
1371few dependencies on external commands, modules, or libraries; no
1372platform-dependent code (unless it's a platform-specific bug);
1373clear, simple documentation.
1374
1375A good test case is almost always a good candidate to be included in
1376Perl's test suite.  If you have the time, consider writing your test case so
1377that it can be easily included into the standard test suite.
1378
1379=item Have you included all relevant information?
1380
1381Be sure to include the B<exact> error messages, if any.
1382"Perl gave an error" is not an exact error message.
1383
1384If you get a core dump (or equivalent), you may use a debugger
1385(B<dbx>, B<gdb>, etc) to produce a stack trace to include in the bug
1386report.
1387
1388NOTE: unless your Perl has been compiled with debug info
1389(often B<-g>), the stack trace is likely to be somewhat hard to use
1390because it will most probably contain only the function names and not
1391their arguments.  If possible, recompile your Perl with debug info and
1392reproduce the crash and the stack trace.
1393
1394=item Can you describe the bug in plain English?
1395
1396The easier it is to understand a reproducible bug, the more likely
1397it will be fixed.  Any insight you can provide into the problem
1398will help a great deal.  In other words, try to analyze the problem
1399(to the extent you can) and report your discoveries.
1400
1401=item Can you fix the bug yourself?
1402
1403If so, that's great news; bug reports with patches are likely to
1404receive significantly more attention and interest than those without
1405patches.  Please submit your patch via the GitHub Pull Request workflow
1406as described in B<perldoc> L<perlhack>.  You may also send patches to
1407B<perl5-porters@perl.org>.  When sending a patch, create it using
1408C<git format-patch> if possible, though a unified diff created with
1409C<diff -pu> will do nearly as well.
1410
1411Your patch may be returned with requests for changes, or requests for more
1412detailed explanations about your fix.
1413
1414Here are a few hints for creating high-quality patches:
1415
1416Make sure the patch is not reversed (the first argument to diff is
1417typically the original file, the second argument your changed file).
1418Make sure you test your patch by applying it with C<git am> or the
1419C<patch> program before you send it on its way.  Try to follow the
1420same style as the code you are trying to patch.  Make sure your patch
1421really does work (C<make test>, if the thing you're patching is covered
1422by Perl's test suite).
1423
1424=item Can you use C<perlbug> to submit a thank-you note?
1425
1426Yes, you can do this by using the C<-T> option.
1427Thank-you notes are good. It makes people
1428smile.
1429
1430=back
1431
1432Please make your issue title informative.  "a bug" is not informative.
1433Neither is "perl crashes" nor is "HELP!!!".  These don't help.  A compact
1434description of what's wrong is fine.
1435
1436Having done your bit, please be prepared to wait, to be told the
1437bug is in your code, or possibly to get no reply at all.  The
1438volunteers who maintain Perl are busy folks, so if your problem is
1439an obvious bug in your own code, is difficult to understand or is
1440a duplicate of an existing report, you may not receive a personal
1441reply.
1442
1443If it is important to you that your bug be fixed, do monitor the
1444issue tracker (you will be subscribed to notifications for issues you
1445submit or comment on) and the commit logs to development
1446versions of Perl, and encourage the maintainers with kind words or
1447offers of frosty beverages.  (Please do be kind to the maintainers.
1448Harassing or flaming them is likely to have the opposite effect of the
1449one you want.)
1450
1451Feel free to update the ticket about your bug on
1452L<https://github.com/Perl/perl5/issues>
1453if a new version of Perl is released and your bug is still present.
1454
1455=head1 OPTIONS
1456
1457=over 8
1458
1459=item B<-a>
1460
1461Address to send the report to instead of saving to a file.
1462
1463=item B<-b>
1464
1465Body of the report.  If not included on the command line, or
1466in a file with B<-f>, you will get a chance to edit the report.
1467
1468=item B<-C>
1469
1470Don't send copy to administrator when sending report by mail.
1471
1472=item B<-c>
1473
1474Address to send copy of report to when sending report by mail.
1475Defaults to the address of the
1476local perl administrator (recorded when perl was built).
1477
1478=item B<-d>
1479
1480Data mode (the default if you redirect or pipe output).  This prints out
1481your configuration data, without saving or mailing anything.  You can use
1482this with B<-v> to get more complete data.
1483
1484=item B<-e>
1485
1486Editor to use.
1487
1488=item B<-f>
1489
1490File containing the body of the report.  Use this to quickly send a
1491prepared report.
1492
1493=item B<-F>
1494
1495File to output the results to.  Defaults to B<perlbug.rep>.
1496
1497=item B<-h>
1498
1499Prints a brief summary of the options.
1500
1501=item B<-ok>
1502
1503Report successful build on this system to perl porters. Forces B<-S>
1504and B<-C>. Forces and supplies values for B<-s> and B<-b>. Only
1505prompts for a return address if it cannot guess it (for use with
1506B<make>). Honors return address specified with B<-r>.  You can use this
1507with B<-v> to get more complete data.   Only makes a report if this
1508system is less than 60 days old.
1509
1510=item B<-okay>
1511
1512As B<-ok> except it will report on older systems.
1513
1514=item B<-nok>
1515
1516Report unsuccessful build on this system.  Forces B<-C>.  Forces and
1517supplies a value for B<-s>, then requires you to edit the report
1518and say what went wrong.  Alternatively, a prepared report may be
1519supplied using B<-f>.  Only prompts for a return address if it
1520cannot guess it (for use with B<make>). Honors return address
1521specified with B<-r>.  You can use this with B<-v> to get more
1522complete data.  Only makes a report if this system is less than 60
1523days old.
1524
1525=item B<-nokay>
1526
1527As B<-nok> except it will report on older systems.
1528
1529=item B<-p>
1530
1531The names of one or more patch files or other text attachments to be
1532included with the report.  Multiple files must be separated with commas.
1533
1534=item B<-r>
1535
1536Your return address.  The program will ask you to confirm its default
1537if you don't use this option.
1538
1539=item B<-S>
1540
1541Save or send the report without asking for confirmation.
1542
1543=item B<-s>
1544
1545Subject to include with the report.  You will be prompted if you don't
1546supply one on the command line.
1547
1548=item B<-t>
1549
1550Test mode.  Makes it possible to command perlbug from a pipe or file, for
1551testing purposes.
1552
1553=item B<-T>
1554
1555Send a thank-you note instead of a bug report.
1556
1557=item B<-v>
1558
1559Include verbose configuration data in the report.
1560
1561=back
1562
1563=head1 AUTHORS
1564
1565Kenneth Albanowski (E<lt>kjahds@kjahds.comE<gt>), subsequently
1566I<doc>tored by Gurusamy Sarathy (E<lt>gsar@activestate.comE<gt>),
1567Tom Christiansen (E<lt>tchrist@perl.comE<gt>), Nathan Torkington
1568(E<lt>gnat@frii.comE<gt>), Charles F. Randall (E<lt>cfr@pobox.comE<gt>),
1569Mike Guy (E<lt>mjtg@cam.ac.ukE<gt>), Dominic Dunlop
1570(E<lt>domo@computer.orgE<gt>), Hugo van der Sanden (E<lt>hv@crypt.orgE<gt>),
1571Jarkko Hietaniemi (E<lt>jhi@iki.fiE<gt>), Chris Nandor
1572(E<lt>pudge@pobox.comE<gt>), Jon Orwant (E<lt>orwant@media.mit.eduE<gt>,
1573Richard Foley (E<lt>richard.foley@rfi.netE<gt>), Jesse Vincent
1574(E<lt>jesse@bestpractical.comE<gt>), and Craig A. Berry (E<lt>craigberry@mac.comE<gt>).
1575
1576=head1 SEE ALSO
1577
1578perl(1), perldebug(1), perldiag(1), perlport(1), perltrap(1),
1579diff(1), patch(1), dbx(1), gdb(1)
1580
1581=head1 BUGS
1582
1583None known (guess what must have been used to report them?)
1584
1585=cut
1586
1587!NO!SUBS!
1588
1589close OUT or die "Can't close $file: $!";
1590chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
1591exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
1592chdir $origdir;
1593