Lift zip extractor business out of the core client

Lifts a big chunk of reasonably independent functionality into a new file to
reduce clutter, simplify future changes, and provide a more obvious surface
area for future testing. I just lifted the zip extractor parts in this pass - I
think and ideal end state would be for us to move all of the functions that
directly use the zip extractors over too, but I'll do that in another pass.

PiperOrigin-RevId: 249146959
diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD
index fea97a8..c61e459 100644
--- a/src/main/cpp/BUILD
+++ b/src/main/cpp/BUILD
@@ -70,6 +70,23 @@
     }),
 )
 
+cc_library(
+    name = "archive_utils",
+    srcs = [
+        "archive_utils.cc",
+    ],
+    hdrs = [
+        "archive_utils.h",
+    ],
+    deps = [
+        ":blaze_util",
+        "//src/main/cpp/util",
+        "//src/main/cpp/util:blaze_exit_code",
+        "//src/main/cpp/util:logging",
+        "//third_party/ijar:zip",
+    ],
+)
+
 cc_binary(
     name = "client",
     srcs = [
@@ -104,6 +121,7 @@
     }),
     visibility = ["//src:__pkg__"],
     deps = [
+        ":archive_utils",
         ":bazel_startup_options",
         ":blaze_util",
         ":option_processor",
diff --git a/src/main/cpp/archive_utils.cc b/src/main/cpp/archive_utils.cc
new file mode 100644
index 0000000..b73b1a0
--- /dev/null
+++ b/src/main/cpp/archive_utils.cc
@@ -0,0 +1,121 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "src/main/cpp/archive_utils.h"
+
+#include <vector>
+
+#include "src/main/cpp/util/exit_code.h"
+#include "src/main/cpp/util/logging.h"
+#include "src/main/cpp/util/path.h"
+#include "src/main/cpp/util/strings.h"
+#include "third_party/ijar/zip.h"
+
+namespace blaze {
+
+using std::vector;
+
+// A devtools_ijar::ZipExtractorProcessor that processes the ZIP entries using
+// the given PureZipExtractorProcessors.
+CompoundZipProcessor::CompoundZipProcessor(
+    const vector<PureZipExtractorProcessor *> &processors)
+    : processors_(processors) {}
+
+bool CompoundZipProcessor::Accept(const char *filename,
+                                  const devtools_ijar::u4 attr) {
+  bool should_accept = false;
+  for (auto *processor : processors_) {
+    if (processor->Accept(filename, attr)) {
+      // ZipExtractorProcessor::Accept is allowed to be side-effectful, so
+      // we don't want to break out on the first true here.
+      should_accept = true;
+    }
+  }
+  return should_accept;
+}
+
+void CompoundZipProcessor::Process(const char *filename,
+                                   const devtools_ijar::u4 attr,
+                                   const devtools_ijar::u1 *data,
+                                   const size_t size) {
+  for (auto *processor : processors_) {
+    if (processor->AcceptPure(filename, attr)) {
+      processor->Process(filename, attr, data, size);
+    }
+  }
+}
+
+// A PureZipExtractorProcessor to extract the InstallKeyFile
+GetInstallKeyFileProcessor::GetInstallKeyFileProcessor(string *install_base_key)
+    : install_base_key_(install_base_key) {}
+
+bool GetInstallKeyFileProcessor::AcceptPure(
+    const char *filename, const devtools_ijar::u4 attr) const {
+  return strcmp(filename, "install_base_key") == 0;
+}
+
+void GetInstallKeyFileProcessor::Process(const char *filename,
+                                         const devtools_ijar::u4 attr,
+                                         const devtools_ijar::u1 *data,
+                                         const size_t size) {
+  string str(reinterpret_cast<const char *>(data), size);
+  blaze_util::StripWhitespace(&str);
+  if (str.size() != 32) {
+    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
+        << "Failed to extract install_base_key: file size mismatch "
+           "(should be 32, is "
+        << str.size() << ")";
+  }
+  *install_base_key_ = str;
+}
+
+NoteAllFilesZipProcessor::NoteAllFilesZipProcessor(
+    std::vector<std::string> *files)
+    : files_(files) {}
+
+bool NoteAllFilesZipProcessor::AcceptPure(const char *filename,
+                                          const devtools_ijar::u4 attr) const {
+  return false;
+}
+
+bool NoteAllFilesZipProcessor::Accept(const char *filename,
+                                      const devtools_ijar::u4 attr) {
+  files_->push_back(filename);
+  return false;
+}
+
+void NoteAllFilesZipProcessor::Process(const char *filename,
+                                       const devtools_ijar::u4 attr,
+                                       const devtools_ijar::u1 *data,
+                                       const size_t size) {
+  BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
+      << "NoteAllFilesZipProcessor::Process shouldn't be called";
+}
+
+ExtractBlazeZipProcessor::ExtractBlazeZipProcessor(
+    const string &embedded_binaries, blaze::embedded_binaries::Dumper *dumper)
+    : embedded_binaries_(embedded_binaries), dumper_(dumper) {}
+
+bool ExtractBlazeZipProcessor::AcceptPure(const char *filename,
+                                          const devtools_ijar::u4 attr) const {
+  return !devtools_ijar::zipattr_is_dir(attr);
+}
+
+void ExtractBlazeZipProcessor::Process(const char *filename,
+                                       const devtools_ijar::u4 attr,
+                                       const devtools_ijar::u1 *data,
+                                       const size_t size) {
+  dumper_->Dump(data, size, blaze_util::JoinPath(embedded_binaries_, filename));
+}
+
+}  // namespace blaze
diff --git a/src/main/cpp/archive_utils.h b/src/main/cpp/archive_utils.h
new file mode 100644
index 0000000..ae25461
--- /dev/null
+++ b/src/main/cpp/archive_utils.h
@@ -0,0 +1,117 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BAZEL_SRC_MAIN_CPP_ARCHIVE_UTILS_H_
+#define BAZEL_SRC_MAIN_CPP_ARCHIVE_UTILS_H_
+
+#include <string>
+#include <vector>
+
+#include "src/main/cpp/blaze_util_platform.h"
+#include "src/main/cpp/util/strings.h"
+#include "third_party/ijar/zip.h"
+
+namespace blaze {
+
+using std::vector;
+using std::string;
+
+// A devtools_ijar::ZipExtractorProcessor that has a pure version of Accept.
+class PureZipExtractorProcessor : public devtools_ijar::ZipExtractorProcessor {
+ public:
+  virtual ~PureZipExtractorProcessor() {}
+
+  // Like devtools_ijar::ZipExtractorProcessor::Accept, but is guaranteed to not
+  // have side-effects.
+  virtual bool AcceptPure(const char *filename,
+                          const devtools_ijar::u4 attr) const = 0;
+};
+
+// A devtools_ijar::ZipExtractorProcessor that processes the ZIP entries using
+// the given PureZipExtractorProcessors.
+class CompoundZipProcessor : public devtools_ijar::ZipExtractorProcessor {
+ public:
+  explicit CompoundZipProcessor(
+      const vector<PureZipExtractorProcessor *> &processors);
+
+  bool Accept(const char *filename, const devtools_ijar::u4 attr) override;
+
+  void Process(const char *filename, const devtools_ijar::u4 attr,
+               const devtools_ijar::u1 *data, const size_t size) override;
+
+ private:
+  const vector<PureZipExtractorProcessor *> processors_;
+};
+
+// A PureZipExtractorProcessor to extract the InstallKeyFile
+class GetInstallKeyFileProcessor : public PureZipExtractorProcessor {
+ public:
+  explicit GetInstallKeyFileProcessor(string *install_base_key);
+
+  bool Accept(const char *filename, const devtools_ijar::u4 attr) override {
+    return AcceptPure(filename, attr);
+  }
+
+  bool AcceptPure(const char *filename,
+                  const devtools_ijar::u4 attr) const override;
+
+  void Process(const char *filename, const devtools_ijar::u4 attr,
+               const devtools_ijar::u1 *data, const size_t size) override;
+
+ private:
+  string *install_base_key_;
+};
+
+// A PureZipExtractorProcessor that adds the names of all the files ZIP up in
+// the Blaze binary to the given vector.
+class NoteAllFilesZipProcessor : public PureZipExtractorProcessor {
+ public:
+  explicit NoteAllFilesZipProcessor(std::vector<std::string> *files);
+
+  bool AcceptPure(const char *filename,
+                  const devtools_ijar::u4 attr) const override;
+
+  bool Accept(const char *filename, const devtools_ijar::u4 attr) override;
+
+  void Process(const char *filename, const devtools_ijar::u4 attr,
+               const devtools_ijar::u1 *data, const size_t size) override;
+
+ private:
+  std::vector<std::string> *files_;
+};
+
+// A PureZipExtractorProcessor to extract the files from the blaze zip.
+class ExtractBlazeZipProcessor : public PureZipExtractorProcessor {
+ public:
+  explicit ExtractBlazeZipProcessor(const string &embedded_binaries,
+                                    blaze::embedded_binaries::Dumper *dumper);
+
+  bool AcceptPure(const char *filename,
+                  const devtools_ijar::u4 attr) const override;
+
+  bool Accept(const char *filename, const devtools_ijar::u4 attr) override {
+    return AcceptPure(filename, attr);
+  }
+
+  void Process(const char *filename, const devtools_ijar::u4 attr,
+               const devtools_ijar::u1 *data, const size_t size) override;
+
+ private:
+  const string embedded_binaries_;
+  blaze::embedded_binaries::Dumper *dumper_;
+};
+
+}  // namespace blaze
+
+#endif  // BAZEL_SRC_MAIN_CPP_ARCHIVE_UTILS_H_
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index 272d20f..23ee05c 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -28,18 +28,17 @@
 #include <assert.h>
 #include <ctype.h>
 #include <fcntl.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 #include <grpcpp/channel.h>
 #include <grpcpp/client_context.h>
 #include <grpcpp/create_channel.h>
 #include <grpcpp/security/credentials.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <algorithm>
 #include <chrono>  // NOLINT (gRPC requires this)
@@ -53,6 +52,7 @@
 #include <utility>
 #include <vector>
 
+#include "src/main/cpp/archive_utils.h"
 #include "src/main/cpp/blaze_util.h"
 #include "src/main/cpp/blaze_util_platform.h"
 #include "src/main/cpp/global_variables.h"
@@ -69,9 +69,8 @@
 #include "src/main/cpp/util/port.h"
 #include "src/main/cpp/util/strings.h"
 #include "src/main/cpp/workspace_layout.h"
-#include "third_party/ijar/zip.h"
-
 #include "src/main/protobuf/command_server.grpc.pb.h"
+#include "third_party/ijar/zip.h"
 
 using blaze_util::GetLastErrorString;
 
@@ -255,109 +254,10 @@
 ////////////////////////////////////////////////////////////////////////
 // Logic
 
-// A devtools_ijar::ZipExtractorProcessor that has a pure version of Accept.
-class PureZipExtractorProcessor : public devtools_ijar::ZipExtractorProcessor {
- public:
-  virtual ~PureZipExtractorProcessor() {}
 
-  // Like devtools_ijar::ZipExtractorProcessor::Accept, but is guaranteed to not
-  // have side-effects.
-  virtual bool AcceptPure(const char *filename,
-                          const devtools_ijar::u4 attr) const = 0;
-};
-
-// A PureZipExtractorProcessor that adds the names of all the files ZIP up in
-// the Blaze binary to the given vector.
-class NoteAllFilesZipProcessor : public PureZipExtractorProcessor {
- public:
-  explicit NoteAllFilesZipProcessor(std::vector<std::string>* files)
-      : files_(files) {}
-
-  bool AcceptPure(const char *filename,
-                  const devtools_ijar::u4 attr) const override {
-    return false;
-  }
-
-  bool Accept(const char *filename, const devtools_ijar::u4 attr) override {
-    files_->push_back(filename);
-    return false;
-  }
-
-  void Process(const char *filename, const devtools_ijar::u4 attr,
-               const devtools_ijar::u1 *data, const size_t size) override {
-    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
-        << "NoteAllFilesZipProcessor::Process shouldn't be called";
-  }
- private:
-  std::vector<std::string>* files_;
-};
-
-// A devtools_ijar::ZipExtractorProcessor that processes the ZIP entries using
-// the given PureZipExtractorProcessors.
-class CompoundZipProcessor : public devtools_ijar::ZipExtractorProcessor {
- public:
-  explicit CompoundZipProcessor(
-      const vector<PureZipExtractorProcessor*>& processors)
-      : processors_(processors) {}
-
-  bool Accept(const char *filename, const devtools_ijar::u4 attr) override {
-    bool should_accept = false;
-    for (auto* processor : processors_) {
-      if (processor->Accept(filename, attr)) {
-        // ZipExtractorProcessor::Accept is allowed to be side-effectful, so
-        // we don't want to break out on the first true here.
-        should_accept = true;
-      }
-    }
-    return should_accept;
-  }
-
-  void Process(const char *filename, const devtools_ijar::u4 attr,
-               const devtools_ijar::u1 *data, const size_t size) override {
-    for (auto* processor : processors_) {
-      if (processor->AcceptPure(filename, attr)) {
-        processor->Process(filename, attr, data, size);
-      }
-    }
-  }
-
- private:
-  const vector<PureZipExtractorProcessor*> processors_;
-};
 
 static map<string, EnvVarValue> PrepareEnvironmentForJvm();
 
-// A PureZipExtractorProcessor to extract the InstallKeyFile
-class GetInstallKeyFileProcessor : public PureZipExtractorProcessor {
- public:
-  explicit GetInstallKeyFileProcessor(string *install_base_key)
-      : install_base_key_(install_base_key) {}
-
-  bool AcceptPure(const char *filename,
-                  const devtools_ijar::u4 attr) const override {
-    return strcmp(filename, "install_base_key") == 0;
-  }
-
-  bool Accept(const char *filename, const devtools_ijar::u4 attr) override {
-    return AcceptPure(filename, attr);
-  }
-
-  void Process(const char *filename, const devtools_ijar::u4 attr,
-               const devtools_ijar::u1 *data, const size_t size) override {
-    string str(reinterpret_cast<const char *>(data), size);
-    blaze_util::StripWhitespace(&str);
-    if (str.size() != 32) {
-      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
-          << "Failed to extract install_base_key: file size mismatch "
-             "(should be 32, is "
-          << str.size() << ")";
-    }
-    *install_base_key_ = str;
-  }
-
- private:
-  string *install_base_key_;
-};
 
 // Populates globals->install_md5 and globals->extracted_binaries by reading the
 // ZIP entries in the Blaze binary.
@@ -904,33 +804,6 @@
       << "couldn't connect to server (" << server_pid << ") after 120 seconds.";
 }
 
-// A PureZipExtractorProcessor to extract the files from the blaze zip.
-class ExtractBlazeZipProcessor : public PureZipExtractorProcessor {
- public:
-  explicit ExtractBlazeZipProcessor(const string &embedded_binaries,
-                                    blaze::embedded_binaries::Dumper *dumper)
-      : embedded_binaries_(embedded_binaries), dumper_(dumper) {}
-
-  bool AcceptPure(const char *filename,
-                  const devtools_ijar::u4 attr) const override {
-    return !devtools_ijar::zipattr_is_dir(attr);
-  }
-
-  bool Accept(const char *filename, const devtools_ijar::u4 attr) override {
-    return AcceptPure(filename, attr);
-  }
-
-  void Process(const char *filename, const devtools_ijar::u4 attr,
-               const devtools_ijar::u1 *data, const size_t size) override {
-    dumper_->Dump(data, size,
-                  blaze_util::JoinPath(embedded_binaries_, filename));
-  }
-
- private:
-  const string embedded_binaries_;
-  blaze::embedded_binaries::Dumper *dumper_;
-};
-
 // Actually extracts the embedded data files into the tree whose root
 // is 'embedded_binaries'.
 static void ActuallyExtractData(const string &argv0,