xref: /openbsd-src/gnu/usr.bin/perl/utils/perlbug.PL (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
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 \$running_under_some_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.42";
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 ($body) {
623	print REP $body;
624    } elsif ($usefile) {
625	open(F, '<:raw', $file)
626		or die "Unable to read report file from '$file': $!\n";
627	binmode(F, ':raw :crlf') if $Is_MSWin32;
628	while (<F>) {
629	    print REP $_
630	}
631	close(F) or die "Error closing '$file': $!";
632    } else {
633	if ($thanks) {
634	    print REP <<'EOF';
635
636-----------------------------------------------------------------
637[Please enter your thank-you message here]
638
639
640
641[You're welcome to delete anything below this line]
642-----------------------------------------------------------------
643EOF
644	} else {
645	    print REP <<'EOF';
646
647-----------------------------------------------------------------
648[Please describe your issue here]
649
650
651
652[Please do not change anything below this line]
653-----------------------------------------------------------------
654EOF
655	}
656    }
657    Dump(*REP);
658    close(REP) or die "Error closing report file: $!";
659
660    # Set up an initial report fingerprint so we can compare it later
661    _fingerprint_lines_in_report();
662
663} # sub Query
664
665sub Dump {
666    local(*OUT) = @_;
667
668    # these won't have been set if run with -d
669    $category ||= 'core';
670    $severity ||= 'low';
671
672    print OUT <<EFF;
673---
674Flags:
675    category=$category
676    severity=$severity
677EFF
678
679    if ($has_patch) {
680        print OUT <<EFF;
681    Type=Patch
682    PatchStatus=HasPatch
683EFF
684    }
685
686    if ($report_about_module ) {
687        print OUT <<EFF;
688    module=$report_about_module
689EFF
690    }
691    print OUT <<EFF;
692---
693EFF
694    print OUT "This perlbug was built using Perl $config_tag1\n",
695	    "It is being executed now by  Perl $config_tag2.\n\n"
696	if $config_tag2 ne $config_tag1;
697
698    print OUT <<EOF;
699Site configuration information for perl $perl_version:
700
701EOF
702    if ($::Config{cf_by} and $::Config{cf_time}) {
703	print OUT "Configured by $::Config{cf_by} at $::Config{cf_time}.\n\n";
704    }
705    print OUT Config::myconfig;
706
707    if (@patches) {
708	print OUT join "\n    ", "Locally applied patches:", @patches;
709	print OUT "\n";
710    };
711
712    print OUT <<EOF;
713
714---
715\@INC for perl $perl_version:
716EOF
717    for my $i (@INC) {
718	print OUT "    $i\n";
719    }
720
721    print OUT <<EOF;
722
723---
724Environment for perl $perl_version:
725EOF
726    my @env =
727        qw(PATH LD_LIBRARY_PATH LANG PERL_BADLANG SHELL HOME LOGDIR LANGUAGE);
728    push @env, $Config{ldlibpthname} if $Config{ldlibpthname} ne '';
729    push @env, grep /^(?:PERL|LC_|LANG|CYGWIN)/, keys %ENV;
730    my %env;
731    @env{@env} = @env;
732    for my $env (sort keys %env) {
733	print OUT "    $env",
734		exists $ENV{$env} ? "=$ENV{$env}" : ' (unset)',
735		"\n";
736    }
737    if ($verbose) {
738	print OUT "\nComplete configuration data for perl $perl_version:\n\n";
739	my $value;
740	foreach (sort keys %::Config) {
741	    $value = $::Config{$_};
742	    $value = '' unless defined $value;
743	    $value =~ s/'/\\'/g;
744	    print OUT "$_='$value'\n";
745	}
746    }
747} # sub Dump
748
749sub Edit {
750    # Edit the report
751    if ($usefile || $body) {
752	my $description = "Please make sure that the name of the editor you want to use is correct.";
753	my $entry = _prompt($description, 'Editor', $ed);
754	$ed = $entry unless $entry eq '';
755    }
756
757    _edit_file($ed) unless $running_noninteractively;
758}
759
760sub _edit_file {
761    my $editor = shift;
762
763    my $report_written = 0;
764
765    while ( !$report_written ) {
766        my $exit_status = system("$editor $filename");
767        if ($exit_status) {
768            my $desc = <<EOF;
769The editor you chose ('$editor') could not be run!
770
771If you mistyped its name, please enter it now, otherwise just press Enter.
772EOF
773            my $entry = _prompt( $desc, 'Editor', $editor );
774            if ( $entry ne "" ) {
775                $editor = $entry;
776                next;
777            } else {
778                paraprint <<EOF;
779You can edit your report after saving it to a file.
780EOF
781                return;
782            }
783        }
784        return if ( $ok and not $opt{n} ) || $body;
785
786        # Check that we have a report that has some, eh, report in it.
787
788        unless ( _fingerprint_lines_in_report() ) {
789            my $description = <<EOF;
790It looks like you didn't enter a report. You may [r]etry your edit
791or [c]ancel this report.
792EOF
793            my $action = _prompt( $description, "Action (Retry/Cancel) " );
794            if ( $action =~ /^[re]/i ) {    # <R>etry <E>dit
795                next;
796            } elsif ( $action =~ /^[cq]/i ) {    # <C>ancel, <Q>uit
797                Cancel();                        # cancel exits
798            }
799        }
800        # Ok. the user did what they needed to;
801        return;
802
803    }
804}
805
806
807sub Cancel {
808    1 while unlink($filename);  # remove all versions under VMS
809    print "\nQuitting without generating a report.\n";
810    exit(0);
811}
812
813sub NowWhat {
814    # Report is done, prompt for further action
815    if( !$opt{S} ) {
816	while(1) {
817	    my $send_to = $address || 'the Perl developers';
818	    my $menu = <<EOF;
819
820
821You have finished composing your report. At this point, you have
822a few options. You can:
823
824    * Save the report to a [f]ile
825    * [Se]nd the report to $send_to$andcc
826    * [D]isplay the report on the screen
827    * [R]e-edit the report
828    * Display or change the report's [su]bject
829    * [Q]uit without generating the report
830
831EOF
832      retry:
833        print $menu;
834	    my $action =  _prompt('', "Action (Save/Send/Display/Edit/Subject/Quit)",
835	        $opt{t} ? 'q' : '');
836        print "\n";
837	    if ($action =~ /^(f|sa)/i) { # <F>ile/<Sa>ve
838            if ( SaveMessage() ) { exit }
839	    } elsif ($action =~ /^(d|l|sh)/i ) { # <D>isplay, <L>ist, <Sh>ow
840		# Display the message
841		print _read_report($filename);
842		if ($have_attachment) {
843		    print "\n\n---\nAttachment(s):\n";
844		    for my $att (split /\s*,\s*/, $attachments) { print "    $att\n"; }
845		}
846	    } elsif ($action =~ /^su/i) { # <Su>bject
847		my $reply = _prompt( "Subject: $subject", "If the above subject is fine, press Enter. Otherwise, type a replacement now\nSubject");
848		if ($reply ne '') {
849		    unless (TrivialSubject($reply)) {
850			$subject = $reply;
851			print "Subject: $subject\n";
852		    }
853		}
854	    } elsif ($action =~ /^se/i) { # <S>end
855		# Send the message
856		if (not $thanks) {
857		    print <<EOF
858To ensure your issue can be best tracked and resolved,
859you should submit it to the GitHub issue tracker at
860https://github.com/Perl/perl5/issues
861EOF
862		}
863		my $reply =  _prompt( "Are you certain you want to send this report to $send_to$andcc?", 'Please type "yes" if you are','no');
864		if ($reply =~ /^yes$/) {
865		    $address ||= 'perl5-porters@perl.org';
866		    last;
867		} else {
868		    paraprint <<EOF;
869You didn't type "yes", so your report has not been sent.
870EOF
871		}
872	    } elsif ($action =~ /^[er]/i) { # <E>dit, <R>e-edit
873		# edit the message
874		Edit();
875	    } elsif ($action =~ /^[qc]/i) { # <C>ancel, <Q>uit
876		Cancel();
877	    } elsif ($action =~ /^s/i) {
878		paraprint <<EOF;
879The command you entered was ambiguous. Please type "send", "save" or "subject".
880EOF
881	    }
882	}
883    }
884} # sub NowWhat
885
886sub TrivialSubject {
887    my $subject = shift;
888    if ($subject =~
889	/^(y(es)?|no?|help|perl( (bug|problem))?|bug|problem)$/i ||
890	length($subject) < 4 ||
891	($subject !~ /\s/ && ! $opt{t})) { # non-whitespace is accepted in test mode
892	print "\nThe subject you entered wasn't very descriptive. Please try again.\n\n";
893        return 1;
894    } else {
895	return 0;
896    }
897}
898
899sub SaveMessage {
900    my $file = _prompt( '', "Name of file to save report in", $outfile );
901    save_message_to_disk($file) || return undef;
902    return 1;
903}
904
905sub Send {
906
907    # Message has been accepted for transmission -- Send the message
908
909    # on linux certain "mail" implementations won't accept the subject
910    # as "~s subject" and thus the Subject header will be corrupted
911    # so don't use Mail::Send to be safe
912    eval {
913        if ( $::HaveSend && !$Is_Linux && !$Is_OpenBSD ) {
914            _send_message_mailsend();
915        } elsif ($Is_VMS) {
916            _send_message_vms();
917        } else {
918            _send_message_sendmail();
919        }
920    };
921
922    if ( my $error = $@ ) {
923        paraprint <<EOF;
924$0 has detected an error while trying to send your message: $error.
925
926Your message may not have been sent. You will now have a chance to save a copy to disk.
927EOF
928        SaveMessage();
929        return;
930    }
931
932    1 while unlink($filename);    # remove all versions under VMS
933}    # sub Send
934
935sub Help {
936    print <<EOF;
937
938This program is designed to help you generate bug reports
939(and thank-you notes) about perl5 and the modules which ship with it.
940
941In most cases, you can just run "$0" interactively from a command
942line without any special arguments and follow the prompts.
943
944Advanced usage:
945
946$0  [-v] [-a address] [-s subject] [-b body | -f inpufile ] [ -F outputfile ]
947    [-r returnaddress] [-e editor] [-c adminaddress | -C] [-S] [-t] [-h]
948    [-p patchfile ]
949$0  [-v] [-r returnaddress] [-ok | -okay | -nok | -nokay]
950
951
952Options:
953
954  -v    Include Verbose configuration data in the report
955  -f    File containing the body of the report. Use this to
956        quickly send a prepared report.
957  -p    File containing a patch or other text attachment. Separate
958        multiple files with commas.
959  -F    File to output the resulting report to. Defaults to
960        '$outfile'.
961  -S    Save or send the report without asking for confirmation.
962  -a    Send the report to this address, instead of saving to a file.
963  -c    Address to send copy of report to. Defaults to '$cc'.
964  -C    Don't send copy to administrator.
965  -s    Subject to include with the report. You will be prompted
966        if you don't supply one on the command line.
967  -b    Body of the report. If not included on the command line, or
968        in a file with -f, you will get a chance to edit the report.
969  -r    Your return address. The program will ask you to confirm
970        this if you don't give it here.
971  -e    Editor to use.
972  -t    Test mode.
973  -T    Thank-you mode. The target address defaults to '$thanksaddress'.
974  -d    Data mode.  This prints out your configuration data, without mailing
975        anything. You can use this with -v to get more complete data.
976  -ok   Report successful build on this system to perl porters
977        (use alone or with -v). Only use -ok if *everything* was ok:
978        if there were *any* problems at all, use -nok.
979  -okay As -ok but allow report from old builds.
980  -nok  Report unsuccessful build on this system to perl porters
981        (use alone or with -v). You must describe what went wrong
982        in the body of the report which you will be asked to edit.
983  -nokay As -nok but allow report from old builds.
984  -h    Print this help message.
985
986EOF
987}
988
989sub filename {
990    if ($::HaveTemp) {
991	# Good. Use a secure temp file
992	my ($fh, $filename) = File::Temp::tempfile(UNLINK => 1);
993	close($fh);
994	return $filename;
995    } else {
996	# Bah. Fall back to doing things less securely.
997	my $dir = File::Spec->tmpdir();
998	$filename = "bugrep0$$";
999	$filename++ while -e File::Spec->catfile($dir, $filename);
1000	$filename = File::Spec->catfile($dir, $filename);
1001    }
1002}
1003
1004sub paraprint {
1005    my @paragraphs = split /\n{2,}/, "@_";
1006    for (@paragraphs) {   # implicit local $_
1007	s/(\S)\s*\n/$1 /g;
1008	write;
1009	print "\n";
1010    }
1011}
1012
1013sub _prompt {
1014    my ($explanation, $prompt, $default) = (@_);
1015    if ($explanation) {
1016        print "\n\n";
1017        paraprint $explanation;
1018    }
1019    print $prompt. ($default ? " [$default]" :''). ": ";
1020	my $result = scalar(<>);
1021    return $default if !defined $result; # got eof
1022    chomp($result);
1023	$result =~ s/^\s*(.*?)\s*$/$1/s;
1024    if ($default && $result eq '') {
1025        return $default;
1026    } else {
1027        return $result;
1028    }
1029}
1030
1031sub _build_header {
1032    my %attr = (@_);
1033
1034    my $head = '';
1035    for my $header (keys %attr) {
1036        $head .= "$header: ".$attr{$header}."\n";
1037    }
1038    return $head;
1039}
1040
1041sub _message_headers {
1042    my %headers = ( To => $address || 'perl5-porters@perl.org', Subject => $subject );
1043    $headers{'Cc'}         = $cc        if ($cc);
1044    $headers{'Message-Id'} = $messageid if ($messageid);
1045    $headers{'Reply-To'}   = $from      if ($from);
1046    $headers{'From'}       = $from      if ($from);
1047    if ($have_attachment) {
1048        $headers{'MIME-Version'} = '1.0';
1049        $headers{'Content-Type'} = qq{multipart/mixed; boundary=\"$mime_boundary\"};
1050    }
1051    return \%headers;
1052}
1053
1054sub _add_body_start {
1055    my $body_start = <<"BODY_START";
1056This is a multi-part message in MIME format.
1057--$mime_boundary
1058Content-Type: text/plain; format=fixed
1059Content-Transfer-Encoding: 8bit
1060
1061BODY_START
1062    return $body_start;
1063}
1064
1065sub _add_attachments {
1066    my $attach = '';
1067    for my $attachment (split /\s*,\s*/, $attachments) {
1068        my $attach_file = basename($attachment);
1069        $attach .= <<"ATTACHMENT";
1070
1071--$mime_boundary
1072Content-Type: text/x-patch; name="$attach_file"
1073Content-Transfer-Encoding: 8bit
1074Content-Disposition: attachment; filename="$attach_file"
1075
1076ATTACHMENT
1077
1078        open my $attach_fh, '<:raw', $attachment
1079            or die "Couldn't open attachment '$attachment': $!\n";
1080        while (<$attach_fh>) { $attach .= $_; }
1081        close($attach_fh) or die "Error closing attachment '$attachment': $!";
1082    }
1083
1084    $attach .= "\n--$mime_boundary--\n";
1085    return $attach;
1086}
1087
1088sub _read_report {
1089    my $fname = shift;
1090    my $content;
1091    open( REP, "<:raw", $fname ) or die "Couldn't open file '$fname': $!\n";
1092    binmode(REP, ':raw :crlf') if $Is_MSWin32;
1093    # wrap long lines to make sure the report gets delivered
1094    local $Text::Wrap::columns = 900;
1095    local $Text::Wrap::huge = 'overflow';
1096    while (<REP>) {
1097        if ($::HaveWrap && /\S/) { # wrap() would remove empty lines
1098            $content .= Text::Wrap::wrap(undef, undef, $_);
1099        } else {
1100            $content .= $_;
1101        }
1102    }
1103    close(REP) or die "Error closing report file '$fname': $!";
1104    return $content;
1105}
1106
1107sub build_complete_message {
1108    my $content = _build_header(%{_message_headers()}) . "\n\n";
1109    $content .= _add_body_start() if $have_attachment;
1110    $content .= _read_report($filename);
1111    $content .= _add_attachments() if $have_attachment;
1112    return $content;
1113}
1114
1115sub save_message_to_disk {
1116    my $file = shift;
1117
1118        if (-e $file) {
1119            my $response = _prompt( '', "Overwrite existing '$file'", 'n' );
1120            return undef unless $response =~ / yes | y /xi;
1121        }
1122        open OUTFILE, '>:raw', $file or do { warn  "Couldn't open '$file': $!\n"; return undef};
1123        binmode(OUTFILE, ':raw :crlf') if $Is_MSWin32;
1124
1125        print OUTFILE build_complete_message();
1126        close(OUTFILE) or do { warn  "Error closing $file: $!"; return undef };
1127	    print "\nReport saved to '$file'. Please submit it to https://github.com/Perl/perl5/issues\n";
1128        return 1;
1129}
1130
1131sub _send_message_vms {
1132
1133    my $mail_from  = $from;
1134    my $rcpt_to_to = $address;
1135    my $rcpt_to_cc = $cc;
1136
1137    map { $_ =~ s/^[^<]*<//;
1138          $_ =~ s/>[^>]*//; } ($mail_from, $rcpt_to_to, $rcpt_to_cc);
1139
1140    if ( open my $sff_fh, '|-:raw', 'MCR TCPIP$SYSTEM:TCPIP$SMTP_SFF.EXE SYS$INPUT:' ) {
1141        print $sff_fh "MAIL FROM:<$mail_from>\n";
1142        print $sff_fh "RCPT TO:<$rcpt_to_to>\n";
1143        print $sff_fh "RCPT TO:<$rcpt_to_cc>\n" if $rcpt_to_cc;
1144        print $sff_fh "DATA\n";
1145        print $sff_fh build_complete_message();
1146        my $success = close $sff_fh;
1147        if ($success ) {
1148            print "\nMessage sent\n";
1149            return;
1150        }
1151    }
1152    die "Mail transport failed (leaving bug report in $filename): $^E\n";
1153}
1154
1155sub _send_message_mailsend {
1156    my $msg = Mail::Send->new();
1157    my %headers = %{_message_headers()};
1158    for my $key ( keys %headers) {
1159        $msg->add($key => $headers{$key});
1160    }
1161
1162    $fh = $msg->open;
1163    binmode($fh, ':raw');
1164    print $fh _add_body_start() if $have_attachment;
1165    print $fh _read_report($filename);
1166    print $fh _add_attachments() if $have_attachment;
1167    $fh->close or die "Error sending mail: $!";
1168
1169    print "\nMessage sent.\n";
1170}
1171
1172sub _probe_for_sendmail {
1173    my $sendmail = "";
1174    for (qw(/usr/lib/sendmail /usr/sbin/sendmail /usr/ucblib/sendmail)) {
1175        $sendmail = $_, last if -e $_;
1176    }
1177    if ( $^O eq 'os2' and $sendmail eq "" ) {
1178        my $path = $ENV{PATH};
1179        $path =~ s:\\:/:;
1180        my @path = split /$Config{'path_sep'}/, $path;
1181        for (@path) {
1182            $sendmail = "$_/sendmail",     last if -e "$_/sendmail";
1183            $sendmail = "$_/sendmail.exe", last if -e "$_/sendmail.exe";
1184        }
1185    }
1186    return $sendmail;
1187}
1188
1189sub _send_message_sendmail {
1190    my $sendmail = _probe_for_sendmail();
1191    unless ($sendmail) {
1192        my $message_start = !$Is_Linux && !$Is_OpenBSD ? <<'EOT' : <<'EOT';
1193It appears that there is no program which looks like "sendmail" on
1194your system and that the Mail::Send library from CPAN isn't available.
1195EOT
1196It appears that there is no program which looks like "sendmail" on
1197your system.
1198EOT
1199        paraprint(<<"EOF"), die "\n";
1200$message_start
1201Because of this, there's no easy way to automatically send your
1202report.
1203
1204A copy of your report has been saved in '$filename' for you to
1205send to '$address' with your normal mail client.
1206EOF
1207    }
1208
1209    open( SENDMAIL, "|-:raw", $sendmail, "-t", "-oi", "-f", $from )
1210        || die "'|$sendmail -t -oi -f $from' failed: $!";
1211    print SENDMAIL build_complete_message();
1212    if ( close(SENDMAIL) ) {
1213        print "\nMessage sent\n";
1214    } else {
1215        warn "\nSendmail returned status '", $? >> 8, "'\n";
1216    }
1217}
1218
1219
1220
1221# a strange way to check whether any significant editing
1222# has been done: check whether any new non-empty lines
1223# have been added.
1224
1225sub _fingerprint_lines_in_report {
1226    my $new_lines = 0;
1227    # read in the report template once so that
1228    # we can track whether the user does any editing.
1229    # yes, *all* whitespace is ignored.
1230
1231    open(REP, '<:raw', $filename) or die "Unable to open report file '$filename': $!\n";
1232    binmode(REP, ':raw :crlf') if $Is_MSWin32;
1233    while (my $line = <REP>) {
1234        $line =~ s/\s+//g;
1235        $new_lines++ if (!$REP{$line});
1236
1237    }
1238    close(REP) or die "Error closing report file '$filename': $!";
1239    # returns the number of lines with content that wasn't there when last we looked
1240    return $new_lines;
1241}
1242
1243
1244
1245format STDOUT =
1246^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
1247$_
1248.
1249
1250__END__
1251
1252=head1 NAME
1253
1254perlbug - how to submit bug reports on Perl
1255
1256=head1 SYNOPSIS
1257
1258B<perlbug>
1259
1260B<perlbug> S<[ B<-v> ]> S<[ B<-a> I<address> ]> S<[ B<-s> I<subject> ]>
1261S<[ B<-b> I<body> | B<-f> I<inputfile> ]> S<[ B<-F> I<outputfile> ]>
1262S<[ B<-r> I<returnaddress> ]>
1263S<[ B<-e> I<editor> ]> S<[ B<-c> I<adminaddress> | B<-C> ]>
1264S<[ B<-S> ]> S<[ B<-t> ]>  S<[ B<-d> ]>  S<[ B<-h> ]> S<[ B<-T> ]>
1265
1266B<perlbug> S<[ B<-v> ]> S<[ B<-r> I<returnaddress> ]>
1267 S<[ B<-ok> | B<-okay> | B<-nok> | B<-nokay> ]>
1268
1269=head1 DESCRIPTION
1270
1271
1272This program is designed to help you generate bug reports
1273(and thank-you notes) about perl5 and the modules which ship with it.
1274
1275In most cases, you can just run it interactively from a command
1276line without any special arguments and follow the prompts.
1277
1278If you have found a bug with a non-standard port (one that was not
1279part of the I<standard distribution>), a binary distribution, or a
1280non-core module (such as Tk, DBI, etc), then please see the
1281documentation that came with that distribution to determine the
1282correct place to report bugs.
1283
1284Bug reports should be submitted to the GitHub issue tracker at
1285L<https://github.com/Perl/perl5/issues>. The B<perlbug@perl.org>
1286address no longer automatically opens tickets. You can use this tool
1287to compose your report and save it to a file which you can then submit
1288to the issue tracker.
1289
1290In extreme cases, B<perlbug> may not work well enough on your system
1291to guide you through composing a bug report. In those cases, you
1292may be able to use B<perlbug -d> or B<perl -V> to get system
1293configuration information to include in your issue report.
1294
1295
1296When reporting a bug, please run through this checklist:
1297
1298=over 4
1299
1300=item What version of Perl you are running?
1301
1302Type C<perl -v> at the command line to find out.
1303
1304=item Are you running the latest released version of perl?
1305
1306Look at L<http://www.perl.org/> to find out.  If you are not using the
1307latest released version, please try to replicate your bug on the
1308latest stable release.
1309
1310Note that reports about bugs in old versions of Perl, especially
1311those which indicate you haven't also tested the current stable
1312release of Perl, are likely to receive less attention from the
1313volunteers who build and maintain Perl than reports about bugs in
1314the current release.
1315
1316This tool isn't appropriate for reporting bugs in any version
1317prior to Perl 5.0.
1318
1319=item Are you sure what you have is a bug?
1320
1321A significant number of the bug reports we get turn out to be
1322documented features in Perl.  Make sure the issue you've run into
1323isn't intentional by glancing through the documentation that comes
1324with the Perl distribution.
1325
1326Given the sheer volume of Perl documentation, this isn't a trivial
1327undertaking, but if you can point to documentation that suggests
1328the behaviour you're seeing is I<wrong>, your issue is likely to
1329receive more attention. You may want to start with B<perldoc>
1330L<perltrap> for pointers to common traps that new (and experienced)
1331Perl programmers run into.
1332
1333If you're unsure of the meaning of an error message you've run
1334across, B<perldoc> L<perldiag> for an explanation.  If the message
1335isn't in perldiag, it probably isn't generated by Perl.  You may
1336have luck consulting your operating system documentation instead.
1337
1338If you are on a non-UNIX platform B<perldoc> L<perlport>, as some
1339features may be unimplemented or work differently.
1340
1341You may be able to figure out what's going wrong using the Perl
1342debugger.  For information about how to use the debugger B<perldoc>
1343L<perldebug>.
1344
1345=item Do you have a proper test case?
1346
1347The easier it is to reproduce your bug, the more likely it will be
1348fixed -- if nobody can duplicate your problem, it probably won't be
1349addressed.
1350
1351A good test case has most of these attributes: short, simple code;
1352few dependencies on external commands, modules, or libraries; no
1353platform-dependent code (unless it's a platform-specific bug);
1354clear, simple documentation.
1355
1356A good test case is almost always a good candidate to be included in
1357Perl's test suite.  If you have the time, consider writing your test case so
1358that it can be easily included into the standard test suite.
1359
1360=item Have you included all relevant information?
1361
1362Be sure to include the B<exact> error messages, if any.
1363"Perl gave an error" is not an exact error message.
1364
1365If you get a core dump (or equivalent), you may use a debugger
1366(B<dbx>, B<gdb>, etc) to produce a stack trace to include in the bug
1367report.
1368
1369NOTE: unless your Perl has been compiled with debug info
1370(often B<-g>), the stack trace is likely to be somewhat hard to use
1371because it will most probably contain only the function names and not
1372their arguments.  If possible, recompile your Perl with debug info and
1373reproduce the crash and the stack trace.
1374
1375=item Can you describe the bug in plain English?
1376
1377The easier it is to understand a reproducible bug, the more likely
1378it will be fixed.  Any insight you can provide into the problem
1379will help a great deal.  In other words, try to analyze the problem
1380(to the extent you can) and report your discoveries.
1381
1382=item Can you fix the bug yourself?
1383
1384If so, that's great news; bug reports with patches are likely to
1385receive significantly more attention and interest than those without
1386patches.  Please submit your patch via the GitHub Pull Request workflow
1387as described in B<perldoc> L<perlhack>.  You may also send patches to
1388B<perl5-porters@perl.org>.  When sending a patch, create it using
1389C<git format-patch> if possible, though a unified diff created with
1390C<diff -pu> will do nearly as well.
1391
1392Your patch may be returned with requests for changes, or requests for more
1393detailed explanations about your fix.
1394
1395Here are a few hints for creating high-quality patches:
1396
1397Make sure the patch is not reversed (the first argument to diff is
1398typically the original file, the second argument your changed file).
1399Make sure you test your patch by applying it with C<git am> or the
1400C<patch> program before you send it on its way.  Try to follow the
1401same style as the code you are trying to patch.  Make sure your patch
1402really does work (C<make test>, if the thing you're patching is covered
1403by Perl's test suite).
1404
1405=item Can you use C<perlbug> to submit a thank-you note?
1406
1407Yes, you can do this by using the C<-T> option.
1408Thank-you notes are good. It makes people
1409smile.
1410
1411=back
1412
1413Please make your issue title informative.  "a bug" is not informative.
1414Neither is "perl crashes" nor is "HELP!!!".  These don't help.  A compact
1415description of what's wrong is fine.
1416
1417Having done your bit, please be prepared to wait, to be told the
1418bug is in your code, or possibly to get no reply at all.  The
1419volunteers who maintain Perl are busy folks, so if your problem is
1420an obvious bug in your own code, is difficult to understand or is
1421a duplicate of an existing report, you may not receive a personal
1422reply.
1423
1424If it is important to you that your bug be fixed, do monitor the
1425issue tracker (you will be subscribed to notifications for issues you
1426submit or comment on) and the commit logs to development
1427versions of Perl, and encourage the maintainers with kind words or
1428offers of frosty beverages.  (Please do be kind to the maintainers.
1429Harassing or flaming them is likely to have the opposite effect of the
1430one you want.)
1431
1432Feel free to update the ticket about your bug on
1433L<https://github.com/Perl/perl5/issues>
1434if a new version of Perl is released and your bug is still present.
1435
1436=head1 OPTIONS
1437
1438=over 8
1439
1440=item B<-a>
1441
1442Address to send the report to instead of saving to a file.
1443
1444=item B<-b>
1445
1446Body of the report.  If not included on the command line, or
1447in a file with B<-f>, you will get a chance to edit the report.
1448
1449=item B<-C>
1450
1451Don't send copy to administrator when sending report by mail.
1452
1453=item B<-c>
1454
1455Address to send copy of report to when sending report by mail.
1456Defaults to the address of the
1457local perl administrator (recorded when perl was built).
1458
1459=item B<-d>
1460
1461Data mode (the default if you redirect or pipe output).  This prints out
1462your configuration data, without saving or mailing anything.  You can use
1463this with B<-v> to get more complete data.
1464
1465=item B<-e>
1466
1467Editor to use.
1468
1469=item B<-f>
1470
1471File containing the body of the report.  Use this to quickly send a
1472prepared report.
1473
1474=item B<-F>
1475
1476File to output the results to.  Defaults to B<perlbug.rep>.
1477
1478=item B<-h>
1479
1480Prints a brief summary of the options.
1481
1482=item B<-ok>
1483
1484Report successful build on this system to perl porters. Forces B<-S>
1485and B<-C>. Forces and supplies values for B<-s> and B<-b>. Only
1486prompts for a return address if it cannot guess it (for use with
1487B<make>). Honors return address specified with B<-r>.  You can use this
1488with B<-v> to get more complete data.   Only makes a report if this
1489system is less than 60 days old.
1490
1491=item B<-okay>
1492
1493As B<-ok> except it will report on older systems.
1494
1495=item B<-nok>
1496
1497Report unsuccessful build on this system.  Forces B<-C>.  Forces and
1498supplies a value for B<-s>, then requires you to edit the report
1499and say what went wrong.  Alternatively, a prepared report may be
1500supplied using B<-f>.  Only prompts for a return address if it
1501cannot guess it (for use with B<make>). Honors return address
1502specified with B<-r>.  You can use this with B<-v> to get more
1503complete data.  Only makes a report if this system is less than 60
1504days old.
1505
1506=item B<-nokay>
1507
1508As B<-nok> except it will report on older systems.
1509
1510=item B<-p>
1511
1512The names of one or more patch files or other text attachments to be
1513included with the report.  Multiple files must be separated with commas.
1514
1515=item B<-r>
1516
1517Your return address.  The program will ask you to confirm its default
1518if you don't use this option.
1519
1520=item B<-S>
1521
1522Save or send the report without asking for confirmation.
1523
1524=item B<-s>
1525
1526Subject to include with the report.  You will be prompted if you don't
1527supply one on the command line.
1528
1529=item B<-t>
1530
1531Test mode.  Makes it possible to command perlbug from a pipe or file, for
1532testing purposes.
1533
1534=item B<-T>
1535
1536Send a thank-you note instead of a bug report.
1537
1538=item B<-v>
1539
1540Include verbose configuration data in the report.
1541
1542=back
1543
1544=head1 AUTHORS
1545
1546Kenneth Albanowski (E<lt>kjahds@kjahds.comE<gt>), subsequently
1547I<doc>tored by Gurusamy Sarathy (E<lt>gsar@activestate.comE<gt>),
1548Tom Christiansen (E<lt>tchrist@perl.comE<gt>), Nathan Torkington
1549(E<lt>gnat@frii.comE<gt>), Charles F. Randall (E<lt>cfr@pobox.comE<gt>),
1550Mike Guy (E<lt>mjtg@cam.ac.ukE<gt>), Dominic Dunlop
1551(E<lt>domo@computer.orgE<gt>), Hugo van der Sanden (E<lt>hv@crypt.orgE<gt>),
1552Jarkko Hietaniemi (E<lt>jhi@iki.fiE<gt>), Chris Nandor
1553(E<lt>pudge@pobox.comE<gt>), Jon Orwant (E<lt>orwant@media.mit.eduE<gt>,
1554Richard Foley (E<lt>richard.foley@rfi.netE<gt>), Jesse Vincent
1555(E<lt>jesse@bestpractical.comE<gt>), and Craig A. Berry (E<lt>craigberry@mac.comE<gt>).
1556
1557=head1 SEE ALSO
1558
1559perl(1), perldebug(1), perldiag(1), perlport(1), perltrap(1),
1560diff(1), patch(1), dbx(1), gdb(1)
1561
1562=head1 BUGS
1563
1564None known (guess what must have been used to report them?)
1565
1566=cut
1567
1568!NO!SUBS!
1569
1570close OUT or die "Can't close $file: $!";
1571chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
1572exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
1573chdir $origdir;
1574