]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/Tools.pm
sendmail: separate 'mailto' list from the rest of the parameters
[pve-common.git] / src / PVE / Tools.pm
index 076c18a8547bc8852b68d4ac53a92185e94fb49e..4399b2f4d9f13b61de73511f81bb47f6417d64ea 100644 (file)
@@ -50,6 +50,14 @@ file_copy
 get_host_arch
 O_PATH
 O_TMPFILE
+AT_EMPTY_PATH
+AT_FDCWD
+CLONE_NEWNS
+CLONE_NEWUTS
+CLONE_NEWIPC
+CLONE_NEWUSER
+CLONE_NEWPID
+CLONE_NEWNET
 );
 
 my $pvelogdir = "/var/log/pve";
@@ -86,7 +94,8 @@ use constant {CLONE_NEWNS   => 0x00020000,
 use constant {O_PATH    => 0x00200000,
               O_TMPFILE => 0x00410000}; # This includes O_DIRECTORY
 
-use constant {AT_EMPTY_PATH => 0x1000};
+use constant {AT_EMPTY_PATH => 0x1000,
+              AT_FDCWD => -100};
 
 sub run_with_timeout {
     my ($timeout, $code, @param) = @_;
@@ -899,9 +908,13 @@ sub next_vnc_port {
     return next_unused_port(5900, 6000, $family, $address);
 }
 
+sub spice_port_range {
+    return (61000, 61999);
+}
+
 sub next_spice_port {
     my ($family, $address) = @_;
-    return next_unused_port(61000, 61099, $family, $address);
+    return next_unused_port(spice_port_range(), $family, $address);
 }
 
 sub must_stringify {
@@ -998,8 +1011,8 @@ sub df {
     my $res = eval { run_fork_with_timeout($timeout, $df) } // {};
     warn $@ if $@;
 
-    # untaint the values
-    my ($blocks, $used, $bavail) = map { defined($_) ? (/^(\d+)$/) : 0 }
+    # untaint, but be flexible: PB usage can result in scientific notation
+    my ($blocks, $used, $bavail) = map { defined($_) ? (/^([\d\.e\-+]+)$/) : 0 }
        $res->@{qw(blocks used bavail)};
 
     return {
@@ -1441,7 +1454,7 @@ sub sendmail {
 
     $author = $author || 'Proxmox VE';
 
-    open (MAIL, "|-", "sendmail", "-B", "8BITMIME", "-f", $mailfrom, @$mailto) ||
+    open (MAIL, "|-", "sendmail", "-B", "8BITMIME", "-f", $mailfrom, "--", @$mailto) ||
        die "unable to open 'sendmail' - $!";
 
     # multipart spec see https://www.ietf.org/rfc/rfc1521.txt
@@ -1687,5 +1700,79 @@ sub array_intersect {
     return $return_arr;
 }
 
+sub open_tree($$$) {
+    my ($dfd, $pathname, $flags) = @_;
+    return PVE::Syscall::file_handle_result(syscall(
+       &PVE::Syscall::open_tree,
+       $dfd,
+       $pathname,
+       $flags,
+    ));
+}
+
+sub move_mount($$$$$) {
+    my ($from_dirfd, $from_pathname, $to_dirfd, $to_pathname, $flags) = @_;
+    return 0 == syscall(
+       &PVE::Syscall::move_mount,
+       $from_dirfd,
+       $from_pathname,
+       $to_dirfd,
+       $to_pathname,
+       $flags,
+    );
+}
+
+sub fsopen($$) {
+    my ($fsname, $flags) = @_;
+    return PVE::Syscall::file_handle_result(syscall(&PVE::Syscall::fsopen, $fsname, $flags));
+}
+
+sub fsmount($$$) {
+    my ($fd, $flags, $mount_attrs) = @_;
+    return PVE::Syscall::file_handle_result(syscall(
+       &PVE::Syscall::fsmount,
+       $fd,
+       $flags,
+       $mount_attrs,
+    ));
+}
+
+sub fspick($$$) {
+    my ($dirfd, $pathname, $flags) = @_;
+    return PVE::Syscall::file_handle_result(syscall(
+       &PVE::Syscall::fspick,
+       $dirfd,
+       $pathname,
+       $flags,
+    ));
+}
+
+sub fsconfig($$$$$) {
+    my ($fd, $command, $key, $value, $aux) = @_;
+    return 0 == syscall(&PVE::Syscall::fsconfig, $fd, $command, $key, $value, $aux);
+}
+
+# "raw" mount, old api, not for generic use (as it does not invoke any helpers).
+# use for lower level stuff such as bind/remount/... or simple tmpfs mounts
+sub mount($$$$$) {
+    my ($source, $target, $filesystemtype, $mountflags, $data) = @_;
+    return 0 == syscall(
+       &PVE::Syscall::mount,
+       $source,
+       $target,
+       $filesystemtype,
+       $mountflags,
+       $data,
+    );
+}
+
+sub safe_compare {
+    my ($left, $right, $cmp) = @_;
+
+    return 0 if !defined($left) && !defined($right);
+    return -1 if !defined($left);
+    return 1 if !defined($right);
+    return $cmp->($left, $right);
+}
 
 1;