diff options
Diffstat (limited to 'dselect/methods')
-rw-r--r-- | dselect/methods/Dselect/Method.pm | 267 | ||||
-rw-r--r-- | dselect/methods/Dselect/Method/Ftp.pm | 232 | ||||
-rw-r--r-- | dselect/methods/Makefile.am | 57 | ||||
-rw-r--r-- | dselect/methods/Makefile.in | 764 | ||||
-rw-r--r-- | dselect/methods/file/desc.file | 9 | ||||
-rwxr-xr-x | dselect/methods/file/install.sh | 124 | ||||
-rw-r--r-- | dselect/methods/file/names | 1 | ||||
-rwxr-xr-x | dselect/methods/file/setup.sh | 308 | ||||
-rwxr-xr-x | dselect/methods/file/update.sh | 84 | ||||
-rw-r--r-- | dselect/methods/ftp/desc.ftp | 2 | ||||
-rwxr-xr-x | dselect/methods/ftp/install.pl | 626 | ||||
-rw-r--r-- | dselect/methods/ftp/names | 1 | ||||
-rwxr-xr-x | dselect/methods/ftp/setup.pl | 177 | ||||
-rwxr-xr-x | dselect/methods/ftp/update.pl | 250 | ||||
-rw-r--r-- | dselect/methods/media/README.media | 106 | ||||
-rw-r--r-- | dselect/methods/media/desc.media | 3 | ||||
-rwxr-xr-x | dselect/methods/media/install.sh | 282 | ||||
-rw-r--r-- | dselect/methods/media/names | 1 | ||||
-rwxr-xr-x | dselect/methods/media/setup.sh | 489 | ||||
-rwxr-xr-x | dselect/methods/media/update.sh | 121 |
20 files changed, 3904 insertions, 0 deletions
diff --git a/dselect/methods/Dselect/Method.pm b/dselect/methods/Dselect/Method.pm new file mode 100644 index 0000000..d5fe984 --- /dev/null +++ b/dselect/methods/Dselect/Method.pm @@ -0,0 +1,267 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +=encoding utf8 + +=head1 NAME + +Dselect::Method - dselect method support + +=head1 DESCRIPTION + +This module provides support functions to implement methods. + +B<Note>: This is a private module, its API can change at any time. + +=cut + +package Dselect::Method 0.01; + +use strict; +use warnings; + +our @EXPORT = qw( + %CONFIG + yesno + nb + view_mirrors + add_site + edit_site + edit_config + read_config + store_config +); + +use Exporter qw(import); +use Carp; + +eval q{ + use Data::Dumper; + + use Dpkg::File; +}; +if ($@) { + warn "Missing Dpkg modules required by the access method.\n\n"; + exit 1; +} + +our %CONFIG; + +sub yesno($$) { + my ($d, $msg) = @_; + + my ($res, $r); + $r = -1; + $r = 0 if $d eq 'n'; + $r = 1 if $d eq 'y'; + croak 'incorrect usage of yesno, stopped' if $r == -1; + while (1) { + print $msg, " [$d]: "; + $res = <STDIN>; + $res =~ /^[Yy]/ and return 1; + $res =~ /^[Nn]/ and return 0; + $res =~ /^[ \t]*$/ and return $r; + print "Please enter one of the letters 'y' or 'n'\n"; + } +} + +sub nb { + my $nb = shift; + + if ($nb > 1024 ** 2) { + return sprintf '%.2fM', $nb / 1024 ** 2; + } elsif ($nb > 1024) { + return sprintf '%.2fk', $nb / 1024; + } else { + return sprintf '%.2fb', $nb; + } +} + +sub read_config { + my $vars = shift; + my ($code, $conf); + + eval { + $code = file_slurp($vars); + }; + if ($@) { + warn "$@\n"; + die "Try to relaunch the 'Access' step in dselect, thanks.\n"; + } + + my $VAR1; ## no critic (Variables::ProhibitUnusedVariables) + $conf = eval $code; + die "couldn't eval $vars content: $@\n" if $@; + if (ref($conf) =~ /HASH/) { + foreach (keys %{$conf}) { + $CONFIG{$_} = $conf->{$_}; + } + } else { + print "Bad $vars file : removing it.\n"; + print "Please relaunch the 'Access' step in dselect. Thanks.\n"; + unlink $vars; + exit 0; + } +} + +sub store_config { + my $vars = shift; + + # Check that config is completed + return if not $CONFIG{done}; + + file_dump($vars, Dumper(\%CONFIG)); +} + +sub view_mirrors { + print <<'MIRRORS'; +Please see <https://www.debian.org/mirror/list> for a current +list of Debian mirror sites. +MIRRORS +} + +sub edit_config { + my ($method, $methdir) = @_; + my $i; + + # Get a config for the sites + while (1) { + $i = 1; + print "\n\nList of selected $method sites :\n"; + foreach (@{$CONFIG{site}}) { + print "$i. $method://$_->[0]$_->[1] @{$_->[2]}\n"; + $i++; + } + print "\nEnter a command (a=add e=edit d=delete q=quit m=mirror list) \n"; + print 'eventually followed by a site number : '; + chomp($_ = <STDIN>); + /q/i && last; + /a/i && add_site($method); + /d\s*(\d+)/i && do { + splice(@{$CONFIG{site}}, $1 - 1, 1) if $1 <= @{$CONFIG{site}}; + next; + }; + /e\s*(\d+)/i && do { + edit_site($method, $CONFIG{site}[$1 - 1]) if $1 <= @{$CONFIG{site}}; + next; + }; + /m/i && view_mirrors(); + } + + print "\n"; + $CONFIG{use_auth_proxy} = yesno($CONFIG{use_auth_proxy} ? 'y' : 'n', + 'Go through an authenticated proxy'); + + if ($CONFIG{use_auth_proxy}) { + print "\nEnter proxy hostname [$CONFIG{proxyhost}] : "; + chomp($_ = <STDIN>); + $CONFIG{proxyhost} = $_ || $CONFIG{proxyhost}; + + print "\nEnter proxy log name [$CONFIG{proxylogname}] : "; + chomp($_ = <STDIN>); + $CONFIG{proxylogname} = $_ || $CONFIG{proxylogname}; + + print "\nEnter proxy password [$CONFIG{proxypassword}] : "; + chomp($_ = <STDIN>); + $CONFIG{proxypassword} = $_ || $CONFIG{proxypassword}; + } + + print "\nEnter directory to download binary package files to\n"; + print "(relative to $methdir)\n"; + while (1) { + print "[$CONFIG{dldir}] : "; + chomp($_ = <STDIN>); + s{/$}{}; + $CONFIG{dldir} = $_ if $_; + last if -d "$methdir/$CONFIG{dldir}"; + print "$methdir/$CONFIG{dldir} is not a directory !\n"; + } +} + +sub add_site { + my $method = shift; + + my $pas = 1; + my $user = 'anonymous'; + my $email = qx(whoami); + chomp $email; + $email .= '@' . qx(cat /etc/mailname || dnsdomainname); + chomp $email; + my $dir = '/debian'; + + push @{$CONFIG{site}}, [ + '', + $dir, + [ + 'dists/stable/main', + 'dists/stable/contrib', + 'dists/stable/non-free-firmware', + 'dists/stable/non-free', + ], + $pas, + $user, + $email, + ]; + edit_site($method, $CONFIG{site}[@{$CONFIG{site}} - 1]); +} + +sub edit_site { + my ($method, $site) = @_; + + local $_; + + print "\nEnter $method site [$site->[0]] : "; + chomp($_ = <STDIN>); + $site->[0] = $_ || $site->[0]; + + print "\nUse passive mode [" . ($site->[3] ? 'y' : 'n') . '] : '; + chomp($_ = <STDIN>); + $site->[3] = (/y/i ? 1 : 0) if $_; + + print "\nEnter username [$site->[4]] : "; + chomp($_ = <STDIN>); + $site->[4] = $_ || $site->[4]; + + print <<"EOF"; + +If you are using anonymous $method to retrieve files, enter your email +address for use as a password. Otherwise enter your password, +or "?" if you want the $method method to prompt you each time. + +EOF + + print "Enter password [$site->[5]] : "; + chomp($_ = <STDIN>); + $site->[5] = $_ || $site->[5]; + + print "\nEnter debian directory [$site->[1]] : "; + chomp($_ = <STDIN>); + $site->[1] = $_ || $site->[1]; + + print "\nEnter space separated list of distributions to get\n"; + print "[@{$site->[2]}] : "; + chomp($_ = <STDIN>); + $site->[2] = [ split(/\s+/) ] if $_; +} + +=head1 CHANGES + +=head2 Version 0.xx + +This is a private module. + +=cut + +1; + +__END__ diff --git a/dselect/methods/Dselect/Method/Ftp.pm b/dselect/methods/Dselect/Method/Ftp.pm new file mode 100644 index 0000000..c149e0e --- /dev/null +++ b/dselect/methods/Dselect/Method/Ftp.pm @@ -0,0 +1,232 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +=encoding utf8 + +=head1 NAME + +Dselect::Method::Ftp - dselect FTP method support + +=head1 DESCRIPTION + +This module provides support functions for the FTP method. + +B<Note>: This is a private module, its API can change at any time. + +=cut + +package Dselect::Method::Ftp 0.01; + +use strict; +use warnings; + +our @EXPORT = qw( + do_connect + do_mdtm +); + +use Exporter qw(import); +use Carp; + +eval q{ + use Net::FTP; + use Data::Dumper; +}; +if ($@) { + warn "Missing Net::FTP modules required by the FTP access method.\n\n"; + exit 1; +} + +sub do_connect { + my (%opts) = @_; + + my($rpass,$remotehost,$remoteuser,$ftp); + + TRY_CONNECT: + while(1) { + my $exit = 0; + + if ($opts{useproxy}) { + $remotehost = $opts{proxyhost}; + $remoteuser = $opts{username} . '@' . $opts{ftpsite}; + } else { + $remotehost = $opts{ftpsite}; + $remoteuser = $opts{username}; + } + print "Connecting to $opts{ftpsite}...\n"; + $ftp = Net::FTP->new($remotehost, Passive => $opts{passive}); + if(!$ftp || !$ftp->ok) { + print "Failed to connect\n"; + $exit = 1; + } + if (!$exit) { +# $ftp->debug(1); + if ($opts{useproxy}) { + print "Login on $opts{proxyhost}...\n"; + $ftp->_USER($opts{proxylogname}); + $ftp->_PASS($opts{proxypassword}); + } + print "Login as $opts{username}...\n"; + if ($opts{password} eq '?') { + print 'Enter password for ftp: '; + system('stty', '-echo'); + $rpass = <STDIN>; + chomp $rpass; + print "\n"; + system('stty', 'echo'); + } else { + $rpass = $opts{password}; + } + if(!$ftp->login($remoteuser, $rpass)) + { print $ftp->message() . "\n"; $exit = 1; } + } + if (!$exit) { + print "Setting transfer mode to binary...\n"; + if(!$ftp->binary()) { print $ftp->message . "\n"; $exit = 1; } + } + if (!$exit) { + print "Cd to '$opts{ftpdir}'...\n"; + if (!$ftp->cwd($opts{ftpdir})) { + print $ftp->message . "\n"; + $exit = 1; + } + } + + if ($exit) { + if (yesno ('y', 'Retry connection at once')) { + next TRY_CONNECT; + } else { + die 'error'; + } + } + + last TRY_CONNECT; + } + +# if(!$ftp->pasv()) { print $ftp->message . "\n"; die 'error'; } + + return $ftp; +} + +############################## + +# assume server supports MDTM - will be adjusted if needed +my $has_mdtm = 1; + +my %months = ( + Jan => 0, + Feb => 1, + Mar => 2, + Apr => 3, + May => 4, + Jun => 5, + Jul => 6, + Aug => 7, + Sep => 8, + Oct => 9, + Nov => 10, + Dec => 11, +); + +my $ls_l_re = qr< + ([^ ]+\ *){5} # Perms, Links, User, Group, Size + [^ ]+ # Blanks + \ ([A-Z][a-z]{2}) # Month name (abbreviated) + \ ([0-9 ][0-9]) # Day of month + \ ([0-9 ][0-9][:0-9][0-9]{2}) # Filename +>x; + +sub do_mdtm { + my ($ftp, $file) = @_; + my ($time); + + #if ($has_mdtm) { + $time = $ftp->mdtm($file); +# my $code = $ftp->code(); +# my $message = $ftp->message(); +# print " [ $code: $message ] "; + if ($ftp->code() == 502 || # MDTM not implemented + $ftp->code() == 500) { # command not understood (SUN firewall) + $has_mdtm = 0; + } elsif (!$ftp->ok()) { + return; + } + #} + + if (! $has_mdtm) { + require Time::Local; + + my @files = $ftp->dir($file); + if (($#files == -1) || + ($ftp->code == 550)) { # No such file or directory + return; + } + +# my $code = $ftp->code(); +# my $message = $ftp->message(); +# print " [ $code: $message ] "; + +# print "[$#files]"; + + # get the date components from the output of 'ls -l' + if ($files[0] =~ $ls_l_re) { + my($month_name, $day, $year_or_time, $month, $hours, $minutes, + $year); + + # what we can read + $month_name = $2; + $day = 0 + $3; + $year_or_time = $4; + + # translate the month name into number + $month = $months{$month_name}; + + # recognize time or year, and compute missing one + if ($year_or_time =~ /([0-9]{2}):([0-9]{2})/) { + $hours = 0 + $1; $minutes = 0 + $2; + my @this_date = gmtime(time()); + my $this_month = $this_date[4]; + my $this_year = $this_date[5]; + if ($month > $this_month) { + $year = $this_year - 1; + } else { + $year = $this_year; + } + } elsif ($year_or_time =~ / [0-9]{4}/) { + $hours = 0; $minutes = 0; + $year = $year_or_time - 1900; + } else { + die 'cannot parse year-or-time'; + } + + # build a system time + $time = Time::Local::timegm(0, $minutes, $hours, $day, $month, $year); + } else { + die 'regex match failed on LIST output'; + } + } + + return $time; +} + +=head1 CHANGES + +=head2 Version 0.xx + +This is a private module. + +=cut + +1; + +__END__ diff --git a/dselect/methods/Makefile.am b/dselect/methods/Makefile.am new file mode 100644 index 0000000..15c9cab --- /dev/null +++ b/dselect/methods/Makefile.am @@ -0,0 +1,57 @@ +## Process this file with automake to produce Makefile.in + +methodsdir = $(pkglibexecdir)/methods + +nobase_dist_methods_DATA = \ + file/names \ + file/desc.file \ + ftp/names \ + ftp/desc.ftp \ + media/names \ + media/desc.media \ + # EOL + +nobase_methods_SCRIPTS = \ + file/install \ + file/setup \ + file/update \ + ftp/install \ + ftp/setup \ + ftp/update \ + media/install \ + media/setup \ + media/update \ + # EOL + +perllibdir = $(PERL_LIBDIR) +nobase_dist_perllib_DATA = \ + Dselect/Method.pm \ + Dselect/Method/Ftp.pm \ + # EOL + +EXTRA_DIST = \ + file/setup.sh \ + file/update.sh \ + file/install.sh \ + ftp/setup.pl \ + ftp/update.pl \ + ftp/install.pl \ + media/setup.sh \ + media/update.sh \ + media/install.sh \ + media/README.media \ + # EOL + +CLEANFILES = \ + $(nobase_methods_SCRIPTS) \ + # EOL + +SUFFIXES = + +include $(top_srcdir)/build-aux/subst.am + +install-data-local: + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/mnt + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/file + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/ftp + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/media diff --git a/dselect/methods/Makefile.in b/dselect/methods/Makefile.in new file mode 100644 index 0000000..7dfe739 --- /dev/null +++ b/dselect/methods/Makefile.in @@ -0,0 +1,764 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Build time variable substitution for generated files. +# + +# Shell support. + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = dselect/methods +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/dpkg-arch.m4 \ + $(top_srcdir)/m4/dpkg-build.m4 \ + $(top_srcdir)/m4/dpkg-compiler.m4 \ + $(top_srcdir)/m4/dpkg-coverage.m4 \ + $(top_srcdir)/m4/dpkg-funcs.m4 \ + $(top_srcdir)/m4/dpkg-headers.m4 $(top_srcdir)/m4/dpkg-libs.m4 \ + $(top_srcdir)/m4/dpkg-linker.m4 $(top_srcdir)/m4/dpkg-progs.m4 \ + $(top_srcdir)/m4/dpkg-types.m4 \ + $(top_srcdir)/m4/dpkg-unicode.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_dist_methods_DATA) \ + $(nobase_dist_perllib_DATA) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(methodsdir)" "$(DESTDIR)$(methodsdir)" \ + "$(DESTDIR)$(perllibdir)" +SCRIPTS = $(nobase_methods_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(nobase_dist_methods_DATA) $(nobase_dist_perllib_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/subst.am +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOM4TE = @AUTOM4TE@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_DEVEL_DOCS = @BUILD_DEVEL_DOCS@ +BZ2_LIBS = @BZ2_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CURSES_LIBS = @CURSES_LIBS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEB_DEFAULT_COMPRESSOR = @DEB_DEFAULT_COMPRESSOR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DPKG_DEFAULT_PAGER = @DPKG_DEFAULT_PAGER@ +DPKG_DEFAULT_SHELL = @DPKG_DEFAULT_SHELL@ +DPKG_PAGER = @DPKG_PAGER@ +DPKG_SHELL = @DPKG_SHELL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GCOV = @GCOV@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_DOT = @HAVE_DOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +KVM_LIBS = @KVM_LIBS@ +LCOV = @LCOV@ +LCOV_GENHTML = @LCOV_GENHTML@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +LZMA_LIBS = @LZMA_LIBS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MD_LIBS = @MD_LIBS@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_BUG_WEB = @PACKAGE_BUG_WEB@ +PACKAGE_COPYRIGHT_HOLDER = @PACKAGE_COPYRIGHT_HOLDER@ +PACKAGE_CPAN_NAME = @PACKAGE_CPAN_NAME@ +PACKAGE_DIST_IS_RELEASE = @PACKAGE_DIST_IS_RELEASE@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_RELEASE_DATE = @PACKAGE_RELEASE_DATE@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VCS_TYPE = @PACKAGE_VCS_TYPE@ +PACKAGE_VCS_URL = @PACKAGE_VCS_URL@ +PACKAGE_VCS_WEB = @PACKAGE_VCS_WEB@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATCH = @PATCH@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PERL_COVER = @PERL_COVER@ +PERL_COVERAGE = @PERL_COVERAGE@ +PERL_LIBDIR = @PERL_LIBDIR@ +PERL_MIN_VERSION = @PERL_MIN_VERSION@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PO4A = @PO4A@ +POD2MAN = @POD2MAN@ +POSUB = @POSUB@ +PS_LIBS = @PS_LIBS@ +RANLIB = @RANLIB@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKET_LIBS = @SOCKET_LIBS@ +STRIP = @STRIP@ +TAR = @TAR@ +USE_NLS = @USE_NLS@ +USE_PO4A = @USE_PO4A@ +USE_UNICODE = @USE_UNICODE@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +ZSTD_LIBS = @ZSTD_LIBS@ +Z_LIBS = @Z_LIBS@ +Z_NG_LIBS = @Z_NG_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +admindir = @admindir@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +backupsdir = @backupsdir@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +devlibdir = @devlibdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logdir = @logdir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfdir = @pkgconfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +zshcompletionsdir = @zshcompletionsdir@ +methodsdir = $(pkglibexecdir)/methods +nobase_dist_methods_DATA = \ + file/names \ + file/desc.file \ + ftp/names \ + ftp/desc.ftp \ + media/names \ + media/desc.media \ + # EOL + +nobase_methods_SCRIPTS = \ + file/install \ + file/setup \ + file/update \ + ftp/install \ + ftp/setup \ + ftp/update \ + media/install \ + media/setup \ + media/update \ + # EOL + +perllibdir = $(PERL_LIBDIR) +nobase_dist_perllib_DATA = \ + Dselect/Method.pm \ + Dselect/Method/Ftp.pm \ + # EOL + +EXTRA_DIST = \ + file/setup.sh \ + file/update.sh \ + file/install.sh \ + ftp/setup.pl \ + ftp/update.pl \ + ftp/install.pl \ + media/setup.sh \ + media/update.sh \ + media/install.sh \ + media/README.media \ + # EOL + +CLEANFILES = \ + $(nobase_methods_SCRIPTS) \ + # EOL + +SUFFIXES = .sh .pl +do_shell_subst = $(AM_V_GEN) $(SED) \ + -e "s:^ADMINDIR=.*$$:ADMINDIR='$(admindir)':" \ + -e "s:^BACKUPSDIR=.*$$:BACKUPSDIR='$(backupsdir)':" \ + -e "s:^PKGDATADIR_DEFAULT=.*$$:PKGDATADIR_DEFAULT='$(pkgdatadir)':" \ + -e "s:^version=['\"][^'\"]*[\"']:version=\"$(PACKAGE_VERSION)\":" \ + -e "s:^TAR=.*$$:TAR='$(TAR)':" \ + # EOL + + +# Perl support. +do_perl_subst = $(AM_V_GEN) $(SED) \ + -e "s:^\#![[:space:]]*/usr/bin/perl:\#!$(PERL):" \ + -e "s:our \$$CONFDIR = .*;:our \$$CONFDIR = '$(pkgconfdir)';:" \ + -e "s:our \$$ADMINDIR = .*;:our \$$ADMINDIR = '$(admindir)';:" \ + -e "s:our \$$LIBDIR = .*;:our \$$LIBDIR = '$(pkglibexecdir)';:" \ + -e "s:our \$$DATADIR = .*;:our \$$DATADIR = '$(pkgdatadir)';:" \ + -e "s:our \$$PROGMAKE = .*;:our \$$PROGMAKE = '$(MAKE)';:" \ + -e "s:our \$$PROGTAR = .*;:our \$$PROGTAR = '$(TAR)';:" \ + -e "s:our \$$PROGPATCH = .*;:our \$$PROGPATCH = '$(PATCH)';:" \ + -e "s:our \$$PROGVERSION = .*;:our \$$PROGVERSION = '$(PACKAGE_VERSION)';:" \ + # EOL + + +# Makefile support. +do_make_subst = $(AM_V_GEN) $(SED) \ + -e "s:dpkg_datadir[[:space:]]*=[[:space:]]*[^[:space:]]*:dpkg_datadir = $(pkgdatadir):" \ + # EOL + +all: all-am + +.SUFFIXES: +.SUFFIXES: .sh .pl +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build-aux/subst.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dselect/methods/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign dselect/methods/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/build-aux/subst.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-nobase_methodsSCRIPTS: $(nobase_methods_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(nobase_methods_SCRIPTS)'; test -n "$(methodsdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(methodsdir)" || exit 1; \ + fi; \ + $(am__nobase_strip_setup); \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e "s|$$srcdirstrip/||" -e 'h;s|[^/]*$$||; s|^$$|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + case $$type in \ + d) echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(methodsdir)/$$dir" || exit $$?;; \ + f) \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(methodsdir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(methodsdir)$$dir" || exit $$?; \ + } \ + ;; esac \ + ; done + +uninstall-nobase_methodsSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_methods_SCRIPTS)'; test -n "$(methodsdir)" || exit 0; \ + $(am__nobase_strip_setup); \ + files=`$(am__nobase_strip) \ + -e 'h;s,.*/,,;$(transform);x;s|[^/]*$$||;G;s,\n,,'`; \ + dir='$(DESTDIR)$(methodsdir)'; $(am__uninstall_files_from_dir) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-nobase_dist_methodsDATA: $(nobase_dist_methods_DATA) + @$(NORMAL_INSTALL) + @list='$(nobase_dist_methods_DATA)'; test -n "$(methodsdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(methodsdir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(methodsdir)/$$dir"; }; \ + echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(methodsdir)/$$dir'"; \ + $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(methodsdir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_dist_methodsDATA: + @$(NORMAL_UNINSTALL) + @list='$(nobase_dist_methods_DATA)'; test -n "$(methodsdir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(methodsdir)'; $(am__uninstall_files_from_dir) +install-nobase_dist_perllibDATA: $(nobase_dist_perllib_DATA) + @$(NORMAL_INSTALL) + @list='$(nobase_dist_perllib_DATA)'; test -n "$(perllibdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(perllibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(perllibdir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(perllibdir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(perllibdir)/$$dir"; }; \ + echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(perllibdir)/$$dir'"; \ + $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(perllibdir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_dist_perllibDATA: + @$(NORMAL_UNINSTALL) + @list='$(nobase_dist_perllib_DATA)'; test -n "$(perllibdir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(perllibdir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(SCRIPTS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(methodsdir)" "$(DESTDIR)$(methodsdir)" "$(DESTDIR)$(perllibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-data-local install-nobase_dist_methodsDATA \ + install-nobase_dist_perllibDATA install-nobase_methodsSCRIPTS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-nobase_dist_methodsDATA \ + uninstall-nobase_dist_perllibDATA \ + uninstall-nobase_methodsSCRIPTS + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-local install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-nobase_dist_methodsDATA \ + install-nobase_dist_perllibDATA install-nobase_methodsSCRIPTS \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am \ + uninstall-nobase_dist_methodsDATA \ + uninstall-nobase_dist_perllibDATA \ + uninstall-nobase_methodsSCRIPTS + +.PRECIOUS: Makefile + + +.sh: Makefile + @test -d `dirname $@` || $(MKDIR_P) `dirname $@` + $(do_shell_subst) <$< >$@ + $(AM_V_at) chmod +x $@ + +.pl: Makefile + @test -d `dirname $@` || $(MKDIR_P) `dirname $@` + $(do_perl_subst) <$< >$@ + $(AM_V_at) chmod +x $@ + +install-data-local: + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/mnt + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/file + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/ftp + $(MKDIR_P) $(DESTDIR)$(admindir)/methods/media + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/dselect/methods/file/desc.file b/dselect/methods/file/desc.file new file mode 100644 index 0000000..028d099 --- /dev/null +++ b/dselect/methods/file/desc.file @@ -0,0 +1,9 @@ +Installation from a directory on the filesystem. + +The area you are installing from should contain the Packages.gz file +from each distribution area being installed (usually main and optionally +contrib, non-free-firmware and non-free) as well as the corresponding +binary/*/*.deb files. + +The easiest way to do get this is to make a (partial) copy of the +distribution site's directory hierarchy, if possible. diff --git a/dselect/methods/file/install.sh b/dselect/methods/file/install.sh new file mode 100755 index 0000000..f5e3dae --- /dev/null +++ b/dselect/methods/file/install.sh @@ -0,0 +1,124 @@ +#!/bin/sh +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -e +vardir="$1" +method=$2 +option=$3 + +cd "$vardir/methods/file" + +. ./shvar.$option + +xit=1 +trap ' + exit $xit +' 0 + +predep="$vardir/predep-package" +while true; do + set +e + dpkg --admindir "$vardir" --predep-package >"$predep" + rc=$? + set -e + if test $rc = 1; then + break + fi + test $rc = 0 + + perl -e ' + ($binaryprefix,$predep) = @ARGV; + $binaryprefix =~ s,/*$,/, if length($binaryprefix); + open(P, "< $predep") or die "cannot open $predep: $!\n"; + while (<P>) { + s/\s*\n$//; + $package = $_ if s/^Package: //i; + @filename = split(/ /,$_) if s/^Filename: //i; + @msdosfilename = split(/ /,$_) if s/^MSDOS-Filename: //i; + } + die "internal error - no package" if length($package) == 0; + die "internal error - no filename" if not @filename; + die "internal error - mismatch >@filename< >@msdosfilename<" + if @filename && @msdosfilename && + @filename != @msdosfilename; + @invoke = (); $| = 1; + for ($i = 0; $i <= $#filename; $i++) { + $ppart = $i+1; + print "Looking for part $ppart of $package ... "; + if (-f "$binaryprefix$filename[$i]") { + $print = $filename[$i]; + $invoke = "$binaryprefix$filename[$i]"; + } elsif (-f "$binaryprefix$msdosfilename[$i]") { + $print = $msdosfilename[$i]; + $invoke = "$binaryprefix$msdosfilename[$i]"; + } else { + $base = $filename[$i]; $base =~ s,.*/,,; + $msdosbase = $msdosfilename[$i]; $msdosbase =~ s,.*/,,; + $c = open(X, "-|")); + if (not defined $c) { + die "failed to fork for find: $!\n"; + } + if (!$c) { + exec("find", "-L", + length($binaryprefix) ? + $binaryprefix : ".", + "-name",$base,"-o","-name",$msdosbase); + die "failed to exec find: $!\n"; + } + while (chop($invoke = <X>)) { last if -f $invoke; } + $print = $invoke; + if (substr($print,0,length($binaryprefix)+1) eq + "$binaryprefix/") { + $print = substr($print,length($binaryprefix)); + } + } + if (!length($invoke)) { + warn " + +Cannot find the appropriate file(s) anywhere needed to install or upgrade +package $package. Expecting version $version or later, as listed in the +Packages file. + +Perhaps the package was downloaded with an unexpected name? In any case, +you must find the file(s) and then either place it with the correct +filename(s) (as listed in the Packages file or in $vardir/available) +and rerun the installation, or upgrade the package by using +\"dpkg --install --auto-deconfigure" by hand. + +"; + exit(1); + } + print "$print\n"; + push(@invoke,$invoke); + } + print "Running dpkg -iB for $package ...\n"; + exec("dpkg","--admindir",$vardir,"-iB","--",@invoke); + die "failed to exec dpkg: $!\n"; + ' -- "$p_mountpoint$p_main_binary" "$predep" +done + +for f in main ctb nf lcl; do + eval 'this_binary=$p_'$f'_binary' + if [ -z "$this_binary" ]; then + continue + fi + echo Running dpkg --admindir $vardir -iGROEB "$p_mountpoint$this_binary" + dpkg --admindir $vardir -iGROEB "$p_mountpoint$this_binary" +done + +echo -n 'Installation OK. Hit RETURN. ' +read response + +xit=0 diff --git a/dselect/methods/file/names b/dselect/methods/file/names new file mode 100644 index 0000000..3b36a48 --- /dev/null +++ b/dselect/methods/file/names @@ -0,0 +1 @@ +42 file Install from a directory in the filesystem. diff --git a/dselect/methods/file/setup.sh b/dselect/methods/file/setup.sh new file mode 100755 index 0000000..027c8c8 --- /dev/null +++ b/dselect/methods/file/setup.sh @@ -0,0 +1,308 @@ +#!/bin/sh +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -e +vardir="$1" +method=$2 +option=$3 + +cd "$vardir/methods/file" +tp="$(mktemp --tmpdir $method.XXXXXXXXXX)" + +iarch=$(dpkg --admindir $vardir --print-architecture) + +xit=1 +trap ' + rm -f $tp.? + exit $xit +' 0 + +if ls -d "$tp.?" >/dev/null 2>&1; then + rm $tp.? +fi + +yesno () { + while true; do + echo -n "$2 [$1] " + read response + if [ -z "$response" ]; then + response="$1" + fi + case "$response" in + [Nn]*) + yesno=no + return + ;; + [Yy]*) + yesno=yes + return + ;; + esac + done +} + +outputparam () { + echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3 +} + +intrkey="$(stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p')" +echo " +If you make a mistake, use the interrupt key ($intrkey) to abort. +" + +# State variables, “best first” +# {main,ctb,nf,lcl}_{packages,binary} +# Empty before we've found them or if they're not available, +# set to the relevant bit under mountpoint otherwise. +# hierbase +# A directory containing a Debian FTP site mirror tree for ONE distribution. +# eg /pub/debian/dists/stable +# mountpoint +# The mountpoint for the filesystem containing the stuff +# empty or unset if we don't know yet, or if we haven't mounted anything; +# may also be empty if ‘directory’ was set. +# fstype +# The filesystem type to use. + +if [ -f shvar.$option ]; then + . ./shvar.$option +fi + +if [ -n "$mountpoint" ]; then + # We must have $mountpoint + echo \ +"All directory names should be entered relative to the root of the +$fstype filesystem. +" +fi + +while true; do + echo \ +"In order to make it easy to find the relevant files, it is preferred +to install from a straightforward copy of the Debian distribution. +To use this, it is required to know where the top level of that copy of +the distribution is (eg. 'debian/dists/stable') - this directory usually +contains the Packages-Master file. + +If you do not have a straightforward copy of the distribution available +just answer 'none' and each needed part will be prompted individually." + defhierbase=none + # maybe ask for debian/dists and then show and ask for available dists + # eg. {stable,frozen,unstable,bo,hamm,slink} + if [ -n "$p_hierbase" ]; then + if [ -d "$mountpoint/$p_hierbase/main/binary-$iarch" ]; then + echo " +Last time you said '$p_hierbase', and that looks plausible." + defhierbase="$p_hierbase" + else + echo " +Last time you said '$p_hierbase', but that doesn't look plausible, +since '$p_hierbase/main/binary-$iarch' doesn't seem to exist." + fi + fi + if [ none = "$defhierbase" ]; then + if [ -d "$mountpoint/debian/dists/stable/main/binary-$iarch" ]; then + echo " +'/debian/dists/stable' exists and looks plausible, so that's the default." + defhierbase=/debian/dists/stable + elif [ -d "$mountpoint/dists/stable/main/binary-$iarch" ]; then + echo " +'/dists/stable' exists and looks plausible, so that's the default." + defhierbase=/dists/stable + fi + fi + echo -n \ +"Distribution top level ? [$defhierbase] " + read response + if [ -z "$response" ]; then + response="$defhierbase" + fi + if [ none = "$response" ]; then + hierbase="" + break + elif [ -d "$mountpoint/$response/main/binary-$iarch" ]; then + hierbase="$(echo "$response" | sed -e 's:/*$::; s:^/*:/:')" + break + fi + echo \ +"$response/main/binary-$iarch does not exist. +" +done + +case "$hierbase" in +/* ) + ;; +'' ) + ;; +* ) + hierbase="/$hierbase" + ;; +esac + +check_binary () { + # args: area-in-messages directory + # eg: main "$hierbase/main/binary-$iarch" + # checks whether $2 contains *.deb + if ! [ -d "$mountpoint$2/" ]; then + echo "'$2' does not exist." + return + fi + + if ! ( find -L "$mountpoint$2/" -name '*.deb' -print \ + | head -n 1 ) 2>/dev/null | grep . >/dev/null; then + echo "'$2' does not contain any *.deb packages. Hmmpf." + return + fi + echo "Using '$2' as $1 binary dir." + this_binary="$2" +} + +find_area () { + # args: area-in-messages area-in-vars subdirectory-in-hier + # last-time-binary last-time-packages + # eg: main main main + # "$p_main_binary" "$p_main_packages" + + this_binary='' + this_packages='' + if [ -n "$hierbase" ]; then + check_binary $1 "$hierbase/$3/binary-$iarch" + fi + + if [ $2 = lcl ] && [ -z "$this_binary" ]; then + echo " +Note: By default there is no 'local' directory. It is intended for +packages you made yourself." + fi + if [ $2 = nf -a -z "$this_binary" ]; then + echo " +Note: most media distributions of Debian do not include programs available +in the 'non-free' directory of the distribution site. +This is because these programs are under licenses that do not allow source +modification or prevent distribution for profit on a media, or other +restrictions that make them not free software. +If you wish to install these programs you will have to get them from an +alternative source." + fi + while [ -z "$this_binary" ]; do + defaultbinary="$4" + echo " +Which directory contains the *.deb packages from the $1 distribution +area (this directory is named '$3/binary-$iarch' on the distribution site) ? +Say 'none' if this area is not available." + if [ $2 != main ] && [ -z "$defaultbinary" ]; then + defaultbinary=none + fi + echo -n \ +"Enter _$1_ binary dir. [$4] + ? " + read response + if [ -z "$response" ] && [ -n "$defaultbinary" ]; then + response="$defaultbinary" + fi + if [ none = "$response" ]; then + break + fi + case "$response" in + '' | none) + continue + ;; + esac + check_binary $1 "$(echo "$response" | sed -e 's:/$::; s:^/*:/:')" + done + if [ -n "$this_binary" ]; then + for f in Packages.gz packages.gz Packages packages; do + if [ -f "$mountpoint/$this_binary/$f" ]; then + echo "Using '$this_binary/$f' for $1." + this_packages="$this_binary/$f" + break + fi + done + while [ -z "$this_packages" ]; do + echo -n " +Cannot find the $1 'Packages' file. The information in the +'Packages' file is important for package selection during new +installations, and is very useful for upgrades. + +If you overlooked it when downloading you should do get it now and +return to this installation procedure when you have done so: you will +find one Packages file and one Packages.gz file -- either will do -- +in the 'binary-$iarch' subdirectory of each area on the FTP sites and +media discs. Alternatively (and this will be rather slow) the packages in +the distribution area can be scanned - say 'scan' if you want to do so. + +You need a separate Packages file from each of the distribution areas +you wish to install. + +Where is the _$1_ 'Packages' file (if none is available, say 'none') +[$5] + ? " + read response + if [ -z "$response" ] && [ -n "$5" ]; then + response="$5" + fi + case "$response" in + '') + continue + ;; + none) + break + ;; + scan) + this_packages=scan + ;; + /*) + this_packages="$response" + ;; + *) + this_packages="/$response" + ;; + esac + done + fi + eval $2'_binary="$this_binary"' + eval $2'_packages="$this_packages"' +} + +find_area main main main "$p_main_binary" "$p_main_packages" +find_area contrib ctb contrib "$p_ctb_binary" "$p_ctb_packages" +find_area non-free-firmware nff non-free-firmware "$p_nff_binary" "$p_nff_packages" +find_area non-free nf non-free "$p_nf_binary" "$p_nf_packages" +find_area local lcl local "$p_lcl_binary" "$p_lcl_packages" + +echo -n ' +Hit RETURN to continue. ' +read response + +exec 3>shvar.$option.new + +outputparam p_fstype "$fstype" +outputparam p_mountpoint "$mountpoint" +outputparam p_hierbase "$hierbase" + +outputparam p_main_packages "$main_packages" +outputparam p_main_binary "$main_binary" +outputparam p_ctb_packages "$ctb_packages" +outputparam p_ctb_binary "$ctb_binary" +outputparam p_nf_packages "$nf_packages" +outputparam p_nf_binary "$nf_binary" +outputparam p_nff_packages "$nff_packages" +outputparam p_nff_binary "$nff_binary" +outputparam p_lcl_packages "$lcl_packages" +outputparam p_lcl_binary "$lcl_binary" + +mv shvar.$option.new shvar.$option + +xit=0 diff --git a/dselect/methods/file/update.sh b/dselect/methods/file/update.sh new file mode 100755 index 0000000..3784ffe --- /dev/null +++ b/dselect/methods/file/update.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -e +vardir="$1" +method=$2 +option=$3 + +cd "$vardir/methods/file" + +. ./shvar.$option + +if [ -z "$p_main_packages" ] && [ -z "$p_ctb_packages" ] && \ + [ -z "$p_nf_packages" ] && [ -z "$p_lcl_packages" ]; then + echo ' +No Packages files available, cannot update available packages list. +Hit RETURN to continue. ' + read response + exit 0 +fi + +xit=1 +trap ' + rm -f packages-main packages-ctb packages-nf packages-lcl + exit $xit +' 0 + +updatetype=update + +for f in main ctb nf lcl; do + eval 'this_packages=$p_'$f'_packages' + case "$this_packages" in + '') + continue + ;; + scan) + eval 'this_binary=$p_'$f'_binary' + if [ -z "$this_binary" ]; then + continue + fi + if [ "$updatetype" = update ]; then + dpkg --admindir $vardir --clear-avail + updatetype=merge + fi + echo Running dpkg --record-avail -R "$p_mountpoint$this_binary" + dpkg --admindir $vardir --record-avail -R "$p_mountpoint$this_binary" + ;; + *) + packagesfile="$p_mountpoint$this_packages" + case "$packagesfile" in + *.gz) + echo -n "Uncompressing $packagesfile ... " + zcat <"$packagesfile" >packages-$f + echo done. + dpkg --admindir $vardir --$updatetype-avail packages-$f + updatetype=merge + ;; + '') + ;; + *) + dpkg --admindir $vardir --$updatetype-avail "$packagesfile" + updatetype=merge + ;; + esac + ;; + esac +done + +echo -n 'Update OK. Hit RETURN. ' +read response + +xit=0 diff --git a/dselect/methods/ftp/desc.ftp b/dselect/methods/ftp/desc.ftp new file mode 100644 index 0000000..accd994 --- /dev/null +++ b/dselect/methods/ftp/desc.ftp @@ -0,0 +1,2 @@ +Installation using ftp, you must know one (or more) ftp site(s) and the +correct directories for the Debian distribution. diff --git a/dselect/methods/ftp/install.pl b/dselect/methods/ftp/install.pl new file mode 100755 index 0000000..ea6ea71 --- /dev/null +++ b/dselect/methods/ftp/install.pl @@ -0,0 +1,626 @@ +#!/usr/bin/perl +# +# Copyright © 1996 Andy Guy <andy@cyteen.org> +# Copyright © 1998 Martin Schulze <joey@infodrom.north.de> +# Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +use strict; +use warnings; + +use File::Path qw(make_path remove_tree); +use File::Basename; + +eval q{ + use File::Find; + use Data::Dumper; + + use Dpkg::File; +}; +if ($@) { + warn "Missing Dpkg modules required by the FTP access method.\n\n"; + exit 1; +} + +use Dselect::Method; +use Dselect::Method::Ftp; + +my $ftp; + +# exit value +my $exit = 0; + +# deal with arguments +my $vardir = $ARGV[0]; +my $method = $ARGV[1]; +my $option = $ARGV[2]; + +if ($option eq 'manual') { + print "manual mode not supported yet\n"; + exit 1; +} +#print "vardir: $vardir, method: $method, option: $option\n"; + +my $methdir = "$vardir/methods/ftp"; + +# get info from control file +read_config("$methdir/vars"); + +chdir "$methdir"; +make_path("$methdir/$CONFIG{dldir}", { mode => 0755 }); + + +#Read md5sums already calculated +my %md5sums; +if (-f "$methdir/md5sums") { + my $code = file_slurp("$methdir/md5sums"); + my $VAR1; ## no critic (Variables::ProhibitUnusedVariables) + my $res = eval $code; + if ($@) { + die "couldn't eval $methdir/md5sums content: $@\n"; + } + if (ref($res)) { %md5sums = %{$res} } +} + +# Get a stanza. +# returns a ref to a hash containing flds->fld contents +# white space from the ends of lines is removed and newlines added +# (no trailing newline). +# die's if something unexpected happens +sub get_stanza { + my $fh = shift; + my %flds; + my $fld; + while (<$fh>) { + if (length != 0) { + FLDLOOP: while (1) { + if ( /^(\S+):\s*(.*)\s*$/ ) { + $fld = lc($1); + $flds{$fld} = $2; + while (<$fh>) { + if (length == 0) { + return %flds; + } elsif ( /^(\s.*)$/ ) { + $flds{$fld} = $flds{$fld} . "\n" . $1; + } else { + next FLDLOOP; + } + } + return %flds; + } else { + die "expected a start of field line, but got:\n$_"; + } + } + } + } + return %flds; +} + +# process status file +# create curpkgs hash with version (no version implies not currently installed) +# of packages we want +print "Processing status file...\n"; +my %curpkgs; +sub procstatus { + my (%flds, $fld); + open(my $status_fh, '<', "$vardir/status") or + die 'Could not open status file'; + while (%flds = get_stanza($status_fh), %flds) { + if($flds{'status'} =~ /^install ok/) { + my $cs = (split(/ /, $flds{'status'}))[2]; + if (($cs eq 'not-installed') || + ($cs eq 'half-installed') || + ($cs eq 'config-files')) { + $curpkgs{$flds{'package'}} = ''; + } else { + $curpkgs{$flds{'package'}} = $flds{'version'}; + } + } + } + close($status_fh); +} +procstatus(); + +sub dcmpvers { + my($a, $p, $b) = @_; + my ($r); + $r = system('dpkg', '--compare-versions', "$a", "$p", "$b"); + $r = $r/256; + if ($r == 0) { + return 1; + } elsif ($r == 1) { + return 0; + } + die "dpkg --compare-versions $a $p $b - failed with $r"; +} + +# process package files, looking for packages to install +# create a hash of these packages pkgname => version, filenames... +# filename => md5sum, size +# for all packages +my %pkgs; +my %pkgfiles; +sub procpkgfile { + my $fn = shift; + my $site = shift; + my $dist = shift; + my (@files, @sizes, @md5sums, $pkg, $ver, $nfs, $fld); + my(%flds); + open(my $pkgfile_fh, '<', $fn) or die "could not open package file $fn"; + while (%flds = get_stanza($pkgfile_fh), %flds) { + $pkg = $flds{'package'}; + $ver = $curpkgs{$pkg}; + @files = split(/[\s\n]+/, $flds{'filename'}); + @sizes = split(/[\s\n]+/, $flds{'size'}); + @md5sums = split(/[\s\n]+/, $flds{'md5sum'}); + if (defined($ver) && (($ver eq '') || dcmpvers($ver, 'lt', $flds{'version'}))) { + $pkgs{$pkg} = [ $flds{'version'}, [ @files ], $site ]; + $curpkgs{$pkg} = $flds{'version'}; + } + $nfs = scalar(@files); + if(($nfs != scalar(@sizes)) || ($nfs != scalar(@md5sums)) ) { + print "Different number of filenames, sizes and md5sums for $flds{'package'}\n"; + } else { + my $i = 0; + foreach my $fl (@files) { + $pkgfiles{$fl} = [ $md5sums[$i], $sizes[$i], $site, $dist ]; + $i++; + } + } + } + close $pkgfile_fh or die "cannot close package file $fn: $!\n"; +} + +print "\nProcessing Package files...\n"; +my ($i, $j); +$i = 0; +foreach my $site (@{$CONFIG{site}}) { + $j = 0; + foreach my $dist (@{$site->[2]}) { + my $fn = $dist; + $fn =~ tr#/#_#; + $fn = "Packages.$site->[0].$fn"; + if (-f $fn) { + print " $site->[0] $dist...\n"; + procpkgfile($fn,$i,$j); + } else { + print "Could not find packages file for $site->[0] $dist distribution (re-run Update)\n" + } + $j++; + } + $i++; +} + +my $dldir = $CONFIG{dldir}; +# md5sum +sub md5sum($) { + my $fn = shift; + my $m = qx(md5sum $fn); + $m = (split(' ', $m))[0]; + $md5sums{"$dldir/$fn"} = $m; + return $m; +} + +# construct list of files to get +# hash of filenames => size of downloaded part +# query user for each partial file +print "\nConstructing list of files to get...\n"; +my %downloads; +my ($dir, @info, @files, $csize, $size); +my $totsize = 0; +foreach my $pkg (keys(%pkgs)) { + @files = @{$pkgs{$pkg}[1]}; + foreach my $fn (@files) { + #Look for a partial file + if (-f "$dldir/$fn.partial") { + rename "$dldir/$fn.partial", "$dldir/$fn"; + } + $dir = dirname($fn); + if(! -d "$dldir/$dir") { + make_path("$dldir/$dir", { mode => 0755 }); + } + @info = @{$pkgfiles{$fn}}; + $csize = int($info[1]/1024)+1; + if(-f "$dldir/$fn") { + $size = -s "$dldir/$fn"; + if($info[1] > $size) { + # partial download + if (yesno('y', "continue file: $fn (" . nb($size) . '/' . + nb($info[1]) . ')')) { + $downloads{$fn} = $size; + $totsize += $csize - int($size/1024); + } else { + $downloads{$fn} = 0; + $totsize += $csize; + } + } else { + # check md5sum + if (! exists $md5sums{"$dldir/$fn"}) { + $md5sums{"$dldir/$fn"} = md5sum("$dldir/$fn"); + } + if ($md5sums{"$dldir/$fn"} eq $info[0]) { + print "already got: $fn\n"; + } else { + print "corrupted: $fn\n"; + $downloads{$fn} = 0; + } + } + } else { + my $ffn = $fn; + $ffn =~ s/binary-[^\/]+/.../; + print 'want: ' . + $CONFIG{site}[$pkgfiles{$fn}[2]][0] . " $ffn (${csize}k)\n"; + $downloads{$fn} = 0; + $totsize += $csize; + } + } +} + +my $avsp = qx(df -Pk $dldir| awk '{ print \$4}' | tail -n 1); +chomp $avsp; + +print "\nApproximate total space required: ${totsize}k\n"; +print "Available space in $dldir: ${avsp}k\n"; + +#$avsp = qx(df -k $::dldir| paste -s | awk '{ print \$11}); +#chomp $avsp; + +if($totsize == 0) { + print 'Nothing to get.'; +} else { + if($totsize > $avsp) { + print "Space required is greater than available space,\n"; + print "you will need to select which items to get.\n"; + } +# ask user which files to get + if (($totsize > $avsp) || + yesno('n', 'Do you want to select the files to get')) { + $totsize = 0; + my @files = sort(keys(%downloads)); + my $def = 'y'; + foreach my $fn (@files) { + my @info = @{$pkgfiles{$fn}}; + my $csize = int($info[1] / 1024) + 1; + my $rsize = int(($info[1] - $downloads{$fn}) / 1024) + 1; + if ($rsize + $totsize > $avsp) { + print "no room for: $fn\n"; + delete $downloads{$fn}; + } else { + if(yesno($def, $downloads{$fn} + ? "download: $fn ${rsize}k/${csize}k (total = ${totsize}k)" + : "download: $fn ${rsize}k (total = ${totsize}k)")) { + $def = 'y'; + $totsize += $rsize; + } else { + $def = 'n'; + delete $downloads{$fn}; + } + } + } + } +} + +sub download() { + my $i = 0; + + foreach my $site (@{$CONFIG{site}}) { + my @getfiles = grep { $pkgfiles{$_}[2] == $i } keys %downloads; + my @pre_dist = (); # Directory to add before $fn + + #Scan distributions for looking at "(../)+/dir/dir" + my ($n,$cp); + $cp = -1; + foreach (@{$site->[2]}) { + $cp++; + $pre_dist[$cp] = ''; + $n = (s{\.\./}{../}g); + next if (! $n); + if (m<^((?:\.\./){$n}(?:[^/]+/){$n})>) { + $pre_dist[$cp] = $1; + } + } + + if (! @getfiles) { $i++; next; } + + $ftp = do_connect(ftpsite => $site->[0], + ftpdir => $site->[1], + passive => $site->[3], + username => $site->[4], + password => $site->[5], + useproxy => $CONFIG{use_auth_proxy}, + proxyhost => $CONFIG{proxyhost}, + proxylogname => $CONFIG{proxylogname}, + proxypassword => $CONFIG{proxypassword}); + + local $SIG{INT} = sub { die "Interrupted !\n"; }; + + my ($rsize, $res, $pre); + foreach my $fn (@getfiles) { + $pre = $pre_dist[$pkgfiles{$fn}[3]] || ''; + if ($downloads{$fn}) { + $rsize = ${pkgfiles{$fn}}[1] - $downloads{$fn}; + print "getting: $pre$fn (" . nb($rsize) . '/' . + nb($pkgfiles{$fn}[1]) . ")\n"; + } else { + print "getting: $pre$fn (". nb($pkgfiles{$fn}[1]) . ")\n"; + } + $res = $ftp->get("$pre$fn", "$dldir/$fn", $downloads{$fn}); + if(! $res) { + my $r = $ftp->code(); + print $ftp->message() . "\n"; + if (!($r == 550 || $r == 450)) { + return 1; + } else { + #Try to find another file or this package + print "Looking for another version of the package...\n"; + my ($dir, $package) = ($fn =~ m{^(.*)/([^/]+)_[^/]+.deb$}); + my $list = $ftp->ls("$pre$dir"); + if ($ftp->ok() && ref($list)) { + foreach my $file (@{$list}) { + if ($file =~ m/($dir\/\Q$package\E_[^\/]+.deb)/i) { + print "Package found : $file\n"; + print "getting: $file (size not known)\n"; + $res = $ftp->get($file, "$dldir/$1"); + if (! $res) { + $r = $ftp->code(); + print $ftp->message() . "\n"; + return 1 if ($r != 550 and $r != 450); + } + } + } + } + } + } + # fully got, remove it from list in case we have to re-download + delete $downloads{$fn}; + } + $ftp->quit(); + $i++; + } + return 0; +} + +# download stuff (protect from ^C) +if($totsize != 0) { + if (yesno('y', "\nDo you want to download the required files")) { + DOWNLOAD_TRY: while (1) { + print "Downloading files... use ^C to stop\n"; + eval { + if ((download() == 1) && + yesno('y', "\nDo you want to retry downloading at once")) { + next DOWNLOAD_TRY; + } + }; + if($@ =~ /Interrupted|Timeout/i ) { + # close the FTP connection if needed + if ((ref($ftp) =~ /Net::FTP/) and ($@ =~ /Interrupted/i)) { + $ftp->abort(); + $ftp->quit(); + undef $ftp; + } + print "FTP ERROR\n"; + if (yesno('y', "\nDo you want to retry downloading at once")) { + # get the first $fn that foreach would give: + # this is the one that got interrupted. + my $fn; + MY_ITER: foreach my $ffn (keys(%downloads)) { + $fn = $ffn; + last MY_ITER; + } + my $size = -s "$dldir/$fn"; + # partial download + if (yesno('y', "continue file: $fn (at $size)")) { + $downloads{$fn} = $size; + } else { + $downloads{$fn} = 0; + } + next DOWNLOAD_TRY; + } else { + $exit = 1; + last DOWNLOAD_TRY; + } + } elsif ($@) { + print "An error occurred ($@) : stopping download\n"; + } + last DOWNLOAD_TRY; + } + } +} + +# remove duplicate packages (keep latest versions) +# move half downloaded files out of the way +# delete corrupted files +print "\nProcessing downloaded files...(for corrupt/old/partial)\n"; +my %vers; # package => version +my %files; # package-version => files... + +# check a deb or split deb file +# return 1 if it a deb file, 2 if it is a split deb file +# else 0 +sub chkdeb($) { + my ($fn) = @_; + # check to see if it is a .deb file + if (!system "dpkg-deb --info $fn >/dev/null 2>&1 && dpkg-deb --contents $fn >/dev/null 2>&1") { + return 1; + } elsif (!system "dpkg-split --info $fn >/dev/null 2>&1") { + return 2; + } + return 0; +} +sub getdebinfo($) { + my ($fn) = @_; + my $type = chkdeb($fn); + my ($pkg, $ver); + if($type == 1) { + open(my $pkgfile_fh, '-|', "dpkg-deb --field $fn") + or die "cannot create pipe for 'dpkg-deb --field $fn'"; + my %fields = get_stanza($pkgfile_fh); + close($pkgfile_fh); + $pkg = $fields{'package'}; + $ver = $fields{'version'}; + return $pkg, $ver; + } elsif ( $type == 2) { + open(my $pkgfile_fh, '-|', "dpkg-split --info $fn") + or die "cannot create pipe for 'dpkg-split --info $fn'"; + while (<$pkgfile_fh>) { + /Part of package:\s*(\S+)/ and $pkg = $1; + /\.\.\. version:\s*(\S+)/ and $ver = $1; + } + close($pkgfile_fh); + return $pkg, $ver; + } + print "could not figure out type of $fn\n"; + return $pkg, $ver; +} + +# process deb file to make sure we only keep latest versions +sub prcdeb($$) { + my ($dir, $fn) = @_; + my ($pkg, $ver) = getdebinfo($fn); + if(!defined($pkg) || !defined($ver)) { + print "could not get package info from file\n"; + return 0; + } + if($vers{$pkg}) { + if (dcmpvers($vers{$pkg}, 'eq', $ver)) { + $files{$pkg . $ver} = [ $files{$pkg . $ver }, "$dir/$fn" ]; + } elsif (dcmpvers($vers{$pkg}, 'gt', $ver)) { + print "old version\n"; + unlink $fn; + } else { # else $ver is gt current version + foreach my $c (@{$files{$pkg . $vers{$pkg}}}) { + print "replaces: $c\n"; + unlink "$vardir/methods/ftp/$dldir/$c"; + } + $vers{$pkg} = $ver; + $files{$pkg . $ver} = [ "$dir/$fn" ]; + } + } else { + $vers{$pkg} = $ver; + $files{$pkg . $ver} = [ "$dir/$fn" ]; + } +} + +sub prcfile() { + my ($fn) = $_; + if (-f $fn and $fn ne '.') { + my $dir = '.'; + if (length($File::Find::dir) > length($dldir)) { + $dir = substr($File::Find::dir, length($dldir)+1); + } + print "$dir/$fn\n"; + if(defined($pkgfiles{"$dir/$fn"})) { + my @info = @{$pkgfiles{"$dir/$fn"}}; + my $size = -s $fn; + if($size == 0) { + print "zero length file\n"; + unlink $fn; + } elsif($size < $info[1]) { + print "partial file\n"; + rename $fn, "$fn.partial"; + } elsif(( (exists $md5sums{"$dldir/$fn"}) + and ($md5sums{"$dldir/$fn"} ne $info[0]) ) + or + (md5sum($fn) ne $info[0])) { + print "corrupt file\n"; + unlink $fn; + } else { + prcdeb($dir, $fn); + } + } elsif($fn =~ /.deb$/) { + if(chkdeb($fn)) { + prcdeb($dir, $fn); + } else { + print "corrupt file\n"; + unlink $fn; + } + } else { + print "non-debian file\n"; + } + } +} +find(\&prcfile, "$dldir/"); + +# install .debs +if (yesno('y', "\nDo you want to install the files fetched")) { + print "Installing files...\n"; + #Installing pre-dependent package before ! + my (@flds, $package, @filename, $r); + while (@flds = qx(dpkg --predep-package), $? == 0) { + foreach my $field (@flds) { + $field =~ s/\s*\n//; + $package = $field if $field =~ s/^Package: //i; + @filename = split / +/, $field if $field =~ s/^Filename: //i; + } + @filename = map { "$dldir/$_" } @filename; + next if (! @filename); + $r = system('dpkg', '-iB', '--', @filename); + if ($r) { print "DPKG ERROR\n"; $exit = 1; } + } + #Installing other packages after + $r = system('dpkg', '-iGREOB', $dldir); + if($r) { + print "DPKG ERROR\n"; + $exit = 1; + } +} + +sub removeinstalled { + my $fn = $_; + if (-f $fn and $fn ne '.') { + my $dir = '.'; + if (length($File::Find::dir) > length($dldir)) { + $dir = substr($File::Find::dir, length($dldir)+1); + } + if($fn =~ /.deb$/) { + my($pkg, $ver) = getdebinfo($fn); + if(!defined($pkg) || !defined($ver)) { + print "Could not get info for: $dir/$fn\n"; + } else { + if ($curpkgs{$pkg} and dcmpvers($ver, 'le', $curpkgs{$pkg})) { + print "deleting: $dir/$fn\n"; + unlink $fn; + } else { + print "leaving: $dir/$fn\n"; + } + } + } else { + print "non-debian: $dir/$fn\n"; + } + } +} + +# remove .debs that have been installed (query user) +# first need to reprocess status file +if (yesno('y', "\nDo you wish to delete the installed package (.deb) files?")) { + print "Removing installed files...\n"; + %curpkgs = (); + procstatus(); + find(\&removeinstalled, "$dldir/"); +} + +# remove whole ./debian directory if user wants to +if (yesno('n', "\nDo you want to remove $dldir directory?")) { + remove_tree($dldir); +} + +#Store useful md5sums +foreach my $file (keys %md5sums) { + next if -f $file; + delete $md5sums{$file}; +} +file_dump("$methdir/md5sums", Dumper(\%md5sums)); + +exit $exit; diff --git a/dselect/methods/ftp/names b/dselect/methods/ftp/names new file mode 100644 index 0000000..6499279 --- /dev/null +++ b/dselect/methods/ftp/names @@ -0,0 +1 @@ +60 ftp Install using ftp. diff --git a/dselect/methods/ftp/setup.pl b/dselect/methods/ftp/setup.pl new file mode 100755 index 0000000..b9e8e27 --- /dev/null +++ b/dselect/methods/ftp/setup.pl @@ -0,0 +1,177 @@ +#!/usr/bin/perl +# +# Copyright © 1996 Andy Guy <andy@cyteen.org> +# Copyright © 1998 Martin Schulze <joey@infodrom.north.de> +# Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +use strict; +use warnings; + +eval q{ + use Dpkg; # Dummy import to require the presence of Dpkg::*. +}; +if ($@) { + warn "Missing Dpkg modules required by the FTP access method.\n\n"; + exit 1; +} + +use Dselect::Method; +use Dselect::Method::Ftp; + +# deal with arguments +my $vardir = $ARGV[0]; +my $method = $ARGV[1]; +my $option = $ARGV[2]; + +if ($option eq 'manual') { + print "Manual package installation.\n"; + exit 0; +} +#print "vardir: $vardir, method: $method, option: $option\n"; + +#Defaults +my $arch = qx(dpkg --print-architecture); +$arch = 'i386' if $?; +chomp $arch; + +my $logname = qx(whoami); +chomp $logname; +my $host = qx(cat /etc/mailname || dnsdomainname); +chomp $host; + +$CONFIG{dldir} = 'debian'; +$CONFIG{use_auth_proxy} = 0; +$CONFIG{proxyhost} = ''; +$CONFIG{proxylogname} = $logname; +$CONFIG{proxypassword} = ''; + +my $methdir = "$vardir/methods/ftp"; +my $exit = 0; +my $problem = 0; + +if (-f "$methdir/vars") { + read_config("$methdir/vars"); +} + +chdir "$methdir"; +if (! -d 'debian') { + mkdir 'debian', 0755; +} +# get info from user + +$| = 1; + +print <<"EOM"; + +You must supply an ftp site, use of passive mode, username, password, +path to the debian directory,list of distributions you are interested +in and place to download the binary package files to (relative to +/var/lib/dpkg/methods/ftp). You can add as much sites as you like. Later +entries will always override older ones. + +Supply "?" as a password to be asked each time you connect. + +Eg: ftp site: ftp.debian.org + passive: y + username: anonymous + password: $logname\@$host + ftp dir: /debian + distributions: dists/stable/main dists/stable/contrib + download dir: debian + +You may have to use an authenticated FTP proxy in order to reach the +FTP site: + +Eg: use auth proxy: y + proxy: proxy.isp.com + proxy account: $CONFIG{proxylogname} + proxy password: ? +EOM + +if (! $CONFIG{done}) { + view_mirrors() if (yesno('y', 'Would you like to see a list of ftp mirrors')); + add_site('ftp'); +} +edit_config('ftp', $methdir); + +my $ftp; +sub download() { + foreach (@{$CONFIG{site}}) { + $ftp = do_connect(ftpsite => $_->[0], + ftpdir => $_->[1], + passive => $_->[3], + username => $_->[4], + password => $_->[5], + useproxy => $CONFIG{use_auth_proxy}, + proxyhost => $CONFIG{proxyhost}, + proxylogname => $CONFIG{proxylogname}, + proxypassword => $CONFIG{proxypassword}); + + my @dists = @{$_->[2]}; + + foreach my $dist (@dists) { + my $dir = "$dist/binary-$arch"; + print "Checking $dir...\n"; +# if (!$ftp->pasv()) { print $ftp->message . "\n"; die 'error'; } + my @dirlst = $ftp->ls("$dir/"); + my $got_pkgfile = 0; + + foreach my $line (@dirlst) { + if($line =~ /Packages/) { + $got_pkgfile = 1; + } + } + if( !$got_pkgfile) { + print "Warning: Could not find a Packages file in $dir\n", + "This may not be a problem if the directory is a symbolic link\n"; + $problem = 1; + } + } + print "Closing ftp connection...\n"; + $ftp->quit(); + } +} + +# download stuff (protect from ^C) +print "\nUsing FTP to check directories...(stop with ^C)\n\n"; +eval { + local $SIG{INT} = sub { + die "interrupted!\n"; + }; + download(); +}; +if($@) { + $ftp->quit(); + print 'FTP ERROR - '; + if ($@ eq 'connect') { + print "config was untested\n"; + } else { + print "$@\n"; + } + $exit = 1; +}; + +# output new vars file +$CONFIG{done} = 1; +store_config("$methdir/vars"); +chmod 0600, "$methdir/vars"; + +if($exit || $problem) { + print "Press <enter> to continue\n"; + <STDIN>; +} + +exit $exit; diff --git a/dselect/methods/ftp/update.pl b/dselect/methods/ftp/update.pl new file mode 100755 index 0000000..8fcd7b1 --- /dev/null +++ b/dselect/methods/ftp/update.pl @@ -0,0 +1,250 @@ +#!/usr/bin/perl +# +# Copyright © 1996 Andy Guy <andy@cyteen.org> +# Copyright © 1998 Martin Schulze <joey@infodrom.north.de> +# Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +use strict; +use warnings; + +eval q{ + use Dpkg; # Dummy import to require the presence of Dpkg::*. +}; +if ($@) { + warn "Missing Dpkg modules required by the FTP access method.\n\n"; + exit 1; +} + +use Dselect::Method; +use Dselect::Method::Ftp; + +# deal with arguments +my $vardir = $ARGV[0]; +my $method = $ARGV[1]; +my $option = $ARGV[2]; + +if ($option eq 'manual') { + print "Enter package file names or a blank line to finish\n"; + while(1) { + print 'Enter package file name:'; + my $fn = <STDIN>; + chomp $fn; + if ($fn eq '') { + exit 0; + } + if ( -f $fn ) { + system('dpkg', '--merge-avail', $fn); + } else { + print "Could not find $fn, try again\n"; + } + }; +}; + +#print "vardir: $vardir, method: $method, option: $option\n"; + +my $arch = qx(dpkg --print-architecture); +$arch = 'i386' if $?; +chomp $arch; +my $exit = 0; + +# get info from control file +read_config("$vardir/methods/ftp/vars"); + +chdir "$vardir/methods/ftp"; + +print "Getting Packages files...(stop with ^C)\n\n"; + +my @pkgfiles; +my $ftp; +my $packages_modified = 0; + +sub download { +foreach (@{$CONFIG{site}}) { + my $site = $_; + + $ftp = do_connect(ftpsite => $_->[0], + ftpdir => $_->[1], + passive => $_->[3], + username => $_->[4], + password => $_->[5], + useproxy => $CONFIG{use_auth_proxy}, + proxyhost => $CONFIG{proxyhost}, + proxylogname => $CONFIG{proxylogname}, + proxypassword => $CONFIG{proxypassword}); + + my @dists = @{$_->[2]}; + PACKAGE: + foreach my $dist (@dists) { + my $dir = "$dist/binary-$arch"; + my $must_get = 0; + my $newest_pack_date; + + # check existing Packages on remote site + print "\nChecking for Packages file... "; + $newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz"); + if (defined $newest_pack_date) { + print "$dir/Packages.gz\n"; + } else { + $dir = "$dist"; + $newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz"); + if (defined $newest_pack_date) { + print "$dir/Packages.gz\n"; + } else { + print "Couldn't find Packages.gz in $dist/binary-$arch or $dist; ignoring.\n"; + print "Your setup is probably wrong, check the distributions directories,\n"; + print "and try with passive mode enabled/disabled (if you use a proxy/firewall)\n"; + next PACKAGE; + } + } + + # we now have $dir set to point to an existing Packages.gz file + + # check if we already have a Packages file (and get its date) + $dist =~ tr/\//_/; + my $file = "Packages.$site->[0].$dist"; + + # if not + if (! -f $file) { + # must get one +# print "No Packages here; must get it.\n"; + $must_get = 1; + } else { + # else check last modification date + my @pack_stat = stat($file); + if($newest_pack_date > $pack_stat[9]) { +# print "Packages has changed; must get it.\n"; + $must_get = 1; + } elsif ($newest_pack_date < $pack_stat[9]) { + print " Our file is newer than theirs; skipping.\n"; + } else { + print " Already up-to-date; skipping.\n"; + } + } + + if ($must_get) { + -f 'Packages.gz' and unlink 'Packages.gz'; + -f 'Packages' and unlink 'Packages'; + my $size = 0; + + TRY_GET_PACKAGES: + while (1) { + if ($size) { + print ' Continuing '; + } else { + print ' Getting '; + } + print "Packages file from $dir...\n"; + eval { + if ($ftp->get("$dir/Packages.gz", 'Packages.gz', $size)) { + if (system('gunzip', 'Packages.gz')) { + print " Couldn't gunzip Packages.gz, stopped"; + die 'error'; + } + } else { + print " Couldn't get Packages.gz from $dir !!! Stopped."; + die 'error'; + } + }; + if ($@) { + $size = -s 'Packages.gz'; + if (ref($ftp)) { + $ftp->abort(); + $ftp->quit(); + }; + if (yesno ('y', "Transfer failed at $size: retry at once")) { + $ftp = do_connect(ftpsite => $site->[0], + ftpdir => $site->[1], + passive => $site->[3], + username => $site->[4], + password => $site->[5], + useproxy => $CONFIG{use_auth_proxy}, + proxyhost => $CONFIG{proxyhost}, + proxylogname => $CONFIG{proxylogname}, + proxypassword => $CONFIG{proxypassword}); + + if ($newest_pack_date != do_mdtm ($ftp, "$dir/Packages.gz")) { + print ("Packages file has changed !\n"); + $size = 0; + } + next TRY_GET_PACKAGES; + } else { + die 'error'; + } + } + last TRY_GET_PACKAGES; + } + + if (!rename 'Packages', "Packages.$site->[0].$dist") { + print " Couldn't rename Packages to Packages.$site->[0].$dist"; + die 'error'; + } else { + # set local Packages file to same date as the one it mirrors + # to allow comparison to work. + utime $newest_pack_date, $newest_pack_date, "Packages.$site->[0].$dist"; + $packages_modified = 1; + } + } + push @pkgfiles, "Packages.$site->[0].$dist"; + } + $ftp->quit(); + } +} + +eval { + local $SIG{INT} = sub { + die "interrupted!\n"; + }; + download(); +}; +if($@) { + $ftp->quit() if (ref($ftp)); + if($@ =~ /timeout/i) { + print "FTP TIMEOUT\n"; + } else { + print "FTP ERROR - $@\n"; + } + $exit = 1; +}; + +# Don't clear if nothing changed. +if ($packages_modified) { + print <<'EOM'; + +It is a good idea to clear the available list of old packages. +However if you have only downloaded a Package files from non-main +distributions you might not want to do this. + +EOM + if (yesno ('y', 'Do you want to clear available list')) { + print "Clearing...\n"; + if (system('dpkg', '--clear-avail')) { + print 'dpkg --clear-avail failed.'; + die 'error'; + } + } +} + +if (!$packages_modified) { + print "No Packages files was updated.\n"; +} else { + foreach my $file (@pkgfiles) { + if (system('dpkg', '--merge-avail', $file)) { + print "Dpkg merge available failed on $file"; + $exit = 1; + } + } +} +exit $exit; diff --git a/dselect/methods/media/README.media b/dselect/methods/media/README.media new file mode 100644 index 0000000..42be941 --- /dev/null +++ b/dselect/methods/media/README.media @@ -0,0 +1,106 @@ +Installation method for multiple binary media +--------------------------------------------- + + This directory contains a method to be used within dselect in order to + access Debian binary packages stored across multiple binary media + (CDs, DVDs, BDs, or USBs). + +Acquiring package data +--------------------- + + It is possible to access the following binary directories within + «dists/stable»: + + . main + . contrib + . non-free-firmware + . non-free + . local + + The selected method will try to read the «Packages.cd» file from each + of these directories if it is available. + +Identifying the media +---------------------- + + A unique name is associated to each media disc. This name should correspond + with the label on the front of the media disc. The name is also available on + the media disc, so the system can find out which media disc is inserted into + the computer at any time. + +Installing the files +-------------------- + + At the beginning of the installation the “media” method will sort the list + of to-be-installed packages and install them media disc by media disc. If a + different media disc is required the user will be prompted to exchange + the media disc. + +Preparing multiple binary media discs +------------------------------------- + + Since the “media” method needs to know which packages are on which + media disc one cannot use regular «Packages» files. An additional data + field «X-Medium:» is required. The first media disc from the set should + contain all «Packages.cd» files. To be more convenient you should + include the «Packages.cd» files on all media discs. This ensures that + you do not have to start with the first media disc all the time. + + Additionally the package needs to gain information which media disc is + currently used. Thus each media disc contains the file «.disk/info» + which contains the symbolic name for the media disc as specified by + «X-Medium:». + + In order to be able to create the modified «Packages.cd» files, you + have to use the «-M medium» option of dpkg-scanpackages (supported + in dpkg-dev since 1.15.5). + + To split the “main” distribution into two media discs you will need to + create a «Packages.cd» file for each «binary-$arch» directory. + Afterwards you simply append the second one to the first one and + put the resulting «Packages.cd» file into both «binary-$arch» + directories. + +Sample Layout +------------- + + Media disc 1 .disk/info = "Debian GNU/Linux binary-amd64" + dists/stable/main/binary-all/ + binary-amd64/Packages.cd.gz + binary-amd64/net/foo.deb + contrib/binary-amd64/Packages.cd.gz + non-free-firmware/binary-amd64/Packages.cd.gz + non-free/binary-amd64/Packages.cd.gz + + Media disc 2 .disk/info = "Debian GNU/Linux contrib-amd64" + dists/stable/main/binary-amd64/Packages.cd.gz + contrib/binary-all/ + binary-amd64/Packages.cd.gz + binary-amd64/net/foo.deb + non-free-firmware/binary-amd64/Packages.cd.gz + non-free/binary-amd64/Packages.cd.gz + + Media disc 3 .disk/info = "Debian GNU/Linux non-free-amd64" + dists/stable/main/binary-amd64/Packages.cd.gz + contrib/binary-amd64/Packages.cd.gz + non-free-firmware/binary-amd64/Packages.cd.gz + non-free/binary-all/ + binary-amd64/Packages.cd.gz + binary-amd64/net/foo.deb + + To re-generate the Packages file you have to change directory into + «dists/stable/$part» and issue «dpkg-scanpackages» as follows. It is + assumed that you use regular compressed overrides files in + «/pub/debian/indices». + + Media disc 1: dpkg-scanpackages -M "Debian GNU/Linux binary-amd64" \ + binary-amd64 /pub/debian/indices/override.buster.gz \ + dists/stable/ > binary-amd64/Packages + + Media disc 2: dpkg-scanpackages -M "Debian GNU/Linux contrib-amd64" \ + binary-amd64 /pub/debian/indices/override.buster.contrib.gz \ + dists/stable/ > binary-amd64/Packages + + Media disc 3: dpkg-scanpackages -M "Debian GNU/Linux non-free-amd64" \ + binary-amd64 /pub/debian/indices/override.buster.non-free.gz \ + dists/stable/ > binary-amd64/Packages diff --git a/dselect/methods/media/desc.media b/dselect/methods/media/desc.media new file mode 100644 index 0000000..e76022e --- /dev/null +++ b/dselect/methods/media/desc.media @@ -0,0 +1,3 @@ +Installation from a media set containing a Debian distribution. The +media discs may be or not be mounted already and should contain a standard +ISO9660 media filesystem. diff --git a/dselect/methods/media/install.sh b/dselect/methods/media/install.sh new file mode 100755 index 0000000..91e717d --- /dev/null +++ b/dselect/methods/media/install.sh @@ -0,0 +1,282 @@ +#!/bin/sh +# +# Copyright © 1995-1998 Ian Jackson <ijackson@chiark.greenend.org.uk> +# Copyright © 1998 Heiko Schlittermann <hs@schlittermann.de> +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -e +vardir="$1" +method=$2 +option=$3 + +cd "$vardir/methods/$method" + +. ./shvar.$option + +#debug() { echo "DEBUG: $@"; } +debug() { + true +} +iarch=$(dpkg --print-architecture) + +# 1/ mountpoint +# 2/ hierarchy +getdisklabel () { + debug "$1" "$2" + if [ -f $1/.disk/info ]; then + echo -n $(head -1 "$1/.disk/info") + elif [ -f $1$2/.disk/info ]; then + echo -n $(head -1 "$1$2/.disk/info") + else + echo -n 'Non-Debian disc' + fi +} + +xit=1 + +do_umount() { + if [ -n "$umount" ]; then + echo umount "$umount" + #">/dev/null" "2>&1" + fi +} + +do_mount() { + if [ ! -b "$p_blockdev" ]; then + loop=",loop" + fi + + if [ -n "$p_blockdev" ]; then + umount="$p_mountpoint" + echo mount -rt iso9660 -o nosuid,nodev${loop} "$p_blockdev" "$p_mountpoint"\; umount="$p_mountpoint" + fi +} + +trap 'eval $(do_umount); exit $xit' 0 + +eval $(do_mount) + +predep="$vardir/predep-package" +while true; do + thisdisk="$(getdisklabel ${p_mountpoint} ${p_hierbase})" + set +e + dpkg --predep-package >"$predep" + rc=$? + set -e + if test $rc = 1; then + break + fi + test $rc = 0 + + perl -e ' + ($binaryprefix,$predep,$thisdisk) = @ARGV; + open(P, "< $predep") or die "cannot open $predep: $!\n"; + while (<P>) { + s/\s*\n$//; + $package = $_ if s/^Package: //i; + /^X-Medium:\s+(.*)\s*/ and $medium = $1; + @filename = split(/ /,$_) if s/^Filename: //i; + @msdosfilename = split(/ /,$_) if s/^MSDOS-Filename: //i; + } + die "internal error - no package" if length($package) == 0; + die "internal error - no filename" if not @filename; + die "internal error - mismatch >@filename< >@msdosfilename<" + if @filename && @msdosfilename && + @filename != @msdosfilename; + if ($medium && ($medium ne $thisdisk)) { + print " + +This is + $thisdisk +However, $package is expected on disc: + $medium +Please change the discs and press <RETURN>. + +"; + exit(1); + } + @invoke = (); $| =1; + for ($i = 0; $i <= $#filename; $i++) { + $ppart = $i+1; + print "Looking for part $ppart of $package ... "; + if (-f "$binaryprefix$filename[$i]") { + $print = $filename[$i]; + $invoke = "$binaryprefix$filename[$i]"; + } elsif (-f "$binaryprefix$msdosfilename[$i]") { + $print = $msdosfilename[$i]; + $invoke = "$binaryprefix$msdosfilename[$i]"; + } else { + $base = $filename[$i]; $base =~ s,.*/,,; + $msdosbase = $msdosfilename[$i]; $msdosbase =~ s,.*/,,; + $c = open(X, "-|")); + if (not defined $c) { + die "failed to fork for find: $!\n"; + } + if (!$c) { + exec("find", "-L", + length($binaryprefix) ? $binaryprefix : ".", + "-name",$base,"-o","-name",$msdosbase); + die "failed to exec find: $!\n"; + } + while (chop($invoke = <X>)) { last if -f $invoke; } + $print = $invoke; + if (substr($print,0,length($binaryprefix)+1) eq + "$binaryprefix/") { + $print = substr($print,length($binaryprefix)); + } + } + if (!length($invoke)) { + warn " + +Cannot find the appropriate file(s) anywhere needed to install or upgrade +package $package. Expecting version $version or later, as listed in the +Packages file. + +Perhaps the package was downloaded with an unexpected name? In any case, +you must find the file(s) and then either place it with the correct +filename(s) (as listed in the Packages file or in $vardir/available) +and rerun the installation, or upgrade the package by using +\"dpkg --install --auto-deconfigure" by hand. + +"; + exit(1); + } + print "$print\n"; + push(@invoke,$invoke); + } + print "Running dpkg -iB for $package ...\n"; + exec("dpkg","-iB","--",@invoke); + die "failed to exec dpkg: $!\n"; + ' -- "$p_mountpoint$p_hierbase" "$predep" "$thisdisk" +done + +perl -e ' + $SIG{INT} = sub { cd $vardir; unlink <tmp/*>; exit 1; }; + $| = 1; + my ($vardir, $mountpoint, $hierbase, $mount, $umount) = @ARGV; + my $line; + my $AVAIL = "$vardir/methods/media/available"; + my $STATUS = "$vardir/status"; + my %Installed, %Filename, %Medium; + print "Get currently installed package versions..."; + open(IN, "$STATUS") or die "cannot open $STATUS: $!\n"; + $line = 0; + { local $/ = ""; + while (<IN>) { + my %status; + my @pstat; + $line++ % 20 or print "."; + s/\n\s+/ /g; + %status = ("", split /^(\S*?):\s*/m, $_); + map { chomp $status{$_}; $status{$_} =~ s/^\s*(.*?)\s*$/$1/;} keys %status; + @pstat = split(/ /, $status{Status}); + next unless ($pstat[0] eq "install"); + if ($pstat[2] eq "config-files" || $pstat[2] eq "not-installed") { + $Installed{$status{Package}} = "0.0"; + } else { + $Installed{$status{Package}} = $status{Version} || "" ; + } + }; } + print "\nGot ", scalar keys %Installed, " installed/pending packages\n"; + print "Scanning available packages..."; + $line = 0; + open(IN, "$AVAIL") or die("Cannot open $AVAIL: $!\n"); + { local $/ = ""; + while (<IN>) { + my $updated; + $line++ % 20 or print "."; + + s/\n\s+/ /g; + %avail = ("", split /^(\S*?):\s*/m, $_); + map { chomp $avail{$_}; $avail{$_} =~ s/^\s*(.*?)\s*$/$1/;} keys %avail; + + next unless defined $Installed{$avail{Package}}; + + system "dpkg", "--compare-versions", $avail{Version}, "gt", $Installed{$avail{Package}}; + $updated = ($? == 0); + #print "$avail{Package}(" . ($updated ? "+" : "=") . ") "; + $updated or next; + + $Filename{$avail{Package}} = $avail{Filename}; + + next unless defined $avail{"X-Medium"}; + ${Medium{$avail{"X-Medium"}}} or ${Medium{$avail{"X-Medium"}}} = []; + push @{${Medium{$avail{"X-Medium"}}}}, $avail{Package}; + }; }; + print "\n"; + + if (@_ = keys(%Medium)) { + print "You will need the following distribution disc(s):\n", + join (", ", @_), "\n"; + } + + foreach $need (sort @_) { + if (-r "$mountpoint/.disk/info") { + open(IN, "$mountpoint/.disk/info") or die("$mountpoint/.disk/info: $!\n"); + } else { + open(IN, "$mountpoint/$hierbase/.disk/info") or die("$mountpoint/$hierbase/.disk/info: $!\n"); + } + $disk = <IN>; chomp $disk; close(IN); + + print "Processing disc\n $need\n"; + + while ($disk ne $need) { + print "Wrong disc. This is disc\n $disk\n"; + print "However, the needed disc is\n $need\n"; + print "Please change the discs and press <RETURN>\n"; + system($umount); + <STDIN>; + system($mount); + $? and warn("cannot mount $mount\n"); + } continue { + if (-r "$mountpoint/.disk/info") { + open(IN, "$mountpoint/.disk/info") or die("$mountpoint/.disk/info: $!\n"); + } else { + open(IN, "$mountpoint/$hierbase/.disk/info") or die("$mountpoint/$hierbase/.disk/info: $!\n"); + } + $disk = <IN>; chomp $disk; close(IN); + } + + -d "tmp" || mkdir "tmp", 0755 or die("Cannot mkdir tmp: $!\n"); + unlink <tmp/*>; + + print "creating symlinks...\n"; + foreach (@{$Medium{$need}}) { + ($basename = $Filename{$_}) =~ s/.*\///; + symlink "$mountpoint/$hierbase/$Filename{$_}", + "tmp/$basename"; + } + chdir "tmp" or die "cannot chdir to tmp: $!\n"; + system "dpkg", "-iGROEB", "."; + unlink <*>; + chdir ".."; + + if ($?) { + print "\nThe dpkg run produced errors. Please state whether to\n", + "continue with the next media disc. [Y/n]: "; + $answer = <STDIN>; + exit 1 if $answer =~ /^n/i; + $ouch = $?; + } + } + + exit $ouch; + +' "$vardir" "$p_mountpoint" "$p_hierbase" "$(do_mount)" "$(do_umount)" + +echo -n 'Installation OK. Hit RETURN. ' +read response + +xit=0 diff --git a/dselect/methods/media/names b/dselect/methods/media/names new file mode 100644 index 0000000..1d8879d --- /dev/null +++ b/dselect/methods/media/names @@ -0,0 +1 @@ +31 media Install from a media set (CDs, DVDs, BDs, USBs). diff --git a/dselect/methods/media/setup.sh b/dselect/methods/media/setup.sh new file mode 100755 index 0000000..5bf3642 --- /dev/null +++ b/dselect/methods/media/setup.sh @@ -0,0 +1,489 @@ +#!/bin/sh +# +# Copyright © 1995-1998 Ian Jackson <ijackson@chiark.greenend.org.uk> +# Copyright © 1998 Heiko Schlittermann <hs@schlittermann.de> +# Copyright © 1998-1999 Martin Schulze <joey@infodrom.north.de> +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -e +vardir="$1" +method=$2 +option=$3 + +test -d "$vardir/methods/$method" || mkdir "$vardir/methods/$method" +cd "$vardir/methods/$method" +tp="$(mktemp --tmpdir $method.XXXXXXXXXX)" + +iarch=$(dpkg --print-architecture) +dist=stable + +xit=1 +trap ' + rm -f $tp.? + if [ -n "$umount" ]; then + umount "$umount" >/dev/null 2>&1 + fi + exit $xit +' 0 + +if ls -d "$tp.?" >/dev/null 2>&1; then + rm $tp.? +fi + +#debug() { echo "DEBUG: $@"; } +debug() { + true +} +ismulti() { + debug $1 $2; test -e "$1/.disk/info" || test -e "$1$2/.disk/info" +} + +# 1/ mountpoint +# 2/ hierarchy +getdisklabel () { + debug "$1" "$2" + if [ -f $1/.disk/info ]; then + echo -n $(head -1 "$1/.disk/info") + elif [ -f $1$2/.disk/info ]; then + echo -n $(head -1 "$1$2/.disk/info") + else + echo -n 'Non-Debian disc' + fi +} + +yesno () { + while true; do + echo -n "$2 [$1] " + read response + if [ -z "$response" ]; then + response="$1" + fi + case "$response" in + [Nn]*) + yesno=no + return + ;; + [Yy]*) + yesno=yes + return + ;; + esac + done +} + +getblockdev () { + mountpoint="$vardir/methods/mnt" + if [ -z "$defaultdevice" ]; then + defaultdevice="$newdefaultdevice" + elif [ "$defaultdevice" != "$newdefaultdevice" ]; then + echo "Last time you specified installation from $defaultdevice." + fi + promptstring="$1" + while [ -z "$blockdevice" ]; do + echo -n "$promptstring [$defaultdevice]: " + read response + if [ -z "$response" ]; then + response="$defaultdevice" + fi + if [ ! -b "$response" ]; then + echo "$response is not a block device - will try as loopback." + loop=",loop" + fi + tryblockdevice="$response" + fstype=iso9660 + umount="$mountpoint" + if mount -rt "$fstype" -o nosuid,nodev$loop "$tryblockdevice" "$mountpoint" + then + echo + blockdevice="$tryblockdevice" + else + umount="" + echo "Unable to mount $tryblockdevice on $mountpoint, type $fstype." + fi + done +} + +outputparam () { + echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3 +} + +## MAIN +intrkey="$(stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p')" +echo " +If you make a mistake, use the interrupt key ($intrkey) to abort. +" + +# State variables, “best first” +# {main,ctb,nf,lcl}_{packages,binary} +# Empty before we've found them or if they're not available, +# set to the relevant bit under mountpoint otherwise. +# hierbase +# A directory containing a Debian FTP site mirror tree. +# mountpoint +# The mountpoint for the filesystem containing the stuff +# empty or unset if we don't know yet, or if we haven't mounted anything; +# may also be empty if ‘directory’ was set. +# blockdevice +# The actual block device to mount. +# fstype +# The filesystem type to use. +# defaultdevice +# The default block device to mount. + +p_usedevel=no +if [ -f shvar.$option ]; then + . ./shvar.$option + defaultdevice="$p_blockdev" + usedevel="$p_usedevel" +fi + +mount >$tp.m +sed -n 's/ ([^)]*)$//; s/^[^ ]* on //; s/ type iso9660$//p' <$tp.m >$tp.l +ncdroms=$(wc -l <$tp.l) +if [ $ncdroms -gt 1 ]; then + response="" + while [ -z "$response" ]; do + echo 'Several media discs (ISO9660 filesystems) are mounted:' + grep -E 'type iso9660 \([^)]*\)$' <$tp.m | nl + echo -n "Is it any of these ? Type a number, or 'n' for none. " + read response + response="$(echo "$response" | sed -e 's/[ ]*$//')" + if expr "$response" : '[0-9][0-9]*$' >/dev/null && \ + [ $response -ge 1 -a $response -le $ncdroms ]; then + mountpoint="$(sed -n $response'p' <$tp.l)" + echo + elif expr "$response" : '[Nn]' >/dev/null; then + mountpoint="" + else + response="" + fi + done +elif [ $ncdroms = 1 ]; then + mountpoint="$(cat $tp.l)" + perl -ne 'print if s/ type iso9660 \([^)]*\)$// && s/ on .*$//;' \ + <$tp.m >$tp.d + blockdevice="$(cat $tp.d)" + yesno yes \ + "Found a media disc: $blockdevice, mounted on $mountpoint. Is it the right one?" + if [ $yesno = no ]; then + echo 'Unmounting it ...' + umount="$mountpoint" + while true; do + echo -n 'Please insert the right disc, and hit return: ' + read response + if mount -rt iso9660 -o nosuid,nodev \ + "$blockdevice" "$mountpoint"; then + echo + break + fi + done + fi +fi +if [ -z "$mountpoint" ]; then + if [ -b /dev/cdrom ]; then + echo 'Found that /dev/cdrom exists and is a block device.' + newdefaultdevice=/dev/cdrom + fi + getblockdev 'Insert the media and enter the block device name' +fi + +if [ -n "$mountpoint" ]; then + # We must have $mountpoint + echo \ +'All directory names should be entered relative to the root of the media disc. +' +fi + +# now try to get the users idea where the debian +# hierarchy start below the mointpoint + +debug "mountpoint: $mountpoint" +while true; do + if ismulti "${mountpoint}" "${hierbase}"; then + multi=yes + fi + + echo \ +"Need to know where on the media disc the top level of the Debian +distribution is - this will usually contain the 'dists' directory. + +If the media disc is badly organized and doesn't have a straightforward copy of +the distribution you may answer 'none' and the needed parts will be prompted +individually." + + defhierbase=none + if [ -n "$p_hierbase" ]; then + if [ -d "$mountpoint/$p_hierbase/dists/$dist/main/binary-$iarch" \ + -o -n "$multi" ]; then + echo "Last time you said '$p_hierbase', and that looks plausible." + defhierbase="$p_hierbase" + else + echo " +Last time you said '$p_hierbase', but that doesn't look plausible, +since '$p_hierbase/dists/$dist/main/binary-$iarch' doesn't seem to exist. +And it does not appear that you are using a multiple media set." + fi + fi + + # at this point defhierbase is set if it looks plausible + # if ‘none’ was entered, we assume a media with a debian/ directory + + if [ none = "$defhierbase" -a -d "$mountpoint/debian/dists/$dist/main/binary-$iarch" ] + then + echo "'/debian' exists and looks plausible, so that's the default." + defhierbase=/debian + fi + + echo -n "Distribution top level ? [$defhierbase] " + read response + if [ -z "$response" ]; then + response="$defhierbase" + fi + if [ none = "$response" ]; then + hierbase="" + break + elif ismulti "$mountpoint" "$response" && [ -z "$multi" ]; then + multi=yes + fi + + if ! [ -d "$mountpoint/$response/dists/$dist/main/binary-$iarch" \ + -o -n "$multi" ]; then + echo \ +"Neither $response/dists/$dist/main/binary-$iarch does not exist, +nor are you using a multiple media set" + break + fi + + hierbase="$(echo "$response" | sed -e 's:/$::; s:^/*:/:; s:/\+:/:g;')" + debug "hierbase: [$hierbase]" + + if [ -n "$multi" ]; then + disklabel=$(getdisklabel "$mountpoint" "/$response") + echo "Ok, this is disc" + echo " $disklabel" + #echo "Updating multiple media contents file cache ..." + #multi_contentsfile="${mountpoint}/${response}/.disk/contents.gz" + #zcat "$multi_contentsfile" > disk-contents.$option + fi + + break; +done + +distribution=$dist +if [ -n "$hierbase" ]; then + if [ -d "$mountpoint/$hierbase/dists/unstable/binary-$iarch" ]; then + echo \ +' +Both a stable released distribution and a work-in-progress +development tree are available for installation. Would you like to +use the unreleased development tree (this is only recommended for +experts who like to live dangerously and want to help with testing) ?' + yesno "$p_usedevel" 'Use unreleased development distribution ?' + usedevel="$yesno" + if [ "$usedevel" = yes ]; then + distribution=development + fi + else + usedevel=no + fi + echo +fi + +case "$hierbase" in +/* ) + ;; +'' ) + ;; +* ) + hierbase="/$hierbase" + ;; +esac + +check_binary () { + # args: area-in-messages directory + debug "check_binary($@)" + + if [ ! -d "${mountpoint}$2" -a -z "$multi" ]; then + echo "'$2' does not exist." + return + fi + +# In this special case it is ok for a sub-distribution to not contain any +# .deb files. Each media should contain all Packages.cd files but does not +# need to contain the .deb files. +# +# if ! { find -L "$mountpoint$2" -name '*.deb' -print \ +# | head -1 | grep . ; } >/dev/null 2>&1 && [ -z "$multi" ]; +# then +# echo "'$2' does not contain any *.deb packages." +# return +# fi + + this_binary="$2" + echo -n "Using '$this_binary' as $1 binary directory" + + if [ -n "$multi" ]; then + this_disk=$(getdisklabel ${mountpoint} "/$hierbase") + echo " from disc" + echo " '$this_disk'" + else + echo "" + fi +} + +find_area () { + # args: area-in-messages area-in-vars subdirectory-in-hier + # last-time-binary last-time-packages + debug "find_area($@)" + this_binary='' + this_packages='' + this_disk='' + if [ -n "$hierbase" ]; then + check_binary $1 $(echo "$hierbase/dists/$3/$1/binary-$iarch" | sed 's:/\+:/:g') + debug "THIS_BINARY $this_binary" + fi + if [ $2 = nf -a -z "$this_binary" ]; then + echo " +Note: most media distributions of Debian do not include programs available +in the 'non-free' directory of the distribution site. +This is because these programs are under licenses that do not allow source +modification or prevent distribution for profit on a media, or other +restrictions that make them not free software. +If you wish to install these programs you will have to get them from an +alternative source." + fi + while [ -z "$this_binary" ]; do + defaultbinary="$4" + echo " +Which directory contains the *.deb packages from the $1 distribution +area (this directory is named '$3/binary' on the distribution site) ? +Say 'none' if this area is not available." + if [ $2 != main -a -z "$defaultbinary" ]; then + defaultbinary=none + fi + echo -n \ +"Enter _$1_ binary directory. [$4] + ? " + read response + if [ -z "$response" -a -n "$defaultbinary" ]; then + response="$defaultbinary" + fi + if [ none = "$response" ]; then + break + fi + case "$response" in + '' | none) + continue + ;; + esac + check_binary $1 "$(echo "$response" | sed -e 's:/$::; s:^/*:/:')" + done + if [ -n "$this_binary" ]; then + if [ "$multi" = "yes" ]; then + for f in Packages.cd.gz packages.cd.gz Packages.cd packages.cd; do + if [ -f "$mountpoint/$this_binary/$f" ]; then + this_packages="$this_binary/$f" + echo "Using '$this_packages' for $1." + break + fi + done + elif [ -f "${mountpoint}${hierbase}/.disk/packages/$1/Packages.gz" ]; then + this_packages=$(echo "${hierbase}/.disk/packages/$1/Packages.gz"|sed 's:/\+:/:g') + echo "Using '${this_packages}' for $1." + fi + while [ -z "$this_packages" ]; do + echo -n " +Cannot find the $1 'Packages.cd' file. The information in the +'Packages.cd' file is important for package selection during new +installations, and is very useful for upgrades. + +If you overlooked it when downloading you should do get it now and +return to this installation procedure when you have done so: you will +find one Packages.cd file and one Packages.cd.gz file -- either will do -- +in the 'binary' subdirectory of each area on the FTP sites and +media discs. Alternatively (and this will be rather slow) the packages in +the distribution area can be scanned - say 'scan' if you want to do so. + +You need a separate Packages.cd file from each of the distribution areas +you wish to install. + +Where is the _$1_ 'Packages.cd' file (if none is available, say 'none') +[$5] + ? " + read response + if [ -z "$response" -a -n "$5" ]; then + response="$5" + fi + case "$response" in + '') + break + ;; + none) + break + ;; + scan) + this_packages=scan + ;; + /*) + this_packages="$response" + ;; + *) + this_packages="/$response" + ;; + esac + done + fi + eval $2'_binary="$this_binary"' + eval $2'_packages="$this_packages"' + eval $2'_disk="$this_disk"' +} + +find_area main main "$distribution" "$p_main_binary" "$p_main_packages" +find_area contrib ctb "$distribution" "$p_ctb_binary" "$p_ctb_packages" +find_area non-free-firmware nff "$distribution" "$p_nff_binary" "$p_nff_packages" +find_area non-free nf "$distribution" "$p_nf_binary" "$p_nf_packages" +find_area local lcl local "$p_lcl_binary" "$p_lcl_packages" + +echo -n ' +Hit RETURN to continue. ' +read response + +exec 3>shvar.$option.new + +outputparam p_blockdev "$blockdevice" +outputparam p_fstype "$fstype" +outputparam p_mountpoint "$mountpoint" +outputparam p_hierbase "$hierbase" +outputparam p_usedevel "$usedevel" +outputparam p_main_packages "$main_packages" +outputparam p_main_binary "$main_binary" +outputparam p_main_disk "$main_disk" +outputparam p_ctb_packages "$ctb_packages" +outputparam p_ctb_binary "$ctb_binary" +outputparam p_ctb_disk "$ctb_disk" +outputparam p_nff_packages "$nff_packages" +outputparam p_nff_binary "$nff_binary" +outputparam p_nff_disk "$nff_disk" +outputparam p_nf_packages "$nf_packages" +outputparam p_nf_binary "$nf_binary" +outputparam p_nf_disk "$nf_disk" +outputparam p_lcl_packages "$lcl_packages" +outputparam p_lcl_binary "$lcl_binary" +outputparam p_multi "$multi" +outputparam p_multi_contentsfile "$multi_contentsfile" + +mv shvar.$option.new shvar.$option + +xit=0 diff --git a/dselect/methods/media/update.sh b/dselect/methods/media/update.sh new file mode 100755 index 0000000..f0a703f --- /dev/null +++ b/dselect/methods/media/update.sh @@ -0,0 +1,121 @@ +#!/bin/sh +# +# Copyright © 1995-1998 Ian Jackson <ijackson@chiark.greenend.org.uk> +# Copyright © 1998 Heiko Schlittermann <hs@schlittermann.de> +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +set -e +vardir="$1" +method=$2 +option=$3 +iarch=$(dpkg --print-architecture) + +cd "$vardir/methods/$method" + +. ./shvar.$option + +#debug() { echo "DEBUG: $@"; } +debug() { + true +} + +packages=0 +for f in main ctb nf lcl; do + eval 'this_packages=$p_'$f'_packages' + + if [ -n "$this_packages" ]; then + packages=1 + fi +done + +if [ $packages eq 0 ]; then + echo ' +No Packages files available, cannot update available packages list. +Hit RETURN to continue. ' + read response + exit 0 +fi + +xit=1 +trap ' + for area in main ctb nf lcl; do + rm -f packages-$area + done + if [ -n "$umount" ]; then + umount "$umount" >/dev/null 2>&1 + fi + exit $xit +' 0 + +if [ ! -b "$p_blockdev" ]; then + loop=",loop" +fi + +if [ -n "$p_blockdev" ]; then + umount="$p_mountpoint" + mount -rt "$p_fstype" -o nosuid,nodev${loop} "$p_blockdev" "$p_mountpoint" +fi + +updatetype=update + +if [ -z "$p_multi" ]; then + exit 1 +fi + +for f in main ctb nf lcl; do + eval 'this_packages=$p_'$f'_packages' + case "$this_packages" in + '') + continue + ;; + scan) + eval 'this_binary=$p_'$f'_binary' + if [ -z "$this_binary" ]; then + continue + fi + if [ "$updatetype" = update ]; then + dpkg --clear-avail + updatetype=merge + fi + echo Running dpkg --record-avail -R "$p_mountpoint$this_binary" + dpkg --record-avail -R "$p_mountpoint$this_binary" + ;; + *) + packagesfile="$p_mountpoint$this_packages" + case "$packagesfile" in + *.gz) + echo -n "Uncompressing $packagesfile ... " + zcat <"$packagesfile" >packages-$f + echo done. + dpkg --$updatetype-avail packages-$f + updatetype=merge + ;; + '') + ;; + *) + dpkg --$updatetype-avail "$packagesfile" + updatetype=merge + ;; + esac + ;; + esac +done + +cp -f $vardir/available $vardir/methods/$method + +echo -n 'Update OK. Hit RETURN. ' +read response + +xit=0 |