Ejemplo n.º 1
0
std::map<std::string, std::string> Extract(std::string file, std::string prefix) {
  std::map<std::string, std::string> files;
#ifdef HAVE_LIBXAR
  xar_t x;
  xar_iter_t xi;
  xar_file_t xf;
  xar_stream xs;
  char buffer[8192];

  x = xar_open(file.c_str(), READ);
  if (x == nullptr) {
    std::cerr << "Could not open xar archive" << std::endl;
  }

  xi = xar_iter_new();
  if (xi == nullptr) {
    xar_close(x);
    std::cerr << "Could not read xar archive" << std::endl;
  }

  for (xf = xar_file_first(x, xi); xf != nullptr; xf = xar_file_next(xi)) {
    char *path = xar_get_path(xf);
    const char *type;
    xar_prop_get(xf, "type", &type);

    if (type == nullptr) {
      std::cerr << "File has no type" << std::endl;
      free(path);
      continue;
    }

    if (std::strcmp(type, "file") != 0) {
      free(path);
      continue;
    }

    if (xar_extract_tostream_init(x, xf, &xs) != XAR_STREAM_OK) {
      std::cerr << "Error initializing stream" << std::endl;
      free(path);
      continue;
    }

    const std::string fileName = prefix + util::uuid::UuidToString(util::uuid::GenerateUUID());

    // Write bitcode to file
    std::FILE *output = std::fopen(fileName.c_str(), "wb");
    if (output == nullptr) {
      std::cerr << "Error opening output file" << std::endl;
      continue;
    }

    xs.avail_out = sizeof(buffer);
    xs.next_out = buffer;

    int32_t ret;
    while ((ret = xar_extract_tostream(&xs)) != XAR_STREAM_END) {
      if (ret == XAR_STREAM_ERR) {
        std::cerr << "Error extracting stream" << std::endl;
        break;
      }
      std::fwrite(buffer, sizeof(char), sizeof(buffer) - xs.avail_out, output);

      xs.avail_out = sizeof(buffer);
      xs.next_out = buffer;
    }

    if (xar_extract_tostream_end(&xs) != XAR_STREAM_OK) {
      std::cerr << "Error ending stream" << std::endl;
    }

    std::fclose(output);

    // Add to list of extracted files
    files[std::string(path)] = fileName;

    free(path);
  }

  xar_iter_free(xi);
  xar_close(x);
#endif
  return files;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;
	xar_stream s;
	char buffer[8192];

	x = xar_open(argv[1], READ);
	if( !x ) {
		fprintf(stderr, "Error opening archive\n");
		exit(1);
	}

	xar_register_errhandler(x, err_callback, NULL);

	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		char *path;
		const char *type;
		int32_t ret;
		int fd;

		path = xar_get_path(f);

		xar_prop_get(f, "type", &type);
		if( !type ) {
			fprintf(stderr, "File has no type %s\n", path);
			free(path);
			continue;
		}
		if( strcmp(type, "file") != 0 ) {
			fprintf(stderr, "Skipping %s\n", path);
			free(path);
			continue;
		}
	
		fprintf(stderr, "Extracting %s\n", path);
		if( xar_extract_tostream_init(x, f, &s) != XAR_STREAM_OK ) {
			fprintf(stderr, "Error initializing stream %s\n", path);
			free(path);
			continue;
		}
		
		fd = open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
		if( !fd ) {
			fprintf(stderr, "Error opening output file %s\n", path);
			free(path);
			continue;
		}
		s.avail_out = sizeof(buffer);
		s.next_out = buffer;

		while( (ret = xar_extract_tostream(&s)) != XAR_STREAM_END ) {
			if( ret == XAR_STREAM_ERR ) {
				fprintf(stderr, "Error extracting stream %s\n", path);
				exit(2);
			}

			write(fd, buffer, sizeof(buffer)-s.avail_out);

			s.avail_out = sizeof(buffer);
			s.next_out = buffer;
		}

		if( xar_extract_tostream_end(&s) != XAR_STREAM_OK ) {
			fprintf(stderr, "Error ending stream %s\n", path);
		}

		close(fd);
		free(path);
	}
}