services.c revision 7941cf87f624e7747b5bb868a27904c7a3be0ca4
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
25408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#define  TRACE_TAG  TRACE_SERVICES
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>
33408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#    include <sys/ioctl.h>
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  endif
35cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#else
36e3aeeb4de34dbb93e832e6554f494122ba633f3bKen Sumrall#  include <cutils/android_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);
67b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood    free(cookie);
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(hp == 0) {
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(fd, &zero, 4);
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(fd, hp->h_addr, 4);
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_mutex_unlock(&dns_lock);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern int recovery_mode;
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void recover_service(int s, void *cookie)
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char buf[4096];
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned count = (unsigned) cookie;
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_creat("/tmp/update", 0644);
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(s);
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(count > 0) {
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        unsigned xfer = (count > 4096) ? 4096 : count;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(s, buf, xfer)) break;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(fd, buf, xfer)) break;
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count -= xfer;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(count == 0) {
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(s, "OKAY", 4);
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(s, "FAIL", 4);
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(s);
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_creat("/tmp/update.begin", 0644);
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
110e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Projectvoid restart_root_service(int fd, void *cookie)
111e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project{
112e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    char buf[100];
113e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    char value[PROPERTY_VALUE_MAX];
114e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
115e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    if (getuid() == 0) {
116e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        snprintf(buf, sizeof(buf), "adbd is already running as root\n");
117e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        writex(fd, buf, strlen(buf));
118e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        adb_close(fd);
119e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    } else {
120e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        property_get("ro.debuggable", value, "");
121e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        if (strcmp(value, "1") != 0) {
122e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
123e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            writex(fd, buf, strlen(buf));
124ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            adb_close(fd);
125e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            return;
126e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        }
127e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
1287941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby        property_set("service.adb.root", "1");
129e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        snprintf(buf, sizeof(buf), "restarting adbd as root\n");
130e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        writex(fd, buf, strlen(buf));
131e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        adb_close(fd);
132e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
1337941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby        // quit, and init will restart us as root
1347941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby        sleep(1);
1357941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby        exit(1);
136e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    }
137e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project}
138e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
139ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_tcp_service(int fd, void *cookie)
140ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{
141ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    char buf[100];
142ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    char value[PROPERTY_VALUE_MAX];
143ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    int port = (int)cookie;
144ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
145ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    if (port <= 0) {
146ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        snprintf(buf, sizeof(buf), "invalid port\n");
147ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        writex(fd, buf, strlen(buf));
148ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        adb_close(fd);
149ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        return;
150ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    }
151ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
152ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    snprintf(value, sizeof(value), "%d", port);
153ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    property_set("service.adb.tcp.port", value);
154ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port);
155ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    writex(fd, buf, strlen(buf));
156ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    adb_close(fd);
157ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
158ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    // quit, and init will restart us in TCP mode
159ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    sleep(1);
160ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    exit(1);
161ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood}
162ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
163ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_usb_service(int fd, void *cookie)
164ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{
165ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    char buf[100];
166ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
167ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    property_set("service.adb.tcp.port", "0");
168ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    snprintf(buf, sizeof(buf), "restarting in USB mode\n");
169ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    writex(fd, buf, strlen(buf));
170ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    adb_close(fd);
171ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
172ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    // quit, and init will restart us in USB mode
173ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    sleep(1);
174ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    exit(1);
175ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood}
176ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
177ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid reboot_service(int fd, void *arg)
178ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood{
179ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    char buf[100];
180d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood    int pid, ret;
181ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood
182ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    sync();
183d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood
184d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood    /* Attempt to unmount the SD card first.
185d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood     * No need to bother checking for errors.
186d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood     */
187d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood    pid = fork();
188d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood    if (pid == 0) {
189d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood        /* ask vdc to unmount it */
190d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood        execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount",
191d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood                getenv("EXTERNAL_STORAGE"), "force", NULL);
192d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood    } else if (pid > 0) {
193d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood        /* wait until vdc succeeds or fails */
194d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood        waitpid(pid, &ret, 0);
195d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood    }
196d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood
197e3aeeb4de34dbb93e832e6554f494122ba633f3bKen Sumrall    ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg);
198ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    if (ret < 0) {
199ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood        snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
200ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood        writex(fd, buf, strlen(buf));
201ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    }
202b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood    free(arg);
203ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    adb_close(fd);
204ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood}
205ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void echo_service(int fd, void *cookie)
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[4096];
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int r;
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *p;
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int c;
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        r = read(fd, buf, 4096);
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r == 0) goto done;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r < 0) {
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(errno == EINTR) continue;
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            else goto done;
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c = r;
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        p = buf;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while(c > 0) {
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            r = write(fd, p, c);
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(r > 0) {
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                c -= r;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                p += r;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if((r < 0) && (errno == EINTR)) continue;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto done;
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone:
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close(fd);
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int create_service_thread(void (*func)(int, void *), void *cookie)
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    stinfo *sti;
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_thread_t t;
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int s[2];
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(adb_socketpair(s)) {
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("cannot create service socket pair\n");
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti = malloc(sizeof(stinfo));
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(sti == 0) fatal("cannot allocate stinfo");
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti->func = func;
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti->cookie = cookie;
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sti->fd = s[1];
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(adb_thread_create( &t, service_bootstrap_func, sti)){
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(sti);
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(s[0]);
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(s[1]);
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("cannot create service thread\n");
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("service thread started, %d:%d\n",s[0], s[1]);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return s[0];
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
271408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if !ADB_HOST
272408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
27491acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#ifdef HAVE_WIN32_PROC
275408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
276408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
277408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    return -1;
27891acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#else /* !HAVE_WIN32_PROC */
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *devname;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ptm;
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(ptm < 0){
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fcntl(ptm, F_SETFD, FD_CLOEXEC);
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(grantpt(ptm) || unlockpt(ptm) ||
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       ((devname = (char*) ptsname(ptm)) == 0)){
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
292408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        adb_close(ptm);
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
296408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    *pid = fork();
297408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    if(*pid < 0) {
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("- fork failed: %s -\n", strerror(errno));
299408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        adb_close(ptm);
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
303408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    if(*pid == 0){
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int pts;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        setsid();
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pts = unix_open(devname, O_RDWR);
309408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        if(pts < 0) {
310408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
311408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            exit(-1);
312408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        }
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(pts, 0);
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(pts, 1);
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(pts, 2);
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
31895ef82866c7a922bf588027aa38c58a45eb84d9cBenoit Goby        adb_close(pts);
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(ptm);
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
321408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        // set OOM adjustment to zero
322249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        char text[64];
323408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid());
324249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        int fd = adb_open(text, O_WRONLY);
325249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        if (fd >= 0) {
326249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood            adb_write(fd, "0", 1);
327249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood            adb_close(fd);
328249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        } else {
329249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood           D("adb: unable to open %s\n", text);
330249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood        }
331408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        execl(cmd, cmd, arg0, arg1, NULL);
332408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
333408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                cmd, strerror(errno), errno);
334408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        exit(-1);
335408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    } else {
336408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        // Don't set child's OOM adjustment to zero.
337408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        // Let the child do it itself, as sometimes the parent starts
338408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        // running before the child has a /proc/pid/oom_adj.
339408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        // """adb: unable to open /proc/644/oom_adj""" seen in some logs.
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return ptm;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
34291acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#endif /* !HAVE_WIN32_PROC */
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
344408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif  /* !ABD_HOST */
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/bin/sh"
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/system/bin/sh"
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
352408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if !ADB_HOST
353408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic void subproc_waiter_service(int fd, void *cookie)
354408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{
355408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    pid_t pid = (pid_t)cookie;
356408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall
357408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    D("entered. fd=%d of pid=%d\n", fd, pid);
358408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    for (;;) {
359408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        int status;
360408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        pid_t p = waitpid(pid, &status, 0);
361408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        if (p == pid) {
362408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status);
363408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            if (WIFSIGNALED(status)) {
364408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                D("*** Killed by signal %d\n", WTERMSIG(status));
365408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                break;
366408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            } else if (!WIFEXITED(status)) {
367408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                D("*** Didn't exit!!. status %d\n", status);
368408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                break;
369408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            } else if (WEXITSTATUS(status) >= 0) {
370408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                D("*** Exit code %d\n", WEXITSTATUS(status));
371408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                break;
372408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            }
373408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall         }
374408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        usleep(100000);  // poll every 0.1 sec
375408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    }
376408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno);
377408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    if (SHELL_EXIT_NOTIFY_FD >=0) {
378408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall      int res;
379408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall      res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd));
380408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall      D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n",
381408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        SHELL_EXIT_NOTIFY_FD, pid, res, errno);
382408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    }
383408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall}
384408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall
385408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic int create_subproc_thread(const char *name)
386408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{
387408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    stinfo *sti;
388408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    adb_thread_t t;
389408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    int ret_fd;
390408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    pid_t pid;
391408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    if(name) {
392408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
393408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    } else {
394408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
395408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    }
396408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);
397408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall
398408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    sti = malloc(sizeof(stinfo));
399408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    if(sti == 0) fatal("cannot allocate stinfo");
400408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    sti->func = subproc_waiter_service;
401408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    sti->cookie = (void*)pid;
402408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    sti->fd = ret_fd;
403408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall
404408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    if(adb_thread_create( &t, service_bootstrap_func, sti)){
405408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        free(sti);
406408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        adb_close(ret_fd);
407408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        printf("cannot create service thread\n");
408408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        return -1;
409408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    }
410408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall
411408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    D("service thread started, fd=%d pid=%d\n",ret_fd, pid);
412408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall    return ret_fd;
413408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall}
414408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif
415408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint service_to_fd(const char *name)
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ret = -1;
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strncmp(name, "tcp:", 4)) {
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int port = atoi(name + 4);
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        name = strchr(name + 4, ':');
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(name == 0) {
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ret = socket_loopback_client(port, SOCK_STREAM);
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ret >= 0)
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                disable_tcp_nagle(ret);
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_mutex_lock(&dns_lock);
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ret = socket_network_client(name + 1, port, SOCK_STREAM);
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_mutex_unlock(&dns_lock);
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_WINSOCK   /* winsock doesn't implement unix domain sockets */
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "local:", 6)) {
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 6,
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "localreserved:", 14)) {
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 14,
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "localabstract:", 14)) {
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 14,
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "localfilesystem:", 16)) {
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = socket_local_client(name + 16,
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp("dns:", name, 4)){
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *n = strdup(name + 4);
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(n == 0) return -1;
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(dns_service, n);
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* !ADB_HOST */
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp("dev:", name, 4)) {
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = unix_open(name + 4, O_RDWR);
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "framebuffer:", 12)) {
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(framebuffer_service, 0);
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(recovery_mode && !strncmp(name, "recover:", 8)) {
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(recover_service, (void*) atoi(name + 8));
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (!strncmp(name, "jdwp:", 5)) {
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_jdwp_connection_fd(atoi(name+5));
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (!strncmp(name, "log:", 4)) {
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(log_service, get_log_file_path(name + 4));
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!HOST && !strncmp(name, "shell:", 6)) {
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(name[6]) {
468408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            ret = create_subproc_thread(name + 6);
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
470408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            ret = create_subproc_thread(0);
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "sync:", 5)) {
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(file_sync_service, NULL);
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "remount:", 8)) {
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(remount_service, NULL);
476ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood    } else if(!strncmp(name, "reboot:", 7)) {
477b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood        void* arg = strdup(name + 7);
478b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood        if(arg == 0) return -1;
479b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood        ret = create_service_thread(reboot_service, arg);
480e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    } else if(!strncmp(name, "root:", 5)) {
481e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        ret = create_service_thread(restart_root_service, NULL);
482d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    } else if(!strncmp(name, "backup:", 7)) {
483d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        char* arg = strdup(name+7);
484d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        if (arg == NULL) return -1;
485702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        ret = backup_service(BACKUP, arg);
486702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    } else if(!strncmp(name, "restore:", 8)) {
487702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        ret = backup_service(RESTORE, NULL);
488ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    } else if(!strncmp(name, "tcpip:", 6)) {
489ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        int port;
490ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        if (sscanf(name + 6, "%d", &port) == 0) {
491ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            port = 0;
492ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        }
493ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        ret = create_service_thread(restart_tcp_service, (void *)port);
494ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    } else if(!strncmp(name, "usb:", 4)) {
495ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        ret = create_service_thread(restart_usb_service, NULL);
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(!strncmp(name, "echo:", 5)){
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = create_service_thread(echo_service, 0);
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret >= 0) {
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        close_on_exec(ret);
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ret;
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct state_info {
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    transport_type transport;
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* serial;
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int state;
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void wait_for_state(int fd, void* cookie)
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct state_info* sinfo = cookie;
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* err = "unknown error";
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("wait_for_state %d\n", sinfo->state);
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err);
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(t != 0) {
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        writex(fd, "OKAY", 4);
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sendfailmsg(fd, err);
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sinfo->serial)
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(sinfo->serial);
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(sinfo);
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D("wait_for_state is done\n");
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket*  host_service_to_socket(const char*  name, const char *serial)
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strcmp(name,"track-devices")) {
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return create_device_tracker();
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct state_info* sinfo = malloc(sizeof(struct state_info));
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (serial)
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->serial = strdup(serial);
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->serial = NULL;
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        name += strlen("wait-for-");
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strncmp(name, "local", strlen("local"))) {
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->transport = kTransportLocal;
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->state = CS_DEVICE;
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(name, "usb", strlen("usb"))) {
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->transport = kTransportUsb;
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->state = CS_DEVICE;
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strncmp(name, "any", strlen("any"))) {
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->transport = kTransportAny;
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sinfo->state = CS_DEVICE;
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(sinfo);
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return NULL;
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int fd = create_service_thread(wait_for_state, sinfo);
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return create_local_socket(fd);
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return NULL;
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */
572