static void recover_service(int s, void *cookie) { unsigned char buf[4096]; unsigned count = (unsigned) cookie; int fd; fd = adb_creat("/tmp/update", 0644); if(fd < 0) { adb_close(s); return; } while(count > 0) { unsigned xfer = (count > 4096) ? 4096 : count; if(readx(s, buf, xfer)) break; if(writex(fd, buf, xfer)) break; count -= xfer; } if(count == 0) { writex(s, "OKAY", 4); } else { writex(s, "FAIL", 4); } adb_close(fd); adb_close(s); fd = adb_creat("/tmp/update.begin", 0644); adb_close(fd); }
void restart_root_service(int fd, void *cookie) { char buf[100]; char value[PROPERTY_VALUE_MAX]; if (getuid() == 0) { snprintf(buf, sizeof(buf), "adbd is already running as root\n"); writex(fd, buf, strlen(buf)); adb_close(fd); } else { property_get("ro.debuggable", value, ""); if (strcmp(value, "1") != 0) { snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n"); writex(fd, buf, strlen(buf)); adb_close(fd); return; } property_set("service.adb.root", "1"); snprintf(buf, sizeof(buf), "restarting adbd as root\n"); writex(fd, buf, strlen(buf)); adb_close(fd); } }
void framebuffer_service(int fd, void *cookie) { struct fb_var_screeninfo vinfo; int fb; void *ptr = MAP_FAILED; char x; unsigned fbinfo[4]; fb = open("/dev/graphics/fb0", O_RDONLY); if(fb < 0) goto done; if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) goto done; fcntl(fb, F_SETFD, FD_CLOEXEC); fbinfo[0] = 16; fbinfo[1] = vinfo.xres * vinfo.yres * 2; fbinfo[2] = vinfo.xres; fbinfo[3] = vinfo.yres; ptr = mmap(0, fbinfo[1], PROT_READ, MAP_SHARED, fb, 0); if(ptr == MAP_FAILED) goto done; if(writex(fd, fbinfo, sizeof(unsigned) * 4)) goto done; for(;;) { if(readx(fd, &x, 1)) goto done; if(writex(fd, ptr, fbinfo[1])) goto done; } done: if(ptr != MAP_FAILED) munmap(ptr, fbinfo[1]); if(fb >= 0) close(fb); close(fd); }
void reboot_service(int fd, void *arg) { char buf[100]; char property_val[PROPERTY_VALUE_MAX]; int ret; sync(); ret = snprintf(property_val, sizeof(property_val), "reboot,%s", (char *) arg); if (ret >= (int) sizeof(property_val)) { snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret); writex(fd, buf, strlen(buf)); goto cleanup; } ret = property_set(ANDROID_RB_PROPERTY, property_val); if (ret < 0) { snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret); writex(fd, buf, strlen(buf)); goto cleanup; } // Don't return early. Give the reboot command time to take effect // to avoid messing up scripts which do "adb reboot && adb wait-for-device" while(1) { pause(); } cleanup: free(arg); adb_close(fd); }
int sync_readtime(int fd, const char *path, unsigned int *timestamp, unsigned int *mode) { syncmsg msg; int len = strlen(path); msg.req.id = ID_STAT; msg.req.namelen = htoll(len); if(writex(fd, &msg.req, sizeof(msg.req)) || writex(fd, path, len)) { return -1; } if(readx(fd, &msg.stat, sizeof(msg.stat))) { return -1; } if(msg.stat.id != ID_STAT) { return -1; } *timestamp = ltohl(msg.stat.time); *mode = ltohl(msg.stat.mode); return 0; }
int bootimage_write(bootimage *img, int fd) { unsigned off = 4096; unsigned n, s; if (writex(fd, img->entry, 4096)) { return -1; } for (n = 1; n < 64; n++) { if (img->offset[n] == 0) continue; if (img->offset[n] < off) return -1; s = img->offset[n] - off; if (s > 4095) return -1; if (writex(fd, filler, s)) { return -1; } off += s; if (writex(fd, img->data[n], img->length[n])) { return -1; } off += img->length[n]; } if (off & 4095) { if (writex(fd, filler, 4096 - (off & 4095))) return -1; } return 0; }
/* Tokenize the command buffer, locate a matching command, * ensure that the required number of arguments are provided, * call the function(), return the result. */ static int execute(int s, char cmd[BUFFER_MAX]) { char reply[REPLY_MAX]; unsigned n = 0; unsigned short count; int ret = -1; /* default reply is "" */ reply[0] = 0; //Check which command was received if (!strcmp("cpu", cmd)) { FILE *f = fopen(CPU_PATH, "rb"); count = fread(reply, 1, REPLY_MAX, f); fclose(f); reply[count] = 0; goto done; } if (!strcmp("memory", cmd)) { FILE *f = fopen(MEM_PATH, "rb"); count = fread(reply, 1, REPLY_MAX, f); fclose(f); reply[count] = 0; goto done; } if (!strcmp("cmdline", cmd)) { FILE *f = fopen(CMD_PATH, "rb"); count = fread(reply, 1, REPLY_MAX, f); fclose(f); reply[count] = 0; goto done; } ALOGE("unsupported command '%s'\n", cmd); done: ALOGI("Read %d bytes\n", count); if (reply[0]) { n = snprintf(cmd, BUFFER_MAX, "%s", reply); } else { n = snprintf(cmd, BUFFER_MAX, "%d", ret); } if (n > BUFFER_MAX) n = BUFFER_MAX; count = n; ALOGI("reply: '%s'\n", cmd); if (writex(s, &count, sizeof(count))) return -1; if (writex(s, cmd, count)) return -1; return 0; }
void framebuffer_service(int fd, void *cookie) { char x[512]; struct fbinfo fbinfo; int w, h, f; int s[2]; int fb; unsigned int i; int rv; if(adb_socketpair(s)) { printf("cannot create service socket pair\n"); goto done; } pid_t pid = fork(); if (pid < 0) { printf("- fork failed: %s -\n", strerror(errno)); goto done; } if (pid == 0) { dup2(s[1], STDOUT_FILENO); const char* cmd_path = "/system/bin/screencap"; const char* cmd = "screencap"; execl(cmd_path, cmd, NULL); exit(1); } fb = s[0]; /* read w, h, f */ if (readx(fb, &w, 4)) goto done; if (readx(fb, &h, 4)) goto done; if (readx(fb, &f, 4)) goto done; fbinfo.version = DDMS_RAWIMAGE_VERSION; fbinfo.size = w * h * 4; fbinfo.width = w; fbinfo.height = h; rv = fill_format(&fbinfo, f); if (rv != 0) goto done; if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done; for(i = 0; i < fbinfo.size; i += sizeof(x)) { if(readx(fb, &x, sizeof(x))) goto done; if(writex(fd, &x, sizeof(x))) goto done; } if(readx(fb, &x, fbinfo.size % sizeof(x))) goto done; if(writex(fd, &x, fbinfo.size % sizeof(x))) goto done; done: adb_close(s[0]); adb_close(s[1]); adb_close(fd); }
static void send_msg_with_okay(int fd, const char* msg, size_t msglen) { char header[9]; if (msglen > 0xffff) msglen = 0xffff; snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen); writex(fd, header, 8); writex(fd, msg, msglen); }
/* Tokenize the command buffer, locate a matching command, * ensure that the required number of arguments are provided, * call the function(), return the result. */ static int execute(int s, char cmd[BUFFER_MAX]) { char reply[REPLY_MAX]; char *arg[TOKEN_MAX+1]; unsigned i; unsigned n = 0; unsigned short count; int ret = -1; // ALOGI("execute('%s')\n", cmd); /* default reply is "" */ reply[0] = 0; /* n is number of args (not counting arg[0]) */ arg[0] = cmd; while (*cmd) { if (isspace(*cmd)) { *cmd++ = 0; n++; arg[n] = cmd; if (n == TOKEN_MAX) { ALOGE("too many arguments\n"); goto done; } } cmd++; } for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { if (!strcmp(cmds[i].name,arg[0])) { if (n != cmds[i].numargs) { ALOGE("%s requires %d arguments (%d given)\n", cmds[i].name, cmds[i].numargs, n); } else { ret = cmds[i].func(arg + 1, reply); } goto done; } } ALOGE("unsupported command '%s'\n", arg[0]); done: if (reply[0]) { n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); } else { n = snprintf(cmd, BUFFER_MAX, "%d", ret); } if (n > BUFFER_MAX) n = BUFFER_MAX; count = n; // ALOGI("reply: '%s'\n", cmd); if (writex(s, &count, sizeof(count))) return -1; if (writex(s, cmd, count)) return -1; return 0; }
int sendfailmsg(int fd, const char *reason) { char buf[9]; int len; len = strlen(reason); if(len > 0xffff) len = 0xffff; _snprintf(buf, sizeof buf, "FAIL%04x", len); if(writex(fd, buf, 8)) return -1; return writex(fd, reason, len); }
void framebuffer_service(int fd, void *cookie) { struct fb_var_screeninfo vinfo; int fb, offset; char x[256]; struct fbinfo fbinfo; unsigned i, bytespp; fb = open("/dev/graphics/fb0", O_RDONLY); if(fb < 0) goto done; if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) goto done; fcntl(fb, F_SETFD, FD_CLOEXEC); bytespp = vinfo.bits_per_pixel / 8; fbinfo.version = DDMS_RAWIMAGE_VERSION; fbinfo.bpp = vinfo.bits_per_pixel; fbinfo.size = vinfo.xres * vinfo.yres * bytespp; fbinfo.width = vinfo.xres; fbinfo.height = vinfo.yres; fbinfo.red_offset = vinfo.red.offset; fbinfo.red_length = vinfo.red.length; fbinfo.green_offset = vinfo.green.offset; fbinfo.green_length = vinfo.green.length; fbinfo.blue_offset = vinfo.blue.offset; fbinfo.blue_length = vinfo.blue.length; fbinfo.alpha_offset = vinfo.transp.offset; fbinfo.alpha_length = vinfo.transp.length; /* HACK: for several of our 3d cores a specific alignment * is required so the start of the fb may not be an integer number of lines * from the base. As a result we are storing the additional offset in * xoffset. This is not the correct usage for xoffset, it should be added * to each line, not just once at the beginning */ offset = vinfo.xoffset * bytespp; offset += vinfo.xres * vinfo.yoffset * bytespp; if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done; lseek(fb, offset, SEEK_SET); for(i = 0; i < fbinfo.size; i += 256) { if(readx(fb, &x, 256)) goto done; if(writex(fd, &x, 256)) goto done; } if(readx(fb, &x, fbinfo.size % 256)) goto done; if(writex(fd, &x, fbinfo.size % 256)) goto done; done: if(fb >= 0) close(fb); close(fd); }
static int do_list(int s, const char *path) { DIR *d; struct dirent *de; struct stat st; syncmsg msg; int len; char tmp[1024 + 256 + 1]; char *fname; len = strlen(path); memcpy(tmp, path, len); tmp[len] = '/'; fname = tmp + len + 1; msg.dent.id = ID_DENT; d = opendir(path); if(d == 0) goto done; while((de = readdir(d))) { int len = strlen(de->d_name); /* not supposed to be possible, but if it does happen, let's not buffer overrun */ if(len > 256) continue; strcpy(fname, de->d_name); if(lstat(tmp, &st) == 0) { msg.dent.mode = htoll(st.st_mode); msg.dent.size = htoll(st.st_size); msg.dent.time = htoll(st.st_mtime); msg.dent.namelen = htoll(len); if(writex(s, &msg.dent, sizeof(msg.dent)) || writex(s, de->d_name, len)) { closedir(d); return -1; } } } closedir(d); done: msg.dent.id = ID_DONE; msg.dent.mode = 0; msg.dent.size = 0; msg.dent.time = 0; msg.dent.namelen = 0; return writex(s, &msg.dent, sizeof(msg.dent)); }
/******************************************************************************* * Function Name : rt_I2C_write * Description : 向I2C E2PROM 地址中写入一个字节 外部函数 * Input : address 地址 info 数据 * Output : None * Return : None *******************************************************************************/ void rt_I2C_write(unsigned char address,unsigned char info) { start(); writex(0xa0); clock(); writex(address); clock(); writex(info); clock(); stop(); Delay(); }
static int sync_start_readtime(int fd, const char *path) { syncmsg msg; int len = strlen(path); msg.req.id = ID_STAT; msg.req.namelen = htoll(len); if(writex(fd, &msg.req, sizeof(msg.req)) || writex(fd, path, len)) { return -1; } return 0; }
int main(int argc, char **argv) { struct chunk c; off_t a, b = 0; int fin, fout; if (argc != 3) { fprintf(stderr, "usage: mksparse <infile> <outfile>"); return -1; } if ((fin = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "error: cannot open '%s' for reading\n", argv[1]); return -1; } if (!strcmp(argv[2], "-")) { fout = 1; } else if ((fout = open(argv[2], O_WRONLY | O_CREAT, 0600)) < 0) { fprintf(stderr, "error: cannot open '%s' for writing\n", argv[2]); return -1; } while ((a = lseek(fin, b, SEEK_DATA)) >= 0) { b = lseek(fin, a, SEEK_HOLE); c.start = a; c.length = b - a; if (lseek(fin, a, SEEK_SET) != a) goto fail; if (writex(fout, &c, sizeof(c))) goto fail; if (copyx(fin, fout, c.length, buffer, sizeof(buffer))) goto fail; /* fprintf(stderr, "%lu bytes at %lu\n", c.length, c.start); */ } c.start = c.length = 0; if (writex(fout, &c, sizeof(c))) goto fail; if (close(fout)) goto fail; return 0; fail: fprintf(stderr, "error: %s\n", strerror(errno)); return -1; }
void reboot_service(int fd, void *arg) { char buf[100]; int pid, ret; sync(); /* Attempt to unmount the SD card first. * No need to bother checking for errors. */ pid = fork(); if (pid == 0) { /* ask vdc to unmount it */ execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount", getenv("EXTERNAL_STORAGE"), "force", NULL); } else if (pid > 0) { /* wait until vdc succeeds or fails */ waitpid(pid, &ret, 0); } ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg); if (ret < 0) { snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno)); writex(fd, buf, strlen(buf)); } free(arg); adb_close(fd); }
void DrawMenu(char items[][30], int maxitems, int select) { int i,w,p,h; ClearScreen(); /*** Draw Title Centred ***/ p = (480 - (maxitems * font_height)) / 2 + 10; for( i = 0; i < maxitems; i++ ) { w = CentreTextPosition(items[i]); h = GetTextWidth(items[i]); /* if ( i == select ) writex( w, p, h, font_height, items[i], blit_lookup_inv ); else writex( w, p, h, font_height, items[i], blit_lookup );*/ writex( w, p, h, font_height, items[i], i == select ); p += font_height; } SetScreen(); }
static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf, int show_progress) { int err = 0; int total = 0; sbuf->id = ID_DATA; while (total < size) { int count = size - total; if (count > SYNC_DATA_MAX) { count = SYNC_DATA_MAX; } memcpy(sbuf->data, &file_buffer[total], count); sbuf->size = htoll(count); if(writex(fd, sbuf, sizeof(unsigned) * 2 + count)){ err = -1; break; } total += count; total_bytes += count; if (show_progress) { print_transfer_progress(total, size); } } return err; }
static void subproc_waiter_service(int fd, void *cookie) { pid_t pid = (pid_t)cookie; D("entered. fd=%d of pid=%d\n", fd, pid); for (;;) { int status; pid_t p = waitpid(-1/*pid*/, &status, 0); D("fd=%d, post waitpid(pid=%d) status=%04x %s errno(%d)\n", fd, p, status, strerror(errno), errno); //if (p == pid) { if (WIFSIGNALED(status)) { D("*** Killed by signal %d\n", WTERMSIG(status)); //break; } else if (!WIFEXITED(status)) { D("*** Didn't exit!!. status %d\n", status); //break; } else if (WEXITSTATUS(status) >= 0) { D("*** Exit code %d\n", WEXITSTATUS(status)); //break; } //} if ( p == -1 ) usleep(100000); // poll every 0.1 sec } D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); XLOGV("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); if (SHELL_EXIT_NOTIFY_FD >=0) { int res; res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)); D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n", SHELL_EXIT_NOTIFY_FD, pid, res, errno); } }
static void connect_service(int fd, void* cookie) { char buf[4096]; char resp[4096]; char *host = cookie; reconnector *recon; recon = find_reconnector(host); /* if we're already reconnecting, skip the connection and just keep reconnecting */ if (recon) { sendfailmsg(fd, "already reconnecting"); return 0; } if (!strncmp(host, "emu:", 4)) { connect_emulator(host + 4, buf, sizeof(buf)); } else { connect_device(host, buf, sizeof(buf)); } // Send response for emulator and device snprintf(resp, sizeof(resp), "%04x%s",(unsigned)strlen(buf), buf); writex(fd, resp, strlen(resp)); adb_close(fd); }
static int fail_message(int s, const char *reason) { syncmsg msg; int len = strlen(reason); D("sync: failure: %s\n", reason); msg.data.id = ID_FAIL; msg.data.size = htoll(len); if(writex(s, &msg.data, sizeof(msg.data)) || writex(s, reason, len)) { return -1; } else { return 0; } }
static void subproc_waiter_service(int fd, void *cookie) { pid_t pid = (pid_t) (uintptr_t) cookie; D("entered. fd=%d of pid=%d\n", fd, pid); for (;;) { int status; pid_t p = waitpid(pid, &status, 0); if (p == pid) { D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status); if (WIFSIGNALED(status)) { D("*** Killed by signal %d\n", WTERMSIG(status)); break; } else if (!WIFEXITED(status)) { D("*** Didn't exit!!. status %d\n", status); break; } else if (WEXITSTATUS(status) >= 0) { D("*** Exit code %d\n", WEXITSTATUS(status)); break; } } } D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); if (SHELL_EXIT_NOTIFY_FD >=0) { int res; res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)); D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n", SHELL_EXIT_NOTIFY_FD, pid, res, errno); } }
static int switch_socket_transport(int fd) { char service[64]; char tmp[5]; int len; if (__adb_serial) snprintf(service, sizeof service, "host:transport:%s", __adb_serial); else { char* transport_type = "???"; switch (__adb_transport) { case kTransportUsb: transport_type = "transport-usb"; break; case kTransportLocal: transport_type = "transport-local"; break; case kTransportAny: transport_type = "transport-any"; break; case kTransportHost: // no switch necessary return 0; break; } snprintf(service, sizeof service, "host:%s", transport_type); } len = strlen(service); snprintf(tmp, sizeof tmp, "%04x", len); if(writex(fd, tmp, 4) || writex(fd, service, len)) { strcpy(__adb_error, "write failure during connection"); adb_close(fd); return -1; } D("Switch transport in progress\n"); if(adb_status(fd)) { adb_close(fd); D("Switch transport failed\n"); return -1; } D("Switch transport success\n"); return 0; }
int adb_download_buffer(const char *service, const void* data, int sz, unsigned progress) { char buf[4096]; unsigned total; int fd; const unsigned char *ptr; sprintf(buf,"%s:%d", service, sz); fd = adb_connect(buf); if(fd < 0) { fprintf(stderr,"error: %s\n", adb_error()); return -1; } int opt = CHUNK_SIZE; opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char *)&opt, sizeof(opt)); total = sz; ptr = (const unsigned char *)data; if(progress) { char *x = strrchr((char*)service, ':'); if(x) service = x + 1; } while(sz > 0) { unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz; if(writex(fd, ptr, xfer)) { adb_status(fd); fprintf(stderr,"* failed to write data '%s' *\n", adb_error()); return -1; } sz -= xfer; ptr += xfer; if(progress) { printf("sending: '%s' %4d%% \r", service, (int)(100LL - ((100LL * sz) / (total)))); fflush(stdout); } } if(progress) { printf("\n"); } if(readx(fd, buf, 4)){ fprintf(stderr,"* error reading response *\n"); adb_close(fd); return -1; } if(memcmp(buf, "OKAY", 4)) { buf[4] = 0; fprintf(stderr,"* error response '%s' *\n", buf); adb_close(fd); return -1; } adb_close(fd); return 0; }
/******************************************************************************* * Function Name : rt_I2C_read * Description : 从I2C E2PROM 地址中读取一个字节 外部函数 * Input : address 地址 * Output : None * Return : 读出数据 *******************************************************************************/ unsigned char rt_I2C_read(unsigned char address) { unsigned char i; start(); writex(0xa0); clock(); writex(address); clock(); start(); writex(0xa1); clock(); i=readx(); stop(); Delay(); return(i); }
static void dns_service(int fd, void *cookie) { char *hostname = cookie; struct hostent *hp; unsigned zero = 0; adb_mutex_lock(&dns_lock); hp = gethostbyname(hostname); free(cookie); if(hp == 0) { writex(fd, &zero, 4); } else { writex(fd, hp->h_addr, 4); } adb_mutex_unlock(&dns_lock); adb_close(fd); }
void restart_usb_service(int fd, void *cookie) { char buf[100]; property_set("service.adb.tcp.port", "0"); snprintf(buf, sizeof(buf), "restarting in USB mode\n"); writex(fd, buf, strlen(buf)); adb_close(fd); }
void sync_quit(int fd) { syncmsg msg; msg.req.id = ID_QUIT; msg.req.namelen = 0; writex(fd, &msg.req, sizeof(msg.req)); }
void restart_tcp_service(int fd, void *cookie) { char buf[100]; char value[PROPERTY_VALUE_MAX]; int port = (int) (uintptr_t) cookie; if (port <= 0) { snprintf(buf, sizeof(buf), "invalid port\n"); writex(fd, buf, strlen(buf)); adb_close(fd); return; } snprintf(value, sizeof(value), "%d", port); property_set("service.adb.tcp.port", value); snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port); writex(fd, buf, strlen(buf)); adb_close(fd); }