7 Commits

Author SHA1 Message Date
Jay Larson
98c0ab336f The following changes were made:
* Updated Makefile.snaplinux to be more flexible with package names
  * Added bit to set root password in snapinstall
2017-06-02 18:49:47 -05:00
Jay Larson
cdbf4ed7d5 The following changes were made:
* Added ability to dump contents of package
  * Wrapped open3 in eval in Package.pm files()
  * Added :flock to Fcntl in Snap.pm
  * Added lock file to Snap.pm
  * Moved setup() under conditionals where appropriate in snap
2017-06-01 10:39:51 -05:00
Jay Larson
bfa1d110c4 The following changes were made
* Updated Makefile to get version from Snap.pm
  * Updated virtfs() in Snap.pm to properly check for dir with -d
2017-05-31 10:54:33 -05:00
Jay Larson
d306fe03ae The following changes were made:
* corrected issue in reinstall that prevented reinstall of package files
  * added version command
  * updated files() in Package.pm to accept both quiet and verbose options
  * added sha() to Snap.pm which will be used for verify function in future
  * corrected missing '=' in output for search() in Sources.pm
  * removed duplicate file (SRC/snapinstall)
2017-05-26 15:48:52 -05:00
Jay Larson
319401eb51 Corrected issue in assignment to $(SNAP) in Makefile.snaplinux 2017-05-22 14:46:14 -05:00
Jay Larson
4cd5b95d7e The following changes were made:
* Added snapinstall (missed on last check in)
  * Added reinstall functionality to snap
2017-05-22 14:15:38 -05:00
Jay Larson
6a9cce6b3f The following changes were made:
* removed usher
  * various cleanup in output
  * corrected issues with usher() in Package.pm, now using fork()/exec()
  * added snapinstall
  * made virtfs() more robust, will still attempt if fails
  * made strip a little more thoughtful in Makefile.snaplinux
2017-05-22 10:43:07 -05:00
10 changed files with 622 additions and 162 deletions

View File

@@ -8,17 +8,17 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
DEPENDS = binutils,coreutils,gzip,perl=5.20.0,tar DEPENDS = binutils,coreutils,gzip,perl>=5.20.0,tar
ARCH = x86_64 ARCH = x86_64
URL = URL =
DESC = The Snaplinux package management system DESC = The Snaplinux package management system
SNAPVER = 0
ARCHIVE := '' ARCHIVE := ''
SRCDIR := $(PWD)/SRC/snap SRCDIR := $(PWD)/SRC/snap
PATCHDIR := $(PWD)/SRC/patches PATCHDIR := $(PWD)/SRC/patches
VERSION := 0.4-0 VERSION := $(shell grep 'VERSION =>' SRC/snap/Snap.pm| \
sed "s/.*=> '\|',//g")-$(SNAPVER)
MAKEINST = make install
include /usr/share/snap/Makefile.snaplinux include /usr/share/snap/Makefile.snaplinux
@@ -29,7 +29,7 @@ $(ROOT): $(SRCDIR)/Makefile
mkdir -v $(ROOT); \ mkdir -v $(ROOT); \
fi fi
@cd $(SRCDIR) && $(MAKEINST) DESTDIR=$(ROOT) @cd $(SRCDIR) && make install DESTDIR=$(ROOT)
clean: clean:
@rm -rvf $(ROOT) \ @rm -rvf $(ROOT) \

View File

@@ -1,43 +0,0 @@
#!/bin/bash
set -e
case $1 in
preinst)
exit 0
;;
postinst)
setpass=`cat ${TARGET}/etc/shadow|grep ^root|awk -F':' '{print $2}'`
if [ "$setpass" == 'SETPASS' ]; then
echo "Setting root password"
if [[ ${TARGET} ]]; then
if ! mountpoint ${TARGET}/dev; then
mount -o ro -t devtmpfs devtmpfs ${TARGET}/dev
chroot ${TARGET} passwd root
umount ${TARGET}/dev
else
chroot ${TARGET} passwd root
fi
else
passwd root
fi
fi
echo "Refreshing snap"
if [[ ${TARGET} ]]; then
chroot ${TARGET} snap refresh
else
snap refresh
fi
exit 0
;;
prerm)
exit 0
;;
postrm)
exit 0
;;
esac

View File

@@ -208,6 +208,11 @@ my $commands = {
. " separate\n\t\t\t\tdirectory/file system\n", . " separate\n\t\t\t\tdirectory/file system\n",
"\t\t\t\tProceed without prompting" "\t\t\t\tProceed without prompting"
] ]
},
version => {
options => [],
brief => 'Display version information',
help => []
} }
}; };

