1bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert/*
2bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * Copyright (C) 2015 The Android Open Source Project
3bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert *
4bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * Licensed under the Apache License, Version 2.0 (the "License");
5bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * you may not use this file except in compliance with the License.
6bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * You may obtain a copy of the License at
7bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert *
8bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert *      http://www.apache.org/licenses/LICENSE-2.0
9bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert *
10bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * Unless required by applicable law or agreed to in writing, software
11bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * distributed under the License is distributed on an "AS IS" BASIS,
12bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * See the License for the specific language governing permissions and
14bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * limitations under the License.
15bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert */
16bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
17aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui#define TRACE_TAG ADB
183313426fad9eaaf53017cdbde889ebcec91358ecDan Albert
193313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "sysdeps.h"
20bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
21bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <errno.h>
22bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <signal.h>
23bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <stdio.h>
24bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <stdlib.h>
25bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <getopt.h>
266795cd8db5ffab674f2a477d8b7b8cc0e3ab406eDan Albert#include <sys/prctl.h>
27bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
28683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes#include <memory>
29683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes
304f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/logging.h>
31bae15b4f46e2848b43b32a85f346ad2a3163240cJorge Lucangeli Obes#include <android-base/macros.h>
32ffdec180176094dac0fb902263370dea1deb138fElliott Hughes#include <android-base/properties.h>
334f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
34683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes#include <libminijail.h>
351f83aa424f537cf3f07e1d27dbbcc524818b5358Steven Moreland#include <log/log_properties.h>
36bae15b4f46e2848b43b32a85f346ad2a3163240cJorge Lucangeli Obes#include <scoped_minijail.h>
37683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes
3897787a00e6aeb9aba2d744566cfd9de3d2f8c4f6Mark Salyzyn#include <private/android_filesystem_config.h>
39cbe70cb0a8cb0171f3802273050e851a47b090edJosh Gao#include "debuggerd/handler.h"
4038cd57a1450874d4c045ab3612f2dd11d04fca13Tom Cherry#include "selinux/android.h"
41bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
42c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "adb.h"
43c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "adb_auth.h"
44c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "adb_listeners.h"
457d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#include "adb_utils.h"
46c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "transport.h"
47218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert
486cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin#include "mdns.h"
496cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin
50c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertstatic const char* root_seclabel = nullptr;
51bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
524d186ad96447df8d0d39235fb9b3f2022767aefeJorge Lucangeli Obesstatic void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
534d186ad96447df8d0d39235fb9b3f2022767aefeJorge Lucangeli Obes#if defined(ALLOW_ADBD_ROOT)
5497787a00e6aeb9aba2d744566cfd9de3d2f8c4f6Mark Salyzyn    if (__android_log_is_debuggable()) {
55bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        return;
56bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
57bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#endif
584d186ad96447df8d0d39235fb9b3f2022767aefeJorge Lucangeli Obes    minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
59bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert}
60bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
61bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albertstatic bool should_drop_privileges() {
62bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#if defined(ALLOW_ADBD_ROOT)
6313f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    // The properties that affect `adb root` and `adb unroot` are ro.secure and
6413f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    // ro.debuggable. In this context the names don't make the expected behavior
6513f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    // particularly obvious.
6613f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    //
6713f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    // ro.debuggable:
6813f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    //   Allowed to become root, but not necessarily the default. Set to 1 on
6913f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    //   eng and userdebug builds.
7013f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    //
7113f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    // ro.secure:
7213f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert    //   Drop privileges by default. Set to 1 on userdebug and user builds.
73ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
7497787a00e6aeb9aba2d744566cfd9de3d2f8c4f6Mark Salyzyn    bool ro_debuggable = __android_log_is_debuggable();
7513f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert
76bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    // Drop privileges if ro.secure is set...
77bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    bool drop = ro_secure;
78bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
79683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes    // ... except "adb root" lets you keep privileges in a debuggable build.
80ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    std::string prop = android::base::GetProperty("service.adb.root", "");
81ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    bool adb_root = (prop == "1");
82ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    bool adb_unroot = (prop == "0");
83bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    if (ro_debuggable && adb_root) {
84bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        drop = false;
85bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
86683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes    // ... and "adb unroot" lets you explicitly drop privileges.
87bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    if (adb_unroot) {
88bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        drop = true;
89bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
90bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
91bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    return drop;
92bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#else
93bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    return true; // "adb root" not allowed, always drop privileges.
94c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#endif // ALLOW_ADBD_ROOT
95218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert}
96218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert
974120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysingerstatic void drop_privileges(int server_port) {
98bae15b4f46e2848b43b32a85f346ad2a3163240cJorge Lucangeli Obes    ScopedMinijail jail(minijail_new());
99683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes
100c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // Add extra groups:
101c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_ADB to access the USB driver
102c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_LOG to read system logs (adb logcat)
103c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_INPUT to diagnose input issues (getevent)
104c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_INET to diagnose network issues (ping)
105c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
106c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_SDCARD_R to allow reading from the SD card
107c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_SDCARD_RW to allow writing to the SD card
108c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // AID_NET_BW_STATS to read out qtaguid statistics
109c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich    // AID_READPROC for reading /proc entries across UID boundaries
110c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    gid_t groups[] = {AID_ADB,      AID_LOG,       AID_INPUT,
111c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert                      AID_INET,     AID_NET_BT,    AID_NET_BT_ADMIN,
112c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich                      AID_SDCARD_R, AID_SDCARD_RW, AID_NET_BW_STATS,
113683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes                      AID_READPROC};
114bae15b4f46e2848b43b32a85f346ad2a3163240cJorge Lucangeli Obes    minijail_set_supplementary_gids(jail.get(), arraysize(groups), groups);
115bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
116683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes    // Don't listen on a port (default 5037) if running in secure mode.
117683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes    // Don't run as root if running in secure mode.
118bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    if (should_drop_privileges()) {
1194d186ad96447df8d0d39235fb9b3f2022767aefeJorge Lucangeli Obes        drop_capabilities_bounding_set_if_needed(jail.get());
120bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
121683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes        minijail_change_gid(jail.get(), AID_SHELL);
122683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes        minijail_change_uid(jail.get(), AID_SHELL);
123683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes        // minijail_enter() will abort if any priv-dropping step fails.
124683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes        minijail_enter(jail.get());
125bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
1267a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui        D("Local port disabled");
127bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    } else {
128683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes        // minijail_enter() will abort if any priv-dropping step fails.
129683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes        minijail_enter(jail.get());
130683dc4817f1e3cb3a043a7ce6496c00d19fa27f5Jorge Lucangeli Obes
1314d87095ebfefdb9e641492462f0a0e21d5b96ecfNick Kralevich        if (root_seclabel != nullptr) {
13238cd57a1450874d4c045ab3612f2dd11d04fca13Tom Cherry            if (selinux_android_setcon(root_seclabel) < 0) {
133f39c56456d1f9bb910a9bc1187027a75942c8658Jorge Lucangeli Obes                LOG(FATAL) << "Could not set SELinux context";
134bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert            }
135bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        }
1365200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low        std::string error;
137c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        std::string local_name =
138c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert            android::base::StringPrintf("tcp:%d", server_port);
139eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if (install_listener(local_name, "*smartsocket*", nullptr, 0, nullptr, &error)) {
140eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            LOG(FATAL) << "Could not install *smartsocket* listener: " << error;
141bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        }
142bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
1434120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger}
1444120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
1456cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic void setup_port(int port) {
1466cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin    local_init(port);
1476cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin    setup_mdns(port);
1486cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin}
1496cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin
1504120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysingerint adbd_main(int server_port) {
1514120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    umask(0);
1524120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
1534120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    signal(SIGPIPE, SIG_IGN);
1544120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
1554120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    init_transport_registration();
1564120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
1574120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    // We need to call this even if auth isn't enabled because the file
1584120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    // descriptor will always be open.
1594120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    adbd_cloexec_auth_socket();
1604120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
161ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) {
1624120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger        auth_required = false;
1634120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    }
1644120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
1654120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    adbd_auth_init();
1664120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
1674120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    // Our external storage path may be different than apps, since
1684120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    // we aren't able to bind mount after dropping root.
1694120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
1704120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    if (adb_external_storage != nullptr) {
1714120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger        setenv("EXTERNAL_STORAGE", adb_external_storage, 1);
1724120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    } else {
1734120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger        D("Warning: ADB_EXTERNAL_STORAGE is not set.  Leaving EXTERNAL_STORAGE"
1744120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger          " unchanged.\n");
1754120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    }
1764120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger
1774120ebc635b41b17a7283b5c2d0ef1e4425a169fMike Frysinger    drop_privileges(server_port);
178bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
179c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    bool is_usb = false;
180183b73e665a4cd369ef88c657019cd29f009672bJosh Gao    if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
181c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        // Listen on USB.
182bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        usb_init();
183c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        is_usb = true;
184bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
185bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
186c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // If one of these properties is set, also listen on that port.
187c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // If one of the properties isn't set and we couldn't listen on usb, listen
188c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    // on the default port.
189ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    std::string prop_port = android::base::GetProperty("service.adb.tcp.port", "");
190ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    if (prop_port.empty()) {
191ffdec180176094dac0fb902263370dea1deb138fElliott Hughes        prop_port = android::base::GetProperty("persist.adb.tcp.port", "");
192bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
193c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert
194c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    int port;
195ffdec180176094dac0fb902263370dea1deb138fElliott Hughes    if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) {
1967a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui        D("using port=%d", port);
197c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        // Listen on TCP port specified by service.adb.tcp.port property.
1986cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin        setup_port(port);
199c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    } else if (!is_usb) {
200c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        // Listen on default port.
2016cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin        setup_port(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
202bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
203bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
2047a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("adbd_main(): pre init_jdwp()");
205bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    init_jdwp();
2067a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("adbd_main(): post init_jdwp()");
207bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
2087a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("Event loop starting");
209bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    fdevent_loop();
210bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
211bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    return 0;
212bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert}
213bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
214c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertint main(int argc, char** argv) {
215a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes    while (true) {
216bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        static struct option opts[] = {
2171ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert            {"root_seclabel", required_argument, nullptr, 's'},
2181ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert            {"device_banner", required_argument, nullptr, 'b'},
2191ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert            {"version", no_argument, nullptr, 'v'},
220bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        };
2211ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert
2221ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert        int option_index = 0;
2231ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert        int c = getopt_long(argc, argv, "", opts, &option_index);
224c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        if (c == -1) {
225218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert            break;
226c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert        }
227c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert
228bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        switch (c) {
229bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        case 's':
230bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert            root_seclabel = optarg;
231bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert            break;
232bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        case 'b':
233bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert            adb_device_banner = optarg;
234bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert            break;
2351ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert        case 'v':
2361ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert            printf("Android Debug Bridge Daemon version %d.%d.%d %s\n",
2371ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert                   ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION,
2381ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert                   ADB_REVISION);
2391ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert            return 0;
240bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        default:
241c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert            // getopt already prints "adbd: invalid option -- %c" for us.
242c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert            return 1;
243bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert        }
244bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert    }
245bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert
2461ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert    close_stdin();
2471ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert
248809607ae288350ec20ef0dc1bb7f722b312038efJosh Gao    debuggerd_init(nullptr);
2499313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert    adb_trace_init(argv);
2501ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert
2517a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui    D("Handling main()");
252c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert    return adbd_main(DEFAULT_ADB_PORT);
253bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert}
254