summaryrefslogtreecommitdiffstats
path: root/perl-install/common.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/common.pm')
-rw-r--r--perl-install/common.pm409
1 files changed, 409 insertions, 0 deletions
diff --git a/perl-install/common.pm b/perl-install/common.pm
new file mode 100644
index 000000000..eb8d669d7
--- /dev/null
+++ b/perl-install/common.pm
@@ -0,0 +1,409 @@
+package common; # $Id: common.pm 149989 2007-03-30 09:35:46Z pixel $
+
+use MDK::Common;
+use diagnostics;
+use strict;
+BEGIN { eval { require Locale::gettext } } #- allow common.pm to be used in drakxtools-backend without perl-Locale-gettext
+
+use log;
+use run_program;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw($SECTORSIZE N P N_ check_for_xserver files_exist formatTime formatXiB makedev mandrake_release removeXiBSuffix require_root_capability setVirtual set_alternative set_l10n_sort set_permissions translate unmakedev);
+
+# perl_checker: RE-EXPORT-ALL
+push @EXPORT, @MDK::Common::EXPORT;
+
+
+$::prefix ||= ""; # no warning
+
+#-#####################################################################################
+#- Globals
+#-#####################################################################################
+our $SECTORSIZE = 512;
+
+#-#####################################################################################
+#- Functions
+#-#####################################################################################
+
+sub P {
+ my ($s_singular, $s_plural, $nb, @para) = @_;
+ sprintf(translate($s_singular, $s_plural, $nb), @para);
+}
+
+sub N {
+ my ($s, @para) = @_;
+ sprintf(translate($s), @para);
+}
+sub N_ { $_[0] }
+
+
+sub makedev { ($_[0] << 8) | $_[1] }
+sub unmakedev { $_[0] >> 8, $_[0] & 0xff }
+
+sub translate_real {
+ my ($s, $o_plural, $o_nb) = @_;
+ $s or return '';
+ foreach (@::textdomains, 'libDrakX') {
+ my $s2;
+ if ($o_nb) {
+ $s2 = Locale::gettext::dngettext($_, $s, $o_plural, $o_nb);
+ } else {
+ $s2 = Locale::gettext::dgettext($_, $s);
+ }
+ # when utf8 pragma is in use, Locale::gettext() returns an utf8 string not tagged as such:
+ c::set_tagged_utf8($s2) if !utf8::is_utf8($s2) && utf8::is_utf8($s);
+ return $s2 if $s ne $s2;
+ }
+ $s;
+}
+
+sub remove_translate_context {
+ my ($s) = @_;
+ #- translation with context, kde-like
+ $s =~ s/^_:.*\n//;
+ $s;
+}
+
+sub translate {
+ my $s = translate_real(@_);
+ $::one_message_has_been_translated ||= join(':', (caller(1))[1,2]); #- see mygtk2.pm
+ remove_translate_context($s);
+}
+
+sub from_utf8 {
+ my ($s) = @_;
+ Locale::gettext::iconv($s, "utf-8", undef); #- undef = locale charmap = nl_langinfo(CODESET)
+}
+sub to_utf8 {
+ my ($s) = @_;
+ Locale::gettext::iconv($s, undef, "utf-8"); #- undef = locale charmap = nl_langinfo(CODESET)
+}
+
+#- This is needed because text printed by Gtk2 will always be encoded
+#- in UTF-8;
+#- we first check if LC_ALL is defined, because if it is, changing
+#- only LC_COLLATE will have no effect.
+sub set_l10n_sort() {
+ my $collation_locale = $ENV{LC_ALL};
+ if (!$collation_locale) {
+ $collation_locale = c::setlocale(c::LC_COLLATE());
+ $collation_locale =~ /UTF-8/ or c::setlocale(c::LC_COLLATE(), "$collation_locale.UTF-8");
+ }
+}
+
+
+sub setVirtual {
+ my ($vt_number) = @_;
+ my $vt = '';
+ sysopen(my $C, "/dev/console", 2) or die "failed to open /dev/console: $!";
+ ioctl($C, c::VT_GETSTATE(), $vt) &&
+ ioctl($C, c::VT_ACTIVATE(), $vt_number) &&
+ ioctl($C, c::VT_WAITACTIVE(), $vt_number) or die "setVirtual failed";
+ unpack "S", $vt;
+}
+
+sub nonblock {
+ my ($F) = @_;
+ fcntl($F, c::F_SETFL(), fcntl($F, c::F_GETFL(), 0) | c::O_NONBLOCK()) or die "can not fcntl F_SETFL: $!";
+}
+
+sub removeXiBSuffix {
+ local $_ = shift;
+
+ /(\d+)\s*kB?$/i and return $1 * 1024;
+ /(\d+)\s*MB?$/i and return $1 * 1024 * 1024;
+ /(\d+)\s*GB?$/i and return $1 * 1024 * 1024 * 1024;
+ /(\d+)\s*TB?$/i and return $1 * 1024 * 1024 * 1024 * 1024;
+ $_;
+}
+sub formatXiB {
+ my ($newnb, $o_newbase) = @_;
+ my $newbase = $o_newbase || 1;
+ my ($nb, $base);
+ my $decr = sub {
+ ($nb, $base) = ($newnb, $newbase);
+ $base >= 1024 ? ($newbase = $base / 1024) : ($newnb = $nb / 1024);
+ };
+ foreach (N("B"), N("KB"), N("MB"), N("GB")) {
+ $decr->();
+ if ($newnb < 1 && $newnb * $newbase < 1) {
+ my $v = $nb * $base;
+ my $s = $v < 10 && int(10 * $v - 10 * int($v));
+ return int($v) . ($s ? ".$s" : '') . $_;
+ }
+ }
+ int($newnb * $newbase) . N("TB");
+}
+
+sub formatTime {
+ my ($s, $m, $h) = gmtime($_[0]);
+ if ($h) {
+ sprintf "%02d:%02d", $h, $m;
+ } elsif ($m > 1) {
+ N("%d minutes", $m);
+ } elsif ($m == 1) {
+ N("1 minute");
+ } else {
+ N("%d seconds", $s);
+ }
+}
+
+sub expand_symlinks_but_simple {
+ my ($f) = @_;
+ my $link = readlink($f);
+ my $f2 = expand_symlinks($f);
+ if ($link && $link !~ m|/|) {
+ # put back the last simple symlink
+ $f2 =~ s|\Q$link\E$|basename($f)|e;
+ }
+ $f2;
+}
+
+sub sync { &MDK::Common::System::sync }
+
+BEGIN { undef *formatError }
+sub formatError {
+ my ($err) = @_;
+ ref($err) eq 'SCALAR' and $err = $$err;
+ log::l("error: $err");
+ &MDK::Common::String::formatError($err);
+}
+
+sub group_by(&@) {
+ my $f = shift;
+ @_ or return;
+ my $e = shift;
+ my @l = my $last_l = [$e];
+ foreach (@_) {
+ if ($f->($e, $_)) {
+ push @$last_l, $_;
+ } else {
+ push @l, $last_l = [$_];
+ $e = $_;
+ }
+ }
+ @l;
+}
+
+# Group the list by n. Returns a reference of lists of length n
+sub group_n_lm {
+ my $n = shift;
+ my @l;
+ push @l, [ splice(@_, 0, $n) ] while @_;
+ @l;
+}
+
+sub join_lines {
+ my @l;
+ my $s;
+ foreach (@_) {
+ if (/^\s/) {
+ $s .= $_;
+ } else {
+ push @l, $s if $s;
+ $s = $_;
+ }
+ }
+ @l, if_($s, $s);
+}
+
+
+sub set_alternative {
+ my ($command, $executable) = @_;
+
+ #- check the existance of $executable as an alternative for $command
+ #- (is this needed???)
+ run_program::rooted_get_stdout($::prefix, 'update-alternatives', '--display', $command) =~ /^\Q$executable /m or return;
+
+ #- this does not handle relative symlink, but neither does update-alternatives ;p
+ symlinkf $executable, "$::prefix/etc/alternatives/$command";
+}
+
+sub files_exist { and_(map { -f "$::prefix$_" } @_) }
+
+sub open_file {
+ my ($file) = @_;
+ my $F;
+ open($F, $file) ? $F : do { log::l("Can not open $file: $!"); undef };
+}
+
+
+sub secured_file {
+ my ($f) = @_;
+ c::is_secure_file($f) or die "can not ensure a safe $f";
+ $f;
+}
+
+sub chown_ {
+ my ($b_recursive, $name, $group, @files) = @_;
+
+ my ($uid, $gid) = (getpwnam($name) || $name, getgrnam($group) || $group);
+
+ require POSIX;
+ my $chown; $chown = sub {
+ foreach (@_) {
+ POSIX::lchown($uid, $gid, $_) or die "chown of file $_ failed: $!\n";
+ ! -l $_ && -d $_ && $b_recursive and &$chown(glob_($_));
+ }
+ };
+ $chown->(@files);
+}
+
+
+sub set_permissions {
+ my ($file, $perms, $o_owner, $o_group) = @_;
+ # We only need to set the permissions during installation to be able to
+ # print test pages. After installation udev does the business automatically.
+ return 1 unless $::isInstall;
+ if ($o_owner || $o_group) {
+ $o_owner ||= (lstat($file))[4];
+ $o_group ||= (lstat($file))[5];
+ chown_(0, $o_owner, $o_group, $file);
+ }
+ chmod(oct($perms), $file) or die "chmod of file $file failed: $!\n";
+}
+
+sub release_file {
+ my ($o_dir) = @_;
+ my @names = ('mandrakelinux-release', 'mandrake-release', 'conectiva-release', 'release', 'redhat-release');
+ find { -r "$o_dir$_" } (
+ (map { "/root/drakx/$_.upgrading" } @names),
+ (map { "/etc/$_" } @names),
+ );
+}
+
+sub parse_LDAP_namespace_structure {
+ my ($s) = @_;
+ my %h = map { if_(/(.*?)=(.*)/, $1 => $2) } split(',', $s);
+ \%h;
+}
+
+sub mandrake_release {
+ my ($o_dir) = @_;
+ my $f = release_file($o_dir);
+ $f && chomp_(cat_("$o_dir$f"));
+}
+
+sub wrap_command_for_root {
+ my ($name, @args) = @_;
+ ([ 'consolehelper', $name ], @args);
+}
+
+sub require_root_capability() {
+ return if $::testing || !$>; # we're already root
+
+ my ($command, @args) = wrap_command_for_root($0, @ARGV);
+ exec { $command->[0] } $command->[1], @args or die N("command %s missing", $command->[0]);
+
+ # still not root ?
+ die "you must be root to run this program" if $>;
+}
+
+sub check_for_xserver() {
+ if (!defined $::xtest) {
+ $::xtest = 0;
+ eval {
+ require xf86misc::main;
+ $::xtest = xf86misc::main::Xtest($ENV{DISPLAY});
+ } if $ENV{DISPLAY};
+ }
+ return $::xtest;
+}
+
+#- special unpack
+#- - returning an array refs for each element like "s10"
+#- - handling things like s10* at the end of the format
+sub unpack_with_refs {
+ my ($format, $s) = @_;
+ my $initial_format = $format;
+ my @r;
+ while ($format =~ s/\s*(\w(\d*))(\*?)\s*//) {
+ my ($sub_format, $nb, $many) = ($1, $2, $3);
+ $many && $format and internal_error("bad * in the middle of format in $initial_format");
+
+ my $done = $many && !length($s);
+ while (!$done) {
+ my @l = unpack("$sub_format a*", $s);
+ $s = pop @l;
+ push @r, $nb ? \@l : @l;
+ $done = !$many || !length($s);
+ }
+ }
+ @r;
+}
+
+#- used in userdrake and mdkonline
+sub md5file {
+ require Digest::MD5;
+ my @md5 = map {
+ my $sum;
+ if (open(my $FILE, $_)) {
+ binmode($FILE);
+ $sum = Digest::MD5->new->addfile($FILE)->hexdigest;
+ close($FILE);
+ }
+ $sum;
+ } @_;
+ return wantarray() ? @md5 : $md5[0];
+}
+
+sub load_modules_from_base {
+ my ($base) = @_;
+ $base =~ s|::|/|g;
+ my $base_file = $base . ".pm";
+ require $base_file;
+ my ($inc_path) = substr($INC{$base_file}, 0, -length($base_file));
+ my @files = map { substr($_, length($inc_path)) } glob_($inc_path . $base . '/*.pm');
+ require $_ foreach @files;
+ #- return the matching modules list
+ map { local $_ = $_; s|/|::|g; s|\.pm$||g; $_ } @files;
+}
+
+sub get_alternatives {
+ my ($name) = @_;
+
+ my $dir = '/var/lib/rpm/alternatives';
+ my ($state, $main_link, @l) = chomp_(cat_("$dir/$name")) or return;
+ my @slaves;
+ while (@l && $l[0] ne '') {
+ my ($name, $link) = splice(@l, 0, 2);
+ push @slaves, { name => $name, link => $link };
+ }
+ shift @l; #- empty line
+ my @alternatives;
+ while (@l && $l[0] ne '') {
+ my ($file, $weight, @slave_files) = splice(@l, 0, 2 + @slaves);
+
+ push @alternatives, { file => $file, weight => $weight, slave_files => \@slave_files };
+ }
+ { name => $name, link => $main_link, state => $state, slaves => \@slaves, alternatives => \@alternatives };
+}
+
+sub symlinkf_update_alternatives {
+ my ($name, $wanted_file) = @_;
+ my $conf = get_alternatives($name);
+ my $chosen = find { $_->{file} eq $wanted_file } @{$conf->{alternatives}} or return;
+ symlinkf("/etc/alternatives/$name", $::prefix . $conf->{link});
+ symlinkf($wanted_file, "$::prefix/etc/alternatives/$name");
+ mapn {
+ my ($slave, $file) = @_;
+ if ($file) {
+ symlinkf("/etc/alternatives/$slave->{name}", $::prefix . $slave->{link});
+ symlinkf($file, "$::prefix/etc/alternatives/$slave->{name}");
+ } else {
+ unlink $::prefix . $slave->{link};
+ unlink "$::prefix/etc/alternatives/$slave->{name}";
+ }
+ } $conf->{slaves}, $chosen->{slave_files};
+}
+
+sub update_gnomekderc_no_create {
+ my ($file, $category, %subst_) = @_;
+ if (-e $file) {
+ update_gnomekderc($file, $category, %subst_);
+ }
+}
+
+1;