This file is indexed.

/usr/bin/perlbug is in perl 5.26.1-6.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
#!/usr/bin/perl
    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
	if $running_under_some_shell;

my $config_tag1 = '5.26.1 - Sat Mar 10 18:40:42 UTC 2018';

my $patchlevel_date = 1520707242;
my @patches = Config::local_patches();
my $patch_tags = join "", map /(\S+)/ ? "+$1 " : (), @patches;

BEGIN { pop @INC if $INC[-1] eq '.' }
use warnings;
use strict;
use Config;
use File::Spec;		# keep perlbug Perl 5.005 compatible
use Getopt::Std;
use File::Basename 'basename';

sub paraprint;

BEGIN {
    eval { require Mail::Send;};
    $::HaveSend = ($@ eq "");
    eval { require Mail::Util; } ;
    $::HaveUtil = ($@ eq "");
    # use secure tempfiles wherever possible
    eval { require File::Temp; };
    $::HaveTemp = ($@ eq "");
    eval { require Module::CoreList; };
    $::HaveCoreList = ($@ eq "");
    eval { require Text::Wrap; };
    $::HaveWrap = ($@ eq "");
};

my $Version = "1.40";

#TODO:
#       make sure failure (transmission-wise) of Mail::Send is accounted for.
#       (This may work now. Unsure of the original author's issue -JESSE 2008-06-08)
#       - Test -b option

my( $file, $usefile, $cc, $address, $bugaddress, $testaddress, $thanksaddress,
    $filename, $messageid, $domain, $subject, $from, $verbose, $ed, $outfile,
    $fh, $me, $body, $andcc, %REP, $ok, $thanks, $progname,
    $Is_MSWin32, $Is_Linux, $Is_VMS, $Is_OpenBSD,
    $report_about_module, $category, $severity,
    %opt, $have_attachment, $attachments, $has_patch, $mime_boundary
);

my $running_noninteractively = !-t STDIN;

my $perl_version = $^V ? sprintf("%vd", $^V) : $];

my $config_tag2 = "$perl_version - $Config{cf_time}";

Init();

if ($opt{h}) { Help(); exit; }
if ($opt{d}) { Dump(*STDOUT); exit; }
if ($running_noninteractively && !$opt{t} && !($ok and not $opt{n})) {
    paraprint <<"EOF";
Please use $progname interactively. If you want to
include a file, you can use the -f switch.
EOF
    die "\n";
}

Query();
Edit() unless $usefile || ($ok and not $opt{n});
NowWhat();
if ($outfile) {
    save_message_to_disk($outfile);
} else {
    Send();
    if ($thanks) {
	print "\nThank you for taking the time to send a thank-you message!\n\n";

	paraprint <<EOF
Please note that mailing lists are moderated, your message may take a while to
show up.
EOF
    } else {
	print "\nThank you for taking the time to file a bug report!\n\n";

	paraprint <<EOF
Please note that mailing lists are moderated, your message may take a while to
show up. If you do not receive an automated response acknowledging your message
within a few hours (check your SPAM folder and outgoing mail) please consider
sending an email directly from your mail client to perlbug\@perl.org.
EOF
    }

}

exit;

sub ask_for_alternatives { # (category|severity)
    my $name = shift;
    my %alts = (
	'category' => {
	    'default' => 'core',
	    'ok'      => 'install',
	    # Inevitably some of these will end up in RT whatever we do:
	    'thanks'  => 'thanks',
	    'opts'    => [qw(core docs install library utilities)], # patch, notabug
	},
	'severity' => {
	    'default' => 'low',
	    'ok'      => 'none',
	    'thanks'  => 'none',
	    'opts'    => [qw(critical high medium low wishlist none)], # zero
	},
    );
    die "Invalid alternative ($name) requested\n" unless grep(/^$name$/, keys %alts);
    my $alt = "";
    my $what = $ok || $thanks;
    if ($what) {
	$alt = $alts{$name}{$what};
    } else {
 	my @alts = @{$alts{$name}{'opts'}};
    print "\n\n";
	paraprint <<EOF;
Please pick a $name from the following list:

    @alts
EOF
	my $err = 0;
	do {
	    if ($err++ > 5) {
		die "Invalid $name: aborting.\n";
	    }
        $alt = _prompt('', "\u$name", $alts{$name}{'default'});
		$alt ||= $alts{$name}{'default'};
	} while !((($alt) = grep(/^$alt/i, @alts)));
    }
    lc $alt;
}

sub Init {
    # -------- Setup --------

    $Is_MSWin32 = $^O eq 'MSWin32';
    $Is_VMS = $^O eq 'VMS';
    $Is_Linux = lc($^O) eq 'linux';
    $Is_OpenBSD = lc($^O) eq 'openbsd';

    if (!getopts("Adhva:s:b:f:F:r:e:SCc:to:n:T:p:", \%opt)) { Help(); exit; };

    # This comment is needed to notify metaconfig that we are
    # using the $perladmin, $cf_by, and $cf_time definitions.

    # -------- Configuration ---------

    # perlbug address
    $bugaddress = 'perlbug@perl.org';

    # Test address
    $testaddress = 'perlbug-test@perl.org';

    # Thanks address
    $thanksaddress = 'perl-thanks@perl.org';

    if (basename ($0) =~ /^perlthanks/i) {
	# invoked as perlthanks
	$opt{T} = 1;
	$opt{C} = 1; # don't send a copy to the local admin
    }

    if ($opt{T}) {
	$thanks = 'thanks';
    }
    
    $progname = $thanks ? 'perlthanks' : 'perlbug';
    # Target address
    $address = $opt{a} || ($opt{t} ? $testaddress
			    : $thanks ? $thanksaddress : $bugaddress);

    # Users address, used in message and in From and Reply-To headers
    $from = $opt{r} || "";

    # Include verbose configuration information
    $verbose = $opt{v} || 0;

    # Subject of bug-report message
    $subject = $opt{s} || "";

    # Send a file
    $usefile = ($opt{f} || 0);

    # File to send as report
    $file = $opt{f} || "";

    # We have one or more attachments
    $have_attachment = ($opt{p} || 0);
    $mime_boundary = ('-' x 12) . "$Version.perlbug" if $have_attachment;

    # Comma-separated list of attachments
    $attachments = $opt{p} || "";
    $has_patch = 0; # TBD based on file type

    for my $attachment (split /\s*,\s*/, $attachments) {
        unless (-f $attachment && -r $attachment) {
            die "The attachment $attachment is not a readable file: $!\n";
        }
        $has_patch = 1 if $attachment =~ m/\.(patch|diff)$/;
    }

    # File to output to
    $outfile = $opt{F} || "";

    # Body of report
    $body = $opt{b} || "";
	
    # Editor
    $ed = $opt{e} || $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT}
	|| ($Is_VMS && "edit/tpu")
	|| ($Is_MSWin32 && "notepad")
	|| "vi";

    # Not OK - provide build failure template by finessing OK report
    if ($opt{n}) {
	if (substr($opt{n}, 0, 2) eq 'ok' )	{
	    $opt{o} = substr($opt{n}, 1);
	} else {
	    Help();
	    exit();
	}
    }

    # OK - send "OK" report for build on this system
    $ok = '';
    if ($opt{o}) {
	if ($opt{o} eq 'k' or $opt{o} eq 'kay') {
	    my $age = time - $patchlevel_date;
	    if ($opt{o} eq 'k' and $age > 60 * 24 * 60 * 60 ) {
		my $date = localtime $patchlevel_date;
		print <<"EOF";
"perlbug -ok" and "perlbug -nok" do not report on Perl versions which
are more than 60 days old.  This Perl version was constructed on
$date.  If you really want to report this, use
"perlbug -okay" or "perlbug -nokay".
EOF
		exit();
	    }
	    # force these options
	    unless ($opt{n}) {
		$opt{S} = 1; # don't prompt for send
		$opt{b} = 1; # we have a body
		$body = "Perl reported to build OK on this system.\n";
	    }
	    $opt{C} = 1; # don't send a copy to the local admin
	    $opt{s} = 1; # we have a subject line
	    $subject = ($opt{n} ? 'Not ' : '')
		    . "OK: perl $perl_version ${patch_tags}on"
		    ." $::Config{'archname'} $::Config{'osvers'} $subject";
	    $ok = 'ok';
	} else {
	    Help();
	    exit();
	}
    }

    # Possible administrator addresses, in order of confidence
    # (Note that cf_email is not mentioned to metaconfig, since
    # we don't really want it. We'll just take it if we have to.)
    #
    # This has to be after the $ok stuff above because of the way
    # that $opt{C} is forced.
    $cc = $opt{C} ? "" : (
	$opt{c} || $::Config{'perladmin'}
	|| $::Config{'cf_email'} || $::Config{'cf_by'}
    );

    if ($::HaveUtil) {
		$domain = Mail::Util::maildomain();
    } elsif ($Is_MSWin32) {
		$domain = $ENV{'USERDOMAIN'};
    } else {
		require Sys::Hostname;
		$domain = Sys::Hostname::hostname();
    }

    # Message-Id - rjsf
    $messageid = "<$::Config{'version'}_${$}_".time."\@$domain>"; 

    # My username
    $me = $Is_MSWin32 ? $ENV{'USERNAME'}
	    : $^O eq 'os2' ? $ENV{'USER'} || $ENV{'LOGNAME'}
	    : eval { getpwuid($<) };	# May be missing

    $from = $::Config{'cf_email'}
       if !$from && $::Config{'cf_email'} && $::Config{'cf_by'} && $me &&
               ($me eq $::Config{'cf_by'});
} # sub Init

