262{
263 try {
264 std::error_code ec;
265 fs::path qf = fs::absolute(fs::path(quarantinedFile), ec);
266 if (ec) {
267 std::cerr <<
_(
"❌ Percorso quarantena non valido: ")
268 << quarantinedFile << " | " << ec.message() << std::endl;
269 return false;
270 }
271 qf = qf.lexically_normal();
272
274 if (quarantine_dir_string.empty())
275 return false;
276
277 const fs::path quarantine_dir(quarantine_dir_string);
279 std::cerr <<
_(
"❌ Ripristino rifiutato: file esterno alla quarantena: ")
280 << qf << std::endl;
281 return false;
282 }
283
285 std::cerr <<
_(
"❌ Ripristino rifiutato: elemento non regolare: ")
286 << qf << std::endl;
287 return false;
288 }
289
290 const fs::path meta(qf.string() + ".meta");
292 std::cerr <<
_(
"❌ Ripristino impossibile: metadata mancante o non valido per ")
293 << qf << std::endl;
294 return false;
295 }
296
297 std::ifstream in(meta);
298 std::string original_path;
299 std::getline(in, original_path);
300 in.close();
301
302 if (original_path.empty()) {
303 std::cerr <<
_(
"❌ Ripristino impossibile: metadata vuoto o corrotto in ")
304 << meta << std::endl;
305 return false;
306 }
307
308 fs::path original = fs::absolute(fs::path(original_path), ec);
309 if (ec) {
310 std::cerr <<
_(
"❌ Percorso originale non valido nei metadata: ")
311 << original_path << " | " << ec.message() << std::endl;
312 return false;
313 }
314 original = original.lexically_normal();
315
317 std::cerr <<
_(
"❌ Ripristino rifiutato: destinazione interna alla quarantena: ")
318 << original << std::endl;
319 return false;
320 }
321
322 fs::create_directories(original.parent_path(), ec);
323 if (ec) {
324 std::cerr <<
_(
"❌ Impossibile ricreare la directory originale: ")
325 << original.parent_path() << " | " << ec.message() << std::endl;
326 return false;
327 }
328
329 fs::path final_dest = original;
330 int counter = 1;
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());
335 ++counter;
336 }
337
338 ec.clear();
339 fs::rename(qf, final_dest, ec);
340
341 if (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");
344
346 return false;
347 } else {
348 std::cerr <<
_(
"❌ Errore ripristino: ")
349 << ec.message() << std::endl;
350 return false;
351 }
352 }
353
355
356 std::cout <<
_(
"✔ File ripristinato in: ")
357 << final_dest << std::endl;
358 return true;
359
360 } catch (const std::exception& e) {
361 std::cerr <<
_(
"❌ Errore ripristino: ")
362 << e.what() << std::endl;
363 return false;
364 }
365}