tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FileUtilsImpl.h (3683B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_cache_FileUtilsImpl_h
      8 #define mozilla_dom_cache_FileUtilsImpl_h
      9 
     10 #include "mozilla/dom/FlippedOnce.h"
     11 #include "mozilla/dom/cache/FileUtils.h"
     12 #include "mozilla/dom/quota/ResultExtensions.h"
     13 
     14 namespace mozilla::dom::cache {
     15 
     16 template <typename Func>
     17 nsresult BodyTraverseFilesForCleanup(
     18    const Maybe<CacheDirectoryMetadata>& aDirectoryMetadata, nsIFile& aBodyDir,
     19    const Func& aHandleFileFunc) {
     20  MOZ_DIAGNOSTIC_ASSERT(aDirectoryMetadata.isSome());
     21 
     22 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
     23  {
     24    nsCOMPtr<nsIFile> parentFile;
     25    nsresult rv = aBodyDir.GetParent(getter_AddRefs(parentFile));
     26    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
     27    MOZ_DIAGNOSTIC_ASSERT(parentFile);
     28 
     29    nsAutoCString nativeLeafName;
     30    rv = parentFile->GetNativeLeafName(nativeLeafName);
     31    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
     32 
     33    MOZ_DIAGNOSTIC_ASSERT(StringEndsWith(nativeLeafName, "morgue"_ns));
     34  }
     35 #endif
     36 
     37  FlippedOnce<true> isEmpty;
     38  QM_TRY(quota::CollectEachFile(
     39      aBodyDir,
     40      [&isEmpty, &aDirectoryMetadata, &aHandleFileFunc](
     41          const nsCOMPtr<nsIFile>& file) -> Result<Ok, nsresult> {
     42        QM_TRY_INSPECT(const auto& dirEntryKind, quota::GetDirEntryKind(*file));
     43 
     44        switch (dirEntryKind) {
     45          case quota::nsIFileKind::ExistsAsDirectory: {
     46            // If it's a directory somehow, try to remove it and move on
     47            DebugOnly<nsresult> result = RemoveNsIFileRecursively(
     48                aDirectoryMetadata, *file, /* aTrackQuota */ false);
     49            MOZ_ASSERT(NS_SUCCEEDED(result));
     50            break;
     51          }
     52 
     53          case quota::nsIFileKind::ExistsAsFile: {
     54            nsAutoCString leafName;
     55            QM_TRY(MOZ_TO_RESULT(file->GetNativeLeafName(leafName)));
     56 
     57            // Delete all tmp files regardless of known bodies. These are all
     58            // considered orphans.
     59            if (StringEndsWith(leafName, ".tmp"_ns)) {
     60              DebugOnly<nsresult> result = RemoveNsIFile(
     61                  aDirectoryMetadata, *file, /* aTrackQuota */ true);
     62              MOZ_ASSERT(NS_SUCCEEDED(result));
     63              return Ok{};
     64            }
     65            // Otherwise, it must be a .final file.
     66            QM_WARNONLY_TRY_UNWRAP(const auto maybeEndingOk,
     67                                   OkIf(StringEndsWith(leafName, ".final"_ns)));
     68 
     69            // If its not, try to remove it and move on.
     70            if (!maybeEndingOk) {
     71              DebugOnly<nsresult> result = RemoveNsIFile(
     72                  aDirectoryMetadata, *file, /* aTrackQuota */ false);
     73              MOZ_ASSERT(NS_SUCCEEDED(result));
     74              return Ok{};
     75            }
     76 
     77            QM_TRY_INSPECT(const bool& fileDeleted,
     78                           aHandleFileFunc(*file, leafName));
     79            if (fileDeleted) {
     80              return Ok{};
     81            }
     82 
     83            isEmpty.EnsureFlipped();
     84            break;
     85          }
     86 
     87          case quota::nsIFileKind::DoesNotExist:
     88            // Ignore files that got removed externally while iterating.
     89            break;
     90        }
     91 
     92        return Ok{};
     93      }));
     94 
     95  if (isEmpty) {
     96    DebugOnly<nsresult> result = RemoveNsIFileRecursively(
     97        aDirectoryMetadata, aBodyDir, /* aTrackQuota */ false);
     98    MOZ_ASSERT(NS_SUCCEEDED(result));
     99  }
    100 
    101  return NS_OK;
    102 }
    103 
    104 }  // namespace mozilla::dom::cache
    105 
    106 #endif  // mozilla_dom_cache_FileUtilsImpl_h