⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adb.c

📁 Android 一些工具
💻 C
📖 第 1 页 / 共 2 页
字号:
            }            return 0;        }    }    if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;    if((l->local_name = strdup(local_name)) == 0) goto nomem;    if((l->connect_to = strdup(connect_to)) == 0) goto nomem;    l->fd = local_name_to_fd(local_name);    if(l->fd < 0) {        free((void*) l->local_name);        free((void*) l->connect_to);        free(l);        printf("cannot bind '%s'\n", local_name);        return -2;    }    close_on_exec(l->fd);    if(!strcmp(l->connect_to, "*smartsocket*")) {        fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);    } else {        fdevent_install(&l->fde, l->fd, listener_event_func, l);    }    fdevent_set(&l->fde, FDE_READ);    l->next = &listener_list;    l->prev = listener_list.prev;    l->next->prev = l;    l->prev->next = l;    l->transport = transport;    if (transport) {        l->disconnect.opaque = l;        l->disconnect.func   = listener_disconnect;        add_transport_disconnect(transport, &l->disconnect);    }    return 0;nomem:    fatal("cannot allocate listener");    return 0;}#ifdef HAVE_FORKEXECstatic void sigchld_handler(int n){    int status;    while(waitpid(-1, &status, WNOHANG) > 0) ;}#endif#ifdef HAVE_WIN32_PROCstatic BOOL WINAPI ctrlc_handler(DWORD type){    exit(STATUS_CONTROL_C_EXIT);    return TRUE;}#endifstatic void adb_cleanup(void){    usb_cleanup();}void start_logging(void){#ifdef HAVE_WIN32_PROC    char    temp[ MAX_PATH ];    FILE*   fnul;    FILE*   flog;    GetTempPath( sizeof(temp) - 8, temp );    strcat( temp, "adb.log" );    /* Win32 specific redirections */    fnul = fopen( "NUL", "rt" );    if (fnul != NULL)        stdin[0] = fnul[0];    flog = fopen( temp, "at" );    if (flog == NULL)        flog = fnul;    setvbuf( flog, NULL, _IONBF, 0 );    stdout[0] = flog[0];    stderr[0] = flog[0];    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());#else    int fd;    fd = unix_open("/dev/null", O_RDONLY);    dup2(fd, 0);    fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);    if(fd < 0) {        fd = unix_open("/dev/null", O_WRONLY);    }    dup2(fd, 1);    dup2(fd, 2);    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());#endif}#if !ADB_HOSTvoid start_device_log(void){    int fd;    char    path[100];    snprintf(path, sizeof path, "/data/adb_%ld.txt", (long)time(NULL));    fd = unix_open(path, O_WRONLY | O_CREAT | O_APPEND, 0640);    if (fd < 0)        return;    // redirect stdout and stderr to the log file    dup2(fd, 1);    dup2(fd, 2);    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());    fd = unix_open("/dev/null", O_RDONLY);    dup2(fd, 0);    // log everything    adb_trace_mask = ~0;    // except TRACE_RWX is a bit too verbose    adb_trace_mask &= ~TRACE_RWX;}#endif#if ADB_HOSTint launch_server(){#ifdef HAVE_WIN32_PROC    /* we need to start the server in the background                    */    /* we create a PIPE that will be used to wait for the server's "OK" */    /* message since the pipe handles must be inheritable, we use a     */    /* security attribute                                               */    HANDLE                pipe_read, pipe_write;    SECURITY_ATTRIBUTES   sa;    STARTUPINFO           startup;    PROCESS_INFORMATION   pinfo;    char                  program_path[ MAX_PATH ];    int                   ret;    sa.nLength = sizeof(sa);    sa.lpSecurityDescriptor = NULL;    sa.bInheritHandle = TRUE;    /* create pipe, and ensure its read handle isn't inheritable */    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );    if (!ret) {        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );        return -1;    }    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );    ZeroMemory( &startup, sizeof(startup) );    startup.cb = sizeof(startup);    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );    startup.hStdOutput = pipe_write;    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );    startup.dwFlags    = STARTF_USESTDHANDLES;    ZeroMemory( &pinfo, sizeof(pinfo) );    /* get path of current program */    GetModuleFileName( NULL, program_path, sizeof(program_path) );    ret = CreateProcess(            program_path,                              /* program path  */            "adb fork-server server",                                    /* the fork-server argument will set the                                       debug = 2 in the child           */            NULL,                   /* process handle is not inheritable */            NULL,                    /* thread handle is not inheritable */            TRUE,                          /* yes, inherit some handles */            DETACHED_PROCESS, /* the new process doesn't have a console */            NULL,                     /* use parent's environment block */            NULL,                    /* use parent's starting directory */            &startup,                 /* startup info, i.e. std handles */            &pinfo );    CloseHandle( pipe_write );    if (!ret) {        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );        CloseHandle( pipe_read );        return -1;    }    CloseHandle( pinfo.hProcess );    CloseHandle( pinfo.hThread );    /* wait for the "OK\n" message */    {        char  temp[3];        DWORD  count;        ret = ReadFile( pipe_read, temp, 3, &count, NULL );        CloseHandle( pipe_read );        if ( !ret ) {            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );            return -1;        }        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {            fprintf(stderr, "ADB server didn't ACK\n" );            return -1;        }    }#elif defined(HAVE_FORKEXEC)    char    path[PATH_MAX];    int     fd[2];    // set up a pipe so the child can tell us when it is ready.    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.    if (pipe(fd)) {        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);        return -1;    }    get_my_path(path);    pid_t pid = fork();    if(pid < 0) return -1;    if (pid == 0) {        // child side of the fork        // redirect stderr to the pipe        // we use stderr instead of stdout due to stdout's buffering behavior.        adb_close(fd[0]);        dup2(fd[1], STDERR_FILENO);        adb_close(fd[1]);        // child process        int result = execl(path, "adb", "fork-server", "server", NULL);	    // this should not return	    fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);    } else  {        // parent side of the fork        char  temp[3];        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';        // wait for the "OK\n" message        adb_close(fd[1]);        int ret = adb_read(fd[0], temp, 3);        adb_close(fd[0]);        if (ret < 0) {            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", errno);            return -1;        }        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {            fprintf(stderr, "ADB server didn't ACK\n" );            return -1;        }        setsid();    }#else#error "cannot implement background server start on this platform"#endif    return 0;}#endifint adb_main(int is_daemon){#if !ADB_HOST    int secure = 0;    char value[PROPERTY_VALUE_MAX];    // prevent the OOM killer from killing us    char text[64];    snprintf(text, sizeof text, "/proc/%d/oom_adj", (int)getpid());    int fd = adb_open(text, O_WRONLY);    if (fd >= 0) {        // -17 should make us immune to OOM        snprintf(text, sizeof text, "%d", -17);        adb_write(fd, text, strlen(text));        adb_close(fd);    } else {       D("adb: unable to open %s\n", text);    }#endif    atexit(adb_cleanup);#ifdef HAVE_WIN32_PROC    SetConsoleCtrlHandler( ctrlc_handler, TRUE );#elif defined(HAVE_FORKEXEC)    signal(SIGCHLD, sigchld_handler);    signal(SIGPIPE, SIG_IGN);#endif    init_transport_registration();#if ADB_HOST    HOST = 1;    usb_init();    local_init();    if(install_listener("tcp:5037", "*smartsocket*", NULL)) {        exit(1);    }#else    /* run adbd in secure mode if ro.secure is set and    ** we are not in the emulator    */    property_get("ro.kernel.qemu", value, "");    if (strcmp(value, "1") != 0) {        property_get("ro.secure", value, "");        if (strcmp(value, "1") == 0)            secure = 1;    }    /* don't listen on port 5037 if we are running in secure mode */    /* don't run as root if we are running in secure mode */    if (secure) {        /* add extra groups:        ** AID_ADB to access the USB driver        ** AID_LOG to read system logs (adb logcat)        ** AID_INPUT to diagnose input issues (getevent)        ** AID_INET to diagnose network issues (netcfg, ping)        ** AID_GRAPHICS to access the frame buffer        */        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS };        setgroups(sizeof(groups)/sizeof(groups[0]), groups);        /* then switch user and group to "shell" */        setgid(AID_SHELL);        setuid(AID_SHELL);        D("Local port 5037 disabled\n");    } else {        if(install_listener("tcp:5037", "*smartsocket*", NULL)) {            exit(1);        }    }        /* for the device, start the usb transport if the        ** android usb device exists, otherwise start the        ** network transport.        */    if(access("/dev/android_adb", F_OK) == 0 ||       access("/dev/android", F_OK) == 0) {        usb_init();	} else {        local_init();    }    init_jdwp();#endif    if (is_daemon)    {        // inform our parent that we are up and running.#ifdef HAVE_WIN32_PROC        DWORD  count;        WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );#elif defined(HAVE_FORKEXEC)        fprintf(stderr, "OK\n");#endif        start_logging();    }    fdevent_loop();    usb_cleanup();    return 0;}int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s){    atransport *transport = NULL;    char buf[4096];    if(!strcmp(service, "kill")) {        fprintf(stderr,"adb server killed by remote request\n");        fflush(stdout);        adb_write(reply_fd, "OKAY", 4);        usb_cleanup();        exit(0);    }#if ADB_HOST    // "transport:" is used for switching transport with a specified serial number    // "transport-usb:" is used for switching transport to the only USB transport    // "transport-local:" is used for switching transport to the only local transport    // "transport-any:" is used for switching transport to the only transport    if (!strncmp(service, "transport", strlen("transport"))) {        char* error_string = "unknown failure";        transport_type type = kTransportAny;        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {            type = kTransportUsb;        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {            type = kTransportLocal;        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {            type = kTransportAny;        } else if (!strncmp(service, "transport:", strlen("transport:"))) {            service += strlen("transport:");            serial = strdup(service);        }        transport = acquire_one_transport(CS_ANY, type, serial, &error_string);        if (transport) {            s->transport = transport;            adb_write(reply_fd, "OKAY", 4);        } else {            sendfailmsg(reply_fd, error_string);        }        return 1;    }    // return a list of all connected devices    if (!strcmp(service, "devices")) {        char buffer[4096];        memset(buf, 0, sizeof(buf));        memset(buffer, 0, sizeof(buffer));        D("Getting device list \n");        list_transports(buffer, sizeof(buffer));        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);        D("Wrote device list \n");        writex(reply_fd, buf, strlen(buf));        return 0;    }    // returns our value for ADB_SERVER_VERSION    if (!strcmp(service, "version")) {        char version[12];        snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);        snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version);        writex(reply_fd, buf, strlen(buf));        return 0;    }    if(!strncmp(service,"get-product",strlen("get-product"))) {        char *out = "unknown";        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);        if (transport && transport->product) {            out = transport->product;        }        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);        writex(reply_fd, buf, strlen(buf));        return 0;    }    if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {        char *out = "unknown";         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);       if (transport && transport->serial) {            out = transport->serial;        }        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);        writex(reply_fd, buf, strlen(buf));        return 0;    }    // indicates a new emulator instance has started    if (!strncmp(service,"emulator:",9)) {        int  port = atoi(service+9);        local_connect(port);        /* we don't even need to send a reply */        return 0;    }#endif // ADB_HOST    if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {        char *local, *remote, *err;        int r;        atransport *transport;        int createForward = strncmp(service,"kill",4);        local = service + (createForward ? 8 : 12);        remote = strchr(local,';');        if(remote == 0) {            sendfailmsg(reply_fd, "malformed forward spec");            return 0;        }        *remote++ = 0;        if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){            sendfailmsg(reply_fd, "malformed forward spec");            return 0;        }        transport = acquire_one_transport(CS_ANY, ttype, serial, &err);        if (!transport) {            sendfailmsg(reply_fd, err);            return 0;        }        if (createForward) {            r = install_listener(local, remote, transport);        } else {            r = remove_listener(local, remote, transport);        }        if(r == 0) {                /* 1st OKAY is connect, 2nd OKAY is status */            writex(reply_fd, "OKAYOKAY", 8);            return 0;        }        if (createForward) {            sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");        } else {            sendfailmsg(reply_fd, "cannot remove listener");        }        return 0;    }    if(!strncmp(service,"get-state",strlen("get-state"))) {        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);        char *state = connection_state_name(transport);        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);        writex(reply_fd, buf, strlen(buf));        return 0;    }    return -1;}#if !ADB_HOSTint recovery_mode = 0;#endifint main(int argc, char **argv){    adb_trace_init();#if ADB_HOST    adb_sysdeps_init();    return adb_commandline(argc - 1, argv + 1);#else    if((argc > 1) && (!strcmp(argv[1],"recovery"))) {        adb_device_banner = "recovery";        recovery_mode = 1;    }#if ADB_DEVICE_LOG    start_device_log();#endif    return adb_main(0);#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -