Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37817376
en ru br
Репозитории ALT

Группа :: Разработка/Perl
Пакет: perl-CPAN-Checksums

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

CPAN-Checksums-2.08/000075500000000000000000000000001163670205700141145ustar00rootroot00000000000000CPAN-Checksums-2.08/MANIFEST000064400000000000000000000004031163670205700152420ustar00rootroot00000000000000lib/CPAN/Checksums.pm
Makefile.PL
MANIFEST
MANIFEST.SKIP
META.yml
README
SIGNATURE
t/00signature.t
t/42.gz
t/43
t/44.bz2
t/52podcover.t
t/CHECKSUMS
t/pod.t
t/updatedir.t
Todo
META.json Module JSON meta-data (added by MakeMaker)
CPAN-Checksums-2.08/MANIFEST.SKIP000064400000000000000000000002121163670205700160050ustar00rootroot00000000000000MYMETA.(yml|json)
ChangeLog.old
DISTS
MANIFEST.bak
Makefile.old
^Makefile$
\.lwpcookies
\.releaserc
\.svn/
blib/
pm_to_blib
~$
\.tar\.gz$
CPAN-Checksums-2.08/META.json000064400000000000000000000022041163670205700155330ustar00rootroot00000000000000{
"abstract" : "unknown",
"author" : [
"unknown"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 6.59, CPAN::Meta::Converter version 2.112150",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : "2"
},
"name" : "CPAN-Checksums",
"no_index" : {
"directory" : [
"t",
"inc"
]
},
"prereqs" : {
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : 0
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : 0
}
},
"runtime" : {
"requires" : {
"Compress::Bzip2" : 0,
"Compress::Zlib" : 0,
"Data::Compare" : 0,
"Data::Dumper" : 0,
"Digest::MD5" : "2.36",
"Digest::SHA" : 0,
"DirHandle" : 0,
"File::Spec" : 0,
"File::Temp" : 0,
"IO::File" : "1.14",
"Module::Signature" : 0
}
}
},
"release_status" : "stable",
"version" : "2.08"
}
CPAN-Checksums-2.08/META.yml000064400000000000000000000011621163670205700153650ustar00rootroot00000000000000---
abstract: unknown
author:
- unknown
build_requires:
ExtUtils::MakeMaker: 0
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 6.59, CPAN::Meta::Converter version 2.112150'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: CPAN-Checksums
no_index:
directory:
- t
- inc
requires:
Compress::Bzip2: 0
Compress::Zlib: 0
Data::Compare: 0
Data::Dumper: 0
Digest::MD5: 2.36
Digest::SHA: 0
DirHandle: 0
File::Spec: 0
File::Temp: 0
IO::File: 1.14
Module::Signature: 0
version: 2.08
CPAN-Checksums-2.08/Makefile.PL000064400000000000000000000144501163670205700160720ustar00rootroot00000000000000use ExtUtils::MakeMaker qw(:DEFAULT);
my $Id = q$Id: Makefile.PL 3 2005-10-30 13:58:32Z k $;

my $version_diff = 0; # we'll have to die if this becomes true
{
my $version_from = q(lib/CPAN/Checksums.pm);

{
local $^W;
$ExtUtils::MakeMaker::VERSION = eval $ExtUtils::MakeMaker::VERSION;
warn "Your MakeMaker is a bit dated[$ExtUtils::MakeMaker::VERSION].\nYou should get a new one\n"
if $ExtUtils::MakeMaker::VERSION < 6.0;
}

if ($ARGV[0] && $ARGV[0] eq "--setversion") {
die "Your perl is a bit dated[$]].\nDo not make a release with it\n" if $] < 5.008;
die "Your MakeMaker is a bit dated[$ExtUtils::MakeMaker::VERSION].\nDo not make a release with it\n"
if $ExtUtils::MakeMaker::VERSION < 6.4;
die "Your MakeMaker doesn't do the sign woodoo" unless
MM->can("signature_target");
shift @ARGV;
local $ENV{LANG} = "C";
open my $st, "svn st -u|" or die;
my $dirty = 0;
while (<$st>) {
next if /^\?/;
next if /^Head revision:/;
next if /^Status against revision:/;
print;
$dirty++;
}
close $st;
die "Not everything checked in?" if $dirty;

# $re parses the upper boundary of the output of svnversion
my $re = qr/(?:\d+:)?(\d+)[SM]*$/;
my($sv_dot) = `svnversion .` =~ $re;
my($sv_from) = `svn st -u -v $version_from` =~ /^.{8}\s*(?:\d+)\s*(\d+)/;
die "Could not determine sv_from or sv_dot"
unless $sv_from > 0 && $sv_dot > 0;
my $version_set_manually = 1;
if ($version_set_manually) {
# we must control that the VERSION in CPAN.pm is the same as in the Makefile
unshift @INC, "lib";
require $version_from;
open my $fh, "make the-release-name|" or die;
my $have_version;
while (<$fh>) {
next unless /^version\s+([\d\._]+)/;
$have_version = eval $1;
}
die "could not determine current version from Makefile" unless $have_version;
eval q{
no warnings "numeric";
if ($CPAN::Checksums::VERSION != $have_version) {
warn "Not equal: CPAN::Checksums::VERSION[$CPAN::Checksums::VERSION] Makefile version[$have_version]";
$version_diff = 1;
}
};
die $@ if $@;
} else {
if ($sv_dot > $sv_from) {
warn "setting some property to make a checkin of this file possible";
0==system(svn => "propset",
"cpan:release",
"after_$sv_dot",
$version_from) or die;
warn "checking in to get the version up to the bleading edge";
0==system(svn => "ci",
"-m",
"Property set for release after_$sv_dot",
$version_from) or die;
# will have to die after Makefile is rewritten:
$version_diff = 1;
}
}
exit unless $version_diff;
}
}
my $prereq_pm = {
'Compress::Bzip2' => 0,
'Compress::Zlib' => 0,
'Data::Compare' => 0,
'Data::Dumper' => 0,
'Digest::MD5' => "2.36",
'Digest::SHA' => 0,
'DirHandle' => 0,
'File::Spec' => 0,
'File::Temp' => 0,
'IO::File' => "1.14",
};
for my $interesting_module (qw(
Module::Signature
)) {
eval "require $interesting_module";
if (!$@) {
$prereq_pm->{$interesting_module} ||= 0;
}
}

