summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Android Open Source Project2008-10-21 09:00:00 -0500
committerThe Android Open Source Project2008-10-21 09:00:00 -0500
commit4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53 (patch)
tree54fd1b2695a591d2306d41264df67c53077b752c
downloadplatform-system-core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.tar.gz
platform-system-core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.tar.xz
platform-system-core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.zip
Initial Contribution
-rw-r--r--Android.mk28
-rw-r--r--README20
-rw-r--r--adb/Android.mk116
-rw-r--r--adb/adb.c1093
-rw-r--r--adb/adb.h402
-rw-r--r--adb/adb_client.c318
-rw-r--r--adb/adb_client.h49
-rw-r--r--adb/commandline.c1371
-rw-r--r--adb/console.c45
-rw-r--r--adb/file_sync_client.c1022
-rw-r--r--adb/file_sync_service.c412
-rw-r--r--adb/file_sync_service.h87
-rw-r--r--adb/framebuffer_service.c69
-rw-r--r--adb/get_my_path_darwin.c31
-rw-r--r--adb/get_my_path_linux.c33
-rw-r--r--adb/get_my_path_windows.c31
-rwxr-xr-xadb/history.h13
-rw-r--r--adb/jdwp_service.c709
-rw-r--r--adb/kdbg.c474
-rw-r--r--adb/log_service.c92
-rw-r--r--adb/mutex_list.h14
-rw-r--r--adb/protocol.txt252
-rw-r--r--adb/remount_service.c103
-rw-r--r--adb/services.c370
-rwxr-xr-xadb/shlist.c185
-rwxr-xr-xadb/shlist.h34
-rw-r--r--adb/sockets.c733
-rw-r--r--adb/sockets.diabin0 -> 2333 bytes
-rw-r--r--adb/sysdeps.h473
-rw-r--r--adb/sysdeps_win32.c1953
-rw-r--r--adb/test_track_devices.c97
-rw-r--r--adb/test_track_jdwp.c97
-rw-r--r--adb/transport.c958
-rw-r--r--adb/transport_local.c262
-rw-r--r--adb/transport_usb.c147
-rw-r--r--adb/usb_linux.c653
-rw-r--r--adb/usb_linux_client.c156
-rw-r--r--adb/usb_osx.c536
-rw-r--r--adb/usb_windows.c513
-rw-r--r--cpio/Android.mk13
-rw-r--r--cpio/mkbootfs.c220
-rw-r--r--debuggerd/Android.mk22
-rw-r--r--debuggerd/MODULE_LICENSE_APACHE20
-rw-r--r--debuggerd/NOTICE190
-rw-r--r--debuggerd/crasher.c105
-rw-r--r--debuggerd/crashglue.S28
-rw-r--r--debuggerd/debuggerd.c852
-rw-r--r--debuggerd/getevent.c219
-rw-r--r--debuggerd/pr-support.c345
-rw-r--r--debuggerd/unwind-arm.c618
-rw-r--r--debuggerd/utility.c78
-rw-r--r--debuggerd/utility.h56
-rw-r--r--fastboot/Android.mk57
-rw-r--r--fastboot/bootimg.c85
-rw-r--r--fastboot/engine.c289
-rw-r--r--fastboot/engineering_key.p12bin0 -> 2610 bytes
-rw-r--r--fastboot/fastboot.c657
-rw-r--r--fastboot/fastboot.h57
-rwxr-xr-xfastboot/genkey.sh25
-rwxr-xr-xfastboot/p12topem.sh9
-rw-r--r--fastboot/protocol.c181
-rwxr-xr-xfastboot/signfile.sh10
-rw-r--r--fastboot/usb.h64
-rw-r--r--fastboot/usb_linux.c373
-rw-r--r--fastboot/usb_osx.c538
-rw-r--r--fastboot/usb_windows.c375
-rw-r--r--fastboot/usbtest.c212
-rw-r--r--fastboot/util_linux.c52
-rw-r--r--fastboot/util_osx.c47
-rw-r--r--fastboot/util_windows.c93
-rw-r--r--include/arch/darwin-x86/AndroidConfig.h260
-rw-r--r--include/arch/linux-arm/AndroidConfig.h294
-rw-r--r--include/arch/linux-x86/AndroidConfig.h286
-rw-r--r--include/arch/windows/AndroidConfig.h290
-rw-r--r--include/ctest/ctest.h70
-rwxr-xr-xinclude/cutils/adb_networking.h35
-rw-r--r--include/cutils/array.h67
-rw-r--r--include/cutils/ashmem.h42
-rw-r--r--include/cutils/atomic.h79
-rw-r--r--include/cutils/config_utils.h61
-rw-r--r--include/cutils/cpu_info.h34
-rw-r--r--include/cutils/dir_hash.h26
-rw-r--r--include/cutils/event_tag_map.h50
-rw-r--r--include/cutils/fdevent.h74
-rw-r--r--include/cutils/hashmap.h150
-rw-r--r--include/cutils/jstring.h43
-rw-r--r--include/cutils/log.h346
-rw-r--r--include/cutils/logd.h78
-rw-r--r--include/cutils/logprint.h156
-rw-r--r--include/cutils/memory.h42
-rw-r--r--include/cutils/misc.h48
-rw-r--r--include/cutils/mq.h124
-rw-r--r--include/cutils/mspace.h117
-rw-r--r--include/cutils/process_name.h42
-rw-r--r--include/cutils/properties.h70
-rw-r--r--include/cutils/record_stream.h43
-rw-r--r--include/cutils/selector.h130
-rw-r--r--include/cutils/sockets.h100
-rw-r--r--include/cutils/threads.h146
-rw-r--r--include/cutils/tztime.h32
-rw-r--r--include/cutils/uio.h48
-rw-r--r--include/cutils/zygote.h32
-rw-r--r--include/mincrypt/rsa.h56
-rw-r--r--include/mincrypt/sha.h56
-rw-r--r--include/pixelflinger/format.h126
-rw-r--r--include/pixelflinger/pixelflinger.h330
-rw-r--r--include/private/android_filesystem_config.h209
-rw-r--r--include/private/pixelflinger/ggl_context.h542
-rw-r--r--include/private/pixelflinger/ggl_fixed.h302
-rw-r--r--include/zipfile/zipfile.h58
-rw-r--r--init/Android.mk33
-rw-r--r--init/MODULE_LICENSE_APACHE20
-rw-r--r--init/NOTICE190
-rw-r--r--init/README.BOOTCHART34
-rw-r--r--init/bootchart.c337
-rw-r--r--init/builtins.c402
-rw-r--r--init/devices.c622
-rw-r--r--init/devices.h27
-rwxr-xr-xinit/grab-bootchart.sh22
-rw-r--r--init/init.c891
-rw-r--r--init/init.h167
-rw-r--r--init/keywords.h75
-rw-r--r--init/logo.c163
-rw-r--r--init/parser.c755
-rw-r--r--init/property_service.c502
-rw-r--r--init/property_service.h28
-rw-r--r--init/readme.txt290
-rw-r--r--init/util.c211
-rw-r--r--libctest/Android.mk7
-rw-r--r--libctest/ctest.c161
-rw-r--r--libcutils/Android.mk106
-rw-r--r--libcutils/MODULE_LICENSE_APACHE20
-rw-r--r--libcutils/NOTICE190
-rw-r--r--libcutils/adb_networking.c172
-rw-r--r--libcutils/array.c155
-rw-r--r--libcutils/ashmem-dev.c85
-rw-r--r--libcutils/ashmem-host.c94
-rw-r--r--libcutils/atomic-android-arm.S222
-rw-r--r--libcutils/atomic-android-armv6.S169
-rw-r--r--libcutils/atomic.c335
-rw-r--r--libcutils/buffer.c116
-rw-r--r--libcutils/buffer.h112
-rw-r--r--libcutils/config_utils.c317
-rw-r--r--libcutils/cpu_info.c83
-rw-r--r--libcutils/dir_hash.c334
-rw-r--r--libcutils/dlmalloc_stubs.c29
-rw-r--r--libcutils/fdevent.c506
-rw-r--r--libcutils/hashmap.c350
-rw-r--r--libcutils/load_file.c51
-rw-r--r--libcutils/loghack.h38
-rw-r--r--libcutils/memory.c87
-rw-r--r--libcutils/memset32.S93
-rw-r--r--libcutils/mq.c1357
-rw-r--r--libcutils/mspace.c246
-rw-r--r--libcutils/private.h368
-rw-r--r--libcutils/process_name.c75
-rw-r--r--libcutils/properties.c368
-rw-r--r--libcutils/record_stream.c186
-rw-r--r--libcutils/selector.c263
-rw-r--r--libcutils/socket_inaddr_any_server.c70
-rw-r--r--libcutils/socket_local.h39
-rw-r--r--libcutils/socket_local_client.c167
-rw-r--r--libcutils/socket_local_server.c124
-rw-r--r--libcutils/socket_loopback_client.c59
-rw-r--r--libcutils/socket_loopback_server.c71
-rw-r--r--libcutils/socket_network_client.c65
-rw-r--r--libcutils/strdup16to8.c104
-rw-r--r--libcutils/strdup8to16.c209
-rw-r--r--libcutils/threads.c84
-rw-r--r--libcutils/tzfile.h180
-rw-r--r--libcutils/tztime.c1915
-rw-r--r--libcutils/uio.c76
-rw-r--r--libcutils/zygote.c267
-rw-r--r--liblog/Android.mk72
-rw-r--r--liblog/event_tag_map.c438
-rw-r--r--liblog/fake_log_device.c677
-rw-r--r--liblog/logd_write.c229
-rw-r--r--liblog/logprint.c972
-rw-r--r--libmincrypt/Android.mk11
-rw-r--r--libmincrypt/rsa.c198
-rw-r--r--libmincrypt/sha.c142
-rw-r--r--libmincrypt/tools/Android.mk21
-rw-r--r--libmincrypt/tools/DumpPublicKey.java130
-rw-r--r--libmincrypt/tools/DumpPublicKey.mf1
-rw-r--r--libnetutils/Android.mk23
-rw-r--r--libnetutils/dhcp_utils.c186
-rw-r--r--libnetutils/dhcpclient.c562
-rw-r--r--libnetutils/dhcpmsg.c100
-rw-r--r--libnetutils/dhcpmsg.h106
-rw-r--r--libnetutils/ifc_utils.c428
-rw-r--r--libnetutils/ifc_utils.h35
-rw-r--r--libnetutils/packet.c239
-rw-r--r--libnetutils/packet.h25
-rw-r--r--libpixelflinger/Android.mk87
-rw-r--r--libpixelflinger/MODULE_LICENSE_APACHE20
-rw-r--r--libpixelflinger/NOTICE190
-rw-r--r--libpixelflinger/buffer.cpp384
-rw-r--r--libpixelflinger/buffer.h39
-rw-r--r--libpixelflinger/clear.cpp171
-rw-r--r--libpixelflinger/clear.h30
-rw-r--r--libpixelflinger/codeflinger/ARMAssembler.cpp428
-rw-r--r--libpixelflinger/codeflinger/ARMAssembler.h155
-rw-r--r--libpixelflinger/codeflinger/ARMAssemblerInterface.cpp173
-rw-r--r--libpixelflinger/codeflinger/ARMAssemblerInterface.h324
-rw-r--r--libpixelflinger/codeflinger/ARMAssemblerProxy.cpp200
-rw-r--r--libpixelflinger/codeflinger/ARMAssemblerProxy.h123
-rw-r--r--libpixelflinger/codeflinger/CodeCache.cpp151
-rw-r--r--libpixelflinger/codeflinger/CodeCache.h134
-rw-r--r--libpixelflinger/codeflinger/GGLAssembler.cpp1135
-rw-r--r--libpixelflinger/codeflinger/GGLAssembler.h549
-rw-r--r--libpixelflinger/codeflinger/armreg.h300
-rw-r--r--libpixelflinger/codeflinger/blending.cpp676
-rw-r--r--libpixelflinger/codeflinger/disassem.c702
-rw-r--r--libpixelflinger/codeflinger/disassem.h65
-rw-r--r--libpixelflinger/codeflinger/load_store.cpp378
-rw-r--r--libpixelflinger/codeflinger/texturing.cpp1208
-rw-r--r--libpixelflinger/fixed.cpp339
-rw-r--r--libpixelflinger/format.cpp67
-rw-r--r--libpixelflinger/picker.cpp173
-rw-r--r--libpixelflinger/picker.h31
-rw-r--r--libpixelflinger/pixelflinger.cpp843
-rw-r--r--libpixelflinger/raster.cpp217
-rw-r--r--libpixelflinger/raster.h33
-rw-r--r--libpixelflinger/rotate90CW_4x4_16v6.S62
-rw-r--r--libpixelflinger/scanline.cpp1487
-rw-r--r--libpixelflinger/scanline.h32
-rw-r--r--libpixelflinger/t32cb16blend.S171
-rw-r--r--libpixelflinger/tinyutils/KeyedVector.h193
-rw-r--r--libpixelflinger/tinyutils/SharedBuffer.cpp106
-rw-r--r--libpixelflinger/tinyutils/SharedBuffer.h138
-rw-r--r--libpixelflinger/tinyutils/TypeHelpers.h245
-rw-r--r--libpixelflinger/tinyutils/Vector.h352
-rw-r--r--libpixelflinger/tinyutils/VectorImpl.cpp552
-rw-r--r--libpixelflinger/tinyutils/VectorImpl.h185
-rw-r--r--libpixelflinger/tinyutils/smartpointer.h170
-rw-r--r--libpixelflinger/trap.cpp1173
-rw-r--r--libpixelflinger/trap.h31
-rw-r--r--libzipfile/Android.mk48
-rw-r--r--libzipfile/MODULE_LICENSE_APACHE20
-rw-r--r--libzipfile/NOTICE190
-rw-r--r--libzipfile/centraldir.c256
-rw-r--r--libzipfile/private.h45
-rw-r--r--libzipfile/test_zipfile.c92
-rw-r--r--libzipfile/zipfile.c160
-rw-r--r--logcat/Android.mk27
-rw-r--r--logcat/MODULE_LICENSE_APACHE20
-rw-r--r--logcat/NOTICE190
-rw-r--r--logcat/event-log-tags305
-rw-r--r--logcat/logcat.cpp569
-rw-r--r--logwrapper/Android.mk7
-rw-r--r--logwrapper/logwrapper.c126
-rw-r--r--mkbootimg/Android.mk11
-rw-r--r--mkbootimg/bootimg.h97
-rw-r--r--mkbootimg/mkbootimg.c257
-rw-r--r--mountd/Android.mk19
-rw-r--r--mountd/AutoMount.c924
-rw-r--r--mountd/MODULE_LICENSE_APACHE20
-rw-r--r--mountd/NOTICE190
-rw-r--r--mountd/ProcessKiller.c209
-rw-r--r--mountd/Server.c232
-rw-r--r--mountd/mountd.c106
-rw-r--r--mountd/mountd.h159
-rw-r--r--netcfg/Android.mk16
-rw-r--r--netcfg/MODULE_LICENSE_APACHE20
-rw-r--r--netcfg/NOTICE190
-rw-r--r--netcfg/netcfg.c175
-rw-r--r--rootdir/Android.mk57
-rw-r--r--rootdir/etc/dbus.conf67
-rw-r--r--rootdir/etc/hcid.conf64
-rw-r--r--rootdir/etc/hosts1
-rw-r--r--rootdir/etc/init.goldfish.rc53
-rwxr-xr-xrootdir/etc/init.goldfish.sh39
-rwxr-xr-xrootdir/etc/init.gprs-pppd23
-rwxr-xr-xrootdir/etc/init.testmenu322
-rw-r--r--rootdir/etc/mountd.conf13
-rw-r--r--rootdir/etc/ppp/chap-secrets2
-rwxr-xr-xrootdir/etc/ppp/ip-down14
-rwxr-xr-xrootdir/etc/ppp/ip-up24
-rw-r--r--rootdir/init.rc235
-rw-r--r--sh/Android.mk49
-rw-r--r--sh/MODULE_LICENSE_BSD0
-rw-r--r--sh/NOTICE31
-rw-r--r--sh/TOUR357
-rw-r--r--sh/alias.c273
-rw-r--r--sh/alias.h50
-rw-r--r--sh/arith.c1587
-rw-r--r--sh/arith.h25
-rw-r--r--sh/arith.y199
-rw-r--r--sh/arith_lex.c1890
-rw-r--r--sh/arith_lex.l103
-rw-r--r--sh/bltin/bltin.h94
-rw-r--r--sh/bltin/echo.1109
-rw-r--r--sh/bltin/echo.c116
-rw-r--r--sh/builtins.c61
-rw-r--r--sh/builtins.def94
-rw-r--r--sh/builtins.h56
-rw-r--r--sh/cd.c446
-rw-r--r--sh/cd.h35
-rw-r--r--sh/error.c366
-rw-r--r--sh/error.h117
-rw-r--r--sh/eval.c1257
-rw-r--r--sh/eval.h64
-rw-r--r--sh/exec.c1063
-rw-r--r--sh/exec.h79
-rw-r--r--sh/expand.c1559
-rw-r--r--sh/expand.h72
-rw-r--r--sh/funcs/cmv50
-rw-r--r--sh/funcs/dirs74
-rw-r--r--sh/funcs/kill50
-rw-r--r--sh/funcs/login39
-rw-r--r--sh/funcs/newgrp38
-rw-r--r--sh/funcs/popd74
-rw-r--r--sh/funcs/pushd74
-rw-r--r--sh/funcs/suspend42
-rw-r--r--sh/histedit.c540
-rw-r--r--sh/init.c1090
-rw-r--r--sh/init.h39
-rw-r--r--sh/input.c531
-rw-r--r--sh/input.h62
-rw-r--r--sh/jobs.c1487
-rw-r--r--sh/jobs.h106
-rw-r--r--sh/machdep.h47
-rw-r--r--sh/main.c394
-rw-r--r--sh/main.h43
-rw-r--r--sh/memalloc.c307
-rw-r--r--sh/memalloc.h77
-rw-r--r--sh/miscbltin.c447
-rw-r--r--sh/miscbltin.h31
-rw-r--r--sh/mkbuiltins136
-rw-r--r--sh/mkinit.sh197
-rw-r--r--sh/mknodes.sh217
-rw-r--r--sh/mktokens92
-rw-r--r--sh/myhistedit.h49
-rw-r--r--sh/mystring.c133
-rw-r--r--sh/mystring.h45
-rw-r--r--sh/nodes.c347
-rw-r--r--sh/nodes.c.pat166
-rw-r--r--sh/nodes.h159
-rw-r--r--sh/nodetypes143
-rw-r--r--sh/options.c530
-rw-r--r--sh/options.h131
-rw-r--r--sh/output.c516
-rw-r--r--sh/output.h81
-rw-r--r--sh/parser.c1651
-rw-r--r--sh/parser.h82
-rw-r--r--sh/redir.c389
-rw-r--r--sh/redir.h48
-rw-r--r--sh/sh.11928
-rw-r--r--sh/shell.h83
-rw-r--r--sh/show.c425
-rw-r--r--sh/show.h45
-rw-r--r--sh/syntax.c102
-rw-r--r--sh/syntax.h83
-rw-r--r--sh/token.h112
-rw-r--r--sh/trap.c470
-rw-r--r--sh/trap.h46
-rw-r--r--sh/var.c825
-rw-r--r--sh/var.h131
-rw-r--r--toolbox/Android.mk85
-rw-r--r--toolbox/MODULE_LICENSE_BSD0
-rw-r--r--toolbox/NOTICE131
-rw-r--r--toolbox/alarm.c190
-rw-r--r--toolbox/cat.c291
-rw-r--r--toolbox/chmod.c40
-rw-r--r--toolbox/cmp.c90
-rw-r--r--toolbox/date.c132
-rw-r--r--toolbox/dd.c1358
-rw-r--r--toolbox/dd.h91
-rw-r--r--toolbox/df.c63
-rw-r--r--toolbox/dmesg.c43
-rw-r--r--toolbox/exists.c16
-rw-r--r--toolbox/getevent.c427
-rw-r--r--toolbox/getprop.c34
-rw-r--r--toolbox/hd.c95
-rw-r--r--toolbox/id.c51
-rw-r--r--toolbox/ifconfig.c139
-rw-r--r--toolbox/iftop.c278
-rw-r--r--toolbox/insmod.c81
-rw-r--r--toolbox/ioctl.c125
-rw-r--r--toolbox/kill.c35
-rw-r--r--toolbox/ln.c34
-rw-r--r--toolbox/log.c145
-rw-r--r--toolbox/ls.c285
-rw-r--r--toolbox/lsmod.c10
-rw-r--r--toolbox/mkdir.c29
-rw-r--r--toolbox/mkdosfs.c849
-rw-r--r--toolbox/mount.c273
-rw-r--r--toolbox/mv.c59
-rw-r--r--toolbox/netstat.c120
-rw-r--r--toolbox/notify.c144
-rw-r--r--toolbox/powerd.c441
-rw-r--r--toolbox/printenv.c29
-rw-r--r--toolbox/ps.c214
-rw-r--r--toolbox/r.c74
-rw-r--r--toolbox/readtty.c183
-rw-r--r--toolbox/reboot.c56
-rw-r--r--toolbox/renice.c144
-rw-r--r--toolbox/rm.c92
-rw-r--r--toolbox/rmdir.c29
-rw-r--r--toolbox/rmmod.c42
-rw-r--r--toolbox/rotatefb.c71
-rw-r--r--toolbox/route.c97
-rw-r--r--toolbox/schedtop.c335
-rw-r--r--toolbox/sendevent.c80
-rw-r--r--toolbox/setconsole.c164
-rw-r--r--toolbox/setkey.c89
-rw-r--r--toolbox/setprop.c18
-rw-r--r--toolbox/sleep.c64
-rw-r--r--toolbox/smd.c40
-rw-r--r--toolbox/start.c20
-rw-r--r--toolbox/stop.c20
-rw-r--r--toolbox/sync.c7
-rw-r--r--toolbox/syren.c154
-rw-r--r--toolbox/toolbox.c57
-rw-r--r--toolbox/top.c516
-rw-r--r--toolbox/umount.c74
-rw-r--r--toolbox/vmstat.c247
-rw-r--r--toolbox/watchprops.c76
-rw-r--r--toolbox/wipe.c176
419 files changed, 98588 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 000000000..44ea560be
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,28 @@
1#
2# Copyright (C) 2008 The Android Open Source Project
3#
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
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
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.
15#
16LOCAL_PATH := $(my-dir)
17
18ifneq ($(TARGET_SIMULATOR),true)
19 include $(call first-makefiles-under,$(LOCAL_PATH))
20else
21 include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
22 libcutils \
23 liblog \
24 libnetutils \
25 libpixelflinger \
26 libzipfile \
27 ))
28endif
diff --git a/README b/README
new file mode 100644
index 000000000..0083247ac
--- /dev/null
+++ b/README
@@ -0,0 +1,20 @@
1
2The system/ directory is intended for pieces of the world that are the
3core of the embedded linux platform at the heart of Android. These
4essential bits are required for basic booting, operation, and debugging.
5
6They should not depend on libraries outside of system/... (some of them
7do currently -- they need to be updated or changed) and they should not
8be required for the simulator build.
9
10The license for all these pieces should be clean (Apache2, BSD, or MIT).
11
12Currently system/bluetooth/... and system/extra/... have some pieces
13with GPL/LGPL licensed code.
14
15Assorted Issues:
16
17- pppd depends on libutils for logging
18- pppd depends on libcrypt/libcrypto
19- init, linker, debuggerd, toolbox, usbd depend on libcutils
20- should probably rename bionic to libc
diff --git a/adb/Android.mk b/adb/Android.mk
new file mode 100644
index 000000000..8ac5eb437
--- /dev/null
+++ b/adb/Android.mk
@@ -0,0 +1,116 @@
1# Copyright 2005 The Android Open Source Project
2#
3# Android.mk for adb
4#
5
6LOCAL_PATH:= $(call my-dir)
7
8# adb host tool
9# =========================================================
10include $(CLEAR_VARS)
11
12# Default to a virtual (sockets) usb interface
13USB_SRCS :=
14EXTRA_SRCS :=
15
16ifeq ($(HOST_OS),linux)
17 USB_SRCS := usb_linux.c
18 EXTRA_SRCS := get_my_path_linux.c
19 LOCAL_LDLIBS += -lrt -lncurses -lpthread
20endif
21
22ifeq ($(HOST_OS),darwin)
23 USB_SRCS := usb_osx.c
24 EXTRA_SRCS := get_my_path_darwin.c
25 LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
26endif
27
28ifeq ($(HOST_OS),windows)
29 USB_SRCS := usb_windows.c
30 EXTRA_SRCS := get_my_path_windows.c
31 EXTRA_STATIC_LIBS := AdbWinApi
32 LOCAL_C_INCLUDES += /usr/include/w32api/ddk $(LOCAL_PATH)/../windows/usb/api
33 ifneq ($(strip $(USE_CYGWIN)),)
34 LOCAL_LDLIBS += -lpthread
35 else
36 LOCAL_LDLIBS += -lws2_32
37 USE_SYSDEPS_WIN32 := 1
38 endif
39endif
40
41LOCAL_SRC_FILES := \
42 adb.c \
43 console.c \
44 transport.c \
45 transport_local.c \
46 transport_usb.c \
47 commandline.c \
48 adb_client.c \
49 sockets.c \
50 services.c \
51 file_sync_client.c \
52 $(EXTRA_SRCS) \
53 $(USB_SRCS) \
54 shlist.c
55
56
57ifneq ($(USE_SYSDEPS_WIN32),)
58 LOCAL_SRC_FILES += sysdeps_win32.c
59endif
60
61LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter
62LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY
63LOCAL_MODULE := adb
64
65LOCAL_STATIC_LIBRARIES := libzipfile libunz $(EXTRA_STATIC_LIBS)
66ifeq ($(USE_SYSDEPS_WIN32),)
67 LOCAL_STATIC_LIBRARIES += libcutils
68endif
69
70include $(BUILD_HOST_EXECUTABLE)
71
72ifeq ($(HOST_OS),windows)
73$(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll
74endif
75
76ifeq ($(HOST_OS),linux)
77include $(CLEAR_VARS)
78LOCAL_SRC_FILES := \
79 kdbg.c
80LOCAL_MODULE := kdbg
81include $(BUILD_HOST_EXECUTABLE)
82endif
83
84
85# adbd device daemon
86# =========================================================
87ifeq ($(TARGET_ARCH),arm)
88include $(CLEAR_VARS)
89
90LOCAL_SRC_FILES := \
91 adb.c \
92 transport.c \
93 transport_local.c \
94 transport_usb.c \
95 sockets.c \
96 services.c \
97 file_sync_service.c \
98 jdwp_service.c \
99 framebuffer_service.c \
100 remount_service.c \
101 usb_linux_client.c \
102 log_service.c
103
104
105LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -DANDROID_GADGET=1 -Wall -Wno-unused-parameter
106LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
107LOCAL_MODULE := adbd
108
109LOCAL_FORCE_STATIC_EXECUTABLE := true
110LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
111LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
112
113LOCAL_STATIC_LIBRARIES := libcutils libc
114
115include $(BUILD_EXECUTABLE)
116endif
diff --git a/adb/adb.c b/adb/adb.c
new file mode 100644
index 000000000..a50ef334b
--- /dev/null
+++ b/adb/adb.c
@@ -0,0 +1,1093 @@
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#define TRACE_TAG TRACE_ADB
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <ctype.h>
22#include <stdarg.h>
23#include <errno.h>
24#include <string.h>
25#include <time.h>
26
27#include "sysdeps.h"
28#include "adb.h"
29
30#if !ADB_HOST
31#include <private/android_filesystem_config.h>
32#endif
33
34
35int HOST = 0;
36
37static const char *adb_device_banner = "device";
38
39void fatal(const char *fmt, ...)
40{
41 va_list ap;
42 va_start(ap, fmt);
43 fprintf(stderr, "error: ");
44 vfprintf(stderr, fmt, ap);
45 fprintf(stderr, "\n");
46 va_end(ap);
47 exit(-1);
48}
49
50void fatal_errno(const char *fmt, ...)
51{
52 va_list ap;
53 va_start(ap, fmt);
54 fprintf(stderr, "error: %s: ", strerror(errno));
55 vfprintf(stderr, fmt, ap);
56 fprintf(stderr, "\n");
57 va_end(ap);
58 exit(-1);
59}
60
61int adb_trace_mask;
62
63/* read a comma/space/colum/semi-column separated list of tags
64 * from the ADB_TRACE environment variable and build the trace
65 * mask from it. note that '1' and 'all' are special cases to
66 * enable all tracing
67 */
68void adb_trace_init(void)
69{
70 const char* p = getenv("ADB_TRACE");
71 const char* q;
72
73 static const struct {
74 const char* tag;
75 int flag;
76 } tags[] = {
77 { "1", 0 },
78 { "all", 0 },
79 { "adb", TRACE_ADB },
80 { "sockets", TRACE_SOCKETS },
81 { "packets", TRACE_PACKETS },
82 { "rwx", TRACE_RWX },
83 { "usb", TRACE_USB },
84 { "sync", TRACE_SYNC },
85 { "sysdeps", TRACE_SYSDEPS },
86 { "transport", TRACE_TRANSPORT },
87 { "jdwp", TRACE_JDWP },
88 { NULL, 0 }
89 };
90
91 if (p == NULL)
92 return;
93
94 /* use a comma/column/semi-colum/space separated list */
95 while (*p) {
96 int len, tagn;
97
98 q = strpbrk(p, " ,:;");
99 if (q == NULL) {
100 q = p + strlen(p);
101 }
102 len = q - p;
103
104 for (tagn = 0; tags[tagn].tag != NULL; tagn++)
105 {
106 int taglen = strlen(tags[tagn].tag);
107
108 if (len == taglen && !memcmp(tags[tagn].tag, p, len) )
109 {
110 int flag = tags[tagn].flag;
111 if (flag == 0) {
112 adb_trace_mask = ~0;
113 return;
114 }
115 adb_trace_mask |= (1 << flag);
116 break;
117 }
118 }
119 p = q;
120 if (*p)
121 p++;
122 }
123}
124
125
126apacket *get_apacket(void)
127{
128 apacket *p = malloc(sizeof(apacket));
129 if(p == 0) fatal("failed to allocate an apacket");
130 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
131 return p;
132}
133
134void put_apacket(apacket *p)
135{
136 free(p);
137}
138
139void handle_online(void)
140{
141 D("adb: online\n");
142#if !ADB_HOST
143 property_set("adb.connected","1");
144#endif
145}
146
147void handle_offline(atransport *t)
148{
149 D("adb: offline\n");
150 //Close the associated usb
151 run_transport_disconnects(t);
152#if !ADB_HOST
153 property_set("adb.connected","");
154#endif
155}
156
157#if TRACE_PACKETS
158#define DUMPMAX 32
159void print_packet(const char *label, apacket *p)
160{
161 char *tag;
162 char *x;
163 unsigned count;
164
165 switch(p->msg.command){
166 case A_SYNC: tag = "SYNC"; break;
167 case A_CNXN: tag = "CNXN" ; break;
168 case A_OPEN: tag = "OPEN"; break;
169 case A_OKAY: tag = "OKAY"; break;
170 case A_CLSE: tag = "CLSE"; break;
171 case A_WRTE: tag = "WRTE"; break;
172 default: tag = "????"; break;
173 }
174
175 fprintf(stderr, "%s: %s %08x %08x %04x \"",
176 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
177 count = p->msg.data_length;
178 x = (char*) p->data;
179 if(count > DUMPMAX) {
180 count = DUMPMAX;
181 tag = "\n";
182 } else {
183 tag = "\"\n";
184 }
185 while(count-- > 0){
186 if((*x >= ' ') && (*x < 127)) {
187 fputc(*x, stderr);
188 } else {
189 fputc('.', stderr);
190 }
191 x++;
192 }
193 fprintf(stderr, tag);
194}
195#endif
196
197static void send_ready(unsigned local, unsigned remote, atransport *t)
198{
199 D("Calling send_ready \n");
200 apacket *p = get_apacket();
201 p->msg.command = A_OKAY;
202 p->msg.arg0 = local;
203 p->msg.arg1 = remote;
204 send_packet(p, t);
205}
206
207static void send_close(unsigned local, unsigned remote, atransport *t)
208{
209 D("Calling send_close \n");
210 apacket *p = get_apacket();
211 p->msg.command = A_CLSE;
212 p->msg.arg0 = local;
213 p->msg.arg1 = remote;
214 send_packet(p, t);
215}
216
217static void send_connect(atransport *t)
218{
219 D("Calling send_connect \n");
220 apacket *cp = get_apacket();
221 cp->msg.command = A_CNXN;
222 cp->msg.arg0 = A_VERSION;
223 cp->msg.arg1 = MAX_PAYLOAD;
224 snprintf((char*) cp->data, sizeof cp->data, "%s::",
225 HOST ? "host" : adb_device_banner);
226 cp->msg.data_length = strlen((char*) cp->data) + 1;
227 send_packet(cp, t);
228#if ADB_HOST
229 /* XXX why sleep here? */
230 // allow the device some time to respond to the connect message
231 adb_sleep_ms(1000);
232#endif
233}
234
235static char *connection_state_name(atransport *t)
236{
237 if (t == NULL) {
238 return "unknown";
239 }
240
241 switch(t->connection_state) {
242 case CS_BOOTLOADER:
243 return "bootloader";
244 case CS_DEVICE:
245 return "device";
246 case CS_OFFLINE:
247 return "offline";
248 default:
249 return "unknown";
250 }
251}
252
253void parse_banner(char *banner, atransport *t)
254{
255 char *type, *product, *end;
256
257 D("parse_banner: %s\n", banner);
258 type = banner;
259 product = strchr(type, ':');
260 if(product) {
261 *product++ = 0;
262 } else {
263 product = "";
264 }
265
266 /* remove trailing ':' */
267 end = strchr(product, ':');
268 if(end) *end = 0;
269
270 /* save product name in device structure */
271 if (t->product == NULL) {
272 t->product = strdup(product);
273 } else if (strcmp(product, t->product) != 0) {
274 free(t->product);
275 t->product = strdup(product);
276 }
277
278 if(!strcmp(type, "bootloader")){
279 D("setting connection_state to CS_BOOTLOADER\n");
280 t->connection_state = CS_BOOTLOADER;
281 update_transports();
282 return;
283 }
284
285 if(!strcmp(type, "device")) {
286 D("setting connection_state to CS_DEVICE\n");
287 t->connection_state = CS_DEVICE;
288 update_transports();
289 return;
290 }
291
292 if(!strcmp(type, "recovery")) {
293 D("setting connection_state to CS_RECOVERY\n");
294 t->connection_state = CS_RECOVERY;
295 update_transports();
296 return;
297 }
298
299 t->connection_state = CS_HOST;
300}
301
302void handle_packet(apacket *p, atransport *t)
303{
304 asocket *s;
305
306 D("handle_packet() %d\n", p->msg.command);
307
308 print_packet("recv", p);
309
310 switch(p->msg.command){
311 case A_SYNC:
312 if(p->msg.arg0){
313 send_packet(p, t);
314 if(HOST) send_connect(t);
315 } else {
316 t->connection_state = CS_OFFLINE;
317 handle_offline(t);
318 send_packet(p, t);
319 }
320 return;
321
322 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
323 /* XXX verify version, etc */
324 if(t->connection_state != CS_OFFLINE) {
325 t->connection_state = CS_OFFLINE;
326 handle_offline(t);
327 }
328 parse_banner((char*) p->data, t);
329 handle_online();
330 if(!HOST) send_connect(t);
331 break;
332
333 case A_OPEN: /* OPEN(local-id, 0, "destination") */
334 if(t->connection_state != CS_OFFLINE) {
335 char *name = (char*) p->data;
336 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
337 s = create_local_service_socket(name);
338 if(s == 0) {
339 send_close(0, p->msg.arg0, t);
340 } else {
341 s->peer = create_remote_socket(p->msg.arg0, t);
342 s->peer->peer = s;
343 send_ready(s->id, s->peer->id, t);
344 s->ready(s);
345 }
346 }
347 break;
348
349 case A_OKAY: /* READY(local-id, remote-id, "") */
350 if(t->connection_state != CS_OFFLINE) {
351 if((s = find_local_socket(p->msg.arg1))) {
352 if(s->peer == 0) {
353 s->peer = create_remote_socket(p->msg.arg0, t);
354 s->peer->peer = s;
355 }
356 s->ready(s);
357 }
358 }
359 break;
360
361 case A_CLSE: /* CLOSE(local-id, remote-id, "") */
362 if(t->connection_state != CS_OFFLINE) {
363 if((s = find_local_socket(p->msg.arg1))) {
364 s->close(s);
365 }
366 }
367 break;
368
369 case A_WRTE:
370 if(t->connection_state != CS_OFFLINE) {
371 if((s = find_local_socket(p->msg.arg1))) {
372 unsigned rid = p->msg.arg0;
373 p->len = p->msg.data_length;
374
375 if(s->enqueue(s, p) == 0) {
376 D("Enqueue the socket\n");
377 send_ready(s->id, rid, t);
378 }
379 return;
380 }
381 }
382 break;
383
384 default:
385 printf("handle_packet: what is %08x?!\n", p->msg.command);
386 }
387
388 put_apacket(p);
389}
390
391alistener listener_list = {
392 .next = &listener_list,
393 .prev = &listener_list,
394};
395
396static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
397{
398 asocket *s;
399
400 if(ev & FDE_READ) {
401 struct sockaddr addr;
402 socklen_t alen;
403 int fd;
404
405 alen = sizeof(addr);
406 fd = adb_socket_accept(_fd, &addr, &alen);
407 if(fd < 0) return;
408
409 adb_socket_setbufsize(fd, CHUNK_SIZE);
410
411 s = create_local_socket(fd);
412 if(s) {
413 connect_to_smartsocket(s);
414 return;
415 }
416
417 adb_close(fd);
418 }
419}
420
421static void listener_event_func(int _fd, unsigned ev, void *_l)
422{
423 alistener *l = _l;
424 asocket *s;
425
426 if(ev & FDE_READ) {
427 struct sockaddr addr;
428 socklen_t alen;
429 int fd;
430
431 alen = sizeof(addr);
432 fd = adb_socket_accept(_fd, &addr, &alen);
433 if(fd < 0) return;
434
435 s = create_local_socket(fd);
436 if(s) {
437 s->transport = l->transport;
438 connect_to_remote(s, l->connect_to);
439 return;
440 }
441
442 adb_close(fd);
443 }
444}
445
446static void free_listener(alistener* l)
447{
448 if (l->next) {
449 l->next->prev = l->prev;
450 l->prev->next = l->next;
451 l->next = l->prev = l;
452 }
453
454 // closes the corresponding fd
455 fdevent_remove(&l->fde);
456
457 if (l->local_name)
458 free((char*)l->local_name);
459
460 if (l->connect_to)
461 free((char*)l->connect_to);
462
463 if (l->transport) {
464 remove_transport_disconnect(l->transport, &l->disconnect);
465 }
466 free(l);
467}
468
469static void listener_disconnect(void* _l, atransport* t)
470{
471 alistener* l = _l;
472
473 free_listener(l);
474}
475
476int local_name_to_fd(const char *name)
477{
478 int port;
479
480 if(!strncmp("tcp:", name, 4)){
481 int ret;
482 port = atoi(name + 4);
483 ret = socket_loopback_server(port, SOCK_STREAM);
484 return ret;
485 }
486#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */
487 // It's non-sensical to support the "reserved" space on the adb host side
488 if(!strncmp(name, "local:", 6)) {
489 return socket_local_server(name + 6,
490 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
491 } else if(!strncmp(name, "localabstract:", 14)) {
492 return socket_local_server(name + 14,
493 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
494 } else if(!strncmp(name, "localfilesystem:", 16)) {
495 return socket_local_server(name + 16,
496 ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
497 }
498
499#endif
500 printf("unknown local portname '%s'\n", name);
501 return -1;
502}
503
504static int remove_listener(const char *local_name, const char *connect_to, atransport* transport)
505{
506 alistener *l;
507
508 for (l = listener_list.next; l != &listener_list; l = l->next) {
509 if (!strcmp(local_name, l->local_name) &&
510 !strcmp(connect_to, l->connect_to) &&
511 l->transport && l->transport == transport) {
512
513 listener_disconnect(l, transport);
514 return 0;
515 }
516 }
517
518 return -1;
519}
520
521static int install_listener(const char *local_name, const char *connect_to, atransport* transport)
522{
523 alistener *l;
524
525 //printf("install_listener('%s','%s')\n", local_name, connect_to);
526
527 for(l = listener_list.next; l != &listener_list; l = l->next){
528 if(strcmp(local_name, l->local_name) == 0) {
529 char *cto;
530
531 /* can't repurpose a smartsocket */
532 if(l->connect_to[0] == '*') {
533 return -1;
534 }
535
536 cto = strdup(connect_to);
537 if(cto == 0) {
538 return -1;
539 }
540
541 //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
542 free((void*) l->connect_to);
543 l->connect_to = cto;
544 if (l->transport != transport) {
545 remove_transport_disconnect(l->transport, &l->disconnect);
546 l->transport = transport;
547 add_transport_disconnect(l->transport, &l->disconnect);
548 }
549 return 0;
550 }
551 }
552
553 if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
554 if((l->local_name = strdup(local_name)) == 0) goto nomem;
555 if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
556
557
558 l->fd = local_name_to_fd(local_name);
559 if(l->fd < 0) {
560 free((void*) l->local_name);
561 free((void*) l->connect_to);
562 free(l);
563 printf("cannot bind '%s'\n", local_name);
564 return -2;
565 }
566
567 close_on_exec(l->fd);
568 if(!strcmp(l->connect_to, "*smartsocket*")) {
569 fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
570 } else {
571 fdevent_install(&l->fde, l->fd, listener_event_func, l);
572 }
573 fdevent_set(&l->fde, FDE_READ);
574
575 l->next = &listener_list;
576 l->prev = listener_list.prev;
577 l->next->prev = l;
578 l->prev->next = l;
579 l->transport = transport;
580
581 if (transport) {
582 l->disconnect.opaque = l;
583 l->disconnect.func = listener_disconnect;
584 add_transport_disconnect(transport, &l->disconnect);
585 }
586 return 0;
587
588nomem:
589 fatal("cannot allocate listener");
590 return 0;
591}
592
593#ifdef HAVE_FORKEXEC
594static void sigchld_handler(int n)
595{
596 int status;
597 while(waitpid(-1, &status, WNOHANG) > 0) ;
598}
599#endif
600
601#ifdef HAVE_WIN32_PROC
602static BOOL WINAPI ctrlc_handler(DWORD type)
603{
604 exit(STATUS_CONTROL_C_EXIT);
605 return TRUE;
606}
607#endif
608
609static void adb_cleanup(void)
610{
611 usb_cleanup();
612}
613
614void start_logging(void)
615{
616#ifdef HAVE_WIN32_PROC
617 char temp[ MAX_PATH ];
618 FILE* fnul;
619 FILE* flog;
620
621 GetTempPath( sizeof(temp) - 8, temp );
622 strcat( temp, "adb.log" );
623
624 /* Win32 specific redirections */
625 fnul = fopen( "NUL", "rt" );
626 if (fnul != NULL)
627 stdin[0] = fnul[0];
628
629 flog = fopen( temp, "at" );
630 if (flog == NULL)
631 flog = fnul;
632
633 setvbuf( flog, NULL, _IONBF, 0 );
634
635 stdout[0] = flog[0];
636 stderr[0] = flog[0];
637 fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
638#else
639 int fd;
640
641 fd = unix_open("/dev/null", O_RDONLY);
642 dup2(fd, 0);
643
644 fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);
645 if(fd < 0) {
646 fd = unix_open("/dev/null", O_WRONLY);
647 }
648 dup2(fd, 1);
649 dup2(fd, 2);
650 fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
651#endif
652}
653
654#if !ADB_HOST
655void start_device_log(void)
656{
657 int fd;
658 char path[100];
659
660 snprintf(path, sizeof path, "/data/adb_%ld.txt", (long)time(NULL));
661 fd = unix_open(path, O_WRONLY | O_CREAT | O_APPEND, 0640);
662 if (fd < 0)
663 return;
664
665 // redirect stdout and stderr to the log file
666 dup2(fd, 1);
667 dup2(fd, 2);
668 fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
669
670 fd = unix_open("/dev/null", O_RDONLY);
671 dup2(fd, 0);
672
673 // log everything
674 adb_trace_mask = ~0;
675 // except TRACE_RWX is a bit too verbose
676 adb_trace_mask &= ~TRACE_RWX;
677}
678#endif
679
680#if ADB_HOST
681int launch_server()
682{
683#ifdef HAVE_WIN32_PROC
684 /* we need to start the server in the background */
685 /* we create a PIPE that will be used to wait for the server's "OK" */
686 /* message since the pipe handles must be inheritable, we use a */
687 /* security attribute */
688 HANDLE pipe_read, pipe_write;
689 SECURITY_ATTRIBUTES sa;
690 STARTUPINFO startup;
691 PROCESS_INFORMATION pinfo;
692 char program_path[ MAX_PATH ];
693 int ret;
694
695 sa.nLength = sizeof(sa);
696 sa.lpSecurityDescriptor = NULL;
697 sa.bInheritHandle = TRUE;
698
699 /* create pipe, and ensure its read handle isn't inheritable */
700 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
701 if (!ret) {
702 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
703 return -1;
704 }
705
706 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
707
708 ZeroMemory( &startup, sizeof(startup) );
709 startup.cb = sizeof(startup);
710 startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
711 startup.hStdOutput = pipe_write;
712 startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
713 startup.dwFlags = STARTF_USESTDHANDLES;
714
715 ZeroMemory( &pinfo, sizeof(pinfo) );
716
717 /* get path of current program */
718 GetModuleFileName( NULL, program_path, sizeof(program_path) );
719
720 ret = CreateProcess(
721 program_path, /* program path */
722 "adb fork-server server",
723 /* the fork-server argument will set the
724 debug = 2 in the child */
725 NULL, /* process handle is not inheritable */
726 NULL, /* thread handle is not inheritable */
727 TRUE, /* yes, inherit some handles */
728 DETACHED_PROCESS, /* the new process doesn't have a console */
729 NULL, /* use parent's environment block */
730 NULL, /* use parent's starting directory */
731 &startup, /* startup info, i.e. std handles */
732 &pinfo );
733
734 CloseHandle( pipe_write );
735
736 if (!ret) {
737 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
738 CloseHandle( pipe_read );
739 return -1;
740 }
741
742 CloseHandle( pinfo.hProcess );
743 CloseHandle( pinfo.hThread );
744
745 /* wait for the "OK\n" message */
746 {
747 char temp[3];
748 DWORD count;
749
750 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
751 CloseHandle( pipe_read );
752 if ( !ret ) {
753 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
754 return -1;
755 }
756 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
757 fprintf(stderr, "ADB server didn't ACK\n" );
758 return -1;
759 }
760 }
761#elif defined(HAVE_FORKEXEC)
762 char path[PATH_MAX];
763 int fd[2];
764
765 // set up a pipe so the child can tell us when it is ready.
766 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
767 if (pipe(fd)) {
768 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
769 return -1;
770 }
771 get_my_path(path);
772 pid_t pid = fork();
773 if(pid < 0) return -1;
774
775 if (pid == 0) {
776 // child side of the fork
777
778 // redirect stderr to the pipe
779 // we use stderr instead of stdout due to stdout's buffering behavior.
780 adb_close(fd[0]);
781 dup2(fd[1], STDERR_FILENO);
782 adb_close(fd[1]);
783
784 // child process
785 int result = execl(path, "adb", "fork-server", "server", NULL);
786 // this should not return
787 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
788 } else {
789 // parent side of the fork
790
791 char temp[3];
792
793 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
794 // wait for the "OK\n" message
795 adb_close(fd[1]);
796 int ret = adb_read(fd[0], temp, 3);
797 adb_close(fd[0]);
798 if (ret < 0) {
799 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", errno);
800 return -1;
801 }
802 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
803 fprintf(stderr, "ADB server didn't ACK\n" );
804 return -1;
805 }
806
807 setsid();
808 }
809#else
810#error "cannot implement background server start on this platform"
811#endif
812 return 0;
813}
814#endif
815
816int adb_main(int is_daemon)
817{
818#if !ADB_HOST
819 int secure = 0;
820 char value[PROPERTY_VALUE_MAX];
821
822 // prevent the OOM killer from killing us
823 char text[64];
824 snprintf(text, sizeof text, "/proc/%d/oom_adj", (int)getpid());
825 int fd = adb_open(text, O_WRONLY);
826 if (fd >= 0) {
827 // -17 should make us immune to OOM
828 snprintf(text, sizeof text, "%d", -17);
829 adb_write(fd, text, strlen(text));
830 adb_close(fd);
831 } else {
832 D("adb: unable to open %s\n", text);
833 }
834#endif
835
836 atexit(adb_cleanup);
837#ifdef HAVE_WIN32_PROC
838 SetConsoleCtrlHandler( ctrlc_handler, TRUE );
839#elif defined(HAVE_FORKEXEC)
840 signal(SIGCHLD, sigchld_handler);
841 signal(SIGPIPE, SIG_IGN);
842#endif
843
844 init_transport_registration();
845
846
847#if ADB_HOST
848 HOST = 1;
849 usb_init();
850 local_init();
851
852 if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
853 exit(1);
854 }
855#else
856 /* run adbd in secure mode if ro.secure is set and
857 ** we are not in the emulator
858 */
859 property_get("ro.kernel.qemu", value, "");
860 if (strcmp(value, "1") != 0) {
861 property_get("ro.secure", value, "");
862 if (strcmp(value, "1") == 0)
863 secure = 1;
864 }
865
866 /* don't listen on port 5037 if we are running in secure mode */
867 /* don't run as root if we are running in secure mode */
868 if (secure) {
869 /* add extra groups:
870 ** AID_ADB to access the USB driver
871 ** AID_LOG to read system logs (adb logcat)
872 ** AID_INPUT to diagnose input issues (getevent)
873 ** AID_INET to diagnose network issues (netcfg, ping)
874 ** AID_GRAPHICS to access the frame buffer
875 */
876 gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS };
877 setgroups(sizeof(groups)/sizeof(groups[0]), groups);
878
879 /* then switch user and group to "shell" */
880 setgid(AID_SHELL);
881 setuid(AID_SHELL);
882
883 D("Local port 5037 disabled\n");
884 } else {
885 if(install_listener("tcp:5037", "*smartsocket*", NULL)) {
886 exit(1);
887 }
888 }
889
890 /* for the device, start the usb transport if the
891 ** android usb device exists, otherwise start the
892 ** network transport.
893 */
894 if(access("/dev/android_adb", F_OK) == 0 ||
895 access("/dev/android", F_OK) == 0) {
896 usb_init();
897 } else {
898 local_init();
899 }
900 init_jdwp();
901#endif
902
903 if (is_daemon)
904 {
905 // inform our parent that we are up and running.
906#ifdef HAVE_WIN32_PROC
907 DWORD count;
908 WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );
909#elif defined(HAVE_FORKEXEC)
910 fprintf(stderr, "OK\n");
911#endif
912 start_logging();
913 }
914
915 fdevent_loop();
916
917 usb_cleanup();
918
919 return 0;
920}
921
922int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
923{
924 atransport *transport = NULL;
925 char buf[4096];
926
927 if(!strcmp(service, "kill")) {
928 fprintf(stderr,"adb server killed by remote request\n");
929 fflush(stdout);
930 adb_write(reply_fd, "OKAY", 4);
931 usb_cleanup();
932 exit(0);
933 }
934
935#if ADB_HOST
936 // "transport:" is used for switching transport with a specified serial number
937 // "transport-usb:" is used for switching transport to the only USB transport
938 // "transport-local:" is used for switching transport to the only local transport
939 // "transport-any:" is used for switching transport to the only transport
940 if (!strncmp(service, "transport", strlen("transport"))) {
941 char* error_string = "unknown failure";
942 transport_type type = kTransportAny;
943
944 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
945 type = kTransportUsb;
946 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
947 type = kTransportLocal;
948 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
949 type = kTransportAny;
950 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
951 service += strlen("transport:");
952 serial = strdup(service);
953 }
954
955 transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
956
957 if (transport) {
958 s->transport = transport;
959 adb_write(reply_fd, "OKAY", 4);
960 } else {
961 sendfailmsg(reply_fd, error_string);
962 }
963 return 1;
964 }
965
966 // return a list of all connected devices
967 if (!strcmp(service, "devices")) {
968 char buffer[4096];
969 memset(buf, 0, sizeof(buf));
970 memset(buffer, 0, sizeof(buffer));
971 D("Getting device list \n");
972 list_transports(buffer, sizeof(buffer));
973 snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
974 D("Wrote device list \n");
975 writex(reply_fd, buf, strlen(buf));
976 return 0;
977 }
978
979 // returns our value for ADB_SERVER_VERSION
980 if (!strcmp(service, "version")) {
981 char version[12];
982 snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
983 snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version);
984 writex(reply_fd, buf, strlen(buf));
985 return 0;
986 }
987
988 if(!strncmp(service,"get-product",strlen("get-product"))) {
989 char *out = "unknown";
990 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
991 if (transport && transport->product) {
992 out = transport->product;
993 }
994 snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
995 writex(reply_fd, buf, strlen(buf));
996 return 0;
997 }
998 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
999 char *out = "unknown";
1000 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
1001 if (transport && transport->serial) {
1002 out = transport->serial;
1003 }
1004 snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
1005 writex(reply_fd, buf, strlen(buf));
1006 return 0;
1007 }
1008 // indicates a new emulator instance has started
1009 if (!strncmp(service,"emulator:",9)) {
1010 int port = atoi(service+9);
1011 local_connect(port);
1012 /* we don't even need to send a reply */
1013 return 0;
1014 }
1015#endif // ADB_HOST
1016
1017 if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {
1018 char *local, *remote, *err;
1019 int r;
1020 atransport *transport;
1021
1022 int createForward = strncmp(service,"kill",4);
1023
1024 local = service + (createForward ? 8 : 12);
1025 remote = strchr(local,';');
1026 if(remote == 0) {
1027 sendfailmsg(reply_fd, "malformed forward spec");
1028 return 0;
1029 }
1030
1031 *remote++ = 0;
1032 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
1033 sendfailmsg(reply_fd, "malformed forward spec");
1034 return 0;
1035 }
1036
1037 transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
1038 if (!transport) {
1039 sendfailmsg(reply_fd, err);
1040 return 0;
1041 }
1042
1043 if (createForward) {
1044 r = install_listener(local, remote, transport);
1045 } else {
1046 r = remove_listener(local, remote, transport);
1047 }
1048 if(r == 0) {
1049 /* 1st OKAY is connect, 2nd OKAY is status */
1050 writex(reply_fd, "OKAYOKAY", 8);
1051 return 0;
1052 }
1053
1054 if (createForward) {
1055 sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");
1056 } else {
1057 sendfailmsg(reply_fd, "cannot remove listener");
1058 }
1059 return 0;
1060 }
1061
1062 if(!strncmp(service,"get-state",strlen("get-state"))) {
1063 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
1064 char *state = connection_state_name(transport);
1065 snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);
1066 writex(reply_fd, buf, strlen(buf));
1067 return 0;
1068 }
1069 return -1;
1070}
1071
1072#if !ADB_HOST
1073int recovery_mode = 0;
1074#endif
1075
1076int main(int argc, char **argv)
1077{
1078 adb_trace_init();
1079#if ADB_HOST
1080 adb_sysdeps_init();
1081 return adb_commandline(argc - 1, argv + 1);
1082#else
1083 if((argc > 1) && (!strcmp(argv[1],"recovery"))) {
1084 adb_device_banner = "recovery";
1085 recovery_mode = 1;
1086 }
1087#if ADB_DEVICE_LOG
1088 start_device_log();
1089#endif
1090 return adb_main(0);
1091#endif
1092}
1093
diff --git a/adb/adb.h b/adb/adb.h
new file mode 100644
index 000000000..5a74b7b9a
--- /dev/null
+++ b/adb/adb.h
@@ -0,0 +1,402 @@
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#ifndef __ADB_H
18#define __ADB_H
19
20#include <limits.h>
21
22#define MAX_PAYLOAD 4096
23
24#define A_SYNC 0x434e5953
25#define A_CNXN 0x4e584e43
26#define A_OPEN 0x4e45504f
27#define A_OKAY 0x59414b4f
28#define A_CLSE 0x45534c43
29#define A_WRTE 0x45545257
30
31#define A_VERSION 0x01000000 // ADB protocol version
32
33#define ADB_VERSION_MAJOR 1 // Used for help/version information
34#define ADB_VERSION_MINOR 0 // Used for help/version information
35
36#define ADB_SERVER_VERSION 20 // Increment this when we want to force users to start a new adb server
37
38typedef struct amessage amessage;
39typedef struct apacket apacket;
40typedef struct asocket asocket;
41typedef struct alistener alistener;
42typedef struct aservice aservice;
43typedef struct atransport atransport;
44typedef struct adisconnect adisconnect;
45typedef struct usb_handle usb_handle;
46
47struct amessage {
48 unsigned command; /* command identifier constant */
49 unsigned arg0; /* first argument */
50 unsigned arg1; /* second argument */
51 unsigned data_length; /* length of payload (0 is allowed) */
52 unsigned data_check; /* checksum of data payload */
53 unsigned magic; /* command ^ 0xffffffff */
54};
55
56struct apacket
57{
58 apacket *next;
59
60 unsigned len;
61 unsigned char *ptr;
62
63 amessage msg;
64 unsigned char data[MAX_PAYLOAD];
65};
66
67/* An asocket represents one half of a connection between a local and
68** remote entity. A local asocket is bound to a file descriptor. A
69** remote asocket is bound to the protocol engine.
70*/
71struct asocket {
72 /* chain pointers for the local/remote list of
73 ** asockets that this asocket lives in
74 */
75 asocket *next;
76 asocket *prev;
77
78 /* the unique identifier for this asocket
79 */
80 unsigned id;
81
82 /* the asocket we are connected to
83 */
84
85 asocket *peer;
86
87 /* For local asockets, the fde is used to bind
88 ** us to our fd event system. For remote asockets
89 ** these fields are not used.
90 */
91 fdevent fde;
92 int fd;
93
94 /* queue of apackets waiting to be written
95 */
96 apacket *pkt_first;
97 apacket *pkt_last;
98
99 /* enqueue is called by our peer when it has data
100 ** for us. It should return 0 if we can accept more
101 ** data or 1 if not. If we return 1, we must call
102 ** peer->ready() when we once again are ready to
103 ** receive data.
104 */
105 int (*enqueue)(asocket *s, apacket *pkt);
106
107 /* ready is called by the peer when it is ready for
108 ** us to send data via enqueue again
109 */
110 void (*ready)(asocket *s);
111
112 /* close is called by the peer when it has gone away.
113 ** we are not allowed to make any further calls on the
114 ** peer once our close method is called.
115 */
116 void (*close)(asocket *s);
117
118 /* socket-type-specific extradata */
119 void *extra;
120
121 /* A socket is bound to atransport */
122 atransport *transport;
123};
124
125
126/* the adisconnect structure is used to record a callback that
127** will be called whenever a transport is disconnected (e.g. by the user)
128** this should be used to cleanup objects that depend on the
129** transport (e.g. remote sockets, listeners, etc...)
130*/
131struct adisconnect
132{
133 void (*func)(void* opaque, atransport* t);
134 void* opaque;
135 adisconnect* next;
136 adisconnect* prev;
137};
138
139
140/* a transport object models the connection to a remote device or emulator
141** there is one transport per connected device/emulator. a "local transport"
142** connects through TCP (for the emulator), while a "usb transport" through
143** USB (for real devices)
144**
145** note that kTransportHost doesn't really correspond to a real transport
146** object, it's a special value used to indicate that a client wants to
147** connect to a service implemented within the ADB server itself.
148*/
149typedef enum transport_type {
150 kTransportUsb,
151 kTransportLocal,
152 kTransportAny,
153 kTransportHost,
154} transport_type;
155
156struct atransport
157{
158 atransport *next;
159 atransport *prev;
160
161 int (*read_from_remote)(apacket *p, atransport *t);
162 int (*write_to_remote)(apacket *p, atransport *t);
163 void (*close)(atransport *t);
164 void (*kick)(atransport *t);
165
166 int fd;
167 int transport_socket;
168 fdevent transport_fde;
169 int ref_count;
170 unsigned sync_token;
171 int connection_state;
172 transport_type type;
173
174 /* usb handle or socket fd as needed */
175 usb_handle *usb;
176 int sfd;
177
178 /* used to identify transports for clients */
179 char *serial;
180 char *product;
181
182 /* a list of adisconnect callbacks called when the transport is kicked */
183 int kicked;
184 adisconnect disconnects;
185};
186
187
188/* A listener is an entity which binds to a local port
189** and, upon receiving a connection on that port, creates
190** an asocket to connect the new local connection to a
191** specific remote service.
192**
193** TODO: some listeners read from the new connection to
194** determine what exact service to connect to on the far
195** side.
196*/
197struct alistener
198{
199 alistener *next;
200 alistener *prev;
201
202 fdevent fde;
203 int fd;
204
205 const char *local_name;
206 const char *connect_to;
207 atransport *transport;
208 adisconnect disconnect;
209};
210
211
212void print_packet(const char *label, apacket *p);
213
214asocket *find_local_socket(unsigned id);
215void install_local_socket(asocket *s);
216void remove_socket(asocket *s);
217void close_all_sockets(atransport *t);
218
219#define LOCAL_CLIENT_PREFIX "emulator-"
220
221asocket *create_local_socket(int fd);
222asocket *create_local_service_socket(const char *destination);
223
224asocket *create_remote_socket(unsigned id, atransport *t);
225void connect_to_remote(asocket *s, const char *destination);
226void connect_to_smartsocket(asocket *s);
227
228void fatal(const char *fmt, ...);
229void fatal_errno(const char *fmt, ...);
230
231void handle_packet(apacket *p, atransport *t);
232void send_packet(apacket *p, atransport *t);
233
234void get_my_path(char s[PATH_MAX]);
235int launch_server();
236int adb_main(int is_daemon);
237
238
239/* transports are ref-counted
240** get_device_transport does an acquire on your behalf before returning
241*/
242void init_transport_registration(void);
243int list_transports(char *buf, size_t bufsize);
244void update_transports(void);
245
246asocket* create_device_tracker(void);
247
248/* Obtain a transport from the available transports.
249** If state is != CS_ANY, only transports in that state are considered.
250** If serial is non-NULL then only the device with that serial will be chosen.
251** If no suitable transport is found, error is set.
252*/
253atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char **error_out);
254void add_transport_disconnect( atransport* t, adisconnect* dis );
255void remove_transport_disconnect( atransport* t, adisconnect* dis );
256void run_transport_disconnects( atransport* t );
257void kick_transport( atransport* t );
258
259/* initialize a transport object's func pointers and state */
260int init_socket_transport(atransport *t, int s, int port);
261void init_usb_transport(atransport *t, usb_handle *usb);
262
263/* for MacOS X cleanup */
264void close_usb_devices();
265
266/* cause new transports to be init'd and added to the list */
267void register_socket_transport(int s, const char *serial, int port);
268void register_usb_transport(usb_handle *h, const char *serial);
269
270int service_to_fd(const char *name);
271#if ADB_HOST
272asocket *host_service_to_socket(const char* name, const char *serial);
273#endif
274
275#if !ADB_HOST
276int init_jdwp(void);
277asocket* create_jdwp_service_socket();
278asocket* create_jdwp_tracker_service_socket();
279int create_jdwp_connection_fd(int jdwp_pid);
280#endif
281
282#if !ADB_HOST
283void framebuffer_service(int fd, void *cookie);
284void log_service(int fd, void *cookie);
285void remount_service(int fd, void *cookie);
286char * get_log_file_path(const char * log_name);
287#endif
288
289/* packet allocator */
290apacket *get_apacket(void);
291void put_apacket(apacket *p);
292
293int check_header(apacket *p);
294int check_data(apacket *p);
295
296/* convenience wrappers around read/write that will retry on
297** EINTR and/or short read/write. Returns 0 on success, -1
298** on error or EOF.
299*/
300int readx(int fd, void *ptr, size_t len);
301int writex(int fd, const void *ptr, size_t len);
302
303/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */
304
305#define ADB_TRACE 1
306
307/* IMPORTANT: if you change the following list, don't
308 * forget to update the corresponding 'tags' table in
309 * the adb_trace_init() function implemented in adb.c
310 */
311typedef enum {
312 TRACE_ADB = 0,
313 TRACE_SOCKETS,
314 TRACE_PACKETS,
315 TRACE_TRANSPORT,
316 TRACE_RWX,
317 TRACE_USB,
318 TRACE_SYNC,
319 TRACE_SYSDEPS,
320 TRACE_JDWP,
321} AdbTrace;
322
323#if ADB_TRACE
324
325 int adb_trace_mask;
326
327 void adb_trace_init(void);
328
329# define ADB_TRACING ((adb_trace_mask & (1 << TRACE_TAG)) != 0)
330
331 /* you must define TRACE_TAG before using this macro */
332 #define D(...) \
333 do { \
334 if (ADB_TRACING) \
335 fprintf(stderr, __VA_ARGS__ ); \
336 } while (0)
337#else
338# define D(...) ((void)0)
339# define ADB_TRACING 0
340#endif
341
342
343/* set this to log to /data/adb/adb_<time>.txt on the device.
344 * has no effect if the /data/adb/ directory does not exist.
345 */
346#define ADB_DEVICE_LOG 0
347
348#if !TRACE_PACKETS
349#define print_packet(tag,p) do {} while (0)
350#endif
351
352#define ADB_PORT 5037
353#define ADB_LOCAL_TRANSPORT_PORT 5555
354
355// Google's USB Vendor ID
356#define VENDOR_ID_GOOGLE 0x18d1
357// HTC's USB Vendor ID
358#define VENDOR_ID_HTC 0x0bb4
359
360// products for VENDOR_ID_GOOGLE
361#define PRODUCT_ID_SOONER 0xd00d // Sooner bootloader
362#define PRODUCT_ID_SOONER_COMP 0xdeed // Sooner composite device
363
364// products for VENDOR_ID_HTC
365#define PRODUCT_ID_DREAM 0x0c01 // Dream bootloader
366#define PRODUCT_ID_DREAM_COMP 0x0c02 // Dream composite device
367
368void local_init();
369int local_connect(int port);
370
371/* usb host/client interface */
372void usb_init();
373void usb_cleanup();
374int usb_write(usb_handle *h, const void *data, int len);
375int usb_read(usb_handle *h, void *data, int len);
376int usb_close(usb_handle *h);
377void usb_kick(usb_handle *h);
378
379/* used for USB device detection */
380int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
381
382unsigned host_to_le32(unsigned n);
383int adb_commandline(int argc, char **argv);
384
385int connection_state(atransport *t);
386
387#define CS_ANY -1
388#define CS_OFFLINE 0
389#define CS_BOOTLOADER 1
390#define CS_DEVICE 2
391#define CS_HOST 3
392#define CS_RECOVERY 4
393#define CS_ERROR 5
394
395extern int HOST;
396
397#define CHUNK_SIZE (64*1024)
398
399int sendfailmsg(int fd, const char *reason);
400int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);
401
402#endif
diff --git a/adb/adb_client.c b/adb/adb_client.c
new file mode 100644
index 000000000..c1b87ee51
--- /dev/null
+++ b/adb/adb_client.c
@@ -0,0 +1,318 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <errno.h>
5#include <limits.h>
6#include <stdarg.h>
7#include <zipfile/zipfile.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10
11#include "sysdeps.h"
12
13#define TRACE_TAG TRACE_ADB
14#include "adb_client.h"
15
16static transport_type __adb_transport = kTransportAny;
17static const char* __adb_serial = NULL;
18
19void adb_set_transport(transport_type type, const char* serial)
20{
21 __adb_transport = type;
22 __adb_serial = serial;
23}
24
25int adb_get_emulator_console_port(void)
26{
27 const char* serial = __adb_serial;
28 int port;
29
30 if (serial == NULL) {
31 /* if no specific device was specified, we need to look at */
32 /* the list of connected devices, and extract an emulator */
33 /* name from it. two emulators is an error */
34 char* tmp = adb_query("host:devices");
35 char* p = tmp;
36 if(!tmp) {
37 printf("no emulator connected\n");
38 return -1;
39 }
40 while (*p) {
41 char* q = strchr(p, '\n');
42 if (q != NULL)
43 *q++ = 0;
44 else
45 q = p + strlen(p);
46
47 if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) {
48 if (serial != NULL) { /* more than one emulator listed */
49 free(tmp);
50 return -2;
51 }
52 serial = p;
53 }
54
55 p = q;
56 }
57 free(tmp);
58
59 if (serial == NULL)
60 return -1; /* no emulator found */
61 }
62 else {
63 if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0)
64 return -1; /* not an emulator */
65 }
66
67 serial += sizeof(LOCAL_CLIENT_PREFIX)-1;
68 port = strtol(serial, NULL, 10);
69 return port;
70}
71
72static char __adb_error[256] = { 0 };
73
74const char *adb_error(void)
75{
76 return __adb_error;
77}
78
79static int switch_socket_transport(int fd)
80{
81 char service[64];
82 char tmp[5];
83 int len;
84
85 if (__adb_serial)
86 snprintf(service, sizeof service, "host:transport:%s", __adb_serial);
87 else {
88 char* transport_type = "???";
89
90 switch (__adb_transport) {
91 case kTransportUsb:
92 transport_type = "transport-usb";
93 break;
94 case kTransportLocal:
95 transport_type = "transport-local";
96 break;
97 case kTransportAny:
98 transport_type = "transport-any";
99 break;
100 case kTransportHost:
101 // no switch necessary
102 return 0;
103 break;
104 }
105
106 snprintf(service, sizeof service, "host:%s", transport_type);
107 }
108 len = strlen(service);
109 snprintf(tmp, sizeof tmp, "%04x", len);
110
111 if(writex(fd, tmp, 4) || writex(fd, service, len)) {
112 strcpy(__adb_error, "write failure during connection");
113 adb_close(fd);
114 return -1;
115 }
116 D("Switch transport in progress\n");
117
118 if(adb_status(fd)) {
119 adb_close(fd);
120 D("Switch transport failed\n");
121 return -1;
122 }
123 D("Switch transport success\n");
124 return 0;
125}
126
127int adb_status(int fd)
128{
129 unsigned char buf[5];
130 unsigned len;
131
132 if(readx(fd, buf, 4)) {
133 strcpy(__adb_error, "protocol fault (no status)");
134 return -1;
135 }
136
137 if(!memcmp(buf, "OKAY", 4)) {
138 return 0;
139 }
140
141 if(memcmp(buf, "FAIL", 4)) {
142 sprintf(__adb_error,
143 "protocol fault (status %02x %02x %02x %02x?!)",
144 buf[0], buf[1], buf[2], buf[3]);
145 return -1;
146 }
147
148 if(readx(fd, buf, 4)) {
149 strcpy(__adb_error, "protocol fault (status len)");
150 return -1;
151 }
152 buf[4] = 0;
153 len = strtoul((char*)buf, 0, 16);
154 if(len > 255) len = 255;
155 if(readx(fd, __adb_error, len)) {
156 strcpy(__adb_error, "protocol fault (status read)");
157 return -1;
158 }
159 __adb_error[len] = 0;
160 return -1;
161}
162
163int _adb_connect(const char *service)
164{
165 char tmp[5];
166 int len;
167 int fd;
168
169 D("_adb_connect: %s\n", service);
170 len = strlen(service);
171 if((len < 1) || (len > 1024)) {
172 strcpy(__adb_error, "service name too long");
173 return -1;
174 }
175 snprintf(tmp, sizeof tmp, "%04x", len);
176
177 fd = socket_loopback_client(ADB_PORT, SOCK_STREAM);
178 if(fd < 0) {
179 strcpy(__adb_error, "cannot connect to daemon");
180 return -2;
181 }
182
183 if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) {
184 return -1;
185 }
186
187 if(writex(fd, tmp, 4) || writex(fd, service, len)) {
188 strcpy(__adb_error, "write failure during connection");
189 adb_close(fd);
190 return -1;
191 }
192
193 if(adb_status(fd)) {
194 adb_close(fd);
195 return -1;
196 }
197
198 return fd;
199}
200
201int adb_connect(const char *service)
202{
203 // first query the adb server's version
204 int fd = _adb_connect("host:version");
205
206 if(fd == -2) {
207 fprintf(stdout,"* daemon not running. starting it now *\n");
208 start_server:
209 if(launch_server(0)) {
210 fprintf(stderr,"* failed to start daemon *\n");
211 return -1;
212 } else {
213 fprintf(stdout,"* daemon started successfully *\n");
214 }
215 /* give the server some time to start properly and detect devices */
216 adb_sleep_ms(2000);
217 // fall through to _adb_connect
218 } else {
219 // if server was running, check its version to make sure it is not out of date
220 char buf[100];
221 int n;
222 int version = ADB_SERVER_VERSION - 1;
223
224 // if we have a file descriptor, then parse version result
225 if(fd >= 0) {
226 if(readx(fd, buf, 4)) goto error;
227
228 buf[4] = 0;
229 n = strtoul(buf, 0, 16);
230 if(n > (int)sizeof(buf)) goto error;
231 if(readx(fd, buf, n)) goto error;
232 adb_close(fd);
233
234 if (sscanf(buf, "%04x", &version) != 1) goto error;
235 } else {
236 // if fd is -1, then check for "unknown host service",
237 // which would indicate a version of adb that does not support the version command
238 if (strcmp(__adb_error, "unknown host service") != 0)
239 return fd;
240 }
241
242 if(version != ADB_SERVER_VERSION) {
243 printf("adb server is out of date. killing...\n");
244 fd = _adb_connect("host:kill");
245 adb_close(fd);
246
247 /* XXX can we better detect its death? */
248 adb_sleep_ms(2000);
249 goto start_server;
250 }
251 }
252
253 // if the command is start-server, we are done.
254 if (!strcmp(service, "host:start-server"))
255 return 0;
256
257 fd = _adb_connect(service);
258 if(fd == -2) {
259 fprintf(stderr,"** daemon still not running");
260 }
261
262 return fd;
263error:
264 adb_close(fd);
265 return -1;
266}
267
268
269int adb_command(const char *service)
270{
271 int fd = adb_connect(service);
272 if(fd < 0) {
273 return -1;
274 }
275
276 if(adb_status(fd)) {
277 adb_close(fd);
278 return -1;
279 }
280
281 return 0;
282}
283
284char *adb_query(const char *service)
285{
286 char buf[5];
287 unsigned n;
288 char *tmp;
289
290 D("adb_query: %s\n", service);
291 int fd = adb_connect(service);
292 if(fd < 0) {
293 fprintf(stderr,"error: %s\n", __adb_error);
294 return 0;
295 }
296
297 if(readx(fd, buf, 4)) goto oops;
298
299 buf[4] = 0;
300 n = strtoul(buf, 0, 16);
301 if(n > 1024) goto oops;
302
303 tmp = malloc(n + 1);
304 if(tmp == 0) goto oops;
305
306 if(readx(fd, tmp, n) == 0) {
307 tmp[n] = 0;
308 adb_close(fd);
309 return tmp;
310 }
311 free(tmp);
312
313oops:
314 adb_close(fd);
315 return 0;
316}
317
318
diff --git a/adb/adb_client.h b/adb/adb_client.h
new file mode 100644
index 000000000..80615790c
--- /dev/null
+++ b/adb/adb_client.h
@@ -0,0 +1,49 @@
1#ifndef _ADB_CLIENT_H_
2#define _ADB_CLIENT_H_
3
4#include "adb.h"
5
6/* connect to adb, connect to the named service, and return
7** a valid fd for interacting with that service upon success
8** or a negative number on failure
9*/
10int adb_connect(const char *service);
11int _adb_connect(const char *service);
12
13/* connect to adb, connect to the named service, return 0 if
14** the connection succeeded AND the service returned OKAY
15*/
16int adb_command(const char *service);
17
18/* connect to adb, connect to the named service, return
19** a malloc'd string of its response upon success or NULL
20** on failure.
21*/
22char *adb_query(const char *service);
23
24/* Set the preferred transport to connect to.
25*/
26void adb_set_transport(transport_type type, const char* serial);
27
28/* Return the console port of the currently connected emulator (if any)
29 * of -1 if there is no emulator, and -2 if there is more than one.
30 * assumes adb_set_transport() was alled previously...
31 */
32int adb_get_emulator_console_port(void);
33
34/* send commands to the current emulator instance. will fail if there
35 * is zero, or more than one emulator connected (or if you use -s <serial>
36 * with a <serial> that does not designate an emulator)
37 */
38int adb_send_emulator_command(int argc, char** argv);
39
40/* return verbose error string from last operation */
41const char *adb_error(void);
42
43/* read a standard adb status response (OKAY|FAIL) and
44** return 0 in the event of OKAY, -1 in the event of FAIL
45** or protocol error
46*/
47int adb_status(int fd);
48
49#endif
diff --git a/adb/commandline.c b/adb/commandline.c
new file mode 100644
index 000000000..c1ef8b011
--- /dev/null
+++ b/adb/commandline.c
@@ -0,0 +1,1371 @@
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <errno.h>
21#include <unistd.h>
22#include <limits.h>
23#include <stdarg.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <ctype.h>
27#include <assert.h>
28
29#include "sysdeps.h"
30
31#ifdef HAVE_TERMIO_H
32#include <termios.h>
33#endif
34
35#define TRACE_TAG TRACE_ADB
36#include "adb.h"
37#include "adb_client.h"
38#include "file_sync_service.h"
39
40#ifdef SH_HISTORY
41#include "shlist.h"
42#include "history.h"
43#endif
44
45enum {
46 IGNORE_DATA,
47 WIPE_DATA,
48 FLASH_DATA
49};
50
51static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
52
53void get_my_path(char s[PATH_MAX]);
54int find_sync_dirs(const char *srcarg,
55 char **android_srcdir_out, char **data_srcdir_out);
56int install_app(transport_type transport, char* serial, int argc, char** argv);
57int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
58
59static const char *gProductOutPath = NULL;
60
61static char *product_file(const char *extra)
62{
63 int n;
64 char *x;
65
66 if (gProductOutPath == NULL) {
67 fprintf(stderr, "adb: Product directory not specified; "
68 "use -p or define ANDROID_PRODUCT_OUT\n");
69 exit(1);
70 }
71
72 n = strlen(gProductOutPath) + strlen(extra) + 2;
73 x = malloc(n);
74 if (x == 0) {
75 fprintf(stderr, "adb: Out of memory (product_file())\n");
76 exit(1);
77 }
78
79 snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
80 return x;
81}
82
83void version(FILE * out) {
84 fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
85 ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
86}
87
88void help()
89{
90 version(stderr);
91
92 fprintf(stderr,
93 "\n"
94 " -d - directs command to the only connected USB device\n"
95 " returns an error if more than one USB device is present.\n"
96 " -e - directs command to the only running emulator.\n"
97 " returns an error if more than one emulator is running.\n"
98 " -s <serial number> - directs command to the USB device or emulator with\n"
99 " the given serial number\n"
100 " -p <product name or path> - simple product name like 'sooner', or\n"
101 " a relative/absolute path to a product\n"
102 " out directory like 'out/target/product/sooner'.\n"
103 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
104 " environment variable is used, which must\n"
105 " be an absolute path.\n"
106 " devices - list all connected devices\n"
107 "\n"
108 "device commands:\n"
109 " adb push <local> <remote> - copy file/dir to device\n"
110 " adb pull <remote> <local> - copy file/dir from device\n"
111 " adb sync [ <directory> ] - copy host->device only if changed\n"
112 " (see 'adb help all')\n"
113 " adb shell - run remote shell interactively\n"
114 " adb shell <command> - run remote shell command\n"
115 " adb emu <command> - run emulator console command\n"
116 " adb logcat [ <filter-spec> ] - View device log\n"
117 " adb forward <local> <remote> - forward socket connections\n"
118 " forward specs are one of: \n"
119 " tcp:<port>\n"
120 " localabstract:<unix domain socket name>\n"
121 " localreserved:<unix domain socket name>\n"
122 " localfilesystem:<unix domain socket name>\n"
123 " dev:<character device name>\n"
124 " jdwp:<process pid> (remote only)\n"
125 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
126 " adb install [-l] [-r] <file> - push this package file to the device and install it\n"
127 " ('-l' means forward-lock the app)\n"
128 " ('-r' means reinstall the app, keeping its data)\n"
129 " adb uninstall [-k] <package> - remove this app package from the device\n"
130 " ('-k' means keep the data and cache directories)\n"
131 " adb bugreport - return all information from the device\n"
132 " that should be included in a bug report.\n"
133 "\n"
134 " adb help - show this help message\n"
135 " adb version - show version num\n"
136 "\n"
137 "DATAOPTS:\n"
138 " (no option) - don't touch the data partition\n"
139 " -w - wipe the data partition\n"
140 " -d - flash the data partition\n"
141 "\n"
142 "scripting:\n"
143 " adb wait-for-device - block until device is online\n"
144 " adb start-server - ensure that there is a server running\n"
145 " adb kill-server - kill the server if it is running\n"
146 " adb get-state - prints: offline | bootloader | device\n"
147 " adb get-product - prints: <product-id>\n"
148 " adb get-serialno - prints: <serial-number>\n"
149 " adb status-window - continuously print device status for a specified device\n"
150 " adb remount - remounts the /system partition on the device read-write\n"
151 "\n"
152 "networking:\n"
153 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
154 " Note: you should not automatically start a PDP connection.\n"
155 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
156 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
157 "\n"
158 "adb sync notes: adb sync [ <directory> ]\n"
159 " <localdir> can be interpreted in several ways:\n"
160 "\n"
161 " - If <directory> is not specified, both /system and /data partitions will be updated.\n"
162 "\n"
163 " - If it is \"system\" or \"data\", only the corresponding partition\n"
164 " is updated.\n"
165 );
166}
167
168int usage()
169{
170 help();
171 return 1;
172}
173
174#ifdef HAVE_TERMIO_H
175static struct termios tio_save;
176
177static void stdin_raw_init(int fd)
178{
179 struct termios tio;
180
181 if(tcgetattr(fd, &tio)) return;
182 if(tcgetattr(fd, &tio_save)) return;
183
184 tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
185
186 /* no timeout but request at least one character per read */
187 tio.c_cc[VTIME] = 0;
188 tio.c_cc[VMIN] = 1;
189
190 tcsetattr(fd, TCSANOW, &tio);
191 tcflush(fd, TCIFLUSH);
192}
193
194static void stdin_raw_restore(int fd)
195{
196 tcsetattr(fd, TCSANOW, &tio_save);
197 tcflush(fd, TCIFLUSH);
198}
199#endif
200
201static void read_and_dump(int fd)
202{
203 char buf[4096];
204 int len;
205
206 while(fd >= 0) {
207 len = adb_read(fd, buf, 4096);
208 if(len == 0) {
209 break;
210 }
211
212 if(len < 0) {
213 if(errno == EINTR) continue;
214 break;
215 }
216 /* we want to output to stdout, so no adb_write here !! */
217 unix_write(1, buf, len);
218 }
219}
220
221#ifdef SH_HISTORY
222int shItemCmp( void *val, void *idata )
223{
224 return( (strcmp( val, idata ) == 0) );
225}
226#endif
227
228static void *stdin_read_thread(void *x)
229{
230 int fd, fdi;
231 unsigned char buf[1024];
232#ifdef SH_HISTORY
233 unsigned char realbuf[1024], *buf_ptr;
234 SHLIST history;
235 SHLIST *item = &history;
236 int cmdlen = 0, ins_flag = 0;
237#endif
238 int r, n;
239 int state = 0;
240
241 int *fds = (int*) x;
242 fd = fds[0];
243 fdi = fds[1];
244 free(fds);
245
246#ifdef SH_HISTORY
247 shListInitList( &history );
248#endif
249 for(;;) {
250 /* fdi is really the client's stdin, so use read, not adb_read here */
251 r = unix_read(fdi, buf, 1024);
252 if(r == 0) break;
253 if(r < 0) {
254 if(errno == EINTR) continue;
255 break;
256 }
257#ifdef SH_HISTORY
258 if( (r == 3) && /* Arrow processing */
259 (memcmp( (void *)buf, SH_ARROW_ANY, 2 ) == 0) ) {
260 switch( buf[2] ) {
261 case SH_ARROW_UP:
262 item = shListGetNextItem( &history, item );
263 break;
264 case SH_ARROW_DOWN:
265 item = shListGetPrevItem( &history, item );
266 break;
267 default:
268 item = NULL;
269 break;
270 }
271 memset( buf, SH_DEL_CHAR, cmdlen );
272 if( item != NULL ) {
273 n = snprintf( (char *)(&buf[cmdlen]), sizeof buf - cmdlen, "%s", (char *)(item->data) );
274 memcpy( realbuf, item->data, n );
275 }
276 else { /* Clean buffer */
277 item = &history;
278 n = 0;
279 }
280 r = n + cmdlen;
281 cmdlen = n;
282 ins_flag = 0;
283 if( r == 0 )
284 continue;
285 }
286 else {
287#endif
288 for(n = 0; n < r; n++){
289 switch(buf[n]) {
290 case '\n':
291#ifdef SH_HISTORY
292 if( ins_flag && (SH_BLANK_CHAR <= realbuf[0]) ) {
293 buf_ptr = malloc(cmdlen + 1);
294 if( buf_ptr != NULL ) {
295 memcpy( buf_ptr, realbuf, cmdlen );
296 buf_ptr[cmdlen] = '\0';
297 if( (item = shListFindItem( &history, (void *)buf_ptr, shItemCmp )) == NULL ) {
298 shListInsFirstItem( &history, (void *)buf_ptr );
299 item = &history;
300 }
301 }
302 }
303 cmdlen = 0;
304 ins_flag = 0;
305#endif
306 state = 1;
307 break;
308 case '\r':
309 state = 1;
310 break;
311 case '~':
312 if(state == 1) state++;
313 break;
314 case '.':
315 if(state == 2) {
316 fprintf(stderr,"\n* disconnect *\n");
317 #ifdef HAVE_TERMIO_H
318 stdin_raw_restore(fdi);
319 #endif
320 exit(0);
321 }
322 default:
323#ifdef SH_HISTORY
324 if( buf[n] == SH_DEL_CHAR ) {
325 if( cmdlen > 0 )
326 cmdlen--;
327 }
328 else {
329 realbuf[cmdlen] = buf[n];
330 cmdlen++;
331 }
332 ins_flag = 1;
333#endif
334 state = 0;
335 }
336 }
337#ifdef SH_HISTORY
338 }
339#endif
340 r = adb_write(fd, buf, r);
341 if(r <= 0) {
342 break;
343 }
344 }
345#ifdef SH_HISTORY
346 shListDelAllItems( &history, (shListFree)free );
347#endif
348 return 0;
349}
350
351int interactive_shell(void)
352{
353 adb_thread_t thr;
354 int fdi, fd;
355 int *fds;
356
357 fd = adb_connect("shell:");
358 if(fd < 0) {
359 fprintf(stderr,"error: %s\n", adb_error());
360 return 1;
361 }
362 fdi = 0; //dup(0);
363
364 fds = malloc(sizeof(int) * 2);
365 fds[0] = fd;
366 fds[1] = fdi;
367
368#ifdef HAVE_TERMIO_H
369 stdin_raw_init(fdi);
370#endif
371 adb_thread_create(&thr, stdin_read_thread, fds);
372 read_and_dump(fd);
373#ifdef HAVE_TERMIO_H
374 stdin_raw_restore(fdi);
375#endif
376 return 0;
377}
378
379
380
381int adb_download_buffer(const char *service, const void* data, int sz,
382 unsigned progress)
383{
384 char buf[4096];
385 unsigned total;
386 int fd;
387 const unsigned char *ptr;
388
389 snprintf(buf, sizeof buf, "%s:%d", service, sz);
390 fd = adb_connect(buf);
391 if(fd < 0) {
392 fprintf(stderr,"error: %s\n", adb_error());
393 return -1;
394 }
395
396 adb_socket_setbufsize(fd, CHUNK_SIZE);
397
398 total = sz;
399 ptr = data;
400
401 if(progress) {
402 char *x = strrchr(service, ':');
403 if(x) service = x + 1;
404 }
405
406 while(sz > 0) {
407 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
408 if(writex(fd, ptr, xfer)) {
409 adb_status(fd);
410 fprintf(stderr,"* failed to write data '%s' *\n", adb_error());
411 return -1;
412 }
413 sz -= xfer;
414 ptr += xfer;
415 if(progress) {
416 int percent = 100 - (int)(100.0 * ((float)sz / (float)total));
417 printf("sending: '%s' %4d%% \r", service, percent);
418 fflush(stdout);
419 }
420 }
421 if(progress) {
422 printf("\n");
423 }
424
425 if(readx(fd, buf, 4)){
426 fprintf(stderr,"* error reading response *\n");
427 adb_close(fd);
428 return -1;
429 }
430 if(memcmp(buf, "OKAY", 4)) {
431 buf[4] = 0;
432 fprintf(stderr,"* error response '%s' *\n", buf);
433 adb_close(fd);
434 return -1;
435 }
436
437 adb_close(fd);
438 return 0;
439}
440
441
442int adb_download(const char *service, const char *fn, unsigned progress)
443{
444 void *data;
445 unsigned sz;
446
447 data = load_file(fn, &sz);
448 if(data == 0) {
449 fprintf(stderr,"* cannot read '%s' *\n", service);
450 return -1;
451 }
452
453 return adb_download_buffer(service, data, sz, progress);
454}
455
456static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial)
457{
458 if (serial) {
459 snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
460 } else {
461 const char* prefix = "host";
462 if (ttype == kTransportUsb)
463 prefix = "host-usb";
464 else if (ttype == kTransportLocal)
465 prefix = "host-local";
466
467 snprintf(buffer, buflen, "%s:%s", prefix, command);
468 }
469}
470
471static void status_window(transport_type ttype, const char* serial)
472{
473 char command[4096];
474 char *state = 0;
475 char *laststate = 0;
476
477 /* silence stderr */
478#ifdef _WIN32
479 /* XXX: TODO */
480#else
481 int fd;
482 fd = unix_open("/dev/null", O_WRONLY);
483 dup2(fd, 2);
484 adb_close(fd);
485#endif
486
487 format_host_command(command, sizeof command, "get-state", ttype, serial);
488
489 for(;;) {
490 adb_sleep_ms(250);
491
492 if(state) {
493 free(state);
494 state = 0;
495 }
496
497 state = adb_query(command);
498
499 if(state) {
500 if(laststate && !strcmp(state,laststate)){
501 continue;
502 } else {
503 if(laststate) free(laststate);
504 laststate = strdup(state);
505 }
506 }
507
508 printf("%c[2J%c[2H", 27, 27);
509 printf("Android Debug Bridge\n");
510 printf("State: %s\n", state ? state : "offline");
511 fflush(stdout);
512 }
513}
514
515/** duplicate string and quote all \ " ( ) chars */
516static char *
517dupAndQuote(const char *s)
518{
519 const char *ts;
520 size_t alloc_len;
521 char *ret;
522 char *dest;
523
524 ts = s;
525
526 alloc_len = 0;
527
528 for( ;*ts != '\0'; ts++) {
529 alloc_len++;
530 if (*ts == '"' || *ts == '\\') {
531 alloc_len++;
532 }
533 }
534
535 ret = (char *)malloc(alloc_len + 1);
536
537 ts = s;
538 dest = ret;
539
540 for ( ;*ts != '\0'; ts++) {
541 if (*ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
542 *dest++ = '\\';
543 }
544
545 *dest++ = *ts;
546 }
547
548 *dest++ = '\0';
549
550 return ret;
551}
552
553/**
554 * Run ppp in "notty" mode against a resource listed as the first parameter
555 * eg:
556 *
557 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
558 *
559 */
560int ppp(int argc, char **argv)
561{
562#ifdef HAVE_WIN32_PROC
563 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
564 return -1;
565#else
566 char *adb_service_name;
567 pid_t pid;
568 int fd;
569
570 if (argc < 2) {
571 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
572 argv[0]);
573
574 return 1;
575 }
576
577 adb_service_name = argv[1];
578
579 fd = adb_connect(adb_service_name);
580
581 if(fd < 0) {
582 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
583 adb_service_name, adb_error());
584 return 1;
585 }
586
587 pid = fork();
588
589 if (pid < 0) {
590 perror("from fork()");
591 return 1;
592 } else if (pid == 0) {
593 int err;
594 int i;
595 const char **ppp_args;
596
597 // copy args
598 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
599 ppp_args[0] = "pppd";
600 for (i = 2 ; i < argc ; i++) {
601 //argv[2] and beyond become ppp_args[1] and beyond
602 ppp_args[i - 1] = argv[i];
603 }
604 ppp_args[i-1] = NULL;
605
606 // child side
607
608 dup2(fd, STDIN_FILENO);
609 dup2(fd, STDOUT_FILENO);
610 adb_close(STDERR_FILENO);
611 adb_close(fd);
612
613 err = execvp("pppd", (char * const *)ppp_args);
614
615 if (err < 0) {
616 perror("execing pppd");
617 }
618 exit(-1);
619 } else {
620 // parent side
621
622 adb_close(fd);
623 return 0;
624 }
625#endif /* !HAVE_WIN32_PROC */
626}
627
628static int send_shellcommand(transport_type transport, char* serial, char* buf)
629{
630 int fd, ret;
631
632 for(;;) {
633 fd = adb_connect(buf);
634 if(fd >= 0)
635 break;
636 fprintf(stderr,"- waiting for device -\n");
637 adb_sleep_ms(1000);
638 do_cmd(transport, serial, "wait-for-device", 0);
639 }
640
641 read_and_dump(fd);
642 ret = adb_close(fd);
643 if (ret)
644 perror("close");
645
646 return ret;
647}
648
649static int logcat(transport_type transport, char* serial, int argc, char **argv)
650{
651 char buf[4096];
652
653 char *log_tags;
654 char *quoted_log_tags;
655
656 log_tags = getenv("ANDROID_LOG_TAGS");
657 quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
658
659 snprintf(buf, sizeof(buf),
660 "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
661 quoted_log_tags);
662
663 free(quoted_log_tags);
664
665 argc -= 1;
666 argv += 1;
667 while(argc-- > 0) {
668 char *quoted;
669
670 quoted = dupAndQuote (*argv++);
671
672 strncat(buf, " ", sizeof(buf)-1);
673 strncat(buf, quoted, sizeof(buf)-1);
674 free(quoted);
675 }
676
677 send_shellcommand(transport, serial, buf);
678 return 0;
679}
680
681int adb_download_data(const char *what, const void* data, int sz, unsigned progress)
682{
683 char service[4096];
684 snprintf(service, sizeof service, "bootloader:flash:%s", what);
685 return adb_download_buffer(service, data, sz, 1);
686}
687
688#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
689static int top_works(const char *top)
690{
691 if (top != NULL && adb_is_absolute_host_path(top)) {
692 char path_buf[PATH_MAX];
693 snprintf(path_buf, sizeof(path_buf),
694 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
695 return access(path_buf, F_OK) == 0;
696 }
697 return 0;
698}
699
700static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
701{
702 strcpy(path_buf, indir);
703 while (1) {
704 if (top_works(path_buf)) {
705 return path_buf;
706 }
707 char *s = adb_dirstop(path_buf);
708 if (s != NULL) {
709 *s = '\0';
710 } else {
711 path_buf[0] = '\0';
712 return NULL;
713 }
714 }
715}
716
717static char *find_top(char path_buf[PATH_MAX])
718{
719 char *top = getenv("ANDROID_BUILD_TOP");
720 if (top != NULL && top[0] != '\0') {
721 if (!top_works(top)) {
722 fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
723 return NULL;
724 }
725 } else {
726 top = getenv("TOP");
727 if (top != NULL && top[0] != '\0') {
728 if (!top_works(top)) {
729 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
730 return NULL;
731 }
732 } else {
733 top = NULL;
734 }
735 }
736
737 if (top != NULL) {
738 /* The environment pointed to a top directory that works.
739 */
740 strcpy(path_buf, top);
741 return path_buf;
742 }
743
744 /* The environment didn't help. Walk up the tree from the CWD
745 * to see if we can find the top.
746 */
747 char dir[PATH_MAX];
748 top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
749 if (top == NULL) {
750 /* If the CWD isn't under a good-looking top, see if the
751 * executable is.
752 */
753 get_my_path(dir);
754 top = find_top_from(dir, path_buf);
755 }
756 return top;
757}
758
759/* <hint> may be:
760 * - A simple product name
761 * e.g., "sooner"
762TODO: debug? sooner-debug, sooner:debug?
763 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
764 * e.g., "out/target/product/sooner"
765 * - An absolute path to the PRODUCT_OUT dir
766 * e.g., "/src/device/out/target/product/sooner"
767 *
768 * Given <hint>, try to construct an absolute path to the
769 * ANDROID_PRODUCT_OUT dir.
770 */
771static const char *find_product_out_path(const char *hint)
772{
773 static char path_buf[PATH_MAX];
774
775 if (hint == NULL || hint[0] == '\0') {
776 return NULL;
777 }
778
779 /* If it's already absolute, don't bother doing any work.
780 */
781 if (adb_is_absolute_host_path(hint)) {
782 strcpy(path_buf, hint);
783 return path_buf;
784 }
785
786 /* If there are any slashes in it, assume it's a relative path;
787 * make it absolute.
788 */
789 if (adb_dirstart(hint) != NULL) {
790 if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
791 fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
792 return NULL;
793 }
794 if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
795 fprintf(stderr, "adb: Couldn't assemble path\n");
796 return NULL;
797 }
798 strcat(path_buf, OS_PATH_SEPARATOR_STR);
799 strcat(path_buf, hint);
800 return path_buf;
801 }
802
803 /* It's a string without any slashes. Try to do something with it.
804 *
805 * Try to find the root of the build tree, and build a PRODUCT_OUT
806 * path from there.
807 */
808 char top_buf[PATH_MAX];
809 const char *top = find_top(top_buf);
810 if (top == NULL) {
811 fprintf(stderr, "adb: Couldn't find top of build tree\n");
812 return NULL;
813 }
814//TODO: if we have a way to indicate debug, look in out/debug/target/...
815 snprintf(path_buf, sizeof(path_buf),
816 "%s" OS_PATH_SEPARATOR_STR
817 "out" OS_PATH_SEPARATOR_STR
818 "target" OS_PATH_SEPARATOR_STR
819 "product" OS_PATH_SEPARATOR_STR
820 "%s", top_buf, hint);
821 if (access(path_buf, F_OK) < 0) {
822 fprintf(stderr, "adb: Couldn't find a product dir "
823 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
824 return NULL;
825 }
826 return path_buf;
827}
828
829int adb_commandline(int argc, char **argv)
830{
831 char buf[4096];
832 int no_daemon = 0;
833 int is_daemon = 0;
834 int persist = 0;
835 int r;
836 int quote;
837 transport_type ttype = kTransportAny;
838 char* serial = NULL;
839
840 /* If defined, this should be an absolute path to
841 * the directory containing all of the various system images
842 * for a particular product. If not defined, and the adb
843 * command requires this information, then the user must
844 * specify the path using "-p".
845 */
846 gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
847 if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
848 gProductOutPath = NULL;
849 }
850 // TODO: also try TARGET_PRODUCT as a hint
851
852 /* modifiers and flags */
853 while(argc > 0) {
854 if(!strcmp(argv[0],"nodaemon")) {
855 no_daemon = 1;
856 } else if (!strcmp(argv[0], "fork-server")) {
857 /* this is a special flag used only when the ADB client launches the ADB Server */
858 is_daemon = 1;
859 } else if(!strcmp(argv[0],"persist")) {
860 persist = 1;
861 } else if(!strncmp(argv[0], "-p", 2)) {
862 const char *product = NULL;
863 if (argv[0][2] == '\0') {
864 if (argc < 2) return usage();
865 product = argv[1];
866 argc--;
867 argv++;
868 } else {
869 product = argv[1] + 2;
870 }
871 gProductOutPath = find_product_out_path(product);
872 if (gProductOutPath == NULL) {
873 fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
874 product);
875 return usage();
876 }
877 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
878 if (isdigit(argv[0][2])) {
879 serial = argv[0] + 2;
880 } else {
881 if(argc < 2) return usage();
882 serial = argv[1];
883 argc--;
884 argv++;
885 }
886 } else if (!strcmp(argv[0],"-d")) {
887 ttype = kTransportUsb;
888 } else if (!strcmp(argv[0],"-e")) {
889 ttype = kTransportLocal;
890 } else {
891 /* out of recognized modifiers and flags */
892 break;
893 }
894 argc--;
895 argv++;
896 }
897
898 adb_set_transport(ttype, serial);
899
900 if ((argc > 0) && (!strcmp(argv[0],"server"))) {
901 if (no_daemon || is_daemon) {
902 r = adb_main(is_daemon);
903 } else {
904 r = launch_server();
905 }
906 if(r) {
907 fprintf(stderr,"* could not start server *\n");
908 }
909 return r;
910 }
911
912top:
913 if(argc == 0) {
914 return usage();
915 }
916
917 /* adb_connect() commands */
918
919 if(!strcmp(argv[0], "devices")) {
920 char *tmp;
921 snprintf(buf, sizeof buf, "host:%s", argv[0]);
922 tmp = adb_query(buf);
923 if(tmp) {
924 printf("List of devices attached \n");
925 printf("%s\n", tmp);
926 return 0;
927 } else {
928 return 1;
929 }
930 }
931
932 if (!strcmp(argv[0], "emu")) {
933 return adb_send_emulator_command(argc, argv);
934 }
935
936 if(!strcmp(argv[0], "shell")) {
937 int r;
938 int fd;
939
940 if(argc < 2) {
941 return interactive_shell();
942 }
943
944 snprintf(buf, sizeof buf, "shell:%s", argv[1]);
945 argc -= 2;
946 argv += 2;
947 while(argc-- > 0) {
948 strcat(buf, " ");
949
950 /* quote empty strings and strings with spaces */
951 quote = (**argv == 0 || strchr(*argv, ' '));
952 if (quote)
953 strcat(buf, "\"");
954 strcat(buf, *argv++);
955 if (quote)
956 strcat(buf, "\"");
957 }
958
959 for(;;) {
960 fd = adb_connect(buf);
961 if(fd >= 0) {
962 read_and_dump(fd);
963 adb_close(fd);
964 r = 0;
965 } else {
966 fprintf(stderr,"error: %s\n", adb_error());
967 r = -1;
968 }
969
970 if(persist) {
971 fprintf(stderr,"\n- waiting for device -\n");
972 adb_sleep_ms(1000);
973 do_cmd(ttype, serial, "wait-for-device", 0);
974 } else {
975 return r;
976 }
977 }
978 }
979
980 if(!strcmp(argv[0], "debug")) {
981 int fd = adb_connect("bootdebug:");
982 if(fd >= 0) {
983 read_and_dump(fd);
984 adb_close(fd);
985 return 0;
986 }
987 fprintf(stderr,"error: %s\n", adb_error());
988 return 1;
989 }
990
991 if(!strcmp(argv[0], "bl")) {
992 int fd;
993 if(argc != 2) return usage();
994 snprintf(buf, sizeof buf, "bootloader:%s", argv[1]);
995 fd = adb_connect(buf);
996 if(fd >= 0) {
997 read_and_dump(fd);
998 adb_close(fd);
999 return 0;
1000 } else {
1001 fprintf(stderr,"* command failed: %s *\n", adb_error());
1002 }
1003 return 1;
1004 }
1005
1006 if(!strcmp(argv[0], "kill-server")) {
1007 int fd;
1008 fd = _adb_connect("host:kill");
1009 if(fd == -1) {
1010 fprintf(stderr,"* server not running *\n");
1011 return 1;
1012 }
1013 return 0;
1014 }
1015
1016 if(!strcmp(argv[0], "remount")) {
1017 int fd = adb_connect("remount:");
1018 if(fd >= 0) {
1019 read_and_dump(fd);
1020 adb_close(fd);
1021 return 0;
1022 }
1023 fprintf(stderr,"error: %s\n", adb_error());
1024 return 1;
1025 }
1026
1027 /* adb_download() commands */
1028
1029 if(!strcmp(argv[0], "send")) {
1030 if(argc != 3) return usage();
1031 snprintf(buf, sizeof buf, "bootloader:send:%s", argv[1]);
1032 if(adb_download(buf, argv[2], 1)) {
1033 return 1;
1034 } else {
1035 return 0;
1036 }
1037 }
1038
1039 if(!strcmp(argv[0], "recover")) {
1040 if(argc != 2) return usage();
1041 if(adb_download("recover", argv[1], 1)) {
1042 return 1;
1043 } else {
1044 return 0;
1045 }
1046 }
1047
1048 if(!strcmp(argv[0], "bugreport")) {
1049 if (argc != 1) {
1050 return 1;
1051 }
1052 do_cmd(ttype, serial, "shell", "dumpstate", "-", 0);
1053 return 0;
1054 }
1055
1056 /* adb_command() wrapper commands */
1057
1058 if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1059 char* service = argv[0];
1060 if (!strncmp(service, "wait-for-bootloader", strlen("wait-for-bootloader"))) {
1061 fprintf(stderr,"WAIT FOR BOOTLOADER\n");
1062 } else if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
1063 if (ttype == kTransportUsb) {
1064 service = "wait-for-usb";
1065 } else if (ttype == kTransportLocal) {
1066 service = "wait-for-local";
1067 } else {
1068 service = "wait-for-any";
1069 }
1070 }
1071
1072 format_host_command(buf, sizeof buf, service, ttype, serial);
1073
1074 if (adb_command(buf)) {
1075 D("failure: %s *\n",adb_error());
1076 fprintf(stderr,"error: %s\n", adb_error());
1077 return 1;
1078 }
1079
1080 /* Allow a command to be run after wait-for-device,
1081 * e.g. 'adb wait-for-device shell'.
1082 */
1083 if(argc > 1) {
1084 argc--;
1085 argv++;
1086 goto top;
1087 }
1088 return 0;
1089 }
1090
1091 if(!strcmp(argv[0], "forward")) {
1092 if(argc != 3) return usage();
1093 if (serial) {
1094 snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial,argv[1],argv[2]);
1095 } else {
1096 snprintf(buf, sizeof buf, "host:forward:%s;%s",argv[1],argv[2]);
1097 }
1098 if(adb_command(buf)) {
1099 fprintf(stderr,"error: %s\n", adb_error());
1100 return 1;
1101 }
1102 return 0;
1103 }
1104
1105 /* do_sync_*() commands */
1106
1107 if(!strcmp(argv[0], "ls")) {
1108 if(argc != 2) return usage();
1109 return do_sync_ls(argv[1]);
1110 }
1111
1112 if(!strcmp(argv[0], "push")) {
1113 if(argc != 3) return usage();
1114 return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
1115 }
1116
1117 if(!strcmp(argv[0], "pull")) {
1118 if(argc != 3) return usage();
1119 return do_sync_pull(argv[1], argv[2]);
1120 }
1121
1122 if(!strcmp(argv[0], "install")) {
1123 if (argc < 2) return usage();
1124 return install_app(ttype, serial, argc, argv);
1125 }
1126
1127 if(!strcmp(argv[0], "uninstall")) {
1128 if (argc < 2) return usage();
1129 return uninstall_app(ttype, serial, argc, argv);
1130 }
1131
1132 if(!strcmp(argv[0], "sync")) {
1133 char *srcarg, *android_srcpath, *data_srcpath;
1134 int ret;
1135 if(argc < 2) {
1136 /* No local path was specified. */
1137 srcarg = NULL;
1138 } else if(argc == 2) {
1139 /* A local path or "android"/"data" arg was specified. */
1140 srcarg = argv[1];
1141 } else {
1142 return usage();
1143 }
1144 ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1145 if(ret != 0) return usage();
1146
1147 if(android_srcpath != NULL)
1148 ret = do_sync_sync(android_srcpath, "/system");
1149 if(ret == 0 && data_srcpath != NULL)
1150 ret = do_sync_sync(data_srcpath, "/data");
1151
1152 free(android_srcpath);
1153 free(data_srcpath);
1154 return ret;
1155 }
1156
1157 /* passthrough commands */
1158
1159 if(!strcmp(argv[0],"get-state") ||
1160 !strcmp(argv[0],"get-product") ||
1161 !strcmp(argv[0],"get-serialno"))
1162 {
1163 char *tmp;
1164
1165 format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1166 tmp = adb_query(buf);
1167 if(tmp) {
1168 printf("%s\n", tmp);
1169 return 0;
1170 } else {
1171 return 1;
1172 }
1173 }
1174
1175 /* other commands */
1176
1177 if(!strcmp(argv[0],"status-window")) {
1178 status_window(ttype, serial);
1179 return 0;
1180 }
1181
1182 if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
1183 return logcat(ttype, serial, argc, argv);
1184 }
1185
1186 if(!strcmp(argv[0],"ppp")) {
1187 return ppp(argc, argv);
1188 }
1189
1190 if (!strcmp(argv[0], "start-server")) {
1191 return adb_connect("host:start-server");
1192 }
1193
1194 if (!strcmp(argv[0], "jdwp")) {
1195 int fd = adb_connect("jdwp");
1196 if (fd >= 0) {
1197 read_and_dump(fd);
1198 adb_close(fd);
1199 return 0;
1200 } else {
1201 fprintf(stderr, "error: %s\n", adb_error());
1202 return -1;
1203 }
1204 }
1205
1206 /* "adb /?" is a common idiom under Windows */
1207 if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1208 help();
1209 return 0;
1210 }
1211
1212 if(!strcmp(argv[0], "version")) {
1213 version(stdout);
1214 return 0;
1215 }
1216
1217 usage();
1218 return 1;
1219}
1220
1221static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1222{
1223 char *argv[16];
1224 int argc;
1225 va_list ap;
1226
1227 va_start(ap, cmd);
1228 argc = 0;
1229
1230 if (serial) {
1231 argv[argc++] = "-s";
1232 argv[argc++] = serial;
1233 } else if (ttype == kTransportUsb) {
1234 argv[argc++] = "-d";
1235 } else if (ttype == kTransportLocal) {
1236 argv[argc++] = "-e";
1237 }
1238
1239 argv[argc++] = cmd;
1240 while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1241 va_end(ap);
1242
1243#if 0
1244 int n;
1245 fprintf(stderr,"argc = %d\n",argc);
1246 for(n = 0; n < argc; n++) {
1247 fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1248 }
1249#endif
1250
1251 return adb_commandline(argc, argv);
1252}
1253
1254int find_sync_dirs(const char *srcarg,
1255 char **android_srcdir_out, char **data_srcdir_out)
1256{
1257 char *android_srcdir, *data_srcdir;
1258
1259 if(srcarg == NULL) {
1260 android_srcdir = product_file("system");
1261 data_srcdir = product_file("data");
1262 } else {
1263 /* srcarg may be "data", "system" or NULL.
1264 * if srcarg is NULL, then both data and system are synced
1265 */
1266 if(strcmp(srcarg, "system") == 0) {
1267 android_srcdir = product_file("system");
1268 data_srcdir = NULL;
1269 } else if(strcmp(srcarg, "data") == 0) {
1270 android_srcdir = NULL;
1271 data_srcdir = product_file("data");
1272 } else {
1273 /* It's not "system" or "data".
1274 */
1275 return 1;
1276 }
1277 }
1278
1279 if(android_srcdir_out != NULL)
1280 *android_srcdir_out = android_srcdir;
1281 else
1282 free(android_srcdir);
1283
1284 if(data_srcdir_out != NULL)
1285 *data_srcdir_out = data_srcdir;
1286 else
1287 free(data_srcdir);
1288
1289 return 0;
1290}
1291
1292static int pm_command(transport_type transport, char* serial,
1293 int argc, char** argv)
1294{
1295 char buf[4096];
1296
1297 snprintf(buf, sizeof(buf), "shell:pm");
1298
1299 while(argc-- > 0) {
1300 char *quoted;
1301
1302 quoted = dupAndQuote (*argv++);
1303
1304 strncat(buf, " ", sizeof(buf)-1);
1305 strncat(buf, quoted, sizeof(buf)-1);
1306 free(quoted);
1307 }
1308
1309 send_shellcommand(transport, serial, buf);
1310 return 0;
1311}
1312
1313int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1314{
1315 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1316 return pm_command(transport, serial, argc, argv);
1317}
1318
1319static int delete_file(transport_type transport, char* serial, char* filename)
1320{
1321 char buf[4096];
1322 char* quoted;
1323
1324 snprintf(buf, sizeof(buf), "shell:rm ");
1325 quoted = dupAndQuote(filename);
1326 strncat(buf, quoted, sizeof(buf)-1);
1327 free(quoted);
1328
1329 send_shellcommand(transport, serial, buf);
1330 return 0;
1331}
1332
1333int install_app(transport_type transport, char* serial, int argc, char** argv)
1334{
1335 struct stat st;
1336 int err;
1337 const char *const WHERE = "/data/local/tmp/%s";
1338 char to[PATH_MAX];
1339 char* filename = argv[argc - 1];
1340 const char* p;
1341
1342 p = adb_dirstop(filename);
1343 if (p) {
1344 p++;
1345 snprintf(to, sizeof to, WHERE, p);
1346 } else {
1347 snprintf(to, sizeof to, WHERE, filename);
1348 }
1349 if (p[0] == '\0') {
1350 }
1351
1352 err = stat(filename, &st);
1353 if (err != 0) {
1354 fprintf(stderr, "can't find '%s' to install\n", filename);
1355 return 1;
1356 }
1357 if (!S_ISREG(st.st_mode)) {
1358 fprintf(stderr, "can't install '%s' because it's not a file\n",
1359 filename);
1360 return 1;
1361 }
1362
1363 if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) {
1364 /* file in place; tell the Package Manager to install it */
1365 argv[argc - 1] = to; /* destination name, not source location */
1366 pm_command(transport, serial, argc, argv);
1367 delete_file(transport, serial, to);
1368 }
1369