+ die (shellquote @_)." $? $!" if $r;
+}
+
+sub policyhook {
+ my ($policyallowbits, @polargs) = @_;
+ # => ($exitstatuspolicybitmap);
+ die if $policyallowbits & ~0x3e;
+ my @cmd = ($policyhook,$distro,$dgitrepos,$dgitlive,@polargs);
+ debugcmd '+',@cmd;
+ my $r = system @cmd;
+ die "system: $!" if $r < 0;
+ die "hook (".(shellquote @cmd).") failed ($?)"
+ if $r & ~($policyallowbits << 8);
+ printdebug sprintf "hook => %#x\n", $r;
+ return $r >> 8;
+}
+
+sub mkemptyrepo ($$) {
+ my ($dir,$sharedperm) = @_;
+ runcmd qw(git init --bare --quiet), "--shared=$sharedperm", $dir;
+}
+
+sub mkrepo_fromtemplate ($) {
+ my ($dir) = @_;
+ my $template = "$dgitrepos/_template";
+ locksometree($template);
+ printdebug "copy template $template -> $dir\n";
+ my $r = system qw(cp -a --), $template, $dir;
+ !$r or die "create new repo $dir failed: $r $!";
+}
+
+sub movetogarbage () {
+ # realdestrepo must have been locked
+ my $garbagerepo = "$dgitrepos/${package}_garbage";
+ # We arrange to always keep at least one old tree, for anti-rewind
+ # purposes (and, I guess, recovery from mistakes). This is either
+ # $garbage or $garbage-old.
+ if (stat_exists "$garbagerepo") {
+ rmtree "$garbagerepo-tmp";
+ if (rename "$garbagerepo-old", "$garbagerepo-tmp") {
+ rmtree "$garbagerepo-tmp";
+ } else {
+ die "$garbagerepo $!" unless $!==ENOENT;
+ }
+ rename "$garbagerepo", "$garbagerepo-old" or die "$garbagerepo $!";
+ }
+ rename realdestrepo, $garbagerepo
+ or $! == ENOENT
+ or die "$garbagerepo $!";
+}
+
+sub policy_checkpackage () {
+ my $lfh = lockrealtree();
+
+ $policy = policyhook(FRESHREPO,'check-package',$package);
+ if ($policy & FRESHREPO) {
+ movetogarbage();
+ }
+
+ close $lfh;