#include #include #include #include #include "bootstrap.h" #include "patchelf.h" // Duplicate MCPI Executable Into /tmp static void duplicate_mcpi_executable() { // Get Original Path const char *original_path = getenv("MCPI_EXECUTABLE_PATH"); // Generate New File char new_path[] = "/tmp/.minecraft-pi-XXXXXX"; int new_file_fd = mkstemp(new_path); if (new_file_fd == -1) { ERR("Unable To Create Temporary File: %s", strerror(errno)); } FILE *new_file = fdopen(new_file_fd, "wb"); if (new_file == NULL) { ERR("Unable To Open Temporary File: %s", strerror(errno)); } set_and_print_env("MCPI_EXECUTABLE_PATH", new_path); // Copy Original File { // Open Original File FILE *original_file = fopen(original_path, "rb"); if (original_file == NULL) { ERR("Unable To Open File: %s", original_path); } // Copy #define BUFFER_SIZE 1024 char buf[BUFFER_SIZE]; size_t bytes_read = 0; while ((bytes_read = fread((void *) buf, 1, BUFFER_SIZE, original_file)) > 0) { fwrite((void *) buf, 1, bytes_read, new_file); if (ferror(new_file) != 0) { ERR("Unable To Write File: %s", new_path); } } if (ferror(original_file) != 0) { ERR("Unable To Read File: %s", original_path); } // Close Original File fclose(original_file); } // Close New File fclose(new_file); close(new_file_fd); } // Fix MCPI Dependencies #define patch_mcpi_elf_dependencies_with_extra_patchelf_args(...) \ ({ \ const char *const _macro_command[] = { \ "patchelf", \ ##__VA_ARGS__, \ "--remove-needed", "libbcm_host.so", \ "--remove-needed", "libX11.so.6", \ "--remove-needed", "libEGL.so", \ "--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \ exe, \ NULL \ }; \ int _macro_return_code = 0; \ char *_macro_output = run_command(_macro_command, &_macro_return_code); \ if (_macro_output != NULL) { \ free(_macro_output); \ } \ _macro_return_code; \ }) void patch_mcpi_elf_dependencies(const char *linker) { // Duplicate MCPI executable into /tmp so it can be modified. duplicate_mcpi_executable(); // Get Path char *exe = getenv("MCPI_EXECUTABLE_PATH"); // Run patchelf int return_code; if (linker == NULL) { return_code = patch_mcpi_elf_dependencies_with_extra_patchelf_args(); } else { return_code = patch_mcpi_elf_dependencies_with_extra_patchelf_args("--set-interpreter", linker); } if (return_code != 0) { ERR("patchelf Failed: Exit Code: %i", return_code); } // Fix Permissions if (chmod(exe, S_IRUSR | S_IXUSR) != 0) { ERR("Unable To Set File Permissions: %s: %s", exe, strerror(errno)); } }