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