/* Return a pointer to the next file in the archive `a' */
static struct pkg_file *
freebsd_get_next_entry(struct archive *a)
{
	uint64_t length;
	char *str;
	struct archive_entry *entry;
	const struct stat *sb;

	assert(a != NULL);

	/* Read the next entry to a buffer. */
	if (archive_read_next_header(a, &entry) != ARCHIVE_OK) {
		return NULL;
	}

	/* Allocate enough space for the file and copy it to the string */
	length = archive_entry_size(entry);
	str = malloc(length+1);
	if (!str) {
		return NULL;
	}
	archive_read_data_into_buffer(a, str, length);
	str[length] = '\0';

	/* Get the needed struct stat from the archive */
	sb = archive_entry_stat(entry);

	/* Create the pkg_file and return it */
	return pkg_file_new_from_buffer(archive_entry_pathname(entry),
		length, str, sb);
}
Beispiel #2
0
inline void genSafariExtension(const std::string& path, QueryData& results) {
  Row r;
  r["path"] = path;

  // Loop through (Plist key -> table column name) in kSafariExtensionKeys.
  struct archive* ext = archive_read_new();
  if (ext == nullptr) {
    return;
  }

  // Use open_file, instead of the preferred open_filename for OS X 10.9.
  archive_read_support_format_xar(ext);
  if (archive_read_open_file(ext, path.c_str(), 10240) != ARCHIVE_OK) {
    archive_read_finish(ext);
    return;
  }

  struct archive_entry* entry = nullptr;
  while (archive_read_next_header(ext, &entry) == ARCHIVE_OK) {
    auto item_path = archive_entry_pathname(entry);
    // Documentation for libarchive mentions these APIs may return NULL.
    if (item_path == nullptr) {
      archive_read_data_skip(ext);
      continue;
    }

    // Assume there is no non-root Info.
    if (std::string(item_path).find("Info.plist") == std::string::npos) {
      archive_read_data_skip(ext);
      continue;
    }

    // Read the decompressed Info.plist content.
    auto content = std::string(archive_entry_size(entry), '\0');
    archive_read_data_into_buffer(ext, &content[0], content.size());

    // If the Plist can be parsed, extract important keys into columns.
    pt::ptree tree;
    if (parsePlistContent(content, tree).ok()) {
      for (const auto& it : kSafariExtensionKeys) {
        r[it.second] = tree.get(it.first, "");
      }
    }
    break;
  }

  archive_read_close(ext);
  archive_read_finish(ext);
  results.push_back(std::move(r));
}