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; }
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); }
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); }