This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.003_01: utils/perlbug.PL
[perl5.git] / utils / perlbug.PL
CommitLineData
37fa004c 1#!/usr/local/bin/perl
2
3use Config;
4use File::Basename qw(&basename &dirname);
5
6# List explicitly here the variables you want Configure to
7# generate. Metaconfig only looks for shell variables, so you
8# have to mention them as if they were shell variables, not
9# %Config entries. Thus you write
10# $startperl
11# to ensure Configure will look for $Config{startperl}.
12
13# This forces PL files to create target in same directory as PL file.
14# This is so that make depend always knows where to find PL derivatives.
15chdir(dirname($0));
16($file = basename($0)) =~ s/\.PL$//;
17$file =~ s/\.pl$//
84478119 18 if ($^O eq 'VMS' or $^O eq 'os2'); # "case-forgiving"
37fa004c 19
20open OUT,">$file" or die "Can't create $file: $!";
21
22print "Extracting $file (with variable substitutions)\n";
23
24# In this section, perl variables will be expanded during extraction.
25# You can use $Config{...} to use Configure variables.
26
27print OUT <<"!GROK!THIS!";
28$Config{'startperl'}
29 eval 'exec perl -S \$0 "\$@"'
30 if 0;
31!GROK!THIS!
32
33# In the following, perl variables are not expanded during extraction.
34
35print OUT <<'!NO!SUBS!';
36
37use Config;
37fa004c 38use Getopt::Std;
39
c07a80fd 40BEGIN {
41 eval "use Mail::Send;";
42 $::HaveSend = ($@ eq "");
43 eval "use Mail::Util;";
44 $::HaveUtil = ($@ eq "");
45};
46
47
37fa004c 48use strict;
49
50sub paraprint;
51
c07a80fd 52
ab3ef367 53my($Version) = "1.14";
c07a80fd 54
55# Changed in 1.06 to skip Mail::Send and Mail::Util if not available.
a5f75d66
AD
56# Changed in 1.07 to see more sendmail execs, and added pipe output.
57# Changed in 1.08 to use correct address for sendmail.
c07a80fd 58# Changed in 1.09 to close the REP file before calling it up in the editor.
59# Also removed some old comments duplicated elsewhere.
60# Changed in 1.10 to run under VMS without Mail::Send; also fixed
a5f75d66 61# temp filename generation.
c07a80fd 62# Changed in 1.11 to clean up some text and removed Mail::Send deactivator.
a5f75d66
AD
63# Changed in 1.12 to check for editor errors, make save/send distinction
64# clearer and add $ENV{REPLYTO}.
84478119 65# Changed in 1.13 to hopefully make it more difficult to accidentally
66# send mail
ab3ef367 67# Changed in 1.14 to make the prompts a little more clear on providing
68# helpful information. Also let file read fail gracefully.
c07a80fd 69
70# TODO: Allow the user to re-name the file on mail failure, and
71# make sure failure (transmission-wise) of Mail::Send is
72# accounted for.
37fa004c 73
ab3ef367 74my( $file, $usefile, $cc, $address, $perlbug, $testaddress, $filename,
37fa004c 75 $subject, $from, $verbose, $ed,
76 $fh, $me, $Is_VMS, $msg, $body, $andcc );
77
78Init();
79
80if($::opt_h) { Help(); exit; }
81
84478119 82if(!-t STDIN) {
83 paraprint <<EOF;
84Please use perlbug interactively. If you want to
85include a file, you can use the -f switch.
86EOF
87 die "\n";
88}
89
c07a80fd 90if($::opt_d or !-t STDOUT) { Dump(*STDOUT); exit; }
91
37fa004c 92Query();
ab3ef367 93Edit() unless $usefile;
37fa004c 94NowWhat();
95Send();
96
97exit;
98
99sub Init {
100
101 # -------- Setup --------
102
84478119 103 $Is_VMS = $^O eq 'VMS';
37fa004c 104
c07a80fd 105 getopts("dhva:s:b:f:r:e:SCc:t");
37fa004c 106
107
108 # This comment is needed to notify metaconfig that we are
109 # using the $perladmin, $cf_by, and $cf_time definitions.
110
111
112 # -------- Configuration ---------
113
114 # perlbug address
115 $perlbug = 'perlbug@perl.com';
116
117 # Test address
118 $testaddress = 'perlbug-test@perl.com';
119
120 # Target address
121 $address = $::opt_a || ($::opt_t ? $testaddress : $perlbug);
122
123 # Possible administrator addresses, in order of confidence
124 # (Note that cf_email is not mentioned to metaconfig, since
125 # we don't really want it. We'll just take it if we have to.)
126 $cc = ($::opt_C ? "" : (
127 $::opt_c || $::Config{perladmin} || $::Config{cf_email} || $::Config{cf_by}
128 ));
129
130 # Users address, used in message and in Reply-To header
131 $from = $::opt_r || "";
132
133 # Include verbose configuration information
134 $verbose = $::opt_v || 0;
135
136 # Subject of bug-report message
137 $subject = $::opt_s || "";
138
ab3ef367 139 # Send a file
140 $usefile = ($::opt_f || 0);
141
37fa004c 142 # File to send as report
143 $file = $::opt_f || "";
144
145 # Body of report
146 $body = $::opt_b || "";
147
148 # Editor
ab3ef367 149 $ed = ( $::opt_e || $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT} ||
37fa004c 150 ($Is_VMS ? "edit/tpu" : "vi")
ab3ef367 151 );
152
37fa004c 153
154 # My username
155 $me = getpwuid($<);
156
157}
158
159
160sub Query {
161
162 # Explain what perlbug is
163
164 paraprint <<EOF;
ab3ef367 165This program provides an easy way to create a message reporting a bug in
166perl, and e-mail it to $address.
37fa004c 167
168EOF
169
170
171 # Prompt for subject of message, if needed
172 if(! $subject) {
173 paraprint <<EOF;
174First of all, please provide a subject for the
ab3ef367 175message. It should be a concise description of
176the bug or problem.
37fa004c 177
178EOF
179 print "Subject: ";
180
181 $subject = <>;
182 chop $subject;
183
184 my($err)=0;
185 while( $subject =~ /^\s*$/ ) {
186 print "\nPlease enter a subject: ";
187 $subject = <>;
188 chop $subject;
189 if($err++>5) {
190 die "Aborting.\n";
191 }
192 }
193 }
194
195
196 # Prompt for return address, if needed
197 if( !$from) {
198
199 # Try and guess return address
c07a80fd 200 my($domain);
201
202 if($::HaveUtil) {
203 $domain = Mail::Util::maildomain();
204 } elsif ($Is_VMS) {
205 require Sys::Hostname;
206 $domain = Sys::Hostname::hostname();
207 } else {
208 $domain = `hostname`.".".`domainname`;
209 $domain =~ s/[\r\n]+//g;
210 }
37fa004c 211
212 my($guess);
213
214 if( !$domain) {
215 $guess = "";
ab3ef367 216 } elsif ($Is_VMS && !$::Config{'has_sockets'}) {
c07a80fd 217 $guess = "$domain\:\:$me";
37fa004c 218 } else {
c07a80fd 219 $guess = "$me\@$domain" if $domain;
220 $guess = "$me\@unknown.addresss" unless $domain;
37fa004c 221 }
a5f75d66
AD
222
223 $guess = $ENV{'REPLYTO'} if defined($ENV{'REPLYTO'});
224 $guess = $ENV{"REPLY-TO"} if defined($ENV{'REPLY-TO'});
37fa004c 225
226 if( $guess ) {
227 paraprint <<EOF;
228
229
a5f75d66
AD
230Your e-mail address will be useful if you need to be contacted. If the
231default shown is not your full internet e-mail address, please correct it.
37fa004c 232
233EOF
234 } else {
235 paraprint <<EOF;
236
237So that you may be contacted if necessary, please enter
a5f75d66 238your full internet e-mail address here.
37fa004c 239
240EOF
241 }
242 print "Your address [$guess]: ";
243
244 $from = <>;
245 chop $from;
246
247 if($from eq "") { $from = $guess }
248
249 }
250
251 #if( $from =~ /^(.*)\@(.*)$/ ) {
252 # $mailname = $1;
253 # $maildomain = $2;
254 #}
255
256 if( $from eq $cc or $me eq $cc ) {
257 # Try not to copy ourselves
c07a80fd 258 $cc = "yourself";
37fa004c 259 }
260
261
262 # Prompt for administrator address, unless an override was given
263 if( !$::opt_C and !$::opt_c ) {
264 paraprint <<EOF;
265
266
267A copy of this report can be sent to your local
268perl administrator. If the address is wrong, please
c07a80fd 269correct it, or enter 'none' or 'yourself' to not send
270a copy.
37fa004c 271
272EOF
273
274 print "Local perl administrator [$cc]: ";
275
276 my($entry) = scalar(<>);
277 chop $entry;
278
279 if($entry ne "") {
280 $cc = $entry;
281 if($me eq $cc) { $cc = "" }
282 }
283
284 }
285
84478119 286 if($cc =~ /^(none|yourself|me|myself|ourselves)$/i) { $cc = "" }
37fa004c 287
288 $andcc = " and $cc" if $cc;
289
ab3ef367 290editor:
291
37fa004c 292 # Prompt for editor, if no override is given
293 if(! $::opt_e and ! $::opt_f and ! $::opt_b) {
294 paraprint <<EOF;
295
296
c07a80fd 297Now you need to supply the bug report. Try to make
37fa004c 298the report concise but descriptive. Include any
ab3ef367 299relevant detail. If you are reporting something
300that does not work as you think it should, please
301try to include example of both the actual
302result, and what you expected.
303
304Some information about your local
37fa004c 305perl configuration will automatically be included
ab3ef367 306at the end of the report. If you are using any
307unusual version of perl, please try and confirm
308exactly which versions are relevant.
37fa004c 309
310You will probably want to use an editor to enter
311the report. If "$ed" is the editor you want
312to use, then just press Enter, otherwise type in
313the name of the editor you would like to use.
314
c07a80fd 315If you would like to use a prepared file, type
37fa004c 316"file", and you will be asked for the filename.
317
318EOF
319
320 print "Editor [$ed]: ";
321
322 my($entry) =scalar(<>);
323 chop $entry;
ab3ef367 324
325 $usefile = 0;
326 if($entry eq "file") {
327 $usefile = 1;
328 } elsif($entry ne "") {
37fa004c 329 $ed = $entry;
330 }
331 }
332
333
334 # Generate scratch file to edit report in
335
c07a80fd 336 {
337 my($dir) = $Is_VMS ? 'sys$scratch:' : '/tmp/';
338 $filename = "bugrep0$$";
339 $filename++ while -e "$dir$filename";
340 $filename = "$dir$filename";
341 }
37fa004c 342
343
344 # Prompt for file to read report from, if needed
345
ab3ef367 346 if( $usefile and ! $file) {
347filename:
37fa004c 348 paraprint <<EOF;
349
37fa004c 350What is the name of the file that contains your report?
351
352EOF
353
354 print "Filename: ";
355
356 my($entry) = scalar(<>);
357 chop($entry);
358
ab3ef367 359 if($entry eq "") {
360 paraprint <<EOF;
361
362No filename? I'll let you go back and choose an editor again.
363
364EOF
365 goto editor;
366 }
367
37fa004c 368 if(!-f $entry or !-r $entry) {
ab3ef367 369 paraprint <<EOF;
370
371I'm sorry, but I can't read from `$entry'. Maybe you mistyped the name of
372the file? If you don't want to send a file, just enter a blank line and you
373can get back to the editor selection.
374
375EOF
376 goto filename;
37fa004c 377 }
378 $file = $entry;
379
380 }
381
382
383 # Generate report
384
385 open(REP,">$filename");
386
387 print REP <<EOF;
388This is a bug report for perl from $from,
389generated with the help of perlbug $Version running under perl $].
390
391EOF
392
393 if($body) {
394 print REP $body;
ab3ef367 395 } elsif($usefile) {
396 open(F,"<$file") or die "Unable to read report file from `$file': $!\n";
37fa004c 397 while(<F>) {
398 print REP $_
399 }
400 close(F);
401 } else {
402 print REP "[Please enter your report here]\n";
403 }
c07a80fd 404
405 Dump(*REP);
406 close(REP);
37fa004c 407
c07a80fd 408}
409
410sub Dump {
411 local(*OUT) = @_;
412
413 print OUT <<EOF;
37fa004c 414
415
416
417Site configuration information for perl $]:
418
419EOF
420
421 if( $::Config{cf_by} and $::Config{cf_time}) {
c07a80fd 422 print OUT "Configured by $::Config{cf_by} at $::Config{cf_time}.\n\n";
37fa004c 423 }
424
c07a80fd 425 print OUT Config::myconfig;
37fa004c 426
427 if($verbose) {
c07a80fd 428 print OUT "\nComplete configuration data for perl $]:\n\n";
37fa004c 429 my($value);
430 foreach (sort keys %::Config) {
431 $value = $::Config{$_};
432 $value =~ s/'/\\'/g;
c07a80fd 433 print OUT "$_='$value'\n";
37fa004c 434 }
435 }
37fa004c 436}
437
438sub Edit {
439 # Edit the report
ab3ef367 440
441 if($usefile) {
442 $usefile = 0;
443 paraprint <<EOF;
444
445Please make sure that the name of the editor you want to use is correct.
446
447EOF
448 print "Editor [$ed]: ";
449
450 my($entry) =scalar(<>);
451 chop $entry;
37fa004c 452
ab3ef367 453 if($entry ne "") {
454 $ed = $entry;
455 }
456 }
457
458tryagain:
459 if(!$usefile and !$body) {
c07a80fd 460 my($sts) = system("$ed $filename");
461 if( $Is_VMS ? !($sts & 1) : $sts ) {
a5f75d66
AD
462 #print "\nUnable to run editor!\n";
463 paraprint <<EOF;
464
465The editor you chose (`$ed') could apparently not be run!
466Did you mistype the name of your editor? If so, please
467correct it here, otherwise just press Enter.
468
469EOF
470 print "Editor [$ed]: ";
471
472 my($entry) =scalar(<>);
473 chop $entry;
474
475 if($entry ne "") {
476 $ed = $entry;
477 goto tryagain;
478 } else {
479
480 paraprint <<EOF;
481
482You may want to save your report to a file, so you can edit and mail it
483yourself.
484EOF
485 }
37fa004c 486 }
487 }
488}
489
490sub NowWhat {
491
492 # Report is done, prompt for further action
493 if( !$::opt_S ) {
494 while(1) {
495
496 paraprint <<EOF;
497
498
499Now that you have completed your report, would you like to send
500the message to $address$andcc, display the message on
501the screen, re-edit it, or cancel without sending anything?
502You may also save the message as a file to mail at another time.
503
504EOF
505
a5f75d66 506 print "Action (Send/Display/Edit/Cancel/Save to File): ";
37fa004c 507 my($action) = scalar(<>);
508 chop $action;
509
a5f75d66 510 if( $action =~ /^(f|sa)/i ) { # <F>ile/<Sa>ve
37fa004c 511 print "\n\nName of file to save message in [perlbug.rep]: ";
512 my($file) = scalar(<>);
513 chop $file;
514 if($file eq "") { $file = "perlbug.rep" }
515
516 open(FILE,">$file");
517 open(REP,"<$filename");
518 print FILE "To: $address\nSubject: $subject\n";
519 print FILE "Cc: $cc\n" if $cc;
520 print FILE "Reply-To: $from\n" if $from;
521 print FILE "\n";
522 while(<REP>) { print FILE }
523 close(REP);
524 close(FILE);
525
526 print "\nMessage saved in `$file'.\n";
527 exit;
528
a5f75d66 529 } elsif( $action =~ /^(d|l|sh)/i ) { # <D>isplay, <L>ist, <Sh>ow
37fa004c 530 # Display the message
531 open(REP,"<$filename");
532 while(<REP>) { print $_ }
533 close(REP);
84478119 534 } elsif( $action =~ /^se/i ) { # <S>end
a5f75d66 535 # Send the message
84478119 536 print "\
537Are you certain you want to send this message?
538Please type \"yes\" if you are: ";
539 my($reply) = scalar(<STDIN>);
540 chop($reply);
541 if( $reply eq "yes" ) {
542 last;
ab3ef367 543 } else {
544 paraprint <<EOF;
545
546That wasn't a clear "yes", so I won't send your message. If you are sure
547your message should be sent, type in "yes" (without the quotes) at the
548confirmation prompt.
549
550EOF
551
84478119 552 }
a5f75d66 553 } elsif( $action =~ /^[er]/i ) { # <E>dit, <R>e-edit
37fa004c 554 # edit the message
a5f75d66
AD
555 Edit();
556 #system("$ed $filename");
557 } elsif( $action =~ /^[qc]/i ) { # <C>ancel, <Q>uit
37fa004c 558 1 while unlink($filename); # remove all versions under VMS
559 print "\nCancelling.\n";
560 exit(0);
84478119 561 } elsif( $action =~ /^s/ ) {
562 paraprint <<EOF;
563
564I'm sorry, but I didn't understand that. Please type "send" or "save".
565EOF
37fa004c 566 }
567
568 }
569 }
570}
571
572
573sub Send {
574
575 # Message has been accepted for transmission -- Send the message
c07a80fd 576
577 if($::HaveSend) {
37fa004c 578
c07a80fd 579 $msg = new Mail::Send Subject => $subject, To => $address;
37fa004c 580
c07a80fd 581 $msg->cc($cc) if $cc;
582 $msg->add("Reply-To",$from) if $from;
37fa004c 583
c07a80fd 584 $fh = $msg->open;
585
586 open(REP,"<$filename");
587 while(<REP>) { print $fh $_ }
588 close(REP);
37fa004c 589
c07a80fd 590 $fh->close;
591
592 } else {
593 if ($Is_VMS) {
594 if ( ($address =~ /@/ and $address !~ /^\w+%"/) or
595 ($cc =~ /@/ and $cc !~ /^\w+%"/) ){
596 my($prefix);
597 foreach (qw[ IN MX SMTP UCX PONY WINS ],'') {
598 $prefix = "$_%",last if $ENV{"MAIL\$PROTOCOL_$_"};
599 }
600 $address = qq[${prefix}"$address"] unless $address =~ /^\w+%"/;
601 $cc = qq[${prefix}"$cc"] unless !$cc || $cc =~ /^\w+%"/;
602 }
603 $subject =~ s/"/""/g; $address =~ s/"/""/g; $cc =~ s/"/""/g;
604 my($sts) = system(qq[mail/Subject="$subject" $filename. "$address","$cc"]);
605 if (!($sts & 1)) { die "Can't spawn off mail\n\t(leaving bug report in $filename): $sts\n;" }
606 } else {
607 my($sendmail) = "";
608
609 foreach (qw(/usr/lib/sendmail /usr/sbin/sendmail /usr/ucblib/sendmail))
610 {
611 $sendmail = $_, last if -e $_;
612 }
613
614 paraprint <<"EOF" and die "\n" if $sendmail eq "";
615
616I am terribly sorry, but I cannot find sendmail, or a close equivalent, and
617the perl package Mail::Send has not been installed, so I can't send your bug
618report. We apologize for the inconveniencence.
619
620So you may attempt to find some way of sending your message, it has
621been left in the file `$filename'.
622
623EOF
624
625 open(SENDMAIL,"|$sendmail -t");
626 print SENDMAIL "To: $address\n";
627 print SENDMAIL "Subject: $subject\n";
628 print SENDMAIL "Cc: $cc\n" if $cc;
629 print SENDMAIL "Reply-To: $from\n" if $from;
630 print SENDMAIL "\n\n";
631 open(REP,"<$filename");
632 while(<REP>) { print SENDMAIL $_ }
633 close(REP);
634
635 close(SENDMAIL);
636 }
37fa004c 637
c07a80fd 638 }
37fa004c 639
640 print "\nMessage sent.\n";
641
642 1 while unlink($filename); # remove all versions under VMS
643
644}
645
646sub Help {
647 print <<EOF;
648
649A program to help generate bug reports about perl5, and mail them.
650It is designed to be used interactively. Normally no arguments will
651be needed.
652
653Usage:
654$0 [-v] [-a address] [-s subject] [-b body | -f file ]
655 [-r returnaddress] [-e editor] [-c adminaddress | -C] [-S] [-t]
656
c07a80fd 657Simplest usage: run "$0", and follow the prompts.
37fa004c 658
659Options:
660
661 -v Include Verbose configuration data in the report
662 -f File containing the body of the report. Use this to
663 quickly send a prepared message.
664 -S Send without asking for confirmation.
665 -a Address to send the report to. Defaults to `$address'.
666 -c Address to send copy of report to. Defaults to `$cc'.
667 -C Don't send copy to administrator.
668 -s Subject to include with the message. You will be prompted
669 if you don't supply one on the command line.
670 -b Body of the report. If not included on the command line, or
671 in a file with -f, you will get a chance to edit the message.
672 -r Your return address. The program will ask you to confirm
673 this if you don't give it here.
674 -e Editor to use.
675 -t Test mode. The target address defaults to `$testaddress'.
c07a80fd 676 -d Data mode (the default if you redirect or pipe output.)
677 This prints out your configuration data, without mailing
678 anything. You can use this with -v to get more complete data.
37fa004c 679
680EOF
681}
682
683sub paraprint {
684 my @paragraphs = split /\n{2,}/, "@_";
c07a80fd 685 print "\n\n";
37fa004c 686 for (@paragraphs) { # implicit local $_
687 s/(\S)\s*\n/$1 /g;
688 write;
689 print "\n";
690 }
691
692}
693
694
695format STDOUT =
696^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
697$_
698.
699!NO!SUBS!
700
701close OUT or die "Can't close $file: $!";
702chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
703exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';