Beispiel #1
0
static bool
property_vector_append(struct property_vector* pv, const prop_info* pi)
{
    if (pv->size == pv->capacity) {
        size_t new_capacity;
        if (SATADD(&new_capacity, pv->capacity, pv->capacity))
            return false;

        if (new_capacity > SIZE_MAX / sizeof (const prop_info*))
            return false;

        size_t allocsz = new_capacity * sizeof (const prop_info*);

        const prop_info** new_props = resize_alloc(pv->props, allocsz);
        if (new_props == NULL)
            return false;

        pv->props = new_props;
        pv->capacity = new_capacity;
    }

    pv->props[pv->size++] = pi;
    return true;
}
Beispiel #2
0
int
logw_main(int argc, const char** argv)
{
    const char* tag = "fb-adb-logw";
    int priority = ANDROID_LOG_INFO;

    for (;;) {
        char c = getopt_long(argc,
                             (char**) argv,
                             logw_opts,
                             logw_longopts,
                             NULL);
        if (c == -1)
            break;

        switch (c) {
            case 't':
                tag = optarg;
                break;
            case 'r':
                priority = -1;
                char* xprio = xstrdup(optarg);
                tolower_inplace(xprio);
                size_t xprio_len = strlen(xprio);
                for (unsigned i = 0; i < ARRAYSIZE(log_levels); ++i) {
                    if (!strncmp(xprio, log_levels[i], xprio_len)) {
                        priority = ANDROID_LOG_VERBOSE + i;
                        break;
                    }
                }

                if (priority == -1)
                    die(EINVAL, "invalid logging priority \"%s\"", optarg);

                break;
            case ':':
                if (optopt == '\0') {
                    die(EINVAL, "missing argument for %s", argv[optind-1]);
                } else {
                    die(EINVAL, "missing argument for -%c", optopt);
                }
            case '?':
                if (optopt == '?') {
                    // Fall through to help
                } else if (optopt == '\0') {
                    die(EINVAL, "invalid option %s", argv[optind-1]);
                } else {
                    die(EINVAL, "invalid option -%d", (int) optopt);
                }
            case 'h':
                fputs(logw_usage, stdout);
                return 0;
            default:
                abort();
        }
    }

    argc -= optind;
    argv += optind;

    size_t sz = 1;
    for (int i = 0; i < argc; ++i) {
        if (SATADD(&sz, sz, strlen(argv[i]) + 1))
            die(EINVAL, "argument list too long");
    }

    char* msg = xalloc(sz);
    char* pos = msg;
    for (int i = 0; i < argc; ++i) {
        size_t len = strlen(argv[i]);
        memcpy(pos, argv[i], len);
        pos += len;
        if (i != argc -1)
            *pos++ = ' ';
    }

    msg[sz-1] = '\0';
    return __android_log_write(priority, tag, msg);
}
Beispiel #3
0
static void
send_stat_packet(int to_peer, int xfer_fd)
{
    struct stat st;
    if (fstat(xfer_fd, &st) == -1)
        die_errno("fstat");
    struct xfer_msg m = {
        .type = XFER_MSG_STAT,
        .u.stat.atime = st.st_atime,
        .u.stat.mtime = st.st_mtime,
#ifdef HAVE_STRUCT_STAT_ST_ATIM
        .u.stat.atime_ns = st.st_atim.tv_nsec,
#endif
#ifdef HAVE_STRUCT_STAT_ST_MTIM
        .u.stat.mtime_ns = st.st_mtim.tv_nsec,
#endif
        .u.stat.size = st.st_size,
        .u.stat.ugo_bits = st.st_mode & 0777,
    };

    send_xfer_msg(to_peer, &m);
}

struct xfer_ctx {
    int from_peer;
    int to_peer;
    const struct cmd_xfer_stub_info* info;
};

static uint32_t
recv_data_header(int from_peer)
{
    struct xfer_msg m = recv_xfer_msg(from_peer);
    if (m.type != XFER_MSG_DATA)
        die(ECOMM, "unexpected message type %u", (unsigned) m.type);
    return m.u.data.payload_size;
}

static void
send_data_header(int to_peer, uint32_t size)
{
    struct xfer_msg m = {
        .type = XFER_MSG_DATA,
        .u.data.payload_size = size,
    };

    send_xfer_msg(to_peer, &m);
}

static uint64_t
copy_loop_posix_recv(
    int from_peer,
    int dest_fd)
{
    SCOPED_RESLIST(rl);
    struct growable_buffer buf = { 0 };
    uint64_t total_written = 0;
    size_t chunksz;

    do {
        chunksz = recv_data_header(from_peer);
        dbg("data chunk header chunksz=%u", (unsigned) chunksz);
        resize_buffer(&buf, chunksz);
        if (read_all(from_peer, buf.buf, chunksz) != chunksz)
            die(ECOMM, "unexpected EOF");
        write_all(dest_fd, buf.buf, chunksz);
        if (SATADD(&total_written, total_written, chunksz))
            die(ECOMM, "file size too large");
    } while (chunksz > 0);

    return total_written;
}

static void
copy_loop_posix_send(
    int to_peer,
    int source_fd)
{
    SCOPED_RESLIST(rl);
    size_t bufsz = 32 * 1024;
    uint8_t* buf = xalloc(bufsz);
    size_t nr_read;

    assert(bufsz <= UINT32_MAX);

    do {
        nr_read = read_all(source_fd, buf, bufsz);
        send_data_header(to_peer, nr_read);
        write_all(to_peer, buf, nr_read);
    } while (nr_read > 0);
}