sub Query {
    # Explain what perlbug is
    unless ($ok) {
	if ($thanks) {
	    paraprint <<'EOF';
This program provides an easy way to send a thank-you message back to the
authors and maintainers of perl.

If you wish to submit a bug report, please run it without the -T flag
(or run the program perlbug rather than perlthanks)
EOF
	} else {
	    paraprint <<"EOF";
This program provides an easy way to create a message reporting a
bug in the core perl distribution (along with tests or patches)
to the volunteers who maintain perl at $address.  To send a thank-you
note to $thanksaddress instead of a bug report, please run 'perlthanks'.

Please do not use $0 to send test messages, test whether perl
works, or to report bugs in perl modules from CPAN.

Suggestions for how to find help using Perl can be found at
http://perldoc.perl.org/perlcommunity.html
EOF
	}
    }

    # Prompt for subject of message, if needed
    
    if ($subject && TrivialSubject($subject)) {
	$subject = '';
    }

    unless ($subject) {
	    print 
"First of all, please provide a subject for the message.\n";
	if ( not $thanks)  {
	    paraprint <<EOF;
This should be a concise description of your bug or problem
which will help the volunteers working to improve perl to categorize
and resolve the issue.  Be as specific and descriptive as
you can. A subject like "perl bug" or "perl problem" will make it
much less likely that your issue gets the attention it deserves.
EOF
	}

	my $err = 0;
	do {
        $subject = _prompt('','Subject');
	    if ($err++ == 5) {
		if ($thanks) {
		    $subject = 'Thanks for Perl';
		} else {
		    die "Aborting.\n";
		}
	    }
	} while (TrivialSubject($subject));
    }
    $subject = '[PATCH] ' . $subject
        if $has_patch && ($subject !~ m/^\[PATCH/i);

    # Prompt for return address, if needed
    unless ($opt{r}) {
	# Try and guess return address
	my $guess;

	$guess = $ENV{'REPLY-TO'} || $ENV{'REPLYTO'} || $ENV{'EMAIL'}
	    || $from || '';

	unless ($guess) {
		# move $domain to where we can use it elsewhere	
        if ($domain) {
		if ($Is_VMS && !$::Config{'d_socket'}) {
		    $guess = "$domain\:\:$me";
		} else {
		    $guess = "$me\@$domain" if $domain;
		}
	    }
	}

	if ($guess) {
	    unless ($ok) {
		paraprint <<EOF;
Perl's developers may need your email address to contact you for
further information about your issue or to inform you when it is
resolved.  If the default shown is not your email address, please
correct it.
EOF
	    }
	} else {
	    paraprint <<EOF;
Please enter your full internet email address so that Perl's
developers can contact you with questions about your issue or to
inform you that it has been resolved.
EOF
	}

	if ($ok && $guess) {
	    # use it
	    $from = $guess;
	} else {
	    # verify it
        $from = _prompt('','Your address',$guess);
	    $from = $guess if $from eq '';
	}
    }

    if ($from eq $cc or $me eq $cc) {
	# Try not to copy ourselves
	$cc = "yourself";
    }

    # Prompt for administrator address, unless an override was given
    if( !$opt{C} and !$opt{c} ) {
	my $description =  <<EOF;
$0 can send a copy of this report to your local perl
administrator.  If the address below is wrong, please correct it,
or enter 'none' or 'yourself' to not send a copy.
EOF
	my $entry = _prompt($description, "Local perl administrator", $cc);

	if ($entry ne "") {
	    $cc = $entry;
	    $cc = '' if $me eq $cc;
	}
    }

    $cc = '' if $cc =~ /^(none|yourself|me|myself|ourselves)$/i;
    if ($cc) { 
        $andcc = " and $cc" 
    } else {
        $andcc = ''
    }

    # Prompt for editor, if no override is given
editor:
    unless ($opt{e} || $opt{f} || $opt{b}) {

    my $description;

	chomp (my $common_end = <<"EOF");
You will probably want to use a text editor to enter the body of
your report. If "$ed" is the editor you want to use, then just press
Enter, otherwise type in the name of the editor you would like to
use.

If you have already composed the body of your report, you may enter
"file", and $0 will prompt you to enter the name of the file
containing your report.
EOF

	if ($thanks) {
	    $description = <<"EOF";
It's now time to compose your thank-you message.

Some information about your local perl configuration will automatically
be included at the end of your message, because we're curious about
the different ways that people build and use perl. If you'd rather
not share this information, you're welcome to delete it.

$common_end
EOF
	} else {
	    $description =  <<"EOF";
It's now time to compose your bug report. Try to make the report
concise but descriptive. Please include any detail which you think
might be relevant or might help the volunteers working to improve
perl. If you are reporting something that does not work as you think
it should, please try to include examples of the actual result and of
what you expected.

Some information about your local perl configuration will automatically
be included at the end of your report. If you are using an unusual
version of perl, it would be useful if you could confirm that you
can replicate the problem on a standard build of perl as well.

$common_end
EOF
	}

    my $entry = _prompt($description, "Editor", $ed);
	$usefile = 0;
	if ($entry eq "file") {
	    $usefile = 1;
	} elsif ($entry ne "") {
	    $ed = $entry;
	}
    }
    if ($::HaveCoreList && !$ok && !$thanks) {
	my $description =  <<EOF;
If your bug is about a Perl module rather than a core language
feature, please enter its name here. If it's not, just hit Enter
to skip this question.
EOF

    my $entry = '';
	while ($entry eq '') {
        $entry = _prompt($description, 'Module');
	    my $first_release = Module::CoreList->first_release($entry);
	    if ($entry and not $first_release) {
		paraprint <<EOF;
$entry is not a "core" Perl module. Please check that you entered
its name correctly. If it is correct, quit this program, try searching
for $entry on http://rt.cpan.org, and report your issue there.
EOF

            $entry = '';
	} elsif (my $bug_tracker = $Module::CoreList::bug_tracker{$entry}) {
		paraprint <<"EOF";
$entry included with core Perl is copied directly from the CPAN distribution.
Please report bugs in $entry directly to its maintainers using $bug_tracker
EOF
            $entry = '';
        } elsif ($entry) {
	        $category ||= 'library';
	        $report_about_module = $entry;
            last;
        } else {
            last;
        }
	}
    }

    # Prompt for category of bug
    $category ||= ask_for_alternatives('category');

    # Prompt for severity of bug
    $severity ||= ask_for_alternatives('severity');

    # Generate scratch file to edit report in
    $filename = filename();

    # Prompt for file to read report from, if needed
    if ($usefile and !$file) {
filename:
	my $description = <<EOF;
What is the name of the file that contains your report?
EOF
	my $entry = _prompt($description, "Filename");

	if ($entry eq "") {
	    paraprint <<EOF;
It seems you didn't enter a filename. Please choose to use a text
editor or enter a filename.
EOF
	    goto editor;
	}

	unless (-f $entry and -r $entry) {
	    paraprint <<EOF;
'$entry' doesn't seem to be a readable file.  You may have mistyped
its name or may not have permission to read it.

If you don't want to use a file as the content of your report, just
hit Enter and you'll be able to select a text editor instead.
EOF
	    goto filename;
	}
	$file = $entry;
    }

    # Generate report
    open(REP, '>:raw', $filename) or die "Unable to create report file '$filename': $!\n";
    binmode(REP, ':raw :crlf') if $Is_MSWin32;

    my $reptype = !$ok ? ($thanks ? 'thank-you' : 'bug')
	: $opt{n} ? "build failure" : "success";

    print REP <<EOF;
This is a $reptype report for perl from $from,
generated with the help of perlbug $Version running under perl $perl_version.

EOF

    if ($body) {
	print REP $body;
    } elsif ($usefile) {
	open(F, '<:raw', $file)
		or die "Unable to read report file from '$file': $!\n";
	binmode(F, ':raw :crlf') if $Is_MSWin32;
	while (<F>) {
	    print REP $_
	}
	close(F) or die "Error closing '$file': $!";
    } else {
	if ($thanks) {
	    print REP <<'EOF';

-----------------------------------------------------------------
[Please enter your thank-you message here]



[You're welcome to delete anything below this line]
-----------------------------------------------------------------
EOF
	} else {
	    print REP <<'EOF';

-----------------------------------------------------------------
[Please describe your issue here]



[Please do not change anything below this line]
-----------------------------------------------------------------
EOF
	}
    }
    Dump(*REP);
    close(REP) or die "Error closing report file: $!";

    # Set up an initial report fingerprint so we can compare it later
    _fingerprint_lines_in_report();

} # sub Query

sub Dump {
    local(*OUT) = @_;

    # these won't have been set if run with -d
    $category ||= 'core';
    $severity ||= 'low';

    print OUT <<EFF;
---
Flags:
    category=$category
    severity=$severity
EFF

    if ($has_patch) {
        print OUT <<EFF;
    Type=Patch
    PatchStatus=HasPatch
EFF
    }

    if ($report_about_module ) { 
        print OUT <<EFF;
    module=$report_about_module
EFF
    }
    if ($opt{A}) {
	print OUT <<EFF;
    ack=no
EFF
    }
    print OUT <<EFF;
---
EFF
    print OUT "This perlbug was built using Perl $config_tag1\n",
	    "It is being executed now by  Perl $config_tag2.\n\n"
	if $config_tag2 ne $config_tag1;

    print OUT <<EOF;
Site configuration information for perl $perl_version:

EOF
    if ($::Config{cf_by} and $::Config{cf_time}) {
	print OUT "Configured by $::Config{cf_by} at $::Config{cf_time}.\n\n";
    }
    print OUT Config::myconfig;

    if (@patches) {
	print OUT join "\n    ", "Locally applied patches:", @patches;
	print OUT "\n";
    };

    print OUT <<EOF;

---
\@INC for perl $perl_version:
EOF
    for my $i (@INC) {
	print OUT "    $i\n";
    }

    print OUT <<EOF;

---
Environment for perl $perl_version:
EOF
    my @env =
        qw(PATH LD_LIBRARY_PATH LANG PERL_BADLANG SHELL HOME LOGDIR LANGUAGE);
    push @env, $Config{ldlibpthname} if $Config{ldlibpthname} ne '';
    push @env, grep /^(?:PERL|LC_|LANG|CYGWIN)/, keys %ENV;
    my %env;
    @env{@env} = @env;
    for my $env (sort keys %env) {
	print OUT "    $env",
		exists $ENV{$env} ? "=$ENV{$env}" : ' (unset)',
		"\n";
    }
    if ($verbose) {
	print OUT "\nComplete configuration data for perl $perl_version:\n\n";
	my $value;
	foreach (sort keys %::Config) {
	    $value = $::Config{$_};
	    $value = '' unless defined $value;
	    $value =~ s/'/\\'/g;
	    print OUT "$_='$value'\n";
	}
    }
} # sub Dump

sub Edit {
    # Edit the report
    if ($usefile || $body) {
	my $description = "Please make sure that the name of the editor you want to use is correct.";
	my $entry = _prompt($description, 'Editor', $ed);
	$ed = $entry unless $entry eq '';
    }

    _edit_file($ed) unless $running_noninteractively;
}

sub _edit_file {
    my $editor = shift;

    my $report_written = 0;

    while ( !$report_written ) {
        my $exit_status = system("$editor $filename");
        if ($exit_status) {
            my $desc = <<EOF;
The editor you chose ('$editor') could not be run!

If you mistyped its name, please enter it now, otherwise just press Enter.
EOF
            my $entry = _prompt( $desc, 'Editor', $editor );
            if ( $entry ne "" ) {
                $editor = $entry;
                next;
            } else {
                paraprint <<EOF;
You may want to save your report to a file, so you can edit and
mail it later.
EOF
                return;
            }
        }
        return if ( $ok and not $opt{n} ) || $body;

        # Check that we have a report that has some, eh, report in it.

        unless ( _fingerprint_lines_in_report() ) {
            my $description = <<EOF;
It looks like you didn't enter a report. You may [r]etry your edit
or [c]ancel this report.
EOF
            my $action = _prompt( $description, "Action (Retry/Cancel) " );
            if ( $action =~ /^[re]/i ) {    # <R>etry <E>dit
                next;
            } elsif ( $action =~ /^[cq]/i ) {    # <C>ancel, <Q>uit
                Cancel();                        # cancel exits
            }
        }
        # Ok. the user did what they needed to;
        return;

    }
}


sub Cancel {
    1 while unlink($filename);  # remove all versions under VMS
    print "\nQuitting without sending your message.\n";
    exit(0);
}

sub NowWhat {
    # Report is done, prompt for further action
    if( !$opt{S} ) {
	while(1) {
	    my $menu = <<EOF;


You have finished composing your message. At this point, you have 
a few options. You can:

    * [Se]nd the message to $address$andcc, 
    * [D]isplay the message on the screen,
    * [R]e-edit the message
    * Display or change the message's [su]bject
    * Save the message to a [f]ile to mail at another time
    * [Q]uit without sending a message

EOF
      retry:
        print $menu;
	    my $action =  _prompt('', "Action (Send/Display/Edit/Subject/Save to File)",
	        $opt{t} ? 'q' : '');
        print "\n";
	    if ($action =~ /^(f|sa)/i) { # <F>ile/<Sa>ve
            if ( SaveMessage() ) { exit }
	    } elsif ($action =~ /^(d|l|sh)/i ) { # <D>isplay, <L>ist, <Sh>ow
		# Display the message
		print _read_report($filename);
		if ($have_attachment) {
		    print "\n\n---\nAttachment(s):\n";
		    for my $att (split /\s*,\s*/, $attachments) { print "    $att\n"; }
		}
	    } elsif ($action =~ /^su/i) { # <Su>bject
		my $reply = _prompt( "Subject: $subject", "If the above subject is fine, press Enter. Otherwise, type a replacement now\nSubject");
		if ($reply ne '') {
		    unless (TrivialSubject($reply)) {
			$subject = $reply;
			print "Subject: $subject\n";
		    }
		}
	    } elsif ($action =~ /^se/i) { # <S>end
		# Send the message
		my $reply =  _prompt( "Are you certain you want to send this message?", 'Please type "yes" if you are','no');
		if ($reply =~ /^yes$/) {
		    last;
		} else {
		    paraprint <<EOF;
You didn't type "yes", so your message has not yet been sent.
EOF
		}
	    } elsif ($action =~ /^[er]/i) { # <E>dit, <R>e-edit
		# edit the message
		Edit();
	    } elsif ($action =~ /^[qc]/i) { # <C>ancel, <Q>uit
		Cancel();
	    } elsif ($action =~ /^s/i) {
		paraprint <<EOF;
The command you entered was ambiguous. Please type "send", "save" or "subject".
EOF
	    }
	}
    }
} # sub NowWhat

sub TrivialSubject {
    my $subject = shift;
    if ($subject =~
	/^(y(es)?|no?|help|perl( (bug|problem))?|bug|problem)$/i ||
	length($subject) < 4 ||
	($subject !~ /\s/ && ! $opt{t})) { # non-whitespace is accepted in test mode
	print "\nThe subject you entered wasn't very descriptive. Please try again.\n\n";
        return 1;
    } else {
	return 0;
    }
}

sub SaveMessage {
    my $file_save = $outfile || "$progname.rep";
    my $file = _prompt( '', "Name of file to save message in", $file_save );
    save_message_to_disk($file) || return undef;
    print "\n";
    paraprint <<EOF;
A copy of your message has been saved in '$file' for you to
send to '$address' with your normal mail client.
EOF
}

sub Send {

    # Message has been accepted for transmission -- Send the message

    # on linux certain "mail" implementations won't accept the subject
    # as "~s subject" and thus the Subject header will be corrupted
    # so don't use Mail::Send to be safe
    eval {
        if ( $::HaveSend && !$Is_Linux && !$Is_OpenBSD ) {
            _send_message_mailsend();
        } elsif ($Is_VMS) {
            _send_message_vms();
        } else {
            _send_message_sendmail();
        }
    };

    if ( my $error = $@ ) {
        paraprint <<EOF;
$0 has detected an error while trying to send your message: $error.

Your message may not have been sent. You will now have a chance to save a copy to disk.
EOF
        SaveMessage();
        return;
    }

    1 while unlink($filename);    # remove all versions under VMS
}    # sub Send

sub Help {
    print <<EOF;

This program is designed to help you generate and send bug reports
(and thank-you notes) about perl5 and the modules which ship with it.

In most cases, you can just run "$0" interactively from a command
line without any special arguments and follow the prompts.

Advanced usage:

$0  [-v] [-a address] [-s subject] [-b body | -f inpufile ] [ -F outputfile ]
    [-r returnaddress] [-e editor] [-c adminaddress | -C] [-S] [-t] [-h]
    [-p patchfile ]
$0  [-v] [-r returnaddress] [-A] [-ok | -okay | -nok | -nokay]


Options:

  -v    Include Verbose configuration data in the report
  -f    File containing the body of the report. Use this to
        quickly send a prepared message.
  -p    File containing a patch or other text attachment. Separate
        multiple files with commas.
  -F    File to output the resulting mail message to, instead of mailing.
  -S    Send without asking for confirmation.
  -a    Address to send the report to. Defaults to '$address'.
  -c    Address to send copy of report to. Defaults to '$cc'.
  -C    Don't send copy to administrator.
  -s    Subject to include with the message. You will be prompted
        if you don't supply one on the command line.
  -b    Body of the report. If not included on the command line, or
        in a file with -f, you will get a chance to edit the message.
  -r    Your return address. The program will ask you to confirm
        this if you don't give it here.
  -e    Editor to use.
  -t    Test mode. The target address defaults to '$testaddress'.
  -T    Thank-you mode. The target address defaults to '$thanksaddress'.
  -d    Data mode.  This prints out your configuration data, without mailing
        anything. You can use this with -v to get more complete data.
  -A    Don't send a bug received acknowledgement to the return address.
  -ok   Report successful build on this system to perl porters
        (use alone or with -v). Only use -ok if *everything* was ok:
        if there were *any* problems at all, use -nok.
  -okay As -ok but allow report from old builds.
  -nok  Report unsuccessful build on this system to perl porters
        (use alone or with -v). You must describe what went wrong
        in the body of the report which you will be asked to edit.
  -nokay As -nok but allow report from old builds.
  -h    Print this help message.

EOF
}

sub filename {
    if ($::HaveTemp) {
	# Good. Use a secure temp file
	my ($fh, $filename) = File::Temp::tempfile(UNLINK => 1);
	close($fh);
	return $filename;
    } else {
	# Bah. Fall back to doing things less securely.
	my $dir = File::Spec->tmpdir();
	$filename = "bugrep0$$";
	$filename++ while -e File::Spec->catfile($dir, $filename);
	$filename = File::Spec->catfile($dir, $filename);
    }
}

sub paraprint {
    my @paragraphs = split /\n{2,}/, "@_";
    for (@paragraphs) {   # implicit local $_
	s/(\S)\s*\n/$1 /g;
	write;
	print "\n";
    }
}

sub _prompt {
    my ($explanation, $prompt, $default) = (@_);
    if ($explanation) {
        print "\n\n";
        paraprint $explanation;
    }
    print $prompt. ($default ? " [$default]" :''). ": ";
	my $result = scalar(<>);
    return $default if !defined $result; # got eof
    chomp($result);
	$result =~ s/^\s*(.*?)\s*$/$1/s;
    if ($default && $result eq '') {
        return $default;
    } else {
        return $result;
    }
}

sub _build_header {
    my %attr = (@_);

    my $head = '';
    for my $header (keys %attr) {
        $head .= "$header: ".$attr{$header}."\n";
    }
    return $head;
}

sub _message_headers {
    my %headers = ( To => $address, Subject => $subject );
    $headers{'Cc'}         = $cc        if ($cc);
    $headers{'Message-Id'} = $messageid if ($messageid);
    $headers{'Reply-To'}   = $from      if ($from);
    $headers{'From'}       = $from      if ($from);
    if ($have_attachment) {
        $headers{'MIME-Version'} = '1.0';
        $headers{'Content-Type'} = qq{multipart/mixed; boundary=\"$mime_boundary\"};
    }
    return \%headers;
}

sub _add_body_start {
    my $body_start = <<"BODY_START";
This is a multi-part message in MIME format.
--$mime_boundary
Content-Type: text/plain; format=fixed
Content-Transfer-Encoding: 8bit

BODY_START
    return $body_start;
}

sub _add_attachments {
    my $attach = '';
    for my $attachment (split /\s*,\s*/, $attachments) {
        my $attach_file = basename($attachment);
        $attach .= <<"ATTACHMENT";

--$mime_boundary
Content-Type: text/x-patch; name="$attach_file"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="$attach_file"

ATTACHMENT

        open my $attach_fh, '<:raw', $attachment
            or die "Couldn't open attachment '$attachment': $!\n";
        while (<$attach_fh>) { $attach .= $_; }
        close($attach_fh) or die "Error closing attachment '$attachment': $!";
    }

    $attach .= "\n--$mime_boundary--\n";
    return $attach;
}

sub _read_report {
    my $fname = shift;
    my $content;
    open( REP, "<:raw", $fname ) or die "Couldn't open file '$fname': $!\n";
    binmode(REP, ':raw :crlf') if $Is_MSWin32;
    # wrap long lines to make sure the report gets delivered
    local $Text::Wrap::columns = 900;
    local $Text::Wrap::huge = 'overflow';
    while (<REP>) {
        if ($::HaveWrap && /\S/) { # wrap() would remove empty lines
            $content .= Text::Wrap::wrap(undef, undef, $_);
        } else {
            $content .= $_;
        }
    }
    close(REP) or die "Error closing report file '$fname': $!";
    return $content;
}

sub build_complete_message {
    my $content = _build_header(%{_message_headers()}) . "\n\n";
    $content .= _add_body_start() if $have_attachment;
    $content .= _read_report($filename);
    $content .= _add_attachments() if $have_attachment;
    return $content;
}

sub save_message_to_disk {
    my $file = shift;

        open OUTFILE, '>:raw', $file or do { warn  "Couldn't open '$file': $!\n"; return undef};
        binmode(OUTFILE, ':raw :crlf') if $Is_MSWin32;

        print OUTFILE build_complete_message();
        close(OUTFILE) or do { warn  "Error closing $file: $!"; return undef };
	    print "\nMessage saved.\n";
        return 1;
}

sub _send_message_vms {

    my $mail_from  = $from;
    my $rcpt_to_to = $address;
    my $rcpt_to_cc = $cc;

    map { $_ =~ s/^[^<]*<//;
          $_ =~ s/>[^>]*//; } ($mail_from, $rcpt_to_to, $rcpt_to_cc);

    if ( open my $sff_fh, '|-:raw', 'MCR TCPIP$SYSTEM:TCPIP$SMTP_SFF.EXE SYS$INPUT:' ) {
        print $sff_fh "MAIL FROM:<$mail_from>\n";
        print $sff_fh "RCPT TO:<$rcpt_to_to>\n";
        print $sff_fh "RCPT TO:<$rcpt_to_cc>\n" if $rcpt_to_cc;
        print $sff_fh "DATA\n";
        print $sff_fh build_complete_message();
        my $success = close $sff_fh;
        if ($success ) {
            print "\nMessage sent\n";
            return;
        }
    }
    die "Mail transport failed (leaving bug report in $filename): $^E\n";
}

sub _send_message_mailsend {
    my $msg = Mail::Send->new();
    my %headers = %{_message_headers()};
    for my $key ( keys %headers) {
        $msg->add($key => $headers{$key});
    }

    $fh = $msg->open;
    binmode($fh, ':raw');
    print $fh _add_body_start() if $have_attachment;
    print $fh _read_report($filename);
    print $fh _add_attachments() if $have_attachment;
    $fh->close or die "Error sending mail: $!";

    print "\nMessage sent.\n";
}

sub _probe_for_sendmail {
    my $sendmail = "";
    for (qw(/usr/lib/sendmail /usr/sbin/sendmail /usr/ucblib/sendmail)) {
        $sendmail = $_, last if -e $_;
    }
    if ( $^O eq 'os2' and $sendmail eq "" ) {
        my $path = $ENV{PATH};
        $path =~ s:\\:/:;
        my @path = split /$Config{'path_sep'}/, $path;
        for (@path) {
            $sendmail = "$_/sendmail",     last if -e "$_/sendmail";
            $sendmail = "$_/sendmail.exe", last if -e "$_/sendmail.exe";
        }
    }
    return $sendmail;
}

sub _send_message_sendmail {
    my $sendmail = _probe_for_sendmail();
    unless ($sendmail) {
        my $message_start = !$Is_Linux && !$Is_OpenBSD ? <<'EOT' : <<'EOT';
It appears that there is no program which looks like "sendmail" on
your system and that the Mail::Send library from CPAN isn't available.
EOT
It appears that there is no program which looks like "sendmail" on
your system.
EOT
        paraprint(<<"EOF"), die "\n";
$message_start
Because of this, there's no easy way to automatically send your
message.

A copy of your message has been saved in '$filename' for you to
send to '$address' with your normal mail client.
EOF
    }

    open( SENDMAIL, "|-:raw", $sendmail, "-t", "-oi", "-f", $from )
        || die "'|$sendmail -t -oi -f $from' failed: $!";
    print SENDMAIL build_complete_message();
    if ( close(SENDMAIL) ) {
        print "\nMessage sent\n";
    } else {
        warn "\nSendmail returned status '", $? >> 8, "'\n";
    }
}



# a strange way to check whether any significant editing
# has been done: check whether any new non-empty lines
# have been added.

sub _fingerprint_lines_in_report {
    my $new_lines = 0;
    # read in the report template once so that
    # we can track whether the user does any editing.
    # yes, *all* whitespace is ignored.

    open(REP, '<:raw', $filename) or die "Unable to open report file '$filename': $!\n";
    binmode(REP, ':raw :crlf') if $Is_MSWin32;
    while (my $line = <REP>) {
        $line =~ s/\s+//g;
        $new_lines++ if (!$REP{$line});

    }
    close(REP) or die "Error closing report file '$filename': $!";
    # returns the number of lines with content that wasn't there when last we looked
    return $new_lines;
}



format STDOUT =
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~
$_
.

__END__

=head1 NAME

perlbug - how to submit bug reports on Perl

=head1 SYNOPSIS

B<perlbug>

B<perlbug> S<[ B<-v> ]> S<[ B<-a> I<address> ]> S<[ B<-s> I<subject> ]>
S<[ B<-b> I<body> | B<-f> I<inputfile> ]> S<[ B<-F> I<outputfile> ]>
S<[ B<-r> I<returnaddress> ]>
S<[ B<-e> I<editor> ]> S<[ B<-c> I<adminaddress> | B<-C> ]>
S<[ B<-S> ]> S<[ B<-t> ]>  S<[ B<-d> ]>  S<[ B<-A> ]>  S<[ B<-h> ]> S<[ B<-T> ]>

B<perlbug> S<[ B<-v> ]> S<[ B<-r> I<returnaddress> ]>
 S<[ B<-A> ]> S<[ B<-ok> | B<-okay> | B<-nok> | B<-nokay> ]>

B<perlthanks>

=head1 DESCRIPTION


This program is designed to help you generate and send bug reports
(and thank-you notes) about perl5 and the modules which ship with it.

In most cases, you can just run it interactively from a command
line without any special arguments and follow the prompts.

If you have found a bug with a non-standard port (one that was not
part of the I<standard distribution>), a binary distribution, or a
non-core module (such as Tk, DBI, etc), then please see the
documentation that came with that distribution to determine the
correct place to report bugs.

If you are unable to send your report using B<perlbug> (most likely
because your system doesn't have a way to send mail that perlbug
recognizes), you may be able to use this tool to compose your report
and save it to a file which you can then send to B<perlbug@perl.org>
using your regular mail client.

In extreme cases, B<perlbug> may not work well enough on your system
to guide you through composing a bug report. In those cases, you
may be able to use B<perlbug -d> to get system configuration
information to include in a manually composed bug report to
B<perlbug@perl.org>.


When reporting a bug, please run through this checklist:

=over 4

=item What version of Perl you are running?

Type C<perl -v> at the command line to find out.

=item Are you running the latest released version of perl?

Look at http://www.perl.org/ to find out.  If you are not using the
latest released version, please try to replicate your bug on the
latest stable release.

Note that reports about bugs in old versions of Perl, especially
those which indicate you haven't also tested the current stable
release of Perl, are likely to receive less attention from the
volunteers who build and maintain Perl than reports about bugs in
the current release.

This tool isn't appropriate for reporting bugs in any version
prior to Perl 5.0.

=item Are you sure what you have is a bug?

A significant number of the bug reports we get turn out to be
documented features in Perl.  Make sure the issue you've run into
isn't intentional by glancing through the documentation that comes
with the Perl distribution.

Given the sheer volume of Perl documentation, this isn't a trivial
undertaking, but if you can point to documentation that suggests
the behaviour you're seeing is I<wrong>, your issue is likely to
receive more attention. You may want to start with B<perldoc>
L<perltrap> for pointers to common traps that new (and experienced)
Perl programmers run into.

If you're unsure of the meaning of an error message you've run
across, B<perldoc> L<perldiag> for an explanation.  If the message
isn't in perldiag, it probably isn't generated by Perl.  You may
have luck consulting your operating system documentation instead.

If you are on a non-UNIX platform B<perldoc> L<perlport>, as some
features may be unimplemented or work differently.

You may be able to figure out what's going wrong using the Perl
debugger.  For information about how to use the debugger B<perldoc>
L<perldebug>.

=item Do you have a proper test case?

The easier it is to reproduce your bug, the more likely it will be
fixed -- if nobody can duplicate your problem, it probably won't be 
addressed.

A good test case has most of these attributes: short, simple code;
few dependencies on external commands, modules, or libraries; no
platform-dependent code (unless it's a platform-specific bug);
clear, simple documentation.

A good test case is almost always a good candidate to be included in
Perl's test suite.  If you have the time, consider writing your test case so
that it can be easily included into the standard test suite.

=item Have you included all relevant information?

Be sure to include the B<exact> error messages, if any.
"Perl gave an error" is not an exact error message.

If you get a core dump (or equivalent), you may use a debugger
(B<dbx>, B<gdb>, etc) to produce a stack trace to include in the bug
report.  

NOTE: unless your Perl has been compiled with debug info
(often B<-g>), the stack trace is likely to be somewhat hard to use
because it will most probably contain only the function names and not
their arguments.  If possible, recompile your Perl with debug info and
reproduce the crash and the stack trace.

=item Can you describe the bug in plain English?

The easier it is to understand a reproducible bug, the more likely
it will be fixed.  Any insight you can provide into the problem
will help a great deal.  In other words, try to analyze the problem
(to the extent you can) and report your discoveries.

=item Can you fix the bug yourself?

If so, that's great news; bug reports with patches are likely to
receive significantly more attention and interest than those without
patches.  Please attach your patch to the report using the C<-p> option.
When sending a patch, create it using C<git format-patch> if possible,
though a unified diff created with C<diff -pu> will do nearly as well.

Your patch may be returned with requests for changes, or requests for more
detailed explanations about your fix.

Here are a few hints for creating high-quality patches:

Make sure the patch is not reversed (the first argument to diff is
typically the original file, the second argument your changed file).
Make sure you test your patch by applying it with C<git am> or the
C<patch> program before you send it on its way.  Try to follow the
same style as the code you are trying to patch.  Make sure your patch
really does work (C<make test>, if the thing you're patching is covered
by Perl's test suite).

=item Can you use C<perlbug> to submit the report?

B<perlbug> will, amongst other things, ensure your report includes
crucial information about your version of perl.  If C<perlbug> is
unable to mail your report after you have typed it in, you may have
to compose the message yourself, add the output produced by C<perlbug
-d> and email it to B<perlbug@perl.org>.  If, for some reason, you
cannot run C<perlbug> at all on your system, be sure to include the
entire output produced by running C<perl -V> (note the uppercase V).

Whether you use C<perlbug> or send the email manually, please make
your Subject line informative.  "a bug" is not informative.  Neither
is "perl crashes" nor is "HELP!!!".  These don't help.  A compact
description of what's wrong is fine.

=item Can you use C<perlbug> to submit a thank-you note?

Yes, you can do this by either using the C<-T> option, or by invoking
the program as C<perlthanks>. Thank-you notes are good. It makes people
smile. 

=back

Having done your bit, please be prepared to wait, to be told the
bug is in your code, or possibly to get no reply at all.  The
volunteers who maintain Perl are busy folks, so if your problem is
an obvious bug in your own code, is difficult to understand or is
a duplicate of an existing report, you may not receive a personal
reply.

If it is important to you that your bug be fixed, do monitor the
perl5-porters@perl.org mailing list (mailing lists are moderated, your
message may take a while to show up) and the commit logs to development
versions of Perl, and encourage the maintainers with kind words or
offers of frosty beverages.  (Please do be kind to the maintainers.
Harassing or flaming them is likely to have the opposite effect of the
one you want.)

Feel free to update the ticket about your bug on http://rt.perl.org
if a new version of Perl is released and your bug is still present.

=head1 OPTIONS

=over 8

=item B<-a>

Address to send the report to.  Defaults to B<perlbug@perl.org>.

=item B<-A>

Don't send a bug received acknowledgement to the reply address.
Generally it is only a sensible to use this option if you are a
perl maintainer actively watching perl porters for your message to
arrive.

=item B<-b>

Body of the report.  If not included on the command line, or
in a file with B<-f>, you will get a chance to edit the message.

=item B<-C>

Don't send copy to administrator.

=item B<-c>

Address to send copy of report to.  Defaults to the address of the
local perl administrator (recorded when perl was built).

=item B<-d>

Data mode (the default if you redirect or pipe output).  This prints out
your configuration data, without mailing anything.  You can use this
with B<-v> to get more complete data.

=item B<-e>

Editor to use.

=item B<-f>

File containing the body of the report.  Use this to quickly send a
prepared message.

=item B<-F>

File to output the results to instead of sending as an email. Useful
particularly when running perlbug on a machine with no direct internet
connection.

=item B<-h>

Prints a brief summary of the options.

=item B<-ok>

Report successful build on this system to perl porters. Forces B<-S>
and B<-C>. Forces and supplies values for B<-s> and B<-b>. Only
prompts for a return address if it cannot guess it (for use with
B<make>). Honors return address specified with B<-r>.  You can use this
with B<-v> to get more complete data.   Only makes a report if this
system is less than 60 days old.

=item B<-okay>

As B<-ok> except it will report on older systems.

=item B<-nok>

Report unsuccessful build on this system.  Forces B<-C>.  Forces and
supplies a value for B<-s>, then requires you to edit the report
and say what went wrong.  Alternatively, a prepared report may be
supplied using B<-f>.  Only prompts for a return address if it
cannot guess it (for use with B<make>). Honors return address
specified with B<-r>.  You can use this with B<-v> to get more
complete data.  Only makes a report if this system is less than 60
days old.

=item B<-nokay>

As B<-nok> except it will report on older systems.

=item B<-p>

The names of one or more patch files or other text attachments to be
included with the report.  Multiple files must be separated with commas.

=item B<-r>

Your return address.  The program will ask you to confirm its default
if you don't use this option.

=item B<-S>

Send without asking for confirmation.

=item B<-s>

Subject to include with the message.  You will be prompted if you don't
supply one on the command line.

=item B<-t>

Test mode.  The target address defaults to B<perlbug-test@perl.org>.
Also makes it possible to command perlbug from a pipe or file, for
testing purposes.

=item B<-T>

Send a thank-you note instead of a bug report. 

=item B<-v>

Include verbose configuration data in the report.

=back

=head1 AUTHORS

Kenneth Albanowski (E<lt>kjahds@kjahds.comE<gt>), subsequently
I<doc>tored by Gurusamy Sarathy (E<lt>gsar@activestate.comE<gt>),
Tom Christiansen (E<lt>tchrist@perl.comE<gt>), Nathan Torkington
(E<lt>gnat@frii.comE<gt>), Charles F. Randall (E<lt>cfr@pobox.comE<gt>),
Mike Guy (E<lt>mjtg@cam.ac.ukE<gt>), Dominic Dunlop
(E<lt>domo@computer.orgE<gt>), Hugo van der Sanden (E<lt>hv@crypt.orgE<gt>),
Jarkko Hietaniemi (E<lt>jhi@iki.fiE<gt>), Chris Nandor
(E<lt>pudge@pobox.comE<gt>), Jon Orwant (E<lt>orwant@media.mit.eduE<gt>,
Richard Foley (E<lt>richard.foley@rfi.netE<gt>), Jesse Vincent
(E<lt>jesse@bestpractical.comE<gt>), and Craig A. Berry (E<lt>craigberry@mac.comE<gt>).

=head1 SEE ALSO

perl(1), perldebug(1), perldiag(1), perlport(1), perltrap(1),
diff(1), patch(1), dbx(1), gdb(1)

=head1 BUGS

None known (guess what must have been used to report them?)

=cut