View File

@@ -5,6 +5,7 @@ dirs:
files: files:
install -v -m 755 snap $(DESTDIR)/usr/bin/snap install -v -m 755 snap $(DESTDIR)/usr/bin/snap
install -v -m 755 snapinstall $(DESTDIR)/usr/bin/snapinstall
install -v -m 644 Makefile.skel \ install -v -m 644 Makefile.skel \
$(DESTDIR)/usr/share/snap/Makefile.skel $(DESTDIR)/usr/share/snap/Makefile.skel
install -v -m 644 Makefile.snaplinux \ install -v -m 644 Makefile.snaplinux \

View File

@@ -19,7 +19,7 @@ ARCHIVE := $(PWD)/SRC/$(shell ls SRC|egrep '(bz2|gz|tar|xz)$$'|tail -1)
TYPE := $(shell file -ib $(ARCHIVE)|cut -d';' -f1|tr -d '\n') TYPE := $(shell file -ib $(ARCHIVE)|cut -d';' -f1|tr -d '\n')
SRCDIR := $(shell tar -tf $(ARCHIVE)|head -1|sed 's/\/.*//') SRCDIR := $(shell tar -tf $(ARCHIVE)|head -1|sed 's/\/.*//')
PATCHDIR := $(PWD)/SRC/patches PATCHDIR := $(PWD)/SRC/patches
VERSION := $(shell echo $(SRCDIR)|egrep -o '\-[0-9].*'|sed 's/^-//')$(SNAPVER) VERSION := $(shell echo $(SRCDIR)|egrep -o '\-[0-9].*'|sed 's/^-//')-$(SNAPVER)
include /usr/share/snap/Makefile.snaplinux include /usr/share/snap/Makefile.snaplinux

View File

@@ -9,11 +9,23 @@
# GNU General Public License for more details. # GNU General Public License for more details.
PWD := $(shell pwd) PWD := $(shell pwd)
PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
SNAPDIR = $(PWD)/SNAP SNAPDIR = $(PWD)/SNAP
ROOT = $(PWD)/ROOT ROOT = $(PWD)/ROOT
SNAP = $(PACKAGE)-$(VERSION).snap # This will set PACKAGE only if the package itself has
# not provided a package name
ifndef PACKAGE
PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
endif
# This defines the name of the package file unless
# specified
ifndef PKGFILE
PKGFILE := $(PACKAGE)-$(VERSION).snap
endif
SNAPINFO = $(SNAPDIR)/snapinfo SNAPINFO = $(SNAPDIR)/snapinfo
MANIFEST = $(SNAPDIR)/manifest MANIFEST = $(SNAPDIR)/manifest
USHER = $(SNAPDIR)/usher USHER = $(SNAPDIR)/usher
@@ -24,7 +36,7 @@ FILES = $(SNAPDIR)/files.tar.gz
# if we find that not to be supplied we're going to # if we find that not to be supplied we're going to
# assume that the SRCPKG is the same as the PACKAGE # assume that the SRCPKG is the same as the PACKAGE
ifeq ( $(SRCPKG), ) ifndef SRCPKG
SRCPKG := $(PACKAGE) SRCPKG := $(PACKAGE)
endif endif
@@ -34,19 +46,19 @@ ifndef VERSION
$(error VERSION is not set) $(error VERSION is not set)
endif endif
$(SNAP): $(SNAPINFO) $(FILES) $(PKGFILE): $(SNAPINFO) $(FILES)
@if [ -f $(SNAP) ]; then \ @if [ -f $(PKGFILE) ]; then \
rm -v $(SNAP); \ rm -v $(PKGFILE); \
fi fi
@ar cvr $(SNAP) $(SNAPINFO) $(MANIFEST); \ @ar cvr $(PKGFILE) $(SNAPINFO) $(MANIFEST); \
if [ -f $(USHER) ]; then \ if [ -f $(USHER) ]; then \
chmod +x $(USHER); \ chmod +x $(USHER); \
ar cvr $(SNAP) $(USHER); \ ar cvr $(PKGFILE) $(USHER); \
fi; \ fi; \
ar cvr $(SNAP) $(FILES) ar cvr $(PKGFILE) $(FILES)
@echo "Successfully built $(SNAP)" @echo "Successfully built $(PKGFILE)"
$(SNAPINFO): $(MANIFEST) $(SNAPINFO): $(MANIFEST)
@>$(SNAPINFO) @>$(SNAPINFO)
@@ -105,21 +117,22 @@ $(FILES): $(ROOT)
done; \ done; \
fi fi
if [ "$(PACKAGE)" != 'grub' ]; then
@find $(ROOT) -type f | while read -r file; do \ @find $(ROOT) -type f | while read -r file; do \
type=`file -i $$file|sed 's/.*: //'`; \ type=`file -i $$file|sed 's/.*: //'`; \
case $$type in \ case $$type in \
*'/x-executable; charset=binary') \ *'/x-executable; charset=binary') \
echo "--strip-unneeded $$file"; \
strip --strip-unneeded $$file \ strip --strip-unneeded $$file \
;; \ ;; \
*'/x-object; charset=binary') \ *'/x-object; charset=binary') \
strip --strip-unneeded $$file \ echo "--strip-debug $$file"; \
strip --strip-debug $$file \
;; \ ;; \
*'/x-sharedlib; charset=binary') \ *'/x-sharedlib; charset=binary') \
strip --strip-unneeded $$file \ echo "--strip-debug $$file"; \
strip --strip-debug $$file \
;; \ ;; \
esac; \ esac; \
done; \ done
fi
@cd $(ROOT) && tar cvzf $(FILES) * @cd $(ROOT) && tar cvzf $(FILES) *

