bool swu_cmd()

in src/native/tools/recompress/recompress_tool.cpp [206:304]


bool swu_cmd(fs::path &source, fs::path &dest, std::string *signing_cmd)
{
	{
		archive_diff::cpio_archive archive;
		if (!fs::is_regular_file(source))
		{
			printf("No such file exists: %s\n", source.string().c_str());
			return false;
		}

		auto reader = archive_diff::io::file::io_device::make_reader(source.string());
		if (!archive.try_read(reader))
		{
			return false;
		}

		printf("Writing new swu to %s\n", dest.string().c_str());

		auto sw_description_reader = archive.get_payload_reader(SW_DESCRPTION_FILE_NAME);

		auto config        = load_config(sw_description_reader);
		auto &root         = config->getRoot();
		auto image_entries = get_image_entries(config.get());

		std::map<std::string, std::string> file_to_hash_map;

		for (auto &entry : image_entries)
		{
			auto file = entry.filename;

			if (!file_to_hash_map.contains(file))
			{
				auto payload_reader = archive.get_payload_reader(file);

				auto temp_file = std::make_shared<archive_diff::io::file::temp_file>();

				auto writer = archive_diff::io::file::temp_file_writer::make_shared(temp_file);

				recompress(payload_reader, writer);

				auto recompressed_reader = archive_diff::io::file::temp_file_io_device::make_reader(temp_file);

				archive.set_payload_reader(file, recompressed_reader);

				auto hash = hash_reader(recompressed_reader);

				file_to_hash_map.insert(std::make_pair(file, hash.get_data_string()));
			}

			auto &entry_setting = root.lookup(entry.setting_path);
			if (!entry_setting.exists("sha256"))
			{
				entry_setting.add("sha256", libconfig::Setting::TypeString);
			}

			auto hash_string        = file_to_hash_map[file];
			entry_setting["sha256"] = hash_string;
		}

		fs::create_directories(dest.parent_path());

		std::shared_ptr<archive_diff::io::writer> writer =
			std::make_shared<archive_diff::io::file::binary_file_writer>(dest.string());
		archive_diff::io::sequential::basic_writer_wrapper wrapper(writer);

		// Update the sw-descripton file
		char delimiters[]   = {'/', '\\', ':'};
		auto source_escaped = replace(source.string(), delimiters, '_');
		auto description_path =
			fs::temp_directory_path() / "recompress_tool" / source_escaped / SW_DESCRPTION_FILE_NAME;

		printf("Writing new sw-description to: %s\n", description_path.string().c_str());
		fs::create_directories(description_path.parent_path());
		config->writeFile(description_path.string().c_str());

		auto description_reader = archive_diff::io::file::io_device::make_reader(description_path.string());
		archive.set_payload_reader("sw-description", description_reader);

		if (signing_cmd == nullptr)
		{
			if (archive.has_file(SIG_FILE_NAME))
			{
				printf("No signing mechanism passed in, deleting sw-description.sig\n");
				archive.remove_file("sw-description.sig");
			}
		}
		else
		{
			if (!generate_description_sig(description_path, *signing_cmd, archive))
			{
				return false;
			}
		}

		archive.write(wrapper);
	}

	return true;
}