All pastes #615402 Raw Edit

Mine

public text v1 · immutable
·published 2007-07-12 03:21 UTC
rendered paste body
#include <stdio.h>
#include <stdlib.h>
#include <readline/history.h>
#include <readline/readline.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <CoreFoundation/CoreFoundation.h>
#include <MobileDevice/MobileDevice.h>

void put_file(struct afc_connection *conn, char *local_path, char *remote_path)
{
    FILE *f;
    struct stat sb;
    unsigned char *buf;
    unsigned int size;
    afc_file_ref ref;

    f = fopen(local_path, "r");
    if (!f) {
        printf("failed to open local file\n");
        return;
    }

    size = fstat(fileno(f), &sb);
    buf = (unsigned char *)malloc(sb.st_size);
    fread(buf, sb.st_size, 1, f);
    fclose(f);

    if (AFCFileRefOpen(conn, remote_path, 3, 0, &ref)) {
        printf("failed to open remote file\n");
        return;
    }
    if (AFCFileRefWrite(conn, ref, buf, sb.st_size)) {
        printf("failed to write to remote file\n");
        return;
    }
    if (AFCFileRefClose(conn, ref)) {
        printf("failed to close remote file\n");
        return;
    }

    free(buf);

    printf("put command successful\n");
}

unsigned int get_file_size(struct afc_connection *conn, char *path)
{
    char *key, *val;
    unsigned int size;
    struct afc_dictionary *info;

    if (AFCFileInfoOpen(conn, path, &info))
        return 0;

    while (1) {
        AFCKeyValueRead(info, &key, &val);
        if (!key || !val)
            break;

        if (!strcmp(key, "st_size")) {
            sscanf(val, "%u", &size);
            AFCKeyValueClose(info);
            return size;
        }
    }

    AFCKeyValueClose(info);

    return 0;
}

void get_file(struct afc_connection *conn, char *local_path, char *remote_path)
{
    FILE *f;
    unsigned char *buf;
    unsigned int size = get_file_size(conn, remote_path); 
    afc_file_ref ref;

    if (AFCFileRefOpen(conn, remote_path, 2, 0, &ref)) {
        printf("failed to open remote file\n");
        return;
    }

    buf = (unsigned char *)malloc(size);
    if (AFCFileRefRead(conn, ref, buf, &size)) {
        printf("failed to read from file\n");
        return;
    }

    if (AFCFileRefClose(conn, ref)) {
        printf("failed to close remote file\n");
        return;
    }

    f = fopen(local_path, "w");
    if (!f) {
        printf("failed to open local file\n");
        return;
    }

    fwrite(buf, size, 1, f);

    fclose(f);
    free(buf);

    printf("transfer successful\n");
}

void run_afc(struct am_device *dev, unsigned int afch)
{
    char *line, *path, *tok, *dirent;
    struct afc_connection *conn;
    struct afc_directory *dir;

    AFCConnectionOpen(afch, 0, &conn);
    AFCPlatformInit();

    fprintf(stderr, "done.\n");
    path = strdup("/");

    while (1) {
        line = readline("(afc) ");
        if (!line)
            break;
        if (!(line[0]))
            continue;
        add_history(line);

        tok = strsep(&line, " ");
        if (!strcmp(tok, "pwd"))
            printf("%s\n", path);
        else if (!strcmp(tok, "cd")) {
            if (AFCDirectoryOpen(conn, line, &dir))
                printf("Failed.\n");
            free(path);
            path = strdup(line);
        } else if (!strcmp(tok, "ls")) {
            if (AFCDirectoryOpen(conn, path, &dir)) {
                printf("Failed.\n");
                continue;
            }

            while (1) {
                AFCDirectoryRead(0, dir, &dirent);
                if (!dirent)
                    break;
                printf("%s\n", dirent);
            }

            AFCDirectoryClose(0, dir);
        } else if (!strcmp(tok, "exit")) {
            AFCConnectionClose(conn);
            exit(0);
        } else if (!strcmp(tok, "put")) {
            tok = strsep(&line, " ");
            put_file(conn, tok, line);
        } else if (!strcmp(tok, "get")) {
            tok = strsep(&line, " ");
            get_file(conn, line, tok);
        } else if (!strcmp(tok, "size")) {
            printf("%u\n", get_file_size(conn, line));
        } else
            printf("Unknown command '%s'.\n", tok);
    }
}

void notification(struct am_device_notification_callback_info *info)
{
    struct am_device *dev = info->dev;
    unsigned int afch;
    unsigned int msg = info->msg;

    if (msg != 1)
        return;

    fprintf(stderr, "iPhone attached. Connecting...\n");

    AMDeviceConnect(dev);
    AMDeviceIsPaired(dev);
    AMDeviceValidatePairing(dev);
    AMDeviceStartSession(dev);
    AMDeviceStartService(dev, AMSVC_AFC, &afch, NULL);
    AMDeviceStopSession(dev);

    run_afc(dev, afch); 
}

int main()
{
    struct am_device_notification *notif; 

    AMDeviceNotificationSubscribe(notification, 0, 0, 0, &notif);

    fprintf(stderr, "Please connect an iPhone in normal mode.\n");

    CFRunLoopRun();

    return 0;
}