if ($_ eq 'From' and $param{avatars}) {
my $libravatar_url = __libravatar_url(decode_rfc1522($head_field));
if (defined $libravatar_url and length $libravatar_url) {
- push @headers,q(<img src="http://).$libravatar_url.qq(">\n);
+ push @headers,q(<img src="http://).$libravatar_url.qq(" alt="">\n);
}
}
- push @headers, qq(<p><span class="header">$_:</span> ) . html_escape(decode_rfc1522($head_field))."</p>\n";
+ push @headers, qq(<div class="header"><span class="headerfield">$_:</span> ) . html_escape(decode_rfc1522($head_field))."</div>\n";
}
print {$output} join(qq(), @headers);
} else {
my $body = $entity->stringify_body;
# this attachment has its own content type, so we must not
# try to convert it to UTF-8 or do anything funky.
- my @layers = PerlIO::get_layers($output);
binmode($output,':raw');
print {$output} "Content-Type: $type";
my ($charset) = $head->get('Content-Type:') =~ m/charset\s*=\s*\"?([\w-]+)\"?/i;
print {$output} "\n";
my $decoder = MIME::Decoder->new($head->mime_encoding);
$decoder->decode(IO::Scalar->new(\$body), $output);
- if (grep {/utf8/} @layers) {
- binmode($output,':utf8');
- }
- return;
+ # we don't reset the layers here, because it makes no
+ # sense to add anything to the output handle after this
+ # point.
+ return(1);
}
elsif (not exists $param{att}) {
my @dlargs = (msg=>$xmessage, att=>$#$attachments);
}
}
- return if not $param{outer} and $disposition eq 'attachment' and not exists $param{att};
- return unless ($type =~ m[^text/?] and
- $type !~ m[^text/(?:html|enriched)(?:;|$)]) or
- $type =~ m[^application/pgp(?:;|$)] or
- $entity->parts;
+ return 0 if not $param{outer} and $disposition eq 'attachment' and not exists $param{att};
+ return 0 unless (($type =~ m[^text/?] and
+ $type !~ m[^text/(?:html|enriched)(?:;|$)]) or
+ $type =~ m[^application/pgp(?:;|$)] or
+ $entity->parts);
if ($entity->is_multipart) {
my @parts = $entity->parts;
foreach my $part (@parts) {
- display_entity(entity => $part,
- bug_num => $ref,
- outer => 0,
- msg_num => $xmessage,
- output => $output,
- attachments => $attachments,
- terse => $param{terse},
- exists $param{msg}?(msg=>$param{msg}):(),
- exists $param{att}?(att=>$param{att}):(),
- exists $param{avatars}?(avatars=>$param{avatars}):(),
- );
+ my $raw_output =
+ display_entity(entity => $part,
+ bug_num => $ref,
+ outer => 0,
+ msg_num => $xmessage,
+ output => $output,
+ attachments => $attachments,
+ terse => $param{terse},
+ exists $param{msg}?(msg=>$param{msg}):(),
+ exists $param{att}?(att=>$param{att}):(),
+ exists $param{avatars}?(avatars=>$param{avatars}):(),
+ );
+ if ($raw_output) {
+ return $raw_output;
+ }
# print {$output} "\n";
}
} elsif ($entity->parts) {
print {$output} qq(<pre class="message">$body</pre>\n);
}
}
+ return 0;
}
$parser->output_to_core(1);
my $entity = $parser->parse_data( $email);
my @attachments = ();
- display_entity(entity => $entity,
- bug_num => $param{ref},
- outer => 1,
- msg_num => $param{msg_num},
- output => $output_fh,
- attachments => \@attachments,
- terse => $param{terse},
- exists $param{msg}?(msg=>$param{msg}):(),
- exists $param{att}?(att=>$param{att}):(),
- exists $param{trim_headers}?(trim_headers=>$param{trim_headers}):(),
- exists $param{avatars}?(avatars=>$param{avatars}):(),
- );
- return decode_utf8($output);
+ my $raw_output =
+ display_entity(entity => $entity,
+ bug_num => $param{ref},
+ outer => 1,
+ msg_num => $param{msg_num},
+ output => $output_fh,
+ attachments => \@attachments,
+ terse => $param{terse},
+ exists $param{msg}?(msg=>$param{msg}):(),
+ exists $param{att}?(att=>$param{att}):(),
+ exists $param{trim_headers}?(trim_headers=>$param{trim_headers}):(),
+ exists $param{avatars}?(avatars=>$param{avatars}):(),
+ );
+ return $raw_output?$output:decode_utf8($output);
}
=head2 handle_record
If summary is undef, unsets the summary
-If summary is 0, sets the summary to the first paragraph contained in
+If summary is 0 or -1, sets the summary to the first paragraph contained in
the message passed.
If summary is a positive integer, sets the summary to the message specified.
elsif ($param{$cmd} =~ /^\d+$/) {
my $log = [];
my @records = Debbugs::Log::read_log_records(bug_num => $param{bug});
- if ($param{$cmd} == 0) {
+ if ($param{$cmd} == 0 or $param{$cmd} == -1) {
$log = $param{message};
$summary_msg = @records + 1;
}
}
# skip a paragraph if it looks like it's control or
# pseudo-headers
- if ($line =~ m{^\s*(?:Package|Source|Version|User|Tag|Severity)\:\s+\S}xi or #pseudo headers
+ if ($line =~ m{^\s*(?:Package|Source|Version|User|Tag|Severity|Control)\:\s+\S}xi or #pseudo headers
$line =~ m{^(?:package:?|(?:no|)owner|severity|tags?|summary| #control
\#|reopen|close|(?:not|)(?:fixed|found)|clone|
debug|(?:not|)forwarded|priority|
use vars qw($VERSION $DEBUG %EXPORT_TAGS @EXPORT_OK @EXPORT);
use base qw(Exporter);
use Debbugs::Log;
-#use Params::Validate;
use Search::Estraier;
-use Date::Manip;
use Debbugs::Common qw(getbuglocation getbugcomponent make_list);
use Debbugs::Status qw(readbug);
use Debbugs::MIME qw(parse);
+use Encode qw(encode_utf8);
BEGIN{
($VERSION) = q$Revision: 1.3 $ =~ /^Revision:\s+([^\s+])/;
$doc = new Search::Estraier::Document if not defined $doc;
my $message = parse($bug_message);
- $doc->add_text(join("\n",make_list(values %{$message})));
+ $doc->add_text(encode_utf8(join("\n",make_list(values %{$message}))));
# * @id : the ID number determined automatically when the document is registered.
# * @uri : the location of a document which any document should have.
my @attr = qw(status subject date submitter package tags severity);
# parse the date
my ($date) = $bug_message =~ /^Date:\s+(.+?)\s*$/mi;
- $doc->add_attr('@cdate' => $date) if defined $date;
+ $doc->add_attr('@cdate' => encode_utf8($date)) if defined $date;
# parse the title
my ($subject) = $bug_message =~ /^Subject:\s+(.+?)\s*$/mi;
- $doc->add_attr('@title' => $subject) if defined $subject;
+ $doc->add_attr('@title' => encode_utf8($subject)) if defined $subject;
# parse the author
my ($author) = $bug_message =~ /^From:\s+(.+?)\s*$/mi;
- $doc->add_attr('@author' => $author) if defined $author;
+ $doc->add_attr('@author' => encode_utf8($author)) if defined $author;
# create the uri
- $doc->add_attr('@uri' => $uri);
+ $doc->add_attr('@uri' => encode_utf8($uri));
foreach my $attr (@attr) {
- $doc->add_attr($attr => $status->{$attr}) if defined $status->{$attr};
+ $doc->add_attr($attr => encode_utf8($status->{$attr})) if defined $status->{$attr};
}
print STDERR "adding $uri\n" if $DEBUG;
# Try a bit harder if estraier is returning timeouts
package Debbugs::MIME;
+=encoding utf8
+
=head1 NAME
Debbugs::MIME -- Mime handling routines for debbugs
If you specify one of C<bcc>, C<cc>, or C<to>, you will receive only a
LIST of recipients which the main should be Bcc'ed, Cc'ed, or To'ed
respectively. By default, a LIST with keys bcc, cc, and to is returned
-with ARRAYREF values correponding to the users to whom a message
+with ARRAYREF values corresponding to the users to whom a message
should be sent.
=over
=back
-This function correponds to L<Debbugs::Packages::get_versions>
+This function corresponds to L<Debbugs::Packages::get_versions>
=cut
qw(removefoundversions removefixedversions)
],
hook => [qw(bughook bughook_archive)],
+ indexdb => [qw(generate_index_db_line)],
fields => [qw(%fields)],
);
@EXPORT_OK = ();
$log = $status;
$log =~ s/\.summary$/.log/;
($location) = $status =~ m/(db-h|db|archive)/;
+ ($param{bug}) = $status =~ m/(\d+)\.summary$/;
}
if ($param{lock}) {
filelock("$config{spool_dir}/lock/$param{bug}",exists $param{locks}?$param{locks}:());
my $status_modified = (stat($status))[9];
# Add log last modified time
- $data{log_modified} = (stat($log))[9];
+ $data{log_modified} = (stat($log))[9] // (stat("${log}.gz"))[9];
$data{last_modified} = max($status_modified,$data{log_modified});
$data{location} = $location;
$data{archived} = (defined($location) and ($location eq 'archive'))?1:0;
push @data,$newdata;
# perform a sanity check to make sure that the merged bugs
# are all merged with eachother
- my $expectmerge= join(' ',grep {$_ != $bug } sort { $a <=> $b } @bugs);
+ # We do a cmp sort instead of an <=> sort here, because that's
+ # what merge does
+ my $expectmerge= join(' ',grep {$_ != $bug } sort @bugs);
if ($newdata->{mergedwith} ne $expectmerge) {
for (1..$locks) {
unfilelock(exists $param{locks}?$param{locks}:());
}
- die "Bug $param{bug} differs from bug $bug: ($newdata->{bug_num}: '$newdata->{mergedwith}') vs. ('$expectmerge') (".join(' ',@bugs).")";
+ die "Bug $param{bug} mergedwith differs from bug $bug: ($newdata->{bug_num}: '$newdata->{mergedwith}') vs. ('$expectmerge') (".join(' ',@bugs).")";
}
}
}
Writes the bug status and summary files out.
-Skips writting out a status file if minversion is 2
+Skips writing out a status file if minversion is 2
Does not call bughook if disablebughook is true.
number are removed.
Currently $package and $isbinary are entirely ignored, but accepted
-for backwards compatibilty.
+for backwards compatibility.
=cut
return grep { $_ eq $severity } @{$config{strong_severities}};
}
+=head1 indexdb
+
+=head2 generate_index_db_line
+
+ my $data = read_bug(bug => $bug,
+ location => $initialdir);
+ # generate_index_db_line hasn't been written yet at all.
+ my $line = generate_index_db_line($data);
+
+Returns a line for a bug suitable to be written out to index.db.
+
+=cut
+
+sub generate_index_db_line {
+ my ($data,$bug) = @_;
+
+ # just in case someone has given us a split out data
+ $data = join_status_fields($data);
+
+ my $whendone = "open";
+ my $severity = $config{default_severity};
+ (my $pkglist = $data->{package}) =~ s/[,\s]+/,/g;
+ $pkglist =~ s/^,+//;
+ $pkglist =~ s/,+$//;
+ $whendone = "forwarded" if defined $data->{forwarded} and length $data->{forwarded};
+ $whendone = "done" if defined $data->{done} and length $data->{done};
+ $severity = $data->{severity} if length $data->{severity};
+ return sprintf "%s %d %d %s [%s] %s %s\n",
+ $pkglist, $data->{bug_num}//$bug, $data->{date}, $whendone,
+ $data->{originator}, $severity, $data->{keywords};
+}
+
+
=head1 PRIVATE FUNCTIONS
my $data = $bugs_temp{$bug};
appendfile("$config{spool_dir}/debbugs.trace","$type $bug\n",makestatus($data, 1));
- my $whendone = "open";
- my $severity = $config{default_severity};
- (my $pkglist = $data->{package}) =~ s/[,\s]+/,/g;
- $pkglist =~ s/^,+//;
- $pkglist =~ s/,+$//;
- $whendone = "forwarded" if defined $data->{forwarded} and length $data->{forwarded};
- $whendone = "done" if defined $data->{done} and length $data->{done};
- $severity = $data->{severity} if length $data->{severity};
-
- my $k = sprintf "%s %d %d %s [%s] %s %s\n",
- $pkglist, $bug, $data->{date}, $whendone,
- $data->{originator}, $severity, $data->{keywords};
- $bugs{$bug} = $k;
+ $bugs{$bug} = generate_index_db_line($data,$bug);
}
update_realtime("$config{spool_dir}/index.db.realtime", %bugs);
sub encode_utf8_structure {
++$depth;
my @ret;
- for my $_ (@_) {
+ for $_ (@_) {
if (ref($_) eq 'HASH') {
push @ret, {encode_utf8_structure(%{$depth == 1 ? dclone($_):$_})};
}
=cut
-our %iconv_converters;
-
sub convert_to_utf8 {
- my ($data,$charset) = @_;
+ my ($data,$charset,$internal_call) = @_;
+ $internal_call //= 0;
if (is_utf8($data)) {
cluck("utf8 flag is set when calling convert_to_utf8");
return $data;
if ($charset eq 'RAW') {
croak("Charset must not be raw when calling convert_to_utf8");
}
- if (not defined $iconv_converters{$charset}) {
- eval {
- $iconv_converters{$charset} = Text::Iconv->new($charset,"UTF-8") or
- die "Unable to create converter for '$charset'";
- };
- if ($@) {
- warn $@;
- # We weren't able to create the converter, so use Encode
- # instead
- return __fallback_convert_to_utf8($data,$charset);
- }
- }
- if (not defined $iconv_converters{$charset}) {
- warn "The converter for $charset wasn't created properly somehow!";
+ my $iconv_converter;
+ eval {
+ $iconv_converter = Text::Iconv->new($charset,"UTF-8") or
+ die "Unable to create converter for '$charset'";
+ };
+ if ($@) {
+ return undef if $internal_call;
+ warn $@;
+ # We weren't able to create the converter, so use Encode
+ # instead
return __fallback_convert_to_utf8($data,$charset);
}
- my $converted_data = $iconv_converters{$charset}->convert($data);
+ my $converted_data = $iconv_converter->convert($data);
# if the conversion failed, retval will be undefined or perhaps
# -1.
- my $retval = $iconv_converters{$charset}->retval();
+ my $retval = $iconv_converter->retval();
if (not defined $retval or
$retval < 0
) {
- warn "failed to convert to utf8";
+ # try iso8559-1 first
+ if (not $internal_call) {
+ my $call_back_data = convert_to_utf8($data,'ISO8859-1',1);
+ # if there's an à (0xC3), it's probably something
+ # horrible, and we shouldn't try to convert it.
+ if (defined $call_back_data and $call_back_data !~ /\x{C3}/) {
+ warn "failed to convert to utf8 (charset: $charset, data: $data), but succeeded with ISO8859-1: ".encode_utf8($call_back_data);
+ return $call_back_data;
+ }
+ }
+ warn "failed to convert to utf8 (charset: $charset, data: $data)";
# Fallback to encode, which will probably also fail.
return __fallback_convert_to_utf8($data,$charset);
}
$charset //= 'utf8';
my $result;
eval {
- $result = decode($charset,$data);
+ $result = decode($charset,$data,0);
};
if ($@) {
warn "Unable to decode charset; '$charset' and '$data': $@";
# create the directories if they aren't there
for dir in $(sbin_dir) $(etc_dir)/html $(etc_dir)/indices \
$(var_dir)/indices $(var_dir)/www/cgi $(var_dir)/www/db $(var_dir)/www/txt \
+$(var_dir)/www/css \
$(var_dir)/spool/lock $(var_dir)/spool/archive $(var_dir)/spool/incoming \
$(var_dir)/spool/db-h $(scripts_dir) $(examples_dir) $(man8_dir); \
do test -d $$dir || $(install_exec) -d $$dir; done
# install the HTML pages etc
$(foreach html, $(htmls_in), $(install_data) $(html) $(etc_dir)/html;)
$(install_data) html/htaccess $(var_dir)/www/db/.htaccess
- $(install_data) html/bugs.css $(var_dir)/www/bugs.css
+ $(install_data) html/bugs.css $(var_dir)/www/css/bugs.css
# install the CGIs
for cgi in $(cgis); do $(install_exec) $$cgi $(var_dir)/www/cgi; done
--- /dev/null
+#! /usr/bin/perl
+# debbugs-rebuild-index.db is part of debbugs, and is released
+# under the terms of the GPL version 2, or any later version, at your
+# option. See the file README and COPYING for more information.
+# Copyright 2012 by Don Armstrong <don@donarmstrong.com>.
+
+
+use warnings;
+use strict;
+
+use Getopt::Long qw(:config no_ignore_case);
+use Pod::Usage;
+
+=head1 NAME
+
+debbugs-rebuild-index.db -- rebuild Debbug's index.db
+
+=head1 SYNOPSIS
+
+debbugs-rebuild-index.db [options]
+
+ Options:
+ --spool-dir debbugs spool directory
+ --debug, -d debugging level (Default 0)
+ --help, -h display this help
+ --man, -m display manual
+
+=head1 OPTIONS
+
+=over
+
+=item B<--spool-dir>
+
+Debbugs spool directory; defaults to the value configured in the
+debbugs configuration file.
+
+=item B<--debug, -d>
+
+Debug verbosity.
+
+=item B<--help, -h>
+
+Display brief useage information.
+
+=item B<--man, -m>
+
+Display this manual.
+
+=back
+
+=head1 EXAMPLES
+
+Rebuild the index.db for db-h.
+
+ debbugs-rebuild-index.db;
+
+Rebuild the index.db for archive
+
+ debbugs-rebuild-index.db archive;
+
+
+=cut
+
+
+use vars qw($DEBUG);
+
+use Debbugs::Common qw(checkpid lockpid get_hashname getparsedaddrs getbugcomponent make_list);
+use Debbugs::Config qw(:config);
+use Debbugs::Status qw(read_bug split_status_fields generate_index_db_line);
+
+my %options = (debug => 0,
+ help => 0,
+ man => 0,
+ verbose => 0,
+ quiet => 0,
+ quick => 0,
+ service => 'debbugs',
+ );
+
+
+GetOptions(\%options,
+ 'quick|q',
+ 'service|s',
+ 'sysconfdir|c',
+ 'spool_dir|spool-dir=s',
+ 'debug|d+','help|h|?','man|m');
+
+pod2usage() if $options{help};
+pod2usage({verbose=>2}) if $options{man};
+
+$DEBUG = $options{debug};
+
+my @USAGE_ERRORS;
+$options{verbose} = $options{verbose} - $options{quiet};
+
+pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS;
+
+if (exists $options{spool_dir} and defined $options{spool_dir}) {
+ $config{spool_dir} = $options{spool_dir};
+}
+chdir($config{spool_dir}) or die "chdir $config{spool_dir} failed: $!";
+
+my $verbose = $options{debug};
+
+my $initialdir = "db-h";
+
+if (defined $ARGV[0] and $ARGV[0] eq "archive") {
+ $initialdir = "archive";
+}
+
+if (not lockpid($config{spool_dir}.'/lock/debbugs-rebuild-index.db')) {
+ print STDERR "Another debbugs-rebuild-index.db is running; stopping\n";
+ exit 1;
+}
+
+my $fh_type = $initialdir;
+# if initaldir is db-h, the file is db.
+$fh_type = 'db' if $initialdir eq 'db-h';
+
+my $file = "index.${fh_type}.realtime";
+my $idx_rebuild = IO::File->new($file.'.rebuild','w')
+ or die "Couldn't open ${file}.rebuild: $!";
+
+
+my @dirs = ($initialdir);
+my $cnt = 0;
+my %bugs;
+while (my $dir = shift @dirs) {
+ printf "Doing dir %s ...\n", $dir if $verbose;
+
+ opendir(DIR, "$dir/.") or die "opendir $dir: $!";
+ my @subdirs = readdir(DIR);
+ closedir(DIR);
+
+ my @list = map { m/^(\d+)\.summary$/?($1):() } @subdirs;
+ push @dirs, map { m/^(\d+)$/ && -d "$dir/$1"?("$dir/$1"):() } @subdirs;
+
+ for my $bug (@list) {
+ print "Up to $cnt bugs...\n" if (++$cnt % 100 == 0 && $verbose);
+ my $stat = stat(getbugcomponent($bug,'summary',$initialdir));
+ if (not defined $stat) {
+ print STDERR "Unable to stat $bug $!\n";
+ next;
+ }
+ my $data = read_bug(bug => $bug,
+ location => $initialdir);
+ my $line = generate_index_db_line($data);
+ $bugs{$bug} = $line;
+ }
+}
+binmode($idx_rebuild,':raw:encoding(UTF-8)');
+print {$idx_rebuild} $bugs{$_} foreach sort {$a <=> $b} keys %bugs;
+close($idx_rebuild);
+rename("$file.rebuild", $file);
+
+
+__END__
* Fix failure to forcibly merge/merge when found/fixed is not qualified
(closes: #670456). Thanks to Jonathan Nieder and Bernhard Schmidt.
* Add libravatar support.
+ * Fix double encoding of attachments (closes: #703300)
[Thanks to Arnout Engelen: ]
* Add Homepage (closes: #670555).
a site admin aware of its existence (closes: #688345).
* Make sure that mails to gSubscriptionDomain and gBugSubscriptionDomain
are only sent out if the variables in config are defined and
- have a lenght < 0 (closes: #688344).
+ have a length < 0 (closes: #688344).
* Use locale independent date format for mail processing and service mail
generation (closes: #688745).
+ * Fix spelling error in /debian/changelog.
+ * Fix lintian issue: description-synopsis-starts-with-article.
+ * Fix lintian issues: debian-rules-missing-recommended-target build-arch,
+ debian-rules-missing-recommended-target build-indep.
+ * Switch to debian/source/format: 3.0 (native).
+ * Fix lintian issue: debbugs source: duplicate-in-relation-field in
+ libdebbugs-perl depends: libtext-template-perl, libtext-template-perl.
+ * Fix lintian issues: debbugs source:
+ debian-rules-makemaker-prefix-is-deprecated line 44,
+ debian-rules-makemaker-prefix-is-deprecated line 56.
+ * Fix lintian issues: libdebbugs-perl: spelling-error-in-manpage for:
+ + usr/share/man/man3/Debbugs::Recipients.3pm.gz
+ + usr/share/man/man3/Debbugs::SOAP.3pm.gz
+ + usr/share/man/man3/Debbugs::Status.3pm.gz
+ * Raise Standards to 3.9.4 (after fixing several lintian issues).
+ * Pass param bug=<NNN> to bugreport.html call in bugreport.cgi.
-- Don Armstrong <don@debian.org> Wed, 25 Aug 2010 01:57:38 -0700
Priority: extra
Maintainer: Debbugs developers <debian-debbugs@lists.debian.org>
Uploaders: Colin Watson <cjwatson@debian.org>, Don Armstrong <don@debian.org>
-Standards-Version: 3.8.2
+Standards-Version: 3.9.4
Vcs-Browser: http://bugs.debian.org/debbugs-source/mainline
Vcs-Git: http://bugs.debian.org/debbugs-source/debbugs.git
Build-Depends: debhelper (>= 5)
libdebbugs-perl,
Recommends: debbugs-web
Suggests: spamassassin (>= 3.0), libcgi-alert-perl
-Description: The bug tracking system based on the active Debian BTS
+Description: bug tracking system based on the active Debian BTS
Debian has a bug tracking system which files details of bugs reported by
users and developers. Each bug is given a number, and is kept on file until
it is marked as having been dealt with. The system is mainly controlled by
${misc:Depends},
libdebbugs-perl, debbugs-web, libconfig-simple-perl,
libuser-perl, rsync, libhttp-server-simple-perl, libnet-server-perl
-Description: run and maintains a local mirror of the Debian BTS
+Description: Run and maintains a local mirror of the Debian BTS
Debian has a bug tracking system which files details of bugs reported
by users and developers. Each bug is given a number, and is kept on
file until it is marked as having been dealt with. The system is
PERL ?= /usr/bin/perl
-build: build-stamp
+build: build-arch build-indep
+
+build-arch:
+# nothing to do, as there aren't any architecture-dependent packages
+
+build-indep: build-stamp
+
build-stamp:
# Call the test suite
$(PERL) Makefile.PL INSTALLDIRS=vendor
dh_clean -k
dh_installdirs
$(MAKE) install_mostfiles DESTDIR=$(DEST_DIR)
- $(MAKE) -f Makefile.perl install PREFIX=$(DEST_DIR)/usr
+ $(MAKE) -f Makefile.perl install DESTDIR=$(DEST_DIR)
touch $@
binary-arch:
dh_clean -k
dh_installdirs
$(MAKE) install_mostfiles DESTDIR=$(DEST_DIR)
- $(MAKE) -f Makefile.perl install PREFIX=$(DEST_DIR)/usr
+ $(MAKE) -f Makefile.perl install DESTDIR=$(DEST_DIR)
dh_install --sourcedir=debian/tmp --fail-missing
dh_installdocs
dh_installchangelogs
--- /dev/null
+3.0 (native)
\ No newline at end of file
open BUGCLOSERS, '> /org/bugs.debian.org/www/stats/bugclosers.txt.new'
or die "can't open bugclosers.txt.new: $!";
+binmode(BUGCLOSERS,':raw:encoding(UTF-8)');
for my $closer (sort { $bugclosers{$a} <=> $bugclosers{$b} } keys %bugclosers) {
printf BUGCLOSERS "%4d %s\n", $bugclosers{$closer}, $closer
or die "can't write to bugclosers.txt.new: $!";
pre.message {
font-family: monospace;
- padding-top: 0;
+ padding-top: 8px;
margin-top: 0;
border-top: 0;
}
overflow: auto;
}
+div.header {
+ font-family: sans-serif;
+ font-size: 95%;
+ color: #3c3c3c;
+ padding: 0px;
+ line-height: 120%;
+ margin: 0px;
+}
+
div.headers p {
font-family: sans-serif;
font-size: 95%;
float: right;
}
-span.header {
+span.headerfield {
font-weight: bold
};
use Test::More;
eval "use Test::Pod 1.00";
plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
-all_pod_files_ok(all_pod_files('.'));
+all_pod_files_ok(grep {$_ !~ /[~#]$/} all_pod_files((-e 'blib'?'blib':(qw(Debbugs Mail))),
+ (qw(bin cgi scripts))
+ ));
--- /dev/null
+# -*- mode: cperl;-*-
+
+use Test::More tests => 9;
+
+use warnings;
+use strict;
+
+use utf8;
+
+# Here, we're going to shoot messages through a set of things that can
+# happen.
+
+# First, we're going to send mesages to receive.
+# To do so, we'll first send a message to submit,
+# then send messages to the newly created bugnumber.
+
+use IO::File;
+use File::Temp qw(tempdir);
+use Cwd qw(getcwd);
+use Debbugs::MIME qw(create_mime_message);
+use File::Basename qw(dirname basename);
+# The test functions are placed here to make things easier
+use lib qw(t/lib);
+use DebbugsTest qw(:all);
+use Data::Dumper;
+use Encode qw(decode encode decode_utf8 encode_utf8);
+
+# HTTP::Server:::Simple defines a SIG{CHLD} handler that breaks system; undef it here.
+$SIG{CHLD} = sub {};
+my %config;
+eval {
+ %config = create_debbugs_configuration(debug => exists $ENV{DEBUG}?$ENV{DEBUG}:0);
+};
+if ($@) {
+ BAIL_OUT($@);
+}
+
+my $sendmail_dir = $config{sendmail_dir};
+my $spool_dir = $config{spool_dir};
+my $config_dir = $config{config_dir};
+
+END{
+ if ($ENV{DEBUG}) {
+ diag("spool_dir: $spool_dir\n");
+ diag("config_dir: $config_dir\n");
+ diag("sendmail_dir: $sendmail_dir\n");
+ }
+}
+
+# We're going to use create mime message to create these messages, and
+# then just send them to receive.
+
+send_message(to=>'submit@bugs.something',
+ headers => [To => 'submit@bugs.something',
+ From => 'föoff@bugs.something',
+ Subject => 'Submiting a bug',
+ ],
+ body => <<EOF,attachments => [{Type=>"text/plain",Charset=>"utf-8",Data=><<EOF2}]) or fail('Unable to send message');
+Package: foo
+Severity: normal
+
+This is a silly bug
+EOF
+This is the silly bug's test ütff8 attachment.
+EOF2
+
+
+
+# now we check to see that we have a bug, and nextnumber has been incremented
+ok(-e "$spool_dir/db-h/01/1.log",'log file created');
+ok(-e "$spool_dir/db-h/01/1.summary",'sumary file created');
+ok(-e "$spool_dir/db-h/01/1.status",'status file created');
+ok(-e "$spool_dir/db-h/01/1.report",'report file created');
+ok(system('sh','-c','[ $(grep "attachment." '.$spool_dir.'/db-h/01/1.log|grep -v "ütff8"|wc -l) -eq 0 ]') == 0,
+ 'Everything attachment is escaped properly');
+
+# next, we check to see that (at least) the proper messages have been
+# sent out. 1) ack to submitter 2) mail to maintainer
+
+# This keeps track of the previous size of the sendmail directory
+my $SD_SIZE = 0;
+$SD_SIZE =
+ num_messages_sent($SD_SIZE,2,
+ $sendmail_dir,
+ 'submit messages appear to have been sent out properly',
+ );
+
+
+# now send a message to the bug
+
+send_message(to => '1@bugs.something',
+ headers => [To => '1@bugs.something',
+ From => 'föoff@bugs.something',
+ Subject => 'Sending a message to a bug',
+ ],
+ body => <<EOF) or fail('sending message to 1@bugs.someting failed');
+Package: foo
+Severity: normal
+
+This is a silly bug
+EOF
+
+$SD_SIZE =
+ num_messages_sent($SD_SIZE,2,
+ $sendmail_dir,
+ '1@bugs.something messages appear to have been sent out properly');
+
+# just check to see that control doesn't explode
+send_message(to => 'control@bugs.something',
+ headers => [To => 'control@bugs.something',
+ From => 'föoff@bugs.something',
+ Subject => 'Munging a bug',
+ ],
+ body => <<EOF) or fail 'message to control@bugs.something failed';
+severity 1 wishlist
+retitle 1 ütff8 title encoding test
+thanks
+EOF
+
+$SD_SIZE =
+ num_messages_sent($SD_SIZE,1,
+ $sendmail_dir,
+ 'control@bugs.something messages appear to have been sent out properly');
+# now we need to check to make sure the control message was processed without errors
+# now we need to check to make sure that the control message actually did anything
+# This is an eval because $ENV{DEBBUGS_CONFIG_FILE} isn't set at BEGIN{} time
+eval "use Debbugs::Status qw(read_bug writebug);";
+ok(system('bin/debbugs-rebuild-index.db')==0,'debbugs-rebuild-index seems to work');
"$spool_dir/index.archive");
# create the spool files and sub directories
- map {system('mkdir','-p',"$spool_dir/$_"); }
- map {('db-h/'.$_,'archive/'.$_)}
- map { sprintf "%02d",$_ % 100} 0..99;
+ for my $dir (0..99) {
+ for my $archive (qw(db-h archive)) {
+ system('mkdir','-p',"$spool_dir/$archive/".sprintf('%02d',$dir));
+ }
+ }
system('mkdir','-p',"$spool_dir/incoming");
system('mkdir','-p',"$spool_dir/lock");
$ENV{LOCAL_PART} = $param{to};
my ($rfd,$wfd);
my $output='';
- local $SIG{PIPE} = 'IGNORE';
- local $SIG{CHLD} = sub {};
+ my $pipe_handler = $SIG{PIPE};
+ $SIG{PIPE} = 'IGNORE';
+ $SIG{CHLD} = 'DEFAULT';
my $pid = open3($wfd,$rfd,$rfd,'scripts/receive')
or die "Unable to start receive: $!";
print {$wfd} create_mime_message($param{headers},
$param{attachments}) or
die "Unable to to print to receive";
close($wfd) or die "Unable to close receive";
+ $SIG{PIPE} = $pipe_handler;
my $err = $? >> 8;
my $childpid = waitpid($pid,0);
if ($childpid != -1) {
}
{$log}
<hr>
-<p class="msgreceived">Send a report that <a href="http://{$config{cgi_domain}}/bugspam.cgi">this bug log contains spam</a>.</p>
+<p class="msgreceived">Send a report that <a href="http://{$config{cgi_domain}}/bugspam.cgi?bug={$bug_num}">this bug log contains spam</a>.</p>
<hr>
{include(q(html/html_tail))}
</body>