2 * Copyright (C) 2007 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
25 #define TRACE_TAG TRACE_ADB
27 #include "file_sync_service.h"
31 # include <netinet/in.h>
35 //#include <sys/reboot.h> // liunote
36 #include <linux/reboot.h>
39 typedef struct stinfo stinfo
;
42 void (*func
)(int fd
, void *cookie
);
48 void *service_bootstrap_func(void *x
)
51 sti
->func(sti
->fd
, sti
->cookie
);
57 ADB_MUTEX_DEFINE( dns_lock
);
59 static void dns_service(int fd
, void *cookie
)
61 char *hostname
= cookie
;
65 adb_mutex_lock(&dns_lock
);
66 hp
= gethostbyname(hostname
);
71 writex(fd
, hp
->h_addr
, 4);
73 adb_mutex_unlock(&dns_lock
);
77 extern int recovery_mode
;
79 static void recover_service(int s
, void *cookie
)
81 unsigned char buf
[4096];
82 unsigned count
= (unsigned) cookie
;
85 fd
= adb_creat("/tmp/update", 0644);
92 unsigned xfer
= (count
> 4096) ? 4096 : count
;
93 if(readx(s
, buf
, xfer
)) break;
94 if(writex(fd
, buf
, xfer
)) break;
101 writex(s
, "FAIL", 4);
106 fd
= adb_creat("/tmp/update.begin", 0644);
110 void restart_root_service(int fd
, void *cookie
)
113 //char value[PROPERTY_VALUE_MAX];
116 snprintf(buf
, sizeof(buf
), "adbd is already running as root\n");
117 writex(fd
, buf
, strlen(buf
));
120 #if 0 // liunote remove for no property
121 property_get("ro.debuggable", value
, "");
122 if (strcmp(value
, "1") != 0) {
123 snprintf(buf
, sizeof(buf
), "adbd cannot run as root in production builds\n");
124 writex(fd
, buf
, strlen(buf
));
129 property_set("service.adb.root", "1");
130 snprintf(buf
, sizeof(buf
), "restarting adbd as root\n");
131 writex(fd
, buf
, strlen(buf
));
135 // quit, and init will restart us as root
141 void restart_tcp_service(int fd
, void *cookie
)
144 // char value[PROPERTY_VALUE_MAX];
145 int port
= (int)cookie
;
148 snprintf(buf
, sizeof(buf
), "invalid port\n");
149 writex(fd
, buf
, strlen(buf
));
154 // snprintf(value, sizeof(value), "%d", port); // liunote remove
155 // property_set("service.adb.tcp.port", value);
157 snprintf(buf
, sizeof(buf
), "restarting in TCP mode port: %d\n", port
);
158 writex(fd
, buf
, strlen(buf
));
161 // quit, and init will restart us in TCP mode
166 void restart_usb_service(int fd
, void *cookie
)
170 //property_set("service.adb.tcp.port", "0"); // liunote remove
171 snprintf(buf
, sizeof(buf
), "restarting in USB mode\n");
172 writex(fd
, buf
, strlen(buf
));
175 // quit, and init will restart us in USB mode
180 #if 1 /* liunote use reboot service do adbd exit */
181 void reboot_service(int fd
, void *arg
)
188 ret
= __reboot(LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
189 LINUX_REBOOT_CMD_RESTART2
, (char *)arg
);
191 snprintf(buf
, sizeof(buf
), "reboot failed: %s\n", strerror(errno
));
192 writex(fd
, buf
, strlen(buf
));
208 static void echo_service(int fd
, void *cookie
)
216 r
= read(fd
, buf
, 4096);
217 if(r
== 0) goto done
;
219 if(errno
== EINTR
) continue;
232 if((r
< 0) && (errno
== EINTR
)) continue;
241 static int create_service_thread(void (*func
)(int, void *), void *cookie
)
247 if(adb_socketpair(s
)) {
248 printf("cannot create service socket pair\n");
252 sti
= malloc(sizeof(stinfo
));
253 if(sti
== 0) fatal("cannot allocate stinfo");
255 sti
->cookie
= cookie
;
258 if(adb_thread_create( &t
, service_bootstrap_func
, sti
)){
262 printf("cannot create service thread\n");
266 D("service thread started, %d:%d\n",s
[0], s
[1]);
270 static int create_subprocess(const char *cmd
, const char *arg0
, const char *arg1
)
272 #ifdef HAVE_WIN32_PROC
273 fprintf(stderr
, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd
, arg0
, arg1
);
275 #else /* !HAVE_WIN32_PROC */
280 ptm
= unix_open("/dev/ptmx", O_RDWR
); // | O_NOCTTY);
282 printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno
));
285 fcntl(ptm
, F_SETFD
, FD_CLOEXEC
);
287 if(grantpt(ptm
) || unlockpt(ptm
) ||
288 ((devname
= (char*) ptsname(ptm
)) == 0)){
289 printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno
));
295 printf("- fork failed: %s -\n", strerror(errno
));
304 pts
= unix_open(devname
, O_RDWR
);
305 if(pts
< 0) exit(-1);
313 execl(cmd
, cmd
, arg0
, arg1
, NULL
);
314 fprintf(stderr
, "- exec '%s' failed: %s (%d) -\n",
315 cmd
, strerror(errno
), errno
);
319 // set child's OOM adjustment to zero
321 snprintf(text
, sizeof text
, "/proc/%d/oom_adj", pid
);
322 int fd
= adb_open(text
, O_WRONLY
);
324 adb_write(fd
, "0", 1);
327 D("adb: unable to open %s\n", text
);
332 #endif /* !HAVE_WIN32_PROC */
336 #define SHELL_COMMAND "/bin/sh"
338 #define SHELL_COMMAND "/system/bin/sh"
341 int service_to_fd(const char *name
)
345 if(!strncmp(name
, "tcp:", 4)) {
346 int port
= atoi(name
+ 4);
347 name
= strchr(name
+ 4, ':');
349 ret
= socket_loopback_client(port
, SOCK_STREAM
);
351 disable_tcp_nagle(ret
);
354 adb_mutex_lock(&dns_lock
);
355 ret
= socket_network_client(name
+ 1, port
, SOCK_STREAM
);
356 adb_mutex_unlock(&dns_lock
);
361 #ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */
362 } else if(!strncmp(name
, "local:", 6)) {
363 ret
= socket_local_client(name
+ 6,
364 ANDROID_SOCKET_NAMESPACE_RESERVED
, SOCK_STREAM
);
365 } else if(!strncmp(name
, "localreserved:", 14)) {
366 ret
= socket_local_client(name
+ 14,
367 ANDROID_SOCKET_NAMESPACE_RESERVED
, SOCK_STREAM
);
368 } else if(!strncmp(name
, "localabstract:", 14)) {
369 ret
= socket_local_client(name
+ 14,
370 ANDROID_SOCKET_NAMESPACE_ABSTRACT
, SOCK_STREAM
);
371 } else if(!strncmp(name
, "localfilesystem:", 16)) {
372 ret
= socket_local_client(name
+ 16,
373 ANDROID_SOCKET_NAMESPACE_FILESYSTEM
, SOCK_STREAM
);
376 } else if(!strncmp("dns:", name
, 4)){
377 char *n
= strdup(name
+ 4);
378 if(n
== 0) return -1;
379 ret
= create_service_thread(dns_service
, n
);
380 #else /* !ADB_HOST */
381 } else if(!strncmp("dev:", name
, 4)) {
382 ret
= unix_open(name
+ 4, O_RDWR
);
383 } else if(!strncmp(name
, "framebuffer:", 12)) {
384 ret
= create_service_thread(framebuffer_service
, 0);
385 } else if(recovery_mode
&& !strncmp(name
, "recover:", 8)) {
386 ret
= create_service_thread(recover_service
, (void*) atoi(name
+ 8));
387 } else if (!strncmp(name
, "jdwp:", 5)) {
388 ret
= create_jdwp_connection_fd(atoi(name
+5));
389 } /* else if (!strncmp(name, "log:", 4)) {
390 ret = create_service_thread(log_service, get_log_file_path(name + 4)); */
391 #endif /* liunote remove log_service for log cat cmd */
392 /*}*/ else if(!HOST
&& !strncmp(name
, "shell:", 6)) {
394 ret
= create_subprocess(SHELL_COMMAND
, "-c", name
+ 6);
396 ret
= create_subprocess(SHELL_COMMAND
, "-", 0);
399 } else if(!strncmp(name
, "sync:", 5)) {
400 ret
= create_service_thread(file_sync_service
, NULL
);
401 } else if(!strncmp(name
, "remount:", 8)) {
402 ret
= create_service_thread(remount_service
, NULL
);
403 } else if(!strncmp(name
, "reboot:", 7)) {
404 void* arg
= strdup(name
+ 7);
405 if(arg
== 0) return -1;
406 ret
= create_service_thread(reboot_service
, arg
); /* liunote use reboot service do adb close */
407 } else if(!strncmp(name
, "root:", 5)) {
408 ret
= create_service_thread(restart_root_service
, NULL
);
409 } else if(!strncmp(name
, "tcpip:", 6)) {
411 if (sscanf(name
+ 6, "%d", &port
) == 0) {
414 ret
= create_service_thread(restart_tcp_service
, (void *)port
);
415 } else if(!strncmp(name
, "usb:", 4)) {
416 ret
= create_service_thread(restart_usb_service
, NULL
);
419 } else if(!strncmp(name
, "echo:", 5)){
420 ret
= create_service_thread(echo_service
, 0);
431 transport_type transport
;
436 static void wait_for_state(int fd
, void* cookie
)
438 struct state_info
* sinfo
= cookie
;
439 char* err
= "unknown error";
441 D("wait_for_state %d\n", sinfo
->state
);
443 atransport
*t
= acquire_one_transport(sinfo
->state
, sinfo
->transport
, sinfo
->serial
, &err
);
445 writex(fd
, "OKAY", 4);
447 sendfailmsg(fd
, err
);
454 D("wait_for_state is done\n");
459 asocket
* host_service_to_socket(const char* name
, const char *serial
)
461 if (!strcmp(name
,"track-devices")) {
462 return create_device_tracker();
463 } else if (!strncmp(name
, "wait-for-", strlen("wait-for-"))) {
464 struct state_info
* sinfo
= malloc(sizeof(struct state_info
));
467 sinfo
->serial
= strdup(serial
);
469 sinfo
->serial
= NULL
;
471 name
+= strlen("wait-for-");
473 if (!strncmp(name
, "local", strlen("local"))) {
474 sinfo
->transport
= kTransportLocal
;
475 sinfo
->state
= CS_DEVICE
;
476 } else if (!strncmp(name
, "usb", strlen("usb"))) {
477 sinfo
->transport
= kTransportUsb
;
478 sinfo
->state
= CS_DEVICE
;
479 } else if (!strncmp(name
, "any", strlen("any"))) {
480 sinfo
->transport
= kTransportAny
;
481 sinfo
->state
= CS_DEVICE
;
487 int fd
= create_service_thread(wait_for_state
, sinfo
);
488 return create_local_socket(fd
);
492 #endif /* ADB_HOST */