From 33026bcefeebb82441d62910572ff98803e146a2 Mon Sep 17 00:00:00 2001 From: Ben Wiederhake Date: Sat, 13 May 2023 13:39:19 +0200 Subject: [PATCH] LibCore: Remove recursive copy API from DeprecatedFile --- Userland/Libraries/LibCore/DeprecatedFile.cpp | 195 ------------------ Userland/Libraries/LibCore/DeprecatedFile.h | 37 ---- 2 files changed, 232 deletions(-) diff --git a/Userland/Libraries/LibCore/DeprecatedFile.cpp b/Userland/Libraries/LibCore/DeprecatedFile.cpp index 46740bd3ef..d0cdefec2f 100644 --- a/Userland/Libraries/LibCore/DeprecatedFile.cpp +++ b/Userland/Libraries/LibCore/DeprecatedFile.cpp @@ -24,11 +24,6 @@ # include #endif -// On Linux distros that use glibc `basename` is defined as a macro that expands to `__xpg_basename`, so we undefine it -#if defined(AK_OS_LINUX) && defined(basename) -# undef basename -#endif - namespace Core { ErrorOr> DeprecatedFile::open(DeprecatedString filename, OpenMode mode, mode_t permissions) @@ -181,196 +176,6 @@ DeprecatedString DeprecatedFile::absolute_path(DeprecatedString const& path) return LexicalPath::canonicalized_path(full_path.string()); } -static DeprecatedString get_duplicate_name(DeprecatedString const& path, int duplicate_count) -{ - if (duplicate_count == 0) { - return path; - } - LexicalPath lexical_path(path); - StringBuilder duplicated_name; - duplicated_name.append('/'); - auto& parts = lexical_path.parts_view(); - for (size_t i = 0; i < parts.size() - 1; ++i) { - duplicated_name.appendff("{}/", parts[i]); - } - auto prev_duplicate_tag = DeprecatedString::formatted("({})", duplicate_count); - auto title = lexical_path.title(); - if (title.ends_with(prev_duplicate_tag)) { - // remove the previous duplicate tag "(n)" so we can add a new tag. - title = title.substring_view(0, title.length() - prev_duplicate_tag.length()); - } - duplicated_name.appendff("{} ({})", title, duplicate_count); - if (!lexical_path.extension().is_empty()) { - duplicated_name.appendff(".{}", lexical_path.extension()); - } - return duplicated_name.to_deprecated_string(); -} - -ErrorOr DeprecatedFile::copy_file_or_directory(DeprecatedString const& dst_path, DeprecatedString const& src_path, RecursionMode recursion_mode, LinkMode link_mode, AddDuplicateFileMarker add_duplicate_file_marker, PreserveMode preserve_mode) -{ - if (add_duplicate_file_marker == AddDuplicateFileMarker::Yes) { - int duplicate_count = 0; - while (access(get_duplicate_name(dst_path, duplicate_count).characters(), F_OK) == 0) { - ++duplicate_count; - } - if (duplicate_count != 0) { - return copy_file_or_directory(get_duplicate_name(dst_path, duplicate_count), src_path, RecursionMode::Allowed, LinkMode::Disallowed, AddDuplicateFileMarker::Yes, preserve_mode); - } - } - - auto source_or_error = DeprecatedFile::open(src_path, OpenMode::ReadOnly); - if (source_or_error.is_error()) - return CopyError { errno, false }; - - auto& source = *source_or_error.value(); - - struct stat src_stat; - if (fstat(source.fd(), &src_stat) < 0) - return CopyError { errno, false }; - - if (source.is_directory()) { - if (recursion_mode == RecursionMode::Disallowed) - return CopyError { errno, true }; - return copy_directory(dst_path, src_path, src_stat); - } - - if (link_mode == LinkMode::Allowed) { - if (link(src_path.characters(), dst_path.characters()) < 0) - return CopyError { errno, false }; - - return {}; - } - - return copy_file(dst_path, src_stat, source, preserve_mode); -} - -ErrorOr DeprecatedFile::copy_file(DeprecatedString const& dst_path, struct stat const& src_stat, DeprecatedFile& source, PreserveMode preserve_mode) -{ - int dst_fd = creat(dst_path.characters(), 0666); - if (dst_fd < 0) { - if (errno != EISDIR) - return CopyError { errno, false }; - - auto dst_dir_path = DeprecatedString::formatted("{}/{}", dst_path, LexicalPath::basename(source.filename())); - dst_fd = creat(dst_dir_path.characters(), 0666); - if (dst_fd < 0) - return CopyError { errno, false }; - } - - ScopeGuard close_fd_guard([dst_fd]() { ::close(dst_fd); }); - - if (src_stat.st_size > 0) { - if (ftruncate(dst_fd, src_stat.st_size) < 0) - return CopyError { errno, false }; - } - - for (;;) { - char buffer[32768]; - ssize_t nread = ::read(source.fd(), buffer, sizeof(buffer)); - if (nread < 0) { - return CopyError { errno, false }; - } - if (nread == 0) - break; - ssize_t remaining_to_write = nread; - char* bufptr = buffer; - while (remaining_to_write) { - ssize_t nwritten = ::write(dst_fd, bufptr, remaining_to_write); - if (nwritten < 0) - return CopyError { errno, false }; - - VERIFY(nwritten > 0); - remaining_to_write -= nwritten; - bufptr += nwritten; - } - } - - auto my_umask = umask(0); - umask(my_umask); - // NOTE: We don't copy the set-uid and set-gid bits unless requested. - if (!has_flag(preserve_mode, PreserveMode::Permissions)) - my_umask |= 06000; - - if (fchmod(dst_fd, src_stat.st_mode & ~my_umask) < 0) - return CopyError { errno, false }; - - if (has_flag(preserve_mode, PreserveMode::Ownership)) { - if (fchown(dst_fd, src_stat.st_uid, src_stat.st_gid) < 0) - return CopyError { errno, false }; - } - - if (has_flag(preserve_mode, PreserveMode::Timestamps)) { - struct timespec times[2] = { -#ifdef AK_OS_MACOS - src_stat.st_atimespec, - src_stat.st_mtimespec, -#else - src_stat.st_atim, - src_stat.st_mtim, -#endif - }; - if (utimensat(AT_FDCWD, dst_path.characters(), times, 0) < 0) - return CopyError { errno, false }; - } - - return {}; -} - -ErrorOr DeprecatedFile::copy_directory(DeprecatedString const& dst_path, DeprecatedString const& src_path, struct stat const& src_stat, LinkMode link, PreserveMode preserve_mode) -{ - if (mkdir(dst_path.characters(), 0755) < 0) - return CopyError { errno, false }; - - DeprecatedString src_rp = DeprecatedFile::real_path_for(src_path); - src_rp = DeprecatedString::formatted("{}/", src_rp); - DeprecatedString dst_rp = DeprecatedFile::real_path_for(dst_path); - dst_rp = DeprecatedString::formatted("{}/", dst_rp); - - if (!dst_rp.is_empty() && dst_rp.starts_with(src_rp)) - return CopyError { errno, false }; - - DirIterator di(src_path, DirIterator::SkipParentAndBaseDir); - if (di.has_error()) - return CopyError { errno, false }; - - while (di.has_next()) { - DeprecatedString filename = di.next_path(); - auto result = copy_file_or_directory( - DeprecatedString::formatted("{}/{}", dst_path, filename), - DeprecatedString::formatted("{}/{}", src_path, filename), - RecursionMode::Allowed, link, AddDuplicateFileMarker::Yes, preserve_mode); - if (result.is_error()) - return result.release_error(); - } - - auto my_umask = umask(0); - umask(my_umask); - - if (chmod(dst_path.characters(), src_stat.st_mode & ~my_umask) < 0) - return CopyError { errno, false }; - - if (has_flag(preserve_mode, PreserveMode::Ownership)) { - if (chown(dst_path.characters(), src_stat.st_uid, src_stat.st_gid) < 0) - return CopyError { errno, false }; - } - - if (has_flag(preserve_mode, PreserveMode::Timestamps)) { - struct timespec times[2] = { -#ifdef AK_OS_MACOS - src_stat.st_atimespec, - src_stat.st_mtimespec, -#else - src_stat.st_atim, - src_stat.st_mtim, -#endif - }; - if (utimensat(AT_FDCWD, dst_path.characters(), times, 0) < 0) - return CopyError { errno, false }; - } - - return {}; -} - Optional DeprecatedFile::resolve_executable_from_environment(StringView filename) { if (filename.is_empty()) diff --git a/Userland/Libraries/LibCore/DeprecatedFile.h b/Userland/Libraries/LibCore/DeprecatedFile.h index f94cacb8fc..488286d14c 100644 --- a/Userland/Libraries/LibCore/DeprecatedFile.h +++ b/Userland/Libraries/LibCore/DeprecatedFile.h @@ -35,41 +35,6 @@ public: static DeprecatedString current_working_directory(); static DeprecatedString absolute_path(DeprecatedString const& path); - enum class RecursionMode { - Allowed, - Disallowed - }; - - enum class LinkMode { - Allowed, - Disallowed - }; - - enum class AddDuplicateFileMarker { - Yes, - No, - }; - - enum class PreserveMode { - Nothing = 0, - Permissions = (1 << 0), - Ownership = (1 << 1), - Timestamps = (1 << 2), - }; - - struct CopyError : public Error { - CopyError(int error_code, bool t) - : Error(error_code) - , tried_recursing(t) - { - } - bool tried_recursing; - }; - - static ErrorOr copy_file(DeprecatedString const& dst_path, struct stat const& src_stat, DeprecatedFile& source, PreserveMode = PreserveMode::Nothing); - static ErrorOr copy_directory(DeprecatedString const& dst_path, DeprecatedString const& src_path, struct stat const& src_stat, LinkMode = LinkMode::Disallowed, PreserveMode = PreserveMode::Nothing); - static ErrorOr copy_file_or_directory(DeprecatedString const& dst_path, DeprecatedString const& src_path, RecursionMode = RecursionMode::Allowed, LinkMode = LinkMode::Disallowed, AddDuplicateFileMarker = AddDuplicateFileMarker::Yes, PreserveMode = PreserveMode::Nothing); - static DeprecatedString real_path_for(DeprecatedString const& filename); virtual bool open(OpenMode) override; @@ -96,6 +61,4 @@ private: ShouldCloseFileDescriptor m_should_close_file_descriptor { ShouldCloseFileDescriptor::Yes }; }; -AK_ENUM_BITWISE_OPERATORS(DeprecatedFile::PreserveMode); - }