Public feed #603672

Unnamed

public text v1 · immutable
Raw Edit
·published 2007-07-04 23:57 UTC
rendered paste body
/* ----------------------------------------------------------------------------
 *   iphoneclient - an experimental iPhone access client   v0.01 - 07/03/2007
 *
 *   Place MobileDevice.h in the Headers/ directory in MobileDevice.framework
 *   and link with that framework to compile.
 * ------------------------------------------------------------------------- */

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <CoreFoundation/CoreFoundation.h>
#include <MobileDevice/MobileDevice.h>

struct option program_options[] = {
    { "list-recursive", no_argument,    NULL,   'l' },
    { "restore",        no_argument,    NULL,   'r' },
    { NULL,             0,              NULL,   0 }
}; 

void recursive_ls(struct afc_connection *conn, char *path)
{
    char *dirent;
    char *newpath;
    int i;
    mach_error_t err;
    struct afc_directory *dir;

    err = AFCDirectoryOpen(conn, path, &dir);
    if (err)
        return;

    while (1) {
        err = AFCDirectoryRead(0, dir, &dirent);
        if (err || !dirent)
            return;

        if (!strcmp(dirent, ".") || !strcmp(dirent, ".."))
            continue;

        printf("%s%s\n", path, dirent);
        asprintf(&newpath, "%s%s/", path, dirent);

        recursive_ls(conn, newpath);

        free(newpath);
    }
}

void device_notification_callback(struct am_device_notification_callback_info *
    info)
{
    int i;
    mach_error_t err;
    struct afc_connection *conn;
    struct afc_device_info *dinfo;
    struct am_device *dev = info->dev;
    unsigned int afc_handle;

    fprintf(stderr, "device notification callback: got info with msg %d\n",
        info->msg);

    err = AMDeviceConnect(dev); 
    fprintf(stderr, "AMDeviceConnect: %08x\n", err);
    err = AMDeviceIsPaired(dev); 
    fprintf(stderr, "AMDeviceIsPaired: %08x\n", err);
    err = AMDeviceValidatePairing(dev); 
    fprintf(stderr, "AMDeviceValidatePairing: %08x\n", err);
    err = AMDeviceStartSession(dev);
    fprintf(stderr, "AMDeviceStartSession: %08x\n", err);
    err = AMDeviceStartService(dev, AMSVC_AFC, &afc_handle, NULL);
    fprintf(stderr, "AMDeviceStartService: %08x\n", err);
    err = AMDeviceStopSession(dev);
    fprintf(stderr, "AMDeviceStopSession: %08x\n", err);
    err = AFCConnectionOpen(afc_handle, 0, &conn); 
    fprintf(stderr, "AFCConnectionOpen: %08x\n", err);
    err = AFCDeviceInfoOpen(conn, &dinfo);
    fprintf(stderr, "AFCDeviceInfoOpen: %08x\n", err);
    AFCPlatformInit();

    recursive_ls(conn, "/");
}

void do_recursive_list()
{
    mach_error_t err;
    struct am_device_notification *notif;

    err = AMDeviceNotificationSubscribe(device_notification_callback, 0, 0, 0,
        &notif);
    fprintf(stderr, "AMDeviceNotificationSubscribe: %08x\n", err);

    fprintf(stderr, "Running...\n");

    CFRunLoopRun();
}

void recovery_progress_callback()
{
    fprintf(stderr, "Recovery progress callback...\n");
}

void recovery_connect_callback(struct am_recovery_device *rdev)
{
    CFMutableDictionaryRef opts;
    mach_error_t err;

    fprintf(stderr, "got a recovery connection\n"); 

    /* Get 'er into restore mode... */
    err = AMRestoreEnableFileLogging("restore.log");
    fprintf(stderr, "AMRestoreEnableFileLogging: %08x\n", err);
    opts = AMRestoreCreateDefaultOptions(kCFAllocatorDefault);
    CFDictionarySetValue(opts, CFSTR("RestoreBundlePath"),
        CFSTR("/Users/pcwalton/Projects/iphone/iphone-files")); /* FIXME */
    CFShow(opts);
    err = AMRestorePerformRecoveryModeRestore(rdev, opts,
        recovery_progress_callback, NULL); 
    fprintf(stderr, "AMRestorePerformRecoveryModeRestore: %08x\n", err);
}

void recovery_disconnect_callback(struct am_recovery_device *rdev)
{
    fprintf(stderr, "disconnected from recovery mode\n");
}

void restore_regular_device_notification_callback(struct
    am_device_notification_callback_info *info)
{
    mach_error_t err;
    struct am_device *dev = info->dev;

    fprintf(stderr, "restore regular device notification callback: got info "
        "with msg %d\n", info->msg);
    err = AMDeviceConnect(dev); 
    fprintf(stderr, "AMDeviceConnect: %08x\n", err);
    err = AMDeviceIsPaired(dev); 
    fprintf(stderr, "AMDeviceIsPaired: %08x\n", err);
    err = AMDeviceValidatePairing(dev); 
    fprintf(stderr, "AMDeviceValidatePairing: %08x\n", err);
    err = AMDeviceStartSession(dev);
    fprintf(stderr, "AMDeviceStartSession: %08x\n", err);
    err = AMDeviceEnterRecovery(dev); 
    fprintf(stderr, "AMDeviceEnterRecovery: %08x\n", err);
}

void do_restore()
{
    mach_error_t err;
    struct am_device_notification *notif;

    err = AMRestoreRegisterForDeviceNotifications(NULL,
        recovery_connect_callback, NULL, recovery_disconnect_callback, 0,
        NULL); 
    fprintf(stderr, "AMRestoreRegisterForDeviceNotifications: %08x\n", err);
    err = AMDeviceNotificationSubscribe(
        restore_regular_device_notification_callback, 0, 0, 0, &notif);
    fprintf(stderr, "AMDeviceNotificationSubscribe: %08x\n", err);

    fprintf(stderr, "Running...\n");

    CFRunLoopRun();
}

int main(int argc, char **argv)
{
    int ch;

    while ((ch = getopt_long(argc, argv, "lr", program_options, NULL)))
        switch (ch) {
            case 'l':   do_recursive_list();    break;
            case 'r':   do_restore();           break;

            default:
                fprintf(stderr, "usage: %s [--list-recursive|--restore]\n",
                    argv[0]);
                return 0;
        }

    return 0;
}