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

📄 services.c

📁 Android 一些工具
💻 C
字号:
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <errno.h>#include "sysdeps.h"#define  TRACE_TAG  TRACE_ADB#include "adb.h"#include "file_sync_service.h"#if ADB_HOST#  ifndef HAVE_WINSOCK#    include <netinet/in.h>#    include <netdb.h>#  endif#endiftypedef struct stinfo stinfo;struct stinfo {    void (*func)(int fd, void *cookie);    int fd;    void *cookie;};void *service_bootstrap_func(void *x){    stinfo *sti = x;    sti->func(sti->fd, sti->cookie);    free(sti);    return 0;}#if ADB_HOSTADB_MUTEX_DEFINE( dns_lock );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);    if(hp == 0) {        writex(fd, &zero, 4);    } else {        writex(fd, hp->h_addr, 4);    }    adb_mutex_unlock(&dns_lock);    adb_close(fd);}#elseextern int recovery_mode;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);}#endif#if 0static void echo_service(int fd, void *cookie){    char buf[4096];    int r;    char *p;    int c;    for(;;) {        r = read(fd, buf, 4096);        if(r == 0) goto done;        if(r < 0) {            if(errno == EINTR) continue;            else goto done;        }        c = r;        p = buf;        while(c > 0) {            r = write(fd, p, c);            if(r > 0) {                c -= r;                p += r;                continue;            }            if((r < 0) && (errno == EINTR)) continue;            goto done;        }    }done:    close(fd);}#endifstatic int create_service_thread(void (*func)(int, void *), void *cookie){    stinfo *sti;    adb_thread_t t;    int s[2];    if(adb_socketpair(s)) {        printf("cannot create service socket pair\n");        return -1;    }    sti = malloc(sizeof(stinfo));    if(sti == 0) fatal("cannot allocate stinfo");    sti->func = func;    sti->cookie = cookie;    sti->fd = s[1];    if(adb_thread_create( &t, service_bootstrap_func, sti)){        free(sti);        adb_close(s[0]);        adb_close(s[1]);        printf("cannot create service thread\n");        return -1;    }    D("service thread started, %d:%d\n",s[0], s[1]);    return s[0];}static int create_subprocess(const char *cmd, const char *arg0, const char *arg1){#ifdef HAVE_WIN32_PROC	fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);	return -1;#else /* !HAVE_WIN32_PROC */    char *devname;    int ptm;    pid_t pid;    ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY);    if(ptm < 0){        printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));        return -1;    }    fcntl(ptm, F_SETFD, FD_CLOEXEC);    if(grantpt(ptm) || unlockpt(ptm) ||       ((devname = (char*) ptsname(ptm)) == 0)){        printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));        return -1;    }    pid = fork();    if(pid < 0) {        printf("- fork failed: %s -\n", strerror(errno));        return -1;    }    if(pid == 0){        int pts;        setsid();        pts = unix_open(devname, O_RDWR);        if(pts < 0) exit(-1);        dup2(pts, 0);        dup2(pts, 1);        dup2(pts, 2);        adb_close(ptm);        execl(cmd, cmd, arg0, arg1, NULL);        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",                cmd, strerror(errno), errno);        exit(-1);    } else {        return ptm;    }#endif /* !HAVE_WIN32_PROC */}#if ADB_HOST#define SHELL_COMMAND "/bin/sh"#else#define SHELL_COMMAND "/system/bin/sh"#endifint service_to_fd(const char *name){    int ret = -1;    if(!strncmp(name, "tcp:", 4)) {        int port = atoi(name + 4);        name = strchr(name + 4, ':');        if(name == 0) {            ret = socket_loopback_client(port, SOCK_STREAM);            if (ret >= 0)                disable_tcp_nagle(ret);        } else {#if ADB_HOST            adb_mutex_lock(&dns_lock);            ret = socket_network_client(name + 1, port, SOCK_STREAM);            adb_mutex_unlock(&dns_lock);#else            return -1;#endif        }#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */    } else if(!strncmp(name, "local:", 6)) {        ret = socket_local_client(name + 6,                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);    } else if(!strncmp(name, "localreserved:", 14)) {        ret = socket_local_client(name + 14,                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);    } else if(!strncmp(name, "localabstract:", 14)) {        ret = socket_local_client(name + 14,                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);    } else if(!strncmp(name, "localfilesystem:", 16)) {        ret = socket_local_client(name + 16,                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);#endif#if ADB_HOST    } else if(!strncmp("dns:", name, 4)){        char *n = strdup(name + 4);        if(n == 0) return -1;        ret = create_service_thread(dns_service, n);#else /* !ADB_HOST */    } else if(!strncmp("dev:", name, 4)) {        ret = unix_open(name + 4, O_RDWR);    } else if(!strncmp(name, "framebuffer:", 12)) {        ret = create_service_thread(framebuffer_service, 0);    } else if(recovery_mode && !strncmp(name, "recover:", 8)) {        ret = create_service_thread(recover_service, (void*) atoi(name + 8));    } else if (!strncmp(name, "jdwp:", 5)) {        ret = create_jdwp_connection_fd(atoi(name+5));    } else if (!strncmp(name, "log:", 4)) {        ret = create_service_thread(log_service, get_log_file_path(name + 4));#endif    } else if(!HOST && !strncmp(name, "shell:", 6)) {        if(name[6]) {            ret = create_subprocess(SHELL_COMMAND, "-c", name + 6);        } else {            ret = create_subprocess(SHELL_COMMAND, "-", 0);        }#if !ADB_HOST    } else if(!strncmp(name, "sync:", 5)) {        ret = create_service_thread(file_sync_service, NULL);    } else if(!strncmp(name, "remount:", 8)) {        ret = create_service_thread(remount_service, NULL);#endif#if 0    } else if(!strncmp(name, "echo:", 5)){        ret = create_service_thread(echo_service, 0);#endif    }    if (ret >= 0) {        close_on_exec(ret);    }    return ret;}#if ADB_HOSTstruct state_info {    transport_type transport;    char* serial;    int state;};static void wait_for_state(int fd, void* cookie){    struct state_info* sinfo = cookie;    char* err = "unknown error";    D("wait_for_state %d\n", sinfo->state);    atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err);    if(t != 0) {        writex(fd, "OKAY", 4);    } else {        sendfailmsg(fd, err);    }    if (sinfo->serial)        free(sinfo->serial);    free(sinfo);    adb_close(fd);    D("wait_for_state is done\n");}#endif#if ADB_HOSTasocket*  host_service_to_socket(const char*  name, const char *serial){    if (!strcmp(name,"track-devices")) {        return create_device_tracker();    } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {        struct state_info* sinfo = malloc(sizeof(struct state_info));        if (serial)            sinfo->serial = strdup(serial);        else            sinfo->serial = NULL;        name += strlen("wait-for-");        if (!strncmp(name, "bootloader", strlen("bootloader"))) {            sinfo->transport = kTransportUsb;            sinfo->state = CS_BOOTLOADER;        } else if (!strncmp(name, "local", strlen("local"))) {            sinfo->transport = kTransportLocal;            sinfo->state = CS_DEVICE;        } else if (!strncmp(name, "usb", strlen("usb"))) {            sinfo->transport = kTransportUsb;            sinfo->state = CS_DEVICE;        } else if (!strncmp(name, "any", strlen("any"))) {            sinfo->transport = kTransportAny;            sinfo->state = CS_DEVICE;        } else {            free(sinfo);            return NULL;        }        int fd = create_service_thread(wait_for_state, sinfo);        return create_local_socket(fd);    }    return NULL;}#endif /* ADB_HOST */

⌨️ 快捷键说明

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