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