WriteMakefile(
'NAME' => 'CPAN::Checksums',
'VERSION_FROM' => 'lib/CPAN/Checksums.pm',
(MM->can("signature_target") ? (SIGN => 1) : ()),
'PREREQ_PM' => $prereq_pm,
($ExtUtils::MakeMaker::VERSION >= 6.3002 ?
(LICENSE => "perl") : (),
),
'dist' => {
DIST_DEFAULT => join(" ",
"verify-changes-date",
"verify-changes-version",
'Makefile',
"META.yml",
"setversion",
"README",
"all",
'tardist',
),
COMPRESS => 'gzip -9f'
},
);

if ($version_diff){
die "
==> I had to update some \$VERSIONs <==
==> Your Makefile has been rebuilt. <==
==> Please rerun the make command. <==
";
}

package MY;
sub postamble {
q{
setversion:
$(PERL) Makefile.PL --setversion

Makefile : lib/CPAN/Checksums.pm

README: Makefile
$(PERL) -MPod::Text -e 'Pod::Text->new->parse_from_file(\*ARGV)' lib/CPAN/Checksums.pm > $@

the-release-name :
$(NOECHO) $(ECHO) 'version ' $(VERSION)
$(NOECHO) $(ECHO) 'release-name ' $(DISTVNAME).tar$(SUFFIX)

release :: disttest
echo Once we are on git: git tag -m 'This is $(VERSION)' "$(VERSION)"
ls -l $(DISTVNAME).tar$(SUFFIX)
rm -rf $(DISTVNAME)
$(NOECHO) $(ECHO) ' lftp pause.perl.org'
$(NOECHO) $(ECHO) ' cd incoming'
$(NOECHO) $(ECHO) ' put $(DISTVNAME).tar$(SUFFIX)'
$(NOECHO) $(ECHO) ' quit'
$(NOECHO) $(ECHO) ' Once we are on git: git push --tags'

sign:
`dirname $(PERL)`/cpansign -s

META.yml: metafile
$(CP) $(DISTVNAME)/META.yml ./META.yml

verify-changes-date:
@$(PERL) -ne 'BEGIN{my@t=(localtime)[5,4,3];$$t[0]+=1900;$$t[1]++;$$t=sprintf"%04d-%02d-%02d",@t}' \
-e '$$ok++,exit if /^$$t\s/; END{die "Alert: did not find <$$t> in Changes file" unless $$ok}' Changes

verify-changes-version:
@$(PERL) -ne '$$ok++,exit if /\b$(VERSION)\b/; END{die "Alert: did not find <$(VERSION)> in Changes file" unless $$ok}' Changes

}
}

sub dist_ci {
return qq{ci :
svn ci
};
}

