From: Ian Jackson Date: Mon, 18 Feb 2013 16:46:05 +0000 (+0000) Subject: automatic agpl compliance: generation stuff, compiles but untested and not hooked in X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=cgi-auth-flexible.git;a=commitdiff_plain;h=7fd33ab35a68417cac98fd0a8aa4ffcfecf86015 automatic agpl compliance: generation stuff, compiles but untested and not hooked in --- diff --git a/cgi-auth-flexible.pm b/cgi-auth-flexible.pm index 81a12aa..4dd6daf 100644 --- a/cgi-auth-flexible.pm +++ b/cgi-auth-flexible.pm @@ -200,14 +200,6 @@ sub gen_plain_footer_html ($$) { #---------- licence and source code ---------- -#sub dump_licence ($$$) { -# -# my ($c,$r, $fh) = @_; -# foreach my $incdir ($r->_ch('getsource_includedirs')) { -# -# } -#} - sub srcdump_dump_thing ($$$) { my ($c,$r, $thing, $outfn) = @_; die if $thing =~ m/\W/ || $thing !~ m/\w/; @@ -234,6 +226,117 @@ sub dump_plain ($$$$) { } } +sub srcdump_process_dir ($$$$$$) { + my ($c, $v, $dumpdir, $incdir, $tarballcounter, + $needlicence, $dirsdone) = @_; + return () if $v->_ch('srcdump_system_dir', $incdir); + my $upwards = $incdir; + for (;;) { + $upwards =~ s#/+##; + last unless $upwards =~ m#[^/]#; + foreach my $try (@{ $v->{S}{srcdump_vcs_dirs} }) { + if (!stat "$upwards/$try") { + $!==&ENOENT or die "check $upwards/$try $!"; + next; + } + $try =~ m/\w+/ or die; + return if $dirsdone->{$upwards}++; + return $v->_ch(('srcdump_byvcs_'.lc $try), + $dumpdir, $upwards, $tarballcounter); + } + $upwards =~ s#/*[^/]+##; + } + return $v->_ch('srcdump_novcs', $dumpdir, $incdir, $tarballcounter); +} + +sub srcdump_novcs ($$$$$) { + my ($c, $v, $dumpdir, $dir, $tarballcounter) = @_; + my $script = 'find -type f -perm +004'; + foreach my $excl (@{ $v->{S}{srcdump_excludes} }) { + $script .= " \\! -name '$excl'"; + } + $script .= " -print0"; + return srcdump_dir_cpio($c,$v,$dumpdir,$dir,$tarballcounter,$script); +} + +sub srcdump_byvcs_git ($$$$$) { + my ($c, $v, $dumpdir, $dir, $tarballcounter) = @_; + return srcdump_dir_cpio($c,$v,$dumpdir,$dir,$tarballcounter," + git-ls-files -z; + git-ls-files -z --others --exclude-from=.gitignore; + find .git -print0 + "); +} + +sub scrdump_dir_cpio ($$$$$) { + my ($c,$v,$dumpdir,$dir,$tarballcounter,$script) = @_; + my $outfile = "$dumpdir/$$tarballcounter.tar"; + my $pid = fork(); + defined $pid or die $!; + if (!$pid) { + open STDOUT, ">", $outfile or die "$outfile $!"; + chdir $dir or die "chdir $dir: $!"; + exec '/bin/bash','-ec',''," + set -o pipefail + ( + $script + ) | ( + cpio -Hustar -o --quiet -0 -R 1000:1000 || \ + cpio -Hustar -o --quiet -0 + ) + "; + die $!; + } + $!=0; (waitpid $pid, 0) == $pid or die "$!"; + die "$dir ($script) $outfile $?" if $?; + $$tarballcounter++; + return $outfile; +} + +sub srcdump_dirscan_prepare ($$) { + my ($c, $v) = @_; + my $dumpdir = $v->_get_path('srcdump'); + my $lockf = new IO::File "$dumpdir/generate.lock", 'w+' + or die "$dumpdir/generate.lock $!"; + flock $lockf, LOCK_EX or die "$dumpdir/generate.lock $!"; + my $needlicence = "$dumpdir/licence.tmp"; + unlink $needlicence || $!==&ENOENT or die "rm $needlicence $!"; + if (defined $v->{S}{srcdump_licence_path}) { + copy($v->{S}{srcdump_licence_path}, $needlicence) + or die "$v->{S}{srcdump_licence_path} $!"; + $needlicence = undef; + } + my $srctarballcounter = 'aaa'; + my %dirsdone; + my @srcfiles = ("$dumpdir/licence.data"); + foreach my $incdir ($v->_ch('getsource_includedirs')) { + if (defined $needlicence) { + foreach my $try (@{ $v->{S}{srcdump_licence_files} }) { + last if copy("$incdir/$try", $needlicence); + $!==&ENOENT or die "copy $incdir/$try $!"; + } + } + push @srcfiles, $v->_ch('srcdump_process_dir', $dumpdir, $incdir, + \$srctarballcounter, \$needlicence, \%dirsdone); + $dirsdone{$incdir}++; + } + die "licence file not found" unless defined $needlicence; + srcdump_install($c,$v, $dumpdir, 'licence', 'text/plain'); + close $lockf or die $!; +} + +sub srcdump_install ($$$$$) { + my ($c,$v, $dumpdir, $which, $ctype) = @_; + rename "$dumpdir/$which.tmp", "$dumpdir/$which.data" + or die "$dumpdir/$which.data $!"; + my $ctf = new IO::File "$dumpdir/$which.tmp", 'w' + or die "$dumpdir/$which.tmp $!"; + print $ctf $ctype, "\n" or die $!; + close $ctf or die $!; + rename "$dumpdir/$which.tmp", "$dumpdir/$which.ctype" + or die "$dumpdir/$which.ctype $!"; +} + #---------- verifier object methods ---------- sub new_verifier { @@ -292,7 +395,17 @@ sub new_verifier { gen_login_link => \&gen_plain_login_link, gen_postmainpage_form => \&gen_postmainpage_form, srcdump_dump_thing => \&srcdump_dump_thing, - source_includedirs => sub { grep { !m#^/etc/# } @INC; }, + srcdump_prepare => \&srcdump_dirscan_prepare, + srcdump_licence_path => undef, + srcdump_licence_files => [qw(AGPLv3 CGI/Auth/Flexible/AGPLv3)], + srcdump_system_dir => sub { $_[2] =~ m#^/etc/|^/usr/(?!local/)#; }, + srcdump_vcs_dirs => [qw(.git .hg .svn CVS)], + srcdump_byvcs_git => \&srcdump_byvcs_git, + srcdump_byvcs_hg => \&srcdump_byvcs_hg, + srcdump_byvcs_svn => \&srcdump_byvcs_svn, + srcdump_byvcs_cvs => \&srcdump_byvcs_cvs, + srcdump_novcs => \&srcdump_novcs, + srcdump_excludes => [qw(*~ *.bak *.tmp), '#*#'], gettext => sub { gettext($_[2]); }, print => sub { print $_[2] or die $!; }, debug => sub { }, # like print; msgs contain trailing \n