/* * This file is part of MultiROM. * * MultiROM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MultiROM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MultiROM. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include "adb.h" #include "../lib/util.h" #include "../lib/log.h" static pthread_t adb_thread; static volatile int run_thread = 0; static pid_t adb_pid = -1; static char busybox_path[64] = { 0 }; static char adbd_path[64] = { 0 }; static char * const ENV[] = { "PATH=/sbin:/bin:/usr/bin:/usr/sbin:/mrom_bin", "LD_LIBRARY_PATH=.:/sbin", "ANDROID_ROOT=/system", "ANDROID_DATA=/data", "EXTERNAL_STORAGE=/sdcard", "ANDROID_PROPERTY_WORKSPACE=8,49152", "SHELL=/mrom_bin/sh", NULL }; static void *adb_thread_work(void *mrom_path) { int enabled = adb_is_enabled((char*)mrom_path); free(mrom_path); if(enabled == 0) return NULL; adb_init_usb(); if(adb_init_busybox() < 0) return NULL; adb_init_fs(); chmod(adbd_path, 0755); while(run_thread) { adb_pid = fork(); if(adb_pid == 0) // child { umask(077); setsid(); stdio_to_null(); setpgid(0, getpid()); static char * const cmd[] = { adbd_path, NULL }; execve(cmd[0], cmd, ENV); exit(0); } else { int status = 0; waitpid(adb_pid, &status, 0); } usleep(300000); } adb_cleanup(); return NULL; } void adb_init(char *mrom_path) { if(run_thread) return; sprintf(busybox_path, "%s/busybox", mrom_path); sprintf(adbd_path, "%s/adbd", mrom_path); INFO("Starting adbd\n"); run_thread = 1; pthread_create(&adb_thread, NULL, adb_thread_work, strdup(mrom_path)); } void adb_quit(void) { if(!run_thread) return; INFO("Stopping adbd\n"); run_thread = 0; if(adb_pid != -1) { kill(adb_pid, 9); adb_pid = -1; } pthread_join(adb_thread, NULL); } void adb_init_usb(void) { mkdir_with_perms("/dev/usb-ffs", 0770, "shell", "shell"); mkdir_with_perms("/dev/usb-ffs/adb", 0770, "shell", "shell"); mount("adb", "/dev/usb-ffs/adb", "functionfs", 0, "uid=2000,gid=2000"); write_file("/sys/class/android_usb/android0/enable", "0"); char serial[64] = { 0 }; adb_get_serial(serial, sizeof(serial)); // this vid and pid is used in TWRP, CWM and AOSP recovery // for all devices, so I guess it is universal write_file("/sys/class/android_usb/android0/idVendor", "18d1"); write_file("/sys/class/android_usb/android0/idProduct", "d001"); write_file("/sys/class/android_usb/android0/f_ffs/aliases", "adb"); write_file("/sys/class/android_usb/android0/functions", "adb"); write_file("/sys/class/android_usb/android0/iManufacturer", PRODUCT_MANUFACTURER); write_file("/sys/class/android_usb/android0/iProduct", PRODUCT_MODEL); write_file("/sys/class/android_usb/android0/iSerial", serial); write_file("/sys/class/android_usb/android0/enable", "1"); } int adb_init_busybox(void) { mkdir("/mrom_bin", 0777); copy_file(busybox_path, "/mrom_bin/busybox"); chmod("/mrom_bin/busybox", 0755); static const char *install_cmd[] = { "/mrom_bin/busybox", "--install", "/mrom_bin/", NULL }; if(run_cmd((char**)install_cmd) != 0) { ERROR("adb: failed to --install busybox\n"); return -1; } mkdir("/dev/pts", 0666); if(mount("devpts", "/dev/pts", "devpts", 0, NULL) < 0) { ERROR("Failed to mount devpts: %d (%s)\n", errno, strerror(errno)); return -1; } return 0; } void adb_init_fs(void) { mkdir("/sdcard", 0777); if(strstr(adbd_path, "/realdata/media/0/multirom")) mount("/realdata/media/0/", "/sdcard/", "auto", MS_BIND, ""); else mount("/realdata/media/", "/sdcard/", "auto", MS_BIND, ""); } void adb_cleanup(void) { if(umount("/sdcard") >= 0) remove_dir("/sdcard"); remove_dir("/mrom_bin"); umount("/dev/pts"); rmdir("/dev/pts"); umount("/dev/usb-ffs/adb"); rmdir("/dev/usb-ffs/adb"); rmdir("/dev/usb-ffs"); } int adb_get_serial(char *serial, int maxlen) { FILE *f = fopen("/proc/cmdline", "re"); if(!f) return -1; int res = -1; char cmdline[1024]; static const char *tag = "androidboot.serialno="; if(fgets(cmdline, sizeof(cmdline), f)) { char *start = strstr(cmdline, tag); if(start) { start += strlen(tag); char *end = strchr(start, ' '); if(end && end-start < maxlen) { strncpy(serial, start, end-start); res = 0; } } } fclose(f); return res; } int adb_is_enabled(char *mrom_path) { // REMOVE, DEBUGGING return 1; /*char cfg[64]; char *cmd[] = { busybox_path, "grep", "^enable_adb=1$", cfg, NULL }; sprintf(cfg, "%s/multirom.ini", mrom_path); return run_cmd(cmd) == 0 ? 1 : 0;*/ }