int main(int argc, char** argv) {
    if (argc == 2) {
        if (strcmp(argv[1], "--reboot") == 0) {
            reboot_to_recovery();
        } else if (strcmp(argv[1], "--clear-bcb") == 0) {
            return clear_bcb(STATUS_FILE);
        } else if (strcmp(argv[1], "--setup-bcb") == 0) {
            return setup_bcb(COMMAND_FILE, STATUS_FILE);
        } else if (strcmp(argv[1], "--read-bcb") == 0) {
            return read_bcb();
        }
    } else if (argc == 1 || argc == 3) {
        const char* input_path = nullptr;
        const char* map_file = CACHE_BLOCK_MAP.c_str();
        if (argc == 3) {
            input_path = argv[1];
            map_file = argv[2];
        }
        return uncrypt_wrapper(input_path, map_file, STATUS_FILE);
    }
    usage(argv[0]);
    return 2;
}
Пример #2
0
int main(int argc, char** argv) {
    enum { UNCRYPT, SETUP_BCB, CLEAR_BCB, UNCRYPT_DEBUG } action;
    const char* input_path = nullptr;
    const char* map_file = CACHE_BLOCK_MAP.c_str();

    if (argc == 2 && strcmp(argv[1], "--clear-bcb") == 0) {
        action = CLEAR_BCB;
    } else if (argc == 2 && strcmp(argv[1], "--setup-bcb") == 0) {
        action = SETUP_BCB;
    } else if (argc == 1) {
        action = UNCRYPT;
    } else if (argc == 3) {
        input_path = argv[1];
        map_file = argv[2];
        action = UNCRYPT_DEBUG;
    } else {
        usage(argv[0]);
        return 2;
    }

    if ((fstab = read_fstab()) == nullptr) {
        log_uncrypt_error_code(kUncryptFstabReadError);
        return 1;
    }

    if (action == UNCRYPT_DEBUG) {
        LOG(INFO) << "uncrypt called in debug mode, skip socket communication";
        bool success = uncrypt_wrapper(input_path, map_file, -1);
        if (success) {
            LOG(INFO) << "uncrypt succeeded";
        } else{
            LOG(INFO) << "uncrypt failed";
        }
        return success ? 0 : 1;
    }

    // c3. The socket is created by init when starting the service. uncrypt
    // will use the socket to communicate with its caller.
    android::base::unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str()));
    if (service_socket == -1) {
        PLOG(ERROR) << "failed to open socket \"" << UNCRYPT_SOCKET << "\"";
        log_uncrypt_error_code(kUncryptSocketOpenError);
        return 1;
    }
    fcntl(service_socket, F_SETFD, FD_CLOEXEC);

    if (listen(service_socket, 1) == -1) {
        PLOG(ERROR) << "failed to listen on socket " << service_socket.get();
        log_uncrypt_error_code(kUncryptSocketListenError);
        return 1;
    }

    android::base::unique_fd socket_fd(accept4(service_socket, nullptr, nullptr, SOCK_CLOEXEC));
    if (socket_fd == -1) {
        PLOG(ERROR) << "failed to accept on socket " << service_socket.get();
        log_uncrypt_error_code(kUncryptSocketAcceptError);
        return 1;
    }

    bool success = false;
    switch (action) {
        case UNCRYPT:
            success = uncrypt_wrapper(input_path, map_file, socket_fd);
            break;
        case SETUP_BCB:
            success = setup_bcb(socket_fd);
            break;
        case CLEAR_BCB:
            success = clear_bcb(socket_fd);
            break;
        default:  // Should never happen.
            LOG(ERROR) << "Invalid uncrypt action code: " << action;
            return 1;
    }

    // c13. Read a 4-byte code from the client before uncrypt exits. This is to
    // ensure the client to receive the last status code before the socket gets
    // destroyed.
    int code;
    if (android::base::ReadFully(socket_fd, &code, 4)) {
        LOG(INFO) << "  received " << code << ", exiting now";
    } else {
        PLOG(ERROR) << "failed to read the code";
    }
    return success ? 0 : 1;
}