Serenity Operating System
at master 59 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2022, Tim Schumacher <timschumi@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/LexicalPath.h> 8#include <AK/Vector.h> 9#include <LibCore/ArgsParser.h> 10#include <LibCore/DeprecatedFile.h> 11#include <LibCore/Directory.h> 12#include <LibCore/FilePermissionsMask.h> 13#include <LibCore/System.h> 14#include <LibMain/Main.h> 15 16ErrorOr<int> serenity_main(Main::Arguments arguments) 17{ 18 TRY(Core::System::pledge("stdio rpath wpath cpath fattr")); 19 20 bool create_leading_dest_components = false; 21 StringView mode = "0755"sv; 22 Vector<StringView> sources; 23 StringView destination; 24 25 Core::ArgsParser args_parser; 26 args_parser.add_ignored(nullptr, 'c'); // "copy files" is the default, no contradicting options exist. 27 args_parser.add_option(create_leading_dest_components, "Create leading components of the destination path", nullptr, 'D'); 28 args_parser.add_option(mode, "Permissions to set (instead of 0755)", "mode", 'm', "mode"); 29 args_parser.add_positional_argument(sources, "Source path", "source"); 30 args_parser.add_positional_argument(destination, "Destination path", "destination"); 31 args_parser.parse(arguments); 32 33 auto permission_mask = TRY(Core::FilePermissionsMask::parse(mode)); 34 35 DeprecatedString destination_dir = (sources.size() > 1 ? DeprecatedString { destination } : LexicalPath::dirname(destination)); 36 37 if (create_leading_dest_components) { 38 DeprecatedString destination_dir_absolute = Core::DeprecatedFile::absolute_path(destination_dir); 39 MUST(Core::Directory::create(destination_dir_absolute, Core::Directory::CreateDirectories::Yes)); 40 } 41 42 for (auto const& source : sources) { 43 DeprecatedString final_destination; 44 if (sources.size() > 1) { 45 final_destination = LexicalPath(destination).append(LexicalPath::basename(source)).string(); 46 } else { 47 final_destination = destination; 48 } 49 50 TRY(Core::DeprecatedFile::copy_file_or_directory(final_destination, source, Core::DeprecatedFile::RecursionMode::Allowed, 51 Core::DeprecatedFile::LinkMode::Disallowed, Core::DeprecatedFile::AddDuplicateFileMarker::No, 52 Core::DeprecatedFile::PreserveMode::Nothing)); 53 54 auto current_access = TRY(Core::System::stat(final_destination)); 55 TRY(Core::System::chmod(final_destination, permission_mask.apply(current_access.st_mode))); 56 } 57 58 return 0; 59}