121 const char* home = std::getenv(
"HOME");
122 path = std::string(home ? home :
"/tmp") +
123 "/.local/share/BastionGuard/quarantine";
127 const fs::path quarantine_path(path);
129 if (quarantine_path.empty() ||
130 quarantine_path == quarantine_path.root_path()) {
131 std::cerr <<
_(
"❌ Percorso di quarantena non valido: ")
132 << quarantine_path << std::endl;
137 fs::create_directories(quarantine_path, ec);
139 std::cerr <<
_(
"❌ Errore creazione cartella quarantena: ")
140 << ec.message() << std::endl;
145 if (!fs::is_directory(quarantine_path, ec) || ec) {
146 std::cerr <<
_(
"❌ Il percorso di quarantena non è una directory valida: ")
147 << quarantine_path << std::endl;
150 }
catch (
const std::exception& e) {
151 std::cerr <<
_(
"❌ Errore creazione cartella quarantena: ")
152 << e.what() << std::endl;
162 if (filepath.empty()) {
163 std::cerr <<
_(
"❌ Percorso file vuoto: quarantena annullata")
169 fs::path src = fs::absolute(fs::path(filepath), ec);
171 std::cerr <<
_(
"❌ Impossibile risolvere il percorso del file: ")
172 << filepath <<
" | " << ec.message() << std::endl;
175 src = src.lexically_normal();
179 if (!is_regular_file_without_following_symlinks(src, ec)) {
180 std::cerr <<
_(
"❌ Quarantena rifiutata: il percorso non è un file regolare: ")
183 std::cerr <<
" | " << ec.message();
184 std::cerr << std::endl;
189 if (quarantine_dir_string.empty())
192 const fs::path quarantine_dir(quarantine_dir_string);
196 if (is_path_inside(src, quarantine_dir)) {
197 std::cerr <<
_(
"❌ Il file è già contenuto nella quarantena: ")
202 fs::path dest = quarantine_dir / src.filename();
205 while (fs::exists(dest) || fs::exists(dest.string() +
".meta")) {
206 dest = quarantine_dir /
207 (src.stem().
string() +
"_" + std::to_string(counter) +
208 src.extension().string());
212 const fs::path meta_path(dest.string() +
".meta");
213 std::ofstream meta(meta_path, std::ios::out | std::ios::trunc);
214 if (!meta.is_open()) {
215 std::cerr <<
_(
"❌ Impossibile creare i metadata di quarantena: ")
216 << meta_path << std::endl;
220 meta << src.string() <<
'\n';
224 remove_without_throwing(meta_path);
225 std::cerr <<
_(
"❌ Scrittura metadata di quarantena fallita: ")
226 << meta_path << std::endl;
232 fs::rename(src, dest, ec);
235 if (ec == std::make_error_code(std::errc::cross_device_link)) {
236 std::cerr <<
_(
"DEBUG move(): filesystem differente, uso copia e rimozione\n");
238 if (!copy_then_remove(src, dest)) {
239 remove_without_throwing(meta_path);
243 std::cerr <<
_(
"❌ Errore spostamento quarantena: ")
244 << ec.message() << std::endl;
245 remove_without_throwing(meta_path);
250 std::cout <<
_(
"✔ File spostato in quarantena: ")
251 << dest << std::endl;
254 }
catch (
const std::exception& e) {
255 std::cerr <<
_(
"❌ Errore spostamento quarantena: ")
256 << e.what() << std::endl;
265 fs::path qf = fs::absolute(fs::path(quarantinedFile), ec);
267 std::cerr <<
_(
"❌ Percorso quarantena non valido: ")
268 << quarantinedFile <<
" | " << ec.message() << std::endl;
271 qf = qf.lexically_normal();
274 if (quarantine_dir_string.empty())
277 const fs::path quarantine_dir(quarantine_dir_string);
278 if (!is_path_inside(qf, quarantine_dir)) {
279 std::cerr <<
_(
"❌ Ripristino rifiutato: file esterno alla quarantena: ")
284 if (!is_regular_file_without_following_symlinks(qf, ec)) {
285 std::cerr <<
_(
"❌ Ripristino rifiutato: elemento non regolare: ")
290 const fs::path meta(qf.string() +
".meta");
291 if (!is_regular_file_without_following_symlinks(meta, ec)) {
292 std::cerr <<
_(
"❌ Ripristino impossibile: metadata mancante o non valido per ")
297 std::ifstream in(meta);
298 std::string original_path;
299 std::getline(in, original_path);
302 if (original_path.empty()) {
303 std::cerr <<
_(
"❌ Ripristino impossibile: metadata vuoto o corrotto in ")
304 << meta << std::endl;
308 fs::path original = fs::absolute(fs::path(original_path), ec);
310 std::cerr <<
_(
"❌ Percorso originale non valido nei metadata: ")
311 << original_path <<
" | " << ec.message() << std::endl;
314 original = original.lexically_normal();
316 if (is_path_inside(original, quarantine_dir)) {
317 std::cerr <<
_(
"❌ Ripristino rifiutato: destinazione interna alla quarantena: ")
318 << original << std::endl;
322 fs::create_directories(original.parent_path(), ec);
324 std::cerr <<
_(
"❌ Impossibile ricreare la directory originale: ")
325 << original.parent_path() <<
" | " << ec.message() << std::endl;
329 fs::path final_dest = original;
331 while (fs::exists(final_dest)) {
332 final_dest = original.parent_path() /
333 (original.stem().
string() +
"_restored" +
334 std::to_string(counter) + original.extension().string());
339 fs::rename(qf, final_dest, ec);
342 if (ec == std::make_error_code(std::errc::cross_device_link)) {
343 std::cerr <<
_(
"DEBUG restore(): filesystem differente, uso copia e rimozione\n");
345 if (!copy_then_remove(qf, final_dest))
348 std::cerr <<
_(
"❌ Errore ripristino: ")
349 << ec.message() << std::endl;
354 remove_without_throwing(meta);
356 std::cout <<
_(
"✔ File ripristinato in: ")
357 << final_dest << std::endl;
360 }
catch (
const std::exception& e) {
361 std::cerr <<
_(
"❌ Errore ripristino: ")
362 << e.what() << std::endl;
371 fs::path qf = fs::absolute(fs::path(quarantinedFile), ec);
373 std::cerr <<
_(
"❌ Percorso quarantena non valido: ")
374 << quarantinedFile <<
" | " << ec.message() << std::endl;
377 qf = qf.lexically_normal();
380 if (quarantine_dir_string.empty())
383 if (!is_path_inside(qf, fs::path(quarantine_dir_string))) {
384 std::cerr <<
_(
"❌ Eliminazione rifiutata: file esterno alla quarantena: ")
389 if (!is_regular_file_without_following_symlinks(qf, ec)) {
390 std::cerr <<
_(
"❌ Eliminazione rifiutata: elemento non regolare: ")
395 const fs::path meta(qf.string() +
".meta");
400 std::cerr <<
_(
"❌ Errore eliminazione file in quarantena: ")
401 << ec.message() << std::endl;
405 remove_without_throwing(meta);
407 std::cout <<
_(
"✔ File eliminato dalla quarantena: ")
411 }
catch (
const std::exception& e) {
412 std::cerr <<
_(
"❌ Errore eliminazione: ")
413 << e.what() << std::endl;