services.c revision ff19670d485fd5ee296e23b00b035ac22975c647
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h"
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  TRACE_TAG  TRACE_ADB
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h"
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "file_sync_service.h"
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  ifndef HAVE_WINSOCK
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#    include <netinet/in.h>
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#    include <netdb.h>
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  endif
34cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#else
35cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#include <sys/poll.h>
36ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood#include <sys/reboot.h>
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct stinfo stinfo;
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct stinfo {
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void (*func)(int fd, void *cookie);
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void *cookie;
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid *service_bootstrap_func(void *x)
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    stinfo *sti = x;
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti->func(sti->fd, sti->cookie);
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(sti);
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectADB_MUTEX_DEFINE( dns_lock );
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dns_service(int fd, void *cookie)
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *hostname = cookie;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct hostent *hp;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned zero = 0;
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_mutex_lock(&dns_lock);
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hp = gethostbyname(hostname);
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(hp == 0) {
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(fd, &zero, 4);
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(fd, hp->h_addr, 4);
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_mutex_unlock(&dns_lock);
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern int recovery_mode;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void recover_service(int s, void *cookie)
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char buf[4096];
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned count = (unsigned) cookie;
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_creat("/tmp/update", 0644);
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(s);
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(count > 0) {
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        unsigned xfer = (count > 4096) ? 4096 : count;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(s, buf, xfer)) break;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(fd, buf, xfer)) break;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count -= xfer;
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(count == 0) {
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(s, "OKAY", 4);
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(s, "FAIL", 4);
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(s);
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_creat("/tmp/update.begin", 0644);
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
109e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Projectvoid restart_root_service(int fd, void *cookie)
110e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project{
111e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    char buf[100];
112e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    char value[PROPERTY_VALUE_MAX];
113e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
114e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    if (getuid() == 0) {
115e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        snprintf(buf, sizeof(buf), "adbd is already running as root\n");
116e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        writex(fd, buf, strlen(buf));
117e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        adb_close(fd);
118e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    } else {
119e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        property_get("ro.debuggable", value, "");
120e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        if (strcmp(value, "1") != 0) {
121e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
122e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            writex(fd, buf, strlen(buf));
123ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            adb_close(fd);
124e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            return;
125e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        }
126e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
127e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        property_set("service.adb.root", "1");
128e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        snprintf(buf, sizeof(buf), "restarting adbd as root\n");
129e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        writex(fd, buf, strlen(buf));
130e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        adb_close(fd);
131e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
132e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        // quit, and init will restart us as root
133e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        sleep(1);
134e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        exit(1);
135e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    }
136e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project}
137e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
138ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_tcp_service(int fd, void *cookie)
139ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{
140ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    char buf[100];
141ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    char value[PROPERTY_VALUE_MAX];
142ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    int port = (int)cookie;
143ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
144ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    if (port <= 0) {
145ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        snprintf(buf, sizeof(buf), "invalid port\n");
146ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        writex(fd, buf, strlen(buf));
147ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        adb_close(fd);
148ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        return;
149ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    }
150ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
151ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    snprintf(value, sizeof(value), "%d", port);
152ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    property_set("service.adb.tcp.port", value);
153ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
154ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    writex(fd, buf, strlen(buf));
155ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    adb_close(fd);
156ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
157ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    // quit, and init will restart us in TCP mode
158ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    sleep(1);
159ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    exit(1);
160ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood}
161ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
162ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_usb_service(int fd, void *cookie)
163ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{
164ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    char buf[100];
165ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
166ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    property_set("service.adb.tcp.port", "0");
167ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    snprintf(buf, sizeof(buf), "restarting in USB mode\n");
168ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    writex(fd, buf, strlen(buf));
169ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    adb_close(fd);
170ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
171ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    // quit, and init will restart us in USB mode
172ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    sleep(1);
173ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    exit(1);
174ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood}
175ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
176ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid reboot_service(int fd, void *arg)
177ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood{
178ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    char buf[100];
179ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    int ret;
180ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood
181ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    sync();
182ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
183ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood                    LINUX_REBOOT_CMD_RESTART2, (char *)arg);
184ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    if (ret < 0) {
185ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood        snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
186ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood        writex(fd, buf, strlen(buf));
187ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    }
188ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    adb_close(fd);
189ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood}
190ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void echo_service(int fd, void *cookie)
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[4096];
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int r;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *p;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int c;
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        r = read(fd, buf, 4096);
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r == 0) goto done;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r < 0) {
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(errno == EINTR) continue;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            else goto done;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c = r;
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        p = buf;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while(c > 0) {
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            r = write(fd, p, c);
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(r > 0) {
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                c -= r;
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                p += r;
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if((r < 0) && (errno == EINTR)) continue;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto done;
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone:
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close(fd);
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int create_service_thread(void (*func)(int, void *), void *cookie)
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    stinfo *sti;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_thread_t t;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int s[2];
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(adb_socketpair(s)) {
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("cannot create service socket pair\n");
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti = malloc(sizeof(stinfo));
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(sti == 0) fatal("cannot allocate stinfo");
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti->func = func;
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti->cookie = cookie;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti->fd = s[1];
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(adb_thread_create( &t, service_bootstrap_func, sti)){
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(sti);
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(s[0]);
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(s[1]);
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("cannot create service thread\n");
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("service thread started, %d:%d\n",s[0], s[1]);
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return s[0];
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
256cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#if !ADB_HOST
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int create_subprocess(const char *cmd, const char *arg0, const char *arg1)
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *devname;
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ptm;
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid_t pid;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(ptm < 0){
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fcntl(ptm, F_SETFD, FD_CLOEXEC);
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(grantpt(ptm) || unlockpt(ptm) ||
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       ((devname = (char*) ptsname(ptm)) == 0)){
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid = fork();
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(pid < 0) {
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("- fork failed: %s -\n", strerror(errno));
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(pid == 0){
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int pts;
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        setsid();
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pts = unix_open(devname, O_RDWR);
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(pts < 0) exit(-1);
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(pts, 0);
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(pts, 1);
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(pts, 2);
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(ptm);
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        execl(cmd, cmd, arg0, arg1, NULL);
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                cmd, strerror(errno), errno);
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(-1);
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
301249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        // set child's OOM adjustment to zero
302249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        char text[64];
303249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        snprintf(text, sizeof text, "/proc/%d/oom_adj", pid);
304249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        int fd = adb_open(text, O_WRONLY);
305249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        if (fd >= 0) {
306249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood            adb_write(fd, "0", 1);
307249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood            adb_close(fd);
308249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        } else {
309249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood           D("adb: unable to open %s\n", text);
310249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        }
311cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return ptm;
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
315cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#endif /* !ADB_HOST */
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/bin/sh"
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/system/bin/sh"
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
323cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#if !ADB_HOST
324cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwoodstatic void shell_service(int s, void *command)
325cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood{
326cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    char    buffer[MAX_PAYLOAD];
327cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    char    buffer2[MAX_PAYLOAD];
328cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    struct pollfd ufds[2];
329cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    int     fd, ret = 0;
330cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    unsigned count = 0;
331cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    char** args = (char **)command;
332cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    fd = create_subprocess(SHELL_COMMAND, args[0], args[1]);
333cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
334cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    while (1) {
335cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        while (count < sizeof(buffer)) {
336cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            ufds[0].fd = fd;
337cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            ufds[0].events = POLLIN | POLLHUP;
338cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            ufds[0].revents = 0;
339cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            ufds[1].fd = s;
340cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            ufds[1].events = POLLIN | POLLHUP;
341cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            ufds[1].revents = 0;
342cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            // use a 100ms timeout so we don't block indefinitely with our
343cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            // buffer partially filled.
344cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            ret = poll(ufds, 2, 100);
345cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            if (ret <= 0) {
346cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                D("poll returned %d\n", ret);
347cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                // file has closed or we timed out
348cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                // set ret to 1 so we don't exit the outer loop
349cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                ret = 1;
350cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                break;
351cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            }
352cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
353cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            if (ufds[0].revents & POLLIN) {
354cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                ret = adb_read(fd, buffer + count, sizeof(buffer) - count);
355cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                D("read fd ret: %d, count: %d\n", ret, count);
356cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                if (ret > 0)
357cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                    count += ret;
358cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                else
359cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                    break;
360cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            }
361cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            if (ufds[1].revents & POLLIN) {
362cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                ret = adb_read(s, buffer2, sizeof(buffer2));
363cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                D("read s ret: %d\n", ret);
364cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                if (ret > 0)
365cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                    adb_write(fd, buffer2, ret);
366cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                else
367cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                    break;
368cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            }
369cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
370cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            if ((ufds[0].revents & POLLHUP) || (ufds[1].revents & POLLHUP)) {
371cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                // set flag to exit after flushing the buffer
372cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                ret = -1;
373cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood                break;
374cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            }
375cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        }
376cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
377cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        D("writing: %d\n", count);
378cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        if (count > 0) {
379cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            adb_write(s, buffer, count);
380cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            count = 0;
381cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        }
382cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        if (ret <= 0)
383cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            break;
384cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    }
385cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
386cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    D("shell_service done\n");
387cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
388cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    adb_close(fd);
389cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood    adb_close(s);
390cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood}
391cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#endif // !ADB_HOST
392cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint service_to_fd(const char *name)
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ret = -1;
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strncmp(name, "tcp:", 4)) {
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int port = atoi(name + 4);
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        name = strchr(name + 4, ':');
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(name == 0) {
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ret = socket_loopback_client(port, SOCK_STREAM);
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ret >= 0)
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                disable_tcp_nagle(ret);
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_mutex_lock(&dns_lock);
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ret = socket_network_client(name + 1, port, SOCK_STREAM);
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_mutex_unlock(&dns_lock);
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "local:", 6)) {
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 6,
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "localreserved:", 14)) {
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 14,
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "localabstract:", 14)) {
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 14,
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "localfilesystem:", 16)) {
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 16,
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp("dns:", name, 4)){
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *n = strdup(name + 4);
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(n == 0) return -1;
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(dns_service, n);
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* !ADB_HOST */
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp("dev:", name, 4)) {
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = unix_open(name + 4, O_RDWR);
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "framebuffer:", 12)) {
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(framebuffer_service, 0);
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(recovery_mode && !strncmp(name, "recover:", 8)) {
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(recover_service, (void*) atoi(name + 8));
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (!strncmp(name, "jdwp:", 5)) {
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_jdwp_connection_fd(atoi(name+5));
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (!strncmp(name, "log:", 4)) {
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(log_service, get_log_file_path(name + 4));
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!HOST && !strncmp(name, "shell:", 6)) {
444cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        const char* args[2];
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(name[6]) {
446cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            args[0] = "-c";
447cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            args[1] = name + 6;
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
449cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            args[0] = "-";
450cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood            args[1] = 0;
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
452cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood        ret = create_service_thread(shell_service, (void *)args);
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "sync:", 5)) {
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(file_sync_service, NULL);
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "remount:", 8)) {
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(remount_service, NULL);
457ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    } else if(!strncmp(name, "reboot:", 7)) {
458ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        const char* arg = name + 7;
459ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood        if (*name == 0)
460ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood            arg = NULL;
461ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        ret = create_service_thread(reboot_service, (void *)arg);
462e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    } else if(!strncmp(name, "root:", 5)) {
463e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        ret = create_service_thread(restart_root_service, NULL);
464ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    } else if(!strncmp(name, "tcpip:", 6)) {
465ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        int port;
466ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        if (sscanf(name + 6, "%d", &port) == 0) {
467ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            port = 0;
468ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        }
469ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        ret = create_service_thread(restart_tcp_service, (void *)port);
470ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    } else if(!strncmp(name, "usb:", 4)) {
471ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        ret = create_service_thread(restart_usb_service, NULL);
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "echo:", 5)){
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(echo_service, 0);
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret >= 0) {
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        close_on_exec(ret);
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ret;
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct state_info {
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    transport_type transport;
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* serial;
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int state;
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void wait_for_state(int fd, void* cookie)
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct state_info* sinfo = cookie;
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* err = "unknown error";
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("wait_for_state %d\n", sinfo->state);
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err);
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(t != 0) {
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(fd, "OKAY", 4);
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sendfailmsg(fd, err);
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sinfo->serial)
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(sinfo->serial);
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(sinfo);
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("wait_for_state is done\n");
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket*  host_service_to_socket(const char*  name, const char *serial)
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strcmp(name,"track-devices")) {
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return create_device_tracker();
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct state_info* sinfo = malloc(sizeof(struct state_info));
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (serial)
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->serial = strdup(serial);
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->serial = NULL;
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        name += strlen("wait-for-");
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strncmp(name, "local", strlen("local"))) {
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->transport = kTransportLocal;
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->state = CS_DEVICE;
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(name, "usb", strlen("usb"))) {
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->transport = kTransportUsb;
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->state = CS_DEVICE;
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(name, "any", strlen("any"))) {
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->transport = kTransportAny;
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->state = CS_DEVICE;
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(sinfo);
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return NULL;
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int fd = create_service_thread(wait_for_state, sinfo);
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return create_local_socket(fd);
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return NULL;
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */
548