diff --git a/install.sh b/install.sh index 980bae8..0a72f40 100755 --- a/install.sh +++ b/install.sh @@ -90,5 +90,6 @@ install_exec prun/prun "$DESTDIR$usr_bindir/prun" install_exec put_websafe/put_websafe "$DESTDIR$usrlocal_bindir/put_websafe" install_exec switch-passwd/switch-passwd "$DESTDIR$root_sbindir/switch-passwd" install_data switch-passwd/switch-passwd.service "$DESTDIR$systemdunitdir/switch-passwd.service" +install_exec pkgadmin/pkgadmin "$DESTDIR$usr_sbindir/pkgadmin" exit diff --git a/make-automaps/make-automaps b/make-automaps/make-automaps index ac88524..e13b778 100755 --- a/make-automaps/make-automaps +++ b/make-automaps/make-automaps @@ -79,7 +79,7 @@ sub create_pkg_map { s/#.*//; /\S/ or next; my ($pkg,$flags)=split ' '; - my $local="/usr/local/pkg/$pkg"; + my $local="/var/pkg/$pkg"; my $rw = $flags eq 'BUILD' ? ' -rw' : ''; if (-d $local) { print $out "$pkg$rw :$local\n"; diff --git a/pkgadmin/pkgadmin b/pkgadmin/pkgadmin new file mode 100755 index 0000000..825075a --- /dev/null +++ b/pkgadmin/pkgadmin @@ -0,0 +1,124 @@ +#! /usr/bin/perl +use strict; +use warnings; + +our $USAGE=<<"EOF"; +usage: + $0 list # show packag status + $0 update # update /var/pkg according to policy and usage +EOF + +our $PKGDIR='/var/pkg'; + +sub sys { + my @cmd=@_; + print join(' ',@cmd),"\n"; + system @cmd; + $? and exit 1; +} + +sub scandir { + my ($dirname)=@_; + opendir my $dir,$dirname or die "$dirname: $!\n"; + return sort grep !/^\./,readdir $dir; +} + +our %WANT_LOCAL; +our %IS_MOUNTED; + +sub get_mounts { + open my $in,'<','/proc/self/mountinfo' or die "/proc/self/mountinfo $!\n"; + while (<$in>) { + my @f=split; + my $root_within_fs=$f[3]; + if ($root_within_fs=~m"^$PKGDIR/(.+)$") { + my ($pkg)=$1; + $IS_MOUNTED{$pkg}=1; + }; + } +} + +sub read_mxpkg { + open my $in,'<','/etc/mxpkg' or die "/etc/mxpkg: $!\n"; + while (<$in>) { + s/#.*//; + /\S/ or next; + my ($pkg,$flags)=split ' '; + $flags eq 'LOCAL' and $WANT_LOCAL{$pkg}=1; + } +} + +sub list { + my %is_local=map {$_=>1} scandir($PKGDIR); + read_mxpkg(); + get_mounts(); + my %pkg=map {$_=>1} (keys %is_local,keys %WANT_LOCAL); + for my $pkg (sort keys %pkg) { + my $want_local=$WANT_LOCAL{$pkg}; + my $is_local =$is_local{$pkg}; + my $is_mounted=$IS_MOUNTED{$pkg}; + printf "%s %s %s %s\n", + ($want_local?'WANT':' '), + ($is_local ?'HAVE':' '), + ($is_mounted?'MNT':' '), + $pkg; + } +} + +sub update { + read_mxpkg(); + for my $dir (scandir $PKGDIR) { + $dir=~/\.TRASH$/ and next; + $WANT_LOCAL{$dir} and next; + -e "$PKGDIR/$dir.TRASH" and next; + sys('mv',"$PKGDIR/$dir","$PKGDIR/$dir.TRASH"); + sys("/usr/sbin/make-automaps"); + } + get_mounts(); + for my $pkg (scandir $PKGDIR) { + $pkg=~/\.TRASH$/ or next; + if ($IS_MOUNTED{$pkg}) { + print "$pkg: still mounted\n"; + } else { + $pkg or die; + sys('rm','-rf',"$PKGDIR/$pkg"); + } + } + for my $pkg (sort keys %WANT_LOCAL) { + -d "$PKGDIR/$pkg" and next; + -d "/package/pkg/$pkg" or next; + sys( + 'pmirror', + '--allowremotefs', + '--delete', + '--mkdir', + '--exclude','./build', + '--nice', + "/package/pkg/$pkg","$PKGDIR/$pkg.INCOMING" + ); + sys('mv',"$PKGDIR/$pkg.INCOMING","$PKGDIR/$pkg"); + sys("/usr/sbin/make-automaps"); + } +} + +umask 022; +-d $PKGDIR or sys('mkdir','-p',$PKGDIR); + +@ARGV or die $USAGE; +my ($cmd,@args)=@ARGV; +if ($cmd eq 'list') { + @args==0 or die $USAGE; + list(); +} elsif ($cmd eq 'update') { + @args==0 or die $USAGE; + update(); +} else { + die $USAGE; +} + + + + + + +