feat: add --follow-symlinks flag to follow links for search/archiving

pull/566/head
Falko Galperin 2025-04-04 16:49:02 +02:00
parent 4fbdec2878
commit e60d52a136
No known key found for this signature in database
GPG Key ID: C4A60C593B625612
2 changed files with 18 additions and 2 deletions

View File

@ -148,6 +148,14 @@ pub fn build_cli() -> Command {
.action(ArgAction::SetTrue)
.help("Allow download folders as archive file"),
)
.arg(
Arg::new("follow-symlinks")
.env("DUFS_FOLLOW_SYMLINKS")
.hide_env(true)
.long("follow-symlinks")
.action(ArgAction::SetTrue)
.help("When searching files/folders or when archiving folders, also search/archive symlinked targets"),
)
.arg(
Arg::new("enable-cors")
.env("DUFS_ENABLE_CORS")
@ -281,6 +289,7 @@ pub struct Args {
pub allow_search: bool,
pub allow_symlink: bool,
pub allow_archive: bool,
pub follow_symlinks: bool,
pub render_index: bool,
pub render_spa: bool,
pub render_try_index: bool,
@ -372,6 +381,9 @@ impl Args {
if !args.allow_search {
args.allow_search = allow_all || matches.get_flag("allow-search");
}
if !args.follow_symlinks {
args.follow_symlinks = matches.get_flag("follow-symlinks");
}
if !args.allow_symlink {
args.allow_symlink = allow_all || matches.get_flag("allow-symlink");
}

View File

@ -594,11 +594,12 @@ impl Server {
let hidden = Arc::new(self.args.hidden.to_vec());
let hidden = hidden.clone();
let running = self.running.clone();
let search_symlinks = self.args.follow_symlinks;
let access_paths = access_paths.clone();
let search_paths = tokio::task::spawn_blocking(move || {
let mut paths: Vec<PathBuf> = vec![];
for dir in access_paths.entry_paths(&path_buf) {
let mut it = WalkDir::new(&dir).into_iter();
let mut it = WalkDir::new(&dir).follow_links(search_symlinks).into_iter();
it.next();
while let Some(Ok(entry)) = it.next() {
if !running.load(atomic::Ordering::SeqCst) {
@ -659,6 +660,7 @@ impl Server {
let hidden = self.args.hidden.clone();
let running = self.running.clone();
let compression = self.args.compress.to_compression();
let follow_symlinks = self.args.follow_symlinks;
tokio::spawn(async move {
if let Err(e) = zip_dir(
&mut writer,
@ -666,6 +668,7 @@ impl Server {
access_paths,
&hidden,
compression,
follow_symlinks,
running,
)
.await
@ -1639,6 +1642,7 @@ async fn zip_dir<W: AsyncWrite + Unpin>(
access_paths: AccessPaths,
hidden: &[String],
compression: Compression,
follow_symlinks: bool,
running: Arc<AtomicBool>,
) -> Result<()> {
let mut writer = ZipFileWriter::with_tokio(writer);
@ -1647,7 +1651,7 @@ async fn zip_dir<W: AsyncWrite + Unpin>(
let zip_paths = tokio::task::spawn_blocking(move || {
let mut paths: Vec<PathBuf> = vec![];
for dir in access_paths.entry_paths(&dir_clone) {
let mut it = WalkDir::new(&dir).into_iter();
let mut it = WalkDir::new(&dir).follow_links(follow_symlinks).into_iter();
it.next();
while let Some(Ok(entry)) = it.next() {
if !running.load(atomic::Ordering::SeqCst) {