diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-09-21 18:54:08 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-09-21 18:54:08 +0000 |
commit | 0bd5eb71a0a23b27a02af591ba46e4cf2c34aa04 (patch) | |
tree | 46e32a4eee45d30bcb2d5f780fe9ccd3bb41552d /scripts/nix-install-package.in | |
parent | 4e91d8621f6620f8b15535002309882fd7794a1f (diff) |
* `nix-install-package --url': install from a URL (NIX-12).
* `nix-install-package --help' (NIX-9).
* `nix-install-package --non-interactive': don't prompt or pause.
* Tests for nix-install-package.
* Security fixes: filter the values obtained from the nixpkg.
Diffstat (limited to 'scripts/nix-install-package.in')
-rw-r--r-- | scripts/nix-install-package.in | 124 |
1 files changed, 105 insertions, 19 deletions
diff --git a/scripts/nix-install-package.in b/scripts/nix-install-package.in index 7959070c0..4f5b0087f 100644 --- a/scripts/nix-install-package.in +++ b/scripts/nix-install-package.in @@ -3,28 +3,107 @@ use strict; use POSIX qw(tmpnam); -my $pkgFile = $ARGV[0]; -die unless defined $pkgFile; + +sub usageError { + print STDERR <<EOF; +Usage: nix-install-package (FILE | --url URL) + +Install a Nix Package (.nixpkg) either directly from FILE or by +downloading it from URL. + +Flags: + --profile / -p LINK: install into the specified profile + --non-interactive: don't run inside a new terminal XXX +EOF + ; # ' + exit 1; +} + + +# Parse the command line arguments. +my @args = @ARGV; +usageError if scalar @args == 0; + +my $source; +my $fromURL = 0; +my @extraNixEnvArgs = (); +my $interactive = 1; + +while (scalar @args) { + my $arg = shift @args; + if ($arg eq "--help") { + usageError; + } + elsif ($arg eq "--url") { + $fromURL = 1; + } + elsif ($arg eq "--profile" || $arg eq "-p") { + my $profile = shift @args; + usageError if !defined $profile; + push @extraNixEnvArgs, "-p", $profile; + } + elsif ($arg eq "--non-interactive") { + $interactive = 0; + } + else { + $source = $arg; + } +} + +usageError unless defined $source; # Re-execute in a terminal, if necessary, so that if we're executed # from a web browser, the user gets to see us. -if (!defined $ENV{"NIX_HAVE_TERMINAL"}) { +if ($interactive && !defined $ENV{"NIX_HAVE_TERMINAL"}) { $ENV{"NIX_HAVE_TERMINAL"} = "1"; $ENV{"LD_LIBRARY_PATH"} = ""; - foreach my $term ("konsole", "gnome-terminal", "xterm") { - exec($term, "-e", "@shell@", "-c", "@bindir@/nix-install-package '$pkgFile' || read"); + foreach my $term ("xterm", "konsole", "gnome-terminal", "xterm") { + exec($term, "-e", "@bindir@/nix-install-package", @ARGV); } die "cannot execute `xterm'"; } +my $tmpDir; +do { $tmpDir = tmpnam(); } +until mkdir $tmpDir, 0777; +END { if (defined $tmpDir) { my $x = $?; system ("@coreutils@/rm", "-rf", $tmpDir); $? = $x; } } + + +sub barf { + my $msg = shift; + print "$msg\n"; + <STDIN> if $interactive; + exit 1; +} + + +# Download the package description, if necessary. +my $pkgFile = $source; +if ($fromURL) { + $pkgFile = "$tmpDir/tmp.nixpkg"; + system ("@curl@", "--silent", $source, "-o", $pkgFile) == 0 + or barf "curl failed: $?"; +} + + # Read and parse the package file. -open PKGFILE, "<$pkgFile" or die "cannot open `$pkgFile': $!"; +open PKGFILE, "<$pkgFile" or barf "cannot open `$pkgFile': $!"; my $contents = <PKGFILE>; close PKGFILE; -$contents =~ /^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/ or die "invalid package contents"; +my $urlRE = "(?: [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']+ )"; +my $nameRE = "(?: [A-Za-z0-9\+\-\.\_\?\=]+ )"; # see checkStoreName() +my $systemRE = "(?: [A-Za-z0-9\+\-\_]+ )"; +my $pathRE = "(?: \/ [\/A-Za-z0-9\+\-\.\_\?\=]* )"; + +# Note: $pathRE doesn't check that whether we're looking at a valid +# store path. We'll let nix-env do that. + +$contents =~ + / ^ \s* (\S+) \s+ ($urlRE) \s+ ($nameRE) \s+ ($systemRE) \s+ ($pathRE) \s+ ($pathRE) /x + or barf "invalid package contents"; my $version = $1; my $manifestURL = $2; my $drvName = $3; @@ -32,22 +111,29 @@ my $system = $4; my $drvPath = $5; my $outPath = $6; -die "invalid package version `$version'" unless $version eq "NIXPKG1"; +barf "invalid package version `$version'" unless $version eq "NIXPKG1"; -# Ask confirmation. -print "Do you want to install `$drvName' (Y/N)? "; -my $reply = <STDIN>; -chomp $reply; -exit if $reply ne "y" && $reply ne "Y"; +if ($interactive) { + # Ask confirmation. + print "Do you want to install `$drvName' (Y/N)? "; + my $reply = <STDIN>; + chomp $reply; + exit if $reply ne "y" && $reply ne "Y"; +} + print "\nPulling manifests...\n"; -system "@bindir@/nix-pull '$manifestURL'"; -die if $? != 0; +system ("@bindir@/nix-pull", $manifestURL) == 0 + or barf "nix-pull failed: $?"; + print "\nInstalling package...\n"; -system "@bindir@/nix-env -i '$outPath'"; -die if $? != 0; +system ("@bindir@/nix-env", "--install", $outPath, @extraNixEnvArgs) == 0 + or barf "nix-env failed: $?"; + -print "\nInstallation succeeded! Press Enter to continue.\n"; -<STDIN>; +if ($interactive) { + print "\nInstallation succeeded! Press Enter to continue.\n"; + <STDIN>; +} |