View File

@@ -255,7 +255,7 @@ sub depends {
} ); } );
if ( ! $package ) { if ( ! $package ) {
push( @$failures, $depend ); push( @$failures, "$depend" );
next; next;
} }
@@ -273,16 +273,96 @@ sub depends {
} }
if ( @$failures ) { if ( @$failures ) {
print STDERR "Failed to resolve dependencies for" print STDERR "Failed to resolve dependencies\n";
. " $self->{'name'}!\n";
Snap->error( -1, "depends(): dependencies failed: " Snap->error( -1, "depends(): unresolved dependencies: "
. join( ",", @$failures ) ); . join( ",", @$failures ) );
} }
$self->revdeps( $sources, $dependencies ); $self->revdeps( $sources, $dependencies );
} }
sub dump {
my $self = shift;
my $pid;
my $sel;
my $cnt;
my $stderr;
my $stat;
local $| = 1;
if ( $self->{'path'} =~ /^https*:\/\// ) {
( my $filename = $self->{'path'} ) =~ s/.*\///;
Snap->httpget( $self->{'path'}, Snap->PKGDIR
. "/$filename", 0644 );
$self->{'path'} = Snap->PKGDIR . "/$filename";
}
print "Dumping $self->{'name'}=$self->{'version'}\n";
print "\e[?25l\r";
eval {
my $target = Snap->TARGET ||
"$self->{'name'}-$self->{'version'}";
if ( ! -d $target ) {
mkdir( $target );
}
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"/usr/bin/ar p $self->{'path'} files.tar.gz|"
. "tar --no-overwrite-dir --keep-directory-symlink"
. " -hzvxf - -C $target" );
} || Snap->error( int( $! ), "open3(): /usr/bin/ar: $!" );
close( CHLDIN );
$sel = IO::Select->new();
$sel->add( *CHLDOUT, *CHLDERR );
while ( my @fhs = $sel->can_read ) {
foreach my $fh ( @fhs ) {
if ( eof( $fh ) ) {
$sel->remove( $fh );
next;
}
if ( fileno( $fh ) == fileno( *CHLDOUT ) ) {
my $line = <$fh>;
( my $file = $line ) =~ s/.*\/|\n$//;
chomp( $line );
chomp( $file );
if ( $file ) {
$cnt++;
print "\e[K$file\r";
}
}
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
$stderr .= <$fh>;
}
}
}
close( CHLDOUT );
close( CHLDERR );
waitpid( $pid, 0 );
$stat = $? >> 8;
if ( $stat ) {
Snap->error( $stat, "Failed dumping $self->{'name'}:"
. " $stderr\e[?25h" );
}
print "\e[K$cnt files extracted\e[?25h\n";
}
sub files { sub files {
my $self = shift; my $self = shift;
my $opts = shift; my $opts = shift;
@@ -294,8 +374,13 @@ sub files {
my $stdout; my $stdout;
my $stderr; my $stderr;
my $stat; my $stat;
my $pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR, my $pid;
eval {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"/usr/bin/ar p $self->{'path'} manifest" ); "/usr/bin/ar p $self->{'path'} manifest" );
} || Snap->error( int( $! ), "open3(): /usr/bin/ar:"
. " $!" );
close( CHLDIN ); close( CHLDIN );
@@ -318,7 +403,12 @@ sub files {
next; next;
} }
if ( $opts->{'quiet'} ) { if ( $opts->{'quiet'} &&
$opts->{'verbose'} ) {
push( @{$self->{'files'}}, [
$sha, $perms, $file ] );
}
elsif ( $opts->{'quiet'} ) {
push( @{$self->{'files'}}, push( @{$self->{'files'}},
$file ); $file );
} }
@@ -368,8 +458,14 @@ sub files {
$self->{'files'} = []; $self->{'files'} = [];
} }
if ( $opts->{'verbose'} ) {
push( @{$self->{'files'}}, [
$sha, $perms, $file ] );
}
else {
push( @{$self->{'files'}}, $file ); push( @{$self->{'files'}}, $file );
} }
}
elsif ( $opts->{'verbose'} ) { elsif ( $opts->{'verbose'} ) {
print "$sha\t$perms\t$file\n"; print "$sha\t$perms\t$file\n";
} }
@@ -402,7 +498,12 @@ sub install {
my $stat; my $stat;
local $| = 1; local $| = 1;
print "\e[?25lInstalling $self->{'name'}:\r"; $ENV{'VERSION'} = $self->{'version'};
if ( ! -f $self->{'path'} ) {
Snap->error( -1, "install(): $self->{'path'}:"
. " No such file or directory" );
}
if ( $self->{'path'} =~ /^https*:\/\// ) { if ( $self->{'path'} =~ /^https*:\/\// ) {
( my $filename = $self->{'path'} ) =~ s/.*\///; ( my $filename = $self->{'path'} ) =~ s/.*\///;
@@ -443,13 +544,19 @@ sub install {
Snap->error( int( $! ), "rename(): $manifest: $!" ); Snap->error( int( $! ), "rename(): $manifest: $!" );
} }
print "Installing $self->{'name'}=$self->{'version'}\n";
$self->usher( 'preinst' ); $self->usher( 'preinst' );
print "\e[?25l\r";
eval { eval {
my $target = Snap->TARGET || '/';
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR, $pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"/usr/bin/ar p $self->{'path'} files.tar.gz|" "/usr/bin/ar p $self->{'path'} files.tar.gz|"
. "tar --no-overwrite-dir -hzvxf - -C " . "tar --no-overwrite-dir --keep-directory-symlink"
. Snap->TARGET ); . " -hzvxf - -C $target" );
} || Snap->error( int( $! ), "open3(): /usr/bin/ar: $!" ); } || Snap->error( int( $! ), "open3(): /usr/bin/ar: $!" );
close( CHLDIN ); close( CHLDIN );
@@ -481,8 +588,7 @@ sub install {
if ( $file ) { if ( $file ) {
$cnt++; $cnt++;
print "\e[KInstalling " print "\e[K$file\r";
. "$self->{'name'}: $file\r";
} }
} }
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) { elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
@@ -502,6 +608,8 @@ sub install {
. " $stderr\e[?25h" ); . " $stderr\e[?25h" );
} }
print "\e[K$cnt files extracted\e[?25h\n";
if ( $oldpkg ) { if ( $oldpkg ) {
foreach ( @{$oldpkg->{'files'}} ) { foreach ( @{$oldpkg->{'files'}} ) {
if ( -f Snap->TARGET . "/$_" ) { if ( -f Snap->TARGET . "/$_" ) {
@@ -548,7 +656,7 @@ sub install {
Snap->error( int( $! ), "unlink(): $manifest: $!" ); Snap->error( int( $! ), "unlink(): $manifest: $!" );
} }
print "\e[KInstalling $self->{'name'}: DONE\e[?25h\n"; print "Finished installing $self->{'name'}\n";
} }
sub installed { sub installed {
@@ -741,7 +849,7 @@ sub usher {
my $stderr; my $stderr;
my $stat; my $stat;
if ( ! -f $usher || $action eq 'preinst' ) { if ( $action eq 'preinst' ) {
my $cnt = 0; my $cnt = 0;
eval { eval {
@@ -769,17 +877,16 @@ sub usher {
if ( fileno( $fh ) == fileno( *CHLDOUT ) ) { if ( fileno( $fh ) == fileno( *CHLDOUT ) ) {
my $line = <$fh>; my $line = <$fh>;
if ( ! $cnt && $line =~
/^no entry usher in archive$/ ) {
last;
}
print USHER $line; print USHER $line;
$cnt++; $cnt++;
} }
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) { elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
$stderr .= <$fh>; $stderr .= <$fh>;
if ( $stderr =~ /^no entry usher/ ) {
last;
}
} }
} }
} }
@@ -798,6 +905,8 @@ sub usher {
if ( ! $cnt && -f $usher ) { if ( ! $cnt && -f $usher ) {
unlink( $usher ); unlink( $usher );
return;
} }
} }
@@ -805,17 +914,17 @@ sub usher {
return; return;
} }
eval { if ( $pid = fork() ) {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR, waitpid( $pid, 0 );
"TARGET=" . Snap->TARGET . " $usher $action" ); $stat = $? >> 8;
} || Snap->error( int( $! ), "open3():" }
. " $usher ($action): $!" ); else {
exec( "$usher $action" );
}
close( CHLDIN ); if ( $stat ) {
Snap->error( $stat, "usher(): Failed executing usher" );
$sel = IO::Select->new(); }
$sel->add( *CHLDOUT, *CHLDERR );
$sel = IO::Select->new();
} }
############################################################ ############################################################

View File

@@ -7,7 +7,7 @@ use Snap::Commands;
use Snap::Package; use Snap::Package;
use Snap::Sources; use Snap::Sources;
use Fcntl; use Fcntl qw( :flock );
use IPC::Open3; use IPC::Open3;
use IO::Socket::INET; use IO::Socket::INET;
use Digest::SHA qw( sha256_hex ); use Digest::SHA qw( sha256_hex );
@@ -23,9 +23,12 @@ our @EXPORT = qw(
human human
list list
listfiles listfiles
virtfs
readconf readconf
refresh refresh
setup setup
sha
sha256
target target
termsize termsize
vercmp vercmp
@@ -86,7 +89,7 @@ use constant VERFILE => eval {
} }
}; };
use constant { use constant {
VERSION => '0.3', VERSION => '0.10',
SNAPDIR => TARGET . '/var/lib/snap', SNAPDIR => TARGET . '/var/lib/snap',
PKGDIR => TARGET . '/var/lib/snap/packages', PKGDIR => TARGET . '/var/lib/snap/packages',
INSTDIR => TARGET . '/var/lib/snap/installed', INSTDIR => TARGET . '/var/lib/snap/installed',
@@ -102,6 +105,7 @@ use constant SNAPVER => eval {
return( $version ); return( $version );
}; };
use constant LOCKFILE => '/var/lock/snap';
############################################################ ############################################################
# #
@@ -111,6 +115,17 @@ use constant SNAPVER => eval {
$0 =~ s/.*\///; $0 =~ s/.*\///;
############################################################
#
# Exit unless we can get exclusive lock
#
############################################################
open( LOCK, '>', LOCKFILE ) || Snap->error( int( $! ), "open(): "
. LOCKFILE . ": Unable to open lock file" );
flock( LOCK, LOCK_EX|LOCK_NB ) || Snap->error( int( $! ), "flock(): "
. LOCKFILE . ": Unable to lock file" );
############################################################ ############################################################
# #
# Make sure we bring back the cursor if we're killed # Make sure we bring back the cursor if we're killed
@@ -118,6 +133,8 @@ $0 =~ s/.*\///;
############################################################ ############################################################
$SIG{INT} = sub{ $SIG{INT} = sub{
virtfs( 'umount' );
print "\e[?25h\n"; print "\e[?25h\n";
exit( -1 ); exit( -1 );
@@ -125,7 +142,7 @@ $SIG{INT} = sub{
############################################################ ############################################################
# #
# Export TARGET to the environment # Export TARGET to the environment for usher
# #
############################################################ ############################################################
@@ -195,6 +212,8 @@ sub error {
chomp( $errstr ); chomp( $errstr );
print "\e[?25h\n";
print STDERR ( caller() )[1] .":\n $errstr at line " print STDERR ( caller() )[1] .":\n $errstr at line "
. ( caller() )[2] . "\n"; . ( caller() )[2] . "\n";
@@ -212,6 +231,8 @@ sub error {
print "\n"; print "\n";
if ( $status ) { if ( $status ) {
virtfs( 'umount' );
exit( $status ); exit( $status );
} }
} }
@@ -404,6 +425,26 @@ sub human {
return( $human ); return( $human );
} }
sub ismountpoint {
my $dir = shift;
my $statA;
my $statB;
if ( ! -d $dir ) {
return( 0 );
}
$statA = ( stat( $dir ) )[0];
$statB = ( stat( "$dir/.." ) )[0];
if ( $statA == $statB ) {
return( 0 );
}
else {
return( 1 );
}
}
sub list { sub list {
my $packages = {}; my $packages = {};
my $package = {}; my $package = {};
@@ -621,6 +662,15 @@ sub setup {
} }
} }
sub sha {
my $file = shift;
my $digest = eval {
Digest::SHA->new( 1 )->addfile( $file );
} || Snap->error( -1, "sha(): $file: $!\n" );
return( $digest->hexdigest );
}
### sha256() ############################################### ### sha256() ###############################################
# #
# This sub returns a hex sha256 hash of a supplied file # This sub returns a hex sha256 hash of a supplied file
@@ -638,20 +688,50 @@ sub sha256 {
} }
sub termsize { sub termsize {
require 'sys/ioctl.ph'; my $row = 24;
my $data; my $col = 80;
my $row; my $sel = IO::Select->new();
my $col; my $stdout;
my $stderr;
my $stat;
my $pid;
open( TTY, "+</dev/tty" ) || Snap->error( 0, "No tty: $!" ); eval {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"stty size -F /dev/tty" );
} || return( { row => $row, col => $col } );
if ( ! ioctl( TTY, &TIOCGWINSZ, $data='' ) ) { close( CHLDIN );
Snap->error( 0, "Failed to determine window size" );
$sel->add( *CHLDOUT, *CHLDERR );
while ( my @fhs = $sel->can_read ) {
foreach my $fh ( @fhs ) {
if ( eof( $fh ) ) {
$sel->remove( $fh );
next;
} }
close( TTY ); if ( fileno( $fh ) == fileno( *CHLDOUT ) ) {
$stdout .= <$fh>;
}
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
$stderr .= <$fh>;
}
}
}
( $row, $col ) = unpack( 'S4', $data ); close( CHLDOUT );
close( CHLDERR );
waitpid( $pid, 0 );
$stat = $? >> 8;
if ( $stdout =~ /(\d+)\s+(\d+)/ ) {
$row = $1;
$col = $2;
}
return( { row => $row, col => $col } ); return( { row => $row, col => $col } );
} }
@@ -732,4 +812,108 @@ sub vercmp {
@A <=> @B; @A <=> @B;
} }
sub virtfs {
my $command = shift;
my $virtfs = {
dev => {
fs => 'devtmpfs',
dev => 'none',
dir => TARGET . '/dev'
},
proc => {
fs => 'proc',
dev => 'none',
dir => TARGET . '/proc'
},
sys => {
fs => 'sysfs',
dev => 'none',
dir => TARGET .'/sys'
}
};
if ( ! TARGET ) {
return;
}
foreach my $fs ( sort( keys( %$virtfs ) ) ) {
my $sel;
my $cmd;
my $stdout = '';
my $stderr = '';
my $stat = 0;
my $pid;
if ( ! -d $virtfs->{$fs}{'dir'} ) {
next;
}
if ( $command eq 'mount' ) {
if ( ismountpoint( $virtfs->{$fs}{'dir'} ) ) {
next;
}
$cmd = "mount -t $virtfs->{$fs}{'fs'}"
. " $virtfs->{$fs}{'dev'}"
. " $virtfs->{$fs}{'dir'}";
}
elsif ( $command eq 'umount' ) {
if ( ! ismountpoint( $virtfs->{$fs}{'dir'} ) ) {
next;
}
$cmd = "umount $virtfs->{$fs}{'dir'}";
}
else {
Snap->error( -1, "virtfs(): $command:"
. " not a valid command" );
}
eval {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR, $cmd );
} || Snap->error( int( $! ), "open3(): $cmd: $!" );
close( CHLDIN );
$sel = IO::Select->new();
$sel->add( *CHLDOUT, *CHLDERR );
while ( my @fhs = $sel->can_read ) {
foreach my $fh ( @fhs ) {
if ( eof( $fh ) ) {
$sel->remove( $fh );
next;
}
if ( fileno( $fh ) == fileno( *CHLDOUT ) ) {
$stdout .= <$fh>;
}
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
$stderr .= <$fh>;
}
}
}
close( CHLDOUT );
close( CHLDERR );
waitpid( $pid, 0 );
$stat = $? >> 8;
if ( $stat ) {
Snap->error( $stat, "Failed $command for"
. " $virtfs->{$fs}{'dir'}: $stderr" );
}
}
foreach my $fs ( sort( keys( %$virtfs ) ) ) {
if ( ! ismountpoint( $virtfs->{$fs}{'dir'} ) ) {
return( 0 );
}
}
return( 1 );
}
1; 1;

View File

@@ -6,15 +6,6 @@ use warnings;
use Snap; use Snap;
use Data::Dumper; use Data::Dumper;
############################################################
#
# setup() will give the user the option to create the files
# and directories needed for snap to function
#
############################################################
setup();
my $command = shift( @ARGV ); my $command = shift( @ARGV );
my $conf = readconf(); my $conf = readconf();
my $commands = Snap::Commands->new(); my $commands = Snap::Commands->new();
@@ -23,9 +14,15 @@ my $sources = Snap::Sources->new( $conf->{'sources'} );
if ( $ARGV[0] && $ARGV[0] eq '-h' ) { if ( $ARGV[0] && $ARGV[0] eq '-h' ) {
$commands->commandhelp( $command ); $commands->commandhelp( $command );
} }
elsif ( $command eq 'genpkg' ) { elsif ( $command eq 'dump' ) {
print "\n";
foreach my $arg ( @ARGV ) { foreach my $arg ( @ARGV ) {
genpkg( $arg ); my $package = Snap::Package->new( $arg );
$package->dump();
print "\n";
} }
} }
elsif ( $command eq 'files' ) { elsif ( $command eq 'files' ) {
@@ -61,11 +58,15 @@ elsif ( $command eq 'files' ) {
print "\n"; print "\n";
} }
elsif ( $command eq 'genpkg' ) {
foreach my $arg ( @ARGV ) {
genpkg( $arg );
}
}
elsif ( $command eq 'help' ) { elsif ( $command eq 'help' ) {
$commands->help(); $commands->help();
} }
elsif ( $command eq 'info' ) { elsif ( $command eq 'info' ) {
print "\n"; print "\n";
foreach my $arg ( @ARGV ) { foreach my $arg ( @ARGV ) {
@@ -102,6 +103,9 @@ elsif ( $command eq 'install' ) {
my $string = "@ARGV"; my $string = "@ARGV";
my $packages = []; my $packages = [];
my $bytes = 0; my $bytes = 0;
my $virtfs = 0;
setup();
foreach my $attrib ( @attribs ) { foreach my $attrib ( @attribs ) {
if ( $string =~ /$attrib\s*:\s*(\S+)/ ) { if ( $string =~ /$attrib\s*:\s*(\S+)/ ) {
@@ -291,17 +295,31 @@ elsif ( $command eq 'install' ) {
} }
} }
if ( $bytes < 0 ) {
print "\n\nInstall will recover " . human( -1 * $bytes )
. ". Continue? (y/n): ";
}
else {
print "\n\nInstall will require " . human( $bytes ) print "\n\nInstall will require " . human( $bytes )
. ". Continue? (y/n): "; . ". Continue? (y/n): ";
}
chkyes(); chkyes();
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
print "\n"; print "\n";
foreach my $package ( @$packages ) {
$package->install( $sources ); $package->install( $sources );
} }
if ( $virtfs ) {
virtfs( 'umount' );
}
print "\n"; print "\n";
} }
elsif ( $command eq 'list' ) { elsif ( $command eq 'list' ) {
@@ -316,6 +334,8 @@ elsif ( $command eq 'list' ) {
print "\n"; print "\n";
} }
elsif ( $command eq 'refresh' ) { elsif ( $command eq 'refresh' ) {
setup();
print "\n"; print "\n";
$sources->refresh(); $sources->refresh();
@@ -331,6 +351,105 @@ elsif ( $command eq 'refresh' ) {
print "\n"; print "\n";
} }
} }
elsif ( $command eq 'reinstall' ) {
my $opts = {
yes => eval {
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
if ( $ARGV[$i] eq '-y' ) {
splice( @ARGV, $i, 1 );
return( 1 );
}
}
}
};
my $packages = [];
my $virtfs = 0;
setup();
$sources->readpkgs();
print "\n";
foreach my $pkgname ( @ARGV ) {
my $package;
if ( -f $pkgname ) {
$package = Snap::Package->new( $pkgname );
}
else {
$package = $sources->{'installed'}{$pkgname};
$package = $sources->search( {
name => $package->{'name'},
version => $package->{'version'},
quiet => 1
} );
}
if ( ! $package ) {
print STDERR "Package '$pkgname' not installed\n";
next;
}
if ( $package->{'path'} =~ /https*:\/\// ) {
( my $filename = $package->{'path'} ) =~ s/.*\///;
if ( ! -f Snap->PKGDIR . "/$filename" ) {
Snap->httpget( $package->{'path'},
Snap->PKGDIR . "/$filename", 0644 );
}
$package->{'path'} = Snap->PKGDIR . "/$filename";
}
push( @$packages, $package );
}
foreach my $package ( @$packages ) {
my $termsize = Snap->termsize();
my $cnt = 0;
foreach my $package ( sort { $a->{'name'} cmp $b->{'name'} }
( @$packages ) ) {
if ( ! $cnt ) {
print "The following packages will be"
. " reinstalled:\n ";
}
if ( $termsize->{'col'} - ( length(
$package->{'name'} ) + 3 ) <= 0 ) {
print "\n ";
$termsize = Snap->termsize();
}
print "$package->{'name'} ";
$termsize->{'col'} -= length( $package->{'name'} ) + 1;
$cnt++;
}
}
print "\n\nContinue? (y/n): ";
chkyes();
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
print "\n";
$package->install();
}
virtfs( 'umount' );
print "\n";
}
elsif ( $command eq 'remove' ) { elsif ( $command eq 'remove' ) {
my $opts = { my $opts = {
nodeps => eval { nodeps => eval {
@@ -498,35 +617,6 @@ elsif ( $command eq 'search' ) {
exit -1; exit -1;
} }
print "\n";
}
elsif ( $command eq 'setup' ) {
my $opts = {
repo => 'core',
quiet => 1
};
my $packages;
print "\n";
if ( ! Snap->TARGET ) {
Snap->error( -1, 'A target must be specified with -t' );
}
$sources->readpkgs();
$packages = $sources->search( $opts );
for ( my $i = 0; $i <= $#$packages; $i++ ) {
if ( $packages->[$i]{'name'} eq 'snap-base' ) {
unshift( @$packages, $packages->[$i] );
splice( @$packages, $i+1, 1 );
}
}
foreach my $package ( @$packages ) {
$package->install();
}
print "\n"; print "\n";
} }
elsif ( $command eq 'verify' ) { elsif ( $command eq 'verify' ) {
@@ -536,6 +626,9 @@ elsif ( $command eq 'verify' ) {
print Dumper( $package ); print Dumper( $package );
} }
} }
elsif ( $command eq 'version' ) {
print "\n" . Snap->VERSION . "\n\n";
}
elsif ( $command ) { elsif ( $command ) {
print "\n"; print "\n";

98
SRC/snap/snapinstall Normal file
View File

@@ -0,0 +1,98 @@
#!/usr/bin/perl
use strict;
use warnings;
use Snap;
use Data::Dumper;
setup();
my $conf = readconf();
my $sources = Snap::Sources->new( $conf->{'sources'} );
my $opts = {
repo => 'core',
quiet => 1
};
my $corepkgs;
my $packages;
my $virtfs = 0;
my $prepkgs = {};
my $prelist = [ 'snap-base', 'bash', 'coreutils', 'glibc',
'libacl', 'libattr', 'libcap', 'ncurses', 'readline',
'tzdata', 'perl', 'initscripts' ];
print "\n";
if ( ! Snap->TARGET ) {
Snap->error( -1, 'A target must be specified with -t' );
}
$sources->readpkgs();
$corepkgs = $sources->search( $opts );
for ( my $i = 0; $i <= $#$corepkgs; $i++ ) {
if ( ! $opts->{'nodeps'} ) {
print "Resolving dependencies for"
. " $corepkgs->[$i]{'name'}\n";
$corepkgs->[$i]->depends( $sources, $packages );
}
else {
print "Ignoring dependencies for"
. " $corepkgs->[$i]{'name'}\n";
}
push( @$packages, $corepkgs->[$i] );
}
for ( my $i = 0; $i <= $#$packages; $i++ ) {
if ( $packages->[$i]{'path'} =~ /https*:\/\// ) {
( my $filename = $packages->[$i]{'path'} ) =~ s/.*\///;
if ( ! -f Snap->PKGDIR . "/$filename" ) {
Snap->httpget( $packages->[$i]{'path'},
Snap->PKGDIR . "/$filename", 0644 );
}
$packages->[$i]{'path'} = Snap->PKGDIR . "/$filename";
}
if ( grep( $_ eq $packages->[$i]{'name'}, @$prelist ) ) {
$prepkgs->{$packages->[$i]{'name'}} = $packages->[$i];
splice( @$packages, $i, 1 );
$i--;
}
}
foreach my $package ( @$prelist ) {
print "\n";
$prepkgs->{$package}->install();
}
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
print "\n";
$package->install();
}
if ( $virtfs ) {
if ( $pid = fork() ) {
waitpid( $pid, 0 );
}
else {
exec( "chroot " . Snap->TARGET . " passwd" );
}
}
virtfs( 'umount' );
print "\n";