mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 06:26:15 +01:00
Update C examples for new FFI
This commit is contained in:
@@ -7,187 +7,189 @@
|
||||
#include <unistd.h>
|
||||
|
||||
void print_usage() {
|
||||
printf("Usage: ipa_installer [options] <ipa_path>\n");
|
||||
printf("Options:\n");
|
||||
printf(" --ip IP_ADDRESS Device IP address (default: 10.7.0.2)\n");
|
||||
printf(" --pairing FILE Pairing file path (default: pairing_file.plist)\n");
|
||||
printf(" --udid UDID Device UDID (optional)\n");
|
||||
printf("Usage: ipa_installer [options] <ipa_path>\n");
|
||||
printf("Options:\n");
|
||||
printf(" --ip IP_ADDRESS Device IP address (default: 10.7.0.2)\n");
|
||||
printf(" --pairing FILE Pairing file path (default: "
|
||||
"pairing_file.plist)\n");
|
||||
printf(" --udid UDID Device UDID (optional)\n");
|
||||
}
|
||||
|
||||
int read_file(const char *filename, uint8_t **data, size_t *length) {
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
perror("Failed to open file");
|
||||
return 0;
|
||||
}
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
perror("Failed to open file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
*length = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
*data = malloc(*length);
|
||||
if (!*data) {
|
||||
perror("Failed to allocate memory");
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fread(*data, 1, *length, file) != *length) {
|
||||
perror("Failed to read file");
|
||||
free(*data);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
fseek(file, 0, SEEK_END);
|
||||
*length = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
*data = malloc(*length);
|
||||
if (!*data) {
|
||||
perror("Failed to allocate memory");
|
||||
fclose(file);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fread(*data, 1, *length, file) != *length) {
|
||||
perror("Failed to read file");
|
||||
free(*data);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Initialize logger
|
||||
idevice_init_logger(Debug, Disabled, NULL);
|
||||
// Initialize logger
|
||||
idevice_init_logger(Debug, Disabled, NULL);
|
||||
|
||||
// Default values
|
||||
char *ip = "10.7.0.2";
|
||||
char *pairing_file_path = "pairing_file.plist";
|
||||
char *udid = NULL;
|
||||
char *ipa_path = NULL;
|
||||
// Default values
|
||||
char *ip = "10.7.0.2";
|
||||
char *pairing_file_path = "pairing_file.plist";
|
||||
char *udid = NULL;
|
||||
char *ipa_path = NULL;
|
||||
|
||||
// Parse arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--ip") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
printf("Error: Missing IP address argument\n");
|
||||
return 1;
|
||||
}
|
||||
ip = argv[++i];
|
||||
} else if (strcmp(argv[i], "--pairing") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
printf("Error: Missing pairing file argument\n");
|
||||
return 1;
|
||||
}
|
||||
pairing_file_path = argv[++i];
|
||||
} else if (strcmp(argv[i], "--udid") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
printf("Error: Missing UDID argument\n");
|
||||
return 1;
|
||||
}
|
||||
udid = argv[++i];
|
||||
} else if (strcmp(argv[i], "help") == 0) {
|
||||
print_usage();
|
||||
return 0;
|
||||
} else {
|
||||
ipa_path = argv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ipa_path) {
|
||||
print_usage();
|
||||
// Parse arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--ip") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
printf("Error: Missing IP address argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create the socket address
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(LOCKDOWN_PORT);
|
||||
if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1) {
|
||||
fprintf(stderr, "Invalid IP address\n");
|
||||
}
|
||||
ip = argv[++i];
|
||||
} else if (strcmp(argv[i], "--pairing") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
printf("Error: Missing pairing file argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read pairing file
|
||||
IdevicePairingFile *pairing_file = NULL;
|
||||
IdeviceErrorCode err = idevice_pairing_file_read(pairing_file_path, &pairing_file);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to read pairing file: %d\n", err);
|
||||
}
|
||||
pairing_file_path = argv[++i];
|
||||
} else if (strcmp(argv[i], "--udid") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
printf("Error: Missing UDID argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create TCP provider
|
||||
TcpProviderHandle *provider = NULL;
|
||||
err = idevice_tcp_provider_new((struct sockaddr *)&addr, pairing_file,
|
||||
"IPAInstaller", &provider);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to create TCP provider: %d\n", err);
|
||||
idevice_pairing_file_free(pairing_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Connect to AFC service
|
||||
AfcClientHandle *afc_client = NULL;
|
||||
err = afc_client_connect_tcp(provider, &afc_client);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to connect to AFC service: %d\n", err);
|
||||
tcp_provider_free(provider);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Extract filename from path
|
||||
char *filename = strrchr(ipa_path, '/');
|
||||
if (filename == NULL) {
|
||||
filename = ipa_path;
|
||||
}
|
||||
udid = argv[++i];
|
||||
} else if (strcmp(argv[i], "help") == 0) {
|
||||
print_usage();
|
||||
return 0;
|
||||
} else {
|
||||
filename++; // Skip the '/'
|
||||
ipa_path = argv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create destination path
|
||||
char dest_path[256];
|
||||
snprintf(dest_path, sizeof(dest_path), "/PublicStaging/%s", filename);
|
||||
if (!ipa_path) {
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Upload IPA file
|
||||
printf("Uploading %s to %s...\n", ipa_path, dest_path);
|
||||
uint8_t *data = NULL;
|
||||
size_t length = 0;
|
||||
if (!read_file(ipa_path, &data, &length)) {
|
||||
fprintf(stderr, "Failed to read IPA file\n");
|
||||
afc_client_free(afc_client);
|
||||
return 1;
|
||||
}
|
||||
// Create the socket address
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(LOCKDOWN_PORT);
|
||||
if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1) {
|
||||
fprintf(stderr, "Invalid IP address\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
AfcFileHandle *file = NULL;
|
||||
err = afc_file_open(afc_client, dest_path, AfcWrOnly | AfcCreat, &file);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to open destination file: %d\n", err);
|
||||
free(data);
|
||||
afc_client_free(afc_client);
|
||||
return 1;
|
||||
}
|
||||
// Read pairing file
|
||||
IdevicePairingFile *pairing_file = NULL;
|
||||
IdeviceErrorCode err =
|
||||
idevice_pairing_file_read(pairing_file_path, &pairing_file);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to read pairing file: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = afc_file_write(file, data, length);
|
||||
free(data);
|
||||
afc_file_close(file);
|
||||
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to write file: %d\n", err);
|
||||
afc_client_free(afc_client);
|
||||
return 1;
|
||||
}
|
||||
printf("Upload completed successfully\n");
|
||||
// Create TCP provider
|
||||
IdeviceProviderHandle *provider = NULL;
|
||||
err = idevice_tcp_provider_new((struct sockaddr *)&addr, pairing_file,
|
||||
"IPAInstaller", &provider);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to create TCP provider: %d\n", err);
|
||||
idevice_pairing_file_free(pairing_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Connect to installation proxy
|
||||
InstallationProxyClientHandle *instproxy_client = NULL;
|
||||
err = installation_proxy_connect_tcp(provider, &instproxy_client);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to connect to installation proxy: %d\n", err);
|
||||
afc_client_free(afc_client);
|
||||
return 1;
|
||||
}
|
||||
// Connect to AFC service
|
||||
AfcClientHandle *afc_client = NULL;
|
||||
err = afc_client_connect(provider, &afc_client);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to connect to AFC service: %d\n", err);
|
||||
idevice_provider_free(provider);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Install the uploaded IPA
|
||||
printf("Installing %s...\n", dest_path);
|
||||
err = installation_proxy_install(instproxy_client, dest_path, NULL);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to install IPA: %d\n", err);
|
||||
} else {
|
||||
printf("Installation completed successfully\n");
|
||||
}
|
||||
// Extract filename from path
|
||||
char *filename = strrchr(ipa_path, '/');
|
||||
if (filename == NULL) {
|
||||
filename = ipa_path;
|
||||
} else {
|
||||
filename++; // Skip the '/'
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
installation_proxy_client_free(instproxy_client);
|
||||
// Create destination path
|
||||
char dest_path[256];
|
||||
snprintf(dest_path, sizeof(dest_path), "/PublicStaging/%s", filename);
|
||||
|
||||
// Upload IPA file
|
||||
printf("Uploading %s to %s...\n", ipa_path, dest_path);
|
||||
uint8_t *data = NULL;
|
||||
size_t length = 0;
|
||||
if (!read_file(ipa_path, &data, &length)) {
|
||||
fprintf(stderr, "Failed to read IPA file\n");
|
||||
afc_client_free(afc_client);
|
||||
tcp_provider_free(provider);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return err == IdeviceSuccess ? 0 : 1;
|
||||
AfcFileHandle *file = NULL;
|
||||
err = afc_file_open(afc_client, dest_path, AfcWrOnly, &file);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to open destination file: %d\n", err);
|
||||
free(data);
|
||||
afc_client_free(afc_client);
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = afc_file_write(file, data, length);
|
||||
free(data);
|
||||
afc_file_close(file);
|
||||
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to write file: %d\n", err);
|
||||
afc_client_free(afc_client);
|
||||
return 1;
|
||||
}
|
||||
printf("Upload completed successfully\n");
|
||||
|
||||
// Connect to installation proxy
|
||||
InstallationProxyClientHandle *instproxy_client = NULL;
|
||||
err = installation_proxy_connect_tcp(provider, &instproxy_client);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to connect to installation proxy: %d\n", err);
|
||||
afc_client_free(afc_client);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Install the uploaded IPA
|
||||
printf("Installing %s...\n", dest_path);
|
||||
err = installation_proxy_install(instproxy_client, dest_path, NULL);
|
||||
if (err != IdeviceSuccess) {
|
||||
fprintf(stderr, "Failed to install IPA: %d\n", err);
|
||||
} else {
|
||||
printf("Installation completed successfully\n");
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
installation_proxy_client_free(instproxy_client);
|
||||
afc_client_free(afc_client);
|
||||
idevice_provider_free(provider);
|
||||
|
||||
return err == IdeviceSuccess ? 0 : 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user