sub dist_test {
return q{
# if we depend on $(DISTVNAME).tar$(SUFFIX), then the rest of the
# Makefile breaks our intent to NOT remake dist
disttest :
rm -rf $(DISTVNAME)
tar xvzf $(DISTVNAME).tar$(SUFFIX)
cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)

}
}
sub distsignature {
my($self) = shift;
my $ret = $self->SUPER::distsignature_target(@_);
$ret =~ s|cpansign|\`dirname \$(PERL)\`/cpansign|g;
return $ret;
}
CPAN-Checksums-2.08/README000064400000000000000000000072071163670205700150020ustar00rootroot00000000000000NAME
CPAN::Checksums - Write a "CHECKSUMS" file for a directory as on CPAN

SYNOPSIS
use CPAN::Checksums qw(updatedir);
my $success = updatedir($directory);

INCOMPATIBILITY ALERT
Since version 1.0 the generation of the attribute "shortname" is turned
off by default. It was too slow and was not used as far as I know, and
above all, it could fail on large directories. The shortname feature can
still be turned on by setting the global variable $TRY_SHORTNAME to a
true value.

DESCRIPTION
$success = updatedir($dir)
"updatedir()" takes a directory name as argument and writes a typical
"CHECKSUMS" file in that directory as used on CPAN unless a previously
written "CHECKSUMS" file is there that is still valid. Returns 2 if a
new "CHECKSUMS" file has been written, 1 if a valid "CHECKSUMS" file
is already there, otherwise dies.

Note: since version 2.0 updatedir on empty directories behaves just
the same. In older versions it silently did nothing.

Global Variables in package CPAN::Checksums
$IGNORE_MATCH
If the global variable $IGNORE_MATCH is set, then all files matching
this expression will be completely ignored and will not be included
in the CPAN "CHECKSUMS" files. Per default this variable is set to

qr{(?i-xsm:readme$)}

$CAUTION
Setting the global variable $CAUTION causes updatedir() to report
changes of files in the attributes "size", "mtime", "md5", or
"md5-ungz" to STDERR.

$TRY_SHORTNAME
By setting the global variable $TRY_SHORTNAME to a true value, you
can tell updatedir() to include an attribute "shortname" in the
resulting hash that is 8.3-compatible. Please note, that updatedir()
in this case may be slow and may even fail on large directories,
because it will always only try 1000 iterations to find a name that
is not yet taken and then give up.

$SIGNING_KEY
Setting the global variable $SIGNING_KEY makes the generated
"CHECKSUMS" file to be clear-signed by the command specified in
$SIGNING_PROGRAM (defaults to "gpg --clearsign --default-key "),
passing the signing key as an extra argument. The resulting
"CHECKSUMS" file should look like:

0&&<<''; # this PGP-signed message is also valid perl
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

# CHECKSUMS file written on ... by CPAN::Checksums (v...)
$cksum = {
...
};

__END__
-----BEGIN PGP SIGNATURE-----
...
-----END PGP SIGNATURE-----

note that the actual data remains intact, but two extra lines are
added to make it legal for both OpenPGP and perl syntax.

$MIN_MTIME_CHECKSUMS
If the global variable $MIN_MTIME_CHECKSUMS is set, then updatedir
will renew signatures on checksum files that have an older mtime
than the given value.

PREREQUISITES
DirHandle, IO::File, Digest::MD5, Digest::SHA, Compress::Bzip2,
Compress::Zlib, File::Spec, Data::Dumper, Data::Compare, File::Temp

BUGS
If updatedir is interrupted, it may leave a temporary file lying around.
These files have the File::Temp template "CHECKSUMS.XXXX" and should be
harvested by a cronjob.

AUTHOR
Andreas Koenig, andreas.koenig@anima.de; GnuPG support by Autrijus Tang

COPYRIGHT & LICENSE
Copyright (c) 2002-2008 Andreas Koenig, Audrey Tang, Steve Peters.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

SEE ALSO
perl(1).

CPAN-Checksums-2.08/SIGNATURE000064400000000000000000000031531163670205700154020ustar00rootroot00000000000000This file contains message digests of all files listed in MANIFEST,
signed via the Module::Signature module, version 0.68.

To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:

% cpansign -v

It will check each file's integrity, as well as the signature's
validity. If "==> Signature verified OK! <==" is not displayed,
the distribution may already have been compromised, and you should
not run its Makefile.PL or Build.PL.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

SHA1 6587f782cbd9cb71036f2e2492ca3daa389521c3 MANIFEST
SHA1 1c21142a9af69d1da5c027b924b8b0c052beb1da MANIFEST.SKIP
SHA1 7faea96c2f741328c696fe04e9bcc8fe41a61499 META.json
SHA1 ae1ec5a6c499264b265a45d2471cbba867758196 META.yml
SHA1 98d4acdec8e5b42574f8f32f453c0c0933fa569f Makefile.PL
SHA1 378ba4b97d5a989790877de0214ca23ac5aeef37 README
SHA1 b929ff9f01730419548cab2dfcc30003b49fbbfb Todo
SHA1 b8158703f7dbb962c56a07183b375a766951e4f1 lib/CPAN/Checksums.pm
SHA1 8091e870af6f081607bab636ab1e8fcfa18b12be t/00signature.t
SHA1 51e1c061bc02e9a38948a5d8e3ca7352830f0fac t/42.gz
SHA1 23e182506f4b883d8aae3d29d08e044c55b04deb t/43
SHA1 0d942b3ef6791694fde4693d3329a0ff924cb583 t/44.bz2
SHA1 57fa704d8f013fd117d9431b933932ae5c2f6a89 t/52podcover.t
SHA1 2d74a36030efca3a42026e2ceab6837c052e8a53 t/CHECKSUMS
SHA1 6a79f15a10337bd3450604abf39d4462df2a550b t/pod.t
SHA1 3a73818d40fce12a21bf9d4d2c38ee2145cc0628 t/updatedir.t
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)

iEYEARECAAYFAk5cg3wACgkQ7IA58KMXwV0uzQCfc/vBboe7anyS25qj+zBglXSv
gJkAn2f3uvbHfXjdSN/XXNvss5YLH1Yc
=snWE
-----END PGP SIGNATURE-----
CPAN-Checksums-2.08/Todo000064400000000000000000000025711163670205700147510ustar00rootroot000000000000002009-09-20 Andreas J. Koenig <andk@cpan.org>

* Ryan Niebur sent me a note that we have no copyright information in
the whole package. So although I have LICENSE stuff in the Makefile.PL,
the copyrigth escaped me somehow. How many other distros will have this
deficiency!

"In Debian we need copyright/license information for all of the packages
we upload. Could you give us (replying to this email is fine): years of
copyright, copyright holders' names, copyright holders' e-mail
addresses. Unfortunately without this information we cannot upload it."

That's only Audrey and Steve Peters and me.

2005-12-11 Andreas Koenig <andk@cpan.org>

* running updateddir on all 4012 checksummed directories on CPAN takes a
hell lot of time (over an hour) and slows other processes down, so I
wonder where the time is spent. If it were ungzip, we could lax our
interest to only computing it for files that have a new ungzip checksum
or so ($SKIP_UNGZ_IF_GZ_UNCHANGED or so).

But if we can make sure that updatedir is always run after a change
(both upload and delete), we can run the whole find/update thing just
once a week. For now I have reduced it to every 6 hours so I can
investigate changes better.

#########################################################################
Local Variables:
mode: change-log
change-log-default-name: "Todo"
tab-width: 2
left-margin: 2
End:
CPAN-Checksums-2.08/lib/000075500000000000000000000000001163670205700146625ustar00rootroot00000000000000CPAN-Checksums-2.08/lib/CPAN/000075500000000000000000000000001163670205700154035ustar00rootroot00000000000000CPAN-Checksums-2.08/lib/CPAN/Checksums.pm000064400000000000000000000307031163670205700176710ustar00rootroot00000000000000package CPAN::Checksums;

use strict;
use vars qw(
$CAUTION
$DIRNAME
$IGNORE_MATCH
$MIN_MTIME_CHECKSUMS
$SIGNING_KEY
$SIGNING_PROGRAM
$TRY_SHORTNAME
$VERSION
@EXPORT_OK
@ISA
);

require Exporter;

@ISA = qw(Exporter);
@EXPORT_OK = qw(updatedir);
$VERSION = "2.08";
$VERSION =~ s/_//;
$CAUTION ||= 0;
$TRY_SHORTNAME ||= 0;
$SIGNING_PROGRAM ||= 'gpg --clearsign --default-key ';
$SIGNING_KEY ||= '';
$MIN_MTIME_CHECKSUMS ||= 0;
$IGNORE_MATCH = qr{(?i-xsm:readme$)};

use DirHandle ();
use IO::File ();
use Digest::MD5 ();
use Compress::Bzip2();
use Compress::Zlib ();
use File::Spec ();
use File::Temp;
use Data::Dumper ();
use Data::Compare ();
use Digest::SHA ();

sub _dir_to_dref {
my($dirname,$old_dref) = @_;
my($dref) = {};
my($dh)= DirHandle->new;
my($fh) = new IO::File;
$dh->open($dirname) or die "Couldn't opendir $dirname\: $!";
my(%shortnameseen);
DIRENT: for my $de ($dh->read) {
next if $de =~ /^\./;
next if substr($de,0,9) eq "CHECKSUMS";
next if $IGNORE_MATCH && $de =~ $IGNORE_MATCH;

my $abs = File::Spec->catfile($dirname,$de);

#
# SHORTNAME offers an 8.3 name, probably not needed but it was
# always there,,,
#
if ($TRY_SHORTNAME) {
my $shortname = lc $de;
$shortname =~ s/\.tar[._-]gz$/\.tgz/;
my $suffix;
($suffix = $shortname) =~ s/.*\.//;
substr($suffix,3) = "" if length($suffix) > 3;
my @p;
if ($shortname =~ /\-/) {
@p = $shortname =~ /(.{1,16})-.*?([\d\.]{2,8})/;
} else {
@p = $shortname =~ /(.{1,8}).*?([\d\.]{2,8})/;
}
$p[0] ||= lc $de;
$p[0] =~ s/[^a-z0-9]//g;
$p[1] ||= 0;
$p[1] =~ s/\D//g;
my $counter = 7;
while (length($p[0]) + length($p[1]) > 8) {
substr($p[0], $counter) = "" if length($p[0]) > $counter;
substr($p[1], $counter) = "" if length($p[1]) > $counter--;
}
my $dot = $suffix ? "." : "";
$shortname = "$p[0]$p[1]$dot$suffix";
while (exists $shortnameseen{$shortname}) {
my($modi) = $shortname =~ /([a-z\d]+)/;
$modi++;
$shortname = "$modi$dot$suffix";
if (++$counter > 1000){ # avoid endless loops and accept the buggy choice
warn "Warning: long loop on shortname[$shortname]de[$de]";
last;
}
}
$dref->{$de}->{shortname} = $shortname;
$shortnameseen{$shortname} = undef; # for exists check good enough
}

#
# STAT facts
#
if (-l File::Spec->catdir($dirname,$de)){
# Symlinks are a mess on a replicated, database driven system,
# but as they are not forbidden, we cannot ignore them. We do
# have a directory with nothing but a symlink in it. When we
# ignored the symlink, we did not write a CHECKSUMS file and
# CPAN.pm issued lots of warnings:-(
$dref->{$de}{issymlink} = 1;
}
if (-d File::Spec->catdir($dirname,$de)){
$dref->{$de}{isdir} = 1;
} else {
my @stat = stat $abs or next DIRENT;
$dref->{$de}{size} = $stat[7];
my(@gmtime) = gmtime $stat[9];
$gmtime[4]++;
$gmtime[5]+=1900;
$dref->{$de}{mtime} = sprintf "%04d-%02d-%02d", @gmtime[5,4,3];
_add_digests($de,$dref,"Digest::SHA",[256],"sha256",$abs,$old_dref);
my $can_reuse_old_md5 = 1;
COMPARE: for my $param (qw(size mtime sha256)) {
if (!exists $old_dref->{$de}{$param} ||
$dref->{$de}{$param} ne $old_dref->{$de}{$param}) {
$can_reuse_old_md5 = 0;
last COMPARE;
}
}
if ( $can_reuse_old_md5 ) {
for my $param (qw(md5 md5-ungz md5-unbz2)) {
next unless exists $old_dref->{$de}{$param};
$dref->{$de}{$param} = $old_dref->{$de}{$param};
}
} else {
_add_digests($de,$dref,"Digest::MD5",[],"md5",$abs,$old_dref);
}

} # ! -d
}
$dh->close;
$dref;
}

sub _read_old_ddump {
my($ckfn) = @_;
my $is_signed = 0;
my($fh) = new IO::File;
my $old_ddump = "";
if ($fh->open($ckfn)) {
local $/ = "\n";
while (<$fh>) {
next if /^\#/;
$is_signed = 1 if /SIGNED MESSAGE/;
$old_ddump .= $_;
}
close $fh;
}
return($old_ddump,$is_signed);
}

sub updatedir ($) {
my($dirname) = @_;
my $ckfn = File::Spec->catfile($dirname, "CHECKSUMS"); # checksum-file-name
my($old_ddump,$is_signed) = _read_old_ddump($ckfn);
my($old_dref) = makehashref($old_ddump);
my $dref = _dir_to_dref($dirname,$old_dref);
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Quotekeys = 1;
local $Data::Dumper::Sortkeys = 1;
my $ddump = Data::Dumper->new([$dref],["cksum"])->Dump;
my @ckfnstat = stat $ckfn;
if ($old_ddump) {
local $DIRNAME = $dirname;
if ( !!$SIGNING_KEY == !!$is_signed ) { # either both or neither
if (!$MIN_MTIME_CHECKSUMS || $ckfnstat[9] > $MIN_MTIME_CHECKSUMS ) {
# recent enough
return 1 if $old_ddump eq $ddump;
return 1 if ckcmp($old_dref,$dref);
}
}
if ($CAUTION) {
my $report = investigate($old_dref,$dref);
warn $report if $report;
}
}
my $ft = File::Temp->new(
DIR => $dirname,
TEMPLATE => "CHECKSUMS.XXXX",
CLEANUP => 0,
) or die;
my $tckfn = $ft->filename;
close $ft;
my($fh) = new IO::File;
open $fh, ">$tckfn\0" or die "Couldn't open >$tckfn\: $!";

local $\;
if ($SIGNING_KEY) {
print $fh "0&&<<''; # this PGP-signed message is also valid perl\n";
close $fh;
open $fh, "| $SIGNING_PROGRAM $SIGNING_KEY >> $tckfn"
or die "Could not call gpg: $!";
$ddump .= "__END__\n";
}

my $message = sprintf "# CHECKSUMS file written on %s GMT by CPAN::Checksums (v%s)\n%s",
scalar gmtime, $VERSION, $ddump;
print $fh $message;
my $success = close $fh;
if ($SIGNING_KEY && !$success) {
warn "Couldn't run '$SIGNING_PROGRAM $SIGNING_KEY'!
Writing to $tckfn directly";
open $fh, ">$tckfn\0" or die "Couldn't open >$tckfn\: $!";
print $fh $message;
close $fh or warn "Couldn't close $tckfn: $!";
}
chmod 0644, $ckfn or die "Couldn't chmod to 0644 for $ckfn\: $!" if -f $ckfn;
rename $tckfn, $ckfn or die "Could not rename: $!";
chmod 0444, $ckfn or die "Couldn't chmod to 0444 for $ckfn\: $!";
return 2;
}

sub _add_digests ($$$$$$$) {
my($de,$dref,$module,$constructor_args,$keyname,$abs,$old_dref) = @_;
my($fh) = new IO::File;
my $dig = $module->new(@$constructor_args);
$fh->open("$abs\0") or die "Couldn't open $abs: $!";
binmode($fh); # make sure it's called as a function, solaris with
# perl 5.8.4 complained about missing method in
# IO::File
$dig->addfile($fh);
$fh->close;
my $digest = $dig->hexdigest;
$dref->{$de}{$keyname} = $digest;
$dig = $module->new(@$constructor_args);
if ($de =~ /\.gz$/) {
my($buffer, $zip);
if (exists $old_dref->{$de}{$keyname} &&
$dref->{$de}{$keyname} eq $old_dref->{$de}{$keyname} &&
exists $old_dref->{$de}{"$keyname-ungz"}
) {
$dref->{$de}{"$keyname-ungz"} = $old_dref->{$de}{"$keyname-ungz"};
return;
}
if ($zip = Compress::Zlib::gzopen($abs, "rb")) {
$dig->add($buffer)
while $zip->gzread($buffer) > 0;
$dref->{$de}{"$keyname-ungz"} = $dig->hexdigest;
$zip->gzclose;
}
} elsif ($de =~ /\.bz2$/) {
my($buffer, $zip);
if (exists $old_dref->{$de}{$keyname} &&
$dref->{$de}{$keyname} eq $old_dref->{$de}{$keyname} &&
exists $old_dref->{$de}{"$keyname-unbz2"}
) {
$dref->{$de}{"$keyname-unbz2"} = $old_dref->{$de}{"$keyname-unbz2"};
return;
}
if ($zip = Compress::Bzip2::bzopen($abs, "rb")) {
$dig->add($buffer)
while $zip->bzread($buffer) > 0;
$dref->{$de}{"$keyname-unbz2"} = $dig->hexdigest;
$zip->bzclose;
}
}
}

sub ckcmp ($$) {
my($old,$new) = @_;
for ($old,$new) {
$_ = makehashref($_);
}
Data::Compare::Compare($old,$new);
}

# see if a file changed but the name not
sub investigate ($$) {
my($old,$new) = @_;
for ($old,$new) {
$_ = makehashref($_);
}
my $complain = "";
for my $dist (sort keys %$new) {
if (exists $old->{$dist}) {
my $headersaid;
for my $diff (qw/md5 sha256 size md5-ungz sha256-ungz mtime/) {
next unless exists $old->{$dist}{$diff} &&
exists $new->{$dist}{$diff};
next if $old->{$dist}{$diff} eq $new->{$dist}{$diff};
$complain .=
scalar gmtime().
" GMT:\ndiffering old/new version of same file $dist:\n"
unless $headersaid++;
$complain .=
qq{\t$diff "$old->{$dist}{$diff}" -> "$new->{$dist}{$diff}"\n}; #};
}
}
}
$complain;
}

sub makehashref ($) {
local($_) = shift;
unless (ref $_ eq "HASH") {
require Safe;
my($comp) = Safe->new("CPAN::Checksums::reval");
my $cksum; # used by Data::Dumper
$_ = $comp->reval($_) || {};
die "CPAN::Checksums: Caught error[$@] while checking $DIRNAME" if $@;
}
$_;
}

1;

__END__

=head1 NAME

CPAN::Checksums - Write a C<CHECKSUMS> file for a directory as on CPAN

=head1 SYNOPSIS

use CPAN::Checksums qw(updatedir);
my $success = updatedir($directory);

=head1 INCOMPATIBILITY ALERT

Since version 1.0 the generation of the attribute C<shortname> is
turned off by default. It was too slow and was not used as far as I
know, and above all, it could fail on large directories. The shortname
feature can still be turned on by setting the global variable
$TRY_SHORTNAME to a true value.

=head1 DESCRIPTION

=over 2

=item $success = updatedir($dir)

C<updatedir()> takes a directory name as argument and writes a typical
C<CHECKSUMS> file in that directory as used on CPAN unless a previously
written C<CHECKSUMS> file is there that is still valid. Returns 2 if a
new C<CHECKSUMS> file has been written, 1 if a valid C<CHECKSUMS> file is
already there, otherwise dies.

Note: since version 2.0 updatedir on empty directories behaves just
the same. In older versions it silently did nothing.

=back

=head2 Global Variables in package CPAN::Checksums

=over

=item $IGNORE_MATCH

If the global variable $IGNORE_MATCH is set, then all files matching
this expression will be completely ignored and will not be included in
the CPAN C<CHECKSUMS> files. Per default this variable is set to

qr{(?i-xsm:readme$)}

=item $CAUTION

Setting the global variable $CAUTION causes updatedir() to report
changes of files in the attributes C<size>, C<mtime>, C<md5>, or
C<md5-ungz> to STDERR.

=item $TRY_SHORTNAME

By setting the global variable $TRY_SHORTNAME to a true value, you can
tell updatedir() to include an attribute C<shortname> in the resulting
hash that is 8.3-compatible. Please note, that updatedir() in this
case may be slow and may even fail on large directories, because it
will always only try 1000 iterations to find a name that is not yet
taken and then give up.

=item $SIGNING_KEY

Setting the global variable $SIGNING_KEY makes the generated C<CHECKSUMS>
file to be clear-signed by the command specified in $SIGNING_PROGRAM
(defaults to C<gpg --clearsign --default-key >), passing the signing
key as an extra argument. The resulting C<CHECKSUMS> file should look like:

0&&<<''; # this PGP-signed message is also valid perl
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

# CHECKSUMS file written on ... by CPAN::Checksums (v...)
$cksum = {
...
};

__END__
-----BEGIN PGP SIGNATURE-----
...
-----END PGP SIGNATURE-----

note that the actual data remains intact, but two extra lines are
added to make it legal for both OpenPGP and perl syntax.

=item $MIN_MTIME_CHECKSUMS

If the global variable $MIN_MTIME_CHECKSUMS is set, then updatedir
will renew signatures on checksum files that have an older mtime than
the given value.

=back

=head1 PREREQUISITES

DirHandle, IO::File, Digest::MD5, Digest::SHA, Compress::Bzip2,
Compress::Zlib, File::Spec, Data::Dumper, Data::Compare, File::Temp

=head1 BUGS

If updatedir is interrupted, it may leave a temporary file lying
around. These files have the File::Temp template C<CHECKSUMS.XXXX> and
should be harvested by a cronjob.

=head1 AUTHOR

Andreas Koenig, andreas.koenig@anima.de; GnuPG support by Autrijus Tang

=head1 COPYRIGHT & LICENSE

Copyright (c) 2002-2008 Andreas Koenig, Audrey Tang, Steve Peters.

This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=head1 SEE ALSO

perl(1).

=cut
CPAN-Checksums-2.08/t/000075500000000000000000000000001163670205700143575ustar00rootroot00000000000000CPAN-Checksums-2.08/t/00signature.t000064400000000000000000000044501163670205700167100ustar00rootroot00000000000000# -*- mode: cperl -*-

use strict;
BEGIN {
sub find_exe {
my($exe,$path) = @_;
my($dir);
#warn "in find_exe exe[$exe] path[@$path]";
for $dir (@$path) {
my $abs = File::Spec->catfile($dir,$exe);
require ExtUtils::MakeMaker;
if (($abs = MM->maybe_command($abs))) {
return $abs;
}
}
}
my $found_prereq = 0;
unless ($found_prereq) {
$found_prereq = eval { require Digest::SHA; 1 };
}
unless ($found_prereq) {
$found_prereq = eval { require Digest::SHA1; 1 };
}
unless ($found_prereq) {
$found_prereq = eval { require Digest::SHA::PurePerl; 1 };
}
my $exit_message = "";
unless ($found_prereq) {
$exit_message = "None of the supported SHA modules (Digest::SHA,Digest::SHA1,Digest::SHA::PurePerl) found";
}
unless ($exit_message) {
if (!-f 'SIGNATURE') {
$exit_message = "No signature file";
}
}
unless ($exit_message) {
if (!-s 'SIGNATURE') {
$exit_message = "Empty signature file";
}
}
unless ($exit_message) {
if (eval { require Module::Signature; 1 }) {
my $min = "0.66";
if ($Module::Signature::VERSION < $min-0.0000001) {
$exit_message = "Signature testing disabled for Module::Signature versions < $min";
}
} else {
$exit_message = "No Module::Signature found [INC = @INC]";
}
}
unless ($exit_message) {
if (!eval { require Socket; Socket::inet_aton('pool.sks-keyservers.net') }) {
$exit_message = "Cannot connect to the keyserver";
}
}
unless ($exit_message) {
require Config;
my(@path) = split /$Config::Config{'path_sep'}/, $ENV{'PATH'};
if (!find_exe('gpg',\@path)) {
$exit_message = "Signature testing disabled without gpg program available";
}
}
if ($exit_message) {
$|=1;
print "1..0 # SKIP $exit_message\n";
eval "require POSIX; 1" and POSIX::_exit(0);
}
}

print "1..1\n";

(Module::Signature::verify() == Module::Signature::SIGNATURE_OK())
or print "not ";
print "ok 1 # Valid signature\n";

# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# End:
CPAN-Checksums-2.08/t/42.gz000064400000000000000000000000321163670205700151410ustar00rootroot00000000000000▀ч3:4231Б1)├яCPAN-Checksums-2.08/t/43000064400000000000000000000000031163670205700145210ustar00rootroot0000000000000043
CPAN-Checksums-2.08/t/44.bz2000064400000000000000000000000471163670205700152260ustar00rootroot00000000000000BZh91AY&SY3:29H !┌,]иАB@лХхДCPAN-Checksums-2.08/t/52podcover.t000064400000000000000000000010671163670205700165400ustar00rootroot00000000000000# -*- mode: cperl -*-
use Test::More;
eval "use 5.00504";
plan skip_all => "perl 5.00504 required for this test" if $@;
eval "use Test::Pod::Coverage 0.18"; # 0.15 was misbehaving according to David Cantrell
plan skip_all => "Test::Pod::Coverage 0.18 required for testing pod coverage" if $@;
plan tests => 1;
my $trustme = { trustme => [ qw{
ckcmp
investigate
makehashref
}]
};
pod_coverage_ok( "CPAN::Checksums", $trustme );
CPAN-Checksums-2.08/t/CHECKSUMS000064400000000000000000000034121163670205700156270ustar00rootroot00000000000000# CHECKSUMS file written on Sat Nov 20 22:14:24 2010 GMT by CPAN::Checksums (v2.07)
$cksum = {
'00signature.t' => {
'md5' => '55d2528e0129b0c32bc51bf287f2ac01',
'mtime' => '2010-11-20',
'sha256' => 'f429ad014eb27261603740854130e696bd106a087f0f92086b2862a3af6dcaf4',
'size' => 2344
},
'42.gz' => {
'md5' => '915cdde7181ab542763969e063b7a9a9',
'md5-ungz' => '50a2fabfdd276f573ff97ace8b11c5f4',
'mtime' => '2005-10-30',
'sha256' => '787e758a975d04560f6a9d4671646a48c4e9da4f40d4e102bc4562cd15c71ab5',
'sha256-ungz' => '084c799cd551dd1d8d5c5f9a5d593b2e931f5e36122ee5c793c1d08a19839cc0',
'size' => 26
},
'43' => {
'md5' => 'f0287f33eba7192e2a9c6a14f829aa1a',
'mtime' => '2010-11-20',
'sha256' => '0e55092af0746630c98d1b2e0d960617c33f8ea7b55739fd18cb7cd5342a28ca',
'size' => 3
},
'44.bz2' => {
'md5' => 'b3c551bfbf1d15ce93b47346a11cc87a',
'md5-unbz2' => 'e760668b6273d38c832c153fde5725da',
'mtime' => '2005-10-30',
'sha256' => '09f646275a0b0622418ed364affe3c2df7dbb02c01862d84d7d06e6b6605c790',
'sha256-unbz2' => 'b1ce0aa6fdf3cf349d773243dab9fbbe09d30619f38b0c1e8977e28c4f0bc495',
'size' => 39
},
'52podcover.t' => {
'md5' => '9845f6c5f049d637c92ae34e67328c77',
'mtime' => '2007-08-05',
'sha256' => '558d9083fe9dfa6aa66806caf4545bee35f2cac36592627aeed3b8cf0ca4fdf2',
'size' => 567
},
'pod.t' => {
'md5' => '45b17e11a9736a0c485f861f95f063b9',
'mtime' => '2005-12-15',
'sha256' => '6109dadab614d170fc3db10b00a4c41c221860b1b1085a54af9a5f9f52480494',
'size' => 152
},
'updatedir.t' => {
'md5' => 'b2dad83957b2786005860303866548c0',
'mtime' => '2010-01-23',
'sha256' => '583d24e7cbbf77a61b56ccced45b6f5b17844d0c8146f652fc92e2380ca63cc7',
'size' => 1808
}
};
CPAN-Checksums-2.08/t/pod.t000064400000000000000000000002301163670205700153210ustar00rootroot00000000000000# -*- mode: cperl -*-

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();
CPAN-Checksums-2.08/t/updatedir.t000064400000000000000000000034201163670205700165240ustar00rootroot00000000000000# -*- Mode: cperl; cperl-indent-level: 4 -*-

# Before `make install' is performed this script should be runnable with
# `make test'.

use File::Path qw(mkpath rmtree);
use File::Spec;
use Test::More;
my $HAVE_TIME_HIRES = 0;

sub _f ($) {File::Spec->catfile(split /\//, shift);}
sub _d ($) {File::Spec->catdir(split /\//, shift);}

my $plan = 21;
if (eval { require Time::HiRes; 1; }) {
$HAVE_TIME_HIRES = 1;
}
plan tests => $plan;

use_ok("CPAN::Checksums");
my $ret = CPAN::Checksums::updatedir("t");
ok($ret >= 1, "ret[$ret]");

my $warn;
{
chmod 0644, _f"t/43";
local *F;
open F, ">", _f"t/43" or die;
print F "4321\n" x 1_000_000;
close F;
local $CPAN::Checksums::CAUTION;
$CPAN::Checksums::CAUTION=1;
$SIG{__WARN__} = sub { $warn = shift; };
$ret = CPAN::Checksums::updatedir("t");
is($ret,2,"changed once");

like($warn,qr/^differing old\/new/m,"warning emitted");

my $start = $HAVE_TIME_HIRES ? Time::HiRes::time() : time;
$ret = CPAN::Checksums::updatedir("t");
my $tooktime = ($HAVE_TIME_HIRES ? Time::HiRes::time() : time) - $start;
is($ret,1,"no change tooktime[$tooktime]");

open F, ">", _f"t/43";
print F "43\n";
close F;
$warn="";
}

$ret = CPAN::Checksums::updatedir("t");
is($ret,2,"changed again");
is($warn,"","no warning");
my @stat = stat _f"t/CHECKSUMS";
sleep 2;
$ret = CPAN::Checksums::updatedir("t");
is($ret,1,"no change");
my @stat2 = stat _f"t/CHECKSUMS";
for my $s (0..7,9..11) { # 8==atime not our business; 12==blocks may magically change
is($stat[$s],$stat2[$s],"unchanged stat element $s");
}
mkpath _d"t/emptydir";
$ret = CPAN::Checksums::updatedir(_d"t/emptydir");
is($ret,2,"empty dir gives also 2");
ok(-f _f"t/emptydir/CHECKSUMS", "found the checksums file");
rmtree _d"t/emptydir";
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin