updater: Minor clean up to EnumerateStash().

Test: Apply an incremental BBOTA package with the new updater.
Test: Resume an interrupted BBOTA (so it cleans up the partial stash).
Change-Id: I620cc57ee6366845bcffbc19210f7a01e2196052
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index 03ce413..6227154 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -32,6 +32,7 @@
 #include <unistd.h>
 #include <fec/io.h>
 
+#include <functional>
 #include <memory>
 #include <string>
 #include <unordered_map>
@@ -473,88 +474,54 @@
     return fn;
 }
 
-typedef void (*StashCallback)(const std::string&, void*);
+// Does a best effort enumeration of stash files. Ignores possible non-file items in the stash
+// directory and continues despite of errors. Calls the 'callback' function for each file.
+static void EnumerateStash(const std::string& dirname,
+                           const std::function<void(const std::string&)>& callback) {
+  if (dirname.empty()) return;
 
-// Does a best effort enumeration of stash files. Ignores possible non-file
-// items in the stash directory and continues despite of errors. Calls the
-// 'callback' function for each file and passes 'data' to the function as a
-// parameter.
+  std::unique_ptr<DIR, decltype(&closedir)> directory(opendir(dirname.c_str()), closedir);
 
-static void EnumerateStash(const std::string& dirname, StashCallback callback, void* data) {
-    if (dirname.empty() || callback == nullptr) {
-        return;
+  if (directory == nullptr) {
+    if (errno != ENOENT) {
+      PLOG(ERROR) << "opendir \"" << dirname << "\" failed";
     }
-
-    std::unique_ptr<DIR, int(*)(DIR*)> directory(opendir(dirname.c_str()), closedir);
-
-    if (directory == nullptr) {
-        if (errno != ENOENT) {
-            PLOG(ERROR) << "opendir \"" << dirname << "\" failed";
-        }
-        return;
-    }
-
-    struct dirent* item;
-    while ((item = readdir(directory.get())) != nullptr) {
-        if (item->d_type != DT_REG) {
-            continue;
-        }
-
-        std::string fn = dirname + "/" + std::string(item->d_name);
-        callback(fn, data);
-    }
-}
-
-static void UpdateFileSize(const std::string& fn, void* data) {
-  if (fn.empty() || !data) {
     return;
   }
 
-  struct stat sb;
-  if (stat(fn.c_str(), &sb) == -1) {
-    PLOG(ERROR) << "stat \"" << fn << "\" failed";
-    return;
+  dirent* item;
+  while ((item = readdir(directory.get())) != nullptr) {
+    if (item->d_type != DT_REG) continue;
+    callback(dirname + "/" + item->d_name);
   }
-
-  size_t* size = static_cast<size_t*>(data);
-  *size += sb.st_size;
 }
 
 // Deletes the stash directory and all files in it. Assumes that it only
 // contains files. There is nothing we can do about unlikely, but possible
 // errors, so they are merely logged.
+static void DeleteFile(const std::string& fn) {
+  if (fn.empty()) return;
 
-static void DeleteFile(const std::string& fn, void* /* data */) {
-    if (!fn.empty()) {
-        LOG(INFO) << "deleting " << fn;
+  LOG(INFO) << "deleting " << fn;
 
-        if (unlink(fn.c_str()) == -1 && errno != ENOENT) {
-            PLOG(ERROR) << "unlink \"" << fn << "\" failed";
-        }
-    }
-}
-
-static void DeletePartial(const std::string& fn, void* data) {
-    if (android::base::EndsWith(fn, ".partial")) {
-        DeleteFile(fn, data);
-    }
+  if (unlink(fn.c_str()) == -1 && errno != ENOENT) {
+    PLOG(ERROR) << "unlink \"" << fn << "\" failed";
+  }
 }
 
 static void DeleteStash(const std::string& base) {
-    if (base.empty()) {
-        return;
+  if (base.empty()) return;
+
+  LOG(INFO) << "deleting stash " << base;
+
+  std::string dirname = GetStashFileName(base, "", "");
+  EnumerateStash(dirname, DeleteFile);
+
+  if (rmdir(dirname.c_str()) == -1) {
+    if (errno != ENOENT && errno != ENOTDIR) {
+      PLOG(ERROR) << "rmdir \"" << dirname << "\" failed";
     }
-
-    LOG(INFO) << "deleting stash " << base;
-
-    std::string dirname = GetStashFileName(base, "", "");
-    EnumerateStash(dirname, DeleteFile, nullptr);
-
-    if (rmdir(dirname.c_str()) == -1) {
-        if (errno != ENOENT && errno != ENOTDIR) {
-            PLOG(ERROR) << "rmdir \"" << dirname << "\" failed";
-        }
-    }
+  }
 }
 
 static int LoadStash(CommandParameters& params, const std::string& base, const std::string& id,
@@ -624,7 +591,7 @@
 
     if (verify && VerifyBlocks(id, buffer, *blocks, true) != 0) {
         LOG(ERROR) << "unexpected contents in " << fn;
-        DeleteFile(fn, nullptr);
+        DeleteFile(fn);
         return -1;
     }
 
@@ -750,13 +717,24 @@
 
   LOG(INFO) << "using existing stash " << dirname;
 
-  // If the directory already exists, calculate the space already allocated to
-  // stash files and check if there's enough for all required blocks. Delete any
-  // partially completed stash files first.
+  // If the directory already exists, calculate the space already allocated to stash files and check
+  // if there's enough for all required blocks. Delete any partially completed stash files first.
+  EnumerateStash(dirname, [](const std::string& fn) {
+    if (android::base::EndsWith(fn, ".partial")) {
+      DeleteFile(fn);
+    }
+  });
 
-  EnumerateStash(dirname, DeletePartial, nullptr);
   size_t existing = 0;
-  EnumerateStash(dirname, UpdateFileSize, &existing);
+  EnumerateStash(dirname, [&existing](const std::string& fn) {
+    if (fn.empty()) return;
+    struct stat sb;
+    if (stat(fn.c_str(), &sb) == -1) {
+      PLOG(ERROR) << "stat \"" << fn << "\" failed";
+      return;
+    }
+    existing += static_cast<size_t>(sb.st_size);
+  });
 
   if (max_stash_size > existing) {
     size_t needed = max_stash_size - existing;
@@ -817,14 +795,13 @@
 }
 
 static int FreeStash(const std::string& base, const std::string& id) {
-    if (base.empty() || id.empty()) {
-        return -1;
-    }
+  if (base.empty() || id.empty()) {
+    return -1;
+  }
 
-    std::string fn = GetStashFileName(base, id, "");
-    DeleteFile(fn, nullptr);
+  DeleteFile(GetStashFileName(base, id, ""));
 
-    return 0;
+  return 0;
 }
 
 static void MoveRange(std::vector<uint8_t>& dest, const RangeSet& locs,