From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <m.frank@proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id 625508A33D
 for <pbs-devel@lists.proxmox.com>; Tue, 16 Aug 2022 11:48:47 +0200 (CEST)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 5B1891AEF3
 for <pbs-devel@lists.proxmox.com>; Tue, 16 Aug 2022 11:48:17 +0200 (CEST)
Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com
 [94.136.29.106])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by firstgate.proxmox.com (Proxmox) with ESMTPS
 for <pbs-devel@lists.proxmox.com>; Tue, 16 Aug 2022 11:48:15 +0200 (CEST)
Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1])
 by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 333F54336D
 for <pbs-devel@lists.proxmox.com>; Tue, 16 Aug 2022 11:48:15 +0200 (CEST)
Message-ID: <dfa472f7-f184-b488-c670-d57f6860f29a@proxmox.com>
Date: Tue, 16 Aug 2022 11:48:13 +0200
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101
 Thunderbird/91.12.0
Content-Language: en-US
From: Markus Frank <m.frank@proxmox.com>
To: pbs-devel@lists.proxmox.com
Reply-To: Proxmox Backup Server development discussion
 <pbs-devel@lists.proxmox.com>
References: <20220816091929.26309-1-m.frank@proxmox.com>
 <20220816091929.26309-2-m.frank@proxmox.com>
In-Reply-To: <20220816091929.26309-2-m.frank@proxmox.com>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL -0.081 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 NICE_REPLY_A           -0.001 Looks like a legit reply (A)
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
 T_SCC_BODY_TEXT_LINE    -0.01 -
 URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See
 http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more
 information. [extract.rs, proxmox.com, main.rs]
Subject: Re: [pbs-devel] [PATCH proxmox-backup 1/3] added
 overwrite-existing-files as
X-BeenThere: pbs-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox Backup Server development discussion
 <pbs-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pbs-devel/>
List-Post: <mailto:pbs-devel@lists.proxmox.com>
List-Help: <mailto:pbs-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Tue, 16 Aug 2022 09:48:47 -0000

I am sorry. Subject/Commit-Message should be:

added overwrite-existing-files to PxarExtractOptions

On 8/16/22 11:19, Markus Frank wrote:
> If true, O_EXCL is not set and therefore overwrites the files and does not
> error out.
> 
> Signed-off-by: Markus Frank <m.frank@proxmox.com>
> ---
>   pbs-client/src/catalog_shell.rs |  4 ++--
>   pbs-client/src/pxar/extract.rs  | 24 +++++++++++++++++++++---
>   pxar-bin/src/main.rs            |  7 +++++++
>   3 files changed, 30 insertions(+), 5 deletions(-)
> 
> diff --git a/pbs-client/src/catalog_shell.rs b/pbs-client/src/catalog_shell.rs
> index b11901ed..25e27b37 100644
> --- a/pbs-client/src/catalog_shell.rs
> +++ b/pbs-client/src/catalog_shell.rs
> @@ -984,7 +984,7 @@ impl Shell {
>               .clone();
> 
>           let extractor =
> -            crate::pxar::extract::Extractor::new(rootdir, root_meta, true, Flags::DEFAULT);
> +            crate::pxar::extract::Extractor::new(rootdir, root_meta, true, false, Flags::DEFAULT);
> 
>           let mut extractor = ExtractorState::new(
>               &mut self.catalog,
> @@ -1172,7 +1172,7 @@ impl<'a> ExtractorState<'a> {
>                   let file_name = CString::new(entry.file_name().as_bytes())?;
>                   let mut contents = entry.contents().await?;
>                   self.extractor
> -                    .async_extract_file(&file_name, entry.metadata(), *size, &mut contents)
> +                    .async_extract_file(&file_name, entry.metadata(), *size, &mut contents, false)
>                       .await
>               }
>               _ => {
> diff --git a/pbs-client/src/pxar/extract.rs b/pbs-client/src/pxar/extract.rs
> index 161d2cef..3b9151aa 100644
> --- a/pbs-client/src/pxar/extract.rs
> +++ b/pbs-client/src/pxar/extract.rs
> @@ -34,6 +34,7 @@ pub struct PxarExtractOptions<'a> {
>       pub match_list: &'a [MatchEntry],
>       pub extract_match_default: bool,
>       pub allow_existing_dirs: bool,
> +    pub overwrite_existing_files: bool,
>       pub on_error: Option<ErrorHandler>,
>   }
> 
> @@ -80,6 +81,7 @@ where
>           dir,
>           root.metadata().clone(),
>           options.allow_existing_dirs,
> +        options.overwrite_existing_files,
>           feature_flags,
>       );
> 
> @@ -198,6 +200,7 @@ where
>                   &mut decoder.contents().ok_or_else(|| {
>                       format_err!("found regular file entry without contents in archive")
>                   })?,
> +                extractor.overwrite_existing_files,
>               ),
>               (false, _) => Ok(()), // skip this
>           }
> @@ -215,6 +218,7 @@ where
>   pub struct Extractor {
>       feature_flags: Flags,
>       allow_existing_dirs: bool,
> +    overwrite_existing_files: bool,
>       dir_stack: PxarDirStack,
> 
>       /// For better error output we need to track the current path in the Extractor state.
> @@ -231,11 +235,13 @@ impl Extractor {
>           root_dir: Dir,
>           metadata: Metadata,
>           allow_existing_dirs: bool,
> +        overwrite_existing_files: bool,
>           feature_flags: Flags,
>       ) -> Self {
>           Self {
>               dir_stack: PxarDirStack::new(root_dir, metadata),
>               allow_existing_dirs,
> +            overwrite_existing_files,
>               feature_flags,
>               current_path: Arc::new(Mutex::new(OsString::new())),
>               on_error: Box::new(Err),
> @@ -392,14 +398,19 @@ impl Extractor {
>           metadata: &Metadata,
>           size: u64,
>           contents: &mut dyn io::Read,
> +        overwrite_existing_files: bool,
>       ) -> Result<(), Error> {
>           let parent = self.parent_fd()?;
> +        let mut oflags = OFlag::O_CREAT | OFlag::O_WRONLY | OFlag::O_CLOEXEC;
> +        if !overwrite_existing_files {
> +            oflags = oflags | OFlag::O_EXCL;
> +        }
>           let mut file = unsafe {
>               std::fs::File::from_raw_fd(
>                   nix::fcntl::openat(
>                       parent,
>                       file_name,
> -                    OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_WRONLY | OFlag::O_CLOEXEC,
> +                    oflags,
>                       Mode::from_bits(0o600).unwrap(),
>                   )
>                   .map_err(|err| format_err!("failed to create file {:?}: {}", file_name, err))?,
> @@ -448,14 +459,19 @@ impl Extractor {
>           metadata: &Metadata,
>           size: u64,
>           contents: &mut T,
> +        overwrite_existing_files: bool,
>       ) -> Result<(), Error> {
>           let parent = self.parent_fd()?;
> +        let mut oflags = OFlag::O_CREAT | OFlag::O_WRONLY | OFlag::O_CLOEXEC;
> +        if !overwrite_existing_files {
> +            oflags = oflags | OFlag::O_EXCL;
> +        }
>           let mut file = tokio::fs::File::from_std(unsafe {
>               std::fs::File::from_raw_fd(
>                   nix::fcntl::openat(
>                       parent,
>                       file_name,
> -                    OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_WRONLY | OFlag::O_CLOEXEC,
> +                    oflags,
>                       Mode::from_bits(0o600).unwrap(),
>                   )
>                   .map_err(|err| format_err!("failed to create file {:?}: {}", file_name, err))?,
> @@ -818,7 +834,7 @@ where
>           )
>       })?;
> 
> -    Ok(Extractor::new(dir, metadata, false, Flags::DEFAULT))
> +    Ok(Extractor::new(dir, metadata, false, false, Flags::DEFAULT))
>   }
> 
>   pub async fn extract_sub_dir<T, DEST, PATH>(
> @@ -951,6 +967,7 @@ where
>                       &mut file.contents().await.map_err(|_| {
>                           format_err!("found regular file entry without contents in archive")
>                       })?,
> +                    extractor.overwrite_existing_files,
>                   )
>                   .await?
>           }
> @@ -998,6 +1015,7 @@ where
>                               &mut decoder.contents().ok_or_else(|| {
>                                   format_err!("found regular file entry without contents in archive")
>                               })?,
> +                            extractor.overwrite_existing_files,
>                           )
>                           .await?
>                   }
> diff --git a/pxar-bin/src/main.rs b/pxar-bin/src/main.rs
> index 3714eb03..4b49df51 100644
> --- a/pxar-bin/src/main.rs
> +++ b/pxar-bin/src/main.rs
> @@ -75,6 +75,11 @@ fn extract_archive_from_reader<R: std::io::Read>(
>                   optional: true,
>                   default: false,
>               },
> +            "overwrite_existing_files": {
> +                description: "overwrite existing files",
> +                optional: true,
> +                default: false,
> +            },
>               "files-from": {
>                   description: "File containing match pattern for files to restore.",
>                   optional: true,
> @@ -112,6 +117,7 @@ fn extract_archive(
>       no_fcaps: bool,
>       no_acls: bool,
>       allow_existing_dirs: bool,
> +    overwrite_existing_files: bool,
>       files_from: Option<String>,
>       no_device_nodes: bool,
>       no_fifos: bool,
> @@ -179,6 +185,7 @@ fn extract_archive(
>       let options = PxarExtractOptions {
>           match_list: &match_list,
>           allow_existing_dirs,
> +        overwrite_existing_files,
>           extract_match_default,
>           on_error,
>       };
> --
> 2.30.2
> 
> 
> 
> _______________________________________________
> pbs-devel mailing list
> pbs-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
> 
>