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; }
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); } }