X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=src%2FPVE%2FTools.pm;h=1fe7f4c8ae12e49515d3d27072980f9587cc55d8;hb=6d46baf63a878e30e7b56e72dc62be9774a9a285;hp=82d598e5bfc614eaa2b6153a785e9b48a548ec2a;hpb=813a5c0d263fd98da93b5765730b029ef343a4e1;p=pve-common.git diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index 82d598e..1fe7f4c 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -4,7 +4,7 @@ use strict; use warnings; use POSIX qw(EINTR EEXIST EOPNOTSUPP); use IO::Socket::IP; -use Socket qw(AF_INET AF_INET6 AI_ALL AI_V4MAPPED); +use Socket qw(AF_INET AF_INET6 AI_ALL AI_V4MAPPED AI_CANONNAME SOCK_DGRAM); use IO::Select; use File::Basename; use File::Path qw(make_path); @@ -341,7 +341,7 @@ sub run_command { my $timeout; my $oldtimeout; my $pid; - my $exitcode; + my $exitcode = -1; my $outfunc; my $errfunc; @@ -350,6 +350,7 @@ sub run_command { my $output; my $afterfork; my $noerr; + my $keeplocale; eval { @@ -374,6 +375,8 @@ sub run_command { $afterfork = $param{$p}; } elsif ($p eq 'noerr') { $noerr = $param{$p}; + } elsif ($p eq 'keeplocale') { + $keeplocale = $param{$p}; } else { die "got unknown parameter '$p' for run_command\n"; } @@ -397,13 +400,10 @@ sub run_command { my $writer = $input && $input =~ m/^<&/ ? $input : IO::File->new(); my $error = IO::File->new(); - # try to avoid locale related issues/warnings - my $lang = $param{lang} || 'C'; - my $orig_pid = $$; eval { - local $ENV{LC_ALL} = $lang; + local $ENV{LC_ALL} = 'C' if !$keeplocale; # suppress LVM warnings like: "File descriptor 3 left open"; local $ENV{LVM_SUPPRESS_FD_WARNINGS} = "1"; @@ -799,7 +799,7 @@ sub next_unused_port { return $newport; }; - my $p = lock_file($filename, 10, $code); + my $p = lock_file('/var/lock/pve-ports.lck', 10, $code); die $@ if $@; die "unable to find free port (${range_start}-${range_end})\n" if !$p; @@ -977,6 +977,8 @@ sub decode_text { return Encode::decode("utf8", uri_unescape($data)); } +# depreciated - do not use! +# we now decode all parameters by default sub decode_utf8_parameters { my ($param) = @_; @@ -1081,7 +1083,7 @@ sub dump_logfile { } sub dump_journal { - my ($start, $limit, $since, $until) = @_; + my ($start, $limit, $since, $until, $service) = @_; my $lines = []; my $count = 0; @@ -1100,6 +1102,7 @@ sub dump_journal { my $cmd = ['journalctl', '-o', 'short', '--no-pager']; + push @$cmd, '--unit', $service if $service; push @$cmd, '--since', $since if $since; push @$cmd, '--until', $until if $until; run_command($cmd, outfunc => $parser); @@ -1197,6 +1200,24 @@ sub get_host_address_family { return $res[0]->{family}; } +# get the fully qualified domain name of a host +# same logic as hostname(1): The FQDN is the name getaddrinfo(3) returns, +# given a nodename as a parameter +sub get_fqdn { + my ($nodename) = @_; + + my $hints = { + flags => AI_CANONNAME, + socktype => SOCK_DGRAM + }; + + my ($err, @addrs) = Socket::getaddrinfo($nodename, undef, $hints); + + die "getaddrinfo: $err" if $err; + + return $addrs[0]->{canonname}; +} + # Parses any sane kind of host, or host+port pair: # The port is always optional and thus may be undef. sub parse_host_and_port { @@ -1443,4 +1464,18 @@ sub enter_systemd_scope { die "systemd job never completed\n" if !$done; } +my $salt_starter = time(); + +sub encrypt_pw { + my ($pw) = @_; + + $salt_starter++; + my $salt = substr(Digest::SHA::sha1_base64(time() + $salt_starter + $$), 0, 8); + + # crypt does not want '+' in salt (see 'man crypt') + $salt =~ s/\+/X/g; + + return crypt(encode("utf8", $pw), "\$5\$$salt\$"); +} + 1;